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.continuum.builddefinition;
20  
21  import java.util.ArrayList;
22  import java.util.List;
23  
24  import org.apache.continuum.buildqueue.BuildQueueServiceException;
25  import org.apache.continuum.configuration.ContinuumConfigurationException;
26  import org.apache.continuum.dao.BuildDefinitionDao;
27  import org.apache.continuum.dao.BuildDefinitionTemplateDao;
28  import org.apache.continuum.dao.ProjectDao;
29  import org.apache.continuum.dao.ProjectGroupDao;
30  import org.apache.maven.continuum.configuration.ConfigurationLoadingException;
31  import org.apache.maven.continuum.configuration.ConfigurationService;
32  import org.apache.maven.continuum.execution.ContinuumBuildExecutorConstants;
33  import org.apache.maven.continuum.model.project.BuildDefinition;
34  import org.apache.maven.continuum.model.project.BuildDefinitionTemplate;
35  import org.apache.maven.continuum.model.project.Project;
36  import org.apache.maven.continuum.model.project.ProjectGroup;
37  import org.apache.maven.continuum.model.project.Schedule;
38  import org.apache.maven.continuum.store.ContinuumObjectNotFoundException;
39  import org.apache.maven.continuum.store.ContinuumStoreException;
40  import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
41  import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException;
42  import org.slf4j.Logger;
43  import org.slf4j.LoggerFactory;
44  
45  /**
46   * @author <a href="mailto:olamy@apache.org">olamy</a>
47   * @version $Id: DefaultBuildDefinitionService.java 794266 2009-07-15 13:35:45Z jzurbano $
48   * @plexus.component role="org.apache.maven.continuum.builddefinition.BuildDefinitionService"
49   * @TODO some cache mechanism ?
50   * @since 15 sept. 07
51   */
52  public class DefaultBuildDefinitionService
53      implements BuildDefinitionService, Initializable
54  {
55      private static final Logger log = LoggerFactory.getLogger( DefaultBuildDefinitionService.class );
56  
57      /**
58       * @plexus.configuration default-value=""
59       */
60      private String defaultAntGoals;
61  
62      /**
63       * @plexus.configuration default-value=""
64       */
65      private String defaultAntArguments;
66  
67      /**
68       * @plexus.configuration default-value="clean:clean jar:install"
69       */
70      private String defaultM1Goals;
71  
72      /**
73       * @plexus.configuration default-value=""
74       */
75      private String defaultM1Arguments;
76  
77      /**
78       * @plexus.configuration default-value="clean install"
79       */
80      private String defaultM2Goals;
81  
82      /**
83       * @plexus.configuration default-value="--batch-mode --non-recursive"
84       */
85      private String defaultM2Arguments;
86  
87      /**
88       * @plexus.requirement
89       */
90      private BuildDefinitionDao buildDefinitionDao;
91  
92      /**
93       * @plexus.requirement
94       */
95      private BuildDefinitionTemplateDao buildDefinitionTemplateDao;
96  
97      /**
98       * @plexus.requirement
99       */
100     private ProjectDao projectDao;
101 
102     /**
103      * @plexus.requirement
104      */
105     private ProjectGroupDao projectGroupDao;
106 
107     /**
108      * @plexus.requirement role-hint="default"
109      */
110     private ConfigurationService configurationService;
111 
112     // -----------------------------------------------
113     //  Plexus Lifecycle
114     // -----------------------------------------------
115 
116     public void initialize()
117         throws InitializationException
118     {
119         try
120         {
121             initializeDefaultContinuumBuildDefintions();
122         }
123         catch ( BuildDefinitionServiceException e )
124         {
125             throw new InitializationException( e.getMessage(), e );
126         }
127     }
128 
129     private void initializeDefaultContinuumBuildDefintions()
130         throws BuildDefinitionServiceException
131     {
132         this.getDefaultAntBuildDefinitionTemplate();
133         this.getDefaultMavenOneBuildDefinitionTemplate();
134         this.getDefaultMavenTwoBuildDefinitionTemplate();
135         this.getDefaultShellBuildDefinitionTemplate();
136     }
137 
138     public BuildDefinition getBuildDefinition( int buildDefinitionId )
139         throws BuildDefinitionServiceException
140     {
141         try
142         {
143             return buildDefinitionDao.getBuildDefinition( buildDefinitionId );
144         }
145         catch ( ContinuumObjectNotFoundException e )
146         {
147             return null;
148         }
149         catch ( ContinuumStoreException e )
150         {
151             throw new BuildDefinitionServiceException( e.getMessage(), e );
152         }
153     }
154 
155     public BuildDefinition addBuildDefinition( BuildDefinition buildDefinition )
156         throws BuildDefinitionServiceException
157     {
158         try
159         {
160             return buildDefinitionDao.addBuildDefinition( buildDefinition );
161         }
162         catch ( ContinuumStoreException e )
163         {
164             throw new BuildDefinitionServiceException( e.getMessage(), e );
165         }
166     }
167 
168 
169     public void removeBuildDefinition( BuildDefinition buildDefinition )
170         throws BuildDefinitionServiceException
171     {
172         try
173         {
174             buildDefinitionDao.removeBuildDefinition( buildDefinition );
175         }
176         catch ( ContinuumStoreException e )
177         {
178             throw new BuildDefinitionServiceException( e.getMessage(), e );
179         }
180     }
181 
182     public void updateBuildDefinition( BuildDefinition buildDefinition )
183         throws BuildDefinitionServiceException
184     {
185         try
186         {
187             BuildDefinition storedBuildDefinition = buildDefinitionDao.getBuildDefinition( buildDefinition.getId() );
188             storedBuildDefinition.setBuildFresh( buildDefinition.isBuildFresh() );
189             storedBuildDefinition.setAlwaysBuild( buildDefinition.isAlwaysBuild() );
190             storedBuildDefinition.setArguments( buildDefinition.getArguments() );
191             storedBuildDefinition.setBuildFile( buildDefinition.getBuildFile() );
192             storedBuildDefinition.setDefaultForProject( buildDefinition.isDefaultForProject() );
193             storedBuildDefinition.setDescription( buildDefinition.getDescription() );
194             storedBuildDefinition.setGoals( buildDefinition.getGoals() );
195             storedBuildDefinition.setProfile( buildDefinition.getProfile() );
196             storedBuildDefinition.setSchedule( buildDefinition.getSchedule() );
197             storedBuildDefinition.setType( buildDefinition.getType() );
198             buildDefinitionDao.storeBuildDefinition( storedBuildDefinition );
199         }
200         catch ( ContinuumStoreException e )
201         {
202             throw new BuildDefinitionServiceException( e.getMessage(), e );
203         }
204 
205     }
206 
207     public List<BuildDefinition> getAllBuildDefinitions()
208         throws BuildDefinitionServiceException
209     {
210         try
211         {
212             return buildDefinitionDao.getAllBuildDefinitions();
213         }
214         catch ( ContinuumStoreException e )
215         {
216             throw new BuildDefinitionServiceException( e.getMessage(), e );
217         }
218     }
219 
220 
221     public List<BuildDefinition> getAllTemplates()
222         throws BuildDefinitionServiceException
223     {
224         try
225         {
226             return buildDefinitionDao.getAllTemplates();
227         }
228         catch ( ContinuumStoreException e )
229         {
230             throw new BuildDefinitionServiceException( e.getMessage(), e );
231         }
232     }
233 
234     /**
235      * @see org.apache.maven.continuum.builddefinition.BuildDefinitionService#cloneBuildDefinition(org.apache.maven.continuum.model.project.BuildDefinition)
236      */
237     public BuildDefinition cloneBuildDefinition( BuildDefinition buildDefinition )
238     {
239         BuildDefinition cloned = new BuildDefinition();
240         cloned.setAlwaysBuild( buildDefinition.isAlwaysBuild() );
241         cloned.setArguments( buildDefinition.getArguments() );
242         cloned.setBuildFile( buildDefinition.getBuildFile() );
243         cloned.setBuildFresh( buildDefinition.isBuildFresh() );
244         cloned.setDefaultForProject( buildDefinition.isDefaultForProject() );
245         cloned.setDescription( buildDefinition.getDescription() );
246         cloned.setGoals( buildDefinition.getGoals() );
247         cloned.setProfile( buildDefinition.getProfile() );
248         cloned.setSchedule( buildDefinition.getSchedule() );
249         cloned.setType( buildDefinition.getType() );
250         cloned.setTemplate( buildDefinition.isTemplate() );
251         return cloned;
252     }
253 
254 
255     public BuildDefinitionTemplate getContinuumDefaultWithType( String type )
256         throws BuildDefinitionServiceException
257     {
258         try
259         {
260             return buildDefinitionTemplateDao.getContinuumBuildDefinitionTemplateWithType( type );
261         }
262         catch ( ContinuumStoreException e )
263         {
264             throw new BuildDefinitionServiceException( e.getMessage(), e );
265         }
266     }
267 
268     public BuildDefinitionTemplate getDefaultAntBuildDefinitionTemplate()
269         throws BuildDefinitionServiceException
270     {
271         BuildDefinitionTemplate template =
272             getContinuumDefaultWithType( ContinuumBuildExecutorConstants.ANT_BUILD_EXECUTOR );
273         if ( template != null )
274         {
275             return template;
276         }
277         log.info( "create default AntBuildDefinitionTemplate" );
278         template = new BuildDefinitionTemplate();
279         template.setContinuumDefault( true );
280         template.setName( "Default Ant Template" );
281         template.setType( ContinuumBuildExecutorConstants.ANT_BUILD_EXECUTOR );
282 
283         template = addBuildDefinitionTemplate( template );
284 
285         BuildDefinition bd = new BuildDefinition();
286 
287         bd.setDefaultForProject( true );
288 
289         bd.setGoals( defaultAntGoals );
290 
291         bd.setArguments( defaultAntArguments );
292 
293         bd.setBuildFile( "build.xml" );
294 
295         bd.setSchedule( getDefaultSchedule() );
296 
297         bd.setDescription( "Default Ant Build Definition" );
298 
299         bd.setTemplate( true );
300 
301         bd.setType( ContinuumBuildExecutorConstants.ANT_BUILD_EXECUTOR );
302         return addBuildDefinitionInTemplate( template, bd, true );
303     }
304 
305     public BuildDefinitionTemplate getDefaultMavenOneBuildDefinitionTemplate()
306         throws BuildDefinitionServiceException
307     {
308         BuildDefinitionTemplate template =
309             getContinuumDefaultWithType( ContinuumBuildExecutorConstants.MAVEN_ONE_BUILD_EXECUTOR );
310         if ( template != null )
311         {
312             log.debug( "found default maven template " + template.getType() );
313             return template;
314         }
315         log.info( "create default MavenOneBuildDefinitionTemplate" );
316         template = new BuildDefinitionTemplate();
317         template.setContinuumDefault( true );
318         template.setName( "Default Maven 1 Template" );
319         template.setType( ContinuumBuildExecutorConstants.MAVEN_ONE_BUILD_EXECUTOR );
320 
321         template = addBuildDefinitionTemplate( template );
322 
323         BuildDefinition bd = new BuildDefinition();
324 
325         bd.setDefaultForProject( true );
326 
327         bd.setArguments( defaultM1Arguments );
328 
329         bd.setGoals( defaultM1Goals );
330 
331         bd.setBuildFile( "project.xml" );
332 
333         bd.setSchedule( getDefaultSchedule() );
334 
335         bd.setType( ContinuumBuildExecutorConstants.MAVEN_ONE_BUILD_EXECUTOR );
336 
337         bd.setDescription( "Default Maven 1 Build Definition" );
338 
339         bd.setTemplate( true );
340 
341         return addBuildDefinitionInTemplate( template, bd, true );
342     }
343 
344     public BuildDefinitionTemplate getDefaultMavenTwoBuildDefinitionTemplate()
345         throws BuildDefinitionServiceException
346     {
347         BuildDefinitionTemplate template =
348             getContinuumDefaultWithType( ContinuumBuildExecutorConstants.MAVEN_TWO_BUILD_EXECUTOR );
349         if ( template != null )
350         {
351             return template;
352         }
353         log.info( "create default MavenTwoBuildDefinitionTemplate" );
354         template = new BuildDefinitionTemplate();
355         template.setContinuumDefault( true );
356         template.setName( "Default Maven 2 Template" );
357         template.setType( ContinuumBuildExecutorConstants.MAVEN_TWO_BUILD_EXECUTOR );
358 
359         template = addBuildDefinitionTemplate( template );
360 
361         BuildDefinition bd = new BuildDefinition();
362 
363         bd.setDefaultForProject( true );
364 
365         bd.setGoals( this.defaultM2Goals );
366 
367         bd.setArguments( this.defaultM2Arguments );
368 
369         bd.setBuildFile( "pom.xml" );
370 
371         bd.setSchedule( getDefaultSchedule() );
372 
373         bd.setType( ContinuumBuildExecutorConstants.MAVEN_TWO_BUILD_EXECUTOR );
374 
375         bd.setDescription( "Default Maven 2 Build Definition" );
376 
377         bd.setTemplate( true );
378 
379         return addBuildDefinitionInTemplate( template, bd, true );
380     }
381 
382     public BuildDefinitionTemplate getDefaultShellBuildDefinitionTemplate()
383         throws BuildDefinitionServiceException
384     {
385         BuildDefinitionTemplate template =
386             getContinuumDefaultWithType( ContinuumBuildExecutorConstants.SHELL_BUILD_EXECUTOR );
387         if ( template != null )
388         {
389             return template;
390         }
391         log.info( "create default ShellBuildDefinitionTemplate" );
392         template = new BuildDefinitionTemplate();
393         template.setContinuumDefault( true );
394         template.setName( "Default Shell Template" );
395         template.setType( ContinuumBuildExecutorConstants.SHELL_BUILD_EXECUTOR );
396 
397         template = addBuildDefinitionTemplate( template );
398 
399         BuildDefinition bd = new BuildDefinition();
400 
401         bd.setDefaultForProject( true );
402 
403         bd.setSchedule( getDefaultSchedule() );
404 
405         bd.setType( ContinuumBuildExecutorConstants.SHELL_BUILD_EXECUTOR );
406 
407         bd.setTemplate( true );
408 
409         bd.setDescription( "Default Shell Build Definition" );
410 
411         return addBuildDefinitionInTemplate( template, bd, true );
412     }
413 
414     private Schedule getDefaultSchedule()
415         throws BuildDefinitionServiceException
416     {
417         try
418         {
419             return configurationService.getDefaultSchedule();
420         }
421         catch ( ContinuumStoreException e )
422         {
423             throw new BuildDefinitionServiceException( e.getMessage(), e );
424         }
425         catch ( ConfigurationLoadingException e )
426         {
427             throw new BuildDefinitionServiceException( e.getMessage(), e );
428         }
429         catch ( ContinuumConfigurationException e )
430         {
431             throw new BuildDefinitionServiceException( e.getMessage(), e );
432         }
433         catch ( BuildQueueServiceException e )
434         {
435             throw new BuildDefinitionServiceException( e.getMessage(), e );
436         }
437     }
438 
439     // ------------------------------------------------------
440     //  BuildDefinitionTemplate
441     // ------------------------------------------------------    
442 
443     public List<BuildDefinitionTemplate> getAllBuildDefinitionTemplate()
444         throws BuildDefinitionServiceException
445     {
446         try
447         {
448             return buildDefinitionTemplateDao.getAllBuildDefinitionTemplate();
449         }
450         catch ( ContinuumStoreException e )
451         {
452             throw new BuildDefinitionServiceException( e.getMessage(), e );
453         }
454     }
455 
456     public BuildDefinitionTemplate getBuildDefinitionTemplate( int id )
457         throws BuildDefinitionServiceException
458     {
459         try
460         {
461             return buildDefinitionTemplateDao.getBuildDefinitionTemplate( id );
462         }
463         catch ( ContinuumStoreException e )
464         {
465             throw new BuildDefinitionServiceException( e.getMessage(), e );
466         }
467     }
468 
469     public void removeBuildDefinitionTemplate( BuildDefinitionTemplate buildDefinitionTemplate )
470         throws BuildDefinitionServiceException
471     {
472         try
473         {
474             // first remove links to buildDefs
475             // TODO in the same db transaction ?
476             buildDefinitionTemplate.setBuildDefinitions( null );
477             buildDefinitionTemplate =
478                 buildDefinitionTemplateDao.updateBuildDefinitionTemplate( buildDefinitionTemplate );
479             buildDefinitionTemplateDao.removeBuildDefinitionTemplate( buildDefinitionTemplate );
480         }
481         catch ( ContinuumStoreException e )
482         {
483             throw new BuildDefinitionServiceException( e.getMessage(), e );
484         }
485     }
486 
487     public BuildDefinitionTemplate updateBuildDefinitionTemplate( BuildDefinitionTemplate buildDefinitionTemplate )
488         throws BuildDefinitionServiceException
489     {
490         try
491         {
492         	if ( !hasDuplicateTemplateName( buildDefinitionTemplate ) )
493         	{
494 	            BuildDefinitionTemplate stored = getBuildDefinitionTemplate( buildDefinitionTemplate.getId() );
495 	            stored.setName( buildDefinitionTemplate.getName() );
496 	            stored.setBuildDefinitions( buildDefinitionTemplate.getBuildDefinitions() );
497 	            return buildDefinitionTemplateDao.updateBuildDefinitionTemplate( stored );
498         	}
499         }
500         catch ( ContinuumStoreException e )
501         {
502             throw new BuildDefinitionServiceException( e.getMessage(), e );
503         }
504         
505         return null;
506     }
507 
508     public BuildDefinitionTemplate addBuildDefinitionTemplate( BuildDefinitionTemplate buildDefinitionTemplate )
509         throws BuildDefinitionServiceException
510     {
511         try
512         {
513         	if ( !hasDuplicateTemplateName( buildDefinitionTemplate ) )
514         	{
515         	    return buildDefinitionTemplateDao.addBuildDefinitionTemplate( buildDefinitionTemplate );
516         	}
517         }
518         catch ( ContinuumStoreException e )
519         {
520             throw new BuildDefinitionServiceException( e.getMessage(), e );
521         }
522         
523         return null;
524     }
525 
526     public BuildDefinitionTemplate addBuildDefinitionInTemplate( BuildDefinitionTemplate buildDefinitionTemplate,
527                                                                  BuildDefinition buildDefinition, boolean template )
528         throws BuildDefinitionServiceException
529     {
530         try
531         {
532             BuildDefinitionTemplate stored = getBuildDefinitionTemplate( buildDefinitionTemplate.getId() );
533             stored.setName( buildDefinitionTemplate.getName() );
534             BuildDefinition storedBuildDefinition = getBuildDefinition( buildDefinition.getId() );
535             if ( storedBuildDefinition != null )
536             {
537                 buildDefinition = storedBuildDefinition;
538             }
539             buildDefinition.setTemplate( template );
540             //stored.addBuildDefinition( addBuildDefinition( buildDefinition ) );
541             stored.addBuildDefinition( buildDefinition );
542             return buildDefinitionTemplateDao.updateBuildDefinitionTemplate( stored );
543         }
544         catch ( ContinuumStoreException e )
545         {
546             throw new BuildDefinitionServiceException( e.getMessage(), e );
547         }
548     }
549 
550     public BuildDefinitionTemplate removeBuildDefinitionFromTemplate( BuildDefinitionTemplate buildDefinitionTemplate,
551                                                                       BuildDefinition buildDefinition )
552         throws BuildDefinitionServiceException
553     {
554         try
555         {
556             BuildDefinitionTemplate stored = getBuildDefinitionTemplate( buildDefinitionTemplate.getId() );
557             stored.setName( buildDefinitionTemplate.getName() );
558             List<BuildDefinition> buildDefinitions = new ArrayList<BuildDefinition>();
559             for ( int i = 0, size = stored.getBuildDefinitions().size(); i < size; i++ )
560             {
561                 BuildDefinition buildDef = (BuildDefinition) stored.getBuildDefinitions().get( i );
562                 if ( buildDef.getId() != buildDefinition.getId() )
563                 {
564                     buildDefinitions.add( getBuildDefinition( buildDef.getId() ) );
565                 }
566             }
567             stored.setBuildDefinitions( buildDefinitions );
568             return buildDefinitionTemplateDao.updateBuildDefinitionTemplate( stored );
569         }
570         catch ( ContinuumStoreException e )
571         {
572             throw new BuildDefinitionServiceException( e.getMessage(), e );
573         }
574 
575     }
576 
577     public void addTemplateInProject( int buildDefinitionTemplateId, Project project )
578         throws BuildDefinitionServiceException
579     {
580         try
581         {
582             BuildDefinitionTemplate template = getBuildDefinitionTemplate( buildDefinitionTemplateId );
583             if ( template.getBuildDefinitions().isEmpty() )
584             {
585                 return;
586             }
587             project = projectDao.getProjectWithBuildDetails( project.getId() );
588 
589             for ( BuildDefinition bd : (List<BuildDefinition>) template.getBuildDefinitions() )
590             {
591                 bd = cloneBuildDefinition( bd );
592                 bd.setTemplate( false );
593                 bd = buildDefinitionDao.addBuildDefinition( bd );
594                 project.addBuildDefinition( bd );
595             }
596             projectDao.updateProject( project );
597 
598         }
599         catch ( ContinuumStoreException e )
600         {
601             throw new BuildDefinitionServiceException( e.getMessage(), e );
602         }
603     }
604 
605     public ProjectGroup addBuildDefinitionTemplateToProjectGroup( int projectGroupId, BuildDefinitionTemplate template )
606         throws BuildDefinitionServiceException, ContinuumObjectNotFoundException
607     {
608         try
609         {
610             ProjectGroup projectGroup =
611                 projectGroupDao.getProjectGroupWithBuildDetailsByProjectGroupId( projectGroupId );
612             if ( template.getBuildDefinitions().isEmpty() )
613             {
614                 return null;
615             }
616 
617             for ( BuildDefinition bd : (List<BuildDefinition>) template.getBuildDefinitions() )
618             {
619                 bd.setTemplate( false );
620                 bd = buildDefinitionDao.addBuildDefinition( cloneBuildDefinition( bd ) );
621                 projectGroup.addBuildDefinition( bd );
622             }
623             projectGroupDao.updateProjectGroup( projectGroup );
624             return projectGroup;
625 
626         }
627         catch ( ContinuumStoreException e )
628         {
629             throw new BuildDefinitionServiceException( e.getMessage(), e );
630         }
631     }
632 
633     public List<BuildDefinitionTemplate> getBuildDefinitionTemplatesWithType( String type )
634         throws BuildDefinitionServiceException
635     {
636         try
637         {
638             return buildDefinitionTemplateDao.getBuildDefinitionTemplatesWithType( type );
639         }
640         catch ( ContinuumStoreException e )
641         {
642             throw new BuildDefinitionServiceException( e.getMessage(), e );
643         }
644     }
645 
646     public List<BuildDefinitionTemplate> getContinuumBuildDefinitionTemplates()
647         throws BuildDefinitionServiceException
648     {
649         try
650         {
651             return buildDefinitionTemplateDao.getContinuumBuildDefinitionTemplates();
652         }
653         catch ( ContinuumStoreException e )
654         {
655             throw new BuildDefinitionServiceException( e.getMessage(), e );
656         }
657     }
658     
659     private boolean hasDuplicateTemplateName( BuildDefinitionTemplate buildDefinitionTemplate )
660         throws BuildDefinitionServiceException
661     {
662         boolean isDuplicate = false;
663         List<BuildDefinitionTemplate> allBuildDefinitionTemplate = this.getAllBuildDefinitionTemplate();
664     
665         for ( BuildDefinitionTemplate template : allBuildDefinitionTemplate )
666         {
667             String name = buildDefinitionTemplate.getName();
668             if ( ( template.getId() != buildDefinitionTemplate.getId() ) && ( template.getName().equals( name ) ) )
669             {
670                 isDuplicate = true;
671                 break;
672             }
673         }
674         return isDuplicate;
675     }
676 }