KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tc > object > config > ConfigVisitor


1 /*
2  * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright
3  * notice. All rights reserved.
4  */

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 JavaDoc;
11 import java.lang.reflect.Modifier JavaDoc;
12 import java.lang.reflect.Constructor JavaDoc;
13 import java.util.HashMap JavaDoc;
14 import java.util.HashSet JavaDoc;
15 import java.util.Map JavaDoc;
16 import java.util.Set JavaDoc;
17
18 /**
19  * Allows a class to visit a L1DSOConfig to augment/adjust it
20  */

21 public class ConfigVisitor {
22   private final Map JavaDoc visited = new HashMap JavaDoc();
23   private final TCLogger logger = TCLogging.getLogger(getClass());
24
25   public static final String JavaDoc VISIT_METHOD_NAME = "visitL1DSOConfig";
26   public static final String JavaDoc VISIT_INSTANCE_METHOD_NAME = "instanceVisitL1DSOConfig";
27   public static final Class JavaDoc[] VISIT_METHOD_PARAMETERS = new Class JavaDoc[] { ConfigVisitor.class,
28       DSOClientConfigHelper.class };
29   public static final Class JavaDoc[] VISIT_METHOD_PARAMETERS_WITH_ATTRIBUTES = new Class JavaDoc[] { ConfigVisitor.class,
30       DSOClientConfigHelper.class, Map JavaDoc.class };
31   public static final String JavaDoc VISIT_DSO_APPLICATION_CONFIG_METHOD_NAME = "visitDSOApplicationConfig";
32   public static final Class JavaDoc[] VISIT_DSO_APPLICATION_CONFIG_METHOD_PARAMETERS = new Class JavaDoc[] { ConfigVisitor.class,
33       DSOApplicationConfig.class };
34
35   public void visitDSOApplicationConfig(DSOApplicationConfig config, Class JavaDoc 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 JavaDoc[] { 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 JavaDoc clazz) {
47     if (checkAndSetVisited(config, clazz)) { return; }
48     Object JavaDoc[] args = new Object JavaDoc[] { this, config };
49     // use instance visiting if available, otherwise do class visiting
50
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 JavaDoc[] {
55                                                                                                         this, config });
56   }
57
58   public void visit(DSOClientConfigHelper config, Class JavaDoc clazz, Map JavaDoc optionalAttributes) {
59     if (checkAndSetVisited(config, clazz)) { return; }
60     Object JavaDoc[] args = new Object JavaDoc[] { this, config };
61     // use instance visiting if available, otherwise do class visiting
62
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 JavaDoc[] {
67                                                                                                         this, config,
68                                                                                                         optionalAttributes });
69   }
70
71   // instance visiting only works if clazz defines a niladic constructor
72
private boolean doInstanceVisit(Class JavaDoc clazz, String JavaDoc methodName, Class JavaDoc[] parameters, Object JavaDoc[] arguments) {
73     boolean result = false;
74     try {
75       Method JavaDoc visitMethod = clazz.getMethod(VISIT_INSTANCE_METHOD_NAME, parameters);
76       System.out.println("instance configuration method found");
77       Constructor JavaDoc construct = clazz.getConstructor(new Class JavaDoc[0]);
78       Object JavaDoc instance = construct.newInstance(new Object JavaDoc[0]);
79       visitMethod.setAccessible(true);
80       visitMethod.invoke(instance, arguments);
81       result = true;
82     } catch (NoSuchMethodException JavaDoc e) {
83       // nothing to do
84
} catch (Exception JavaDoc e) {
85       throw new RuntimeException JavaDoc(e);
86     }
87     return result;
88   }
89
90   private void doVisit(Class JavaDoc clazz, String JavaDoc methodName, Class JavaDoc[] parameters, Object JavaDoc[] arguments) {
91     while (clazz != null) {
92       try {
93         // look for instance method first
94
Method JavaDoc 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 JavaDoc e) {
101         if (!Object JavaDoc.class.getName().equals(clazz.getName())) {
102           StringBuffer JavaDoc paramString = new StringBuffer JavaDoc();
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 JavaDoc e) {
113         throw new RuntimeException JavaDoc(e);
114       } finally {
115         clazz = clazz.getSuperclass();
116       }
117     }
118   }
119
120   private boolean checkAndSetVisited(Object JavaDoc config, Class JavaDoc clazz) {
121     return checkAndSetVisited(config, clazz.getName());
122   }
123
124   private boolean checkAndSetVisited(Object JavaDoc config, Visitable v) {
125     return checkAndSetVisited(config, v.getClass());
126   }
127
128   private boolean checkAndSetVisited(Object JavaDoc config, Object JavaDoc key) {
129     Set JavaDoc 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 JavaDoc getOrCreateVisitedFor(Object JavaDoc key) {
143     synchronized (visited) {
144       Set JavaDoc set = (Set JavaDoc) visited.get(key);
145       if (set == null) {
146         set = new HashSet JavaDoc();
147         visited.put(key, set);
148       }
149       return set;
150     }
151   }
152
153 }
154
Popular Tags