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 java.util.ArrayList;
28  import java.util.List;
29  import java.util.Map;
30  import java.util.concurrent.ConcurrentHashMap;
31  import java.util.concurrent.CopyOnWriteArrayList;
32  
33  import org.codehaus.plexus.component.configurator.ComponentConfigurationException;
34  import org.codehaus.plexus.component.configurator.converters.ConfigurationConverter;
35  import org.codehaus.plexus.component.configurator.converters.basic.BooleanConverter;
36  import org.codehaus.plexus.component.configurator.converters.basic.ByteConverter;
37  import org.codehaus.plexus.component.configurator.converters.basic.CharConverter;
38  import org.codehaus.plexus.component.configurator.converters.basic.DateConverter;
39  import org.codehaus.plexus.component.configurator.converters.basic.DoubleConverter;
40  import org.codehaus.plexus.component.configurator.converters.basic.EnumConverter;
41  import org.codehaus.plexus.component.configurator.converters.basic.FileConverter;
42  import org.codehaus.plexus.component.configurator.converters.basic.FloatConverter;
43  import org.codehaus.plexus.component.configurator.converters.basic.IntConverter;
44  import org.codehaus.plexus.component.configurator.converters.basic.LongConverter;
45  import org.codehaus.plexus.component.configurator.converters.basic.ShortConverter;
46  import org.codehaus.plexus.component.configurator.converters.basic.StringBufferConverter;
47  import org.codehaus.plexus.component.configurator.converters.basic.StringConverter;
48  import org.codehaus.plexus.component.configurator.converters.basic.UriConverter;
49  import org.codehaus.plexus.component.configurator.converters.basic.UrlConverter;
50  import org.codehaus.plexus.component.configurator.converters.composite.ArrayConverter;
51  import org.codehaus.plexus.component.configurator.converters.composite.CollectionConverter;
52  import org.codehaus.plexus.component.configurator.converters.composite.MapConverter;
53  import org.codehaus.plexus.component.configurator.converters.composite.ObjectWithFieldsConverter;
54  import org.codehaus.plexus.component.configurator.converters.composite.PlexusConfigurationConverter;
55  import org.codehaus.plexus.component.configurator.converters.composite.PropertiesConverter;
56  
57  public class DefaultConverterLookup implements ConverterLookup {
58      private final List<ConfigurationConverter> converters = new ArrayList<ConfigurationConverter>();
59  
60      private final List<ConfigurationConverter> customConverters = new CopyOnWriteArrayList<ConfigurationConverter>();
61  
62      private final Map<Class<?>, ConfigurationConverter> converterMap =
63              new ConcurrentHashMap<Class<?>, ConfigurationConverter>();
64  
65      public DefaultConverterLookup() {
66          registerDefaultBasicConverters();
67  
68          registerDefaultCompositeConverters();
69      }
70  
71      public synchronized void registerConverter(ConfigurationConverter converter) {
72          customConverters.add(converter);
73      }
74  
75      protected void registerDefaultConverter(ConfigurationConverter converter) {
76          converters.add(converter);
77      }
78  
79      public ConfigurationConverter lookupConverterForType(Class<?> type) throws ComponentConfigurationException {
80          ConfigurationConverter retValue = converterMap.get(type);
81  
82          if (retValue == null) {
83              if (customConverters != null) {
84                  retValue = findConverterForType(customConverters, type);
85              }
86  
87              if (retValue == null) {
88                  retValue = findConverterForType(converters, type);
89              }
90  
91              if (retValue == null) {
92                  // this is highly irregular
93                  throw new ComponentConfigurationException("Configuration converter lookup failed for type: " + type);
94              }
95  
96              converterMap.put(type, retValue);
97          }
98  
99          return retValue;
100     }
101 
102     private ConfigurationConverter findConverterForType(List<ConfigurationConverter> converters, Class<?> type) {
103         for (ConfigurationConverter converter : converters) {
104             if (converter.canConvert(type)) {
105                 return converter;
106             }
107         }
108 
109         return null;
110     }
111 
112     private void registerDefaultBasicConverters() {
113         registerDefaultConverter(new BooleanConverter());
114 
115         registerDefaultConverter(new ByteConverter());
116 
117         registerDefaultConverter(new CharConverter());
118 
119         registerDefaultConverter(new DoubleConverter());
120 
121         registerDefaultConverter(new FloatConverter());
122 
123         registerDefaultConverter(new IntConverter());
124 
125         registerDefaultConverter(new LongConverter());
126 
127         registerDefaultConverter(new ShortConverter());
128 
129         registerDefaultConverter(new StringBufferConverter());
130 
131         registerDefaultConverter(new StringConverter());
132 
133         registerDefaultConverter(new DateConverter());
134 
135         registerDefaultConverter(new FileConverter());
136 
137         registerDefaultConverter(new UrlConverter());
138 
139         registerDefaultConverter(new UriConverter());
140 
141         registerDefaultConverter(new EnumConverter());
142     }
143 
144     private void registerDefaultCompositeConverters() {
145         registerDefaultConverter(new MapConverter());
146 
147         registerDefaultConverter(new ArrayConverter());
148 
149         registerDefaultConverter(new CollectionConverter());
150 
151         registerDefaultConverter(new PropertiesConverter());
152 
153         registerDefaultConverter(new PlexusConfigurationConverter());
154 
155         // this converter should be always registred as the last one
156         registerDefaultConverter(new ObjectWithFieldsConverter());
157     }
158 }