1 /*
2 * Module.java
3 * Created on August 27, 2003
4 *
5 * The Blues Framework - A lightweight application framework
6 * Copyright (C) 2003 Lonnie Pryor
7 * http://blues.lonniepryor.com
8 *
9 * This library is free software; you can redistribute it and/or modify it under the
10 * terms of the GNU Lesser General Public License as published by the Free Software
11 * Foundation; either version 2.1 of the License, or (at your option) any later
12 * version.
13 *
14 * This library is distributed in the hope that it will be useful, but WITHOUT ANY
15 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
16 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public License along
19 * with this library; if not, write to:
20 *
21 * The Free Software Foundation, Inc.
22 * 59 Temple Place, Suite 330
23 * Boston, MA 02111-1307 USA
24 *
25 */
26 package com.lonniepryor.blues.sys;
27
28 import java.lang.reflect.Method;
29
30 import java.util.Arrays;
31 import java.util.Collections;
32 import java.util.Enumeration;
33 import java.util.HashMap;
34 import java.util.HashSet;
35 import java.util.Iterator;
36 import java.util.LinkedList;
37 import java.util.List;
38 import java.util.Map;
39 import java.util.Set;
40
41 import com.lonniepryor.blues.aop.Aspect;
42 import com.lonniepryor.blues.aop.JoinPoint;
43 import com.lonniepryor.blues.aop.Pointcut;
44 import com.lonniepryor.blues.cfg.AdviceCfg;
45 import com.lonniepryor.blues.cfg.IncludeCfg;
46 import com.lonniepryor.blues.cfg.ModuleCfg;
47 import com.lonniepryor.blues.cfg.PointcutCfg;
48 import com.lonniepryor.blues.cfg.ServiceCfg;
49 import com.lonniepryor.blues.util.EnumerationChain;
50
51 /***
52 * Models the abstract view of a Blues module.
53 *
54 * @author Lonnie Pryor
55 * @version $Revision: 1.1 $
56 */
57 public final class Module extends Context implements Aspect {
58 /*** The context this module is declared in. */
59 private final Context context;
60 /*** The name of this module. */
61 private final String name;
62 /*** The mapping of variable names to refrences in our context. */
63 private final Map variableMapping;
64 /*** The advices declared in this module. */
65 private final List advices = new LinkedList();
66 /*** The services declared in this module. */
67 private final List services = new LinkedList();
68 /*** The maping of service names to Service objects. */
69 private final Map serviceMapping = new HashMap();
70 /*** The mapping of pointcut names to Pointcut objects. */
71 private final Map pointcutMapping = new HashMap();
72 /*** The included modules declared in this module. */
73 private final List includes = new LinkedList();
74 /*** The mapping of included module names to Module objects. */
75 private final Map includeMapping = new HashMap();
76
77 /***
78 * Creates a new Module object.
79 *
80 * @param context The context this module is declared in.
81 * @param name The name of this module.
82 * @param configuration The module configuration information.
83 * @param variableMapping The mapping of variable names to refrences in our
84 * context.
85 */
86 Module (
87 Context context, String name, ModuleCfg configuration, Map variableMapping) {
88 this.context = context;
89 this.name = name;
90 this.variableMapping = variableMapping;
91 String[] myVariables = configuration.getVariables();
92 for (int i = 0; i < myVariables.length; i++) {
93 if (!variableMapping.containsKey(myVariables[i]))
94 throw new SystemException(
95 "Variable '" + getContextPath().append(myVariables[i]) + "' not set");
96 }
97 if (myVariables.length != variableMapping.size()) {
98 HashSet set = new HashSet(variableMapping.keySet());
99 set.removeAll(Arrays.asList(myVariables));
100 throw new SystemException(
101 "Unknown variables '" + set + "' in " + getContextPath());
102 }
103 Set allNames = new HashSet();
104 createPointcuts(configuration.getPointcuts(), allNames);
105 createAdvices(configuration.getAdvices());
106 createServices(configuration.getServices(), allNames);
107 createIncludes(configuration.getIncludes(), allNames);
108 }
109
110 /***
111 * Creates and indexs the pointcuts in this module.
112 *
113 * @param pointcutCfgs The pointcut configurations.
114 * @param allNames The set of all names declared in this module.
115 */
116 private void createPointcuts (PointcutCfg[] pointcutCfgs, Set allNames) {
117 for (int i = 0; i < pointcutCfgs.length; i++) {
118 if (!allNames.add(pointcutCfgs[i].getName()))
119 throw new SystemException(
120 "Cannot declare more than one element with name '"
121 + getContextPath().append(pointcutCfgs[i].getName()) + "'");
122 pointcutMapping.put(pointcutCfgs[i].getName(), pointcutCfgs[i].getPointcut());
123 }
124 }
125
126 /***
127 * Creates and indexs the advices in this module.
128 *
129 * @param adviceCfgs The advice configurations.
130 */
131 private void createAdvices (AdviceCfg[] adviceCfgs) {
132 for (int i = 0; i < adviceCfgs.length; i++)
133 advices.add(new Advice(this, adviceCfgs[i]));
134 }
135
136 /***
137 * Creates and indexs the services in this module.
138 *
139 * @param serviceCfgs The service configurations.
140 * @param allNames The set of all names declared in this module.
141 */
142 private void createServices (ServiceCfg[] serviceCfgs, Set allNames) {
143 for (int i = 0; i < serviceCfgs.length; i++) {
144 Service service = new Service(this, serviceCfgs[i]);
145 if (!allNames.add(service.getName()))
146 throw new SystemException(
147 "Cannot declare more than one element with name '"
148 + getContextPath().append(service.getName()) + "'");
149 services.add(service);
150 serviceMapping.put(service.getName(), service);
151 }
152 }
153
154 /***
155 * Creates and indexs the includes in this module.
156 *
157 * @param includeCfgs The include configurations.
158 * @param allNames The set of all names declared in this module.
159 */
160 private void createIncludes (IncludeCfg[] includeCfgs, Set allNames) {
161 for (int i = 0; i < includeCfgs.length; i++) {
162 if (!allNames.add(includeCfgs[i].getName()))
163 throw new SystemException(
164 "Cannot declare more than one element with name '"
165 + getContextPath().append(includeCfgs[i].getName()) + "'");
166 String[] variableNames = includeCfgs[i].getVariableNames();
167 Map variableValues = new HashMap();
168 for (int j = 0; j < variableNames.length; j++)
169 variableValues.put(
170 variableNames[j], includeCfgs[i].getVariableRefrence(variableNames[j]));
171 Module module = new Module(
172 this, includeCfgs[i].getName(), includeCfgs[i].getIncludedModule(),
173 variableValues);
174 includes.add(module);
175 includeMapping.put(includeCfgs[i].getName(), module);
176 }
177 }
178
179 /* (non-Javadoc)
180 * @see com.lonniepryor.blues.sys.Context#getClassLoader()
181 */
182 ClassLoader getClassLoader () {
183 return context.getClassLoader();
184 }
185
186 /* (non-Javadoc)
187 * @see com.lonniepryor.blues.sys.Context#getContextPath()
188 */
189 StringBuffer getContextPath () {
190 return context.getContextPath().append(name).append('/');
191 }
192
193 /* (non-Javadoc)
194 * @see com.lonniepryor.blues.sys.Context#adviceFor(
195 * com.lonniepryor.blues.aop.JoinPoint)
196 */
197 List adviceFor (final JoinPoint joinPoint) {
198 List boundAdvice = context.adviceFor(
199 new JoinPoint() {
200 String instanceName = name + "/" + joinPoint.getInstanceName();
201
202 public String getInstanceName () {
203 return instanceName;
204 }
205
206 public Method getTargetMethod () {
207 return joinPoint.getTargetMethod();
208 }
209 });
210 for (Iterator iter = advices.iterator(); iter.hasNext();) {
211 Advice advice = (Advice)iter.next();
212 if (advice.getPointcut().isSatisfiedBy(this, joinPoint))
213 boundAdvice.add(advice);
214 }
215 return boundAdvice;
216 }
217
218 /* (non-Javadoc)
219 * @see com.lonniepryor.blues.cfg.Directory#lookupService(java.lang.String)
220 */
221 public Object lookupService (String relativeServiceName) {
222 int firstSlash = relativeServiceName.indexOf('/');
223 if (firstSlash < 0) {
224 Service service = (Service)serviceMapping.get(relativeServiceName);
225 if (service == null) {
226 String variableValue = (String)variableMapping.get(relativeServiceName);
227 if (variableValue == null)
228 throw new SystemException(
229 "Service '" + getContextPath().append(relativeServiceName)
230 + "' not found");
231 return context.lookupService(variableValue);
232 }
233 return service.getComponentInstance();
234 }
235 String includeName = relativeServiceName.substring(0, firstSlash);
236 Module includedModue = (Module)includeMapping.get(includeName);
237 if (includedModue == null)
238 throw new SystemException(
239 "Module '" + getContextPath().append(includeName) + "' not found");
240 return includedModue.lookupService(
241 relativeServiceName.substring(firstSlash + 1));
242 }
243
244 /* (non-Javadoc)
245 * @see com.lonniepryor.blues.aop.Aspect#callPointcut(java.lang.String,
246 * com.lonniepryor.blues.aop.JoinPoint)
247 */
248 public boolean callPointcut (String name, JoinPoint toEvaluate) {
249 Pointcut toCall = (Pointcut)pointcutMapping.get(name);
250 if (toCall == null)
251 throw new SystemException(
252 "Pointcut '" + getContextPath().append(name) + "' not found");
253 return toCall.isSatisfiedBy(this, toEvaluate);
254 }
255
256 /***
257 * Returns an enumeration of all components in this module and included modules.
258 *
259 * @return An enumeration of all components in this module and included modules.
260 */
261 Enumeration enumerateComponents () {
262 Enumeration enum = new EnumerationChain(
263 Collections.enumeration(advices), Collections.enumeration(services));
264 for (Iterator iter = includes.iterator(); iter.hasNext();)
265 enum = new EnumerationChain(
266 enum, ((Module)iter.next()).enumerateComponents());
267 return enum;
268 }
269
270 /***
271 * Activates the interceptors on services in this module and included modules.
272 */
273 void activateInterceptors () {
274 for (Iterator iter = services.iterator(); iter.hasNext();)
275 ((Service)iter.next()).activateInterceptors();
276 for (Iterator iter = includes.iterator(); iter.hasNext();)
277 ((Module)iter.next()).activateInterceptors();
278 }
279
280 /***
281 * Registers the contents of this module and included modules with the supplied
282 * registry.
283 *
284 * @param registry The registry to register with.
285 */
286 void registerWith (Registry registry) {
287 for (Iterator iter = advices.iterator(); iter.hasNext();)
288 ((Advice)iter.next()).registerWith(registry);
289 for (Iterator iter = services.iterator(); iter.hasNext();)
290 ((Service)iter.next()).registerWith(registry);
291 for (Iterator iter = includes.iterator(); iter.hasNext();)
292 ((Module)iter.next()).registerWith(registry);
293 }
294 }
This page was automatically generated by Maven