You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@opennlp.apache.org by jo...@apache.org on 2011/07/12 13:30:05 UTC

svn commit: r1145550 - in /incubator/opennlp/trunk/opennlp-tools/src: main/java/opennlp/tools/cmdline/ main/java/opennlp/tools/cmdline/sentdetect/ test/java/opennlp/tools/cmdline/

Author: joern
Date: Tue Jul 12 11:30:04 2011
New Revision: 1145550

URL: http://svn.apache.org/viewvc?rev=1145550&view=rev
Log:
OPENNLP-221 Refactored and extended the Argument Parser to also accept Charset types. And added the new Charset parameter to the BasicTrainingparameters interface. 

Modified:
    incubator/opennlp/trunk/opennlp-tools/src/main/java/opennlp/tools/cmdline/ArgumentParser.java
    incubator/opennlp/trunk/opennlp-tools/src/main/java/opennlp/tools/cmdline/BasicTrainingParametersI.java
    incubator/opennlp/trunk/opennlp-tools/src/main/java/opennlp/tools/cmdline/sentdetect/SentenceDetectorCrossValidatorTool.java
    incubator/opennlp/trunk/opennlp-tools/src/test/java/opennlp/tools/cmdline/ArgumentParserTest.java

Modified: incubator/opennlp/trunk/opennlp-tools/src/main/java/opennlp/tools/cmdline/ArgumentParser.java
URL: http://svn.apache.org/viewvc/incubator/opennlp/trunk/opennlp-tools/src/main/java/opennlp/tools/cmdline/ArgumentParser.java?rev=1145550&r1=1145549&r2=1145550&view=diff
==============================================================================
--- incubator/opennlp/trunk/opennlp-tools/src/main/java/opennlp/tools/cmdline/ArgumentParser.java (original)
+++ incubator/opennlp/trunk/opennlp-tools/src/main/java/opennlp/tools/cmdline/ArgumentParser.java Tue Jul 12 11:30:04 2011
@@ -22,8 +22,10 @@ import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.reflect.InvocationHandler;
 import java.lang.reflect.Method;
+import java.nio.charset.Charset;
+import java.nio.charset.IllegalCharsetNameException;
+import java.util.Collections;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
 
@@ -40,7 +42,7 @@ import java.util.Set;
  * <p>
  * <b>Note:</b> Do not use this class, internal use only!
  */
-public class ArgumentParser implements InvocationHandler {
+public class ArgumentParser {
 
   public @Retention(RetentionPolicy.RUNTIME)
   @interface OptionalParameter {
@@ -53,20 +55,102 @@ public class ArgumentParser implements I
     public String description() default "";
   }
   
+  private interface ArgumentFactory {
+    
+    static final String INVALID_ARG = "Invalid argument: %s %s \n";
+    
+    Object parseArgument(Method method, String argName, String argValue);
+  }
+ 
+  private static class IntegerArgumentFactory  implements ArgumentFactory {
+
+    public Object parseArgument(Method method, String argName, String argValue) {
+      
+      Object value = null;
+      
+      try {
+        value = Integer.parseInt(argValue);
+      }
+      catch (NumberFormatException e) {
+        throw new TerminateToolException(-1, String.format(INVALID_ARG, argName, argValue) +
+            "Value must be an integer!");
+      }
+      
+      return value;
+    }
+  }
+ 
+  private static class BooleanArgumentFactory implements ArgumentFactory {
+
+    public Object parseArgument(Method method, String argName, String argValue) {
+      return Boolean.parseBoolean(argValue);
+    }
+  } 
   
-  private final Map<String, Object> arguments;
+  private static class StringArgumentFactory implements ArgumentFactory {
+    
+    public Object parseArgument(Method method, String argName, String argValue) {
+      return argValue;
+    }
+  } 
   
-  private ArgumentParser(Map<String, Object> arguments) {
-    this.arguments = arguments;
-  }
+  private static class FileArgumentFactory implements ArgumentFactory {
+    
+    public Object parseArgument(Method method, String argName, String argValue) {
+      return new File(argValue);
+    }
+  } 
   
-  public Object invoke(Object proxy, Method method, Object[] args)
-      throws Throwable {
+  private static class CharsetArgumentFactory implements ArgumentFactory {
     
-    if (args != null)
-      throw new IllegalStateException();
+    public Object parseArgument(Method method, String argName, String charsetName) {
+      
+      try {
+        if (Charset.isSupported(charsetName)) {
+          return Charset.forName(charsetName);
+        } else {
+          throw new TerminateToolException(-1,  String.format(INVALID_ARG, argName, charsetName) + 
+              "Encoding not supported on this platform.");
+        }
+      } catch (IllegalCharsetNameException e) {
+        throw new TerminateToolException(-1, String.format(INVALID_ARG, argName, charsetName) + 
+            "Illegal encoding name.");
+      }
+    }
+  } 
+  
+  private static class ArgumentProxy implements InvocationHandler {
+    
+    private final Map<String, Object> arguments;
+    
+    ArgumentProxy(Map<String, Object> arguments) {
+      this.arguments = arguments;
+    }
     
-    return arguments.get(method.getName());
+    public Object invoke(Object proxy, Method method, Object[] args)
+        throws Throwable {
+      
+      if (args != null)
+        throw new IllegalStateException();
+      
+      return arguments.get(method.getName());
+    }
+  }
+  
+  private static final Map<Class<?>, ArgumentFactory> argumentFactories;
+  
+  static {
+    Map<Class<?>, ArgumentFactory> factories = new HashMap<Class<?>, ArgumentParser.ArgumentFactory>();
+    factories.put(Integer.class, new IntegerArgumentFactory());
+    factories.put(Boolean.class, new BooleanArgumentFactory());
+    factories.put(String.class, new StringArgumentFactory());
+    factories.put(File.class, new FileArgumentFactory());
+    factories.put(Charset.class, new CharsetArgumentFactory());
+    
+    argumentFactories = Collections.unmodifiableMap(factories);
+  }
+  
+  private ArgumentParser() {
   }
   
   private static <T> void checkProxyInterface(Class<T> proxyInterface) {
@@ -93,11 +177,7 @@ public class ArgumentParser implements I
       // check return types of interface
       Class<?> returnType = method.getReturnType();
       
-      Set<Class<?>> compatibleReturnTypes = new HashSet<Class<?>>();
-      compatibleReturnTypes.add(Integer.class);
-      compatibleReturnTypes.add(Boolean.class);
-      compatibleReturnTypes.add(String.class);
-      compatibleReturnTypes.add(File.class);
+      Set<Class<?>> compatibleReturnTypes = argumentFactories.keySet();
       
       if(!compatibleReturnTypes.contains(returnType))
          throw new IllegalArgumentException(method.getName() + " method must have compatible return type!");
@@ -150,20 +230,13 @@ public class ArgumentParser implements I
     return usage.toString();
   }
   
-  /**
-   * Converts the options to their method names and maps
-   * the method names to their return value.
-   * 
-   * @return the mapping or null if arguments are invalid
-   */
-  private static <T> Map<String, Object> createArgumentMap(String args[], Class<T> argProxyInterface) {
+  public static <T> boolean validateArguments(String args[], Class<T> argProxyInterface) {
     
     // number of parameters must be at least 2 and always be even
     if (args.length < 2 || args.length % 2 != 0)
-      return null;
+      return false;
     
-    // create argument map
-    Map<String, Object> arguments = new HashMap<String, Object>();
+    int argumentCount = 0;
     
     for (Method method : argProxyInterface.getMethods()) {
       
@@ -175,7 +248,36 @@ public class ArgumentParser implements I
         
         // missing mandatory parameter
         if (optionalParam == null)
-          return null;
+          return false;
+      }
+      else {
+        argumentCount++;
+      }
+    }
+    
+    if (args.length / 2 != argumentCount)
+      return false;
+    
+    return true;
+  }
+  
+  @SuppressWarnings("unchecked")
+  public static <T> T parse(String args[], Class<T> argProxyInterface) {
+    
+    checkProxyInterface(argProxyInterface);
+    
+    if (!validateArguments(args, argProxyInterface))
+      throw new IllegalArgumentException("Passed args must be valid!");
+    
+    Map<String, Object> arguments = new HashMap<String, Object>();
+    
+    for (Method method : argProxyInterface.getMethods()) {
+      
+      String parameterName = methodNameToParameter(method.getName());
+      String valueString = CmdLineUtil.getParameter(parameterName, args);
+      
+      if (valueString == null) {
+        OptionalParameter optionalParam = method.getAnnotation(OptionalParameter.class);
         
         if (optionalParam.defaultValue().length() > 0)
           valueString = optionalParam.defaultValue();
@@ -188,27 +290,12 @@ public class ArgumentParser implements I
       Object value;
       
       if (valueString != null) {
-        if (Integer.class.equals(returnType)) {
-          try {
-            value = Integer.parseInt(valueString);
-          }
-          catch (NumberFormatException e) {
-            // parameter is not a number
-            return null;
-          }
-        }
-        else if (Boolean.class.equals(returnType)) {
-          value = Boolean.parseBoolean(valueString);
-        }
-        else if (String.class.equals(returnType)) {
-          value = valueString;
-        }
-        else if (File.class.equals(returnType)) {
-          value = new File(valueString);
-        }
-        else {
+        ArgumentFactory factory = argumentFactories.get(returnType);
+        
+        if (factory == null)
           throw new IllegalStateException();
-        }
+        
+        value = factory.parseArgument(method, parameterName, valueString);
       }
       else
         value = null;
@@ -216,28 +303,9 @@ public class ArgumentParser implements I
       arguments.put(method.getName(), value);
     }
     
-    return arguments;
-  }
-  
-  public static <T> boolean validateArguments(String args[], Class<T> argProxyInterface) {
-    return createArgumentMap(args, argProxyInterface) != null;
-  }
-  
-  @SuppressWarnings("unchecked")
-  public static <T> T parse(String args[], Class<T> argProxyInterface) {
-    
-    checkProxyInterface(argProxyInterface);
-    
-    Map<String, Object> argumentMap = createArgumentMap(args, argProxyInterface);
-    
-    if (argumentMap != null) {
-      return (T) java.lang.reflect.Proxy.newProxyInstance(
-          argProxyInterface.getClassLoader(),
-          new Class[]{argProxyInterface},
-          new ArgumentParser(argumentMap));
-    }
-    else {
-      return null;
-    }
+    return (T) java.lang.reflect.Proxy.newProxyInstance(
+        argProxyInterface.getClassLoader(),
+        new Class[]{argProxyInterface},
+        new ArgumentProxy(arguments));
   }
 }

Modified: incubator/opennlp/trunk/opennlp-tools/src/main/java/opennlp/tools/cmdline/BasicTrainingParametersI.java
URL: http://svn.apache.org/viewvc/incubator/opennlp/trunk/opennlp-tools/src/main/java/opennlp/tools/cmdline/BasicTrainingParametersI.java?rev=1145550&r1=1145549&r2=1145550&view=diff
==============================================================================
--- incubator/opennlp/trunk/opennlp-tools/src/main/java/opennlp/tools/cmdline/BasicTrainingParametersI.java (original)
+++ incubator/opennlp/trunk/opennlp-tools/src/main/java/opennlp/tools/cmdline/BasicTrainingParametersI.java Tue Jul 12 11:30:04 2011
@@ -17,6 +17,8 @@
 
 package opennlp.tools.cmdline;
 
+import java.nio.charset.Charset;
+
 import opennlp.tools.cmdline.ArgumentParser.OptionalParameter;
 import opennlp.tools.cmdline.ArgumentParser.ParameterDescription;
 
@@ -33,7 +35,7 @@ public interface BasicTrainingParameters
   String getLang();
   
   @ParameterDescription(valueName = "charset", description = "specifies the encoding which should be used for reading and writing text.")
-  String getEncoding();
+  Charset getEncoding();
   
   @ParameterDescription(valueName = "num", description = "specifies the number of training iterations. It is ignored if a parameters file is passed.")
   @OptionalParameter(defaultValue="100")

Modified: incubator/opennlp/trunk/opennlp-tools/src/main/java/opennlp/tools/cmdline/sentdetect/SentenceDetectorCrossValidatorTool.java
URL: http://svn.apache.org/viewvc/incubator/opennlp/trunk/opennlp-tools/src/main/java/opennlp/tools/cmdline/sentdetect/SentenceDetectorCrossValidatorTool.java?rev=1145550&r1=1145549&r2=1145550&view=diff
==============================================================================
--- incubator/opennlp/trunk/opennlp-tools/src/main/java/opennlp/tools/cmdline/sentdetect/SentenceDetectorCrossValidatorTool.java (original)
+++ incubator/opennlp/trunk/opennlp-tools/src/main/java/opennlp/tools/cmdline/sentdetect/SentenceDetectorCrossValidatorTool.java Tue Jul 12 11:30:04 2011
@@ -72,7 +72,7 @@ public final class SentenceDetectorCross
     File trainingDataInFile = params.getData();
     CmdLineUtil.checkInputFile("Training Data", trainingDataInFile);
     
-    Charset encoding = Charset.forName(params.getEncoding());
+    Charset encoding = params.getEncoding();
     
     ObjectStream<SentenceSample> sampleStream = SentenceDetectorTrainerTool.openSampleData("Training Data",
         trainingDataInFile, encoding);

Modified: incubator/opennlp/trunk/opennlp-tools/src/test/java/opennlp/tools/cmdline/ArgumentParserTest.java
URL: http://svn.apache.org/viewvc/incubator/opennlp/trunk/opennlp-tools/src/test/java/opennlp/tools/cmdline/ArgumentParserTest.java?rev=1145550&r1=1145549&r2=1145550&view=diff
==============================================================================
--- incubator/opennlp/trunk/opennlp-tools/src/test/java/opennlp/tools/cmdline/ArgumentParserTest.java (original)
+++ incubator/opennlp/trunk/opennlp-tools/src/test/java/opennlp/tools/cmdline/ArgumentParserTest.java Tue Jul 12 11:30:04 2011
@@ -19,7 +19,6 @@ package opennlp.tools.cmdline;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import opennlp.tools.cmdline.ArgumentParser.OptionalParameter;
 import opennlp.tools.cmdline.ArgumentParser.ParameterDescription;
@@ -84,12 +83,12 @@ public class ArgumentParserTest {
     assertEquals(false, args.getAlphaNumOpt());
   }
   
-  @Test
+  @Test(expected = IllegalArgumentException.class)
   public void testSimpleArgumentsMissingEncoding() {
     String argsString = "-alphaNumOpt false";
     
     assertFalse(ArgumentParser.validateArguments(argsString.split(" "), SimpleArguments.class));
-    assertNull(ArgumentParser.parse(argsString.split(" "), SimpleArguments.class));
+    ArgumentParser.parse(argsString.split(" "), SimpleArguments.class);
   }
   
   @Test