1 /* ====================================================================
2 * Bigyo Software License, version 1.1
3 *
4 * Copyright (c) 2004, Zsombor Gegesy. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
16 *
17 * 3. Neither the name of the Bigyo Group nor the name "Bigyo" nor
18 * the names of its contributors may be used to endorse or promote
19 * products derived from this software without specific prior
20 * written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
30 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 * POSSIBILITY OF SUCH DAMAGE.
34 *
35 * ====================================================================
36 */
37
38 package net.sf.bigyo.container;
39
40 import java.io.BufferedWriter;
41 import java.io.FileNotFoundException;
42 import java.io.FileReader;
43 import java.io.FileWriter;
44 import java.io.IOException;
45 import java.io.Reader;
46 import java.util.ArrayList;
47 import java.util.HashMap;
48 import java.util.Iterator;
49 import java.util.List;
50 import java.util.Map;
51
52 import net.sf.bigyo.api.ContainerException;
53 import net.sf.bigyo.container.api.Constants;
54 import net.sf.bigyo.container.api.Registry;
55 import net.sf.bigyo.model.ComponentConfig;
56
57 import org.apache.avalon.fortress.util.dag.CyclicDependencyException;
58 import org.apache.avalon.fortress.util.dag.DirectedAcyclicGraphVerifier;
59 import org.apache.avalon.fortress.util.dag.Vertex;
60 import org.apache.log4j.LogManager;
61 import org.apache.log4j.Logger;
62
63 import com.thoughtworks.xstream.XStream;
64 import com.thoughtworks.xstream.converters.ConversionException;
65 import com.thoughtworks.xstream.io.StreamException;
66
67 /***
68 * Created on 2004.04.01.
69 * @author zsombor
70 *
71 * To change the template for this generated type comment go to Window -
72 * Preferences - Java - Code Generation - Code and Comments
73 */
74 class RegistryImpl implements Registry {
75
76 final static Logger LOG = LogManager.getLogger(RegistryImpl.class);
77
78 XStream xstream;
79 List componentDescList;
80 Map componentRegistry = new HashMap();
81
82 Map aliasMap = new HashMap();
83
84 /***
85 *
86 */
87 RegistryImpl(XStream xstream2) {
88 this.xstream = xstream2;
89 this.componentDescList = new ArrayList();
90 }
91
92 RegistryImpl(String componentRegistryFile, XStream xstream2) throws FileNotFoundException, StreamException,
93 ConversionException {
94 LOG.info("load component registry from " + componentRegistryFile);
95 xstream = xstream2;
96
97 componentDescList = new ArrayList();
98
99 loadRegistry(new FileReader(componentRegistryFile));
100 }
101
102 RegistryImpl(Reader source, XStream xstream2) {
103 LOG.info("load component registry from " + source);
104 xstream = xstream2;
105
106 componentDescList = new ArrayList();
107
108 loadRegistry(source);
109 }
110
111 /***
112 * load the registry xml from the reader
113 *
114 * @param reader
115 */
116 public void loadRegistry(Reader reader) {
117 List tmpCompDescList = (List) xstream.fromXML(reader);
118
119 for (Iterator iter = tmpCompDescList.iterator(); iter.hasNext();) {
120 addComponentDescription((ComponentDescription) iter.next());
121 }
122 }
123
124 /***
125 * @param desc
126 */
127 public void addComponentDescription(ComponentDescription desc) {
128 this.componentDescList.add(desc);
129 addMapping(desc);
130 }
131
132 /***
133 * @param desc
134 * @throws ClassNotFoundException
135 */
136 private void addMapping(ComponentDescription desc) {
137 try {
138 if ((desc.getConfigClass() != null) && (!desc.getConfigClass().startsWith("java.lang.")))
139 xstream.alias(desc.classAlias, Class.forName(desc.getConfigClass()));
140 registerShortcuts(xstream,desc);
141 this.componentRegistry.put(desc.getClassAlias(), desc);
142 List provides = desc.getProvides();
143 if (provides != null) {
144 for (Iterator iter = provides.iterator(); iter.hasNext();) {
145 String provide = (String) iter.next();
146 LOG.debug("provide :" + desc.getClassAlias() + " -> " + provide);
147 List result = (List) aliasMap.get(provide);
148 if (result == null) {
149 result = new ArrayList();
150 aliasMap.put(provide, result);
151 }
152 result.add(desc);
153 }
154 }
155 } catch (ClassNotFoundException e) {
156 LOG.warn("missing class :" + desc.getClassName() + ", class-alias:" + desc.getClassAlias());
157 }
158 }
159
160 /***
161 * check to see, that there is no circular dependency
162 *
163 */
164 public void validateRegistry() throws CyclicDependencyException, ContainerException {
165 LOG.info("validate registry");
166 List vertices = new ArrayList(componentDescList.size());
167 Map vertMap = new HashMap();
168 // csomopontok letrehozasa
169 for (int i = 0; i < componentDescList.size(); i++) {
170 ComponentDescription c = (ComponentDescription) componentDescList.get(i);
171 Vertex v = new Vertex(c.getClassAlias(), c);
172 vertMap.put(v.getName(), v);
173 vertices.add(v);
174 }
175
176 for (int i = 0; i < Constants.RESERVED_COMPONENT_NAME.length; i++) {
177 Vertex v = new Vertex(Constants.RESERVED_COMPONENT_NAME[i], null);
178 vertMap.put(v.getName(), v);
179 vertices.add(v);
180 }
181
182 // iranyitasok letrehozasa
183 for (int i = 0; i < vertices.size(); i++) {
184 Vertex v = (Vertex) vertices.get(i);
185 ComponentDescription c = (ComponentDescription) v.getNode();
186 // c is null if it's a built in component. [from the reserved
187 // component list]
188 if (c != null) {
189 List deps = c.getDepends();
190 if (deps != null) {
191 for (Iterator iter = deps.iterator(); iter.hasNext();) {
192 ClassDependency cd = (ClassDependency) iter.next();
193
194 Vertex v2 = (Vertex) vertMap.get(cd.getClassAlias());
195 List alias = (List) aliasMap.get(cd.getClassAlias());
196 if ((v2 == null) && ((alias == null || alias.size() == 0)))
197 throw new ContainerException("Dependency not resolvable for '" + v.getName()
198 + "' dependency named as '" + cd.getClassAlias()
199 + "': unknown component/no component provides the necessary functionality!");
200
201 if (alias != null && alias.size() > 0) {
202 for (Iterator iter2 = alias.iterator(); iter2.hasNext();) {
203 ComponentDescription provider = (ComponentDescription) iter2.next();
204 v2 = (Vertex) vertMap.get(provider.getClassAlias());
205 if (v2 == null)
206 throw new ContainerException("Unknown provider: '" + provider.getClassAlias()
207 + "' for '" + cd.getClassAlias() + "'");
208 if (ClassDependency.BEFORE.equals(cd.getDependencyType())) {
209 LOG.info("dependency '" + cd.getDependencyType() + "' " + v2.getName()
210 + " depend on " + v.getName());
211 v2.addDependency(v);
212 } else {
213 LOG.info("dependency '" + cd.getDependencyType() + "' " + v.getName()
214 + " depend on " + v2.getName());
215 v.addDependency(v2);
216 }
217 }
218 }
219
220 if (v2 != null) {
221 if (ClassDependency.BEFORE.equals(cd.getDependencyType())) {
222 LOG.info("dependency '" + cd.getDependencyType() + "' " + v2.getName() + " depend on "
223 + v.getName());
224 v2.addDependency(v);
225 } else {
226 LOG.info("dependency '" + cd.getDependencyType() + "' " + v.getName() + " depend on "
227 + v2.getName());
228 v.addDependency(v2);
229 }
230 // v.addDependency(v2);
231 }
232 }
233 }
234 }
235 }
236 DirectedAcyclicGraphVerifier.topologicalSort(vertices);
237 LOG.info("component tree is acylic, order " + Util.convertVertexList(vertices));
238 }
239
240
241 /***
242 * Store registry to the specified file.
243 * @param registry file
244 */
245 public void storeRegistry(String componentRegistryFile) throws IOException {
246 LOG.info("store component registry to " + componentRegistryFile);
247 xstream.toXML(componentDescList, new BufferedWriter(new FileWriter(componentRegistryFile)));
248 }
249
250 ComponentDescription getComponentDescription(ComponentConfig config) {
251 return (ComponentDescription) this.componentRegistry.get(config.getClassAlias());
252 }
253
254 private void initXStream(XStream xs) {
255 for (Iterator iter = this.componentRegistry.values().iterator(); iter.hasNext();) {
256 ComponentDescription desc = (ComponentDescription) iter.next();
257 if ((desc.getConfigClass() != null) && (!desc.getConfigClass().startsWith("java.lang."))) {
258 try {
259 xs.alias(desc.classAlias, Class.forName(desc.getConfigClass()));
260 } catch (ClassNotFoundException e) {
261 LOG.fatal("something very weird happened ... this should be never occured!", e);
262 }
263 }
264 registerShortcuts(xs, desc);
265 }
266
267 }
268
269 /***
270 * @param xs
271 * @param desc
272 */
273 private void registerShortcuts(XStream xs, ComponentDescription desc) {
274 Map m = desc.getClassShortcuts();
275 if (m!=null) {
276 for (Iterator it = m.keySet().iterator(); it.hasNext();) {
277 try {
278 String name = (String) it.next();
279 xs.alias(desc.classAlias+'-'+name,Class.forName((String) m.get(name)));
280 } catch (ClassNotFoundException e) {
281 LOG.fatal("something very weird happened ... this should be never occured!", e);
282 }
283
284 }
285 }
286 }
287
288 }
This page was automatically generated by Maven