Changeset 15245 in josm


Ignore:
Timestamp:
2019-07-13T18:41:24+02:00 (6 weeks ago)
Author:
Don-vip
Message:

see #17885 - extract Functions class

Location:
trunk
Files:
1 added
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/data/validation/tests/MapCSSTagChecker.java

    r15104 r15245  
    5757import org.openstreetmap.josm.gui.mappaint.mapcss.ConditionFactory.ExpressionCondition;
    5858import org.openstreetmap.josm.gui.mappaint.mapcss.Expression;
    59 import org.openstreetmap.josm.gui.mappaint.mapcss.ExpressionFactory.Functions;
    6059import org.openstreetmap.josm.gui.mappaint.mapcss.ExpressionFactory.ParameterFunction;
     60import org.openstreetmap.josm.gui.mappaint.mapcss.Functions;
    6161import org.openstreetmap.josm.gui.mappaint.mapcss.Instruction;
    6262import org.openstreetmap.josm.gui.mappaint.mapcss.LiteralExpression;
  • trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/ConditionFactory.java

    r15122 r15245  
    719719         * @param e MapCSS environment
    720720         * @return {@code true} if there is right-hand traffic at the current location
    721          * @see ExpressionFactory.Functions#is_right_hand_traffic(Environment)
     721         * @see Functions#is_right_hand_traffic(Environment)
    722722         */
    723723        static boolean righthandtraffic(Environment e) { // NO_UCD (unused code)
    724             return ExpressionFactory.Functions.is_right_hand_traffic(e);
     724            return Functions.is_right_hand_traffic(e);
    725725        }
    726726
     
    730730         * @param e MapCSS environment
    731731         * @return {@code true} if the way clockwise
    732          * @see ExpressionFactory.Functions#is_clockwise(Environment)
     732         * @see Functions#is_clockwise(Environment)
    733733         */
    734734        static boolean clockwise(Environment e) { // NO_UCD (unused code)
    735             return ExpressionFactory.Functions.is_clockwise(e);
     735            return Functions.is_clockwise(e);
    736736        }
    737737
     
    741741         * @param e MapCSS environment
    742742         * @return {@code true} if the way clockwise
    743          * @see ExpressionFactory.Functions#is_anticlockwise(Environment)
     743         * @see Functions#is_anticlockwise(Environment)
    744744         */
    745745        static boolean anticlockwise(Environment e) { // NO_UCD (unused code)
    746             return ExpressionFactory.Functions.is_anticlockwise(e);
     746            return Functions.is_anticlockwise(e);
    747747        }
    748748
  • trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/ExpressionFactory.java

    r15196 r15245  
    22package org.openstreetmap.josm.gui.mappaint.mapcss;
    33
    4 import java.awt.Color;
    54import java.lang.annotation.ElementType;
    65import java.lang.annotation.Retention;
     
    109import java.lang.reflect.InvocationTargetException;
    1110import java.lang.reflect.Method;
    12 import java.nio.charset.StandardCharsets;
    1311import java.util.ArrayList;
    14 import java.util.Arrays;
    1512import java.util.Collection;
    1613import java.util.Collections;
    1714import java.util.List;
    18 import java.util.Locale;
    1915import java.util.Objects;
    20 import java.util.TreeSet;
    2116import java.util.function.Function;
    22 import java.util.regex.Matcher;
    23 import java.util.regex.Pattern;
    24 import java.util.zip.CRC32;
    25 
    26 import org.openstreetmap.josm.data.coor.LatLon;
    27 import org.openstreetmap.josm.data.gpx.GpxDistance;
    28 import org.openstreetmap.josm.data.osm.IPrimitive;
    29 import org.openstreetmap.josm.data.osm.Node;
    30 import org.openstreetmap.josm.data.osm.OsmPrimitive;
    31 import org.openstreetmap.josm.data.osm.Relation;
    32 import org.openstreetmap.josm.data.osm.RelationMember;
    33 import org.openstreetmap.josm.data.osm.Way;
    34 import org.openstreetmap.josm.data.osm.search.SearchCompiler;
    35 import org.openstreetmap.josm.data.osm.search.SearchCompiler.Match;
    36 import org.openstreetmap.josm.data.osm.search.SearchParseError;
    37 import org.openstreetmap.josm.gui.MainApplication;
     17
    3818import org.openstreetmap.josm.gui.mappaint.Cascade;
    3919import org.openstreetmap.josm.gui.mappaint.Environment;
    40 import org.openstreetmap.josm.gui.mappaint.MapPaintStyles;
    41 import org.openstreetmap.josm.io.XmlWriter;
    42 import org.openstreetmap.josm.tools.AlphanumComparator;
    43 import org.openstreetmap.josm.tools.ColorHelper;
    44 import org.openstreetmap.josm.tools.Geometry;
    4520import org.openstreetmap.josm.tools.JosmRuntimeException;
    4621import org.openstreetmap.josm.tools.Logging;
    47 import org.openstreetmap.josm.tools.RightAndLefthandTraffic;
    48 import org.openstreetmap.josm.tools.RotationAngle;
    4922import org.openstreetmap.josm.tools.SubclassFilteredCollection;
    50 import org.openstreetmap.josm.tools.Territories;
    5123import org.openstreetmap.josm.tools.Utils;
    5224
     
    11284
    11385    /**
    114      * List of functions that can be used in MapCSS expressions.
    115      *
    116      * First parameter can be of type {@link Environment} (if needed). This is
    117      * automatically filled in by JOSM and the user only sees the remaining arguments.
    118      * When one of the user supplied arguments cannot be converted the
    119      * expected type or is null, the function is not called and it returns null
    120      * immediately. Add the annotation {@link NullableArguments} to allow null arguments.
    121      * Every method must be static.
    122      */
    123     @SuppressWarnings("UnusedDeclaration")
    124     public static final class Functions {
    125 
    126         private Functions() {
    127             // Hide implicit public constructor for utility classes
    128         }
    129 
    130         /**
    131          * Identity function for compatibility with MapCSS specification.
    132          * @param o any object
    133          * @return {@code o} unchanged
    134          */
    135         public static Object eval(Object o) { // NO_UCD (unused code)
    136             return o;
    137         }
    138 
    139         /**
    140          * Function associated to the numeric "+" operator.
    141          * @param args arguments
    142          * @return Sum of arguments
    143          */
    144         public static float plus(float... args) { // NO_UCD (unused code)
    145             float res = 0;
    146             for (float f : args) {
    147                 res += f;
    148             }
    149             return res;
    150         }
    151 
    152         /**
    153          * Function associated to the numeric "-" operator.
    154          * @param args arguments
    155          * @return Substraction of arguments
    156          */
    157         public static Float minus(float... args) { // NO_UCD (unused code)
    158             if (args.length == 0) {
    159                 return 0.0F;
    160             }
    161             if (args.length == 1) {
    162                 return -args[0];
    163             }
    164             float res = args[0];
    165             for (int i = 1; i < args.length; ++i) {
    166                 res -= args[i];
    167             }
    168             return res;
    169         }
    170 
    171         /**
    172          * Function associated to the numeric "*" operator.
    173          * @param args arguments
    174          * @return Multiplication of arguments
    175          */
    176         public static float times(float... args) { // NO_UCD (unused code)
    177             float res = 1;
    178             for (float f : args) {
    179                 res *= f;
    180             }
    181             return res;
    182         }
    183 
    184         /**
    185          * Function associated to the numeric "/" operator.
    186          * @param args arguments
    187          * @return Division of arguments
    188          */
    189         public static Float divided_by(float... args) { // NO_UCD (unused code)
    190             if (args.length == 0) {
    191                 return 1.0F;
    192             }
    193             float res = args[0];
    194             for (int i = 1; i < args.length; ++i) {
    195                 if (args[i] == 0) {
    196                     return null;
    197                 }
    198                 res /= args[i];
    199             }
    200             return res;
    201         }
    202 
    203         /**
    204          * Creates a list of values, e.g., for the {@code dashes} property.
    205          * @param args The values to put in a list
    206          * @return list of values
    207          * @see Arrays#asList(Object[])
    208          */
    209         public static List<Object> list(Object... args) { // NO_UCD (unused code)
    210             return Arrays.asList(args);
    211         }
    212 
    213         /**
    214          * Returns the number of elements in a list.
    215          * @param lst the list
    216          * @return length of the list
    217          */
    218         public static Integer count(List<?> lst) { // NO_UCD (unused code)
    219             return lst.size();
    220         }
    221 
    222         /**
    223          * Returns the first non-null object.
    224          * The name originates from <a href="http://wiki.openstreetmap.org/wiki/MapCSS/0.2/eval">MapCSS standard</a>.
    225          * @param args arguments
    226          * @return the first non-null object
    227          * @see Utils#firstNonNull(Object[])
    228          */
    229         @NullableArguments
    230         public static Object any(Object... args) { // NO_UCD (unused code)
    231             return Utils.firstNonNull(args);
    232         }
    233 
    234         /**
    235          * Get the {@code n}th element of the list {@code lst} (counting starts at 0).
    236          * @param lst list
    237          * @param n index
    238          * @return {@code n}th element of the list, or {@code null} if index out of range
    239          * @since 5699
    240          */
    241         public static Object get(List<?> lst, float n) { // NO_UCD (unused code)
    242             int idx = Math.round(n);
    243             if (idx >= 0 && idx < lst.size()) {
    244                 return lst.get(idx);
    245             }
    246             return null;
    247         }
    248 
    249         /**
    250          * Splits string {@code toSplit} at occurrences of the separator string {@code sep} and returns a list of matches.
    251          * @param sep separator string
    252          * @param toSplit string to split
    253          * @return list of matches
    254          * @see String#split(String)
    255          * @since 5699
    256          */
    257         public static List<String> split(String sep, String toSplit) { // NO_UCD (unused code)
    258             return Arrays.asList(toSplit.split(Pattern.quote(sep), -1));
    259         }
    260 
    261         /**
    262          * Creates a color value with the specified amounts of {@code r}ed, {@code g}reen, {@code b}lue (arguments from 0.0 to 1.0)
    263          * @param r the red component
    264          * @param g the green component
    265          * @param b the blue component
    266          * @return color matching the given components
    267          * @see Color#Color(float, float, float)
    268          */
    269         public static Color rgb(float r, float g, float b) { // NO_UCD (unused code)
    270             try {
    271                 return new Color(r, g, b);
    272             } catch (IllegalArgumentException e) {
    273                 Logging.trace(e);
    274                 return null;
    275             }
    276         }
    277 
    278         /**
    279          * Creates a color value with the specified amounts of {@code r}ed, {@code g}reen, {@code b}lue, {@code alpha}
    280          * (arguments from 0.0 to 1.0)
    281          * @param r the red component
    282          * @param g the green component
    283          * @param b the blue component
    284          * @param alpha the alpha component
    285          * @return color matching the given components
    286          * @see Color#Color(float, float, float, float)
    287          */
    288         public static Color rgba(float r, float g, float b, float alpha) { // NO_UCD (unused code)
    289             try {
    290                 return new Color(r, g, b, alpha);
    291             } catch (IllegalArgumentException e) {
    292                 Logging.trace(e);
    293                 return null;
    294             }
    295         }
    296 
    297         /**
    298          * Create color from hsb color model. (arguments form 0.0 to 1.0)
    299          * @param h hue
    300          * @param s saturation
    301          * @param b brightness
    302          * @return the corresponding color
    303          */
    304         public static Color hsb_color(float h, float s, float b) { // NO_UCD (unused code)
    305             try {
    306                 return Color.getHSBColor(h, s, b);
    307             } catch (IllegalArgumentException e) {
    308                 Logging.trace(e);
    309                 return null;
    310             }
    311         }
    312 
    313         /**
    314          * Creates a color value from an HTML notation, i.e., {@code #rrggbb}.
    315          * @param html HTML notation
    316          * @return color matching the given notation
    317          */
    318         public static Color html2color(String html) { // NO_UCD (unused code)
    319             return ColorHelper.html2color(html);
    320         }
    321 
    322         /**
    323          * Computes the HTML notation ({@code #rrggbb}) for a color value).
    324          * @param c color
    325          * @return HTML notation matching the given color
    326          */
    327         public static String color2html(Color c) { // NO_UCD (unused code)
    328             return ColorHelper.color2html(c);
    329         }
    330 
    331         /**
    332          * Get the value of the red color channel in the rgb color model
    333          * @param c color
    334          * @return the red color channel in the range [0;1]
    335          * @see java.awt.Color#getRed()
    336          */
    337         public static float red(Color c) { // NO_UCD (unused code)
    338             return Utils.colorInt2float(c.getRed());
    339         }
    340 
    341         /**
    342          * Get the value of the green color channel in the rgb color model
    343          * @param c color
    344          * @return the green color channel in the range [0;1]
    345          * @see java.awt.Color#getGreen()
    346          */
    347         public static float green(Color c) { // NO_UCD (unused code)
    348             return Utils.colorInt2float(c.getGreen());
    349         }
    350 
    351         /**
    352          * Get the value of the blue color channel in the rgb color model
    353          * @param c color
    354          * @return the blue color channel in the range [0;1]
    355          * @see java.awt.Color#getBlue()
    356          */
    357         public static float blue(Color c) { // NO_UCD (unused code)
    358             return Utils.colorInt2float(c.getBlue());
    359         }
    360 
    361         /**
    362          * Get the value of the alpha channel in the rgba color model
    363          * @param c color
    364          * @return the alpha channel in the range [0;1]
    365          * @see java.awt.Color#getAlpha()
    366          */
    367         public static float alpha(Color c) { // NO_UCD (unused code)
    368             return Utils.colorInt2float(c.getAlpha());
    369         }
    370 
    371         /**
    372          * Assembles the strings to one.
    373          * @param args arguments
    374          * @return assembled string
    375          * @see Utils#join
    376          */
    377         @NullableArguments
    378         public static String concat(Object... args) { // NO_UCD (unused code)
    379             return Utils.join("", Arrays.asList(args));
    380         }
    381 
    382         /**
    383          * Assembles the strings to one, where the first entry is used as separator.
    384          * @param args arguments. First one is used as separator
    385          * @return assembled string
    386          * @see Utils#join
    387          */
    388         @NullableArguments
    389         public static String join(String... args) { // NO_UCD (unused code)
    390             return Utils.join(args[0], Arrays.asList(args).subList(1, args.length));
    391         }
    392 
    393         /**
    394          * Joins a list of {@code values} into a single string with fields separated by {@code separator}.
    395          * @param separator the separator
    396          * @param values collection of objects
    397          * @return assembled string
    398          * @see Utils#join
    399          */
    400         public static String join_list(final String separator, final List<String> values) { // NO_UCD (unused code)
    401             return Utils.join(separator, values);
    402         }
    403 
    404         /**
    405          * Returns the value of the property {@code key}, e.g., {@code prop("width")}.
    406          * @param env the environment
    407          * @param key the property key
    408          * @return the property value
    409          */
    410         public static Object prop(final Environment env, String key) { // NO_UCD (unused code)
    411             return prop(env, key, null);
    412         }
    413 
    414         /**
    415          * Returns the value of the property {@code key} from layer {@code layer}.
    416          * @param env the environment
    417          * @param key the property key
    418          * @param layer layer
    419          * @return the property value
    420          */
    421         public static Object prop(final Environment env, String key, String layer) {
    422             return env.getCascade(layer).get(key);
    423         }
    424 
    425         /**
    426          * Determines whether property {@code key} is set.
    427          * @param env the environment
    428          * @param key the property key
    429          * @return {@code true} if the property is set, {@code false} otherwise
    430          */
    431         public static Boolean is_prop_set(final Environment env, String key) { // NO_UCD (unused code)
    432             return is_prop_set(env, key, null);
    433         }
    434 
    435         /**
    436          * Determines whether property {@code key} is set on layer {@code layer}.
    437          * @param env the environment
    438          * @param key the property key
    439          * @param layer layer
    440          * @return {@code true} if the property is set, {@code false} otherwise
    441          */
    442         public static Boolean is_prop_set(final Environment env, String key, String layer) {
    443             return env.getCascade(layer).containsKey(key);
    444         }
    445 
    446         /**
    447          * Gets the value of the key {@code key} from the object in question.
    448          * @param env the environment
    449          * @param key the OSM key
    450          * @return the value for given key
    451          */
    452         public static String tag(final Environment env, String key) { // NO_UCD (unused code)
    453             return env.osm == null ? null : env.osm.get(key);
    454         }
    455 
    456         /**
    457          * Gets the first non-null value of the key {@code key} from the object's parent(s).
    458          * @param env the environment
    459          * @param key the OSM key
    460          * @return first non-null value of the key {@code key} from the object's parent(s)
    461          */
    462         public static String parent_tag(final Environment env, String key) { // NO_UCD (unused code)
    463             if (env.parent == null) {
    464                 if (env.osm != null) {
    465                     // we don't have a matched parent, so just search all referrers
    466                     for (IPrimitive parent : env.osm.getReferrers()) {
    467                         String value = parent.get(key);
    468                         if (value != null) {
    469                             return value;
    470                         }
    471                     }
    472                 }
    473                 return null;
    474             }
    475             return env.parent.get(key);
    476         }
    477 
    478         /**
    479          * Gets a list of all non-null values of the key {@code key} from the object's parent(s).
    480          *
    481          * The values are sorted according to {@link AlphanumComparator}.
    482          * @param env the environment
    483          * @param key the OSM key
    484          * @return a list of non-null values of the key {@code key} from the object's parent(s)
    485          */
    486         public static List<String> parent_tags(final Environment env, String key) { // NO_UCD (unused code)
    487             if (env.parent == null) {
    488                 if (env.osm != null) {
    489                     final Collection<String> tags = new TreeSet<>(AlphanumComparator.getInstance());
    490                     // we don't have a matched parent, so just search all referrers
    491                     for (IPrimitive parent : env.osm.getReferrers()) {
    492                         String value = parent.get(key);
    493                         if (value != null) {
    494                             tags.add(value);
    495                         }
    496                     }
    497                     return new ArrayList<>(tags);
    498                 }
    499                 return Collections.emptyList();
    500             }
    501             return Collections.singletonList(env.parent.get(key));
    502         }
    503 
    504         /**
    505          * Gets the value of the key {@code key} from the object's child.
    506          * @param env the environment
    507          * @param key the OSM key
    508          * @return the value of the key {@code key} from the object's child, or {@code null} if there is no child
    509          */
    510         public static String child_tag(final Environment env, String key) { // NO_UCD (unused code)
    511             return env.child == null ? null : env.child.get(key);
    512         }
    513 
    514         /**
    515          * Returns the OSM id of the object's parent.
    516          * <p>
    517          * Parent must be matched by child selector.
    518          * @param env the environment
    519          * @return the OSM id of the object's parent, if available, or {@code null}
    520          * @see IPrimitive#getUniqueId()
    521          */
    522         public static Long parent_osm_id(final Environment env) { // NO_UCD (unused code)
    523             return env.parent == null ? null : env.parent.getUniqueId();
    524         }
    525 
    526         /**
    527          * Returns the lowest distance between the OSM object and a GPX point
    528          * <p>
    529          * @param env the environment
    530          * @return the distance between the object and the closest gpx point or {@code Double.MAX_VALUE}
    531          * @since 14802
    532          */
    533         public static double gpx_distance(final Environment env) { // NO_UCD (unused code)
    534             if (env.osm instanceof OsmPrimitive) {
    535                 return MainApplication.getLayerManager().getAllGpxData().stream()
    536                         .mapToDouble(gpx -> GpxDistance.getLowestDistance((OsmPrimitive) env.osm, gpx))
    537                         .min().orElse(Double.MAX_VALUE);
    538             }
    539             return Double.MAX_VALUE;
    540         }
    541 
    542         /**
    543          * Determines whether the object has a tag with the given key.
    544          * @param env the environment
    545          * @param key the OSM key
    546          * @return {@code true} if the object has a tag with the given key, {@code false} otherwise
    547          */
    548         public static boolean has_tag_key(final Environment env, String key) { // NO_UCD (unused code)
    549             return env.osm.hasKey(key);
    550         }
    551 
    552         /**
    553          * Returns the index of node in parent way or member in parent relation.
    554          * @param env the environment
    555          * @return the index as float. Starts at 1
    556          */
    557         public static Float index(final Environment env) { // NO_UCD (unused code)
    558             if (env.index == null) {
    559                 return null;
    560             }
    561             return Float.valueOf(env.index + 1f);
    562         }
    563 
    564         /**
    565          * Returns the role of current object in parent relation, or role of child if current object is a relation.
    566          * @param env the environment
    567          * @return role of current object in parent relation, or role of child if current object is a relation
    568          * @see Environment#getRole()
    569          */
    570         public static String role(final Environment env) { // NO_UCD (unused code)
    571             return env.getRole();
    572         }
    573 
    574         /**
    575          * Returns true if role is in relation. Returns false if not a relation or it does not have the role.
    576          * @param env the environment
    577          * @param roles The roles to count in the relation
    578          * @return The number of relation members with the specified role
    579          * @since 15196
    580          */
    581         public static int count_roles(final Environment env, String... roles) { // NO_UCD (unused code)
    582             int rValue = 0;
    583             if (env.osm instanceof Relation) {
    584                 List<String> roleList = Arrays.asList(roles);
    585                 Relation rel = (Relation) env.osm;
    586                 for (RelationMember member : rel.getMembers()) {
    587                     if (roleList.contains(member.getRole())) rValue++;
    588                 }
    589             }
    590             return rValue;
    591         }
    592 
    593         /**
    594          * Returns the area of a closed way or multipolygon in square meters or {@code null}.
    595          * @param env the environment
    596          * @return the area of a closed way or multipolygon in square meters or {@code null}
    597          * @see Geometry#computeArea(IPrimitive)
    598          */
    599         public static Float areasize(final Environment env) { // NO_UCD (unused code)
    600             final Double area = Geometry.computeArea(env.osm);
    601             return area == null ? null : area.floatValue();
    602         }
    603 
    604         /**
    605          * Returns the length of the way in metres or {@code null}.
    606          * @param env the environment
    607          * @return the length of the way in metres or {@code null}.
    608          * @see Way#getLength()
    609          */
    610         public static Float waylength(final Environment env) { // NO_UCD (unused code)
    611             if (env.osm instanceof Way) {
    612                 return (float) ((Way) env.osm).getLength();
    613             } else {
    614                 return null;
    615             }
    616         }
    617 
    618         /**
    619          * Function associated to the logical "!" operator.
    620          * @param b boolean value
    621          * @return {@code true} if {@code !b}
    622          */
    623         public static boolean not(boolean b) { // NO_UCD (unused code)
    624             return !b;
    625         }
    626 
    627         /**
    628          * Function associated to the logical "&gt;=" operator.
    629          * @param a first value
    630          * @param b second value
    631          * @return {@code true} if {@code a &gt;= b}
    632          */
    633         public static boolean greater_equal(float a, float b) { // NO_UCD (unused code)
    634             return a >= b;
    635         }
    636 
    637         /**
    638          * Function associated to the logical "&lt;=" operator.
    639          * @param a first value
    640          * @param b second value
    641          * @return {@code true} if {@code a &lt;= b}
    642          */
    643         public static boolean less_equal(float a, float b) { // NO_UCD (unused code)
    644             return a <= b;
    645         }
    646 
    647         /**
    648          * Function associated to the logical "&gt;" operator.
    649          * @param a first value
    650          * @param b second value
    651          * @return {@code true} if {@code a &gt; b}
    652          */
    653         public static boolean greater(float a, float b) { // NO_UCD (unused code)
    654             return a > b;
    655         }
    656 
    657         /**
    658          * Function associated to the logical "&lt;" operator.
    659          * @param a first value
    660          * @param b second value
    661          * @return {@code true} if {@code a &lt; b}
    662          */
    663         public static boolean less(float a, float b) { // NO_UCD (unused code)
    664             return a < b;
    665         }
    666 
    667         /**
    668          * Converts an angle in degrees to radians.
    669          * @param degree the angle in degrees
    670          * @return the angle in radians
    671          * @see Math#toRadians(double)
    672          */
    673         public static double degree_to_radians(double degree) { // NO_UCD (unused code)
    674             return Utils.toRadians(degree);
    675         }
    676 
    677         /**
    678          * Converts an angle diven in cardinal directions to radians.
    679          * The following values are supported: {@code n}, {@code north}, {@code ne}, {@code northeast},
    680          * {@code e}, {@code east}, {@code se}, {@code southeast}, {@code s}, {@code south},
    681          * {@code sw}, {@code southwest}, {@code w}, {@code west}, {@code nw}, {@code northwest}.
    682          * @param cardinal the angle in cardinal directions.
    683          * @return the angle in radians
    684          * @see RotationAngle#parseCardinalRotation(String)
    685          */
    686         public static Double cardinal_to_radians(String cardinal) { // NO_UCD (unused code)
    687             try {
    688                 return RotationAngle.parseCardinalRotation(cardinal);
    689             } catch (IllegalArgumentException ignore) {
    690                 Logging.trace(ignore);
    691                 return null;
    692             }
    693         }
    694 
    695         /**
    696          * Determines if the objects {@code a} and {@code b} are equal.
    697          * @param a First object
    698          * @param b Second object
    699          * @return {@code true} if objects are equal, {@code false} otherwise
    700          * @see Object#equals(Object)
    701          */
    702         public static boolean equal(Object a, Object b) {
    703             if (a.getClass() == b.getClass()) return a.equals(b);
    704             if (a.equals(Cascade.convertTo(b, a.getClass()))) return true;
    705             return b.equals(Cascade.convertTo(a, b.getClass()));
    706         }
    707 
    708         /**
    709          * Determines if the objects {@code a} and {@code b} are not equal.
    710          * @param a First object
    711          * @param b Second object
    712          * @return {@code false} if objects are equal, {@code true} otherwise
    713          * @see Object#equals(Object)
    714          */
    715         public static boolean not_equal(Object a, Object b) { // NO_UCD (unused code)
    716             return !equal(a, b);
    717         }
    718 
    719         /**
    720          * Determines whether the JOSM search with {@code searchStr} applies to the object.
    721          * @param env the environment
    722          * @param searchStr the search string
    723          * @return {@code true} if the JOSM search with {@code searchStr} applies to the object
    724          * @see SearchCompiler
    725          */
    726         public static Boolean JOSM_search(final Environment env, String searchStr) { // NO_UCD (unused code)
    727             Match m;
    728             try {
    729                 m = SearchCompiler.compile(searchStr);
    730             } catch (SearchParseError ex) {
    731                 Logging.trace(ex);
    732                 return null;
    733             }
    734             return m.match(env.osm);
    735         }
    736 
    737         /**
    738          * Obtains the JOSM'key {@link org.openstreetmap.josm.data.Preferences} string for key {@code key},
    739          * and defaults to {@code def} if that is null.
    740          * @param env the environment
    741          * @param key Key in JOSM preference
    742          * @param def Default value
    743          * @return value for key, or default value if not found
    744          */
    745         public static String JOSM_pref(Environment env, String key, String def) { // NO_UCD (unused code)
    746             return MapPaintStyles.getStyles().getPreferenceCached(key, def);
    747         }
    748 
    749         /**
    750          * Tests if string {@code target} matches pattern {@code pattern}
    751          * @param pattern The regex expression
    752          * @param target The character sequence to be matched
    753          * @return {@code true} if, and only if, the entire region sequence matches the pattern
    754          * @see Pattern#matches(String, CharSequence)
    755          * @since 5699
    756          */
    757         public static boolean regexp_test(String pattern, String target) { // NO_UCD (unused code)
    758             return Pattern.matches(pattern, target);
    759         }
    760 
    761         /**
    762          * Tests if string {@code target} matches pattern {@code pattern}
    763          * @param pattern The regex expression
    764          * @param target The character sequence to be matched
    765          * @param flags a string that may contain "i" (case insensitive), "m" (multiline) and "s" ("dot all")
    766          * @return {@code true} if, and only if, the entire region sequence matches the pattern
    767          * @see Pattern#CASE_INSENSITIVE
    768          * @see Pattern#DOTALL
    769          * @see Pattern#MULTILINE
    770          * @since 5699
    771          */
    772         public static boolean regexp_test(String pattern, String target, String flags) { // NO_UCD (unused code)
    773             int f = 0;
    774             if (flags.contains("i")) {
    775                 f |= Pattern.CASE_INSENSITIVE;
    776             }
    777             if (flags.contains("s")) {
    778                 f |= Pattern.DOTALL;
    779             }
    780             if (flags.contains("m")) {
    781                 f |= Pattern.MULTILINE;
    782             }
    783             return Pattern.compile(pattern, f).matcher(target).matches();
    784         }
    785 
    786         /**
    787          * Tries to match string against pattern regexp and returns a list of capture groups in case of success.
    788          * The first element (index 0) is the complete match (i.e. string).
    789          * Further elements correspond to the bracketed parts of the regular expression.
    790          * @param pattern The regex expression
    791          * @param target The character sequence to be matched
    792          * @param flags a string that may contain "i" (case insensitive), "m" (multiline) and "s" ("dot all")
    793          * @return a list of capture groups if {@link Matcher#matches()}, or {@code null}.
    794          * @see Pattern#CASE_INSENSITIVE
    795          * @see Pattern#DOTALL
    796          * @see Pattern#MULTILINE
    797          * @since 5701
    798          */
    799         public static List<String> regexp_match(String pattern, String target, String flags) { // NO_UCD (unused code)
    800             int f = 0;
    801             if (flags.contains("i")) {
    802                 f |= Pattern.CASE_INSENSITIVE;
    803             }
    804             if (flags.contains("s")) {
    805                 f |= Pattern.DOTALL;
    806             }
    807             if (flags.contains("m")) {
    808                 f |= Pattern.MULTILINE;
    809             }
    810             return Utils.getMatches(Pattern.compile(pattern, f).matcher(target));
    811         }
    812 
    813         /**
    814          * Tries to match string against pattern regexp and returns a list of capture groups in case of success.
    815          * The first element (index 0) is the complete match (i.e. string).
    816          * Further elements correspond to the bracketed parts of the regular expression.
    817          * @param pattern The regex expression
    818          * @param target The character sequence to be matched
    819          * @return a list of capture groups if {@link Matcher#matches()}, or {@code null}.
    820          * @since 5701
    821          */
    822         public static List<String> regexp_match(String pattern, String target) { // NO_UCD (unused code)
    823             return Utils.getMatches(Pattern.compile(pattern).matcher(target));
    824         }
    825 
    826         /**
    827          * Returns the OSM id of the current object.
    828          * @param env the environment
    829          * @return the OSM id of the current object
    830          * @see IPrimitive#getUniqueId()
    831          */
    832         public static long osm_id(final Environment env) { // NO_UCD (unused code)
    833             return env.osm.getUniqueId();
    834         }
    835 
    836         /**
    837          * Translates some text for the current locale. The first argument is the text to translate,
    838          * and the subsequent arguments are parameters for the string indicated by <code>{0}</code>, <code>{1}</code>, …
    839          * @param args arguments
    840          * @return the translated string
    841          */
    842         @NullableArguments
    843         public static String tr(String... args) { // NO_UCD (unused code)
    844             final String text = args[0];
    845             System.arraycopy(args, 1, args, 0, args.length - 1);
    846             return org.openstreetmap.josm.tools.I18n.tr(text, (Object[]) args);
    847         }
    848 
    849         /**
    850          * Returns the substring of {@code s} starting at index {@code begin} (inclusive, 0-indexed).
    851          * @param s The base string
    852          * @param begin The start index
    853          * @return the substring
    854          * @see String#substring(int)
    855          */
    856         public static String substring(String s, /* due to missing Cascade.convertTo for int*/ float begin) { // NO_UCD (unused code)
    857             return s == null ? null : s.substring((int) begin);
    858         }
    859 
    860         /**
    861          * Returns the substring of {@code s} starting at index {@code begin} (inclusive)
    862          * and ending at index {@code end}, (exclusive, 0-indexed).
    863          * @param s The base string
    864          * @param begin The start index
    865          * @param end The end index
    866          * @return the substring
    867          * @see String#substring(int, int)
    868          */
    869         public static String substring(String s, float begin, float end) { // NO_UCD (unused code)
    870             return s == null ? null : s.substring((int) begin, (int) end);
    871         }
    872 
    873         /**
    874          * Replaces in {@code s} every {@code} target} substring by {@code replacement}.
    875          * @param s The source string
    876          * @param target The sequence of char values to be replaced
    877          * @param replacement The replacement sequence of char values
    878          * @return The resulting string
    879          * @see String#replace(CharSequence, CharSequence)
    880          */
    881         public static String replace(String s, String target, String replacement) { // NO_UCD (unused code)
    882             return s == null ? null : s.replace(target, replacement);
    883         }
    884 
    885         /**
    886          * Converts string {@code s} to uppercase.
    887          * @param s The source string
    888          * @return The resulting string
    889          * @see String#toUpperCase(Locale)
    890          * @since 11756
    891          */
    892         public static String upper(String s) {
    893             return s == null ? null : s.toUpperCase(Locale.ENGLISH);
    894         }
    895 
    896         /**
    897          * Converts string {@code s} to lowercase.
    898          * @param s The source string
    899          * @return The resulting string
    900          * @see String#toLowerCase(Locale)
    901          * @since 11756
    902          */
    903         public static String lower(String s) {
    904             return s == null ? null : s.toLowerCase(Locale.ENGLISH);
    905         }
    906 
    907         /**
    908          * Trim whitespaces from the string {@code s}.
    909          * @param s The source string
    910          * @return The resulting string
    911          * @see Utils#strip
    912          * @since 11756
    913          */
    914         public static String trim(String s) {
    915             return Utils.strip(s);
    916         }
    917 
    918         /**
    919          * Check if two strings are similar, but not identical, i.e., have a Levenshtein distance of 1 or 2.
    920          * @param string1 first string to compare
    921          * @param string2 second string to compare
    922          * @return true if the normalized strings are different but only a "little bit"
    923          * @see Utils#isSimilar
    924          * @since 14371
    925          */
    926         public static boolean is_similar(String string1, String string2) {
    927             return Utils.isSimilar(string1, string2);
    928         }
    929 
    930         /**
    931          * Percent-decode a string. (See https://en.wikipedia.org/wiki/Percent-encoding)
    932          * This is especially useful for wikipedia titles
    933          * @param s url-encoded string
    934          * @return the decoded string, or original in case of an error
    935          * @since 11756
    936          */
    937         public static String URL_decode(String s) {
    938             if (s == null) return null;
    939             try {
    940                 return Utils.decodeUrl(s);
    941             } catch (IllegalStateException e) {
    942                 Logging.debug(e);
    943                 return s;
    944             }
    945         }
    946 
    947         /**
    948          * Percent-encode a string. (See https://en.wikipedia.org/wiki/Percent-encoding)
    949          * This is especially useful for data urls, e.g.
    950          * <code>concat("data:image/svg+xml,", URL_encode("&lt;svg&gt;...&lt;/svg&gt;"));</code>
    951          * @param s arbitrary string
    952          * @return the encoded string
    953          */
    954         public static String URL_encode(String s) { // NO_UCD (unused code)
    955             return s == null ? null : Utils.encodeUrl(s);
    956         }
    957 
    958         /**
    959          * XML-encode a string.
    960          *
    961          * Escapes special characters in xml. Alternative to using &lt;![CDATA[ ... ]]&gt; blocks.
    962          * @param s arbitrary string
    963          * @return the encoded string
    964          */
    965         public static String XML_encode(String s) { // NO_UCD (unused code)
    966             return s == null ? null : XmlWriter.encode(s);
    967         }
    968 
    969         /**
    970          * Calculates the CRC32 checksum from a string (based on RFC 1952).
    971          * @param s the string
    972          * @return long value from 0 to 2^32-1
    973          */
    974         public static long CRC32_checksum(String s) { // NO_UCD (unused code)
    975             CRC32 cs = new CRC32();
    976             cs.update(s.getBytes(StandardCharsets.UTF_8));
    977             return cs.getValue();
    978         }
    979 
    980         /**
    981          * check if there is right-hand traffic at the current location
    982          * @param env the environment
    983          * @return true if there is right-hand traffic
    984          * @since 7193
    985          */
    986         public static boolean is_right_hand_traffic(Environment env) {
    987             return RightAndLefthandTraffic.isRightHandTraffic(center(env));
    988         }
    989 
    990         /**
    991          * Determines whether the way is {@link Geometry#isClockwise closed and oriented clockwise},
    992          * or non-closed and the {@link Geometry#angleIsClockwise 1st, 2nd and last node are in clockwise order}.
    993          *
    994          * @param env the environment
    995          * @return true if the way is closed and oriented clockwise
    996          */
    997         public static boolean is_clockwise(Environment env) {
    998             if (!(env.osm instanceof Way)) {
    999                 return false;
    1000             }
    1001             final Way way = (Way) env.osm;
    1002             return (way.isClosed() && Geometry.isClockwise(way))
    1003                 || (!way.isClosed() && way.getNodesCount() > 2 && Geometry.angleIsClockwise(way.getNode(0), way.getNode(1), way.lastNode()));
    1004         }
    1005 
    1006         /**
    1007          * Determines whether the way is {@link Geometry#isClockwise closed and oriented anticlockwise},
    1008          * or non-closed and the {@link Geometry#angleIsClockwise 1st, 2nd and last node are in anticlockwise order}.
    1009          *
    1010          * @param env the environment
    1011          * @return true if the way is closed and oriented clockwise
    1012          */
    1013         public static boolean is_anticlockwise(Environment env) {
    1014             if (!(env.osm instanceof Way)) {
    1015                 return false;
    1016             }
    1017             final Way way = (Way) env.osm;
    1018             return (way.isClosed() && !Geometry.isClockwise(way))
    1019                 || (!way.isClosed() && way.getNodesCount() > 2 && !Geometry.angleIsClockwise(way.getNode(0), way.getNode(1), way.lastNode()));
    1020         }
    1021 
    1022         /**
    1023          * Prints the object to the command line (for debugging purpose).
    1024          * @param o the object
    1025          * @return the same object, unchanged
    1026          */
    1027         @NullableArguments
    1028         public static Object print(Object o) { // NO_UCD (unused code)
    1029             System.out.print(o == null ? "none" : o.toString());
    1030             return o;
    1031         }
    1032 
    1033         /**
    1034          * Prints the object to the command line, with new line at the end
    1035          * (for debugging purpose).
    1036          * @param o the object
    1037          * @return the same object, unchanged
    1038          */
    1039         @NullableArguments
    1040         public static Object println(Object o) { // NO_UCD (unused code)
    1041             System.out.println(o == null ? "none" : o.toString());
    1042             return o;
    1043         }
    1044 
    1045         /**
    1046          * Get the number of tags for the current primitive.
    1047          * @param env the environment
    1048          * @return number of tags
    1049          */
    1050         public static int number_of_tags(Environment env) { // NO_UCD (unused code)
    1051             return env.osm.getNumKeys();
    1052         }
    1053 
    1054         /**
    1055          * Get value of a setting.
    1056          * @param env the environment
    1057          * @param key setting key (given as layer identifier, e.g. setting::mykey {...})
    1058          * @return the value of the setting (calculated when the style is loaded)
    1059          */
    1060         public static Object setting(Environment env, String key) { // NO_UCD (unused code)
    1061             return env.source.settingValues.get(key);
    1062         }
    1063 
    1064         /**
    1065          * Returns the center of the environment OSM primitive.
    1066          * @param env the environment
    1067          * @return the center of the environment OSM primitive
    1068          * @since 11247
    1069          */
    1070         public static LatLon center(Environment env) { // NO_UCD (unused code)
    1071             return env.osm instanceof Node ? ((Node) env.osm).getCoor() : env.osm.getBBox().getCenter();
    1072         }
    1073 
    1074         /**
    1075          * Determines if the object is inside territories matching given ISO3166 codes.
    1076          * @param env the environment
    1077          * @param codes comma-separated list of ISO3166-1-alpha2 or ISO3166-2 country/subdivision codes
    1078          * @return {@code true} if the object is inside territory matching given ISO3166 codes
    1079          * @since 11247
    1080          */
    1081         public static boolean inside(Environment env, String codes) { // NO_UCD (unused code)
    1082             for (String code : codes.toUpperCase(Locale.ENGLISH).split(",")) {
    1083                 if (Territories.isIso3166Code(code.trim(), center(env))) {
    1084                     return true;
    1085                 }
    1086             }
    1087             return false;
    1088         }
    1089 
    1090         /**
    1091          * Determines if the object is outside territories matching given ISO3166 codes.
    1092          * @param env the environment
    1093          * @param codes comma-separated list of ISO3166-1-alpha2 or ISO3166-2 country/subdivision codes
    1094          * @return {@code true} if the object is outside territory matching given ISO3166 codes
    1095          * @since 11247
    1096          */
    1097         public static boolean outside(Environment env, String codes) { // NO_UCD (unused code)
    1098             return !inside(env, codes);
    1099         }
    1100 
    1101         /**
    1102          * Determines if the object centroid lies at given lat/lon coordinates.
    1103          * @param env the environment
    1104          * @param lat latitude, i.e., the north-south position in degrees
    1105          * @param lon longitude, i.e., the east-west position in degrees
    1106          * @return {@code true} if the object centroid lies at given lat/lon coordinates
    1107          * @since 12514
    1108          */
    1109         public static boolean at(Environment env, double lat, double lon) { // NO_UCD (unused code)
    1110             return new LatLon(lat, lon).equalsEpsilon(center(env));
    1111         }
    1112     }
    1113 
    1114     /**
    111586     * Main method to create an function-like expression.
    111687     *
  • trunk/test/unit/org/openstreetmap/josm/gui/mappaint/mapcss/ExpressionFactoryTest.java

    r11921 r15245  
    44import org.junit.Rule;
    55import org.junit.Test;
    6 import org.openstreetmap.josm.gui.mappaint.mapcss.ExpressionFactory.Functions;
    76import org.openstreetmap.josm.testutils.JOSMTestRules;
    87
  • trunk/test/unit/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSParserTest.java

    r15196 r15245  
    422422        /* Check with empty role and one object */
    423423        Environment e = new Environment(rel1, new MultiCascade(), Environment.DEFAULT_LAYER, null);
    424         assertEquals(1, ExpressionFactory.Functions.count_roles(e, ""));
     424        assertEquals(1, Functions.count_roles(e, ""));
    425425
    426426        /* Check with non-empty role and one object */
    427427        e = new Environment(rel1, new MultiCascade(), Environment.DEFAULT_LAYER, null);
    428         assertEquals(0, ExpressionFactory.Functions.count_roles(e, "from"));
     428        assertEquals(0, Functions.count_roles(e, "from"));
    429429
    430430        /* Check with empty role and two objects */
     
    433433        rel1.addMember(new RelationMember("", way2));
    434434        e = new Environment(rel1, new MultiCascade(), Environment.DEFAULT_LAYER, null);
    435         assertEquals(2, ExpressionFactory.Functions.count_roles(e, ""));
     435        assertEquals(2, Functions.count_roles(e, ""));
    436436
    437437        /* Check with non-empty role and two objects */
    438438        rel1.setMember(0, new RelationMember("from", way1));
    439439        e = new Environment(rel1, new MultiCascade(), Environment.DEFAULT_LAYER, null);
    440         assertEquals(1, ExpressionFactory.Functions.count_roles(e, "from"));
     440        assertEquals(1, Functions.count_roles(e, "from"));
    441441
    442442        /* Check with multiple roles */
    443         assertEquals(1, ExpressionFactory.Functions.count_roles(e, "from", "to"));
     443        assertEquals(1, Functions.count_roles(e, "from", "to"));
    444444
    445445        /* Check with non-relation */
    446446        e = new Environment(way1, new MultiCascade(), Environment.DEFAULT_LAYER, null);
    447         assertEquals(0, ExpressionFactory.Functions.count_roles(e, "from", "to"));
     447        assertEquals(0, Functions.count_roles(e, "from", "to"));
    448448    }
    449449
Note: See TracChangeset for help on using the changeset viewer.