SPOI-5338 #resolve cleanup of operator discoverer class to replace reflection with ASM Addressed review comments
Project: http://git-wip-us.apache.org/repos/asf/incubator-apex-core/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-apex-core/commit/ba46e71f Tree: http://git-wip-us.apache.org/repos/asf/incubator-apex-core/tree/ba46e71f Diff: http://git-wip-us.apache.org/repos/asf/incubator-apex-core/diff/ba46e71f Branch: refs/heads/master Commit: ba46e71f5744e4e822d0f11a35e00b28ee91edb9 Parents: fe5d035 Author: ishark <[email protected]> Authored: Tue Jul 7 16:40:23 2015 -0700 Committer: ishark <[email protected]> Committed: Thu Aug 13 14:38:12 2015 -0700 ---------------------------------------------------------------------- .../java/com/datatorrent/stram/cli/DTCli.java | 18 +- .../stram/webapp/OperatorDiscoverer.java | 204 +++++++++---------- .../stram/webapp/StramWebServices.java | 8 +- .../com/datatorrent/stram/webapp/TypeGraph.java | 86 ++++++-- .../stram/webapp/OperatorDiscoveryTest.java | 9 +- 5 files changed, 175 insertions(+), 150 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-apex-core/blob/ba46e71f/engine/src/main/java/com/datatorrent/stram/cli/DTCli.java ---------------------------------------------------------------------- diff --git a/engine/src/main/java/com/datatorrent/stram/cli/DTCli.java b/engine/src/main/java/com/datatorrent/stram/cli/DTCli.java index eff2404..ff6e84c 100644 --- a/engine/src/main/java/com/datatorrent/stram/cli/DTCli.java +++ b/engine/src/main/java/com/datatorrent/stram/cli/DTCli.java @@ -86,7 +86,6 @@ import com.datatorrent.stram.plan.logical.LogicalPlan; import com.datatorrent.stram.plan.logical.requests.*; import com.datatorrent.stram.security.StramUserLogin; import com.datatorrent.stram.util.JSONSerializationProvider; -import com.datatorrent.stram.util.ObjectMapperFactory; import com.datatorrent.stram.util.VersionInfo; import com.datatorrent.stram.util.WebServicesClient; import com.datatorrent.stram.webapp.OperatorDiscoverer; @@ -3002,26 +3001,22 @@ public class DTCli String[] jarFiles = files.split(","); File tmpDir = copyToLocal(jarFiles); try { - ObjectMapper defaultValueMapper = ObjectMapperFactory.getOperatorValueSerializer(); - OperatorDiscoverer operatorDiscoverer = new OperatorDiscoverer(jarFiles); String searchTerm = commandLineInfo.args.length > 1 ? commandLineInfo.args[1] : null; - Set<Class<? extends Operator>> operatorClasses = operatorDiscoverer.getOperatorClasses(parentName, searchTerm); + Set<String> operatorClasses = operatorDiscoverer.getOperatorClasses(parentName, searchTerm); JSONObject json = new JSONObject(); JSONArray arr = new JSONArray(); JSONObject portClassHier = new JSONObject(); + JSONObject portTypesWithSchemaClasses = new JSONObject(); JSONObject failed = new JSONObject(); - JSONObject portTypesWithSchemaClasses = new JSONObject(); - for (Class<? extends Operator> clazz : operatorClasses) { + for (final String clazz : operatorClasses) { try { JSONObject oper = operatorDiscoverer.describeOperator(clazz); // add default value - Operator operIns = clazz.newInstance(); - String s = defaultValueMapper.writeValueAsString(operIns); - oper.put("defaultValue", new JSONObject(s).get(clazz.getName())); + operatorDiscoverer.addDefaultValue(clazz, oper); // add class hierarchy info to portClassHier and fetch port types with schema classes operatorDiscoverer.buildAdditionalPortInfo(oper, portClassHier, portTypesWithSchemaClasses); @@ -3036,7 +3031,7 @@ public class DTCli arr.put(oper); } catch (Exception | NoClassDefFoundError ex) { // ignore this class - final String cls = clazz.getName(); + final String cls = clazz; failed.put(cls, ex.toString()); } } @@ -3053,7 +3048,6 @@ public class DTCli FileUtils.deleteDirectory(tmpDir); } } - } private class GetJarOperatorPropertiesCommand implements Command @@ -3070,7 +3064,7 @@ public class DTCli try { OperatorDiscoverer operatorDiscoverer = new OperatorDiscoverer(jarFiles); Class<? extends Operator> operatorClass = operatorDiscoverer.getOperatorClass(args[2]); - printJson(operatorDiscoverer.describeOperator(operatorClass)); + printJson(operatorDiscoverer.describeOperator(operatorClass.getName())); } finally { FileUtils.deleteDirectory(tmpDir); } http://git-wip-us.apache.org/repos/asf/incubator-apex-core/blob/ba46e71f/engine/src/main/java/com/datatorrent/stram/webapp/OperatorDiscoverer.java ---------------------------------------------------------------------- diff --git a/engine/src/main/java/com/datatorrent/stram/webapp/OperatorDiscoverer.java b/engine/src/main/java/com/datatorrent/stram/webapp/OperatorDiscoverer.java index 004c100..0867b03 100644 --- a/engine/src/main/java/com/datatorrent/stram/webapp/OperatorDiscoverer.java +++ b/engine/src/main/java/com/datatorrent/stram/webapp/OperatorDiscoverer.java @@ -15,10 +15,11 @@ */ package com.datatorrent.stram.webapp; -import com.datatorrent.api.InputOperator; import com.datatorrent.api.Operator; import com.datatorrent.netlet.util.DTThrowable; +import com.datatorrent.stram.util.ObjectMapperFactory; import com.datatorrent.stram.webapp.TypeDiscoverer.UI_TYPE; +import com.datatorrent.stram.webapp.TypeGraph.TypeGraphVertex; import com.datatorrent.stram.webapp.asm.CompactAnnotationNode; import com.datatorrent.stram.webapp.asm.CompactFieldNode; import com.google.common.base.Predicate; @@ -43,8 +44,11 @@ import java.util.regex.Pattern; import javax.xml.parsers.*; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang.ClassUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.text.WordUtils; +import org.codehaus.jackson.map.ObjectMapper; import org.codehaus.jettison.json.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -62,17 +66,7 @@ import org.xml.sax.helpers.DefaultHandler; public class OperatorDiscoverer { public static final String GENERATED_CLASSES_JAR = "_generated-classes.jar"; - - private static class ClassComparator implements Comparator<Class<?>> { - - @Override - public int compare(Class<?> a, Class<?> b) - { - return a.getName().compareTo(b.getName()); - } - - } - private final Set<Class<? extends Operator>> operatorClasses = new TreeSet<Class<? extends Operator>>(new ClassComparator()); + private Set<String> operatorClassNames; private static final Logger LOG = LoggerFactory.getLogger(OperatorDiscoverer.class); private final List<String> pathsToScan = new ArrayList<String>(); private final ClassLoader classLoader; @@ -261,26 +255,21 @@ public class OperatorDiscoverer classLoader = new URLClassLoader(urls, ClassLoader.getSystemClassLoader()); } - - @SuppressWarnings({ "unchecked" }) private void loadOperatorClass() { buildTypeGraph(); - String operatorRoot = Operator.class.getName(); - Set<String> allOperatorClasses = typeGraph.getDescendants(operatorRoot); -// ClassLoader cLoader = new URLClassLoader(); - for (String opClassName : allOperatorClasses) { - try { - Class<?> clazz = classLoader.loadClass(opClassName); -// typeGraph.get(opClassName).loadedClass = clazz; - if (isInstantiableOperatorClass(clazz)) { - LOG.debug("Adding class {} as an operator", clazz.getName()); - operatorClasses.add((Class<? extends Operator>)clazz); - } - } - catch (Throwable ex) { - LOG.warn("Class cannot be loaded: {} (error was {})", opClassName, ex.getMessage()); - } + operatorClassNames = typeGraph.getAllDTInstantiableOperators(); + } + + @SuppressWarnings("unchecked") + public void addDefaultValue(String className, JSONObject oper) throws Exception + { + ObjectMapper defaultValueMapper = ObjectMapperFactory.getOperatorValueSerializer(); + Class<? extends Operator> clazz = (Class<? extends Operator>) classLoader.loadClass(className); + if (clazz != null) { + Operator operIns = clazz.newInstance(); + String s = defaultValueMapper.writeValueAsString(operIns); + oper.put("defaultValue", new JSONObject(s).get(className)); } } @@ -346,70 +335,51 @@ public class OperatorDiscoverer saxParserFactory.newSAXParser().parse(is, new JavadocSAXHandler()); } - public static boolean isInstantiableOperatorClass(Class<?> clazz) - { - int modifiers = clazz.getModifiers(); - if (Modifier.isAbstract(modifiers) || Modifier.isInterface(modifiers) || !Operator.class.isAssignableFrom(clazz)){ - return false; - } - // return true if it is an InputOperator or if it is an Operator with more than one InputPort - //TODO Use ASM later - return InputOperator.class.isAssignableFrom(clazz) || Iterables.any(Arrays.asList(clazz.getFields()), new Predicate<Field>() { - @Override - public boolean apply(Field f) - { - return Operator.InputPort.class.isAssignableFrom(f.getType()); - } - }); - } - - public Set<Class<? extends Operator>> getOperatorClasses(String parent, String searchTerm) throws ClassNotFoundException + public Set<String> getOperatorClasses(String parent, String searchTerm) throws ClassNotFoundException { - if (operatorClasses.isEmpty()) { + if (CollectionUtils.isEmpty(operatorClassNames)) { loadOperatorClass(); } - Class<?> parentClass; if (parent == null) { - parentClass = Operator.class; - } - else { - parentClass = classLoader.loadClass(parent); - if (!Operator.class.isAssignableFrom(parentClass)) { + parent = Operator.class.getName(); + } else { + if (!typeGraph.isAncestor(Operator.class.getName(), parent)) { throw new IllegalArgumentException("Argument must be a subclass of Operator class"); } } - Set<Class<? extends Operator>> filteredClass = Sets.filter(operatorClasses, new Predicate<Class<? extends Operator>>() { + Set<String> filteredClass = Sets.filter(operatorClassNames, new Predicate<String>() + { @Override - public boolean apply(Class<? extends Operator> c) + public boolean apply(String className) { - OperatorClassInfo oci = classInfo.get(c.getName()); + OperatorClassInfo oci = classInfo.get(className); return oci == null || !oci.tags.containsKey("@omitFromUI"); } }); - if (searchTerm == null && parentClass == Operator.class) { - return Collections.unmodifiableSet(filteredClass); + + if (searchTerm == null && parent == Operator.class.getName()) { + return filteredClass; } + if (searchTerm != null) { searchTerm = searchTerm.toLowerCase(); } - Set<Class<? extends Operator>> result = new HashSet<Class<? extends Operator>>(); - for (Class<? extends Operator> clazz : filteredClass) { - if (parentClass.isAssignableFrom(clazz)) { + + Set<String> result = new HashSet<String>(); + for (String clazz : filteredClass) { + if (parent == Operator.class.getName() || typeGraph.isAncestor(parent, clazz)) { if (searchTerm == null) { result.add(clazz); - } - else { - if (clazz.getName().toLowerCase().contains(searchTerm)) { + } else { + if (clazz.toLowerCase().contains(searchTerm)) { result.add(clazz); - } - else { - OperatorClassInfo oci = classInfo.get(clazz.getName()); + } else { + OperatorClassInfo oci = classInfo.get(clazz); if (oci != null) { if (oci.comment != null && oci.comment.toLowerCase().contains(searchTerm)) { result.add(clazz); - } - else { + } else { for (Map.Entry<String, String> entry : oci.tags.entrySet()) { if (entry.getValue().toLowerCase().contains(searchTerm)) { result.add(clazz); @@ -428,7 +398,7 @@ public class OperatorDiscoverer @SuppressWarnings("unchecked") public Class<? extends Operator> getOperatorClass(String className) throws ClassNotFoundException { - if (operatorClasses.isEmpty()) { + if (CollectionUtils.isEmpty(operatorClassNames)) { loadOperatorClass(); } @@ -440,23 +410,24 @@ public class OperatorDiscoverer return (Class<? extends Operator>)clazz; } - public JSONObject describeOperator(Class<? extends Operator> clazz) throws Exception + public JSONObject describeOperator(String clazz) throws Exception { - if (OperatorDiscoverer.isInstantiableOperatorClass(clazz)) { + TypeGraphVertex tgv = typeGraph.getTypeGraphVertex(clazz); + if (tgv.isInstantiable()) { JSONObject response = new JSONObject(); JSONArray inputPorts = new JSONArray(); JSONArray outputPorts = new JSONArray(); // Get properties from ASM - JSONObject operatorDescriptor = describeClassByASM(clazz.getName()); + JSONObject operatorDescriptor = describeClassByASM(clazz); JSONArray properties = operatorDescriptor.getJSONArray("properties"); properties = enrichProperties(clazz, properties); JSONArray portTypeInfo = operatorDescriptor.getJSONArray("portTypeInfo"); - List<CompactFieldNode> inputPortfields = typeGraph.getAllInputPorts(clazz.getName()); - List<CompactFieldNode> outputPortfields = typeGraph.getAllOutputPorts(clazz.getName()); + List<CompactFieldNode> inputPortfields = typeGraph.getAllInputPorts(clazz); + List<CompactFieldNode> outputPortfields = typeGraph.getAllOutputPorts(clazz); try { @@ -486,13 +457,13 @@ public class OperatorDiscoverer outputPorts.put(outputPort); } - response.put("name", clazz.getName()); + response.put("name", clazz); response.put("properties", properties); response.put(PORT_TYPE_INFO_KEY, portTypeInfo); response.put("inputPorts", inputPorts); response.put("outputPorts", outputPorts); - OperatorClassInfo oci = classInfo.get(clazz.getName()); + OperatorClassInfo oci = classInfo.get(clazz); if (oci != null) { if (oci.comment != null) { @@ -515,7 +486,7 @@ public class OperatorDiscoverer response.put("category", oci.tags.get("@category")); String displayName = oci.tags.get("@displayName"); if (displayName == null) { - displayName = decamelizeClassName(clazz.getSimpleName()); + displayName = decamelizeClassName(ClassUtils.getShortClassName(clazz)); } response.put("displayName", displayName); String tags = oci.tags.get("@tags"); @@ -530,9 +501,9 @@ public class OperatorDiscoverer if (doclink != null) { response.put("doclink", doclink + "?" + getDocName(clazz)); } - else if (clazz.getName().startsWith("com.datatorrent.lib.") || - clazz.getName().startsWith("com.datatorrent.contrib.")) { - response.put("doclink", DT_OPERATOR_DOCLINK_PREFIX + "?" + getDocName(clazz)); + else if (clazz.startsWith("com.datatorrent.lib.") || + clazz.startsWith("com.datatorrent.contrib.")) { + response.put("doclink", DT_OPERATOR_DOCLINK_PREFIX + "?" + getDocName(clazz)); } } } @@ -546,29 +517,18 @@ public class OperatorDiscoverer } } - private JSONObject setFieldAttributes(Class<? extends Operator> clazz, - CompactFieldNode field) throws JSONException { + private JSONObject setFieldAttributes(String clazz, CompactFieldNode field) throws JSONException + { JSONObject port = new JSONObject(); port.put("name", field.getName()); - for (Class<?> c = clazz; c != null; c = c.getSuperclass()) { - OperatorClassInfo oci = classInfo.get(c.getName()); - if (oci != null) { - String fieldDesc = oci.fields.get(field.getName()); - if (fieldDesc != null) { - port.put("description", fieldDesc); - break; - } - } - } + TypeGraphVertex tgv = typeGraph.getTypeGraphVertex(clazz); + putFieldDescription(field, port, tgv); List<CompactAnnotationNode> annotations = field.getVisibleAnnotations(); CompactAnnotationNode firstAnnotation; - if (annotations != null - && !annotations.isEmpty() - && (firstAnnotation = field - .getVisibleAnnotations().get(0)) != null) { - for(Map.Entry<String, Object> entry :firstAnnotation.getAnnotations().entrySet() ) { + if (annotations != null && !annotations.isEmpty() && (firstAnnotation = field.getVisibleAnnotations().get(0)) != null) { + for (Map.Entry<String, Object> entry : firstAnnotation.getAnnotations().entrySet()) { port.put(entry.getKey(), entry.getValue()); } } @@ -576,7 +536,23 @@ public class OperatorDiscoverer return port; } - private JSONArray enrichProperties(Class<?> operatorClass, JSONArray properties) throws JSONException + private void putFieldDescription(CompactFieldNode field, JSONObject port, TypeGraphVertex tgv) throws JSONException + { + OperatorClassInfo oci = classInfo.get(tgv.typeName); + if (oci != null) { + String fieldDesc = oci.fields.get(field.getName()); + if (fieldDesc != null) { + port.put("description", fieldDesc); + return; + } + } + + for (TypeGraphVertex ancestor : tgv.getAncestors()) { + putFieldDescription(field, port, ancestor); + } + } + + private JSONArray enrichProperties(String operatorClass, JSONArray properties) throws JSONException { JSONArray result = new JSONArray(); for (int i = 0; i < properties.length(); i++) { @@ -602,16 +578,26 @@ public class OperatorDiscoverer return result; } - private OperatorClassInfo getOperatorClassWithGetterSetter(Class<?> operatorClass, String setterName, String getterName) { - if(operatorClass != null && !Operator.class.isAssignableFrom(operatorClass)){ - return null; - } - OperatorClassInfo oci = classInfo.get(operatorClass.getName()); - if(oci != null && (oci.getMethods.containsKey(getterName) || oci.setMethods.containsKey(setterName))){ + private OperatorClassInfo getOperatorClassWithGetterSetter(String operatorClass, String setterName, String getterName) + { + TypeGraphVertex tgv = typeGraph.getTypeGraphVertex(operatorClass); + return getOperatorClassWithGetterSetter(tgv, setterName, getterName); + } + + private OperatorClassInfo getOperatorClassWithGetterSetter(TypeGraphVertex tgv, String setterName, String getterName) + { + OperatorClassInfo oci = classInfo.get(tgv.typeName); + if (oci != null && (oci.getMethods.containsKey(getterName) || oci.setMethods.containsKey(setterName))) { return oci; } else { - return getOperatorClassWithGetterSetter(operatorClass.getSuperclass(), setterName, getterName); + if (tgv.getAncestors() != null) { + for (TypeGraphVertex ancestor : tgv.getAncestors()) { + return getOperatorClassWithGetterSetter(ancestor, setterName, getterName); + } + } } + + return null; } private void addTagsToProperties(MethodInfo mi, JSONObject propJ) throws JSONException @@ -675,9 +661,9 @@ public class OperatorDiscoverer } - private static String getDocName(Class<?> clazz) + private static String getDocName(String clazz) { - return clazz.getName().replace('.', '/').replace('$', '.') + ".html"; + return clazz.replace('.', '/').replace('$', '.') + ".html"; } private JSONArray getClassProperties(Class<?> clazz, int level) throws IntrospectionException http://git-wip-us.apache.org/repos/asf/incubator-apex-core/blob/ba46e71f/engine/src/main/java/com/datatorrent/stram/webapp/StramWebServices.java ---------------------------------------------------------------------- diff --git a/engine/src/main/java/com/datatorrent/stram/webapp/StramWebServices.java b/engine/src/main/java/com/datatorrent/stram/webapp/StramWebServices.java index 010a976..97edf39 100644 --- a/engine/src/main/java/com/datatorrent/stram/webapp/StramWebServices.java +++ b/engine/src/main/java/com/datatorrent/stram/webapp/StramWebServices.java @@ -288,11 +288,11 @@ public class StramWebServices } try { - Set<Class<? extends Operator>> operatorClasses = operatorDiscoverer.getOperatorClasses(parent, searchTerm); + Set<String> operatorClasses = operatorDiscoverer.getOperatorClasses(parent, searchTerm); - for (Class<?> clazz : operatorClasses) { + for (String clazz : operatorClasses) { JSONObject j = new JSONObject(); - j.put("name", clazz.getName()); + j.put("name", clazz); classNames.put(j); } @@ -318,7 +318,7 @@ public class StramWebServices try { Class<?> clazz = Class.forName(className); if (Operator.class.isAssignableFrom(clazz)) { - return operatorDiscoverer.describeOperator((Class<? extends Operator>)clazz); + return operatorDiscoverer.describeOperator(className); } else { throw new NotFoundException(); http://git-wip-us.apache.org/repos/asf/incubator-apex-core/blob/ba46e71f/engine/src/main/java/com/datatorrent/stram/webapp/TypeGraph.java ---------------------------------------------------------------------- diff --git a/engine/src/main/java/com/datatorrent/stram/webapp/TypeGraph.java b/engine/src/main/java/com/datatorrent/stram/webapp/TypeGraph.java index 61dc99d..d0b34c2 100644 --- a/engine/src/main/java/com/datatorrent/stram/webapp/TypeGraph.java +++ b/engine/src/main/java/com/datatorrent/stram/webapp/TypeGraph.java @@ -37,6 +37,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.datatorrent.api.Component; +import com.datatorrent.api.InputOperator; import com.datatorrent.api.Operator; import com.datatorrent.netlet.util.DTThrowable; import com.datatorrent.stram.webapp.asm.ClassNodeType; @@ -91,6 +92,22 @@ public class TypeGraph JACKSON_INSTANTIABLE_CLASSES = b.build(); } + public boolean isAncestor(String parentClassName, String subClassName) + { + TypeGraphVertex parentVertex = typeGraph.get(parentClassName); + TypeGraphVertex classVertex = typeGraph.get(subClassName); + + if(parentVertex == null || classVertex == null) + return false; + + return TypeGraph.isAncestor(parentVertex, classVertex); + } + + public TypeGraphVertex getTypeGraphVertex(String className) + { + return typeGraph.get(className); + } + private static boolean isAncestor(TypeGraphVertex typeTgv, TypeGraphVertex tgv) { if (tgv == typeTgv) { @@ -368,6 +385,22 @@ public class TypeGraph return typeGraph.size(); } + public Set<String> getAllDTInstantiableOperators() + { + TypeGraphVertex tgv = typeGraph.get(Operator.class.getName()); + if (tgv == null) { + return null; + } + Set<String> result = new TreeSet<String>(); + for (TypeGraphVertex node : tgv.allInstantiableDescendants) { + if ((isAncestor(InputOperator.class.getName(), node.typeName) || !getAllInputPorts(node).isEmpty())) { + result.add(node.typeName); + } + } + + return result; + } + public Set<String> getDescendants(String fullClassName) { Set<String> result = new HashSet<String>(); @@ -456,6 +489,10 @@ public class TypeGraph this.classNode = classNode; } + public Set<TypeGraphVertex> getAncestors() + { + return ancestors; + } public int numberOfInstantiableDescendants() { return allInstantiableDescendants.size() + (isInstantiable() ? 1 : 0); @@ -467,7 +504,7 @@ public class TypeGraph this.jarName = jarName; } - private boolean isInstantiable() + public boolean isInstantiable() { return JACKSON_INSTANTIABLE_CLASSES.contains(this.typeName) || (isPublicConcrete() && classNode.getDefaultConstructor() != null); } @@ -682,9 +719,17 @@ public class TypeGraph return null; } - public List<CompactFieldNode> getAllInputPorts(String clazzName) { + public List<CompactFieldNode> getAllInputPorts(String clazzName) + { TypeGraphVertex tgv = typeGraph.get(clazzName); + return getAllInputPorts(tgv); + } + + public List<CompactFieldNode> getAllInputPorts(TypeGraphVertex tgv) + { List<CompactFieldNode> ports = new ArrayList<CompactFieldNode>(); + if (tgv == null) + return ports; TypeGraphVertex portVertex = typeGraph.get(Operator.InputPort.class .getName()); getAllPortsWithAncestor(portVertex, tgv, ports); @@ -694,26 +739,28 @@ public class TypeGraph return a.getName().compareTo(b.getName()); } }); + return ports; } - public List<CompactFieldNode> getAllOutputPorts(String clazzName) { + public List<CompactFieldNode> getAllOutputPorts(String clazzName) + { TypeGraphVertex tgv = typeGraph.get(clazzName); List<CompactFieldNode> ports = new ArrayList<CompactFieldNode>(); - TypeGraphVertex portVertex = typeGraph.get(Operator.OutputPort.class - .getName()); + TypeGraphVertex portVertex = typeGraph.get(Operator.OutputPort.class.getName()); getAllPortsWithAncestor(portVertex, tgv, ports); - Collections.sort(ports, new Comparator<CompactFieldNode>() { + Collections.sort(ports, new Comparator<CompactFieldNode>() + { @Override - public int compare(CompactFieldNode a, CompactFieldNode b) { + public int compare(CompactFieldNode a, CompactFieldNode b) + { return a.getName().compareTo(b.getName()); } }); return ports; } - - private void getAllPortsWithAncestor(TypeGraphVertex portVertex, - TypeGraphVertex tgv, List<CompactFieldNode> ports) + + private void getAllPortsWithAncestor(TypeGraphVertex portVertex, TypeGraphVertex tgv, List<CompactFieldNode> ports) { List<CompactFieldNode> fields = tgv.getClassNode().getPorts(); if (fields != null) { @@ -730,21 +777,22 @@ public class TypeGraph } } - private void addClassPropertiesAndPorts(String clazzName, JSONObject desc) throws JSONException { + private void addClassPropertiesAndPorts(String clazzName, JSONObject desc) throws JSONException + { TypeGraphVertex tgv = typeGraph.get(clazzName); if (tgv == null) { return; } Map<String, JSONObject> results = new TreeMap<String, JSONObject>(); - List<CompactMethodNode> getters = new LinkedList<CompactMethodNode>(); + List<CompactMethodNode> getters = new LinkedList<CompactMethodNode>(); List<CompactMethodNode> setters = new LinkedList<CompactMethodNode>(); Map<Type, Type> typeReplacement = new HashMap<Type, Type>(); - List<CompactFieldNode> ports = new LinkedList<CompactFieldNode>(); - + List<CompactFieldNode> ports = new LinkedList<CompactFieldNode>(); + getPublicSetterGetterAndPorts(tgv, setters, getters, typeReplacement, ports); desc.put("portTypeInfo", getPortTypeInfo(clazzName, typeReplacement, ports)); - + for (CompactMethodNode setter : setters) { String prop = WordUtils.uncapitalize(setter.getName().substring(3)); JSONObject propJ = results.get(prop); @@ -756,13 +804,12 @@ public class TypeGraph propJ.put("canSet", true); propJ.put("canGet", false); - MethodSignatureVisitor msv = null; msv = setter.getMethodSignatureNode(); - if(msv==null){ + if (msv == null) { continue; } - + List<Type> param = msv.getParameters(); if (CollectionUtils.isEmpty(param)) { propJ.put("type", "UNKNOWN"); @@ -788,10 +835,9 @@ public class TypeGraph MethodSignatureVisitor msv = null; msv = getter.getMethodSignatureNode(); - if(msv==null){ + if (msv == null) { continue; } - Type rt = msv.getReturnType(); if (rt == null) { http://git-wip-us.apache.org/repos/asf/incubator-apex-core/blob/ba46e71f/engine/src/test/java/com/datatorrent/stram/webapp/OperatorDiscoveryTest.java ---------------------------------------------------------------------- diff --git a/engine/src/test/java/com/datatorrent/stram/webapp/OperatorDiscoveryTest.java b/engine/src/test/java/com/datatorrent/stram/webapp/OperatorDiscoveryTest.java index 8baa08a..0f2fc13 100644 --- a/engine/src/test/java/com/datatorrent/stram/webapp/OperatorDiscoveryTest.java +++ b/engine/src/test/java/com/datatorrent/stram/webapp/OperatorDiscoveryTest.java @@ -190,7 +190,8 @@ public class OperatorDiscoveryTest String[] classFilePath = getClassFileInClasspath(); OperatorDiscoverer operatorDiscoverer = new OperatorDiscoverer(classFilePath); operatorDiscoverer.buildTypeGraph(); - JSONObject oper = operatorDiscoverer.describeOperator(SubSubClassGeneric.class); + JSONObject oper = operatorDiscoverer.describeOperator(SubSubClassGeneric.class.getName()); + String debug = "\n(ASM)type info for " + TestOperator.class + ":\n" + oper.toString(2) + "\n"; JSONArray props = oper.getJSONArray("properties"); @@ -277,8 +278,6 @@ public class OperatorDiscoveryTest od.buildTypeGraph(); Assert.assertNotNull(od.getOperatorClass(BaseOperator.class.getName())); - Assert.assertFalse("Base Operator is not instantiable because it is not an InputOperator and it has no input port ", - OperatorDiscoverer.isInstantiableOperatorClass(BaseOperator.class)); JSONObject asmDesc = od.describeClassByASM(TestOperator.class.getName()); String debug = "\n(ASM)type info for " + TestOperator.class + ":\n" + asmDesc.toString(2) + "\n"; @@ -1057,7 +1056,7 @@ public class OperatorDiscoveryTest String[] classFilePath = getClassFileInClasspath(); OperatorDiscoverer od = new OperatorDiscoverer(classFilePath); od.buildTypeGraph(); - JSONObject operatorJson = od.describeOperator(SchemaRequiredOperator.class); + JSONObject operatorJson = od.describeOperator(SchemaRequiredOperator.class.getName()); JSONArray portsJson = operatorJson.getJSONArray("outputPorts"); Assert.assertEquals("no. of ports", 3, portsJson.length()); @@ -1081,7 +1080,7 @@ public class OperatorDiscoveryTest String[] classFilePath = getClassFileInClasspath(); OperatorDiscoverer operatorDiscoverer = new OperatorDiscoverer(classFilePath); operatorDiscoverer.buildTypeGraph(); - JSONObject operator = operatorDiscoverer.describeOperator(SubSubClassGeneric.class); + JSONObject operator = operatorDiscoverer.describeOperator(SubSubClassGeneric.class.getName()); JSONObject portClassHierarchy = new JSONObject(); JSONObject portsWithSchemaClasses = new JSONObject();
