1 package org.apache.maven.continuum.project.builder.maven;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.File;
23 import java.net.MalformedURLException;
24 import java.net.URL;
25 import java.util.ArrayList;
26 import java.util.List;
27
28 import org.apache.continuum.dao.LocalRepositoryDao;
29 import org.apache.continuum.dao.ScheduleDao;
30 import org.apache.continuum.model.repository.LocalRepository;
31 import org.apache.maven.continuum.builddefinition.BuildDefinitionService;
32 import org.apache.maven.continuum.builddefinition.BuildDefinitionServiceException;
33 import org.apache.maven.continuum.configuration.ConfigurationService;
34 import org.apache.maven.continuum.execution.maven.m2.MavenBuilderHelper;
35 import org.apache.maven.continuum.execution.maven.m2.MavenTwoBuildExecutor;
36 import org.apache.maven.continuum.model.project.BuildDefinition;
37 import org.apache.maven.continuum.model.project.BuildDefinitionTemplate;
38 import org.apache.maven.continuum.model.project.Project;
39 import org.apache.maven.continuum.model.project.ProjectGroup;
40 import org.apache.maven.continuum.model.project.Schedule;
41 import org.apache.maven.continuum.project.builder.AbstractContinuumProjectBuilder;
42 import org.apache.maven.continuum.project.builder.ContinuumProjectBuilder;
43 import org.apache.maven.continuum.project.builder.ContinuumProjectBuilderException;
44 import org.apache.maven.continuum.project.builder.ContinuumProjectBuildingResult;
45 import org.apache.maven.continuum.store.ContinuumStoreException;
46 import org.apache.maven.project.MavenProject;
47 import org.codehaus.plexus.util.StringUtils;
48
49
50
51
52
53
54 public class MavenTwoContinuumProjectBuilder
55 extends AbstractContinuumProjectBuilder
56 implements ContinuumProjectBuilder
57 {
58 public static final String ID = "maven-two-builder";
59
60 private static final String POM_PART = "/pom.xml";
61
62
63
64
65 private LocalRepositoryDao localRepositoryDao;
66
67
68
69
70 private MavenBuilderHelper builderHelper;
71
72
73
74
75 private ScheduleDao scheduleDao;
76
77
78
79
80 private BuildDefinitionService buildDefinitionService;
81
82
83
84
85 private List<String> excludedPackagingTypes = new ArrayList<String>();
86
87
88
89
90 public ContinuumProjectBuildingResult buildProjectsFromMetadata( URL url, String username, String password )
91 throws ContinuumProjectBuilderException
92 {
93 return buildProjectsFromMetadata( url, username, password, true );
94 }
95
96 public ContinuumProjectBuildingResult buildProjectsFromMetadata( URL url, String username, String password,
97 boolean loadRecursiveProjects )
98 throws ContinuumProjectBuilderException
99 {
100 try
101 {
102 return buildProjectsFromMetadata( url, username, password, loadRecursiveProjects,
103 buildDefinitionService.getDefaultMavenTwoBuildDefinitionTemplate() );
104 }
105 catch ( BuildDefinitionServiceException e )
106 {
107 throw new ContinuumProjectBuilderException( e.getMessage(), e );
108 }
109 }
110
111 public ContinuumProjectBuildingResult buildProjectsFromMetadata( URL url, String username, String password,
112 boolean loadRecursiveProjects,
113 BuildDefinitionTemplate buildDefinitionTemplate )
114 throws ContinuumProjectBuilderException
115 {
116
117
118
119
120 ContinuumProjectBuildingResult result = new ContinuumProjectBuildingResult();
121
122 try
123 {
124 readModules( url, result, true, username, password, null, loadRecursiveProjects, buildDefinitionTemplate );
125 }
126 catch ( BuildDefinitionServiceException e )
127 {
128 throw new ContinuumProjectBuilderException( e.getMessage(), e );
129 }
130 return result;
131 }
132
133
134
135
136
137 private void readModules( URL url, ContinuumProjectBuildingResult result, boolean groupPom, String username,
138 String password, String scmUrl, boolean loadRecursiveProjects,
139 BuildDefinitionTemplate buildDefinitionTemplate )
140 throws ContinuumProjectBuilderException, BuildDefinitionServiceException
141 {
142
143 MavenProject mavenProject;
144
145 File pomFile = null;
146
147 try
148 {
149 pomFile = createMetadataFile( result, url, username, password );
150
151 if ( result.hasErrors() )
152 {
153 return;
154 }
155
156 mavenProject = builderHelper.getMavenProject( result, pomFile );
157
158 if ( result.hasErrors() )
159 {
160 return;
161 }
162 }
163 finally
164 {
165 if ( pomFile != null && pomFile.exists() )
166 {
167 pomFile.delete();
168 }
169 }
170 log.debug( "groupPom " + groupPom );
171 if ( groupPom )
172 {
173 ProjectGroup projectGroup = buildProjectGroup( mavenProject, result );
174
175
176
177 log.debug( "projectGroup != null" + ( projectGroup != null ) );
178 if ( projectGroup != null )
179 {
180 List<BuildDefinition> buildDefinitions =
181 getBuildDefinitions( buildDefinitionTemplate, loadRecursiveProjects );
182 boolean defaultSetted = false;
183 for ( BuildDefinition buildDefinition : buildDefinitions )
184 {
185 if ( !defaultSetted && buildDefinition.isDefaultForProject() )
186 {
187 buildDefinition.setDefaultForProject( true );
188 defaultSetted = true;
189 }
190 buildDefinition = buildDefinitionService.addBuildDefinition(
191 buildDefinitionService.cloneBuildDefinition( buildDefinition ) );
192
193 String defaultGoal = mavenProject.getBuild().getDefaultGoal();
194 if ( StringUtils.isNotEmpty( defaultGoal ) )
195 {
196 buildDefinition.setGoals( defaultGoal );
197 }
198 if ( buildDefinition.getSchedule() == null )
199 {
200 try
201 {
202 Schedule schedule =
203 scheduleDao.getScheduleByName( ConfigurationService.DEFAULT_SCHEDULE_NAME );
204
205 buildDefinition.setSchedule( schedule );
206 }
207 catch ( ContinuumStoreException e )
208 {
209 log.warn( "Can't get default schedule.", e );
210 }
211 }
212
213
214
215
216
217 projectGroup.addBuildDefinition( buildDefinition );
218
219 }
220 result.addProjectGroup( projectGroup );
221 }
222 }
223
224 if ( !excludedPackagingTypes.contains( mavenProject.getPackaging() ) )
225 {
226 Project continuumProject = new Project();
227
228
229
230
231
232 if ( username != null && StringUtils.isNotEmpty( username ) )
233 {
234 continuumProject.setScmUsername( username );
235
236 if ( password != null && StringUtils.isNotEmpty( password ) )
237 {
238 continuumProject.setScmPassword( password );
239 }
240 }
241
242 builderHelper.mapMavenProjectToContinuumProject( result, mavenProject, continuumProject, groupPom );
243
244 if ( result.hasErrors() )
245 {
246 log.info(
247 "Error adding project: Unknown error mapping project " + url + ": " + result.getErrorsAsString() );
248 return;
249 }
250
251
252
253 if ( StringUtils.isNotEmpty( scmUrl ) )
254 {
255 continuumProject.setScmUrl( scmUrl );
256 }
257 else
258 {
259 scmUrl = continuumProject.getScmUrl();
260 }
261
262 if ( !"HEAD".equals( mavenProject.getScm().getTag() ) )
263 {
264 continuumProject.setScmTag( mavenProject.getScm().getTag() );
265 }
266 result.addProject( continuumProject, MavenTwoBuildExecutor.ID );
267 }
268
269 List<String> modules = mavenProject.getModules();
270
271 String prefix = url.toExternalForm();
272
273 String suffix = "";
274
275 int i = prefix.indexOf( '?' );
276
277 int lastSlash;
278
279 if ( i != -1 )
280 {
281 suffix = prefix.substring( i );
282
283 lastSlash = prefix.lastIndexOf( "/", i );
284 }
285 else
286 {
287 lastSlash = prefix.lastIndexOf( "/" );
288 }
289
290 prefix = prefix.substring( 0, lastSlash );
291 if ( loadRecursiveProjects )
292 {
293 for ( String module : modules )
294 {
295 if ( StringUtils.isNotEmpty( module ) )
296 {
297 String urlString = prefix + "/" + module + POM_PART + suffix;
298
299 URL moduleUrl;
300
301 try
302 {
303 moduleUrl = new URL( urlString );
304 }
305 catch ( MalformedURLException e )
306 {
307 log.debug( "Error adding project module: Malformed URL " + urlString, e );
308 result.addError( ContinuumProjectBuildingResult.ERROR_MALFORMED_URL, urlString );
309 continue;
310 }
311
312 String moduleScmUrl;
313 if ( scmUrl.endsWith( "/" ) )
314 {
315 moduleScmUrl = scmUrl + module;
316 }
317 else
318 {
319 moduleScmUrl = scmUrl + "/" + module;
320 }
321
322 readModules( moduleUrl, result, false, username, password, moduleScmUrl, true,
323 buildDefinitionTemplate );
324 }
325 }
326 }
327 }
328
329 private List<BuildDefinition> getBuildDefinitions( BuildDefinitionTemplate template, boolean loadRecursiveProjects )
330 throws ContinuumProjectBuilderException, BuildDefinitionServiceException
331 {
332 List<BuildDefinition> buildDefinitions = new ArrayList<BuildDefinition>();
333 for ( BuildDefinition buildDefinition : (List<BuildDefinition>) template.getBuildDefinitions() )
334 {
335
336
337 if ( !loadRecursiveProjects )
338 {
339 if ( StringUtils.isEmpty( buildDefinition.getArguments() ) )
340 {
341
342 log.info( "build definition '" + buildDefinition.getId() + "' has empty args" );
343 }
344 else
345 {
346 String arguments = buildDefinition.getArguments().replace( "--non-recursive", "" );
347 arguments = arguments.replace( "-N", "" );
348 buildDefinition.setArguments( arguments );
349 }
350 }
351 buildDefinition.setTemplate( false );
352 buildDefinitions.add( buildDefinition );
353 }
354 return buildDefinitions;
355
356 }
357
358 private ProjectGroup buildProjectGroup( MavenProject mavenProject, ContinuumProjectBuildingResult result )
359 {
360 ProjectGroup projectGroup = new ProjectGroup();
361
362
363
364
365
366 if ( StringUtils.isEmpty( mavenProject.getGroupId() ) )
367 {
368 result.addError( ContinuumProjectBuildingResult.ERROR_MISSING_GROUPID );
369
370 return null;
371 }
372
373 projectGroup.setGroupId( mavenProject.getGroupId() );
374
375
376
377
378
379 String name = mavenProject.getName();
380
381 if ( StringUtils.isEmpty( name ) )
382 {
383 name = mavenProject.getGroupId();
384 }
385
386 projectGroup.setName( name );
387
388
389
390
391
392 projectGroup.setDescription( mavenProject.getDescription() );
393
394
395
396
397
398 try
399 {
400 LocalRepository repository = localRepositoryDao.getLocalRepositoryByName( "DEFAULT" );
401
402 projectGroup.setLocalRepository( repository );
403 }
404 catch ( ContinuumStoreException e )
405 {
406 log.warn( "Can't get default repository.", e );
407 }
408
409 return projectGroup;
410 }
411
412
413 public BuildDefinitionTemplate getDefaultBuildDefinitionTemplate()
414 throws ContinuumProjectBuilderException
415 {
416 try
417 {
418 return buildDefinitionService.getDefaultMavenTwoBuildDefinitionTemplate();
419 }
420 catch ( BuildDefinitionServiceException e )
421 {
422 throw new ContinuumProjectBuilderException( e.getMessage(), e );
423 }
424 }
425
426 }