From e9039da65d0542d2b333eb030a369772d09d16a4 Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 19 May 2009 04:29:10 +0000 Subject: [PATCH] git-svn-id: http://www.xerial.org/svn/project/XerialJ/trunk/xerial-core@3302 ae02f08e-27ec-0310-ae8c-8ba02fe2eafd --- src/main/java/org/xerial/lens/ObjectLens.java | 112 +++++++++++++++------ src/main/java/org/xerial/lens/RelationSetter.java | 79 ++++++++++++++- .../java/org/xerial/silk/SilkStreamReader.java | 1 + src/test/java/org/xerial/lens/ObjectLensTest.java | 76 ++++++++++++++ 4 files changed, 239 insertions(+), 29 deletions(-) create mode 100644 src/test/java/org/xerial/lens/ObjectLensTest.java diff --git a/src/main/java/org/xerial/lens/ObjectLens.java b/src/main/java/org/xerial/lens/ObjectLens.java index 58782bf..bdd59f9 100644 --- a/src/main/java/org/xerial/lens/ObjectLens.java +++ b/src/main/java/org/xerial/lens/ObjectLens.java @@ -28,23 +28,51 @@ import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.xerial.util.Pair; import org.xerial.util.bean.TypeInformation; +/** + * Tree to Object lens + * + * @author leo + * + */ public class ObjectLens { - public ObjectLens(Class< ? > targetType) + private static HashMap, ObjectLens> cache = new HashMap, ObjectLens>(); + + /** + * Get the lens of the target type + * + * @param target + * @return lens of the target type + */ + public static ObjectLens getObjectLens(Class< ? > target) { - createBindRules(targetType); + if (cache.containsKey(target)) + return cache.get(target); + else + { + cache.put(target, new ObjectLens(target)); + return getObjectLens(target); + } } - private static void createBindRules(Class< ? > targetType) + private List setterContainer = new ArrayList(); + private List relationSetterContainer = new ArrayList(); + + protected ObjectLens(Class< ? > targetType) { - List setterContainer = new ArrayList(); + createBindRules(targetType); + } + private void createBindRules(Class< ? > targetType) + { // look for all super classes for (Class< ? > eachClass = targetType; eachClass != null; eachClass = eachClass.getSuperclass()) { @@ -82,36 +110,34 @@ public class ObjectLens for (Method eachMethod : eachClass.getMethods()) { String methodName = eachMethod.getName(); - String parametrName = pickPropertyName(methodName); - if (methodName.startsWith("add")) - { - // adder - String paramName = getCanonicalParameterName(methodName.substring(3)); - setterContainer.add(ParameterSetter.newSetter(eachClass, paramName, eachMethod)); + String paramPart = pickPropertyName(methodName); - } - else if (methodName.startsWith("set")) + if (methodName.startsWith("add") || methodName.startsWith("set") || methodName.startsWith("put")) { - // setter - String paramName = getCanonicalParameterName(methodName.substring(3)); - - } - else if (methodName.startsWith("get")) - { - // we cannot use any getter that requires some arguments - Class< ? >[] parameterType = eachMethod.getParameterTypes(); - if (parameterType.length != 0) + Class< ? >[] argTypes = eachMethod.getParameterTypes(); + switch (argTypes.length) + { + case 1: + { + addNewSetter(eachClass, paramPart, eachMethod); + break; + } + case 2: + { + // relation adder + Pair relName = pickRelationName(paramPart); + relationSetterContainer.add(RelationSetter.newRelationSetter(relName.getFirst(), relName + .getSecond(), eachMethod)); + break; + } + default: continue; - - } - else if (methodName.startsWith("put")) - { + } } else if (methodName.startsWith("append")) { - // appender for a large text value split into chunks - + addNewSetter(eachClass, paramPart, eachMethod); } } @@ -120,7 +146,26 @@ public class ObjectLens } + private void addNewSetter(Class< ? > c, String paramPart, Method m) + { + Class< ? >[] argTypes = m.getParameterTypes(); + if (argTypes.length != 1) + return; + + assert (argTypes.length == 1); + + String paramName = getCanonicalParameterName(paramPart); + if (paramName.length() <= 0) + { + // infer parameter name from argument type + paramName = getCanonicalParameterName(argTypes[0].getName()); + } + setterContainer.add(ParameterSetter.newSetter(c, paramName, m)); + return; + } + static private Pattern propertyNamePattern = Pattern.compile("^(set|get|add|put|append)((\\S)(\\S*))?"); + static private Pattern pairedNamePattern = Pattern.compile("([A-Za-z0-9]*)_([A-Za-z0-9]*)"); public static String pickPropertyName(String methodName) { @@ -131,12 +176,23 @@ public class ObjectLens else { if (m.group(2) != null) - return getCanonicalParameterName(m.group(3) + m.group(4)); + return getCanonicalParameterName(m.group(2)); else return ""; } } + public static Pair pickRelationName(String pairedName) + { + Matcher m = null; + m = pairedNamePattern.matcher(pairedName); + if (!m.matches()) + return null; + else + return new Pair(getCanonicalParameterName(m.group(1)), + getCanonicalParameterName(m.group(2))); + } + public static String getCanonicalParameterName(String paramName) { paramName = paramName.replaceAll("\\s", ""); diff --git a/src/main/java/org/xerial/lens/RelationSetter.java b/src/main/java/org/xerial/lens/RelationSetter.java index dbfd9f0..740e26b 100644 --- a/src/main/java/org/xerial/lens/RelationSetter.java +++ b/src/main/java/org/xerial/lens/RelationSetter.java @@ -24,6 +24,11 @@ //-------------------------------------- package org.xerial.lens; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +import org.xerial.core.XerialError; +import org.xerial.core.XerialErrorCode; import org.xerial.core.XerialException; /** @@ -34,6 +39,78 @@ import org.xerial.core.XerialException; */ public abstract class RelationSetter { - public abstract void bind(Object object, Object value) throws XerialException; + private final Class< ? > coreNodeType; + private final Class< ? > attributeNodeType; + + private final String coreNodeName; + private final String attributeNodeName; + + protected RelationSetter(Class< ? > coreNodeType, String coreNodeName, Class< ? > attributeNodeType, + String attributeNodeName) + { + this.coreNodeType = coreNodeType; + this.attributeNodeType = attributeNodeType; + this.coreNodeName = coreNodeName; + this.attributeNodeName = attributeNodeName; + } + + @Override + public boolean equals(Object obj) + { + RelationSetter other = RelationSetter.class.cast(obj); + if (other == null) + return false; + boolean eq = this.coreNodeName.equals(other.coreNodeName); + return eq ? this.attributeNodeName.equals(other.attributeNodeName) : false; + } + + @Override + public int hashCode() + { + return coreNodeName.hashCode() + attributeNodeName.hashCode(); + } + + public abstract void bind(Object object, Object coreValue, Object attributeValue) throws XerialException; + + public static RelationSetter newRelationSetter(String coreNodeName, String attributeNodeName, Method setterMethod) + { + Class< ? >[] argType = setterMethod.getParameterTypes(); + if (argType.length != 2) + throw new XerialError(XerialErrorCode.INVALID_INPUT, setterMethod.toString()); + return new MethodRelationSetter(argType[0], coreNodeName, argType[1], attributeNodeName, setterMethod); + } + + private static class MethodRelationSetter extends RelationSetter + { + private final Method setter; + + public MethodRelationSetter(Class< ? > coreNodeType, String coreNodeName, Class< ? > attributeNodeType, + String attributeNodeName, Method setter) + { + super(coreNodeType, coreNodeName, attributeNodeType, attributeNodeName); + this.setter = setter; + } + + @Override + public void bind(Object object, Object coreValue, Object attributeValue) throws XerialException + { + try + { + setter.invoke(object, coreValue, attributeValue); + } + catch (IllegalArgumentException e) + { + throw new XerialException(XerialErrorCode.WRONG_DATA_TYPE, e); + } + catch (IllegalAccessException e) + { + throw new XerialException(XerialErrorCode.INVALID_INPUT, e); + } + catch (InvocationTargetException e) + { + throw new XerialError(XerialErrorCode.WRONG_DATA_TYPE, e); + } + } + } } diff --git a/src/main/java/org/xerial/silk/SilkStreamReader.java b/src/main/java/org/xerial/silk/SilkStreamReader.java index b6b49cb..83c6cb6 100644 --- a/src/main/java/org/xerial/silk/SilkStreamReader.java +++ b/src/main/java/org/xerial/silk/SilkStreamReader.java @@ -653,6 +653,7 @@ public class SilkStreamReader implements TreeStreamReader SilkEvent currentEvent = parser.next(); + // update the line count numReadLine = parser.getNumReadLine(); if (_logger.isTraceEnabled()) diff --git a/src/test/java/org/xerial/lens/ObjectLensTest.java b/src/test/java/org/xerial/lens/ObjectLensTest.java new file mode 100644 index 0000000..e3e4ba6 --- /dev/null +++ b/src/test/java/org/xerial/lens/ObjectLensTest.java @@ -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 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); + + } + +} -- 2.11.0