Changeset 1641 in josm for trunk/src/org/openstreetmap


Ignore:
Timestamp:
2009-06-06T14:37:14+02:00 (15 years ago)
Author:
stoecker
Message:

fix #2673 - patch by jttt - key=value operator for search action

Location:
trunk/src/org/openstreetmap/josm/actions/search
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/actions/search/PushbackTokenizer.java

    r1169 r1641  
    4040            switch (c) {
    4141            case ':':
     42            case '=':
    4243                next = search.read();
    43                 c = (char) next;
    44                 if (next == -1 || c == ' ' || c == '\t') {
     44                if (next == -1 || next == ' ' || next == '\t') {
    4545                    pushBack(" ");
    4646                } else {
    4747                    search.unread(next);
    4848                }
    49                 return ":";
     49                return String.valueOf(c);
    5050            case '-':
    5151                return "-";
     
    7272                }
    7373                c = (char)next;
    74                 if (c == ' ' || c == '\t' || c == '"' || c == ':' || c == '(' || c == ')' || c == '|') {
     74                if (c == ' ' || c == '\t' || c == '"' || c == ':' || c == '(' || c == ')' || c == '|' || c == '=') {
    7575                    search.unread(next);
    7676                    if (s.toString().equals("OR"))
  • trunk/src/org/openstreetmap/josm/actions/search/SearchAction.java

    r1603 r1641  
    44import static org.openstreetmap.josm.tools.I18n.tr;
    55
     6import java.awt.Font;
    67import java.awt.GridBagLayout;
    78import java.awt.event.ActionEvent;
     
    7980
    8081        JPanel right = new JPanel();
    81         right.add(new JLabel("<html><ul>"
     82        JLabel description =
     83        new JLabel("<html><ul>"
    8284                + "<li>"+tr("<b>Baker Street</b> - 'Baker' and 'Street' in any key or name.")+"</li>"
    8385                + "<li>"+tr("<b>\"Baker Street\"</b> - 'Baker Street' in any key or name.")+"</li>"
    8486                + "<li>"+tr("<b>name:Bak</b> - 'Bak' anywhere in the name.")+"</li>"
     87                + "<li>"+tr("<b>type=route</b> - key 'type' with value exactly 'route'.") + "</li>"
     88                + "<li>"+tr("<b>type=*</b> - key 'type' with any value. Try also <b>*=value</b>, <b>type=</b>, <b>*=*</b>, <b>*=</b>") + "</li>"
    8589                + "<li>"+tr("<b>-name:Bak</b> - not 'Bak' in the name.")+"</li>"
    8690                + "<li>"+tr("<b>foot:</b> - key=foot set to any value.")+"</li>"
     
    99103                + "<li>"+tr("Use <b>\"</b> to quote operators (e.g. if key contains :)")+"</li>"
    100104                + "<li>"+tr("Use <b>(</b> and <b>)</b> to group expressions")+"</li>"
    101                 + "</ul></html>"));
     105                + "</ul></html>");
     106        description.setFont(description.getFont().deriveFont(Font.PLAIN));
     107        right.add(description);
    102108
    103109        final JPanel p = new JPanel();
  • trunk/src/org/openstreetmap/josm/actions/search/SearchCompiler.java

    r1625 r1641  
    153153        }
    154154        @Override public String toString() {return key+"="+value;}
     155    }
     156
     157    private static class ExactKeyValue extends Match {
     158
     159        private enum Mode {
     160            ANY, ANY_KEY, ANY_VALUE, EXACT, NONE, MISSING_KEY,
     161            ANY_KEY_REGEXP, ANY_VALUE_REGEXP, EXACT_REGEXP, MISSING_KEY_REGEXP;
     162        }
     163
     164        private final String key;
     165        private final String value;
     166        private final Pattern keyPattern;
     167        private final Pattern valuePattern;
     168        private final Mode mode;
     169
     170        public ExactKeyValue(boolean regexp, String key, String value) throws ParseError {
     171            if (key == "") {
     172                throw new ParseError(tr("Key cannot be empty when tag operator is used. Sample use: key=value"));
     173            }
     174            this.key = key;
     175            this.value = value;
     176            if ("".equals(value) && "*".equals(key)) {
     177                mode = Mode.NONE;
     178            } else if ("".equals(value)) {
     179                if (regexp) {
     180                    mode = Mode.MISSING_KEY_REGEXP;
     181                } else {
     182                    mode = Mode.MISSING_KEY;
     183                }
     184            } else if ("*".equals(key) && "*".equals(value)) {
     185                mode = Mode.ANY;
     186            } else if ("*".equals(key)) {
     187                if (regexp) {
     188                    mode = Mode.ANY_KEY_REGEXP;
     189                } else {
     190                    mode = Mode.ANY_KEY;
     191                }
     192            } else if ("*".equals(value)) {
     193                if (regexp) {
     194                    mode = Mode.ANY_VALUE_REGEXP;
     195                } else {
     196                    mode = Mode.ANY_VALUE;
     197                }
     198            } else {
     199                if (regexp) {
     200                    mode = Mode.EXACT_REGEXP;
     201                } else {
     202                    mode = Mode.EXACT;
     203                }
     204            }
     205
     206            if (regexp && key.length() > 0 && !key.equals("*")) {
     207                keyPattern = Pattern.compile(key);
     208            } else {
     209                keyPattern = null;
     210            }
     211            if (regexp && value.length() > 0 && !value.equals("*")) {
     212                valuePattern = Pattern.compile(value);
     213            } else {
     214                valuePattern = null;
     215            }
     216        }
     217
     218        @Override
     219        public boolean match(OsmPrimitive osm) throws ParseError {
     220
     221            if (osm.keys == null || osm.keys.isEmpty()) {
     222                return mode == Mode.NONE;
     223            }
     224
     225            switch (mode) {
     226            case NONE:
     227                return false;
     228            case MISSING_KEY:
     229                return osm.get(key) == null;
     230            case ANY:
     231                return true;
     232            case ANY_VALUE:
     233                return osm.get(key) != null;
     234            case ANY_KEY:
     235                for (String v:osm.keys.values()) {
     236                    if (v.equals(value)) {
     237                        return true;
     238                    }
     239                }
     240                return false;
     241            case EXACT:
     242                return value.equals(osm.get(key));
     243            case ANY_KEY_REGEXP:
     244                for (String v:osm.keys.values()) {
     245                    if (valuePattern.matcher(v).matches()) {
     246                        return true;
     247                    }
     248                }
     249                return false;
     250            case ANY_VALUE_REGEXP:
     251            case EXACT_REGEXP:
     252                for (Entry<String, String> entry:osm.keys.entrySet()) {
     253                    if (keyPattern.matcher(entry.getKey()).matches()) {
     254                        if (mode == Mode.ANY_VALUE_REGEXP
     255                                || valuePattern.matcher(entry.getValue()).matches()) {
     256                            return true;
     257                        }
     258                    }
     259                }
     260                return false;
     261            case MISSING_KEY_REGEXP:
     262                for (String k:osm.keys.keySet()) {
     263                    if (keyPattern.matcher(k).matches()) {
     264                        return false;
     265                    }
     266                }
     267                return true;
     268            }
     269            throw new AssertionError("Missed state");
     270        }
     271
     272        @Override
     273        public String toString() {
     274            return key + '=' + value;
     275        }
     276
    155277    }
    156278
     
    369491        Match m = parseJuxta();
    370492        if (!tokenizer.readIfEqual(null)) {
    371             throw new ParseError("Unexpected token: " + tokenizer.nextToken());
     493            throw new ParseError(tr("Unexpected token: {0}", tokenizer.nextToken()));
    372494        }
    373495        return m;
     
    427549            if (tok2 == null) tok2 = "";
    428550            return parseKV(tok, tok2);
     551        }
     552
     553        if (tokenizer.readIfEqual("=")) {
     554            String tok2 = tokenizer.readText();
     555            if (tok == null) tok = "";
     556            if (tok2 == null) tok2 = "";
     557            return new ExactKeyValue(regexSearch, tok, tok2);
    429558        }
    430559
Note: See TracChangeset for help on using the changeset viewer.