1 /*
2 * Application.java
3 * Created on August 8, 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.util.Collections;
29 import java.util.Enumeration;
30 import java.util.HashMap;
31 import java.util.Iterator;
32 import java.util.LinkedList;
33 import java.util.List;
34 import java.util.Map;
35
36 import com.lonniepryor.blues.aop.JoinPoint;
37 import com.lonniepryor.blues.cfg.ApplicationCfg;
38 import com.lonniepryor.blues.cfg.ModuleCfg;
39 import com.lonniepryor.blues.cfg.SingletonCfg;
40 import com.lonniepryor.blues.util.BeanHelper;
41 import com.lonniepryor.blues.util.EnumerationChain;
42
43 /***
44 * Models the abstract view of a Blues Application.
45 *
46 * @author Lonnie Pryor
47 * @version $Revision: 1.1 $
48 */
49 public final class Application extends Context {
50 /*** The ClassLoader for this Application. */
51 private final ClassLoader classLoader;
52 /*** The declared Singletons in order. */
53 private final List singletons = new LinkedList();
54 /*** The declared Singletons, indexed by singleton Class. */
55 private final Map singletonMapping = new HashMap();
56 /*** The declared Dispatchers, indexed by observer interface Class. */
57 private final Map dispatcherMapping = new HashMap();
58 /*** The root Module of this Application. */
59 private Module rootModule = null;
60
61 /***
62 * Creates a new Application object.
63 *
64 * @param classLoader The ClassLoader for this Application.
65 * @param configuration The Application configuration information.
66 */
67 public Application (ClassLoader classLoader, ApplicationCfg configuration) {
68 if (classLoader == null)
69 throw new NullPointerException("classLoader");
70 if (configuration == null)
71 throw new NullPointerException("configuration");
72 this.classLoader = classLoader;
73 BeanHelper.activateCache();
74 try {
75 createSingletons(configuration.getSingletons());
76 createRootModule(configuration.getRootModule());
77 configureComponents();
78 for (Iterator iter = dispatcherMapping.values().iterator(); iter.hasNext();)
79 ((Dispatcher)iter.next()).createInstance(classLoader);
80 } finally {
81 BeanHelper.deactivateCache();
82 }
83 }
84
85 /***
86 * Creates and indexes the singletons in this application.
87 *
88 * @param singletonCfgs The singletons configuration information.
89 */
90 private void createSingletons (SingletonCfg[] singletonCfgs) {
91 for (int i = 0; i < singletonCfgs.length; ++i) {
92 Singleton singleton = (Singleton)singletonMapping.get(
93 singletonCfgs[i].getSingeltonType());
94 if (singleton != null)
95 throw new SystemException(
96 "Singleton class " + singletonCfgs[i].getSingeltonType()
97 + " declared twice");
98 singleton = new Singleton(singletonCfgs[i]);
99 singletons.add(singleton);
100 singletonMapping.put(singletonCfgs[i].getSingeltonType(), singleton);
101 }
102 }
103
104 /***
105 * Creates the root module of this application.
106 *
107 * @param moduleCfg The root module configuration information.
108 */
109 private void createRootModule (ModuleCfg moduleCfg) {
110 if (moduleCfg == null)
111 return;
112 if (moduleCfg.getVariables().length > 0)
113 throw new SystemException("Cannot declare variables in the root module");
114 rootModule = new Module(this, "", moduleCfg, Collections.EMPTY_MAP);
115 }
116
117 /***
118 * Configures every component in this application.
119 */
120 private void configureComponents () {
121 for (Enumeration enum = enumerateComponents(); enum.hasMoreElements();) {
122 Component toConfigure = (Component)enum.nextElement();
123 BeanHelper helper = BeanHelper.introspect(
124 toConfigure.getComponentInstance().getClass());
125 for (Iterator iter = helper.getPropertyNames().iterator(); iter.hasNext();) {
126 String propertyName = (String)iter.next();
127 Singleton singleton = (Singleton)singletonMapping.get(
128 helper.getPropertyType(propertyName));
129 if (singleton != null)
130 helper.setProperty(
131 toConfigure.getComponentInstance(), propertyName,
132 singleton.getComponentInstance());
133 }
134 toConfigure.configureInstance();
135 indexDispatchers(toConfigure);
136 }
137 if (rootModule != null)
138 rootModule.activateInterceptors();
139 }
140
141 /***
142 * Creates and indexes the Dispatchers for the supplied component.
143 *
144 * @param forComponent The component to create dispatchers for.
145 */
146 private void indexDispatchers (Component forComponent) {
147 Class[] observerInterfaces = Dispatcher.observerInterfacesFor(forComponent);
148 for (int i = 0; i < observerInterfaces.length; ++i) {
149 Dispatcher dispatcher = (Dispatcher)dispatcherMapping.get(
150 observerInterfaces[i]);
151 if (dispatcher == null)
152 dispatcherMapping.put(
153 observerInterfaces[i], dispatcher = new Dispatcher(observerInterfaces[i]));
154 dispatcher.addTarget(forComponent);
155 }
156 }
157
158 /***
159 * Returns an enumeration of all components in this application.
160 *
161 * @return An enumeration of all components in this application.
162 */
163 private Enumeration enumerateComponents () {
164 Enumeration enum = Collections.enumeration(singletons);
165 if (rootModule != null)
166 enum = new EnumerationChain(enum, rootModule.enumerateComponents());
167 return enum;
168 }
169
170 /***
171 * Creates and returns a new Registry containing the components of this
172 * application.
173 *
174 * @return A new Registry containing the components of this application.
175 */
176 public Registry getAllRegisteredObjects () {
177 Registry registry = new Registry();
178 for (Iterator iter = singletons.iterator(); iter.hasNext();)
179 ((Singleton)iter.next()).registerWith(registry);
180 if (rootModule != null)
181 rootModule.registerWith(registry);
182 for (Iterator iter = dispatcherMapping.values().iterator(); iter.hasNext();)
183 ((Dispatcher)iter.next()).registerWith(registry);
184 return registry;
185 }
186
187 /* (non-Javadoc)
188 * @see com.lonniepryor.blues.sys.Context#getClassLoader()
189 */
190 ClassLoader getClassLoader () {
191 return classLoader;
192 }
193
194 /* (non-Javadoc)
195 * @see com.lonniepryor.blues.sys.Context#getContextPath()
196 */
197 StringBuffer getContextPath () {
198 return new StringBuffer();
199 }
200
201 /* (non-Javadoc)
202 * @see com.lonniepryor.blues.sys.Context#adviceFor(
203 * com.lonniepryor.blues.aop.JoinPoint)
204 */
205 List adviceFor (JoinPoint joinPoint) {
206 return new LinkedList();
207 }
208
209 /* (non-Javadoc)
210 * @see com.lonniepryor.blues.cfg.Directory#lookupService(java.lang.String)
211 */
212 public Object lookupService (String relativeServiceName) {
213 throw new SystemException("Service '" + relativeServiceName + "' not found");
214 }
215 }
This page was automatically generated by Maven