KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > codehaus > dna > impl > DefaultConfiguration


1 /*
2  * Copyright (C) The DNA Group. All rights reserved.
3  *
4  * This software is published under the terms of the DNA
5  * Software License version 1.1, a copy of which has been included
6  * with this distribution in the LICENSE.txt file.
7  */

8 package org.codehaus.dna.impl;
9
10 import java.util.ArrayList JavaDoc;
11 import java.util.HashMap JavaDoc;
12 import java.util.List JavaDoc;
13 import java.util.Map JavaDoc;
14 import java.util.Set JavaDoc;
15
16 import org.codehaus.dna.Configuration;
17 import org.codehaus.dna.ConfigurationException;
18
19 /**
20  * In memory Configuration implementation.
21  * The developer should create the DefaultConfiguration,
22  * associate value, attributes and/or child elements configuration
23  * and then invoke {@link #makeReadOnly()} before passing the
24  * Configuration to the client component.
25  *
26  * @version $Revision: 1.2 $ $Date: 2004/05/01 09:51:48 $
27  */

28 public class DefaultConfiguration
29     extends AbstractFreezable
30     implements Configuration
31 {
32     /**
33      * Postfix indicating that location is generated.
34      */

35     private static final String JavaDoc AUTOGEN_POSTFIX = "<autogen>";
36
37     /**
38      * The constant that boolean values must equal to be "true".
39      */

40     private static final String JavaDoc TRUE_STRING = "true";
41
42     /**
43      * Constant for empty String array to reduce
44      * creation cost for empty array.
45      */

46     private static final String JavaDoc[] EMPTY_STRING_ARRAY = new String JavaDoc[ 0 ];
47
48     /**
49      * Constant for empty configuration array to reduce
50      * creation cost for empty array.
51      */

52     private static final Configuration[] EMPTY_CONFIG_ARRAY = new Configuration[ 0 ];
53
54     /**
55      * The name of configuration element.
56      */

57     private final String JavaDoc m_name;
58
59     /**
60      * The location of configuration element in source.
61      * May be empty string if unknown.
62      */

63     private final String JavaDoc m_location;
64
65     /**
66      * The path of configuration element in document.
67      * May be empty string if unknown.
68      */

69     private final String JavaDoc m_path;
70
71     /**
72      * The attributes defined by configuration (May be null).
73      */

74     private Map JavaDoc m_attributes;
75
76     /**
77      * The child elements defined by
78      * configuration (May be null). If
79      * {@link #m_value} not null then
80      * m_children must be null.
81      */

82     private List JavaDoc m_children;
83
84     /**
85      * The value contained in configuration
86      * (May be null). If {@link #m_children} not
87      * null then m_value must be null.
88      */

89     private String JavaDoc m_value;
90
91     /**
92      * Create a DefaultConfiguration instance.
93      *
94      * @param name the name of configuration element
95      * @param location the location of configuration element in source
96      * @param path the path of configuration element in document
97      */

98     public DefaultConfiguration( final String JavaDoc name,
99                                  final String JavaDoc location,
100                                  final String JavaDoc path )
101     {
102         if( null == name )
103         {
104             throw new NullPointerException JavaDoc( "name" );
105         }
106         if( null == path )
107         {
108             throw new NullPointerException JavaDoc( "path" );
109         }
110         if( null == location )
111         {
112             throw new NullPointerException JavaDoc( "location" );
113         }
114         m_name = name;
115         m_path = path;
116         m_location = location;
117     }
118
119     /**
120      * Return the name of the configuration element.
121      *
122      * @return the name of the configuration element.
123      */

124     public String JavaDoc getName()
125     {
126         return m_name;
127     }
128
129     /**
130      * Return the path to the configuration element.
131      * The path should be in the xpath form but may
132      * be the empty string if unabel to determine path.
133      *
134      * @return the path to the configuration element.
135      */

136     public final String JavaDoc getPath()
137     {
138         return m_path;
139     }
140
141     /**
142      * Return the location of configuration element.
143      * Usually of the form "uri[:line number[:column number]]"
144      * if possible. ie "file:myFile.xml:80:2". However the line
145      * number and column number may be elided if unavailable.
146      *
147      * @return the location of configuration element.
148      */

149     public String JavaDoc getLocation()
150     {
151         return m_location;
152     }
153
154     /**
155      * Return an array of all the child elements.
156      *
157      * @return an array of all the child elements.
158      */

159     public Configuration[] getChildren()
160     {
161         final List JavaDoc childList = getChildList();
162         if( null == childList )
163         {
164             return EMPTY_CONFIG_ARRAY;
165         }
166         else
167         {
168             return (Configuration[])childList.toArray( new Configuration[ childList.size() ] );
169         }
170     }
171
172     /**
173      * Return an array of all the child elements with specified name.
174      *
175      * @param name the name of child configuration objects
176      * @return an array of all the child elements with specified name.
177      */

178     public Configuration[] getChildren( final String JavaDoc name )
179     {
180         if( null == name )
181         {
182             throw new NullPointerException JavaDoc( "name" );
183         }
184         final List JavaDoc children = getChildList();
185         if( null == children )
186         {
187             return EMPTY_CONFIG_ARRAY;
188         }
189         else
190         {
191             final ArrayList JavaDoc results = new ArrayList JavaDoc();
192             final int count = children.size();
193             for( int i = 0; i < count; i++ )
194             {
195                 final Configuration child = (Configuration)children.get( i );
196                 if( child.getName().equals( name ) )
197                 {
198                     results.add( child );
199                 }
200             }
201             return (Configuration[])results.toArray( new Configuration[ results.size() ] );
202         }
203     }
204
205     /**
206      * Return a child Configuration element with specified name.
207      * If no such element exists an element will be autocreated.
208      *
209      * @param name the name of child configuration object
210      * @return a child Configuration element with specified name.
211      */

212     public Configuration getChild( final String JavaDoc name )
213     {
214         return getChild( name, true );
215     }
216
217     /**
218      * Return a child Configuration element with specified name.
219      * If no such element exists and createChild is true then an
220      * element will be autocreated otherwise null will be returned.
221      *
222      * @param name the name of child configuration object
223      * @param createChild true if child should be created if it does not exist
224      * @return a child Configuration element with specified name.
225      */

226     public Configuration getChild( final String JavaDoc name,
227                                    final boolean createChild )
228     {
229         if( null == name )
230         {
231             throw new NullPointerException JavaDoc( "name" );
232         }
233         final List JavaDoc children = getChildList();
234         if( null != children )
235         {
236             final int count = children.size();
237             for( int i = 0; i < count; i++ )
238             {
239                 final Configuration child = (Configuration)children.get( i );
240                 if( child.getName().equals( name ) )
241                 {
242                     return child;
243                 }
244             }
245         }
246         if( createChild )
247         {
248             final String JavaDoc path = getPath() + ConfigurationUtil.PATH_SEPARATOR + getName();
249             return new DefaultConfiguration( name, generateLocation(), path );
250         }
251         else
252         {
253             return null;
254         }
255
256     }
257
258     /**
259      * Return text value of element.
260      *
261      * @return the value
262      * @throws ConfigurationException if no value in element
263      */

264     public String JavaDoc getValue()
265         throws ConfigurationException
266     {
267         if( null != m_value )
268         {
269             return m_value;
270         }
271         else
272         {
273             final String JavaDoc message = "No value specified";
274             throw new ConfigurationException( message, getPath(), getLocation() );
275         }
276     }
277
278     /**
279      * Return text value of element.
280      * Use specified default if no value in element.
281      *
282      * @param defaultValue the default value
283      * @return the value
284      */

285     public String JavaDoc getValue( final String JavaDoc defaultValue )
286     {
287         if( null != m_value )
288         {
289             return m_value;
290         }
291         else
292         {
293             return defaultValue;
294         }
295     }
296
297     /**
298      * Return text value of element as a boolean.
299      *
300      * @return the value
301      * @throws ConfigurationException if no value in element
302      * or value can not be converted to correct type
303      */

304     public boolean getValueAsBoolean()
305         throws ConfigurationException
306     {
307         return getValue().equals( "true" );
308     }
309
310     /**
311      * Return text value of element as a boolean.
312      * Use specified default if no value in element or
313      * value can not be converted to correct type.
314      *
315      * @param defaultValue the default value
316      * @return the value
317      */

318     public boolean getValueAsBoolean( final boolean defaultValue )
319     {
320         if( null == m_value )
321         {
322             return defaultValue;
323         }
324         else
325         {
326             return m_value.equals( TRUE_STRING );
327         }
328     }
329
330     /**
331      * Return text value of element as an integer.
332      *
333      * @return the value
334      * @throws ConfigurationException if no value in element
335      * or value can not be converted to correct type
336      */

337     public int getValueAsInteger()
338         throws ConfigurationException
339     {
340         try
341         {
342             return Integer.parseInt( getValue() );
343         }
344         catch( final NumberFormatException JavaDoc nfe )
345         {
346             final String JavaDoc message =
347                 "Unable to parse " + getValue() + " as an integer";
348             throw new ConfigurationException( message, getPath(), getLocation(), nfe );
349         }
350     }
351
352     /**
353      * Return text value of element as an integer.
354      * Use specified default if no value in element or
355      * value can not be converted to correct type.
356      *
357      * @param defaultValue the default value
358      * @return the value
359      */

360     public int getValueAsInteger( final int defaultValue )
361     {
362         if( null == m_value )
363         {
364             return defaultValue;
365         }
366         else
367         {
368             try
369             {
370                 return Integer.parseInt( m_value );
371             }
372             catch( final NumberFormatException JavaDoc nfe )
373             {
374                 return defaultValue;
375             }
376         }
377     }
378
379     /**
380      * Return text value of element as a long.
381      *
382      * @return the value
383      * @throws ConfigurationException if no value in element
384      * or value can not be converted to correct type
385      */

386     public long getValueAsLong()
387         throws ConfigurationException
388     {
389         try
390         {
391             return Long.parseLong( getValue() );
392         }
393         catch( final NumberFormatException JavaDoc nfe )
394         {
395             final String JavaDoc message =
396                 "Unable to parse " + getValue() + " as a Long";
397             throw new ConfigurationException( message, getPath(), getLocation(), nfe );
398         }
399     }
400
401     /**
402      * Return text value of element as a long.
403      * Use specified default if no value in element or
404      * value can not be converted to correct type.
405      *
406      * @param defaultValue the default value
407      * @return the value
408      */

409     public long getValueAsLong( final long defaultValue )
410     {
411         if( null == m_value )
412         {
413             return defaultValue;
414         }
415         else
416         {
417             try
418             {
419                 return Long.parseLong( m_value );
420             }
421             catch( final NumberFormatException JavaDoc nfe )
422             {
423                 return defaultValue;
424             }
425         }
426     }
427
428     /**
429      * Return text value of element as a float.
430      *
431      * @return the value
432      * @throws ConfigurationException if no value in element
433      * or value can not be converted to correct type
434      */

435     public float getValueAsFloat()
436         throws ConfigurationException
437     {
438         try
439         {
440             return Float.parseFloat( getValue() );
441         }
442         catch( final NumberFormatException JavaDoc nfe )
443         {
444             final String JavaDoc message =
445                 "Unable to parse " + getValue() + " as a Long";
446             throw new ConfigurationException( message, getPath(), getLocation(), nfe );
447         }
448     }
449
450     /**
451      * Return text value of element as a float.
452      * Use specified default if no value in element or
453      * value can not be converted to correct type.
454      *
455      * @param defaultValue the default value
456      * @return the value
457      */

458     public float getValueAsFloat( final float defaultValue )
459     {
460         if( null == m_value )
461         {
462             return defaultValue;
463         }
464         else
465         {
466             try
467             {
468                 return Float.parseFloat( m_value );
469             }
470             catch( final NumberFormatException JavaDoc nfe )
471             {
472                 return defaultValue;
473             }
474         }
475     }
476
477     /**
478      * Return an array of all the attribute names.
479      *
480      * @return an array of all the attribute names.
481      */

482     public String JavaDoc[] getAttributeNames()
483     {
484         final Map JavaDoc attributeMap = getAttributeMap();
485         if( null == attributeMap )
486         {
487             return EMPTY_STRING_ARRAY;
488         }
489         else
490         {
491             final Set JavaDoc keys = attributeMap.keySet();
492             return (String JavaDoc[])attributeMap.keySet().toArray( new String JavaDoc[ keys.size() ] );
493         }
494     }
495
496     /**
497      * Return attribute value with specified name.
498      *
499      * @param name the attribute name
500      * @return the attribute value
501      * @throws ConfigurationException if no attribute with
502      * specified name
503      */

504     public String JavaDoc getAttribute( final String JavaDoc name )
505         throws ConfigurationException
506     {
507         final String JavaDoc value = doGetAttribute( name );
508         if( null != value )
509         {
510             return value;
511         }
512         else
513         {
514             final String JavaDoc message =
515                 "Attribute named " + name + " not specified.";
516             throw new ConfigurationException( message, getPath(), getLocation() );
517         }
518     }
519
520     /**
521      * Return attribute value with specified name.
522      * If no attribute with specified name then return
523      * default value.
524      *
525      * @param name the attribute name
526      * @param defaultValue the default value
527      * @return the attribute value
528      */

529     public String JavaDoc getAttribute( final String JavaDoc name,
530                                 final String JavaDoc defaultValue )
531     {
532         final String JavaDoc value = doGetAttribute( name );
533         if( null != value )
534         {
535             return value;
536         }
537         else
538         {
539             return defaultValue;
540         }
541     }
542
543     /**
544      * Return attribute value with specified name or null
545      * if no such attribute.
546      *
547      * @param name the attribute name
548      * @return the attribute value
549      */

550     private String JavaDoc doGetAttribute( final String JavaDoc name )
551     {
552         if( null == name )
553         {
554             throw new NullPointerException JavaDoc( "name" );
555         }
556         final Map JavaDoc attributeMap = getAttributeMap();
557         if( null != attributeMap )
558         {
559             final String JavaDoc value = (String JavaDoc)attributeMap.get( name );
560             if( null != value )
561             {
562                 return value;
563             }
564         }
565         return null;
566     }
567
568     /**
569      * Return attribute value with specified name as a boolean.
570      *
571      * @param name the attribute name
572      * @return the attribute value
573      * @throws ConfigurationException if no attribute with
574      * specified name or attribute can not be converted
575      * to correct type
576      */

577     public boolean getAttributeAsBoolean( final String JavaDoc name )
578         throws ConfigurationException
579     {
580         return getAttribute( name ).equals( TRUE_STRING );
581     }
582
583     /**
584      * Return attribute value with specified name as a boolean.
585      * If no attribute with specified name or attribute can
586      * not be converted to correct type then return
587      * default value.
588      *
589      * @param name the attribute name
590      * @param defaultValue the default value
591      * @return the attribute value
592      */

593     public boolean getAttributeAsBoolean( final String JavaDoc name,
594                                           final boolean defaultValue )
595     {
596         final String JavaDoc value = getAttribute( name, null );
597         if( null != value )
598         {
599             return value.equals( TRUE_STRING );
600         }
601         return defaultValue;
602     }
603
604     /**
605      * Return attribute value with specified name as an integer.
606      *
607      * @param name the attribute name
608      * @return the attribute value
609      * @throws ConfigurationException if no attribute with
610      * specified name or attribute can not be converted
611      * to correct type
612      */

613     public int getAttributeAsInteger( final String JavaDoc name )
614         throws ConfigurationException
615     {
616         final String JavaDoc value = getAttribute( name );
617         try
618         {
619             return Integer.parseInt( value );
620         }
621         catch( final NumberFormatException JavaDoc nfe )
622         {
623             final String JavaDoc message =
624                 "Unable to parse " + value + " as an Integer.";
625             throw new ConfigurationException( message, getPath(), getLocation() );
626         }
627     }
628
629     /**
630      * Return attribute value with specified name as an integer.
631      * If no attribute with specified name or attribute can
632      * not be converted to correct type then return
633      * default value.
634      *
635      * @param name the attribute name
636      * @param defaultValue the default value
637      * @return the attribute value
638      */

639     public int getAttributeAsInteger( final String JavaDoc name,
640                                       final int defaultValue )
641     {
642         final String JavaDoc value = getAttribute( name, null );
643         if( null != value )
644         {
645             try
646             {
647                 return Integer.parseInt( value );
648             }
649             catch( final NumberFormatException JavaDoc nfe )
650             {
651                 //Fall through to return defaultValue
652
}
653         }
654         return defaultValue;
655     }
656
657     /**
658      * Return attribute value with specified name as a long.
659      *
660      * @param name the attribute name
661      * @return the attribute value
662      * @throws ConfigurationException if no attribute with
663      * specified name or attribute can not be converted
664      * to correct type
665      */

666     public long getAttributeAsLong( final String JavaDoc name )
667         throws ConfigurationException
668     {
669         final String JavaDoc value = getAttribute( name );
670         try
671         {
672             return Long.parseLong( value );
673         }
674         catch( final NumberFormatException JavaDoc nfe )
675         {
676             final String JavaDoc message =
677                 "Unable to parse " + value + " as a Long.";
678             throw new ConfigurationException( message, getPath(), getLocation() );
679         }
680     }
681
682     /**
683      * Return attribute value with specified name as a long.
684      * If no attribute with specified name or attribute can
685      * not be converted to correct type then return
686      * default value.
687      *
688      * @param name the attribute name
689      * @param defaultValue the default value
690      * @return the attribute value
691      */

692     public long getAttributeAsLong( final String JavaDoc name,
693                                     final long defaultValue )
694     {
695         final String JavaDoc value = getAttribute( name, null );
696         if( null != value )
697         {
698             try
699             {
700                 return Long.parseLong( value );
701             }
702             catch( final NumberFormatException JavaDoc nfe )
703             {
704                 //Fall through to return defaultValue
705
}
706         }
707         return defaultValue;
708     }
709
710     /**
711      * Return attribute value with specified name as afloat.
712      *
713      * @param name the attribute name
714      * @return the attribute value
715      * @throws ConfigurationException if no attribute with
716      * specified name or attribute can not be converted
717      * to correct type
718      */

719     public float getAttributeAsFloat( final String JavaDoc name )
720         throws ConfigurationException
721     {
722         final String JavaDoc value = getAttribute( name );
723         try
724         {
725             return Float.parseFloat( value );
726         }
727         catch( final NumberFormatException JavaDoc nfe )
728         {
729             final String JavaDoc message =
730                 "Unable to parse " + value + " as a Float.";
731             throw new ConfigurationException( message, getPath(), getLocation() );
732         }
733     }
734
735     /**
736      * Return attribute value with specified name as a float.
737      * If no attribute with specified name or attribute can
738      * not be converted to correct type then return
739      * default value.
740      *
741      * @param name the attribute name
742      * @param defaultValue the default value
743      * @return the attribute value
744      */

745     public float getAttributeAsFloat( final String JavaDoc name,
746                                       final float defaultValue )
747     {
748         final String JavaDoc value = getAttribute( name, null );
749         if( null != value )
750         {
751             try
752             {
753                 return Float.parseFloat( value );
754             }
755             catch( final NumberFormatException JavaDoc nfe )
756             {
757                 //Fall through to return defaultValue
758
}
759         }
760         return defaultValue;
761     }
762
763     /**
764      * Mark the configuration and child configurations as read only.
765      */

766     public void makeReadOnly()
767     {
768         super.makeReadOnly();
769         final List JavaDoc children = getChildList();
770         if( null != children )
771         {
772             final int count = children.size();
773             for( int i = 0; i < count; i++ )
774             {
775                 final Configuration configuration = (Configuration)children.get( i );
776                 if( configuration instanceof Freezable )
777                 {
778                     ( (Freezable)configuration ).makeReadOnly();
779                 }
780             }
781         }
782     }
783
784     /**
785      * Set an attribute of configuration.
786      *
787      * @param key the attribute key
788      * @param value the attribute value
789      */

790     public void setAttribute( final String JavaDoc key,
791                               final String JavaDoc value )
792     {
793         if( null == key )
794         {
795             throw new NullPointerException JavaDoc( "key" );
796         }
797         if( null == value )
798         {
799             throw new NullPointerException JavaDoc( "value" );
800         }
801         checkWriteable();
802         if( null == m_attributes )
803         {
804             m_attributes = new HashMap JavaDoc();
805         }
806         m_attributes.put( key, value );
807     }
808
809     /**
810      * Add a child configuration element.
811      *
812      * @param configuration the child configuration element.
813      */

814     public void addChild( final Configuration configuration )
815     {
816         if( null == configuration )
817         {
818             throw new NullPointerException JavaDoc( "configuration" );
819         }
820         checkWriteable();
821         if( null != m_value )
822         {
823             throwMixedContentException();
824         }
825         if( null == m_children )
826         {
827             m_children = new ArrayList JavaDoc();
828         }
829         m_children.add( configuration );
830     }
831
832     /**
833      * Set the value of the configuration element.
834      *
835      * @param value the value of the configuration element.
836      */

837     public void setValue( final String JavaDoc value )
838     {
839         if( null == value )
840         {
841             throw new NullPointerException JavaDoc( "value" );
842         }
843         checkWriteable();
844         final List JavaDoc children = getChildList();
845         if( null != children && 0 != children.size() )
846         {
847             throwMixedContentException();
848         }
849         m_value = value;
850     }
851
852     /**
853      * Overide toString to improve ability to debug implementation.
854      *
855      * @return string representation of object
856      */

857     public String JavaDoc toString()
858     {
859         final StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
860         sb.append( "[Configuration name='" );
861         sb.append( getName() );
862         sb.append( "'" );
863         if( null != m_attributes )
864         {
865             sb.append( " attributes=" );
866             sb.append( m_attributes );
867         }
868         sb.append( "]" );
869         return sb.toString();
870     }
871
872     /**
873      * Return the list of child configuration objects.
874      *
875      * @return the list of child configuration objects.
876      */

877     protected final List JavaDoc getChildList()
878     {
879         return m_children;
880     }
881
882     /**
883      * Return the backing map for attributes.
884      *
885      * @return the backing map for attributes.
886      */

887     protected final Map JavaDoc getAttributeMap()
888     {
889         return m_attributes;
890     }
891
892     /**
893      * Generate a location string that postfixes
894      * autogenerated marker.
895      *
896      * @return a autogenerated location string
897      */

898     protected final String JavaDoc generateLocation()
899     {
900         final String JavaDoc location = getLocation();
901         if( !location.endsWith( AUTOGEN_POSTFIX ) )
902         {
903             return location + AUTOGEN_POSTFIX;
904         }
905         else
906         {
907             return location;
908         }
909     }
910
911     /**
912      * Throw an IllegalStateException warning about
913      * mixed content.
914      */

915     protected final void throwMixedContentException()
916     {
917         final String JavaDoc message =
918             "Configuration objects do not support Mixed content. " +
919             "Configuration elements should not have both a value and " +
920             "child elements.";
921         throw new IllegalStateException JavaDoc( message );
922     }
923 }
924
Popular Tags