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