View Javadoc
1   package org.codehaus.plexus.component.configurator.converters.lookup;
2   
3   /*
4    * The MIT License
5    *
6    * Copyright (c) 2004, The Codehaus
7    *
8    * Permission is hereby granted, free of charge, to any person obtaining a copy of
9    * this software and associated documentation files (the "Software"), to deal in
10   * the Software without restriction, including without limitation the rights to
11   * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
12   * of the Software, and to permit persons to whom the Software is furnished to do
13   * so, subject to the following conditions:
14   *
15   * The above copyright notice and this permission notice shall be included in all
16   * copies or substantial portions of the Software.
17   *
18   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24   * SOFTWARE.
25   */
26  
27  import org.codehaus.plexus.component.configurator.ComponentConfigurationException;
28  import org.codehaus.plexus.component.configurator.converters.ConfigurationConverter;
29  import org.codehaus.plexus.component.configurator.converters.basic.BooleanConverter;
30  import org.codehaus.plexus.component.configurator.converters.basic.ByteConverter;
31  import org.codehaus.plexus.component.configurator.converters.basic.CharConverter;
32  import org.codehaus.plexus.component.configurator.converters.basic.DateConverter;
33  import org.codehaus.plexus.component.configurator.converters.basic.DoubleConverter;
34  import org.codehaus.plexus.component.configurator.converters.basic.EnumConverter;
35  import org.codehaus.plexus.component.configurator.converters.basic.FileConverter;
36  import org.codehaus.plexus.component.configurator.converters.basic.FloatConverter;
37  import org.codehaus.plexus.component.configurator.converters.basic.IntConverter;
38  import org.codehaus.plexus.component.configurator.converters.basic.LongConverter;
39  import org.codehaus.plexus.component.configurator.converters.basic.ShortConverter;
40  import org.codehaus.plexus.component.configurator.converters.basic.StringBufferConverter;
41  import org.codehaus.plexus.component.configurator.converters.basic.StringConverter;
42  import org.codehaus.plexus.component.configurator.converters.basic.UriConverter;
43  import org.codehaus.plexus.component.configurator.converters.basic.UrlConverter;
44  import org.codehaus.plexus.component.configurator.converters.composite.ArrayConverter;
45  import org.codehaus.plexus.component.configurator.converters.composite.CollectionConverter;
46  import org.codehaus.plexus.component.configurator.converters.composite.MapConverter;
47  import org.codehaus.plexus.component.configurator.converters.composite.ObjectWithFieldsConverter;
48  import org.codehaus.plexus.component.configurator.converters.composite.PlexusConfigurationConverter;
49  import org.codehaus.plexus.component.configurator.converters.composite.PropertiesConverter;
50  
51  import java.util.List;
52  import java.util.Map;
53  import java.util.ArrayList;
54  import java.util.concurrent.ConcurrentHashMap;
55  import java.util.concurrent.CopyOnWriteArrayList;
56  
57  public class DefaultConverterLookup
58      implements ConverterLookup
59  {
60      private final List<ConfigurationConverter> converters = new ArrayList<ConfigurationConverter>();
61  
62      private final List<ConfigurationConverter> customConverters = new CopyOnWriteArrayList<ConfigurationConverter>();
63  
64      private final Map<Class<?>, ConfigurationConverter> converterMap = new ConcurrentHashMap<Class<?>, ConfigurationConverter>();
65  
66      public DefaultConverterLookup()
67      {
68          registerDefaultBasicConverters();
69  
70          registerDefaultCompositeConverters();
71      }
72  
73      public synchronized void registerConverter( ConfigurationConverter converter )
74      {
75          customConverters.add( converter );
76      }
77  
78      protected void registerDefaultConverter( ConfigurationConverter converter )
79      {
80          converters.add( converter );
81      }
82  
83      public ConfigurationConverter lookupConverterForType( Class<?> type )
84          throws ComponentConfigurationException
85      {
86          ConfigurationConverter retValue = converterMap.get( type );
87  
88          if ( retValue == null )
89          {
90              if ( customConverters != null )
91              {
92                  retValue = findConverterForType( customConverters, type );
93              }
94  
95              if ( retValue == null )
96              {
97                  retValue = findConverterForType( converters, type );
98              }
99  
100             if ( retValue == null )
101             {
102                 // this is highly irregular
103                 throw new ComponentConfigurationException( "Configuration converter lookup failed for type: " + type );
104             }
105 
106             converterMap.put( type, retValue );
107         }
108 
109         return retValue;
110     }
111 
112     private ConfigurationConverter findConverterForType( List<ConfigurationConverter> converters, Class<?> type )
113     {
114         for ( ConfigurationConverter converter : converters )
115         {
116             if ( converter.canConvert( type ) )
117             {
118                 return converter;
119             }
120         }
121 
122         return null;
123     }
124 
125 
126     private void registerDefaultBasicConverters()
127     {
128         registerDefaultConverter( new BooleanConverter() );
129 
130         registerDefaultConverter( new ByteConverter() );
131 
132         registerDefaultConverter( new CharConverter() );
133 
134         registerDefaultConverter( new DoubleConverter() );
135 
136         registerDefaultConverter( new FloatConverter() );
137 
138         registerDefaultConverter( new IntConverter() );
139 
140         registerDefaultConverter( new LongConverter() );
141 
142         registerDefaultConverter( new ShortConverter() );
143 
144         registerDefaultConverter( new StringBufferConverter() );
145 
146         registerDefaultConverter( new StringConverter() );
147 
148         registerDefaultConverter( new DateConverter() );
149 
150         registerDefaultConverter( new FileConverter() );
151 
152         registerDefaultConverter( new UrlConverter() );
153 
154         registerDefaultConverter( new UriConverter() );
155 
156         registerDefaultConverter( new EnumConverter() );
157     }
158 
159     private void registerDefaultCompositeConverters()
160     {
161         registerDefaultConverter( new MapConverter() );
162 
163         registerDefaultConverter( new ArrayConverter() );
164 
165         registerDefaultConverter( new CollectionConverter() );
166 
167         registerDefaultConverter( new PropertiesConverter() );
168 
169         registerDefaultConverter( new PlexusConfigurationConverter() );
170 
171         // this converter should be always registred as the last one
172         registerDefaultConverter( new ObjectWithFieldsConverter() );
173     }
174 }