Ticket #7178: SearchCompiler.java.patch

File SearchCompiler.java.patch, 4.2 KB (added by joshdoe, 9 years ago)

add ability for plugins to register search match operators

  • src/org/openstreetmap/josm/actions/search/SearchCompiler.java

     
    66
    77import java.io.PushbackReader;
    88import java.io.StringReader;
     9import java.lang.reflect.Constructor;
     10import java.lang.reflect.InvocationTargetException;
    911import java.text.Normalizer;
    1012import java.util.Collection;
    1113import java.util.Date;
     14import java.util.HashMap;
     15import java.util.logging.Level;
     16import java.util.logging.Logger;
    1217import java.util.regex.Matcher;
    1318import java.util.regex.Pattern;
    1419import java.util.regex.PatternSyntaxException;
     
    5459    private static String  rxErrorMsg = marktr("The regex \"{0}\" had a parse error at offset {1}, full error:\n\n{2}");
    5560    private static String  rxErrorMsgNoPos = marktr("The regex \"{0}\" had a parse error, full error:\n\n{1}");
    5661    private PushbackTokenizer tokenizer;
     62    private static HashMap<String, Class<? extends PluginMatch>> pluginMatches = new HashMap<String, Class<? extends PluginMatch>>();
    5763
    5864    public SearchCompiler(boolean caseSensitive, boolean regexSearch, PushbackTokenizer tokenizer) {
    5965        this.caseSensitive = caseSensitive;
     
    8793        }
    8894    }
    8995
     96    abstract public static class PluginMatch extends Match {
     97        /* Returns the desired keyword for this search (may be modified, e.g. by
     98         * appending "2" if the keyword is already registered)
     99         * FIXME: should core notify plugin of keyword actually used?
     100         */
     101        abstract public String getKeyword();
     102       
     103        /* Returns a short description, possibly shown in the search dialog */
     104        abstract public String getDescription();
     105       
     106        @Override public String toString() {return getKeyword();}
     107    }
     108
    90109    public static class Always extends Match {
    91110        public static Always INSTANCE = new Always();
    92111        @Override public boolean match(OsmPrimitive osm) {
     
    944963                return new InView(false);
    945964            else if ("allinview".equals(key))
    946965                return new InView(true);
    947             else
    948                 return new Any(key, regexSearch, caseSensitive);
     966            else {
     967                if (pluginMatches.containsKey(key)) {
     968                    PluginMatch match = null;
     969                    try {
     970                        Constructor ctor = pluginMatches.get(key).getDeclaredConstructor((Class[]) null);
     971                        match = (PluginMatch)ctor.newInstance();
     972                    } catch (InstantiationException ex) {
     973                        Logger.getLogger(SearchCompiler.class.getName()).log(Level.SEVERE, null, ex);
     974                    } catch (IllegalAccessException ex) {
     975                        Logger.getLogger(SearchCompiler.class.getName()).log(Level.SEVERE, null, ex);
     976                    } catch (IllegalArgumentException ex) {
     977                        Logger.getLogger(SearchCompiler.class.getName()).log(Level.SEVERE, null, ex);
     978                    } catch (InvocationTargetException ex) {
     979                        Logger.getLogger(SearchCompiler.class.getName()).log(Level.SEVERE, null, ex);
     980                    } catch (NoSuchMethodException ex) {
     981                        Logger.getLogger(SearchCompiler.class.getName()).log(Level.SEVERE, null, ex);
     982                    } catch (SecurityException ex) {
     983                        Logger.getLogger(SearchCompiler.class.getName()).log(Level.SEVERE, null, ex);
     984                    }
     985                    if (match == null)
     986                        throw new ParseError("Failed to use plugin for keyword: " + key);
     987                    return match;
     988                }
     989                else
     990                    return new Any(key, regexSearch, caseSensitive);
     991            }
    949992        } else
    950993            return null;
    951994    }
     
    9941037
    9951038        return searchFlags;
    9961039    }
     1040   
     1041    public static void addPluginMatch(String keyword, Class<? extends PluginMatch> pm) {
     1042        /* TODO: check for keyword clashes, append incrementing number to new keyword */
     1043        pluginMatches.put(keyword, pm);
     1044    }
    9971045}