RLPark 1.0.0
Reinforcement Learning Framework in Java
|
00001 package zephyr.plugin.core.api.internal.codeparser.parsers; 00002 00003 import java.lang.reflect.Field; 00004 import java.lang.reflect.InvocationTargetException; 00005 import java.lang.reflect.Method; 00006 import java.util.Arrays; 00007 import java.util.Comparator; 00008 import java.util.HashMap; 00009 import java.util.LinkedHashMap; 00010 import java.util.LinkedList; 00011 import java.util.Map; 00012 import java.util.Stack; 00013 00014 import zephyr.plugin.core.api.internal.codeparser.codetree.ClassNode; 00015 import zephyr.plugin.core.api.internal.codeparser.codetree.CodeTrees; 00016 import zephyr.plugin.core.api.internal.codeparser.codetree.PrimitiveNode; 00017 import zephyr.plugin.core.api.internal.codeparser.interfaces.CodeNode; 00018 import zephyr.plugin.core.api.internal.codeparser.interfaces.CodeParser; 00019 import zephyr.plugin.core.api.internal.codeparser.interfaces.FieldParser; 00020 import zephyr.plugin.core.api.internal.codeparser.interfaces.MutableParentNode; 00021 import zephyr.plugin.core.api.internal.parsing.CollectionLabelBuilder; 00022 import zephyr.plugin.core.api.monitoring.abstracts.DataMonitor; 00023 import zephyr.plugin.core.api.monitoring.abstracts.LabeledCollection; 00024 import zephyr.plugin.core.api.monitoring.abstracts.MonitorContainer; 00025 import zephyr.plugin.core.api.monitoring.abstracts.Monitored; 00026 import zephyr.plugin.core.api.monitoring.annotations.IgnoreMonitor; 00027 import zephyr.plugin.core.api.monitoring.annotations.LabelProvider; 00028 import zephyr.plugin.core.api.monitoring.annotations.Monitor; 00029 00030 public class CodeTreeParser implements CodeParser { 00031 static private LinkedList<FieldParser> parsers = new LinkedList<FieldParser>(); 00032 static private Stack<Map<String, LabeledCollection>> staticLabelsMapStack = new Stack<Map<String, LabeledCollection>>(); 00033 00034 static { 00035 registerParser(new ObjectParser()); 00036 registerParser(new ObjectCollectionParser()); 00037 registerParser(new ObjectArrayParser()); 00038 registerParser(new PrimitiveArrayParser()); 00039 registerParser(new PrimitiveCollectionParser()); 00040 registerParser(new PrimitiveParser()); 00041 } 00042 00043 private final Stack<Map<String, LabeledCollection>> labelsMapStack = new Stack<Map<String, LabeledCollection>>(); 00044 private final int requiredLevel; 00045 00046 public CodeTreeParser(int requiredLevel) { 00047 labelsMapStack.addAll(staticLabelsMapStack); 00048 this.requiredLevel = requiredLevel; 00049 } 00050 00051 public static void registerLabeledCollection(LabeledCollection labeledCollection, String... ids) { 00052 Map<String, LabeledCollection> map = new HashMap<String, LabeledCollection>(); 00053 for (String id : ids) 00054 map.put(id, labeledCollection); 00055 staticLabelsMapStack.push(map); 00056 } 00057 00058 static private Field[] getFieldList(Class<?> objectClass) { 00059 Field[] fields = objectClass.getDeclaredFields(); 00060 Arrays.sort(fields, new Comparator<Field>() { 00061 @Override 00062 public int compare(Field o1, Field o2) { 00063 return o1.getName().compareTo(o2.getName()); 00064 } 00065 }); 00066 return fields; 00067 } 00068 00069 static private void addLabelMaps(Map<String, LabeledCollection> labelsMap, final Method method, final Object container) { 00070 LabeledCollection labeledElement = new LabeledCollection() { 00071 @Override 00072 public String label(int index) { 00073 try { 00074 return (String) method.invoke(container, index); 00075 } catch (IllegalArgumentException e) { 00076 e.printStackTrace(); 00077 } catch (IllegalAccessException e) { 00078 e.printStackTrace(); 00079 } catch (InvocationTargetException e) { 00080 e.printStackTrace(); 00081 } 00082 return "error"; 00083 } 00084 }; 00085 LabelProvider annotation = method.getAnnotation(LabelProvider.class); 00086 for (String id : annotation.ids()) 00087 labelsMap.put(id, labeledElement); 00088 } 00089 00090 static private Map<String, LabeledCollection> buildLabelMaps(Object container) { 00091 Class<?> objectClass = container.getClass(); 00092 Map<String, LabeledCollection> labelsMaps = new LinkedHashMap<String, LabeledCollection>(); 00093 while (objectClass != null) { 00094 for (Method method : objectClass.getDeclaredMethods()) { 00095 if (!method.isAnnotationPresent(LabelProvider.class)) 00096 continue; 00097 method.setAccessible(true); 00098 addLabelMaps(labelsMaps, method, container); 00099 } 00100 objectClass = objectClass.getSuperclass(); 00101 } 00102 return labelsMaps; 00103 } 00104 00105 private boolean isMonitored(ClassNode classNode, Field field) { 00106 if (field.isSynthetic() || field.isAnnotationPresent(IgnoreMonitor.class)) 00107 return false; 00108 Monitor monitor = field.getDeclaringClass().getAnnotation(Monitor.class); 00109 if (field.isAnnotationPresent(Monitor.class)) 00110 monitor = field.getAnnotation(Monitor.class); 00111 if (monitor == null) 00112 return false; 00113 return monitor.level() <= requiredLevel; 00114 } 00115 00116 @Override 00117 public CodeNode recursiveParseInstance(MutableParentNode parentNode, Field fieldInstance, String instanceLabel, 00118 Object instance) { 00119 for (FieldParser parser : parsers) { 00120 if (parser.canParse(instance)) { 00121 return parser.parse(this, parentNode, fieldInstance, instanceLabel, instance); 00122 } 00123 } 00124 return null; 00125 } 00126 00127 @Override 00128 public void recursiveParseClass(final ClassNode classNode, Object container) { 00129 labelsMapStack.push(buildLabelMaps(container)); 00130 Class<?> objectClass = container.getClass(); 00131 while (objectClass != null) { 00132 Field[] fields = getFieldList(objectClass); 00133 for (Field field : fields) { 00134 if (field.getName().equals("serialVersionUID")) 00135 continue; 00136 field.setAccessible(true); 00137 if (isMonitored(classNode, field)) { 00138 Object fieldValue = CodeTrees.getValueFromField(field, classNode.instance()); 00139 if (fieldValue != null) 00140 recursiveParseInstance(classNode, field, null, fieldValue); 00141 } 00142 } 00143 objectClass = objectClass.getSuperclass(); 00144 } 00145 if (container instanceof MonitorContainer) 00146 ((MonitorContainer) container).addToMonitor(new DataMonitor() { 00147 @Override 00148 public void add(String label, Monitored monitored) { 00149 PrimitiveNode child = new PrimitiveNode(label, classNode, monitored, classNode.level()); 00150 classNode.addChild(child); 00151 } 00152 }); 00153 if (container instanceof Monitored) { 00154 PrimitiveNode child = new PrimitiveNode("this", classNode, (Monitored) container, classNode.level()); 00155 classNode.addChild(child); 00156 } 00157 labelsMapStack.pop(); 00158 } 00159 00160 @Override 00161 public CodeNode parse(MutableParentNode parent, Object root, String rootLabel) { 00162 return recursiveParseInstance(parent, null, rootLabel, root); 00163 } 00164 00165 static public void registerParser(FieldParser parser) { 00166 parsers.addFirst(parser); 00167 } 00168 00169 private LabeledCollection getLabeledElement(String id) { 00170 for (Map<String, LabeledCollection> labelsMap : labelsMapStack) { 00171 LabeledCollection labeledElement = labelsMap.get(id); 00172 if (labeledElement != null) 00173 return labeledElement; 00174 } 00175 return null; 00176 } 00177 00178 @Override 00179 public CollectionLabelBuilder newCollectionLabelBuilder(Field field, int length) { 00180 String id = ""; 00181 boolean arrayDecoration = true; 00182 if (field != null && field.isAnnotationPresent(Monitor.class)) { 00183 Monitor annotation = field.getAnnotation(Monitor.class); 00184 id = annotation.id(); 00185 arrayDecoration = annotation.arrayDecoration(); 00186 } 00187 if (field != null && id.isEmpty()) 00188 id = field.getName(); 00189 return new CollectionLabelBuilder(getLabeledElement(id), ":", length, arrayDecoration); 00190 } 00191 }