View Javadoc

1   package org.apache.continuum.builder.distributed;
2   
3   import java.io.BufferedWriter;
4   import java.io.File;
5   import java.io.FileWriter;
6   import java.io.IOException;
7   import java.util.ArrayList;
8   import java.util.Collections;
9   import java.util.Date;
10  import java.util.HashMap;
11  import java.util.List;
12  import java.util.Map;
13  
14  import org.apache.continuum.builder.distributed.util.DistributedBuildUtil;
15  import org.apache.continuum.builder.utils.ContinuumBuildConstant;
16  import org.apache.continuum.dao.BuildDefinitionDao;
17  import org.apache.continuum.dao.BuildResultDao;
18  import org.apache.continuum.dao.ProjectDao;
19  import org.apache.continuum.dao.ProjectScmRootDao;
20  import org.apache.continuum.model.project.ProjectScmRoot;
21  import org.apache.maven.continuum.ContinuumException;
22  import org.apache.maven.continuum.configuration.ConfigurationException;
23  import org.apache.maven.continuum.configuration.ConfigurationService;
24  import org.apache.maven.continuum.execution.ContinuumBuildExecutorConstants;
25  import org.apache.maven.continuum.installation.InstallationService;
26  import org.apache.maven.continuum.model.project.BuildDefinition;
27  import org.apache.maven.continuum.model.project.BuildResult;
28  import org.apache.maven.continuum.model.project.Project;
29  import org.apache.maven.continuum.model.project.ProjectDependency;
30  import org.apache.maven.continuum.model.project.ProjectDeveloper;
31  import org.apache.maven.continuum.model.project.ProjectNotifier;
32  import org.apache.maven.continuum.model.scm.ChangeFile;
33  import org.apache.maven.continuum.model.scm.ChangeSet;
34  import org.apache.maven.continuum.model.system.Installation;
35  import org.apache.maven.continuum.model.system.Profile;
36  import org.apache.maven.continuum.notification.ContinuumNotificationDispatcher;
37  import org.apache.maven.continuum.project.ContinuumProjectState;
38  import org.apache.maven.continuum.store.ContinuumStoreException;
39  import org.codehaus.plexus.util.StringUtils;
40  import org.slf4j.Logger;
41  import org.slf4j.LoggerFactory;
42  
43  /**
44   * @plexus.component role="org.apache.continuum.builder.distributed.DistributedBuildService"
45   */
46  public class DefaultDistributedBuildService
47      implements DistributedBuildService
48  {
49      private static final Logger log = LoggerFactory.getLogger( DefaultDistributedBuildService.class );
50  
51      /**
52       * @plexus.requirement
53       */
54      private ProjectDao projectDao;
55  
56      /**
57       * @plexus.requirement
58       */
59      private BuildDefinitionDao buildDefinitionDao;
60  
61      /**
62       * @plexus.requirement
63       */
64      private BuildResultDao buildResultDao;
65  
66      /**
67       * @plexus.requirement
68       */
69      private ProjectScmRootDao projectScmRootDao;
70  
71      /**
72       * @plexus.requirement
73       */
74      private ConfigurationService configurationService;
75  
76      /**
77       * @plexus.requirement
78       */
79      private InstallationService installationService;
80  
81      /**
82       * @plexus.requirement
83       */
84      private ContinuumNotificationDispatcher notifierDispatcher;
85  
86      /**
87       * @plexus.requirement
88       */
89      private DistributedBuildUtil distributedBuildUtil;
90  
91      public void updateBuildResult( Map<String, Object> context )
92          throws ContinuumException
93      {
94          try
95          {
96              int projectId = ContinuumBuildConstant.getProjectId( context );
97              int buildDefinitionId = ContinuumBuildConstant.getBuildDefinitionId( context );
98      
99              log.info( "update build result of project '" + projectId + "'" );
100     
101             Project project = projectDao.getProjectWithAllDetails( projectId );
102             BuildDefinition buildDefinition = buildDefinitionDao.getBuildDefinition( buildDefinitionId );
103     
104             BuildResult oldBuildResult =
105                 buildResultDao.getLatestBuildResultForBuildDefinition( projectId, buildDefinitionId );
106     
107             int buildNumber;
108     
109             if ( ContinuumBuildConstant.getBuildState( context ) == ContinuumProjectState.OK )
110             {
111                 buildNumber = project.getBuildNumber() + 1;
112             }
113             else
114             {
115                 buildNumber = project.getBuildNumber();
116             }
117     
118             // ----------------------------------------------------------------------
119             // Make the buildResult
120             // ----------------------------------------------------------------------
121     
122             BuildResult buildResult = distributedBuildUtil.convertMapToBuildResult( context );
123     
124             if ( buildResult.getState() != ContinuumProjectState.CANCELLED )
125             {
126                 buildResult.setBuildDefinition( buildDefinition );
127                 buildResult.setBuildNumber( buildNumber );
128                 buildResult.setModifiedDependencies( distributedBuildUtil.getModifiedDependencies( oldBuildResult, context ) );
129                 buildResult.setScmResult( distributedBuildUtil.getScmResult( context ) );
130     
131                 Date date = ContinuumBuildConstant.getLatestUpdateDate( context );
132                 if ( date != null )
133                 {
134                     buildResult.setLastChangedDate( date.getTime() );
135                 }
136                 else if ( oldBuildResult != null )
137                 {
138                     buildResult.setLastChangedDate( oldBuildResult.getLastChangedDate() );
139                 }
140     
141                 buildResultDao.addBuildResult( project, buildResult );
142 
143                 buildResult = buildResultDao.getBuildResult( buildResult.getId() );
144 
145                 project.setOldState( project.getState() );
146                 project.setState( ContinuumBuildConstant.getBuildState( context ) );
147                 project.setBuildNumber( buildNumber );
148                 project.setLatestBuildId( buildResult.getId() );
149             }
150             else
151             {
152                 project.setState( project.getOldState() );
153                 project.setOldState( 0 );
154             }
155     
156             projectDao.updateProject( project );
157     
158             File buildOutputFile = configurationService.getBuildOutputFile( buildResult.getId(), project.getId() );
159     
160             FileWriter fstream = new FileWriter( buildOutputFile );
161             BufferedWriter out = new BufferedWriter( fstream );
162             out.write( ContinuumBuildConstant.getBuildOutput( context ) == null ? ""
163                 : ContinuumBuildConstant.getBuildOutput( context ) );
164             out.close();
165     
166             if ( buildResult.getState() != ContinuumProjectState.CANCELLED )
167             {
168                 notifierDispatcher.buildComplete( project, buildDefinition, buildResult );
169             }
170         }
171         catch ( ContinuumStoreException e )
172         {
173             throw new ContinuumException( "Error while updating build result for project", e );
174         }
175         catch ( ConfigurationException e )
176         {
177             throw new ContinuumException( "Error retrieving build output file", e );
178         }
179         catch ( IOException e )
180         {
181             throw new ContinuumException( "Error while writing build output to file", e );
182         }
183     }
184     
185     public void prepareBuildFinished( Map<String, Object> context )
186         throws ContinuumException
187     {
188         int projectGroupId = ContinuumBuildConstant.getProjectGroupId( context );
189         String scmRootAddress = ContinuumBuildConstant.getScmRootAddress( context );
190     
191         try
192         {
193             ProjectScmRoot scmRoot =
194                 projectScmRootDao.getProjectScmRootByProjectGroupAndScmRootAddress( projectGroupId, scmRootAddress );
195     
196             String error = ContinuumBuildConstant.getScmError( context );
197     
198             if ( StringUtils.isEmpty( error ) )
199             {
200                 scmRoot.setState( ContinuumProjectState.UPDATED );
201             }
202             else
203             {
204                 scmRoot.setState( ContinuumProjectState.ERROR );
205                 scmRoot.setError( error );
206             }
207     
208             projectScmRootDao.updateProjectScmRoot( scmRoot );
209     
210             notifierDispatcher.prepareBuildComplete( scmRoot );
211         }
212         catch ( ContinuumStoreException e )
213         {
214             throw new ContinuumException( "Error while updating project scm root '" + scmRootAddress + "'", e );
215         }
216     }
217     
218     public void startProjectBuild( int projectId )
219         throws ContinuumException
220     {
221         try
222         {
223             Project project = projectDao.getProject( projectId );
224             project.setState( ContinuumProjectState.BUILDING );
225             projectDao.updateProject( project );
226         }
227         catch ( ContinuumStoreException e )
228         {
229             log.error( "Error while updating project's state", e );
230             throw new ContinuumException( "Error while updating project's state", e );
231         }
232     }
233     
234     public void startPrepareBuild( Map<String, Object> context )
235         throws ContinuumException
236     {
237         try
238         {
239             int projectGroupId = ContinuumBuildConstant.getProjectGroupId( context );
240             String scmRootAddress = ContinuumBuildConstant.getScmRootAddress( context );
241     
242             ProjectScmRoot scmRoot =
243                 projectScmRootDao.getProjectScmRootByProjectGroupAndScmRootAddress( projectGroupId, scmRootAddress );
244             scmRoot.setOldState( scmRoot.getState() );
245             scmRoot.setState( ContinuumProjectState.UPDATING );
246             projectScmRootDao.updateProjectScmRoot( scmRoot );
247         }
248         catch ( ContinuumStoreException e )
249         {
250             log.error( "Error while updating project scm root's state", e );
251             throw new ContinuumException( "Error while updating project scm root's state", e );
252         }
253     }
254     
255     public Map<String, String> getEnvironments( int buildDefinitionId, String installationType )
256         throws ContinuumException
257     {
258         BuildDefinition buildDefinition;
259     
260         try
261         {
262             buildDefinition = buildDefinitionDao.getBuildDefinition( buildDefinitionId );
263         }
264         catch ( ContinuumStoreException e )
265         {
266             throw new ContinuumException( "Failed to retrieve build definition: " + buildDefinitionId, e );
267         }
268     
269         Profile profile = buildDefinition.getProfile();
270         if ( profile == null )
271         {
272             return Collections.EMPTY_MAP;
273         }
274         Map<String, String> envVars = new HashMap<String, String>();
275         String javaHome = getJavaHomeValue( buildDefinition );
276         if ( !StringUtils.isEmpty( javaHome ) )
277         {
278             envVars.put( installationService.getEnvVar( InstallationService.JDK_TYPE ), javaHome );
279         }
280         Installation builder = profile.getBuilder();
281         if ( builder != null )
282         {
283             envVars.put( installationService.getEnvVar( installationType ), builder.getVarValue() );
284         }
285         envVars.putAll( getEnvironmentVariables( buildDefinition ) );
286         return envVars;
287     }
288     
289     public void updateProject( Map<String, Object> context )
290         throws ContinuumException
291     {
292         try
293         {
294             Project project = projectDao.getProjectWithAllDetails( ContinuumBuildConstant.getProjectId( context ) );
295     
296             if ( StringUtils.isNotBlank( ContinuumBuildConstant.getGroupId( context ) ) )
297             {
298                 project.setGroupId( ContinuumBuildConstant.getGroupId( context ) );
299             }
300             if ( StringUtils.isNotBlank( ContinuumBuildConstant.getArtifactId( context ) ) )
301             {
302                 project.setArtifactId( ContinuumBuildConstant.getArtifactId( context ) );
303             }
304             if ( StringUtils.isNotBlank( ContinuumBuildConstant.getVersion( context ) ) )
305             {
306                 project.setVersion( ContinuumBuildConstant.getVersion( context ) );
307             }
308             if ( StringUtils.isNotBlank( ContinuumBuildConstant.getProjectName( context ) ) )
309             {
310                 project.setName( ContinuumBuildConstant.getProjectName( context ) );
311             }
312             if ( StringUtils.isNotBlank( ContinuumBuildConstant.getProjectDescription( context ) ) )
313             {
314                 project.setDescription( ContinuumBuildConstant.getProjectDescription( context ) );
315             }
316             if ( StringUtils.isNotBlank( ContinuumBuildConstant.getProjectUrl( context ) ) )
317             {
318                 project.setUrl( ContinuumBuildConstant.getProjectUrl( context ) );
319             }
320             if ( StringUtils.isNotBlank( ContinuumBuildConstant.getScmUrl( context ) ) )
321             {
322                 project.setScmUrl( ContinuumBuildConstant.getScmUrl( context ) );
323             }
324             if ( StringUtils.isNotBlank( ContinuumBuildConstant.getScmTag( context ) ) )
325             {
326                 project.setScmTag( ContinuumBuildConstant.getScmTag( context ) );
327             }
328             project.setParent( getProjectParent( context ) );
329             project.setDependencies( getProjectDependencies( context ) );
330             project.setDevelopers( getProjectDevelopers( context ) );
331 
332             List<ProjectNotifier> userNotifiers = new ArrayList<ProjectNotifier>();
333 
334             if ( project.getNotifiers() != null )
335             {
336                 for ( ProjectNotifier notifier : project.getNotifiers() )
337                 {
338                     if ( notifier.isFromUser() )
339                     {
340                         ProjectNotifier userNotifier = new ProjectNotifier();
341 
342                         userNotifier.setType( notifier.getType() );
343 
344                         userNotifier.setEnabled( notifier.isEnabled() );
345 
346                         userNotifier.setConfiguration( notifier.getConfiguration() );
347 
348                         userNotifier.setFrom( notifier.getFrom() );
349 
350                         userNotifier.setRecipientType( notifier.getRecipientType() );
351 
352                         userNotifier.setSendOnError( notifier.isSendOnError() );
353 
354                         userNotifier.setSendOnFailure( notifier.isSendOnFailure() );
355 
356                         userNotifier.setSendOnSuccess( notifier.isSendOnSuccess() );
357 
358                         userNotifier.setSendOnWarning( notifier.isSendOnWarning() );
359 
360                         userNotifier.setSendOnScmFailure( notifier.isSendOnScmFailure() );
361 
362                         userNotifiers.add( userNotifier );
363                     }
364                 }
365             }
366 
367             project.setNotifiers( getProjectNotifiers( context ) );
368 
369             for ( ProjectNotifier userNotifier : userNotifiers )
370             {
371                 project.addNotifier( userNotifier );
372             }
373     
374             projectDao.updateProject( project );
375         }
376         catch ( ContinuumStoreException e )
377         {
378             throw new ContinuumException( "Unable to update project from working copy", e );
379         }
380     }
381 
382     public boolean shouldBuild( Map<String, Object> context )
383     {
384         try
385         {
386             int projectId = ContinuumBuildConstant.getProjectId( context );
387     
388             int buildDefinitionId = ContinuumBuildConstant.getBuildDefinitionId( context );
389     
390             int trigger = ContinuumBuildConstant.getTrigger( context );
391     
392             Project project = projectDao.getProjectWithAllDetails( projectId );
393     
394             BuildDefinition buildDefinition = buildDefinitionDao.getBuildDefinition( buildDefinitionId );
395     
396             BuildResult oldBuildResult =
397                 buildResultDao.getLatestBuildResultForBuildDefinition( projectId, buildDefinitionId );
398     
399             List<ProjectDependency> modifiedDependencies = distributedBuildUtil.getModifiedDependencies( oldBuildResult, context );
400     
401             List<ChangeSet> changes = distributedBuildUtil.getScmChanges( context );
402     
403             if ( buildDefinition.isBuildFresh() )
404             {
405                 log.info( "FreshBuild configured, building" );
406                 return true;
407             }
408             if ( buildDefinition.isAlwaysBuild() )
409             {
410                 log.info( "AlwaysBuild configured, building" );
411                 return true;
412             }
413             if ( oldBuildResult == null )
414             {
415                 log.info( "The project was never be built with the current build definition, building" );
416                 return true;
417             }
418     
419             //CONTINUUM-1428
420             if ( project.getOldState() == ContinuumProjectState.ERROR ||
421                 oldBuildResult.getState() == ContinuumProjectState.ERROR )
422             {
423                 log.info( "Latest state was 'ERROR', building" );
424                 return true;
425             }
426     
427             if ( trigger == ContinuumProjectState.TRIGGER_FORCED )
428             {
429                 log.info( "The project build is forced, building" );
430                 return true;
431             }
432     
433             Date date = ContinuumBuildConstant.getLatestUpdateDate( context );
434             if ( date != null && oldBuildResult.getLastChangedDate() >= date.getTime() )
435             {
436                 log.info( "No changes found,not building" );
437                 return false;
438             }
439             else if ( date != null && changes.isEmpty() )
440             {
441                 // fresh checkout from build agent that's why changes is empty
442                 log.info( "Changes found in the current project, building" );
443                 return true;
444             }
445     
446             boolean shouldBuild = false;
447     
448             boolean allChangesUnknown = true;
449     
450             if ( project.getOldState() != ContinuumProjectState.NEW &&
451                 project.getOldState() != ContinuumProjectState.CHECKEDOUT &&
452                 project.getState() != ContinuumProjectState.NEW &&
453                 project.getState() != ContinuumProjectState.CHECKEDOUT )
454             {
455                 // Check SCM changes
456                 allChangesUnknown = checkAllChangesUnknown( changes );
457     
458                 if ( allChangesUnknown )
459                 {
460                     if ( !changes.isEmpty() )
461                     {
462                         log.info(
463                             "The project was not built because all changes are unknown (maybe local modifications or ignored files not defined in your SCM tool." );
464                     }
465                     else
466                     {
467                         log.info(
468                             "The project was not built because no changes were detected in sources since the last build." );
469                     }
470                 }
471     
472                 // Check dependencies changes
473                 if ( modifiedDependencies != null && !modifiedDependencies.isEmpty() )
474                 {
475                     log.info( "Found dependencies changes, building" );
476                     shouldBuild = true;
477                 }
478             }
479     
480             // Check changes
481             if ( !shouldBuild && ( ( !allChangesUnknown && !changes.isEmpty() ) ||
482                 project.getExecutorId().equals( ContinuumBuildExecutorConstants.MAVEN_TWO_BUILD_EXECUTOR ) ) )
483             {
484                 shouldBuild = shouldBuild( changes, buildDefinition, project, getMavenProjectVersion( context ),
485                                            getMavenProjectModules( context ) );
486             }
487     
488             if ( shouldBuild )
489             {
490                 log.info( "Changes found in the current project, building" );
491             }
492             else
493             {
494                 log.info( "No changes in the current project, not building" );
495             }
496     
497             return shouldBuild;
498         }
499         catch ( ContinuumStoreException e )
500         {
501             log.error( "Failed to determine if project should build", e );
502         }
503         catch ( ContinuumException e )
504         {
505             log.error( "Failed to determine if project should build", e );
506         }
507     
508         return false;
509     }
510     
511     private boolean shouldBuild( List<ChangeSet> changes, BuildDefinition buildDefinition, Project project,
512                                  String mavenProjectVersion, List<String> mavenProjectModules )
513     {
514         //Check if it's a recursive build
515         boolean isRecursive = false;
516         if ( StringUtils.isNotEmpty( buildDefinition.getArguments() ) )
517         {
518             isRecursive = buildDefinition.getArguments().indexOf( "-N" ) < 0 &&
519                 buildDefinition.getArguments().indexOf( "--non-recursive" ) < 0;
520         }
521     
522         if ( isRecursive && changes != null && !changes.isEmpty() )
523         {
524             if ( log.isInfoEnabled() )
525             {
526                 log.info( "recursive build and changes found --> building" );
527             }
528             return true;
529         }
530     
531         if ( !project.getVersion().equals( mavenProjectVersion ) )
532         {
533             log.info( "Found changes in project's version ( maybe project was recently released ), building" );
534             return true;
535         }
536     
537         if ( changes == null || changes.isEmpty() )
538         {
539             if ( log.isInfoEnabled() )
540             {
541                 log.info( "Found no changes, not building" );
542             }
543             return false;
544         }
545     
546         //check if changes are only in sub-modules or not
547         List<ChangeFile> files = new ArrayList<ChangeFile>();
548         for ( ChangeSet changeSet : changes )
549         {
550             files.addAll( changeSet.getFiles() );
551         }
552     
553         int i = 0;
554         while ( i <= files.size() - 1 )
555         {
556             ChangeFile file = files.get( i );
557             if ( log.isDebugEnabled() )
558             {
559                 log.debug( "changeFile.name " + file.getName() );
560                 log.debug( "check in modules " + mavenProjectModules );
561             }
562             boolean found = false;
563             if ( mavenProjectModules != null )
564             {
565                 for ( String module : mavenProjectModules )
566                 {
567                     if ( file.getName().indexOf( module ) >= 0 )
568                     {
569                         if ( log.isDebugEnabled() )
570                         {
571                             log.debug( "changeFile.name " + file.getName() + " removed because in a module" );
572                         }
573                         files.remove( file );
574                         found = true;
575                         break;
576                     }
577                     if ( log.isDebugEnabled() )
578                     {
579                         log.debug( "not removing file " + file.getName() + " not in module " + module );
580                     }
581                 }
582             }
583             if ( !found )
584             {
585                 i++;
586             }
587         }
588     
589         boolean shouldBuild = !files.isEmpty();
590     
591         if ( !shouldBuild )
592         {
593             log.info( "Changes are only in sub-modules." );
594         }
595     
596         if ( log.isDebugEnabled() )
597         {
598             log.debug( "shoulbuild = " + shouldBuild );
599         }
600     
601         return shouldBuild;
602     }
603     
604     private boolean checkAllChangesUnknown( List<ChangeSet> changes )
605     {
606         for ( ChangeSet changeSet : changes )
607         {
608             List<ChangeFile> changeFiles = changeSet.getFiles();
609     
610             for ( ChangeFile changeFile : changeFiles )
611             {
612                 if ( !"unknown".equalsIgnoreCase( changeFile.getStatus() ) )
613                 {
614                     return false;
615                 }
616             }
617         }
618     
619         return true;
620     }
621     
622 
623     private String getJavaHomeValue( BuildDefinition buildDefinition )
624     {
625         Profile profile = buildDefinition.getProfile();
626         if ( profile == null )
627         {
628             return null;
629         }
630         Installation jdk = profile.getJdk();
631         if ( jdk == null )
632         {
633             return null;
634         }
635         return jdk.getVarValue();
636     }
637     
638     private Map<String, String> getEnvironmentVariables( BuildDefinition buildDefinition )
639     {
640         Profile profile = buildDefinition.getProfile();
641         Map<String, String> envVars = new HashMap<String, String>();
642         if ( profile == null )
643         {
644             return envVars;
645         }
646         List<Installation> environmentVariables = profile.getEnvironmentVariables();
647         if ( environmentVariables.isEmpty() )
648         {
649             return envVars;
650         }
651         for ( Installation installation : environmentVariables )
652         {
653             envVars.put( installation.getVarName(), installation.getVarValue() );
654         }
655         return envVars;
656     }
657 
658     private ProjectDependency getProjectParent( Map<String, Object> context )
659     {
660         Map<String, Object> map = ContinuumBuildConstant.getProjectParent( context );
661     
662         if ( map != null && map.size() > 0 )
663         {
664             ProjectDependency parent = new ProjectDependency();
665             parent.setGroupId( ContinuumBuildConstant.getGroupId( map ) );
666             parent.setArtifactId( ContinuumBuildConstant.getArtifactId( map ) );
667             parent.setVersion( ContinuumBuildConstant.getVersion( map ) );
668     
669             return parent;
670         }
671     
672         return null;
673     }
674     
675     private List<ProjectDependency> getProjectDependencies( Map<String, Object> context )
676     {
677         List<ProjectDependency> projectDependencies = new ArrayList<ProjectDependency>();
678     
679         List<Map<String, Object>> dependencies = ContinuumBuildConstant.getProjectDependencies( context );
680     
681         if ( dependencies != null )
682         {
683             for ( Map<String, Object> map : dependencies )
684             {
685                 ProjectDependency dependency = new ProjectDependency();
686                 dependency.setGroupId( ContinuumBuildConstant.getGroupId( map ) );
687                 dependency.setArtifactId( ContinuumBuildConstant.getArtifactId( map ) );
688                 dependency.setVersion( ContinuumBuildConstant.getVersion( map ) );
689     
690                 projectDependencies.add( dependency );
691             }
692         }
693         return projectDependencies;
694     }
695     
696     private List<ProjectDeveloper> getProjectDevelopers( Map<String, Object> context )
697     {
698         List<ProjectDeveloper> projectDevelopers = new ArrayList<ProjectDeveloper>();
699     
700         List<Map<String, Object>> developers = ContinuumBuildConstant.getProjectDevelopers( context );
701     
702         if ( developers != null )
703         {
704             for ( Map<String, Object> map : developers )
705             {
706                 ProjectDeveloper developer = new ProjectDeveloper();
707                 developer.setName( ContinuumBuildConstant.getDeveloperName( map ) );
708                 developer.setEmail( ContinuumBuildConstant.getDeveloperEmail( map ) );
709                 developer.setScmId( ContinuumBuildConstant.getDeveloperScmId( map ) );
710     
711                 projectDevelopers.add( developer );
712             }
713         }
714         return projectDevelopers;
715     }
716     
717     private List<ProjectNotifier> getProjectNotifiers( Map<String, Object> context )
718     {
719         List<ProjectNotifier> projectNotifiers = new ArrayList<ProjectNotifier>();
720     
721         List<Map<String, Object>> notifiers = ContinuumBuildConstant.getProjectNotifiers( context );
722     
723         if ( notifiers != null )
724         {
725             for ( Map<String, Object> map : notifiers )
726             {
727                 ProjectNotifier notifier = new ProjectNotifier();
728                 notifier.setConfiguration( ContinuumBuildConstant.getNotifierConfiguration( map ) );
729                 notifier.setEnabled( ContinuumBuildConstant.isNotifierEnabled( map ) );
730                 notifier.setFrom( ContinuumBuildConstant.getNotifierFrom( map ) );
731                 notifier.setRecipientType( ContinuumBuildConstant.getNotifierRecipientType( map ) );
732                 notifier.setSendOnError( ContinuumBuildConstant.isNotifierSendOnError( map ) );
733                 notifier.setSendOnFailure( ContinuumBuildConstant.isNotifierSendOnFailure( map ) );
734                 notifier.setSendOnScmFailure( ContinuumBuildConstant.isNotifierSendOnScmFailure( map ) );
735                 notifier.setSendOnSuccess( ContinuumBuildConstant.isNotifierSendOnSuccess( map ) );
736                 notifier.setSendOnWarning( ContinuumBuildConstant.isNotifierSendOnWarning( map ) );
737                 notifier.setType( ContinuumBuildConstant.getNotifierType( map ) );
738     
739                 projectNotifiers.add( notifier );
740             }
741         }
742         return projectNotifiers;
743     }
744 
745     private String getMavenProjectVersion( Map<String, Object> context )
746     {
747         Map<String, Object> map = ContinuumBuildConstant.getMavenProject( context );
748     
749         if ( !map.isEmpty() )
750         {
751             return ContinuumBuildConstant.getVersion( map );
752         }
753     
754         return null;
755     }
756     
757     private List<String> getMavenProjectModules( Map<String, Object> context )
758     {
759         Map<String, Object> map = ContinuumBuildConstant.getMavenProject( context );
760     
761         if ( !map.isEmpty() )
762         {
763             return ContinuumBuildConstant.getProjectModules( map );
764         }
765     
766         return null;
767     }
768 }