OSDN Git Service

git-svn-id: http://www.xerial.org/svn/project/XerialJ/trunk/xerial-core@3302 ae02f08e...
authorleo <leo@ae02f08e-27ec-0310-ae8c-8ba02fe2eafd>
Tue, 19 May 2009 04:29:10 +0000 (04:29 +0000)
committerleo <leo@ae02f08e-27ec-0310-ae8c-8ba02fe2eafd>
Tue, 19 May 2009 04:29:10 +0000 (04:29 +0000)
src/main/java/org/xerial/lens/ObjectLens.java
src/main/java/org/xerial/lens/RelationSetter.java
src/main/java/org/xerial/silk/SilkStreamReader.java
src/test/java/org/xerial/lens/ObjectLensTest.java [new file with mode: 0644]

index 58782bf..bdd59f9 100644 (file)
@@ -28,23 +28,51 @@ import java.lang.reflect.Field;
 import java.lang.reflect.Method;\r
 import java.lang.reflect.Modifier;\r
 import java.util.ArrayList;\r
+import java.util.HashMap;\r
 import java.util.List;\r
 import java.util.regex.Matcher;\r
 import java.util.regex.Pattern;\r
 \r
+import org.xerial.util.Pair;\r
 import org.xerial.util.bean.TypeInformation;\r
 \r
+/**\r
+ * Tree to Object lens\r
+ * \r
+ * @author leo\r
+ * \r
+ */\r
 public class ObjectLens\r
 {\r
-    public ObjectLens(Class< ? > targetType)\r
+    private static HashMap<Class< ? >, ObjectLens> cache = new HashMap<Class< ? >, ObjectLens>();\r
+\r
+    /**\r
+     * Get the lens of the target type\r
+     * \r
+     * @param target\r
+     * @return lens of the target type\r
+     */\r
+    public static ObjectLens getObjectLens(Class< ? > target)\r
     {\r
-        createBindRules(targetType);\r
+        if (cache.containsKey(target))\r
+            return cache.get(target);\r
+        else\r
+        {\r
+            cache.put(target, new ObjectLens(target));\r
+            return getObjectLens(target);\r
+        }\r
     }\r
 \r
-    private static void createBindRules(Class< ? > targetType)\r
+    private List<ParameterSetter> setterContainer = new ArrayList<ParameterSetter>();\r
+    private List<RelationSetter> relationSetterContainer = new ArrayList<RelationSetter>();\r
+\r
+    protected ObjectLens(Class< ? > targetType)\r
     {\r
-        List<ParameterSetter> setterContainer = new ArrayList<ParameterSetter>();\r
+        createBindRules(targetType);\r
+    }\r
 \r
+    private void createBindRules(Class< ? > targetType)\r
+    {\r
         // look for all super classes\r
         for (Class< ? > eachClass = targetType; eachClass != null; eachClass = eachClass.getSuperclass())\r
         {\r
@@ -82,36 +110,34 @@ public class ObjectLens
             for (Method eachMethod : eachClass.getMethods())\r
             {\r
                 String methodName = eachMethod.getName();\r
-                String parametrName = pickPropertyName(methodName);\r
-                if (methodName.startsWith("add"))\r
-                {\r
-                    // adder\r
-                    String paramName = getCanonicalParameterName(methodName.substring(3));\r
-                    setterContainer.add(ParameterSetter.newSetter(eachClass, paramName, eachMethod));\r
+                String paramPart = pickPropertyName(methodName);\r
 \r
-                }\r
-                else if (methodName.startsWith("set"))\r
+                if (methodName.startsWith("add") || methodName.startsWith("set") || methodName.startsWith("put"))\r
                 {\r
-                    // setter\r
-                    String paramName = getCanonicalParameterName(methodName.substring(3));\r
-\r
-                }\r
-                else if (methodName.startsWith("get"))\r
-                {\r
-                    // we cannot use any getter that requires some arguments\r
-                    Class< ? >[] parameterType = eachMethod.getParameterTypes();\r
-                    if (parameterType.length != 0)\r
+                    Class< ? >[] argTypes = eachMethod.getParameterTypes();\r
+                    switch (argTypes.length)\r
+                    {\r
+                    case 1:\r
+                    {\r
+                        addNewSetter(eachClass, paramPart, eachMethod);\r
+                        break;\r
+                    }\r
+                    case 2:\r
+                    {\r
+                        // relation adder\r
+                        Pair<String, String> relName = pickRelationName(paramPart);\r
+                        relationSetterContainer.add(RelationSetter.newRelationSetter(relName.getFirst(), relName\r
+                                .getSecond(), eachMethod));\r
+                        break;\r
+                    }\r
+                    default:\r
                         continue;\r
-\r
-                }\r
-                else if (methodName.startsWith("put"))\r
-                {\r
+                    }\r
 \r
                 }\r
                 else if (methodName.startsWith("append"))\r
                 {\r
-                    // appender for a large text value split into chunks\r
-\r
+                    addNewSetter(eachClass, paramPart, eachMethod);\r
                 }\r
 \r
             }\r
@@ -120,7 +146,26 @@ public class ObjectLens
 \r
     }\r
 \r
+    private void addNewSetter(Class< ? > c, String paramPart, Method m)\r
+    {\r
+        Class< ? >[] argTypes = m.getParameterTypes();\r
+        if (argTypes.length != 1)\r
+            return;\r
+\r
+        assert (argTypes.length == 1);\r
+\r
+        String paramName = getCanonicalParameterName(paramPart);\r
+        if (paramName.length() <= 0)\r
+        {\r
+            // infer parameter name from argument type\r
+            paramName = getCanonicalParameterName(argTypes[0].getName());\r
+        }\r
+        setterContainer.add(ParameterSetter.newSetter(c, paramName, m));\r
+        return;\r
+    }\r
+\r
     static private Pattern propertyNamePattern = Pattern.compile("^(set|get|add|put|append)((\\S)(\\S*))?");\r
+    static private Pattern pairedNamePattern = Pattern.compile("([A-Za-z0-9]*)_([A-Za-z0-9]*)");\r
 \r
     public static String pickPropertyName(String methodName)\r
     {\r
@@ -131,12 +176,23 @@ public class ObjectLens
         else\r
         {\r
             if (m.group(2) != null)\r
-                return getCanonicalParameterName(m.group(3) + m.group(4));\r
+                return getCanonicalParameterName(m.group(2));\r
             else\r
                 return "";\r
         }\r
     }\r
 \r
+    public static Pair<String, String> pickRelationName(String pairedName)\r
+    {\r
+        Matcher m = null;\r
+        m = pairedNamePattern.matcher(pairedName);\r
+        if (!m.matches())\r
+            return null;\r
+        else\r
+            return new Pair<String, String>(getCanonicalParameterName(m.group(1)),\r
+                    getCanonicalParameterName(m.group(2)));\r
+    }\r
+\r
     public static String getCanonicalParameterName(String paramName)\r
     {\r
         paramName = paramName.replaceAll("\\s", "");\r
index dbfd9f0..740e26b 100644 (file)
 //--------------------------------------\r
 package org.xerial.lens;\r
 \r
+import java.lang.reflect.InvocationTargetException;\r
+import java.lang.reflect.Method;\r
+\r
+import org.xerial.core.XerialError;\r
+import org.xerial.core.XerialErrorCode;\r
 import org.xerial.core.XerialException;\r
 \r
 /**\r
@@ -34,6 +39,78 @@ import org.xerial.core.XerialException;
  */\r
 public abstract class RelationSetter\r
 {\r
-    public abstract void bind(Object object, Object value) throws XerialException;\r
+    private final Class< ? > coreNodeType;\r
+    private final Class< ? > attributeNodeType;\r
+\r
+    private final String coreNodeName;\r
+    private final String attributeNodeName;\r
+\r
+    protected RelationSetter(Class< ? > coreNodeType, String coreNodeName, Class< ? > attributeNodeType,\r
+            String attributeNodeName)\r
+    {\r
+        this.coreNodeType = coreNodeType;\r
+        this.attributeNodeType = attributeNodeType;\r
+        this.coreNodeName = coreNodeName;\r
+        this.attributeNodeName = attributeNodeName;\r
+    }\r
+\r
+    @Override\r
+    public boolean equals(Object obj)\r
+    {\r
+        RelationSetter other = RelationSetter.class.cast(obj);\r
+        if (other == null)\r
+            return false;\r
+        boolean eq = this.coreNodeName.equals(other.coreNodeName);\r
+        return eq ? this.attributeNodeName.equals(other.attributeNodeName) : false;\r
+    }\r
+\r
+    @Override\r
+    public int hashCode()\r
+    {\r
+        return coreNodeName.hashCode() + attributeNodeName.hashCode();\r
+    }\r
+\r
+    public abstract void bind(Object object, Object coreValue, Object attributeValue) throws XerialException;\r
+\r
+    public static RelationSetter newRelationSetter(String coreNodeName, String attributeNodeName, Method setterMethod)\r
+    {\r
+        Class< ? >[] argType = setterMethod.getParameterTypes();\r
+        if (argType.length != 2)\r
+            throw new XerialError(XerialErrorCode.INVALID_INPUT, setterMethod.toString());\r
+        return new MethodRelationSetter(argType[0], coreNodeName, argType[1], attributeNodeName, setterMethod);\r
+    }\r
+\r
+    private static class MethodRelationSetter extends RelationSetter\r
+    {\r
+        private final Method setter;\r
+\r
+        public MethodRelationSetter(Class< ? > coreNodeType, String coreNodeName, Class< ? > attributeNodeType,\r
+                String attributeNodeName, Method setter)\r
+        {\r
+            super(coreNodeType, coreNodeName, attributeNodeType, attributeNodeName);\r
+            this.setter = setter;\r
+        }\r
+\r
+        @Override\r
+        public void bind(Object object, Object coreValue, Object attributeValue) throws XerialException\r
+        {\r
+            try\r
+            {\r
+                setter.invoke(object, coreValue, attributeValue);\r
+            }\r
+            catch (IllegalArgumentException e)\r
+            {\r
+                throw new XerialException(XerialErrorCode.WRONG_DATA_TYPE, e);\r
+            }\r
+            catch (IllegalAccessException e)\r
+            {\r
+                throw new XerialException(XerialErrorCode.INVALID_INPUT, e);\r
+            }\r
+            catch (InvocationTargetException e)\r
+            {\r
+                throw new XerialError(XerialErrorCode.WRONG_DATA_TYPE, e);\r
+            }\r
 \r
+        }\r
+    }\r
 }\r
index b6b49cb..83c6cb6 100644 (file)
@@ -653,6 +653,7 @@ public class SilkStreamReader implements TreeStreamReader
 \r
         SilkEvent currentEvent = parser.next();\r
 \r
+        // update the line count\r
         numReadLine = parser.getNumReadLine();\r
 \r
         if (_logger.isTraceEnabled())\r
diff --git a/src/test/java/org/xerial/lens/ObjectLensTest.java b/src/test/java/org/xerial/lens/ObjectLensTest.java
new file mode 100644 (file)
index 0000000..e3e4ba6
--- /dev/null
@@ -0,0 +1,76 @@
+/*--------------------------------------------------------------------------
+ *  Copyright 2009 Taro L. Saito
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *--------------------------------------------------------------------------*/
+//--------------------------------------
+// XerialJ
+//
+// ObjectLensTest.java
+// Since: May 19, 2009 12:23:25 PM
+//
+// $URL$
+// $Author$
+//--------------------------------------
+package org.xerial.lens;
+
+import static org.junit.Assert.*;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.xerial.util.Pair;
+
+public class ObjectLensTest
+{
+
+    @Before
+    public void setUp() throws Exception
+    {}
+
+    @After
+    public void tearDown() throws Exception
+    {}
+
+    @Test
+    public void pickPairedName() throws Exception
+    {
+        Pair<String, String> p = ObjectLens.pickRelationName("Invoice_Order");
+        assertEquals("invoice", p.getFirst());
+        assertEquals("order", p.getSecond());
+
+        p = ObjectLens.pickRelationName("LineItem_Order");
+        assertEquals("lineitem", p.getFirst());
+        assertEquals("order", p.getSecond());
+
+        p = ObjectLens.pickRelationName("gene_JSON");
+        assertEquals("gene", p.getFirst());
+        assertEquals("json", p.getSecond());
+
+    }
+
+    @Test
+    public void pickPropertyName() throws Exception
+    {
+        String c = ObjectLens.pickPropertyName("addSomething");
+        assertEquals("something", c);
+
+        c = ObjectLens.pickPropertyName("addSomethingImportant");
+        assertEquals("somethingimportant", c);
+
+        c = ObjectLens.pickPropertyName("add");
+        assertEquals("", c);
+
+    }
+
+}