1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 package org.objectledge.container;
30
31 import java.io.IOException;
32 import java.net.URL;
33
34 import org.jcontainer.dna.Configuration;
35 import org.jcontainer.dna.Logger;
36 import org.nanocontainer.integrationkit.ContainerBuilder;
37 import org.nanocontainer.integrationkit.PicoCompositionException;
38 import org.nanocontainer.reflection.StringToObjectConverter;
39 import org.objectledge.configuration.ConfigurationFactory;
40 import org.objectledge.configuration.CustomizedConfigurationProvider;
41 import org.objectledge.filesystem.FileSystem;
42 import org.objectledge.logging.LoggerFactory;
43 import org.objectledge.logging.LoggingConfigurator;
44 import org.objectledge.pico.LedgeStringToObjectConverter;
45 import org.objectledge.pico.customization.CustomizedComponentAdapter;
46 import org.objectledge.pico.customization.CustomizingConstructorComponentAdapterFactory;
47 import org.objectledge.pico.xml.LedgeContainerBuilder;
48 import org.objectledge.xml.XMLGrammarCache;
49 import org.objectledge.xml.XMLValidator;
50 import org.picocontainer.ComponentAdapter;
51 import org.picocontainer.MutablePicoContainer;
52 import org.picocontainer.Parameter;
53 import org.picocontainer.PicoContainer;
54 import org.picocontainer.defaults.CachingComponentAdapterFactory;
55 import org.picocontainer.defaults.ComponentAdapterFactory;
56 import org.picocontainer.defaults.ComponentParameter;
57 import org.picocontainer.defaults.ConstantParameter;
58 import org.picocontainer.defaults.ConstructorInjectionComponentAdapter;
59 import org.picocontainer.defaults.DefaultPicoContainer;
60 import org.picocontainer.defaults.ObjectReference;
61 import org.picocontainer.defaults.SimpleReference;
62
63 /***
64 * <code>LedgeContainer</code> is a NanoContainer flawor, that uses the
65 * {@link org.objectledge.filesystem.FileSystem} component for loading the composition file.
66 * The composition file is parsed using Ledge XmlFrontEnd.
67 * <code>LedgeContainer</code> also pre-feeds the internal PicoContainer with objects
68 * required by various container subsystems, including a FileSystem, ClassLoader and
69 * confiuration directory path.
70 *
71 * @author <a href="Rafal.Krzewski">rafal@caltha.pl</a>
72 * @version $Id: LedgeContainer.java,v 1.14 2005/07/07 08:30:02 zwierzem Exp $
73 */
74 public class LedgeContainer
75 {
76
77
78 /*** Location of the container composition file. */
79 public static final String COMPOSITION_FILE = "/container.xml";
80
81 /*** Default xml front end implementation. */
82 public static final String FRONT_END_CLASS =
83 "org.objectledge.pico.xml.LedgeXMLContainerBuilder";
84
85 /*** Config base path key. */
86 public static final String CONFIG_BASE_KEY = "org.objectledge.ConfigBase";
87
88 /*** The embedded container. */
89 protected ObjectReference containerRef = new SimpleReference();
90
91 /*** The embedded container builder. */
92 protected ContainerBuilder containerBuilder;
93
94
95
96 /***
97 * Creates an instance of the LedgeContainer.
98 *
99 * @param fs the FileSystem
100 * @param configBase configuration directory.
101 * @param classLoader the classload to load classes with.
102 * @throws IOException if the composition file could not be read.
103 * @throws ClassNotFoundException if the container builder class could not be instantiated.
104 * @throws PicoCompositionException if the composition file is invalid, or could not be
105 * verified due to system failure.
106 */
107 public LedgeContainer(FileSystem fs, String configBase, ClassLoader classLoader)
108 throws IOException, ClassNotFoundException, PicoCompositionException
109 {
110 containerBuilder = new LedgeContainerBuilder(getCompositionFile(fs, configBase),
111 classLoader);
112 ObjectReference parentRef = new SimpleReference();
113 parentRef.set(getBootContainer(fs, configBase, classLoader));
114 containerBuilder.buildContainer(containerRef, parentRef, null, true);
115 }
116
117 /***
118 * Returns the embedded container.
119 *
120 * @return the embedded container.
121 */
122 public MutablePicoContainer getContainer()
123 {
124 return (MutablePicoContainer)containerRef.get();
125 }
126
127 /***
128 * Kills the embedded container.
129 */
130 public void killContainer()
131 {
132 containerBuilder.killContainer(containerRef);
133 }
134
135 /***
136 * Verifies and returns the composition file.
137 *
138 * @param fs the FileSystem to load compositoin file from.
139 * @param configBase configuration directory.
140 * @return the composition file.
141 * @throws IOException if the file could not be read.
142 * @throws PicoCompositionException if the composition file is invalid, or could not be
143 * verified due to system failure.
144 */
145 protected static URL getCompositionFile(FileSystem fs, String configBase)
146 throws IOException, PicoCompositionException
147 {
148 return fs.getResource(configBase + COMPOSITION_FILE);
149 }
150
151 /***
152 * Returns the boot component container.
153 *
154 * @param fs the FileSystem
155 * @param configBase configuration directory.
156 * @param classLoader the classload to load classes with.
157 * @return the boot component container.
158 */
159 protected static PicoContainer getBootContainer(FileSystem fs, String configBase,
160 ClassLoader classLoader)
161 {
162 MutablePicoContainer bootContainer = new DefaultPicoContainer();
163 bootContainer.registerComponentInstance(FileSystem.class, fs);
164 bootContainer.registerComponentInstance(ClassLoader.class, classLoader);
165 bootContainer.registerComponentImplementation(XMLGrammarCache.class);
166 bootContainer.registerComponentImplementation(XMLValidator.class);
167 bootContainer.registerComponentImplementation(StringToObjectConverter.class,
168 LedgeStringToObjectConverter.class);
169
170 bootContainer.registerComponentImplementation(ConfigurationFactory.class,
171 ConfigurationFactory.class, params(COMPONENT, COMPONENT, constant(configBase)));
172 bootContainer.registerComponentImplementation(CustomizedConfigurationProvider.class);
173 ComponentAdapter adapter = new ConstructorInjectionComponentAdapter("anonymous",
174 CustomizedComponentAdapter.class, params(constant(Configuration.class),
175 component(CustomizedConfigurationProvider.class)));
176 adapter = (ComponentAdapter)adapter.getComponentInstance(bootContainer);
177 bootContainer.registerComponent(adapter);
178
179 bootContainer.registerComponentImplementation(LoggingConfigurator.class);
180 bootContainer.registerComponentImplementation(LoggerFactory.class);
181 adapter = new ConstructorInjectionComponentAdapter("anonymous",
182 CustomizedComponentAdapter.class, params(constant(Logger.class),
183 component(LoggerFactory.class)));
184 adapter = (ComponentAdapter)adapter.getComponentInstance(bootContainer);
185 bootContainer.registerComponent(adapter);
186
187 bootContainer.
188 registerComponentImplementation(CustomizingConstructorComponentAdapterFactory.class);
189 bootContainer.registerComponentImplementation(ComponentAdapterFactory.class,
190 CachingComponentAdapterFactory.class,
191 params(component(CustomizingConstructorComponentAdapterFactory.class)));
192 return bootContainer;
193 }
194
195 private static final Parameter COMPONENT = new ComponentParameter();
196
197
198 private static Parameter[] params(Parameter... parameters)
199 {
200 return parameters;
201 }
202
203 private static Parameter constant(Object value)
204 {
205 return new ConstantParameter(value);
206 }
207
208 private static Parameter component(Object key)
209 {
210 return new ComponentParameter(key);
211 }
212 }