View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.configuration.internal;
20  
21  import org.codehaus.plexus.component.configurator.ComponentConfigurationException;
22  import org.codehaus.plexus.component.configurator.ConfigurationListener;
23  import org.codehaus.plexus.component.configurator.converters.composite.ObjectWithFieldsConverter;
24  import org.codehaus.plexus.component.configurator.converters.lookup.ConverterLookup;
25  import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluationException;
26  import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluator;
27  import org.codehaus.plexus.component.configurator.expression.TypeAwareExpressionEvaluator;
28  import org.codehaus.plexus.configuration.PlexusConfiguration;
29  import org.eclipse.sisu.plexus.CompositeBeanHelper;
30  
31  /**
32   * An enhanced {@link ObjectWithFieldsConverter} leveraging the {@link TypeAwareExpressionEvaluator}
33   * interface.
34   */
35  class EnhancedConfigurationConverter extends ObjectWithFieldsConverter {
36      protected Object fromExpression(
37              final PlexusConfiguration configuration, final ExpressionEvaluator evaluator, final Class<?> type)
38              throws ComponentConfigurationException {
39          String value = configuration.getValue();
40          try {
41              Object result = null;
42              if (null != value && !value.isEmpty()) {
43                  if (evaluator instanceof TypeAwareExpressionEvaluator) {
44                      result = ((TypeAwareExpressionEvaluator) evaluator).evaluate(value, type);
45                  } else {
46                      result = evaluator.evaluate(value);
47                  }
48              }
49              if (null == result && configuration.getChildCount() == 0) {
50                  value = configuration.getAttribute("default-value");
51                  if (null != value && !value.isEmpty()) {
52                      if (evaluator instanceof TypeAwareExpressionEvaluator) {
53                          result = ((TypeAwareExpressionEvaluator) evaluator).evaluate(value, type);
54                      } else {
55                          result = evaluator.evaluate(value);
56                      }
57                  }
58              }
59              failIfNotTypeCompatible(result, type, configuration);
60              return result;
61          } catch (final ExpressionEvaluationException e) {
62              final String reason = String.format(
63                      "Cannot evaluate expression '%s' for configuration entry '%s'", value, configuration.getName());
64  
65              throw new ComponentConfigurationException(configuration, reason, e);
66          }
67      }
68  
69      public Object fromConfiguration(
70              final ConverterLookup lookup,
71              final PlexusConfiguration configuration,
72              final Class<?> type,
73              final Class<?> enclosingType,
74              final ClassLoader loader,
75              final ExpressionEvaluator evaluator,
76              final ConfigurationListener listener)
77              throws ComponentConfigurationException {
78          final Object value = fromExpression(configuration, evaluator, type);
79          if (type.isInstance(value)) {
80              return value;
81          }
82          try {
83              final Class<?> implType = getClassForImplementationHint(type, configuration, loader);
84              if (null == value && implType.isInterface() && configuration.getChildCount() == 0) {
85                  return null; // nothing to process
86              }
87              final Object bean = instantiateObject(implType);
88              if (null == value) {
89                  processConfiguration(lookup, bean, loader, configuration, evaluator, listener);
90              } else {
91                  new CompositeBeanHelper(lookup, loader, evaluator, listener).setDefault(bean, value, configuration);
92              }
93              return bean;
94          } catch (final ComponentConfigurationException e) {
95              if (null == e.getFailedConfiguration()) {
96                  e.setFailedConfiguration(configuration);
97              }
98              throw e;
99          }
100     }
101 }