View Javadoc
1   package org.codehaus.plexus.component.configurator.converters;
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.lookup.ConverterLookup;
29  import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluationException;
30  import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluator;
31  import org.codehaus.plexus.configuration.PlexusConfiguration;
32  import org.codehaus.plexus.util.StringUtils;
33  
34  /**
35   * @author <a href="mailto:michal@codehaus.org">Michal Maczka</a>
36   */
37  public abstract class AbstractConfigurationConverter implements ConfigurationConverter {
38      private static final String IMPLEMENTATION = "implementation";
39  
40      /**
41       * We will check if user has provided a hint which class should be used for given field.
42       * So we will check if something like {@code <foo implementation="com.MyFoo">} is present in configuraion.
43       * If 'implementation' hint was provided we will try to load correspoding class
44       * If we are unable to do so error will be reported
45       * @param type {@link Class}.
46       * @param configuration {@link PlexusConfiguration}.
47       * @param classLoader {@link ClassLoader}.
48       * @return The class.
49       * @throws ComponentConfigurationException in case of an error.
50       */
51      protected Class getClassForImplementationHint(
52              Class type, PlexusConfiguration configuration, ClassLoader classLoader)
53              throws ComponentConfigurationException {
54          Class retValue = type;
55  
56          String implementation = configuration.getAttribute(IMPLEMENTATION, null);
57  
58          if (implementation != null) {
59              try {
60                  retValue = classLoader.loadClass(implementation);
61  
62              } catch (ClassNotFoundException e) {
63                  String msg = "ClassNotFoundException: Class name which was explicitly given in configuration using"
64                          + " 'implementation' attribute: '" + implementation + "' cannot be loaded";
65  
66                  throw new ComponentConfigurationException(msg, e);
67              } catch (UnsupportedClassVersionError e) {
68                  String msg = "UnsupportedClassVersionError: Class name which was explicitly given in configuration"
69                          + " using 'implementation' attribute: '" + implementation + "' cannot be loaded";
70  
71                  throw new ComponentConfigurationException(msg, e);
72              } catch (LinkageError e) {
73                  String msg = "LinkageError: Class name which was explicitly given in configuration using"
74                          + " 'implementation' attribute: '" + implementation + "' cannot be loaded";
75  
76                  throw new ComponentConfigurationException(msg, e);
77              }
78          }
79  
80          return retValue;
81      }
82  
83      protected Class loadClass(String classname, ClassLoader classLoader) throws ComponentConfigurationException {
84          Class retValue;
85  
86          try {
87              retValue = classLoader.loadClass(classname);
88          } catch (ClassNotFoundException e) {
89              throw new ComponentConfigurationException("Error loading class '" + classname + "'", e);
90          }
91  
92          return retValue;
93      }
94  
95      protected Object instantiateObject(String classname, ClassLoader classLoader)
96              throws ComponentConfigurationException {
97          Class clazz = loadClass(classname, classLoader);
98  
99          return instantiateObject(clazz);
100     }
101 
102     protected Object instantiateObject(Class clazz) throws ComponentConfigurationException {
103         Object retValue;
104 
105         try {
106             retValue = clazz.newInstance();
107 
108             return retValue;
109         } catch (IllegalAccessException e) {
110             throw new ComponentConfigurationException("Class '" + clazz.getName() + "' cannot be instantiated", e);
111         } catch (InstantiationException e) {
112             throw new ComponentConfigurationException("Class '" + clazz.getName() + "' cannot be instantiated", e);
113         }
114     }
115 
116     // first-name --> firstName
117     protected String fromXML(String elementName) {
118         return StringUtils.lowercaseFirstLetter(StringUtils.removeAndHump(elementName, "-"));
119     }
120 
121     // firstName --> first-name
122     protected String toXML(String fieldName) {
123         return StringUtils.addAndDeHump(fieldName);
124     }
125 
126     protected Object fromExpression(
127             PlexusConfiguration configuration, ExpressionEvaluator expressionEvaluator, Class type)
128             throws ComponentConfigurationException {
129         Object v = fromExpression(configuration, expressionEvaluator);
130 
131         if (v != null) {
132             if (!type.isAssignableFrom(v.getClass())) {
133                 String msg = "Cannot assign configuration entry '" + configuration.getName() + "' to '" + type
134                         + "' from '" + configuration.getValue(null) + "', which is of type " + v.getClass();
135                 throw new ComponentConfigurationException(configuration, msg);
136             }
137         }
138         return v;
139     }
140 
141     protected Object fromExpression(PlexusConfiguration configuration, ExpressionEvaluator expressionEvaluator)
142             throws ComponentConfigurationException {
143         Object v = null;
144         String value = configuration.getValue(null);
145         if (value != null && value.length() > 0) {
146             // Object is provided by an expression
147             // This seems a bit ugly... canConvert really should return false in this instance, but it doesn't have the
148             //   configuration to know better
149             try {
150                 v = expressionEvaluator.evaluate(value);
151             } catch (ExpressionEvaluationException e) {
152                 String msg = "Error evaluating the expression '" + value + "' for configuration value '"
153                         + configuration.getName() + "'";
154                 throw new ComponentConfigurationException(configuration, msg, e);
155             }
156         }
157         if (v == null) {
158             value = configuration.getAttribute("default-value", null);
159             if (value != null && value.length() > 0) {
160                 try {
161                     v = expressionEvaluator.evaluate(value);
162                 } catch (ExpressionEvaluationException e) {
163                     String msg = "Error evaluating the expression '" + value + "' for configuration value '"
164                             + configuration.getName() + "'";
165                     throw new ComponentConfigurationException(configuration, msg, e);
166                 }
167             }
168         }
169         return v;
170     }
171 
172     public Object fromConfiguration(
173             ConverterLookup converterLookup,
174             PlexusConfiguration configuration,
175             Class type,
176             Class baseType,
177             ClassLoader classLoader,
178             ExpressionEvaluator expressionEvaluator)
179             throws ComponentConfigurationException {
180         return fromConfiguration(
181                 converterLookup, configuration, type, baseType, classLoader, expressionEvaluator, null);
182     }
183 }