1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.configuration.internal;
20
21 import java.io.File;
22 import java.nio.file.Path;
23 import java.nio.file.Paths;
24 import java.util.Objects;
25 import javax.inject.Named;
26 import javax.inject.Singleton;
27 import org.apache.maven.configuration.BeanConfigurationException;
28 import org.apache.maven.configuration.BeanConfigurationPathTranslator;
29 import org.apache.maven.configuration.BeanConfigurationRequest;
30 import org.apache.maven.configuration.BeanConfigurationValuePreprocessor;
31 import org.apache.maven.configuration.BeanConfigurator;
32 import org.codehaus.plexus.component.configurator.ComponentConfigurationException;
33 import org.codehaus.plexus.component.configurator.ConfigurationListener;
34 import org.codehaus.plexus.component.configurator.converters.basic.AbstractBasicConverter;
35 import org.codehaus.plexus.component.configurator.converters.composite.ObjectWithFieldsConverter;
36 import org.codehaus.plexus.component.configurator.converters.lookup.ConverterLookup;
37 import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluationException;
38 import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluator;
39 import org.codehaus.plexus.component.configurator.expression.TypeAwareExpressionEvaluator;
40 import org.codehaus.plexus.configuration.PlexusConfiguration;
41 import org.codehaus.plexus.configuration.xml.XmlPlexusConfiguration;
42 import org.codehaus.plexus.util.xml.Xpp3Dom;
43
44
45
46
47
48
49
50 @Named
51 @Singleton
52 public class DefaultBeanConfigurator implements BeanConfigurator {
53
54 private final ConverterLookup converterLookup;
55
56 public DefaultBeanConfigurator() {
57 converterLookup = new EnhancedConverterLookup();
58 }
59
60 public void configureBean(BeanConfigurationRequest request) throws BeanConfigurationException {
61 Objects.requireNonNull(request, "request cannot be null");
62 Objects.requireNonNull(request.getBean(), "request.bean cannot be null");
63
64 Object configuration = request.getConfiguration();
65 if (configuration == null) {
66 return;
67 }
68
69 PlexusConfiguration plexusConfig;
70 if (configuration instanceof PlexusConfiguration) {
71 plexusConfig = (PlexusConfiguration) configuration;
72 } else if (configuration instanceof Xpp3Dom) {
73 plexusConfig = new XmlPlexusConfiguration((Xpp3Dom) configuration);
74 } else {
75 throw new BeanConfigurationException("unsupported bean configuration source ("
76 + configuration.getClass().getName() + ")");
77 }
78
79 if (request.getConfigurationElement() != null) {
80 plexusConfig = plexusConfig.getChild(request.getConfigurationElement());
81 }
82
83 ClassLoader classLoader = request.getClassLoader();
84 if (classLoader == null) {
85 classLoader = request.getBean().getClass().getClassLoader();
86 }
87
88 BeanExpressionEvaluator evaluator = new BeanExpressionEvaluator(request);
89
90 ObjectWithFieldsConverter converter = new EnhancedConfigurationConverter();
91
92 try {
93 converter.processConfiguration(
94 converterLookup, request.getBean(), classLoader, plexusConfig, evaluator, null);
95 } catch (ComponentConfigurationException e) {
96 throw new BeanConfigurationException(e.getMessage(), e);
97 }
98 }
99
100 static class BeanExpressionEvaluator implements TypeAwareExpressionEvaluator {
101
102 private final BeanConfigurationValuePreprocessor preprocessor;
103
104 private final BeanConfigurationPathTranslator translator;
105
106 BeanExpressionEvaluator(BeanConfigurationRequest request) {
107 preprocessor = request.getValuePreprocessor();
108 translator = request.getPathTranslator();
109 }
110
111 public Object evaluate(String expression, Class<?> type) throws ExpressionEvaluationException {
112 if (preprocessor != null) {
113 try {
114 return preprocessor.preprocessValue(expression, type);
115 } catch (BeanConfigurationException e) {
116 throw new ExpressionEvaluationException(e.getMessage(), e);
117 }
118 }
119 return expression;
120 }
121
122 public Object evaluate(String expression) throws ExpressionEvaluationException {
123 return evaluate(expression, null);
124 }
125
126 public File alignToBaseDirectory(File file) {
127 if (translator != null) {
128 return translator.translatePath(file);
129 }
130 return file;
131 }
132 }
133
134 static class PathConverter extends AbstractBasicConverter {
135 @Override
136 public boolean canConvert(Class<?> type) {
137 return Path.class.equals(type);
138 }
139
140 @Override
141 protected Object fromString(String value) throws ComponentConfigurationException {
142 return Paths.get(value.replace('/' == File.separatorChar ? '\\' : '/', File.separatorChar));
143 }
144
145 @Override
146 public Object fromConfiguration(
147 final ConverterLookup lookup,
148 final PlexusConfiguration configuration,
149 final Class<?> type,
150 final Class<?> enclosingType,
151 final ClassLoader loader,
152 final ExpressionEvaluator evaluator,
153 final ConfigurationListener listener)
154 throws ComponentConfigurationException {
155 final Object result =
156 super.fromConfiguration(lookup, configuration, type, enclosingType, loader, evaluator, listener);
157
158 return result instanceof Path
159 ? evaluator.alignToBaseDirectory(((Path) result).toFile()).toPath()
160 : result;
161 }
162 }
163 }