Changeset 1641 in josm


Ignore:
Timestamp:
Jun 6, 2009 2:37:14 PM (4 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.