\r
import org.xerial.util.StringUtil;\r
\r
+public class JSONString extends JSONValueBase\r
+{\r
\r
-public class JSONString extends JSONValueBase {\r
+ private String s;\r
\r
- private String s;\r
- public JSONString() {}\r
- public JSONString(String s)\r
- {\r
- this.s = StringUtil.unquote(s);\r
- }\r
- \r
- public String toString()\r
- {\r
- return s;\r
- }\r
- \r
- public String toJSONString()\r
- {\r
- return "\"" + s + "\"";\r
- }\r
- \r
- @Override\r
- public boolean equals(Object obj) {\r
- if (obj instanceof JSONString) {\r
- return s.equals(((JSONString) obj).s);\r
- }\r
- return false;\r
- }\r
- \r
- @Override\r
- public JSONString getJSONString() {\r
- return this;\r
- }\r
- \r
- public String getValue()\r
- {\r
- return s;\r
- }\r
- public JSONValueType getValueType()\r
+ public JSONString()\r
+ {}\r
+\r
+ public JSONString(String s)\r
{\r
- return JSONValueType.String;\r
+ this.s = StringUtil.unquote(s);\r
+ }\r
+\r
+ public String toString()\r
+ {\r
+ return s;\r
+ }\r
+\r
+ public String toJSONString()\r
+ {\r
+ return toJSONString(s);\r
+ }\r
+\r
+ public static String toJSONString(String s)\r
+ {\r
+ return "\"" + s + "\"";\r
}\r
-}\r
\r
+ @Override\r
+ public boolean equals(Object obj)\r
+ {\r
+ if (obj instanceof JSONString)\r
+ {\r
+ return s.equals(((JSONString) obj).s);\r
+ }\r
+ return false;\r
+ }\r
\r
+ @Override\r
+ public JSONString getJSONString()\r
+ {\r
+ return this;\r
+ }\r
\r
+ public String getValue()\r
+ {\r
+ return s;\r
+ }\r
\r
+ public JSONValueType getValueType()\r
+ {\r
+ return JSONValueType.String;\r
+ }\r
+}\r
public void putObject(String key, Object obj)
{
if (obj == null)
- putNull(key);
+ return; // output nothing
else
{
putInternal(key, ObjectLens.toJSON(obj));
//--------------------------------------\r
package org.xerial.lens;\r
\r
+import java.io.StringWriter;\r
import java.lang.reflect.Field;\r
import java.lang.reflect.Method;\r
import java.lang.reflect.Modifier;\r
import java.lang.reflect.Type;\r
import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.Collections;\r
import java.util.HashMap;\r
import java.util.List;\r
+import java.util.Map;\r
+import java.util.Map.Entry;\r
import java.util.regex.Matcher;\r
import java.util.regex.Pattern;\r
\r
+import org.xerial.json.JSONString;\r
+import org.xerial.json.JSONWriter;\r
import org.xerial.util.Pair;\r
import org.xerial.util.bean.TypeInfo;\r
+import org.xerial.util.log.Logger;\r
import org.xerial.util.reflect.ReflectionUtil;\r
\r
/**\r
*/\r
public class ObjectLens\r
{\r
+ private static Logger _logger = Logger.getLogger(ObjectLens.class);\r
+\r
private static HashMap<Class< ? >, ObjectLens> cache = new HashMap<Class< ? >, ObjectLens>();\r
\r
/**\r
}\r
\r
private Class< ? > targetType;\r
+\r
+ private List<ParameterGetter> getterContainer = new ArrayList<ParameterGetter>();\r
private List<ParameterSetter> setterContainer = new ArrayList<ParameterSetter>();\r
private List<RelationSetter> relationSetterContainer = new ArrayList<RelationSetter>();\r
\r
public List<ParameterSetter> getSetterList()\r
{\r
- return setterContainer;\r
+ return Collections.unmodifiableList(setterContainer);\r
}\r
\r
public List<RelationSetter> getRelationSetterList()\r
{\r
- return relationSetterContainer;\r
+ return Collections.unmodifiableList(relationSetterContainer);\r
+ }\r
+\r
+ public List<ParameterGetter> getGetterContainer()\r
+ {\r
+ return Collections.unmodifiableList(getterContainer);\r
}\r
\r
protected ObjectLens(Class< ? > targetType)\r
return targetType;\r
}\r
\r
- public void bindParameter(Object target, String parameterName, Object value)\r
- {\r
-\r
- }\r
-\r
- public void bindRelation(Object target, String relationName, Object coreNode, Object attributeNode)\r
- {\r
-\r
- }\r
-\r
@Override\r
public String toString()\r
{\r
// scan public fields\r
for (Field eachField : targetType.getFields())\r
{\r
+ // ignore fields defined in the Object class\r
+ if (eachField.getDeclaringClass() == Object.class)\r
+ continue;\r
+\r
int fieldModifier = eachField.getModifiers();\r
if (Modifier.isPublic(fieldModifier) && !Modifier.isTransient(fieldModifier))\r
{\r
Class< ? > elementType = ReflectionUtil.getRawClass(ReflectionUtil\r
.getGenericCollectionElementType(eachField));\r
setterContainer.add(ParameterSetter.newSetter(elementType, paramName, eachField));\r
+ getterContainer.add(ParameterGetter.newFieldGetter(eachField, paramName));\r
}\r
else\r
+ {\r
setterContainer.add(ParameterSetter.newSetter(fieldType, paramName, eachField));\r
+ getterContainer.add(ParameterGetter.newFieldGetter(eachField, paramName));\r
+ }\r
\r
}\r
\r
// scan methods\r
for (Method eachMethod : targetType.getMethods())\r
{\r
+\r
String methodName = eachMethod.getName();\r
- String paramPart = pickPropertyName(methodName);\r
+ String paramName = pickPropertyName(methodName);\r
\r
if (methodName.startsWith("add") || methodName.startsWith("set") || methodName.startsWith("put"))\r
{\r
{\r
case 1:\r
{\r
- addNewSetter(setterContainer, paramPart, eachMethod);\r
+ addNewSetter(setterContainer, paramName, eachMethod);\r
break;\r
}\r
case 2:\r
{\r
// relation adder\r
- Pair<String, String> relName = pickRelationName(paramPart);\r
+ Pair<String, String> relName = pickRelationName(paramName);\r
if (relName == null)\r
{\r
// infer relation node names\r
}\r
else if (methodName.startsWith("append"))\r
{\r
- addNewSetter(setterContainer, paramPart, eachMethod);\r
+ addNewSetter(setterContainer, paramName, eachMethod);\r
continue;\r
}\r
+ else if (methodName.startsWith("get"))\r
+ {\r
+ if (eachMethod.getParameterTypes().length == 0)\r
+ {\r
+ // ignore getters defined in the Object.class\r
+ if (Object.class == eachMethod.getDeclaringClass())\r
+ continue;\r
+\r
+ getterContainer.add(ParameterGetter.newGetter(eachMethod, paramName));\r
+ }\r
+\r
+ }\r
\r
}\r
\r
getCanonicalParameterName(m.group(2)));\r
}\r
\r
- static String getCanonicalParameterName(String paramName)\r
+ static private Pattern paramNameReplacePattern = Pattern.compile("[\\s-_]");\r
+\r
+ public static String getCanonicalParameterName(String paramName)\r
+ {\r
+ Matcher m = paramNameReplacePattern.matcher(paramName);\r
+ return m.replaceAll("").toLowerCase();\r
+ }\r
+\r
+ public static String toJSON(Object obj)\r
{\r
- paramName = paramName.replaceAll("\\s", "");\r
- paramName = paramName.replaceAll("-", "");\r
- return paramName.toLowerCase();\r
+ if (obj == null)\r
+ return "null";\r
+\r
+ Class< ? > c = obj.getClass();\r
+\r
+ if (TypeInfo.isBasicType(c))\r
+ {\r
+ if (c == String.class)\r
+ return JSONString.toJSONString(obj.toString());\r
+ else\r
+ return obj.toString();\r
+ }\r
+\r
+ StringWriter buf = new StringWriter();\r
+ JSONWriter json = new JSONWriter(buf);\r
+\r
+ toJSON(json, obj);\r
+\r
+ json.flush();\r
+ return buf.toString();\r
+ }\r
+\r
+ private static void toJSON(JSONWriter json, Object obj)\r
+ {\r
+ Class< ? > c = obj.getClass();\r
+\r
+ if (TypeInfo.isCollection(c))\r
+ {\r
+ json.startArray();\r
+ Collection< ? > collection = (Collection< ? >) obj;\r
+ for (Object elem : collection)\r
+ {\r
+ toJSON(json, elem);\r
+ }\r
+ json.endArray();\r
+ }\r
+ else if (TypeInfo.isMap(c))\r
+ {\r
+ json.startArray();\r
+ Map< ? , ? > map = (Map< ? , ? >) obj;\r
+\r
+ json.startArray();\r
+ for (Entry< ? , ? > each : map.entrySet())\r
+ {\r
+ json.startObject();\r
+ json.putObject("key", each.getKey());\r
+ json.putObject("value", each.getValue());\r
+ json.endObject();\r
+ }\r
+ json.endArray();\r
+\r
+ json.endArray();\r
+ }\r
+ else\r
+ {\r
+ ObjectLens lens = getObjectLens(obj.getClass());\r
+ json.startObject();\r
+ for (ParameterGetter getter : lens.getGetterContainer())\r
+ {\r
+ json.putObject(getter.getParamName(), getter.get(obj));\r
+ }\r
+ json.endObject();\r
+ }\r
}\r
\r
}\r
--- /dev/null
+/*--------------------------------------------------------------------------
+ * 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
+//
+// ParameterGetter.java
+// Since: May 21, 2009 11:15:16 AM
+//
+// $URL$
+// $Author$
+//--------------------------------------
+package org.xerial.lens;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+import org.xerial.core.XerialError;
+import org.xerial.core.XerialErrorCode;
+import org.xerial.util.reflect.ReflectionUtil;
+
+/**
+ * For retrieving object parameter values
+ *
+ * @author leo
+ *
+ */
+public abstract class ParameterGetter
+{
+ private final String paramName;
+
+ public ParameterGetter(String paramName)
+ {
+ this.paramName = paramName;
+ }
+
+ public String getParamName()
+ {
+ return paramName;
+ }
+
+ public abstract Object get(Object obj);
+
+ public static ParameterGetter newFieldGetter(Field field, String paramName)
+ {
+ return new FieldGetter(field, paramName);
+ }
+
+ public static ParameterGetter newGetter(Method getter, String paramName)
+ {
+ return new GetterMethod(getter, paramName);
+ }
+
+ @Override
+ public String toString()
+ {
+ return paramName;
+ }
+
+ private static class FieldGetter extends ParameterGetter
+ {
+ final Field field;
+
+ public FieldGetter(Field field, String paramName)
+ {
+ super(paramName);
+ this.field = field;
+ }
+
+ @Override
+ public Object get(Object obj)
+ {
+ return ReflectionUtil.getFieldValue(obj, field);
+ }
+ }
+
+ private static class GetterMethod extends ParameterGetter
+ {
+ final Method getter;
+
+ public GetterMethod(Method getter, String paramName)
+ {
+ super(paramName);
+
+ this.getter = getter;
+
+ if (getter.getParameterTypes().length != 0)
+ throw new XerialError(XerialErrorCode.INVALID_INPUT, "not a getter");
+
+ }
+
+ @Override
+ public Object get(Object obj)
+ {
+ return ReflectionUtil.invokeGetter(obj, getter);
+ }
+ }
+
+}
super(parameterType, parameterName);\r
this.targetField = targetField;\r
\r
+ // make the final fields accessible\r
if (!targetField.isAccessible())\r
targetField.setAccessible(true);\r
\r
ReflectionUtil.setFieldValue(object, targetField, value);\r
}\r
\r
+ public Object get(Object object) throws XerialException\r
+ {\r
+ return ReflectionUtil.getFieldValue(object, targetField);\r
+ }\r
+\r
}\r
\r
private static class MethodSetter extends ParameterSetter\r
import org.xerial.core.XerialError;
import org.xerial.core.XerialErrorCode;
import org.xerial.core.XerialException;
+import org.xerial.lens.ObjectLens;
import org.xerial.relation.Node;
import org.xerial.relation.TupleIndex;
import org.xerial.relation.Node.NodeBuilder;
return nodeStackOfEachTag.get(nodeName);
}
+ public static String sanitize(String nodeName)
+ {
+ return ObjectLens.getCanonicalParameterName(nodeName);
+ }
+
public void visitNode(String nodeName, String nodeValue, TreeWalker walker) throws XerialException
{
+ nodeName = sanitize(nodeName);
+
Node currentNode = new NodeBuilder(nodeName).nodeID(++nodeCount).nodeValue(nodeValue).build();
Deque<Node> nodeStack = getNodeStack(nodeName);
nodeStack.add(currentNode);
public void text(String nodeName, String textDataFragment, TreeWalker walker) throws XerialException
{
+ nodeName = sanitize(nodeName);
+
Iterator<LatticeNode<String>> it = stateStack.descendingIterator();
LatticeNode<String> currentState = it.next();
LatticeNode<String> prevState = it.next();
public void leaveNode(String nodeName, TreeWalker walker) throws XerialException
{
+ nodeName = sanitize(nodeName);
+
Deque<Node> nodeStack = getNodeStack(nodeName);
Node currentNode = nodeStack.getLast();
import org.xerial.silk.plugin.SilkFunctionPlugin;\r
import org.xerial.util.ArrayDeque;\r
import org.xerial.util.FileResource;\r
+import org.xerial.util.StringUtil;\r
import org.xerial.util.bean.TypeInfo;\r
import org.xerial.util.log.Logger;\r
import org.xerial.util.reflect.ReflectionUtil;\r
}\r
else\r
{\r
- visit(node.getName(), columnData);\r
+ visit(node.getName(), StringUtil.unquote(columnData));\r
leave(node.getName());\r
}\r
}\r
return value;
}
+ public static Object invokeGetter(Object bean, Method getter)
+ {
+ try
+ {
+ return getter.invoke(bean);
+ }
+ catch (IllegalArgumentException e)
+ {
+ throw new XerialError(XerialErrorCode.INVALID_STATE, "not a getter (0-arg public method): " + getter);
+ }
+ catch (IllegalAccessException e)
+ {
+ throw new IllegalAccessError(e.getMessage());
+ }
+ catch (InvocationTargetException e)
+ {
+ throw new XerialError(XerialErrorCode.WRONG_DATA_TYPE, e);
+ }
+ }
+
/**
* Get the generic element type of the field that has a collection type. For
* example, for a field <em>f</em>
@Test
public void testBED() throws Exception
{
- BEDQuery result = new BEDQuery("chr22", 1L, 10000L);
+ BEDQuery result = new BEDQuery("chr7", 1L, 1000000000L);
Lens.loadSilk(result, FileResource.find(LensTest.class, "sample.bed.silk"));
_logger.info(StringUtil.join(result.geneList, "\n"));
+
+ assertEquals("Item,RGB,Demo2", result.track.name);
+ assertEquals("Item RGBdemonstration2", result.track.description);
+ assertEquals(2, result.track.visibility);
+ assertEquals("On", result.track.itemRgb);
+ assertEquals(1, result.track.useScore);
+ assertEquals("0,128,0", result.track.color);
+ assertEquals("http://genome.ucsc.edu/goldenPath/help/clones.html#$$", result.track.url);
}
public static class Locus
{
public String coordinate;
public String name;
+ public String color;
+ public String strand;
public List<CDS> cds;
public List<Exon> exon;
@Override
public String toString()
{
- return String.format("%s %s (%s, %s), cds=%s, exon=%s", coordinate, name, start, end, cds, exon);
+ return ObjectLens.toJSON(this);
}
}
+ public static class BEDTrack
+ {
+ public String name;
+ public String description;
+ public String itemRgb;
+ public int visibility;
+ public String color;
+ public int useScore;
+ public String url;
+ }
+
public static class BEDQuery
{
private String coordinate;
private Locus queryRange;
-
private List<BEDGene> geneList = new ArrayList<BEDGene>();
+ public BEDTrack track;
+
public BEDQuery(String coordinate, long startOnGenome, long endOnGenome)
{
this.coordinate = coordinate;
}
+ @Test
+ public void canonicalNameTest() throws Exception
+ {
+ assertEquals("itemrgb", ObjectLens.getCanonicalParameterName("itemRgb"));
+ assertEquals("itemref", ObjectLens.getCanonicalParameterName("item_ref"));
+ assertEquals("helloworld", ObjectLens.getCanonicalParameterName("Hello World"));
+ assertEquals("helloworld", ObjectLens.getCanonicalParameterName("Hello-World"));
+
+ }
+
}
\r
-track(name:"Item,RGB,Demo2", description:"Item RGBdemonstration2", visibility:2, itemRgb:"On", useScore:1, color:"0,128,0", url:"http://genome.ucsc.edu/goldenPath/help/clones.html#$$")\r
-gene(coordinate, start, end, name, strand, cds(start, end), exon(start, end)*, color, _[json])|\r
-chr7 127471197 127472364 Pos1 + [127471197, 127472364] #ff0000 {"score":300}\r
-chr7 127472364 127473531 Pos2 + [127472364, 127473531] #ff0000 {"score":200}\r
-chr7 127473531 127474698 Pos3 + [127473531, 127474698] #ff0000 {"score":900}\r
-chr7 127474698 127475865 Pos4 + [127474698, 127475865] #ff0000 {"score":400}\r
-chr7 127475865 127477032 Neg1 - [127475865, 127477032] #0000ff {"score":100}\r
-chr7 127477032 127478199 Neg2 - [127477032, 127478199] #0000ff {"score":500}\r
-chr7 127478199 127479366 Neg3 - [127478199, 127479366] #0000ff {"score":200}\r
-chr7 127479366 127480533 Pos5 + [127479366, 127480533] #ff0000 {"score":200}\r
-chr7 127480533 127481700 Neg4 - [127480533, 127481700] #0000ff {"score":600}\r
+chr7 127471197 127472364 Pos1 + [127471197, 127472364] "#ff0000" {"score":300}\r
+chr7 127472364 127473531 Pos2 + [127472364, 127473531] "#ff0000" {"score":200}\r
+chr7 127473531 127474698 Pos3 + [127473531, 127474698] "#ff0000" {"score":900}\r
+chr7 127474698 127475865 Pos4 + [127474698, 127475865] "#ff0000" {"score":400}\r
+chr7 127475865 127477032 Neg1 - [127475865, 127477032] "#0000ff" {"score":100}\r
+chr7 127477032 127478199 Neg2 - [127477032, 127478199] "#0000ff" {"score":500}\r
+chr7 127478199 127479366 Neg3 - [127478199, 127479366] "#0000ff" {"score":200}\r
+chr7 127479366 127480533 Pos5 + [127479366, 127480533] "#ff0000" {"score":200}\r
+chr7 127480533 127481700 Neg4 - [127480533, 127481700] "#0000ff" {"score":600}\r
chr22 2001 7001 itemB - [2201, 6951] [[1, 433], [501, 600], [2001, 2550], [3501, 5000]] {"score":200}\r
chr22 2001 6001 cloneB - [2001, 6001] [[1, 433], [3602, 4000]] {"score":900}\r
chr22 1001 5001 itemA + [1101, 4701] [[1, 1567], [2513, 4000]] {"score":960}\r
chr7 127472364 127473531 Pos2 {"score":200}\r
chr7 127472364 127473531 Pos2 + {"score":200}\r
chr7 127472364 127473531 Pos2 + [127472364, 127473531] {"score":200}\r
-chr7 127472364 127473531 Pos2 + [127472364, 127473531] #ff0000 {"score":200}
\ No newline at end of file
+chr7 127472364 127473531 Pos2 + [127472364, 127473531] "#ff0000" {"score":200}
\ No newline at end of file