1 package org.apache.maven.continuum.core.action;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.apache.maven.continuum.ContinuumException;
23 import org.apache.maven.continuum.execution.maven.m2.SettingsConfigurationException;
24 import org.apache.maven.continuum.model.project.BuildDefinitionTemplate;
25 import org.apache.maven.continuum.model.project.Project;
26 import org.apache.maven.continuum.project.builder.ContinuumProjectBuilder;
27 import org.apache.maven.continuum.project.builder.ContinuumProjectBuilderException;
28 import org.apache.maven.continuum.project.builder.ContinuumProjectBuildingResult;
29 import org.apache.maven.continuum.project.builder.manager.ContinuumProjectBuilderManager;
30 import org.apache.maven.continuum.project.builder.manager.ContinuumProjectBuilderManagerException;
31 import org.apache.maven.continuum.utils.ContinuumUrlValidator;
32 import org.apache.maven.continuum.utils.URLUserInfo;
33 import org.apache.maven.settings.MavenSettingsBuilder;
34 import org.apache.maven.settings.Server;
35 import org.apache.maven.settings.Settings;
36 import org.codehaus.plexus.util.StringUtils;
37 import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
38
39 import java.io.IOException;
40 import java.net.MalformedURLException;
41 import java.net.URISyntaxException;
42 import java.net.URL;
43 import java.util.List;
44 import java.util.Map;
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61 public class CreateProjectsFromMetadataAction
62 extends AbstractContinuumAction
63 {
64
65
66
67 private static final String KEY_URL = "url";
68
69 private static final String KEY_PROJECT_BUILDER_ID = "builderId";
70
71 private static final String KEY_PROJECT_BUILDING_RESULT = "projectBuildingResult";
72
73 private static final String KEY_LOAD_RECURSIVE_PROJECTS = "loadRecursiveProjects";
74
75 public static final String KEY_CHECKOUT_PROJECTS_IN_SINGLE_DIRECTORY = "checkoutProjectsInSingleDirectory";
76
77
78
79
80 private ContinuumProjectBuilderManager projectBuilderManager;
81
82
83
84
85 private MavenSettingsBuilder mavenSettingsBuilder;
86
87
88
89
90 private ContinuumUrlValidator urlValidator;
91
92 public void execute( Map context )
93 throws ContinuumException, ContinuumProjectBuilderManagerException, ContinuumProjectBuilderException
94 {
95 String projectBuilderId = getProjectBuilderId( context );
96
97 boolean loadRecursiveProjects = isLoadRecursiveProject( context );
98
99 boolean checkoutProjectsInSingleDirectory = getBoolean( context, KEY_CHECKOUT_PROJECTS_IN_SINGLE_DIRECTORY );
100
101 int projectGroupId = getProjectGroupId( context );
102
103 String curl = getUrl( context );
104
105 URL url;
106
107 ContinuumProjectBuilder projectBuilder = projectBuilderManager.getProjectBuilder( projectBuilderId );
108
109 ContinuumProjectBuildingResult result;
110
111 try
112 {
113 BuildDefinitionTemplate buildDefinitionTemplate = getBuildDefinitionTemplate( context );
114 if ( buildDefinitionTemplate == null )
115 {
116 buildDefinitionTemplate = projectBuilder.getDefaultBuildDefinitionTemplate();
117 }
118 if ( !curl.startsWith( "http" ) )
119 {
120 url = new URL( curl );
121
122 result = projectBuilder.buildProjectsFromMetadata( url, null, null, loadRecursiveProjects,
123 buildDefinitionTemplate,
124 checkoutProjectsInSingleDirectory, projectGroupId );
125
126 }
127 else
128 {
129 url = new URL( curl );
130 String username = null;
131 String password = null;
132
133 try
134 {
135 Settings settings = getSettings();
136
137 getLogger().info( "checking for settings auth setup" );
138 if ( settings != null && settings.getServer( url.getHost() ) != null )
139 {
140 getLogger().info( "found setting based auth setup, using" );
141 Server server = settings.getServer( url.getHost() );
142
143 username = server.getUsername();
144 password = server.getPassword();
145 }
146 }
147 catch ( SettingsConfigurationException se )
148 {
149 getLogger().warn( "problem with settings file, disabling scm resolution of username and password" );
150 }
151
152 if ( username == null )
153 {
154 URLUserInfo urlUserInfo = urlValidator.extractURLUserInfo( curl );
155 username = urlUserInfo.getUsername();
156 password = urlUserInfo.getPassword();
157 }
158
159 if ( urlValidator.isValid( curl ) )
160 {
161
162 result = projectBuilder.buildProjectsFromMetadata( url, username, password, loadRecursiveProjects,
163 buildDefinitionTemplate,
164 checkoutProjectsInSingleDirectory,
165 projectGroupId );
166
167 }
168 else
169 {
170 result = new ContinuumProjectBuildingResult();
171 getLogger().info( "Malformed URL (MungedHttpsURL is not valid): " + hidePasswordInUrl( curl ) );
172 result.addError( ContinuumProjectBuildingResult.ERROR_MALFORMED_URL );
173 }
174 }
175
176 if ( result.getProjects() != null )
177 {
178 String scmRootUrl = getScmRootUrl( result.getProjects() );
179
180 if ( scmRootUrl == null || scmRootUrl.equals( "" ) )
181 {
182 if ( curl.indexOf( "pom.xml" ) > 0 )
183 {
184 scmRootUrl = curl.substring( 0, curl.indexOf( "pom.xml" ) - 1 );
185 }
186 else
187 {
188 scmRootUrl = curl;
189 }
190 }
191
192
193 setProjectScmRootUrl( context, scmRootUrl );
194 }
195 }
196 catch ( MalformedURLException e )
197 {
198 getLogger().info( "Malformed URL: " + hidePasswordInUrl( curl ), e );
199 result = new ContinuumProjectBuildingResult();
200 result.addError( ContinuumProjectBuildingResult.ERROR_MALFORMED_URL );
201 }
202 catch ( URISyntaxException e )
203 {
204 getLogger().info( "Malformed URL: " + hidePasswordInUrl( curl ), e );
205 result = new ContinuumProjectBuildingResult();
206 result.addError( ContinuumProjectBuildingResult.ERROR_MALFORMED_URL );
207 }
208
209 setProjectBuildingResult( context, result );
210 }
211
212 private String hidePasswordInUrl( String url )
213 {
214 int indexAt = url.indexOf( "@" );
215
216 if ( indexAt < 0 )
217 {
218 return url;
219 }
220
221 String s = url.substring( 0, indexAt );
222
223 int pos = s.lastIndexOf( ":" );
224
225 return s.substring( 0, pos + 1 ) + "*****" + url.substring( indexAt );
226 }
227
228 private Settings getSettings()
229 throws SettingsConfigurationException
230 {
231 try
232 {
233 return mavenSettingsBuilder.buildSettings();
234 }
235 catch ( IOException e )
236 {
237 throw new SettingsConfigurationException( "Error reading settings file", e );
238 }
239 catch ( XmlPullParserException e )
240 {
241 throw new SettingsConfigurationException( e.getMessage(), e.getDetail(), e.getLineNumber(),
242 e.getColumnNumber() );
243 }
244 }
245
246 private String getScmRootUrl( List<Project> projects )
247 {
248 String scmRootUrl = "";
249
250 for ( Project project : projects )
251 {
252 String scmUrl = project.getScmUrl();
253
254 scmRootUrl = getCommonPath( scmUrl, scmRootUrl );
255 }
256
257 return scmRootUrl;
258 }
259
260 private String getCommonPath( String path1, String path2 )
261 {
262 if ( path2 == null || path2.equals( "" ) )
263 {
264 return path1;
265 }
266 else
267 {
268 int indexDiff = StringUtils.differenceAt( path1, path2 );
269 String commonPath = path1.substring( 0, indexDiff );
270
271 if ( commonPath.lastIndexOf( '/' ) != commonPath.length() - 1 && !( path1.contains( new String(
272 commonPath + "/" ) ) || path2.contains( new String( commonPath + "/" ) ) ) )
273 {
274 while ( commonPath.lastIndexOf( '/' ) != commonPath.length() - 1 )
275 {
276 commonPath = commonPath.substring( 0, commonPath.length() - 1 );
277 }
278 }
279
280 return commonPath;
281 }
282 }
283
284 public ContinuumProjectBuilderManager getProjectBuilderManager()
285 {
286 return projectBuilderManager;
287 }
288
289 public void setProjectBuilderManager( ContinuumProjectBuilderManager projectBuilderManager )
290 {
291 this.projectBuilderManager = projectBuilderManager;
292 }
293
294 public MavenSettingsBuilder getMavenSettingsBuilder()
295 {
296 return mavenSettingsBuilder;
297 }
298
299 public void setMavenSettingsBuilder( MavenSettingsBuilder mavenSettingsBuilder )
300 {
301 this.mavenSettingsBuilder = mavenSettingsBuilder;
302 }
303
304 public ContinuumUrlValidator getUrlValidator()
305 {
306 return urlValidator;
307 }
308
309 public void setUrlValidator( ContinuumUrlValidator urlValidator )
310 {
311 this.urlValidator = urlValidator;
312 }
313
314 public static String getUrl( Map<String, Object> context )
315 {
316 return getString( context, KEY_URL );
317 }
318
319 public static void setUrl( Map<String, Object> context, String url )
320 {
321 context.put( KEY_URL, url );
322 }
323
324 public static String getProjectBuilderId( Map<String, Object> context )
325 {
326 return getString( context, KEY_PROJECT_BUILDER_ID );
327 }
328
329 public static void setProjectBuilderId( Map<String, Object> context, String projectBuilderId )
330 {
331 context.put( KEY_PROJECT_BUILDER_ID, projectBuilderId );
332 }
333
334 public static ContinuumProjectBuildingResult getProjectBuildingResult( Map<String, Object> context )
335 {
336 return (ContinuumProjectBuildingResult) getObject( context, KEY_PROJECT_BUILDING_RESULT );
337 }
338
339 private static void setProjectBuildingResult( Map<String, Object> context, ContinuumProjectBuildingResult result )
340 {
341 context.put( KEY_PROJECT_BUILDING_RESULT, result );
342 }
343
344 public static boolean isLoadRecursiveProject( Map<String, Object> context )
345 {
346 return getBoolean( context, KEY_LOAD_RECURSIVE_PROJECTS );
347 }
348
349 public static void setLoadRecursiveProject( Map<String, Object> context, boolean loadRecursiveProject )
350 {
351 context.put( KEY_LOAD_RECURSIVE_PROJECTS, loadRecursiveProject );
352 }
353
354 public static boolean isCheckoutProjectsInSingleDirectory( Map<String, Object> context )
355 {
356 return getBoolean( context, KEY_CHECKOUT_PROJECTS_IN_SINGLE_DIRECTORY );
357 }
358
359 public static void setCheckoutProjectsInSingleDirectory( Map<String, Object> context,
360 boolean checkoutProjectsInSingleDirectory )
361 {
362 context.put( KEY_CHECKOUT_PROJECTS_IN_SINGLE_DIRECTORY, checkoutProjectsInSingleDirectory );
363 }
364 }