001: /* ====================================================================
002: The Jicarilla Software License
003:
004: Copyright (c) 2003 Leo Simons.
005: All rights reserved.
006:
007: Permission is hereby granted, free of charge, to any person obtaining
008: a copy of this software and associated documentation files (the
009: "Software"), to deal in the Software without restriction, including
010: without limitation the rights to use, copy, modify, merge, publish,
011: distribute, sublicense, and/or sell copies of the Software, and to
012: permit persons to whom the Software is furnished to do so, subject to
013: the following conditions:
014:
015: The above copyright notice and this permission notice shall be
016: included in all copies or substantial portions of the Software.
017:
018: THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
019: EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
020: MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
021: IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
022: CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
023: TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
024: SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
025: ==================================================================== */
026: package org.jicarilla.container.integration.pico;
027:
028: import org.jicarilla.container.DefaultContainer;
029: import org.jicarilla.container.Factory;
030: import org.jicarilla.container.JicarillaClassNotFoundException;
031: import org.jicarilla.container.JicarillaIllegalAccessException;
032: import org.jicarilla.container.JicarillaInstantiationException;
033: import org.jicarilla.container.JicarillaInvocationTargetException;
034: import org.jicarilla.container.adapters.SingletonAdapter;
035: import org.jicarilla.container.factories.ManualFactory;
036: import org.jicarilla.container.factories.Type3Factory;
037: import org.jicarilla.container.selectors.ClassSelector;
038: import org.jicarilla.lang.Assert;
039: import org.jicarilla.lang.EquivalenceSelector;
040: import org.jicarilla.lang.OrSelector;
041: import org.jicarilla.lang.Selector;
042: import org.jicarilla.lang.Switch;
043: import org.picocontainer.ComponentAdapter;
044: import org.picocontainer.MutablePicoContainer;
045: import org.picocontainer.Parameter;
046: import org.picocontainer.PicoException;
047: import org.picocontainer.PicoRegistrationException;
048: import org.picocontainer.PicoVerificationException;
049:
050: import java.util.ArrayList;
051: import java.util.Collection;
052: import java.util.Collections;
053: import java.util.HashMap;
054: import java.util.Iterator;
055: import java.util.List;
056: import java.util.Map;
057:
058: /**
059: * @author <a href="lsimons at jicarilla dot org">Leo Simons</a>
060: * @version $Id: JicarillaBasedPicoContainer.java,v 1.3 2004/03/23 13:37:56 lsimons Exp $
061: */
062: public class JicarillaBasedPicoContainer extends DefaultContainer
063: implements org.picocontainer.PicoContainer,
064: MutablePicoContainer {
065: protected final Map m_unmanagedInstances = new HashMap();
066:
067: // ----------------------------------------------------------------------
068: // PicoContainer Interface
069: // ----------------------------------------------------------------------
070:
071: public Object getComponentInstance(final Object componentKey)
072: throws PicoException {
073: try {
074: return super .getResolver().get(componentKey);
075: } catch (JicarillaIllegalAccessException e) {
076: throw new PicoIllegalAccessException(e);
077: } catch (JicarillaInvocationTargetException e) {
078: throw new PicoInvocationTargetException(e);
079: } catch (JicarillaInstantiationException e) {
080: throw new PicoInstantationException(e);
081: } catch (JicarillaClassNotFoundException e) {
082: throw new PicoClassNotFoundException(e);
083: }
084: }
085:
086: public List getComponentInstances() throws PicoException {
087: final List instances = new ArrayList();
088: final Iterator it = super .m_switch.values().iterator();
089: while (it.hasNext()) {
090: final org.jicarilla.container.Adapter adapter = (org.jicarilla.container.Adapter) it
091: .next();
092:
093: final Object instance;
094: try {
095: instance = adapter.getInstance();
096: } catch (JicarillaIllegalAccessException e) {
097: throw new PicoIllegalAccessException(e);
098: } catch (JicarillaInvocationTargetException e) {
099: throw new PicoInvocationTargetException(e);
100: } catch (JicarillaInstantiationException e) {
101: throw new PicoInstantationException(e);
102: } catch (JicarillaClassNotFoundException e) {
103: throw new PicoClassNotFoundException(e);
104: }
105:
106: instances.add(instance);
107: }
108: return instances;
109: }
110:
111: public boolean hasComponent(final Object componentKey) {
112: return super .getResolver().contains(componentKey);
113: }
114:
115: public Object getComponentMulticaster(
116: final boolean callInInstantiationOrder,
117: final boolean callUnmanagedComponents) throws PicoException {
118: throw new UnsupportedOperationException(
119: "The PicoContainer multicaster feature is not supported.");
120: }
121:
122: public Object getComponentMulticaster() throws PicoException {
123: throw new UnsupportedOperationException(
124: "The PicoContainer multicaster feature is not supported.");
125: }
126:
127: public Collection getComponentKeys() {
128: throw new UnsupportedOperationException(
129: "The Jicarilla container cannot export all of its component "
130: + "keys.");
131: }
132:
133: public Collection getChildContainers() {
134: throw new UnsupportedOperationException(
135: "The PicoContainer hierarchy feature is not supported.");
136: }
137:
138: public List getParentContainers() {
139: throw new UnsupportedOperationException(
140: "The PicoContainer hierarchy feature is not supported.");
141: }
142:
143: public ComponentAdapter findComponentAdapter(
144: final Object componentKey) {
145: if (!super .getResolver().contains(componentKey))
146: return null;
147:
148: final Switch.Entry entry = (Switch.Entry) super .m_switch
149: .get(componentKey);
150: final org.jicarilla.container.Adapter adapter = (org.jicarilla.container.Adapter) entry
151: .getValue();
152: return new JicarillaBasedPicoComponentAdapter(adapter,
153: componentKey);
154: }
155:
156: public void verify() throws PicoVerificationException {
157: /*throw new UnsupportedOperationException(
158: "The PicoContainer verification feature is not supported." );*/
159: }
160:
161: public List getUnmanagedComponentInstances() throws PicoException {
162: final Collection values = m_unmanagedInstances.values();
163: final List list = new ArrayList();
164: list.addAll(values);
165: return Collections.unmodifiableList(list);
166: }
167:
168: // ----------------------------------------------------------------------
169: // MutablePicoContainer Interface
170: // ----------------------------------------------------------------------
171:
172: public ComponentAdapter registerComponentImplementation(
173: final Object componentKey,
174: final Class componentImplementation) {
175: final Selector selector = getSelector(componentKey,
176: componentImplementation);
177:
178: final Factory factory = new Type3Factory(super .getResolver(),
179: componentImplementation.getName());
180: final SingletonAdapter adapter = new SingletonAdapter(factory);
181:
182: super .registerAdapter(selector, adapter);
183:
184: //cacheInstance( componentKey );
185:
186: return new JicarillaBasedPicoComponentAdapter(adapter,
187: componentKey);
188: }
189:
190: public ComponentAdapter registerComponentImplementation(
191: final Object componentKey,
192: final Class componentImplementation,
193: final Parameter[] parameters)
194: throws PicoRegistrationException {
195: final Selector selector = getSelector(componentKey,
196: componentImplementation);
197:
198: final Factory factory = new PicoBasedJicarillaComponentFactory(
199: this , componentImplementation.getName(), parameters);
200: final SingletonAdapter adapter = new SingletonAdapter(factory);
201:
202: super .registerAdapter(selector, adapter);
203:
204: //cacheInstance( componentKey );
205:
206: return new JicarillaBasedPicoComponentAdapter(adapter,
207: componentKey);
208: }
209:
210: public ComponentAdapter registerComponentImplementation(
211: final Class componentImplementation)
212: throws PicoRegistrationException {
213: final ClassSelector selector = new ClassSelector(
214: componentImplementation);
215: final Type3Factory factory = new Type3Factory(super
216: .getResolver(), componentImplementation.getName());
217: final SingletonAdapter adapter = new SingletonAdapter(factory);
218:
219: super .registerAdapter(selector, adapter);
220:
221: //cacheInstance( componentImplementation );
222:
223: return new JicarillaBasedPicoComponentAdapter(adapter,
224: componentImplementation);
225: }
226:
227: public ComponentAdapter registerComponentInstance(
228: final Object componentInstance)
229: throws PicoRegistrationException {
230: final Class clazz = componentInstance.getClass();
231: final ClassSelector selector = new ClassSelector(clazz);
232: final ManualFactory factory = new ManualFactory(
233: componentInstance);
234:
235: final SingletonAdapter adapter = new SingletonAdapter(factory);
236:
237: super .registerAdapter(selector, adapter);
238:
239: cacheInstance(clazz);
240:
241: m_unmanagedInstances.put(clazz, componentInstance);
242:
243: return new JicarillaBasedPicoComponentAdapter(adapter, clazz);
244: }
245:
246: public ComponentAdapter registerComponentInstance(
247: final Object componentKey, final Object componentInstance)
248: throws PicoRegistrationException {
249: final Class clazz = componentInstance.getClass();
250: final Selector selector = getSelector(componentKey, clazz);
251:
252: final ManualFactory factory = new ManualFactory(
253: componentInstance);
254: final SingletonAdapter adapter = new SingletonAdapter(factory);
255:
256: super .registerAdapter(selector, adapter);
257:
258: cacheInstance(componentKey);
259:
260: m_unmanagedInstances.put(componentKey, componentInstance);
261:
262: return new JicarillaBasedPicoComponentAdapter(adapter,
263: componentKey);
264: }
265:
266: public ComponentAdapter unregisterComponent(
267: final Object componentKey) {
268: final org.jicarilla.container.Adapter adapter = (org.jicarilla.container.Adapter) super .m_switch
269: .remove(componentKey);
270:
271: if (m_unmanagedInstances.containsKey(componentKey)) {
272: m_unmanagedInstances.remove(componentKey);
273: }
274:
275: if (adapter != null)
276: return new JicarillaBasedPicoComponentAdapter(adapter,
277: componentKey);
278:
279: return null;
280: }
281:
282: public void addOrderedComponentAdapter(
283: final ComponentAdapter componentAdapter) {
284: /* not needed in practice;
285: pico is wrong... Selector selector = getSelector(
286: componentAdapter.getComponentKey(),
287: componentAdapter.getComponentImplementation() );
288: super.addAdapter(
289: selector,
290: new PicoBasedJicarillaComponentAdapter(
291: componentAdapter, this ) );*/
292: }
293:
294: public boolean addChild(final MutablePicoContainer child) {
295: throw new UnsupportedOperationException(
296: "The PicoContainer hierarchy feature is not supported.");
297: }
298:
299: public boolean addParent(final MutablePicoContainer parent) {
300: throw new UnsupportedOperationException(
301: "The PicoContainer hierarchy feature is not supported.");
302: }
303:
304: public boolean removeChild(final MutablePicoContainer child) {
305: throw new UnsupportedOperationException(
306: "The PicoContainer hierarchy feature is not supported.");
307: }
308:
309: public boolean removeParent(final MutablePicoContainer parent) {
310: throw new UnsupportedOperationException(
311: "The PicoContainer hierarchy feature is not supported.");
312: }
313:
314: public void registerOrderedComponentAdapter(
315: final ComponentAdapter componentAdapter) {
316: addOrderedComponentAdapter(componentAdapter);
317: }
318:
319: public void registerComponent(
320: final ComponentAdapter componentAdapter)
321: throws PicoRegistrationException {
322: addOrderedComponentAdapter(componentAdapter);
323: }
324:
325: // ----------------------------------------------------------------------
326: // Helper methods
327: // ----------------------------------------------------------------------
328:
329: protected void cacheInstance(final Object key) {
330: // make the container cache the instance
331: try {
332: Assert.assertNotNull(super .getResolver().get(key));
333: } catch (JicarillaIllegalAccessException e) {
334: throw new PicoIllegalAccessException(e);
335: } catch (JicarillaInvocationTargetException e) {
336: throw new PicoInvocationTargetException(e);
337: } catch (JicarillaInstantiationException e) {
338: throw new PicoInstantationException(e);
339: } catch (JicarillaClassNotFoundException e) {
340: throw new PicoClassNotFoundException(e);
341: }
342: }
343:
344: protected Selector getSelector(final Object componentKey,
345: final Class componentClass) {
346: if (componentKey instanceof Class) {
347: final Class key = (Class) componentKey;
348: if (!key.isAssignableFrom(componentClass)) {
349: throw new PicoAssignabilityException(key,
350: componentClass);
351: }
352: }
353:
354: if (super .getResolver().contains(componentKey))
355: throw new PicoDuplicateComponentKeyRegistrationException(
356: componentKey);
357:
358: final Selector keySelector;
359: if (componentKey instanceof Class)
360: keySelector = new ClassSelector((Class) componentKey);
361: else
362: keySelector = new EquivalenceSelector(componentKey);
363:
364: // add as class as well
365: final Selector classSelector = new ClassSelector(componentClass);
366:
367: final Selector aggregrate = new OrSelector(new Selector[] {
368: keySelector, classSelector });
369:
370: return aggregrate;
371: }
372: }
|