View Javadoc

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