Source Code Cross Referenced for CollectionComponentParameter.java in  » Inversion-of-Control » PicoContainer » org » picocontainer » parameters » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Inversion of Control » PicoContainer » org.picocontainer.parameters 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*****************************************************************************
002:         * Copyright (C) PicoContainer Organization. All rights reserved.            *
003:         * ------------------------------------------------------------------------- *
004:         * The software in this package is published under the terms of the BSD      *
005:         * style license a copy of which has been included with this distribution in *
006:         * the LICENSE.txt file.                                                     *
007:         *                                                                           *
008:         * Original code by                                                          *
009:         *****************************************************************************/package org.picocontainer.parameters;
010:
011:        import org.picocontainer.ComponentAdapter;
012:        import org.picocontainer.Parameter;
013:        import org.picocontainer.NameBinding;
014:        import org.picocontainer.PicoContainer;
015:        import org.picocontainer.PicoCompositionException;
016:        import org.picocontainer.PicoVisitor;
017:
018:        import java.io.Serializable;
019:        import java.lang.reflect.Array;
020:        import java.lang.annotation.Annotation;
021:        import java.util.ArrayList;
022:        import java.util.Collection;
023:        import java.util.HashMap;
024:        import java.util.HashSet;
025:        import java.util.LinkedHashMap;
026:        import java.util.List;
027:        import java.util.Map;
028:        import java.util.Set;
029:        import java.util.SortedMap;
030:        import java.util.SortedSet;
031:        import java.util.TreeMap;
032:        import java.util.TreeSet;
033:
034:        /**
035:         * A CollectionComponentParameter should be used to support inject an {@link Array}, a
036:         * {@link Collection}or {@link Map}of components automatically. The collection will contain
037:         * all components of a special type and additionally the type of the key may be specified. In
038:         * case of a map, the map's keys are the one of the component adapter.
039:         *
040:         * @author Aslak Hellesøy
041:         * @author Jörg Schaible
042:         */
043:        @SuppressWarnings("serial")
044:        public class CollectionComponentParameter implements  Parameter,
045:                Serializable {
046:
047:            /** Use <code>ARRAY</code> as {@link Parameter}for an Array that must have elements. */
048:            public static final CollectionComponentParameter ARRAY = new CollectionComponentParameter();
049:            /**
050:             * Use <code>ARRAY_ALLOW_EMPTY</code> as {@link Parameter}for an Array that may have no
051:             * elements.
052:             */
053:            public static final CollectionComponentParameter ARRAY_ALLOW_EMPTY = new CollectionComponentParameter(
054:                    true);
055:
056:            private final boolean emptyCollection;
057:            private final Class componentKeyType;
058:            private final Class componentValueType;
059:
060:            /**
061:             * Expect an {@link Array}of an appropriate type as parameter. At least one component of
062:             * the array's component type must exist.
063:             */
064:            public CollectionComponentParameter() {
065:                this (false);
066:            }
067:
068:            /**
069:             * Expect an {@link Array}of an appropriate type as parameter.
070:             *
071:             * @param emptyCollection <code>true</code> if an empty array also is a valid dependency
072:             *                        resolution.
073:             */
074:            public CollectionComponentParameter(boolean emptyCollection) {
075:                this (Void.TYPE, emptyCollection);
076:            }
077:
078:            /**
079:             * Expect any of the collection types {@link Array},{@link Collection}or {@link Map}as
080:             * parameter.
081:             *
082:             * @param componentValueType the type of the components (ignored in case of an Array)
083:             * @param emptyCollection    <code>true</code> if an empty collection resolves the
084:             *                           dependency.
085:             */
086:            public CollectionComponentParameter(Class componentValueType,
087:                    boolean emptyCollection) {
088:                this (Object.class, componentValueType, emptyCollection);
089:            }
090:
091:            /**
092:             * Expect any of the collection types {@link Array},{@link Collection}or {@link Map}as
093:             * parameter.
094:             *
095:             * @param componentKeyType   the type of the component's key
096:             * @param componentValueType the type of the components (ignored in case of an Array)
097:             * @param emptyCollection    <code>true</code> if an empty collection resolves the
098:             *                           dependency.
099:             */
100:            public CollectionComponentParameter(Class componentKeyType,
101:                    Class componentValueType, boolean emptyCollection) {
102:                this .emptyCollection = emptyCollection;
103:                this .componentKeyType = componentKeyType;
104:                this .componentValueType = componentValueType;
105:            }
106:
107:            /**
108:             * Resolve the parameter for the expected type. The method will return <code>null</code>
109:             * If the expected type is not one of the collection types {@link Array},
110:             * {@link Collection}or {@link Map}. An empty collection is only a valid resolution, if
111:             * the <code>emptyCollection</code> flag was set.
112:             *
113:             * @param container             {@inheritDoc}
114:             * @param adapter               {@inheritDoc}
115:             * @param expectedType          {@inheritDoc}
116:             * @param expectedNameBinding {@inheritDoc}
117:             *
118:             * @param useNames
119:             * @param binding
120:             * @return the instance of the collection type or <code>null</code>
121:             *
122:             * @throws PicoCompositionException {@inheritDoc}
123:             */
124:            @SuppressWarnings({"unchecked"})
125:            public Object resolveInstance(PicoContainer container,
126:                    ComponentAdapter adapter, Class expectedType,
127:                    NameBinding expectedNameBinding, boolean useNames,
128:                    Annotation binding) {
129:                // type check is done in isResolvable
130:                Object result = null;
131:                final Class collectionType = getCollectionType(expectedType);
132:                if (collectionType != null) {
133:                    final Map<Object, ComponentAdapter<?>> adapterMap = getMatchingComponentAdapters(
134:                            container, adapter, componentKeyType,
135:                            getValueType(expectedType));
136:                    if (Array.class.isAssignableFrom(collectionType)) {
137:                        result = getArrayInstance(container, expectedType,
138:                                adapterMap);
139:                    } else if (Map.class.isAssignableFrom(collectionType)) {
140:                        result = getMapInstance(container, expectedType,
141:                                adapterMap);
142:                    } else if (Collection.class
143:                            .isAssignableFrom(collectionType)) {
144:                        result = getCollectionInstance(container,
145:                                (Class<? extends Collection>) expectedType,
146:                                adapterMap);
147:                    } else {
148:                        throw new PicoCompositionException(expectedType
149:                                .getName()
150:                                + " is not a collective type");
151:                    }
152:                }
153:                return result;
154:            }
155:
156:            /**
157:             * Check for a successful dependency resolution of the parameter for the expected type. The
158:             * dependency can only be satisfied if the expected type is one of the collection types
159:             * {@link Array},{@link Collection}or {@link Map}. An empty collection is only a valid
160:             * resolution, if the <code>emptyCollection</code> flag was set.
161:             *
162:             * @param container             {@inheritDoc}
163:             * @param adapter               {@inheritDoc}
164:             * @param expectedType          {@inheritDoc}
165:             * @param expectedNameBinding {@inheritDoc}
166:             *
167:             * @param useNames
168:             * @param binding
169:             * @return <code>true</code> if matching components were found or an empty collective type
170:             *         is allowed
171:             */
172:            public boolean isResolvable(PicoContainer container,
173:                    ComponentAdapter adapter, Class expectedType,
174:                    NameBinding expectedNameBinding, boolean useNames,
175:                    Annotation binding) {
176:                final Class collectionType = getCollectionType(expectedType);
177:                final Class valueType = getValueType(expectedType);
178:                return collectionType != null
179:                        && (emptyCollection || getMatchingComponentAdapters(
180:                                container, adapter, componentKeyType, valueType)
181:                                .size() > 0);
182:            }
183:
184:            /**
185:             * Verify a successful dependency resolution of the parameter for the expected type. The
186:             * method will only return if the expected type is one of the collection types {@link Array},
187:             * {@link Collection}or {@link Map}. An empty collection is only a valid resolution, if
188:             * the <code>emptyCollection</code> flag was set.
189:             *
190:             * @param container             {@inheritDoc}
191:             * @param adapter               {@inheritDoc}
192:             * @param expectedType          {@inheritDoc}
193:             * @param expectedNameBinding {@inheritDoc}
194:             *
195:             * @param useNames
196:             * @param binding
197:             * @throws PicoCompositionException {@inheritDoc}
198:             */
199:            public void verify(PicoContainer container,
200:                    ComponentAdapter adapter, Class expectedType,
201:                    NameBinding expectedNameBinding, boolean useNames,
202:                    Annotation binding) {
203:                final Class collectionType = getCollectionType(expectedType);
204:                if (collectionType != null) {
205:                    final Class valueType = getValueType(expectedType);
206:                    final Collection componentAdapters = getMatchingComponentAdapters(
207:                            container, adapter, componentKeyType, valueType)
208:                            .values();
209:                    if (componentAdapters.isEmpty()) {
210:                        if (!emptyCollection) {
211:                            throw new PicoCompositionException(expectedType
212:                                    .getName()
213:                                    + " not resolvable, no components of type "
214:                                    + getValueType(expectedType).getName()
215:                                    + " available");
216:                        }
217:                    } else {
218:                        for (Object componentAdapter1 : componentAdapters) {
219:                            final ComponentAdapter componentAdapter = (ComponentAdapter) componentAdapter1;
220:                            componentAdapter.verify(container);
221:                        }
222:                    }
223:                } else {
224:                    throw new PicoCompositionException(expectedType.getName()
225:                            + " is not a collective type");
226:                }
227:            }
228:
229:            /**
230:             * Visit the current {@link Parameter}.
231:             *
232:             * @see org.picocontainer.Parameter#accept(org.picocontainer.PicoVisitor)
233:             */
234:            public void accept(final PicoVisitor visitor) {
235:                visitor.visitParameter(this );
236:            }
237:
238:            /**
239:             * Evaluate whether the given component adapter will be part of the collective type.
240:             *
241:             * @param adapter a <code>ComponentAdapter</code> value
242:             *
243:             * @return <code>true</code> if the adapter takes part
244:             */
245:            protected boolean evaluate(final ComponentAdapter adapter) {
246:                return adapter != null; // use parameter, prevent compiler warning
247:            }
248:
249:            /**
250:             * Collect the matching ComponentAdapter instances.
251:             *
252:             * @param container container to use for dependency resolution
253:             * @param adapter   {@link ComponentAdapter} to exclude
254:             * @param keyType   the compatible type of the key
255:             * @param valueType the compatible type of the addComponent
256:             *
257:             * @return a {@link Map} with the ComponentAdapter instances and their component keys as map key.
258:             */
259:            @SuppressWarnings({"unchecked"})
260:            protected Map<Object, ComponentAdapter<?>> getMatchingComponentAdapters(
261:                    PicoContainer container, ComponentAdapter adapter,
262:                    Class keyType, Class valueType) {
263:                final Map<Object, ComponentAdapter<?>> adapterMap = new LinkedHashMap<Object, ComponentAdapter<?>>();
264:                final PicoContainer parent = container.getParent();
265:                if (parent != null) {
266:                    adapterMap.putAll(getMatchingComponentAdapters(parent,
267:                            adapter, keyType, valueType));
268:                }
269:                final Collection<ComponentAdapter<?>> allAdapters = container
270:                        .getComponentAdapters();
271:                for (ComponentAdapter componentAdapter : allAdapters) {
272:                    adapterMap.remove(componentAdapter.getComponentKey());
273:                }
274:                final List<ComponentAdapter> adapterList = container
275:                        .getComponentAdapters(valueType);
276:                for (ComponentAdapter componentAdapter : adapterList) {
277:                    final Object key = componentAdapter.getComponentKey();
278:                    if (adapter != null
279:                            && key.equals(adapter.getComponentKey())) {
280:                        continue;
281:                    }
282:                    if (keyType.isAssignableFrom(key.getClass())
283:                            && evaluate(componentAdapter)) {
284:                        adapterMap.put(key, componentAdapter);
285:                    }
286:                }
287:                return adapterMap;
288:            }
289:
290:            private Class getCollectionType(final Class collectionType) {
291:                Class collectionClass = null;
292:                if (collectionType.isArray()) {
293:                    collectionClass = Array.class;
294:                } else if (Map.class.isAssignableFrom(collectionType)) {
295:                    collectionClass = Map.class;
296:                } else if (Collection.class.isAssignableFrom(collectionType)) {
297:                    collectionClass = Collection.class;
298:                }
299:                return collectionClass;
300:            }
301:
302:            private Class getValueType(final Class collectionType) {
303:                Class valueType = componentValueType;
304:                if (collectionType.isArray()) {
305:                    valueType = collectionType.getComponentType();
306:                }
307:                return valueType;
308:            }
309:
310:            private Object[] getArrayInstance(final PicoContainer container,
311:                    final Class expectedType,
312:                    final Map<Object, ComponentAdapter<?>> adapterList) {
313:                final Object[] result = (Object[]) Array.newInstance(
314:                        expectedType.getComponentType(), adapterList.size());
315:                int i = 0;
316:                for (ComponentAdapter componentAdapter : adapterList.values()) {
317:                    result[i] = container.getComponent(componentAdapter
318:                            .getComponentKey());
319:                    i++;
320:                }
321:                return result;
322:            }
323:
324:            @SuppressWarnings({"unchecked"})
325:            private Collection getCollectionInstance(
326:                    final PicoContainer container,
327:                    final Class<? extends Collection> expectedType,
328:                    final Map<Object, ComponentAdapter<?>> adapterList) {
329:                Class<? extends Collection> collectionType = expectedType;
330:                if (collectionType.isInterface()) {
331:                    // The order of tests are significant. The least generic types last.
332:                    if (List.class.isAssignableFrom(collectionType)) {
333:                        collectionType = ArrayList.class;
334:                        //            } else if (BlockingQueue.class.isAssignableFrom(collectionType)) {
335:                        //                collectionType = ArrayBlockingQueue.class;
336:                        //            } else if (Queue.class.isAssignableFrom(collectionType)) {
337:                        //                collectionType = LinkedList.class;
338:                    } else if (SortedSet.class.isAssignableFrom(collectionType)) {
339:                        collectionType = TreeSet.class;
340:                    } else if (Set.class.isAssignableFrom(collectionType)) {
341:                        collectionType = HashSet.class;
342:                    } else if (Collection.class
343:                            .isAssignableFrom(collectionType)) {
344:                        collectionType = ArrayList.class;
345:                    }
346:                }
347:                try {
348:                    Collection result = collectionType.newInstance();
349:                    for (ComponentAdapter componentAdapter : adapterList
350:                            .values()) {
351:                        result.add(container.getComponent(componentAdapter
352:                                .getComponentKey()));
353:                    }
354:                    return result;
355:                } catch (InstantiationException e) {
356:                    ///CLOVER:OFF
357:                    throw new PicoCompositionException(e);
358:                    ///CLOVER:ON
359:                } catch (IllegalAccessException e) {
360:                    ///CLOVER:OFF
361:                    throw new PicoCompositionException(e);
362:                    ///CLOVER:ON
363:                }
364:            }
365:
366:            @SuppressWarnings({"unchecked"})
367:            private Map getMapInstance(final PicoContainer container,
368:                    final Class<? extends Map> expectedType,
369:                    final Map<Object, ComponentAdapter<?>> adapterList) {
370:                Class<? extends Map> collectionType = expectedType;
371:                if (collectionType.isInterface()) {
372:                    // The order of tests are significant. The least generic types last.
373:                    if (SortedMap.class.isAssignableFrom(collectionType)) {
374:                        collectionType = TreeMap.class;
375:                        //            } else if (ConcurrentMap.class.isAssignableFrom(collectionType)) {
376:                        //                collectionType = ConcurrentHashMap.class;
377:                    } else if (Map.class.isAssignableFrom(collectionType)) {
378:                        collectionType = HashMap.class;
379:                    }
380:                }
381:                try {
382:                    Map result = collectionType.newInstance();
383:                    for (Map.Entry<Object, ComponentAdapter<?>> entry : adapterList
384:                            .entrySet()) {
385:                        final Object key = entry.getKey();
386:                        result.put(key, container.getComponent(key));
387:                    }
388:                    return result;
389:                } catch (InstantiationException e) {
390:                    ///CLOVER:OFF
391:                    throw new PicoCompositionException(e);
392:                    ///CLOVER:ON
393:                } catch (IllegalAccessException e) {
394:                    ///CLOVER:OFF
395:                    throw new PicoCompositionException(e);
396:                    ///CLOVER:ON
397:                }
398:            }
399:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.