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.archetype.ui;
20  
21  import javax.inject.Named;
22  import javax.inject.Singleton;
23  
24  import java.util.Iterator;
25  import java.util.Properties;
26  
27  import org.apache.maven.archetype.common.Constants;
28  import org.apache.maven.archetype.metadata.RequiredProperty;
29  import org.apache.maven.project.MavenProject;
30  import org.slf4j.Logger;
31  import org.slf4j.LoggerFactory;
32  
33  @Named("default")
34  @Singleton
35  public class DefaultArchetypeFactory implements ArchetypeFactory {
36      private static final Logger LOGGER = LoggerFactory.getLogger(DefaultArchetypeFactory.class);
37  
38      @Override
39      public ArchetypeDefinition createArchetypeDefinition(Properties properties) {
40          ArchetypeDefinition definition = new ArchetypeDefinition();
41  
42          definition.setGroupId(properties.getProperty(Constants.ARCHETYPE_GROUP_ID));
43  
44          definition.setArtifactId(properties.getProperty(Constants.ARCHETYPE_ARTIFACT_ID));
45  
46          definition.setVersion(properties.getProperty(Constants.ARCHETYPE_VERSION));
47  
48          definition.setRepository(properties.getProperty(Constants.ARCHETYPE_REPOSITORY));
49  
50          definition.setUrl(properties.getProperty(Constants.ARCHETYPE_URL));
51  
52          definition.setDescription(properties.getProperty(Constants.ARCHETYPE_DESCRIPTION));
53  
54          return definition;
55      }
56  
57      private void addOldRequiredProperty(
58              ArchetypeConfiguration configuration,
59              Properties properties,
60              String key,
61              String defaultValue,
62              boolean initPropertyWithDefault) {
63          LOGGER.debug("Adding requiredProperty " + key);
64  
65          configuration.addRequiredProperty(key);
66  
67          String property = properties.getProperty(key);
68  
69          if (property != null) {
70              configuration.setProperty(key, property);
71              configuration.setDefaultProperty(key, property);
72          } else if (defaultValue != null) {
73              if (initPropertyWithDefault) {
74                  configuration.setProperty(key, defaultValue);
75              }
76              configuration.setDefaultProperty(key, defaultValue);
77          }
78  
79          LOGGER.debug("Setting property " + key + "=" + configuration.getProperty(key));
80      }
81  
82      @Override
83      @SuppressWarnings("checkstyle:linelength")
84      public ArchetypeConfiguration createArchetypeConfiguration(
85              org.apache.maven.archetype.old.descriptor.ArchetypeDescriptor archetypeDescriptor, Properties properties) {
86          LOGGER.debug("Creating ArchetypeConfiguration from legacy descriptor and Properties");
87  
88          ArchetypeConfiguration configuration = createArchetypeConfiguration(properties);
89  
90          configuration.setName(archetypeDescriptor.getId());
91  
92          addOldRequiredProperty(configuration, properties, Constants.GROUP_ID, null, false);
93  
94          addOldRequiredProperty(configuration, properties, Constants.ARTIFACT_ID, null, false);
95  
96          addOldRequiredProperty(configuration, properties, Constants.VERSION, "1.0-SNAPSHOT", false);
97  
98          addOldRequiredProperty(
99                  configuration, properties, Constants.PACKAGE, configuration.getProperty(Constants.GROUP_ID), true);
100 
101         return configuration;
102     }
103 
104     private void addRequiredProperty(
105             ArchetypeConfiguration configuration,
106             Properties properties,
107             String key,
108             String defaultValue,
109             boolean initPropertyWithDefault) {
110         if (!configuration.isConfigured(key) && configuration.getDefaultValue(key) == null) {
111             addOldRequiredProperty(configuration, properties, key, defaultValue, initPropertyWithDefault);
112         }
113     }
114 
115     @Override
116     @SuppressWarnings("checkstyle:linelength")
117     public ArchetypeConfiguration createArchetypeConfiguration(
118             org.apache.maven.archetype.metadata.ArchetypeDescriptor archetypeDescriptor, Properties properties) {
119         LOGGER.debug("Creating ArchetypeConfiguration from fileset descriptor and Properties");
120 
121         ArchetypeConfiguration configuration = createArchetypeConfiguration(properties);
122 
123         configuration.setName(archetypeDescriptor.getName());
124 
125         for (RequiredProperty requiredProperty : archetypeDescriptor.getRequiredProperties()) {
126             String key = requiredProperty.getKey();
127             LOGGER.debug("Adding requiredProperty " + key);
128 
129             configuration.addRequiredProperty(key);
130 
131             String defaultValue = requiredProperty.getDefaultValue();
132             String validationRegex = requiredProperty.getValidationRegex();
133 
134             if (properties.getProperty(key) != null) {
135                 // using value defined in properties, which overrides any default
136                 String value = properties.getProperty(key);
137                 configuration.setProperty(key, value);
138                 LOGGER.debug("Setting property " + key + "=" + value);
139             } else if ((defaultValue != null) && !containsInnerProperty(defaultValue)) {
140                 // using default value
141                 configuration.setProperty(key, defaultValue);
142                 LOGGER.debug("Setting property " + key + "=" + defaultValue);
143             }
144 
145             if (defaultValue != null) {
146                 configuration.setDefaultProperty(key, defaultValue);
147                 LOGGER.debug("Setting defaultProperty " + key + "=" + defaultValue);
148             }
149 
150             if (validationRegex != null) {
151                 configuration.setPropertyValidationRegex(key, validationRegex);
152                 LOGGER.debug("Setting validation regular expression " + key + "=" + defaultValue);
153             }
154         }
155 
156         addRequiredProperty(configuration, properties, Constants.GROUP_ID, null, false);
157 
158         addRequiredProperty(configuration, properties, Constants.ARTIFACT_ID, null, false);
159 
160         addRequiredProperty(configuration, properties, Constants.VERSION, "1.0-SNAPSHOT", false);
161 
162         addRequiredProperty(
163                 configuration, properties, Constants.PACKAGE, configuration.getProperty(Constants.GROUP_ID), true);
164 
165         String postGenerationGoals = properties.getProperty(Constants.ARCHETYPE_POST_GENERATION_GOALS);
166         if (postGenerationGoals != null) {
167             configuration.setProperty(Constants.ARCHETYPE_POST_GENERATION_GOALS, postGenerationGoals);
168         }
169 
170         return configuration;
171     }
172 
173     private void addRequiredProperty(
174             ArchetypeConfiguration configuration, Properties properties, String key, String defaultValue) {
175         LOGGER.debug("Adding requiredProperty " + key);
176 
177         configuration.addRequiredProperty(key);
178 
179         if (defaultValue != null) {
180             configuration.setDefaultProperty(key, defaultValue);
181         }
182 
183         if (properties.getProperty(key) != null) {
184             configuration.setProperty(key, properties.getProperty(key));
185 
186             LOGGER.debug("Setting property " + key + "=" + configuration.getProperty(Constants.GROUP_ID));
187         }
188     }
189 
190     private void setProperty(ArchetypeConfiguration configuration, Properties properties, String key) {
191         String property = properties.getProperty(key);
192 
193         if (property != null) {
194             configuration.setProperty(key, property);
195         }
196     }
197 
198     @Override
199     public ArchetypeConfiguration createArchetypeConfiguration(
200             MavenProject project, ArchetypeDefinition archetypeDefinition, Properties properties) {
201         LOGGER.debug("Creating ArchetypeConfiguration from ArchetypeDefinition, MavenProject and Properties");
202 
203         ArchetypeConfiguration configuration = createArchetypeConfiguration(properties);
204 
205         for (Iterator<?> requiredProperties = properties.keySet().iterator(); requiredProperties.hasNext(); ) {
206             String requiredProperty = (String) requiredProperties.next();
207 
208             if (!requiredProperty.contains(".")) {
209                 LOGGER.debug("Adding requiredProperty " + requiredProperty);
210                 configuration.addRequiredProperty(requiredProperty);
211 
212                 configuration.setProperty(requiredProperty, properties.getProperty(requiredProperty));
213                 LOGGER.debug(
214                         "Setting property " + requiredProperty + "=" + configuration.getProperty(requiredProperty));
215             }
216         }
217 
218         addRequiredProperty(configuration, properties, Constants.GROUP_ID, project.getGroupId());
219 
220         addRequiredProperty(configuration, properties, Constants.ARTIFACT_ID, project.getArtifactId());
221 
222         addRequiredProperty(configuration, properties, Constants.VERSION, project.getVersion());
223 
224         addRequiredProperty(configuration, properties, Constants.PACKAGE, null);
225 
226         setProperty(configuration, properties, Constants.ARCHETYPE_GROUP_ID);
227 
228         setProperty(configuration, properties, Constants.ARCHETYPE_ARTIFACT_ID);
229 
230         setProperty(configuration, properties, Constants.ARCHETYPE_VERSION);
231 
232         setProperty(configuration, properties, Constants.ARCHETYPE_URL);
233 
234         setProperty(configuration, properties, Constants.ARCHETYPE_DESCRIPTION);
235 
236         return configuration;
237     }
238 
239     private ArchetypeConfiguration createArchetypeConfiguration(Properties properties) {
240         ArchetypeConfiguration configuration = new ArchetypeConfiguration();
241 
242         configuration.setGroupId(properties.getProperty(Constants.ARCHETYPE_GROUP_ID));
243 
244         configuration.setArtifactId(properties.getProperty(Constants.ARCHETYPE_ARTIFACT_ID));
245 
246         configuration.setVersion(properties.getProperty(Constants.ARCHETYPE_VERSION));
247 
248         configuration.setUrl(properties.getProperty(Constants.ARCHETYPE_URL));
249 
250         configuration.setDescription(properties.getProperty(Constants.ARCHETYPE_DESCRIPTION));
251 
252         return configuration;
253     }
254 
255     @Override
256     public void updateArchetypeConfiguration(
257             ArchetypeConfiguration archetypeConfiguration, ArchetypeDefinition archetypeDefinition) {
258         archetypeConfiguration.setGroupId(archetypeDefinition.getGroupId());
259         archetypeConfiguration.setArtifactId(archetypeDefinition.getArtifactId());
260         archetypeConfiguration.setVersion(archetypeDefinition.getVersion());
261     }
262 
263     /**
264      * Check if the given value references a property; that is, it contains <code>${...}</code>.
265      *
266      * @param defaultValue the value to check
267      * @return <code>true</code> if the value contains <code>${</code> followed by <code>}</code>
268      */
269     private boolean containsInnerProperty(String defaultValue) {
270         if (defaultValue == null) {
271             return false;
272         }
273         int start = defaultValue.indexOf("${");
274         return (start >= 0) && (defaultValue.indexOf("}", start) >= 0);
275     }
276 }