Source Code Cross Referenced for HierarchicalProperties.java in  » Web-Framework » rife-1.6.1 » com » uwyn » rife » ioc » 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 » Web Framework » rife 1.6.1 » com.uwyn.rife.ioc 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright 2001-2007 Geert Bevin <gbevin[remove] at uwyn dot com>
003:         * Distributed under the terms of either:
004:         * - the common development and distribution license (CDDL), v1.0; or
005:         * - the GNU Lesser General Public License, v2.1 or later
006:         * $Id: HierarchicalProperties.java 3643 2007-01-12 15:29:45Z gbevin $
007:         */
008:        package com.uwyn.rife.ioc;
009:
010:        import java.util.*;
011:
012:        import com.uwyn.rife.ioc.HierarchicalProperties;
013:        import com.uwyn.rife.ioc.exceptions.IncompatiblePropertyValueTypeException;
014:        import com.uwyn.rife.ioc.exceptions.PropertyValueException;
015:        import java.text.CharacterIterator;
016:        import java.text.StringCharacterIterator;
017:
018:        /**
019:         * This class allows the creation of a hierarchical tree of named {@link
020:         * PropertyValue} instances.
021:         * <p>When a property is looked up in a child
022:         * <code>HierarchicalProperties</code> instance, the lookup will be propagated
023:         * to its parent when it couldn't be found in the child. A single hierarchical
024:         * line is thus considered to be one collection that groups all involved
025:         * <code>HierarchicalProperties</code> instances. Retrieving the names and the
026:         * size will recursively take all the properties of the parents into account
027:         * and return the consolidated result. To offer these features, intelligent
028:         * caching has been implemented to ensure optimal performance.
029:         *
030:         * @author Geert Bevin (gbevin[remove] at uwyn dot com)
031:         * @version $Revision: 3643 $
032:         * @since 1.1
033:         */
034:        public class HierarchicalProperties {
035:            private LinkedHashMap<String, PropertyValue> mProperties;
036:
037:            private HierarchicalProperties mParent;
038:            private LinkedHashSet<HierarchicalProperties> mChildren;
039:            private Set<String> mCachedNames;
040:            private Set<String> mCachedInjectableNames;
041:
042:            public HierarchicalProperties() {
043:            }
044:
045:            private HierarchicalProperties(HierarchicalProperties shadow) {
046:                mProperties = shadow.mProperties;
047:            }
048:
049:            /**
050:             * Creates a copy of this <code>HierarchicalProperties</code> hierarchy
051:             * until a certain instance is reached.
052:             * <p>
053:             * Each copied instance will shared the datastructure in which the
054:             * properties are stored with the original. Creating a shadow is this for
055:             * changing the hierarchical structure but maintaining a centralized
056:             * management of the properties.
057:             *
058:             * @param limit the <code>HierarchicalProperties</code> instance that will
059:             * not be part of the shadow copy and interrupt the copying process; or
060:             * <code>null</code> if the entire hierachy should be copied.
061:             * @return the shadow copy of this <code>HierarchicalProperties</code>
062:             * hierarchy
063:             * hierarchy
064:             * @since 1.1
065:             */
066:            public HierarchicalProperties createShadow(
067:                    HierarchicalProperties limit) {
068:                HierarchicalProperties result = new HierarchicalProperties(this );
069:
070:                HierarchicalProperties original = this ;
071:                HierarchicalProperties shadow = result;
072:                while (original.getParent() != null
073:                        && original.getParent() != limit) {
074:                    shadow.setParent(new HierarchicalProperties(original
075:                            .getParent()));
076:                    original = original.getParent();
077:                    shadow = shadow.getParent();
078:                }
079:                return result;
080:            }
081:
082:            /**
083:             * Retrieves the first parent of this <code>HierarchicalProperties</code>
084:             * hierarchy.
085:             *
086:             * @return the root of this <code>HierarchicalProperties</code>
087:             * hierarchy
088:             * @since 1.1
089:             */
090:            public HierarchicalProperties getRoot() {
091:                HierarchicalProperties root = this ;
092:                while (root.getParent() != null) {
093:                    root = root.getParent();
094:                }
095:
096:                return root;
097:            }
098:
099:            /**
100:             * Retrieves the <code>Map</code> with only the properties that are
101:             * locally present in this <code>HierarchicalProperties</code> instance.
102:             *
103:             * @return the local <code>Map</code> of this
104:             * <code>HierarchicalProperties</code> instance
105:             * @since 1.1
106:             */
107:            public Map<String, PropertyValue> getLocalMap() {
108:                if (null == mProperties) {
109:                    return Collections.EMPTY_MAP;
110:                }
111:
112:                return mProperties;
113:            }
114:
115:            /**
116:             * Sets the parent of this <code>HierarchicalProperties</code> instance.
117:             *
118:             * @param parent the parent of this instance; or <code>null</code> if this
119:             * instance should be isolated
120:             * @see #getParent
121:             * @since 1.1
122:             */
123:            public void setParent(HierarchicalProperties parent) {
124:                clearCaches();
125:
126:                if (mParent != null) {
127:                    mParent.removeChild(this );
128:                }
129:
130:                mParent = parent;
131:
132:                if (mParent != null) {
133:                    mParent.addChild(this );
134:                }
135:            }
136:
137:            /**
138:             * Sets the parent of this <code>HierarchicalProperties</code> instance.
139:             *
140:             * @param parent the parent of this instance; or <code>null</code> if this
141:             * instance should be isolated
142:             * @return this <code>HierarchicalProperties</code> instance
143:             * @see #getParent
144:             * @since 1.1
145:             */
146:            public HierarchicalProperties parent(HierarchicalProperties parent) {
147:                setParent(parent);
148:
149:                return this ;
150:            }
151:
152:            /**
153:             * Retrieves the parent of this <code>HierarchicalProperties</code>
154:             * instance.
155:             *
156:             * @return the parent of this <code>HierarchicalProperties</code>
157:             * instance; or
158:             * <p><code>null</code> if this instance is isolated
159:             * @see #parent
160:             * @since 1.1
161:             */
162:            public HierarchicalProperties getParent() {
163:                return mParent;
164:            }
165:
166:            /**
167:             * Associates the specified value with the specified name in this
168:             * <code>HierarchicalProperties</code> instance. If it previously
169:             * contained a mapping for this name, the old value is replaced by the
170:             * specified value.
171:             *
172:             * @param name the name that will be associated with the property
173:             * @param value the property value that will be associated with the
174:             * specified name
175:             * @return this <code>HierarchicalProperties</code> instance
176:             * @see #put(String, Object)
177:             * @see #putAll
178:             * @since 1.1
179:             */
180:            public HierarchicalProperties put(String name, PropertyValue value) {
181:                clearCaches();
182:
183:                if (null == mProperties) {
184:                    mProperties = new LinkedHashMap<String, PropertyValue>();
185:                }
186:
187:                mProperties.put(name, value);
188:
189:                return this ;
190:            }
191:
192:            /**
193:             * Associates the specified fixed object value with the specified name
194:             * in this <code>HierarchicalProperties</code> instance. If it previously
195:             * contained a mapping for this name, the old value is replaced by the
196:             * specified value.
197:             *
198:             * @param name the name that will be associated with the property
199:             * @param value the property value that will be associated with the
200:             * specified name, note that this method will create a {@link PropertyValueObject}
201:             * instance that will contain the value in a fixed manner
202:             * @return this <code>HierarchicalProperties</code> instance
203:             * @see #put(String, PropertyValue)
204:             * @see #putAll
205:             * @since 1.6
206:             */
207:            public HierarchicalProperties put(String name, Object value) {
208:                put(name, new PropertyValueObject(value));
209:
210:                return this ;
211:            }
212:
213:            /**
214:             * Removes the mapping for this name from this
215:             * <code>HierarchicalProperties</code> instance, if it is present.
216:             *
217:             * @param name the name that will be removed
218:             * @return the previously associated value; or
219:             * <p><code>null</code> if the name wasn't found in this
220:             * <code>HierarchicalProperties</code> instance
221:             * @since 1.1
222:             */
223:            public PropertyValue remove(String name) {
224:                if (null == mProperties) {
225:                    return null;
226:                }
227:
228:                clearCaches();
229:
230:                return mProperties.remove(name);
231:            }
232:
233:            /**
234:             * Copies all of the named properties from the specified
235:             * <code>HierarchicalProperties</code> instance to this
236:             * <code>HierarchicalProperties</code> instance. The effect of this call
237:             * is equivalent to that of calling {@link #put} on this
238:             * <code>HierarchicalProperties</code> once for each mapping from the
239:             * specified <code>HierarchicalProperties</code> instance.
240:             *
241:             * @param source the properties that will be stored in this
242:             * <code>HierarchicalProperties</code> instance
243:             * @return this <code>HierarchicalProperties</code> instance
244:             * @see #put
245:             * @since 1.1
246:             */
247:            public HierarchicalProperties putAll(HierarchicalProperties source) {
248:                clearCaches();
249:
250:                if (source.mProperties != null) {
251:                    if (null == mProperties) {
252:                        mProperties = new LinkedHashMap<String, PropertyValue>();
253:                    }
254:
255:                    mProperties.putAll(source.mProperties);
256:                }
257:
258:                return this ;
259:            }
260:
261:            /**
262:             * Copies all of the entries for a <code>Map</code> instance to this
263:             * <code>HierarchicalProperties</code> instance.
264:             *
265:             * @param source the map entries that will be stored in this
266:             * <code>HierarchicalProperties</code> instance
267:             * @return this <code>HierarchicalProperties</code> instance
268:             * @since 1.5
269:             */
270:            public HierarchicalProperties putAll(Map source) {
271:                if (null == source) {
272:                    return this ;
273:                }
274:
275:                clearCaches();
276:
277:                if (null == mProperties) {
278:                    mProperties = new LinkedHashMap<String, PropertyValue>();
279:                }
280:
281:                for (Map.Entry entry : ((Set<Map.Entry>) source.entrySet())) {
282:                    mProperties.put(String.valueOf(entry.getKey()),
283:                            new PropertyValueObject(entry.getValue()));
284:                }
285:
286:                return this ;
287:            }
288:
289:            /**
290:             * Checks the <code>HierarchicalProperties</code> hierarchy for the
291:             * presence of the specified name.
292:             *
293:             * @param name the name whose presence will be checked
294:             * @return <code>true</code> if the name was found; or
295:             * <p><code>false</code> otherwise
296:             * @see #get
297:             * @since 1.1
298:             */
299:            public boolean contains(String name) {
300:                HierarchicalProperties current = this ;
301:
302:                LinkedHashMap<String, PropertyValue> properties = null;
303:                while (true) {
304:                    properties = current.mProperties;
305:
306:                    if (properties != null) {
307:                        if (properties.containsKey(name)) {
308:                            return true;
309:                        }
310:                    }
311:
312:                    if (null == current.mParent) {
313:                        break;
314:                    }
315:
316:                    current = current.mParent;
317:                }
318:
319:                return false;
320:            }
321:
322:            /**
323:             * Retrieves the <code>PropertyValue</code> for a specific name from the
324:             * <code>HierarchicalProperties</code> hierarchy.
325:             *
326:             * @param name the name whose associated value will be returned
327:             * @return the associated <code>PropertyValue</code>; or
328:             * <p><code>null</code> if the name could not be found
329:             * @see #contains
330:             * @since 1.1
331:             */
332:            public PropertyValue get(String name) {
333:                HierarchicalProperties current = this ;
334:                PropertyValue result;
335:
336:                LinkedHashMap<String, PropertyValue> properties = null;
337:                while (true) {
338:                    properties = current.mProperties;
339:
340:                    if (properties != null) {
341:                        result = properties.get(name);
342:                        if (result != null) {
343:                            return result;
344:                        }
345:                    }
346:
347:                    if (null == current.mParent) {
348:                        break;
349:                    }
350:
351:                    current = current.mParent;
352:                }
353:
354:                return null;
355:            }
356:
357:            /**
358:             * Retrieves the value of <code>PropertyValue</code> for a specific name from
359:             * the <code>HierarchicalProperties</code> hierarchy.
360:             *
361:             * @param name the name whose associated value will be returned
362:             * @return the associated <code>PropertyValue</code>; or
363:             * <p><code>null</code> if the name could not be found
364:             * @throws PropertyValueException when an error occurred while retrieving the
365:             * property value
366:             * @see #get
367:             * @see #getValue(String, Object)
368:             * @since 1.1
369:             */
370:            public Object getValue(String name) throws PropertyValueException {
371:                return getValue(name, null);
372:            }
373:
374:            /**
375:             * Retrieves the value of <code>PropertyValue</code> for a specific name from
376:             * the <code>HierarchicalProperties</code> hierarchy. If the property couldn't
377:             * be found or if the value was <code>null</code>, the default value will be
378:             * returned.
379:             *
380:             * @param name the name whose associated value will be returned
381:             * @param defaultValue the value that should be used as a fallback
382:             * @return the associated <code>PropertyValue</code>; or
383:             * <p>the <code>defaultValue</code> if the property couldn't be found or if
384:             * the value was <code>null</code>
385:             * @throws PropertyValueException when an error occurred while retrieving the
386:             * property value
387:             * @see #get
388:             * @see #getValue(String)
389:             * @since 1.1
390:             */
391:            public Object getValue(String name, Object defaultValue)
392:                    throws PropertyValueException {
393:                Object result = null;
394:
395:                PropertyValue property = get(name);
396:                if (property != null) {
397:                    result = property.getValue();
398:                }
399:
400:                if (null == result) {
401:                    return defaultValue;
402:                }
403:
404:                return result;
405:            }
406:
407:            /**
408:             * Retrieves the string value of <code>PropertyValue</code> for a specific name from
409:             * the <code>HierarchicalProperties</code> hierarchy.
410:             *
411:             * @param name the name whose associated value will be returned
412:             * @return the string value of the retrieved <code>PropertyValue</code>; or
413:             * <p><code>null</code> if the name could not be found
414:             * @throws PropertyValueException when an error occurred while retrieving the
415:             * property value
416:             * @see #get
417:             * @see #getValueString(String, String)
418:             * @see #getValueTyped
419:             * @since 1.1
420:             */
421:            public String getValueString(String name)
422:                    throws PropertyValueException {
423:                return getValueString(name, null);
424:            }
425:
426:            /**
427:             * Retrieves the string value of <code>PropertyValue</code> for a specific name from
428:             * the <code>HierarchicalProperties</code> hierarchy. If the property couldn't
429:             * be found, if the value was <code>null</code> or if the value was empty, the
430:             * default value will be returned.
431:             *
432:             * @param name the name whose associated value will be returned
433:             * @param defaultValue the value that should be used as a fallback
434:             * @return the string value of the retrieved <code>PropertyValue</code>; or
435:             * <p>the <code>defaultValue</code> if the property couldn't be found or if
436:             * the value was <code>null</code> or an empty string
437:             * @throws PropertyValueException when an error occurred while retrieving the
438:             * property value
439:             * @see #get
440:             * @see #getValueString(String)
441:             * @see #getValueTyped
442:             * @since 1.1
443:             */
444:            public String getValueString(String name, String defaultValue)
445:                    throws PropertyValueException {
446:                String result = null;
447:
448:                PropertyValue property = get(name);
449:                if (property != null) {
450:                    result = property.getValueString();
451:                }
452:
453:                if (null == result || 0 == result.length()) {
454:                    return defaultValue;
455:                }
456:
457:                return result;
458:            }
459:
460:            /**
461:             * Retrieves the typed value of <code>PropertyValue</code> for a specific name from
462:             * the <code>HierarchicalProperties</code> hierarchy.
463:             * <p>
464:             * Note that no conversion will occurr, the value is simple verified to be
465:             * assignable to the requested type and then casted to it.
466:             *
467:             * @param name the name whose associated value will be returned
468:             * @param type the class that the value has to be retrieved as
469:             * @return the associated <code>PropertyValue</code> as an instance of the
470:             * provided type;  or
471:             * <p><code>null</code> if the name could not be found
472:             * @throws IncompatiblePropertyValueTypeException when the type of the property
473:             * value wasn't compatible with the requested type
474:             * @throws PropertyValueException when an error occurred while retrieving the
475:             * property value
476:             * @see #get
477:             * @see #getValueString
478:             * @see #getValueTyped(String, Class)
479:             * @since 1.6
480:             */
481:            public <T> T getValueTyped(String name, Class<T> type)
482:                    throws PropertyValueException {
483:                return (T) getValueTyped(name, type, null);
484:            }
485:
486:            /**
487:             * Retrieves the typed value of <code>PropertyValue</code> for a specific name from
488:             * the <code>HierarchicalProperties</code> hierarchy.
489:             * <p>
490:             * Note that no conversion will occurr, the value is simple verified to be
491:             * assignable to the requested type and then casted to it.
492:             *
493:             * @param name the name whose associated value will be returned
494:             * @param type the class that the value has to be retrieved as
495:             * @param defaultValue the value that should be used as a fallback
496:             * @return the associated <code>PropertyValue</code> as an instance of the
497:             * provided type;  or
498:             * <p>the <code>defaultValue</code> if the property couldn't be found or if
499:             * the value was <code>null</code>
500:             * @throws IncompatiblePropertyValueTypeException when the type of the property
501:             * value wasn't compatible with the requested type
502:             * @throws PropertyValueException when an error occurred while retrieving the
503:             * property value
504:             * @see #get
505:             * @see #getValueString
506:             * @see #getValueTyped(String, Class)
507:             * @since 1.6
508:             */
509:            public <T> T getValueTyped(String name, Class<T> type,
510:                    T defaultValue) throws PropertyValueException {
511:                if (null == name || null == type || 0 == name.length()) {
512:                    return defaultValue;
513:                }
514:
515:                Object result = null;
516:
517:                PropertyValue property = get(name);
518:                if (property != null) {
519:                    result = property.getValue();
520:                }
521:
522:                if (null == result) {
523:                    return defaultValue;
524:                }
525:
526:                if (!type.isAssignableFrom(result.getClass())) {
527:                    throw new IncompatiblePropertyValueTypeException(name,
528:                            type, result.getClass(), null);
529:                }
530:
531:                return (T) result;
532:            }
533:
534:            /**
535:             * Retrieves the number of unique names in the
536:             * <code>HierarchicalProperties</code> hierarchy.
537:             *
538:             * @return the amount of unique names
539:             * @since 1.1
540:             */
541:            public int size() {
542:                return getNames().size();
543:            }
544:
545:            /**
546:             * Retrieves a <code>Set</code> with the unique names that are present in
547:             * the <code>HierarchicalProperties</code> hierarchy.
548:             *
549:             * @return a collection with the unique names
550:             * @see #getInjectableNames
551:             * @since 1.1
552:             */
553:            public Collection<String> getNames() {
554:                if (mCachedNames != null) {
555:                    return mCachedNames;
556:                }
557:
558:                HierarchicalProperties current = this ;
559:                Set<String> names = new LinkedHashSet<String>();
560:
561:                LinkedHashMap<String, PropertyValue> properties = null;
562:                while (true) {
563:                    properties = current.mProperties;
564:
565:                    if (properties != null) {
566:                        names.addAll(properties.keySet());
567:                    }
568:
569:                    if (null == current.mParent) {
570:                        break;
571:                    }
572:
573:                    current = current.mParent;
574:                }
575:
576:                mCachedNames = names;
577:
578:                return names;
579:            }
580:
581:            /**
582:             * Retrieves a <code>Set</code> with the unique names that are present in
583:             * the <code>HierarchicalProperties</code> hierarchy and that conform to
584:             * the <a
585:             * href="http://java.sun.com/docs/books/jls/third_edition/html/lexical.html#3.8">Java
586:             * rules for valid identifiers</a>. The names in this set are thus usable
587:             * for injection through bean setters.
588:             *
589:             * @return a <code>Set</code> with the unique injectable names
590:             * @see #getNames
591:             * @since 1.1
592:             */
593:            public Collection<String> getInjectableNames() {
594:                if (mCachedInjectableNames != null) {
595:                    return mCachedInjectableNames;
596:                }
597:
598:                Set<String> injectable_names = new LinkedHashSet<String>();
599:
600:                Collection<String> names = getNames();
601:                for (String name : names) {
602:                    boolean injectable = true;
603:                    CharacterIterator it = new StringCharacterIterator(name);
604:                    for (char c = it.first(); c != CharacterIterator.DONE; c = it
605:                            .next()) {
606:                        if (!Character.isJavaIdentifierPart(c)) {
607:                            injectable = false;
608:                            break;
609:                        }
610:                    }
611:
612:                    if (injectable) {
613:                        injectable_names.add(name);
614:                    }
615:                }
616:
617:                mCachedInjectableNames = injectable_names;
618:
619:                return injectable_names;
620:            }
621:
622:            private void clearCaches() {
623:                mCachedNames = null;
624:                mCachedInjectableNames = null;
625:
626:                if (null == mChildren) {
627:                    return;
628:                }
629:
630:                for (HierarchicalProperties child : mChildren) {
631:                    child.clearCaches();
632:                }
633:            }
634:
635:            private void addChild(HierarchicalProperties child) {
636:                if (null == mChildren) {
637:                    mChildren = new LinkedHashSet<HierarchicalProperties>();
638:                }
639:                mChildren.add(child);
640:            }
641:
642:            private void removeChild(HierarchicalProperties child) {
643:                if (null == mChildren) {
644:                    return;
645:                }
646:                mChildren.remove(child);
647:            }
648:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.