1 5 package com.tc.object.config; 6 7 import com.tc.logging.TCLogger; 8 import com.tc.logging.TCLogging; 9 10 import java.lang.reflect.Method ; 11 import java.lang.reflect.Modifier ; 12 import java.lang.reflect.Constructor ; 13 import java.util.HashMap ; 14 import java.util.HashSet ; 15 import java.util.Map ; 16 import java.util.Set ; 17 18 21 public class ConfigVisitor { 22 private final Map visited = new HashMap (); 23 private final TCLogger logger = TCLogging.getLogger(getClass()); 24 25 public static final String VISIT_METHOD_NAME = "visitL1DSOConfig"; 26 public static final String VISIT_INSTANCE_METHOD_NAME = "instanceVisitL1DSOConfig"; 27 public static final Class [] VISIT_METHOD_PARAMETERS = new Class [] { ConfigVisitor.class, 28 DSOClientConfigHelper.class }; 29 public static final Class [] VISIT_METHOD_PARAMETERS_WITH_ATTRIBUTES = new Class [] { ConfigVisitor.class, 30 DSOClientConfigHelper.class, Map .class }; 31 public static final String VISIT_DSO_APPLICATION_CONFIG_METHOD_NAME = "visitDSOApplicationConfig"; 32 public static final Class [] VISIT_DSO_APPLICATION_CONFIG_METHOD_PARAMETERS = new Class [] { ConfigVisitor.class, 33 DSOApplicationConfig.class }; 34 35 public void visitDSOApplicationConfig(DSOApplicationConfig config, Class clazz) { 36 if (checkAndSetVisited(config, clazz)) { return; } 37 doVisit(clazz, VISIT_DSO_APPLICATION_CONFIG_METHOD_NAME, VISIT_DSO_APPLICATION_CONFIG_METHOD_PARAMETERS, 38 new Object [] { this, config }); 39 } 40 41 public void visit(DSOClientConfigHelper config, Visitable v) { 42 if (checkAndSetVisited(config, v)) { return; } 43 v.visit(this, config); 44 } 45 46 public void visit(DSOClientConfigHelper config, Class clazz) { 47 if (checkAndSetVisited(config, clazz)) { return; } 48 Object [] args = new Object [] { this, config }; 49 if (!doInstanceVisit(clazz, VISIT_INSTANCE_METHOD_NAME, VISIT_METHOD_PARAMETERS, args)) doVisit( 51 clazz, 52 VISIT_METHOD_NAME, 53 VISIT_METHOD_PARAMETERS, 54 new Object [] { 55 this, config }); 56 } 57 58 public void visit(DSOClientConfigHelper config, Class clazz, Map optionalAttributes) { 59 if (checkAndSetVisited(config, clazz)) { return; } 60 Object [] args = new Object [] { this, config }; 61 if (!doInstanceVisit(clazz, VISIT_INSTANCE_METHOD_NAME, VISIT_METHOD_PARAMETERS, args)) doVisit( 63 clazz, 64 VISIT_METHOD_NAME, 65 VISIT_METHOD_PARAMETERS_WITH_ATTRIBUTES, 66 new Object [] { 67 this, config, 68 optionalAttributes }); 69 } 70 71 private boolean doInstanceVisit(Class clazz, String methodName, Class [] parameters, Object [] arguments) { 73 boolean result = false; 74 try { 75 Method visitMethod = clazz.getMethod(VISIT_INSTANCE_METHOD_NAME, parameters); 76 System.out.println("instance configuration method found"); 77 Constructor construct = clazz.getConstructor(new Class [0]); 78 Object instance = construct.newInstance(new Object [0]); 79 visitMethod.setAccessible(true); 80 visitMethod.invoke(instance, arguments); 81 result = true; 82 } catch (NoSuchMethodException e) { 83 } catch (Exception e) { 85 throw new RuntimeException (e); 86 } 87 return result; 88 } 89 90 private void doVisit(Class clazz, String methodName, Class [] parameters, Object [] arguments) { 91 while (clazz != null) { 92 try { 93 Method visitMethod = clazz.getMethod(methodName, parameters); 95 if (Modifier.isStatic(visitMethod.getModifiers())) { 96 visitMethod.setAccessible(true); 97 logger.info("Visiting: " + clazz.getName()); 98 visitMethod.invoke(null, arguments); 99 } 100 } catch (NoSuchMethodException e) { 101 if (!Object .class.getName().equals(clazz.getName())) { 102 StringBuffer paramString = new StringBuffer (); 103 for (int i = 0; i < parameters.length; i++) { 104 if (i > 0) { 105 paramString.append(","); 106 } 107 paramString.append(parameters[i].getName()); 108 } 109 logger.info("Visit method not defined: " + clazz.getName() + "." + methodName + "(" + paramString + ")"); 110 } 111 continue; 112 } catch (Exception e) { 113 throw new RuntimeException (e); 114 } finally { 115 clazz = clazz.getSuperclass(); 116 } 117 } 118 } 119 120 private boolean checkAndSetVisited(Object config, Class clazz) { 121 return checkAndSetVisited(config, clazz.getName()); 122 } 123 124 private boolean checkAndSetVisited(Object config, Visitable v) { 125 return checkAndSetVisited(config, v.getClass()); 126 } 127 128 private boolean checkAndSetVisited(Object config, Object key) { 129 Set set; 130 synchronized (visited) { 131 set = getOrCreateVisitedFor(key); 132 } 133 synchronized (set) { 134 boolean rv = !set.add(config); 135 if (rv) { 136 logger.warn("Already visited: " + key); 137 } 138 return rv; 139 } 140 } 141 142 private Set getOrCreateVisitedFor(Object key) { 143 synchronized (visited) { 144 Set set = (Set ) visited.get(key); 145 if (set == null) { 146 set = new HashSet (); 147 visited.put(key, set); 148 } 149 return set; 150 } 151 } 152 153 } 154 | Popular Tags |