Author: sshafroi
Date: 2008-06-05 17:41:34 +0200 (Thu, 05 Jun 2008)
New Revision: 6676

Added:
   trunk/util/
   trunk/util/pom.xml
   trunk/util/src/
   trunk/util/src/main/
   trunk/util/src/main/java/
   trunk/util/src/main/java/no/
   trunk/util/src/main/java/no/sesat/
   trunk/util/src/main/java/no/sesat/Interpreter.java
Modified:
   trunk/pom.xml
   trunk/search-command-config-spi/pom.xml
   
trunk/search-command-config-spi/src/main/java/no/sesat/search/mode/SearchModeFactory.java
   
trunk/search-command-config-spi/src/main/java/no/sesat/search/mode/config/AbstractSearchConfiguration.java
Log:
Issue SKER4768: (Interpreter for debuging and inspection help)

Modified: trunk/pom.xml
===================================================================
--- trunk/pom.xml       2008-06-05 13:15:27 UTC (rev 6675)
+++ trunk/pom.xml       2008-06-05 15:41:34 UTC (rev 6676)
@@ -136,6 +136,7 @@
         <!-- sitemap-generator must be after 
generic.sesam-search-command-control because they both use assembly -->
         <module>sitemap-generator</module>
         <module>war</module>
+        <module>util</module>
     </modules>
 
     <build>

Modified: trunk/search-command-config-spi/pom.xml
===================================================================
--- trunk/search-command-config-spi/pom.xml     2008-06-05 13:15:27 UTC (rev 
6675)
+++ trunk/search-command-config-spi/pom.xml     2008-06-05 15:41:34 UTC (rev 
6676)
@@ -65,6 +65,11 @@
             <artifactId>sesat-run-transform-config-spi</artifactId>
             <version>${sesat.version}</version>
         </dependency>
+        <dependency>
+            <groupId>sesat</groupId>
+            <artifactId>sesat-util</artifactId>
+            <version>${sesat.version}</version>
+        </dependency>
     </dependencies>
 
-</project>
\ No newline at end of file
+</project>

Modified: 
trunk/search-command-config-spi/src/main/java/no/sesat/search/mode/SearchModeFactory.java
===================================================================
--- 
trunk/search-command-config-spi/src/main/java/no/sesat/search/mode/SearchModeFactory.java
   2008-06-05 13:15:27 UTC (rev 6675)
+++ 
trunk/search-command-config-spi/src/main/java/no/sesat/search/mode/SearchModeFactory.java
   2008-06-05 15:41:34 UTC (rev 6676)
@@ -18,6 +18,7 @@
 package no.sesat.search.mode;
 
 
+import no.sesat.Interpreter;
 import no.sesat.search.run.transform.RunTransformerConfig;
 import no.sesat.search.site.config.AbstractConfigFactory;
 import no.schibstedsok.commons.ioc.ContextWrapper;
@@ -622,4 +623,31 @@
             return clazz;
         }
     }
+
+
+    static {
+        Interpreter.addFunction("commands", new Interpreter.Function() {
+            public String execute(Interpreter.Context ctx) {
+                String res = "";
+                COMMANDS_LOCK.readLock().lock();
+                try {
+                    for (SearchMode c : COMMANDS.keySet()) {
+                        res += "Mode: " + c + "\n";
+                        for (String s : COMMANDS.get(c).keySet()) {
+                            res += "   " + COMMANDS.get(c).get(s).toString() + 
"\n";
+                        }
+                        res += "\n";
+                    }
+                }
+                finally {
+                    COMMANDS_LOCK.readLock().unlock();
+                }
+                return res;
+
+            }
+            public String describe() {
+                return "Print out the SearchModes in COMMANDS.";
+            }
+        });
+    }
 }

Modified: 
trunk/search-command-config-spi/src/main/java/no/sesat/search/mode/config/AbstractSearchConfiguration.java
===================================================================
--- 
trunk/search-command-config-spi/src/main/java/no/sesat/search/mode/config/AbstractSearchConfiguration.java
  2008-06-05 13:15:27 UTC (rev 6675)
+++ 
trunk/search-command-config-spi/src/main/java/no/sesat/search/mode/config/AbstractSearchConfiguration.java
  2008-06-05 15:41:34 UTC (rev 6676)
@@ -20,6 +20,9 @@
 import java.lang.reflect.Method;
 import java.util.*;
 
+import no.sesat.Interpreter;
+import no.sesat.Interpreter.Context;
+
 import org.apache.log4j.Logger;
 import org.w3c.dom.Element;
 import org.w3c.dom.NamedNodeMap;
@@ -33,33 +36,38 @@
     private static final String[] setters = {"set", "add"};
 
     /**
-     * This method will be called before settings from the modes.xml files 
will be applied.
-     * Default implementation is empty.
+     * This method will be called before settings from the modes.xml files will
+     * be applied. Default implementation is empty.
      *
-     * @param element The xml element where the attribues are found.
-     * @param inherit The configuration that we inherit from.
+     * @param element
+     *            The xml element where the attribues are found.
+     * @param inherit
+     *            The configuration that we inherit from.
      */
     protected void readSearchConfigurationBefore(final Element element, final 
SearchConfiguration inherit) {
 
     }
 
     /**
-     * This method will be called after settings from the modes.xml files will 
be applied.
-     * Default implementation is empty.
+     * This method will be called after settings from the modes.xml files will
+     * be applied. Default implementation is empty.
      *
-     * @param element The xml element where the attribues are found.
-     * @param inherit The configuration that we inherit from.
+     * @param element
+     *            The xml element where the attribues are found.
+     * @param inherit
+     *            The configuration that we inherit from.
      */
     protected void readSearchConfigurationAfter(final Element element, final 
SearchConfiguration inherit) {
 
     }
 
-
     /**
      * This method will apply the attributes found in element.
      *
-     * @param element The xml element where the attribues are found.
-     * @param inherit The configuration that we inherit from.
+     * @param element
+     *            The xml element where the attribues are found.
+     * @param inherit
+     *            The configuration that we inherit from.
      */
     public final void readSearchConfiguration(final Element element, final 
SearchConfiguration inherit) {
         readSearchConfigurationBefore(element, inherit);
@@ -98,7 +106,7 @@
     }
 
     private static boolean startsWith(String string, String[] prefixes) {
-        for( String p : prefixes) {
+        for (String p : prefixes) {
             if (string.startsWith(p))
                 return true;
         }
@@ -131,7 +139,9 @@
                 if (paramTypes.length == 1) {
                     MethodWrapper.Type type = 
MethodWrapper.getType(paramTypes[0]);
                     if (type == MethodWrapper.Type.Unsupported) {
-                        LOG.trace("Unsupported type for: " + name + " " + 
method.getParameterTypes()[0].getSimpleName());
+                        LOG
+                                .trace("Unsupported type for: " + name + " "
+                                        + 
method.getParameterTypes()[0].getSimpleName());
                     } else {
 
                         if (!methodMap.containsKey(name)) {
@@ -188,8 +198,7 @@
 
         if (method != null) {
             if (!method.setValue(this, value)) {
-                LOG.error("Setting value on " + getClass().getSimpleName() + " 
" + name + "==" + value
-                        + " failed.");
+                LOG.error("Setting value on " + getClass().getSimpleName() + " 
" + name + "==" + value + " failed.");
             }
         } else {
             LOG.error("Setting value on " + getClass().getSimpleName() + " " + 
name + "==" + value
@@ -207,7 +216,7 @@
     private static MethodWrapper getMethodWrapper(Class klass, final String 
name, final String[] pre) {
         Map<String, MethodWrapper> map = getMethodMap(klass);
         while (map != null) {
-            for(String s : pre) {
+            for (String s : pre) {
                 String g = s + name.substring(0, 1).toUpperCase() + 
name.substring(1);
                 if (map.containsKey(g)) {
                     return map.get(g);
@@ -223,11 +232,11 @@
         String res = getClass().getSimpleName() + " ";
         Set<String> methods = getMethodNames(getters);
         for (String s : methods) {
-            res += s + " == ";
+            res += s + "==";
             Object o = getAttribute(this, s);
             if (o instanceof String[]) {
                 res += "[";
-                for (String a : (String[])o) {
+                for (String a : (String[]) o) {
                     res += "\"" + a + "\" ";
                 }
                 res += "] ";
@@ -240,8 +249,6 @@
         return res;
     }
 
-
-
     /**
      * Helper class to encapsulate a method.
      */
@@ -263,33 +270,33 @@
             if (value instanceof String) {
                 String valueString = (String) value;
                 switch (type) {
-                    case String:
-                        break;
-                    case StringArray:
-                        value = valueString.split(",");
-                        break;
-                    case Integer:
-                        value = Integer.parseInt(valueString);
-                        break;
-                    case Boolean:
-                        value = Boolean.parseBoolean(valueString);
-                        break;
-                    case Char:
-                        value = valueString.charAt(0);
-                        if (valueString.length() > 1)
-                            LOG.error("Setting char attribute where input was 
more then a character long");
-                        break;
-                    default:
-                        LOG.error("Failed to set attribute " + 
method.getName() + ", unnsuported type.");
-                        return false;
-                    }
-                }
-                try {
-                    method.invoke(obj, value);
-                } catch (Exception e) {
-                    LOG.info("Failed to set attribute with name: " + 
method.getName() + "(" + type + ").");
+                case String:
+                    break;
+                case StringArray:
+                    value = valueString.split(",");
+                    break;
+                case Integer:
+                    value = Integer.parseInt(valueString);
+                    break;
+                case Boolean:
+                    value = Boolean.parseBoolean(valueString);
+                    break;
+                case Char:
+                    value = valueString.charAt(0);
+                    if (valueString.length() > 1)
+                        LOG.error("Setting char attribute where input was more 
then a character long");
+                    break;
+                default:
+                    LOG.error("Failed to set attribute " + method.getName() + 
", unnsuported type.");
                     return false;
                 }
+            }
+            try {
+                method.invoke(obj, value);
+            } catch (Exception e) {
+                LOG.info("Failed to set attribute with name: " + 
method.getName() + "(" + type + ").");
+                return false;
+            }
             return true;
         }
 
@@ -297,7 +304,8 @@
             try {
                 return method.invoke(obj);
             } catch (Exception e) {
-                LOG.error("Failed to get attribute with name: " + type + " " + 
method.getName() + "(). " + e.getMessage(), e);
+                LOG.error("Failed to get attribute with name: " + type + " " + 
method.getName() + "(). "
+                        + e.getMessage(), e);
             }
             return null;
         }
@@ -320,6 +328,33 @@
                 type = MethodWrapper.Type.Unsupported;
             return type;
         }
+
+        public String toString() {
+            return method.getName() + " Type: " + type;
+        }
     }
+
+    /**
+     * Add some debug function to the interpreter.
+     */
+    static {
+        Interpreter.addFunction("scmap", new Interpreter.Function() {
+            public String execute(Context ctx) {
+                String res = "";
+                for (Class c : ClassMethodMap.keySet()) {
+                    res += "CLASS: " + c.getSimpleName() + "\n";
+                    for (String s : ClassMethodMap.get(c).keySet()) {
+                        res += "   " + ClassMethodMap.get(c).get(s).toString() 
+ "\n";
+                    }
+                    res += "\n";
+                }
+                return res;
+            }
+
+            public String describe() {
+                return "Print out the ClassMethodMap cache in 
AbstractSearchConfiguration.";
+            }
+
+        });
+    }
 }
-

Added: trunk/util/pom.xml
===================================================================
--- trunk/util/pom.xml                          (rev 0)
+++ trunk/util/pom.xml  2008-06-05 15:41:34 UTC (rev 6676)
@@ -0,0 +1,22 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/maven-v4_0_0.xsd";>
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>sesat</groupId>
+        <artifactId>sesat-kernel</artifactId>
+        <version>2.18-SNAPSHOT</version>
+    </parent>
+    <artifactId>sesat-util</artifactId>
+    <packaging>jar</packaging>
+    <name>Sesat Util</name>
+    <description>
+        This is the Sesam Search Application Toolkit. Aka Sesat.
+        Read http://sesat.no/development-guidelines.html for developing help.
+    </description>
+
+    <dependencies>
+        <dependency>
+            <groupId>log4j</groupId>
+            <artifactId>log4j</artifactId>
+        </dependency>
+    </dependencies>
+</project>

Added: trunk/util/src/main/java/no/sesat/Interpreter.java
===================================================================
--- trunk/util/src/main/java/no/sesat/Interpreter.java                          
(rev 0)
+++ trunk/util/src/main/java/no/sesat/Interpreter.java  2008-06-05 15:41:34 UTC 
(rev 6676)
@@ -0,0 +1,211 @@
+/**
+ * Copyright (2008) Schibsted Søk AS
+ * This file is part of SESAT.
+ *
+ *   SESAT is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU Affero General Public License as published 
by
+ *   the Free Software Foundation, either version 3 of the License, or
+ *   (at your option) any later version.
+ *
+ *   SESAT is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU Affero General Public License for more details.
+ *
+ *   You should have received a copy of the GNU Affero General Public License
+ *   along with SESAT.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+package no.sesat;
+
+import java.io.Console;
+import java.util.*;
+
+import org.apache.log4j.Level;
+import org.apache.log4j.Logger;
+import org.apache.log4j.spi.LoggerRepository;
+
+/**
+ * Simple interpreter that will start if a console is available. You can add
+ * functions to it by using addFunction(String, Function).
+ *
+ */
+public class Interpreter {
+    private static Map<String, Function> functions = new HashMap<String, 
Function>();
+    private static boolean run = true;
+
+    /**
+     * Add a function to this Interpreter.
+     *
+     * @param name
+     *            Name of function
+     * @param fun
+     *            The function
+     */
+    public static void addFunction(String name, Function fun) {
+        if (functions != null) {
+            functions.put(name, fun);
+        }
+    }
+
+    /**
+     * Remove function from interpreter.
+     *
+     * @param name
+     *            Named function
+     */
+    public static void removeFunction(String name) {
+        if (functions != null) {
+            functions.remove(name);
+        }
+    }
+
+    private static interface FunctionInterface {
+        public String execute(Context ctx);
+    }
+
+    /**
+     * Function that you can implement if you want to add a function to this
+     * Interpreter.
+     */
+    public abstract static class Function implements FunctionInterface {
+        /**
+         * One line that describes the function.
+         *
+         * @return Description
+         */
+        protected String describe() {
+            return "";
+        }
+
+        /**
+         * If there is need for a longer description then what you can write in
+         * description then write it here.
+         *
+         * @return Help text
+         */
+        protected String help() {
+            return describe();
+        }
+    }
+
+    /**
+     * Context for a function
+     */
+    public static class Context {
+        protected String[] args;
+
+        private Context(String[] args) {
+            this.args = args;
+        }
+
+        protected int length() {
+            return args.length;
+        }
+    }
+
+    static {
+        addFunction("help", new Function() {
+            public String execute(Context ctx) {
+                if (ctx.length() == 1) {
+                    String res = "Help for " + ctx.args[0] + "\n";
+                    Function fun = functions.get(ctx.args[0].trim());
+                    if (fun != null) {
+                        res += "    " + fun.help();
+                    } else {
+                        res += "    Not found!\n";
+                    }
+                    return res;
+                } else {
+                    String res = "Functions available: \n";
+                    for (String name : functions.keySet()) {
+                        res += "    " + name + "\n";
+                        res += "        " + functions.get(name).describe() + 
"\n";
+                    }
+                    return res;
+                }
+            }
+
+            public String describe() {
+                return "Print this help message";
+            }
+        });
+
+        addFunction("loggers", new Function() {
+            public String execute(Context ctx) {
+                String res = "Active loggers:\n";
+                LoggerRepository repo = 
Logger.getRootLogger().getLoggerRepository();
+
+                Enumeration e = repo.getCurrentCategories();
+                while (e.hasMoreElements()) {
+                    Logger logger = (Logger) e.nextElement();
+                    if (ctx.length() == 0 || (ctx.length() > 0 && 
logger.getName().matches(ctx.args[0]))) {
+                        res += logger.getName() + " " + logger.getLevel();
+                        if (ctx.length() == 2) {
+                            Level level = Level.toLevel(ctx.args[1]);
+                            if 
(level.toString().equalsIgnoreCase(ctx.args[1])) {
+                                res += " (Setting level to " + level + ")";
+                                logger.setLevel(level);
+                            } else {
+                                res += " (unknown debug level: " + ctx.args[1] 
+ ")";
+                            }
+                        }
+                        res += "\n";
+                    }
+                }
+                return res;
+            }
+
+            public String describe() {
+                return "Print active loggers, and set level if specified. 
'loggers [regexp] [level]'";
+            }
+        });
+
+        addFunction("quit", new Function() {
+            public String execute(Context ctx) {
+                run = false;
+                return "Bye!";
+            }
+
+            public String describe() {
+                return "Stop this interpreter.";
+            }
+        });
+
+        Thread replThread = new Thread("REPL") {
+            Console console = System.console();
+
+            public void run() {
+                if (console != null) {
+                    while (run) {
+                        console.printf("$ ");
+                        String line = console.readLine();
+                        if (line != null) { // check for null, this will 
happen on shutdown
+                            String[] input = line.split("\\s");
+                            if (input.length > 0) {
+                                String name = input[0].trim();
+                                if (name.length() > 0) {
+                                    if (functions.containsKey(input[0])) {
+                                        try {
+                                            console.printf("%s\n", 
functions.get(name).execute(
+                                                    new 
Context(Arrays.copyOfRange(input, 1, input.length))));
+                                        } catch (Throwable e) {
+                                            console.printf("Error: %s\n", 
e.toString());
+                                        }
+
+                                    } else {
+                                        console.printf("Unknown function: 
%s\n", name);
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+                functions = null;
+            }
+        };
+        replThread.setDaemon(true);
+        replThread.start();
+    }
+}

_______________________________________________
Kernel-commits mailing list
[email protected]
http://sesat.no/mailman/listinfo/kernel-commits

Reply via email to