1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package net.sf.jour;
22
23 import java.io.IOException;
24 import java.lang.reflect.InvocationTargetException;
25 import java.lang.reflect.Method;
26 import java.net.URL;
27 import java.util.ArrayList;
28 import java.util.HashMap;
29 import java.util.Iterator;
30 import java.util.List;
31
32 import javax.xml.parsers.ParserConfigurationException;
33
34 import net.sf.jour.config.Aspect;
35 import net.sf.jour.config.AspectProperty;
36 import net.sf.jour.config.Jour;
37 import net.sf.jour.config.Pointcut;
38 import net.sf.jour.filter.ClassFilter;
39 import net.sf.jour.filter.PointcutListFilter;
40 import net.sf.jour.instrumentor.Instrumentor;
41 import net.sf.jour.instrumentor.InstrumentorFactory;
42 import net.sf.jour.log.Logger;
43 import net.sf.jour.util.ConfigFileUtil;
44 import net.sf.jour.util.FileUtil;
45
46 import org.w3c.dom.Document;
47 import org.w3c.dom.Node;
48 import org.w3c.dom.NodeList;
49 import org.xml.sax.SAXException;
50
51
52
53
54 public class Config {
55
56 protected static final Logger log = Logger.getLogger();
57
58 public static final String DEFAULTCONFING_FILE = "jour.xml";
59
60 protected boolean isDebug;
61
62 private boolean isSetSerialVersionUID;
63
64
65
66
67 private HashMap instrumentors = new HashMap();
68
69 public Config() {
70 initialize(FileUtil.getFile(DEFAULTCONFING_FILE));
71 }
72
73 public Config(String configFileName) {
74 if (configFileName == null) {
75 configFileName = DEFAULTCONFING_FILE;
76 }
77 initialize(FileUtil.getFile(configFileName));
78 }
79
80 public Config(URL configLocation) {
81 initialize(configLocation);
82 }
83
84 protected void initialize(URL configLocation) {
85 Jour jour = parsJourXML(configLocation);
86 if (jour != null) {
87 isDebug = jour.isDebug();
88 isSetSerialVersionUID = jour.isSetSerialVersionUID();
89 List aspectList = jour.getAspect();
90 if (aspectList == null) {
91 return;
92 }
93 for (Iterator i = aspectList.iterator(); i.hasNext();) {
94 Aspect aspectCfg = (Aspect) i.next();
95 if (aspectCfg.isEnabled()) {
96 ClassFilter filter = createFilter(aspectCfg.getTypedef());
97 PointcutListFilter pointcuts = new PointcutListFilter();
98 pointcuts.readConfig(aspectCfg.getPointcut());
99 Instrumentor instr = InstrumentorFactory.createInstrumentor(aspectCfg.getType(), pointcuts);
100 if (aspectCfg.getProperty() != null) {
101 for (Iterator pi = aspectCfg.getProperty().iterator(); pi.hasNext();) {
102 AspectProperty prop = (AspectProperty) pi.next();
103 setInstrumentorProperty(instr, prop.getName(), prop.getValue());
104 }
105 }
106 instrumentors.put(filter, instr);
107 }
108 }
109 }
110 }
111
112 private Jour parsJourXML(URL configLocation) {
113 Jour jour = new Jour();
114 try {
115 Document xmlDoc = ConfigFileUtil.loadDocument(configLocation);
116 Node jourNode = ConfigFileUtil.getFirstElement(xmlDoc, "jour");
117 if (jourNode == null) {
118 throw new ConfigException("Invalid XML root");
119 }
120
121 jour.setDebug(ConfigFileUtil.getNodeAttribute(jourNode, "debug", false));
122 jour.setSetSerialVersionUID(ConfigFileUtil.getNodeAttribute(jourNode, "setSerialVersionUID", false));
123
124 NodeList aspectList = jourNode.getChildNodes();
125 for (int j = 0; j < aspectList.getLength(); j++) {
126 Node aspectNode = aspectList.item(j);
127 if (!"aspect".equals(aspectNode.getNodeName())) {
128 continue;
129 }
130
131 Aspect aspect = new Aspect();
132
133 aspect.setDescr(ConfigFileUtil.getNodeAttribute(aspectNode, "descr"));
134 aspect.setType(ConfigFileUtil.getNodeAttribute(aspectNode, "type"));
135 aspect.setEnabled(ConfigFileUtil.getNodeAttribute(aspectNode, "enabled", true));
136 aspect.setTypedef(ConfigFileUtil.getNodeValue(aspectNode, "typedef"));
137
138 NodeList aspectChildList = aspectNode.getChildNodes();
139 for (int k = 0; k < aspectChildList.getLength(); k++) {
140 Node aspectChildNode = aspectChildList.item(k);
141 String nodeName = aspectChildNode.getNodeName();
142
143 if ("pointcut".equals(nodeName)) {
144 aspect.addPointcut(parsPointcut(aspectChildNode));
145 } else if ("property".equals(nodeName)) {
146 aspect.addProperty(parsProperty(aspectChildNode));
147 }
148
149 }
150 jour.addAspect(aspect);
151 }
152 } catch (ParserConfigurationException e) {
153 throw new ConfigException("Error parsing XML", e);
154 } catch (SAXException e) {
155 throw new ConfigException("Error parsing XML", e);
156 } catch (IOException e) {
157 throw new ConfigException("Error parsing XML", e);
158 }
159 return jour;
160 }
161
162 private AspectProperty parsProperty(Node node) {
163 AspectProperty p = new AspectProperty();
164 p.setName(ConfigFileUtil.getNodeAttribute(node, "name"));
165
166 String value = ConfigFileUtil.getNodeValue(node, "value");
167 if (value == null) {
168 value = ConfigFileUtil.getNodeAttribute(node, "value");
169 }
170 p.setValue(value);
171 return p;
172 }
173
174 private Pointcut parsPointcut(Node node) {
175 Pointcut p = new Pointcut();
176 String expr = ConfigFileUtil.getNodeAttribute(node, "expr");
177 if (expr == null) {
178 expr = node.getNodeValue();
179 }
180 p.setExpr(expr);
181 return p;
182 }
183
184 void setInstrumentorProperty(Instrumentor instrumentor, String name, String value) {
185 try {
186 Method method = instrumentor.getClass().getMethod(name, new Class[] {String.class});
187 method.invoke(instrumentor, new Object[] {value});
188 } catch (NoSuchMethodException e) {
189 throw new Error("Can't set property " + name, e);
190 } catch (IllegalAccessException e) {
191 throw new Error("Can't set property " + name, e);
192 } catch (InvocationTargetException e) {
193 throw new Error("Can't set property " + name, e);
194 }
195 }
196
197 public boolean isSetSerialVersionUID() {
198 return isSetSerialVersionUID;
199 }
200
201 protected void checkUniqueAspect() throws ConfigException {
202 HashMap map = new HashMap();
203 Iterator iter = instrumentors.entrySet().iterator();
204 while (iter.hasNext()) {
205 String instrumentor = (String) iter.next();
206 map.put(instrumentor, "");
207 }
208 if (instrumentors.entrySet().size() > map.size()) {
209 throw new ConfigException("Duplicate aspects in jour.xml are not supported");
210 }
211 }
212
213 protected ClassFilter createFilter(String typedef) {
214 return new ClassFilter(typedef);
215 }
216
217 public Instrumentor[] getInstrumentors(String className) throws InterceptorException {
218 ArrayList instrList = new ArrayList();
219 Iterator filters = instrumentors.keySet().iterator();
220 while (filters.hasNext()) {
221 ClassFilter filter = (ClassFilter) filters.next();
222 if (filter.accept(className)) {
223 instrList.add(instrumentors.get(filter));
224 }
225 }
226 return (Instrumentor[]) instrList.toArray(new Instrumentor[0]);
227 }
228
229 public Instrumentor[] getAllInstrumentors() {
230 ArrayList instrList = new ArrayList();
231 Iterator filters = instrumentors.keySet().iterator();
232 while (filters.hasNext()) {
233 ClassFilter filter = (ClassFilter) filters.next();
234 instrList.add(instrumentors.get(filter));
235 }
236 return (Instrumentor[]) instrList.toArray(new Instrumentor[0]);
237 }
238 }