1 package org.apache.maven.continuum;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.apache.continuum.buildagent.NoBuildAgentException;
23 import org.apache.continuum.buildagent.NoBuildAgentInGroupException;
24 import org.apache.continuum.builder.distributed.manager.DistributedBuildManager;
25 import org.apache.continuum.buildmanager.BuildManagerException;
26 import org.apache.continuum.buildmanager.BuildsManager;
27 import org.apache.continuum.buildqueue.BuildQueueService;
28 import org.apache.continuum.buildqueue.BuildQueueServiceException;
29 import org.apache.continuum.configuration.BuildAgentConfigurationException;
30 import org.apache.continuum.configuration.ContinuumConfigurationException;
31 import org.apache.continuum.dao.BuildDefinitionDao;
32 import org.apache.continuum.dao.BuildResultDao;
33 import org.apache.continuum.dao.ContinuumReleaseResultDao;
34 import org.apache.continuum.dao.DaoUtils;
35 import org.apache.continuum.dao.NotifierDao;
36 import org.apache.continuum.dao.ProjectDao;
37 import org.apache.continuum.dao.ProjectGroupDao;
38 import org.apache.continuum.dao.ProjectScmRootDao;
39 import org.apache.continuum.dao.ScheduleDao;
40 import org.apache.continuum.model.project.ProjectGroupSummary;
41 import org.apache.continuum.model.project.ProjectScmRoot;
42 import org.apache.continuum.model.release.ContinuumReleaseResult;
43 import org.apache.continuum.purge.ContinuumPurgeManager;
44 import org.apache.continuum.purge.PurgeConfigurationService;
45 import org.apache.continuum.release.config.ContinuumReleaseDescriptor;
46 import org.apache.continuum.release.distributed.manager.DistributedReleaseManager;
47 import org.apache.continuum.release.model.PreparedRelease;
48 import org.apache.continuum.repository.RepositoryService;
49 import org.apache.continuum.taskqueue.manager.TaskQueueManager;
50 import org.apache.continuum.taskqueue.manager.TaskQueueManagerException;
51 import org.apache.continuum.utils.ProjectSorter;
52 import org.apache.continuum.utils.build.BuildTrigger;
53 import org.apache.maven.continuum.build.settings.SchedulesActivationException;
54 import org.apache.maven.continuum.build.settings.SchedulesActivator;
55 import org.apache.maven.continuum.builddefinition.BuildDefinitionService;
56 import org.apache.maven.continuum.builddefinition.BuildDefinitionServiceException;
57 import org.apache.maven.continuum.configuration.ConfigurationException;
58 import org.apache.maven.continuum.configuration.ConfigurationLoadingException;
59 import org.apache.maven.continuum.configuration.ConfigurationService;
60 import org.apache.maven.continuum.core.action.AbstractContinuumAction;
61 import org.apache.maven.continuum.core.action.CheckoutProjectContinuumAction;
62 import org.apache.maven.continuum.core.action.CreateProjectsFromMetadataAction;
63 import org.apache.maven.continuum.core.action.StoreProjectAction;
64 import org.apache.maven.continuum.execution.ContinuumBuildExecutorConstants;
65 import org.apache.maven.continuum.execution.manager.BuildExecutorManager;
66 import org.apache.maven.continuum.initialization.ContinuumInitializationException;
67 import org.apache.maven.continuum.initialization.ContinuumInitializer;
68 import org.apache.maven.continuum.installation.InstallationService;
69 import org.apache.maven.continuum.model.project.BuildDefinition;
70 import org.apache.maven.continuum.model.project.BuildDefinitionTemplate;
71 import org.apache.maven.continuum.model.project.BuildQueue;
72 import org.apache.maven.continuum.model.project.BuildResult;
73 import org.apache.maven.continuum.model.project.Project;
74 import org.apache.maven.continuum.model.project.ProjectGroup;
75 import org.apache.maven.continuum.model.project.ProjectNotifier;
76 import org.apache.maven.continuum.model.project.Schedule;
77 import org.apache.maven.continuum.model.scm.ChangeSet;
78 import org.apache.maven.continuum.model.scm.ScmResult;
79 import org.apache.maven.continuum.profile.ProfileService;
80 import org.apache.maven.continuum.project.ContinuumProjectState;
81 import org.apache.maven.continuum.project.builder.ContinuumProjectBuildingResult;
82 import org.apache.maven.continuum.project.builder.maven.MavenOneContinuumProjectBuilder;
83 import org.apache.maven.continuum.project.builder.maven.MavenTwoContinuumProjectBuilder;
84 import org.apache.maven.continuum.release.ContinuumReleaseException;
85 import org.apache.maven.continuum.release.ContinuumReleaseManager;
86 import org.apache.maven.continuum.store.ContinuumObjectNotFoundException;
87 import org.apache.maven.continuum.store.ContinuumStoreException;
88 import org.apache.maven.continuum.utils.ContinuumUrlValidator;
89 import org.apache.maven.continuum.utils.WorkingDirectoryService;
90 import org.apache.maven.shared.release.ReleaseResult;
91 import org.codehaus.plexus.action.Action;
92 import org.codehaus.plexus.action.ActionManager;
93 import org.codehaus.plexus.action.ActionNotFoundException;
94 import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
95 import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException;
96 import org.codehaus.plexus.personality.plexus.lifecycle.phase.Startable;
97 import org.codehaus.plexus.personality.plexus.lifecycle.phase.StartingException;
98 import org.codehaus.plexus.personality.plexus.lifecycle.phase.StoppingException;
99 import org.codehaus.plexus.util.FileUtils;
100 import org.codehaus.plexus.util.IOUtil;
101 import org.codehaus.plexus.util.StringUtils;
102 import org.slf4j.Logger;
103 import org.slf4j.LoggerFactory;
104 import org.springframework.beans.BeanUtils;
105
106 import java.io.File;
107 import java.io.FileWriter;
108 import java.io.IOException;
109 import java.io.InputStream;
110 import java.io.PrintWriter;
111 import java.util.ArrayList;
112 import java.util.Arrays;
113 import java.util.Collection;
114 import java.util.Collections;
115 import java.util.Date;
116 import java.util.HashMap;
117 import java.util.Iterator;
118 import java.util.List;
119 import java.util.Map;
120 import java.util.Properties;
121 import java.util.regex.Matcher;
122 import java.util.regex.Pattern;
123
124
125
126
127
128
129
130 public class DefaultContinuum
131 implements Continuum, Initializable, Startable
132 {
133 private static final Logger log = LoggerFactory.getLogger( DefaultContinuum.class );
134
135
136
137
138 private ActionManager actionManager;
139
140
141
142
143 private ConfigurationService configurationService;
144
145
146
147
148 private DaoUtils daoUtils;
149
150
151
152
153 private BuildDefinitionDao buildDefinitionDao;
154
155
156
157
158 private BuildResultDao buildResultDao;
159
160
161
162
163 private NotifierDao notifierDao;
164
165
166
167
168 private ProjectDao projectDao;
169
170
171
172
173 private ProjectGroupDao projectGroupDao;
174
175
176
177
178 private ScheduleDao scheduleDao;
179
180
181
182
183 private ContinuumReleaseResultDao releaseResultDao;
184
185
186
187
188 private ProjectScmRootDao projectScmRootDao;
189
190
191
192
193 private ContinuumInitializer initializer;
194
195
196
197
198 private SchedulesActivator schedulesActivator;
199
200
201
202
203 private InstallationService installationService;
204
205
206
207
208 private ProfileService profileService;
209
210
211
212
213 private BuildDefinitionService buildDefinitionService;
214
215
216
217
218
219
220
221
222 private ContinuumReleaseManager releaseManager;
223
224
225
226
227 private WorkingDirectoryService workingDirectoryService;
228
229
230
231
232 private BuildExecutorManager executorManager;
233
234
235
236
237 private ContinuumUrlValidator urlValidator;
238
239 private boolean stopped = false;
240
241
242
243
244 private ContinuumPurgeManager purgeManager;
245
246
247
248
249 private RepositoryService repositoryService;
250
251
252
253
254 private PurgeConfigurationService purgeConfigurationService;
255
256
257
258
259 private TaskQueueManager taskQueueManager;
260
261
262
263
264 private BuildsManager parallelBuildsManager;
265
266
267
268
269 private BuildQueueService buildQueueService;
270
271
272
273
274 private DistributedBuildManager distributedBuildManager;
275
276
277
278
279 private DistributedReleaseManager distributedReleaseManager;
280
281 public DefaultContinuum()
282 {
283 Runtime.getRuntime().addShutdownHook( new Thread()
284 {
285 @Override
286 public void run()
287 {
288 stopContinuum();
289 }
290 } );
291 }
292
293 public ContinuumReleaseManager getReleaseManager()
294 {
295 return releaseManager;
296 }
297
298 public ContinuumPurgeManager getPurgeManager()
299 {
300 return purgeManager;
301 }
302
303 public RepositoryService getRepositoryService()
304 {
305 return repositoryService;
306 }
307
308 public TaskQueueManager getTaskQueueManager()
309 {
310 return taskQueueManager;
311 }
312
313 public PurgeConfigurationService getPurgeConfigurationService()
314 {
315 return purgeConfigurationService;
316 }
317
318 public BuildsManager getBuildsManager()
319 {
320 return parallelBuildsManager;
321 }
322
323 public DistributedReleaseManager getDistributedReleaseManager()
324 {
325 return distributedReleaseManager;
326 }
327
328
329
330
331 public ProjectGroup getProjectGroup( int projectGroupId )
332 throws ContinuumException
333 {
334 try
335 {
336 return projectGroupDao.getProjectGroup( projectGroupId );
337 }
338 catch ( ContinuumObjectNotFoundException e )
339 {
340 throw new ContinuumException( "invalid group id", e );
341 }
342 catch ( ContinuumStoreException e )
343 {
344 throw new ContinuumException( "Error while querying for project group.", e );
345 }
346 }
347
348 public ProjectGroup getProjectGroupWithProjects( int projectGroupId )
349 throws ContinuumException
350 {
351 try
352 {
353 return projectGroupDao.getProjectGroupWithProjects( projectGroupId );
354 }
355 catch ( ContinuumStoreException e )
356 {
357 throw new ContinuumException( "could not find project group containing " + projectGroupId );
358 }
359 }
360
361 public ProjectGroup getProjectGroupByProjectId( int projectId )
362 throws ContinuumException
363 {
364 try
365 {
366 return projectGroupDao.getProjectGroupByProjectId( projectId );
367 }
368 catch ( ContinuumObjectNotFoundException e )
369 {
370 throw new ContinuumException( "could not find project group containing " + projectId );
371 }
372 }
373
374 public void removeProjectGroup( int projectGroupId )
375 throws ContinuumException
376 {
377 ProjectGroup projectGroup = getProjectGroupWithProjects( projectGroupId );
378
379 if ( projectGroup != null )
380 {
381 List<Project> projects = projectGroup.getProjects();
382 int[] projectIds = new int[projects.size()];
383
384 int idx = 0;
385 for ( Project project : projects )
386 {
387 projectIds[idx] = project.getId();
388 idx++;
389 }
390
391
392
393 try
394 {
395 if ( parallelBuildsManager.isAnyProjectCurrentlyBeingCheckedOut( projectIds ) )
396 {
397 throw new ContinuumException(
398 "Unable to delete group. At least one project in group is still being checked out." );
399 }
400
401 if ( parallelBuildsManager.isAnyProjectCurrentlyPreparingBuild( projectIds ) )
402 {
403 throw new ContinuumException(
404 "Unable to delete group. The project group is still preparing build." );
405 }
406
407 if ( parallelBuildsManager.isAnyProjectCurrentlyBuilding( projectIds ) )
408 {
409 throw new ContinuumException(
410 "Unable to delete group. At least one project in group is still building." );
411 }
412
413 if ( isAnyProjectsInReleaseStage( projects ) )
414 {
415 throw new ContinuumException(
416 "Unable to delete group. At least one project in group is in release stage" );
417 }
418 }
419 catch ( BuildManagerException e )
420 {
421 throw new ContinuumException( "Unable to delete group.", e );
422 }
423
424 for ( int projectId : projectIds )
425 {
426 removeProject( projectId );
427 }
428
429
430 List<ProjectScmRoot> scmRoots = getProjectScmRootByProjectGroup( projectGroupId );
431
432 for ( ProjectScmRoot scmRoot : scmRoots )
433 {
434 removeProjectScmRoot( scmRoot );
435 }
436
437 log.info( "Remove project group " + projectGroup.getName() + "(" + projectGroup.getId() + ")" );
438
439 Map<String, Object> context = new HashMap<String, Object>();
440 AbstractContinuumAction.setProjectGroupId( context, projectGroup.getId() );
441 executeAction( "remove-assignable-roles", context );
442
443 projectGroupDao.removeProjectGroup( projectGroup );
444 }
445 }
446
447 public void addProjectGroup( ProjectGroup projectGroup )
448 throws ContinuumException
449 {
450 ProjectGroup pg = null;
451
452 try
453 {
454 pg = projectGroupDao.getProjectGroupByGroupId( projectGroup.getGroupId() );
455 }
456 catch ( ContinuumObjectNotFoundException e )
457 {
458
459
460 }
461 catch ( ContinuumStoreException e )
462 {
463 throw new ContinuumException( "Unable to add the requested project group", e );
464 }
465
466 if ( pg == null )
467 {
468
469 projectGroup.setName( projectGroup.getName().trim() );
470 try
471 {
472 ProjectGroup new_pg = projectGroupDao.addProjectGroup( projectGroup );
473
474 buildDefinitionService.addBuildDefinitionTemplateToProjectGroup( new_pg.getId(),
475 buildDefinitionService.getDefaultMavenTwoBuildDefinitionTemplate() );
476
477 Map<String, Object> context = new HashMap<String, Object>();
478 AbstractContinuumAction.setProjectGroupId( context, new_pg.getId() );
479 executeAction( "add-assignable-roles", context );
480
481 log.info( "Added new project group: " + new_pg.getName() );
482 }
483 catch ( BuildDefinitionServiceException e )
484 {
485 throw new ContinuumException( e.getMessage(), e );
486 }
487 catch ( ContinuumObjectNotFoundException e )
488 {
489 throw new ContinuumException( e.getMessage(), e );
490 }
491
492 }
493 else
494 {
495 throw new ContinuumException( "Unable to add the requested project group: groupId already exists." );
496 }
497
498 }
499
500 public List<ProjectGroup> getAllProjectGroups()
501 {
502 return new ArrayList<ProjectGroup>( projectGroupDao.getAllProjectGroups() );
503 }
504
505 public ProjectGroup getProjectGroupByGroupId( String groupId )
506 throws ContinuumException
507 {
508 try
509 {
510 return projectGroupDao.getProjectGroupByGroupId( groupId );
511 }
512 catch ( ContinuumObjectNotFoundException e )
513 {
514 throw new ContinuumException( "Unable to find project group", e );
515 }
516 catch ( ContinuumStoreException e )
517 {
518 throw new ContinuumException( "Error retrieving", e );
519 }
520 }
521
522 public ProjectGroup getProjectGroupByGroupIdWithBuildDetails( String groupId )
523 throws ContinuumException
524 {
525 try
526 {
527 return projectGroupDao.getProjectGroupByGroupIdWithBuildDetails( groupId );
528 }
529 catch ( ContinuumObjectNotFoundException e )
530 {
531 throw new ContinuumException( "Unable to find project group", e );
532 }
533 catch ( ContinuumStoreException e )
534 {
535 throw new ContinuumException( "Error retrieving", e );
536 }
537 }
538
539 public List<ProjectGroup> getAllProjectGroupsWithRepository( int repositoryId )
540 {
541 return projectGroupDao.getProjectGroupByRepository( repositoryId );
542 }
543
544
545
546
547
548
549
550
551 public Collection<Project> getProjects()
552 throws ContinuumException
553 {
554 return projectDao.getAllProjectsByName();
555 }
556
557
558
559
560 public Collection<Project> getProjectsWithDependencies()
561 throws ContinuumException
562 {
563 return projectDao.getAllProjectsByNameWithDependencies();
564 }
565
566 public Map<Integer, BuildResult> getLatestBuildResults( int projectGroupId )
567 {
568 Map<Integer, BuildResult> result = buildResultDao.getLatestBuildResultsByProjectGroupId( projectGroupId );
569
570 if ( result == null )
571 {
572 result = new HashMap<Integer, BuildResult>();
573 }
574
575 return result;
576 }
577
578 public Map<Integer, BuildResult> getBuildResultsInSuccess( int projectGroupId )
579 {
580 Map<Integer, BuildResult> result = buildResultDao.getBuildResultsInSuccessByProjectGroupId( projectGroupId );
581
582 if ( result == null )
583 {
584 result = new HashMap<Integer, BuildResult>();
585 }
586
587 return result;
588 }
589
590 public BuildResult getLatestBuildResultForProject( int projectId )
591 {
592 return buildResultDao.getLatestBuildResultForProject( projectId );
593 }
594
595 public BuildResult getBuildResultByBuildNumber( int projectId, int buildNumber )
596 throws ContinuumException
597 {
598 List<BuildResult> builds = buildResultDao.getBuildResultByBuildNumber( projectId, buildNumber );
599
600 return ( builds.isEmpty() ? null : builds.get( 0 ) );
601 }
602
603 public List<BuildResult> getBuildResultsInRange( int projectGroupId, Date fromDate, Date toDate, int state,
604 String triggeredBy )
605 {
606 return buildResultDao.getBuildResultsInRange( fromDate, toDate, state, triggeredBy, projectGroupId );
607 }
608
609
610
611
612
613 public void removeProject( int projectId )
614 throws ContinuumException
615 {
616 try
617 {
618 Project project = getProject( projectId );
619
620 try
621 {
622 if ( parallelBuildsManager.isProjectCurrentlyBeingCheckedOut( projectId ) )
623 {
624 throw new ContinuumException(
625 "Unable to remove project " + projectId + " because it is currently being checked out" );
626 }
627
628 if ( parallelBuildsManager.isProjectInAnyCurrentBuild( projectId ) )
629 {
630 throw new ContinuumException(
631 "Unable to remove project " + projectId + " because it is currently building" );
632 }
633 }
634 catch ( BuildManagerException e )
635 {
636 throw new ContinuumException( e.getMessage(), e );
637 }
638
639 if ( isProjectInReleaseStage( project ) )
640 {
641 throw new ContinuumException(
642 "Unable to remove project " + projectId + " because it is in release stage" );
643 }
644
645 try
646 {
647 parallelBuildsManager.removeProjectFromCheckoutQueue( projectId );
648
649 parallelBuildsManager.removeProjectFromBuildQueue( projectId );
650 }
651 catch ( BuildManagerException e )
652 {
653 throw new ContinuumException( e.getMessage(), e );
654 }
655
656 List<ContinuumReleaseResult> releaseResults = releaseResultDao.getContinuumReleaseResultsByProject(
657 projectId );
658
659 ProjectScmRoot scmRoot = getProjectScmRootByProject( projectId );
660
661 try
662 {
663 for ( ContinuumReleaseResult releaseResult : releaseResults )
664 {
665 releaseResultDao.removeContinuumReleaseResult( releaseResult );
666 }
667
668 File releaseOutputDirectory = configurationService.getReleaseOutputDirectory(
669 project.getProjectGroup().getId() );
670
671 if ( releaseOutputDirectory != null )
672 {
673 FileUtils.deleteDirectory( releaseOutputDirectory );
674 }
675 }
676 catch ( ContinuumStoreException e )
677 {
678 throw new ContinuumException( "Error while deleting continuum release result of project group", e );
679 }
680 catch ( IOException e )
681 {
682 throw logAndCreateException( "Error while deleting project group release output directory.", e );
683 }
684
685 log.info( "Remove project " + project.getName() + "(" + projectId + ")" );
686
687
688 project = projectDao.getProjectWithDependencies( projectId );
689 project.setParent( null );
690 project.getDependencies().clear();
691 projectDao.updateProject( project );
692
693 Collection<BuildResult> buildResults = getBuildResultsForProject( projectId );
694
695 for ( BuildResult br : buildResults )
696 {
697 br.setBuildDefinition( null );
698
699 br.getModifiedDependencies().clear();
700 buildResultDao.updateBuildResult( br );
701 removeBuildResult( br );
702 }
703
704 File workingDirectory = getWorkingDirectory( projectId );
705
706 FileUtils.deleteDirectory( workingDirectory );
707
708 File buildOutputDirectory = configurationService.getBuildOutputDirectory( projectId );
709
710 FileUtils.deleteDirectory( buildOutputDirectory );
711
712 projectDao.removeProject( projectDao.getProject( projectId ) );
713
714 removeProjectScmRoot( scmRoot );
715 }
716 catch ( ContinuumStoreException ex )
717 {
718 throw logAndCreateException( "Error while removing project in database.", ex );
719 }
720 catch ( IOException e )
721 {
722 throw logAndCreateException( "Error while deleting project working directory.", e );
723 }
724 }
725
726
727
728
729 public void checkoutProject( int projectId )
730 throws ContinuumException
731 {
732 Map<String, Object> context = new HashMap<String, Object>();
733
734 AbstractContinuumAction.setProjectId( context, projectId );
735
736 try
737 {
738 BuildDefinition buildDefinition = buildDefinitionDao.getDefaultBuildDefinition( projectId );
739 AbstractContinuumAction.setBuildDefinition( context, buildDefinition );
740
741 executeAction( "add-project-to-checkout-queue", context );
742 }
743 catch ( ContinuumStoreException e )
744 {
745 throw new ContinuumException( e.getMessage(), e );
746 }
747 }
748
749 public Project getProject( int projectId )
750 throws ContinuumException
751 {
752 try
753 {
754 return projectDao.getProject( projectId );
755 }
756 catch ( ContinuumStoreException ex )
757 {
758 throw logAndCreateException( "Exception while getting project '" + projectId + "'.", ex );
759 }
760 }
761
762 public Project getProjectWithBuildDetails( int projectId )
763 throws ContinuumException
764 {
765 try
766 {
767 return projectDao.getProjectWithBuildDetails( projectId );
768 }
769 catch ( ContinuumStoreException ex )
770 {
771 throw logAndCreateException( "Exception while getting project '" + projectId + "'.", ex );
772 }
773 }
774
775 public Map<Integer, ProjectGroupSummary> getProjectsSummaryByGroups()
776 {
777 return projectDao.getProjectsSummary();
778 }
779
780
781
782
783
784 public void buildProjects( String username )
785 throws ContinuumException, NoBuildAgentException, NoBuildAgentInGroupException
786 {
787 buildProjects( new BuildTrigger( ContinuumProjectState.TRIGGER_FORCED, username ) );
788 }
789
790 public void buildProjectsWithBuildDefinition( List<Project> projects, List<BuildDefinition> bds )
791 throws ContinuumException, NoBuildAgentException, NoBuildAgentInGroupException
792 {
793 Collection<Project> filteredProjectsList = getProjectsNotInReleaseStage( projects );
794
795 prepareBuildProjects( filteredProjectsList, bds, true, new BuildTrigger( ContinuumProjectState.TRIGGER_FORCED,
796 "" ) );
797 }
798
799 public void buildProjectsWithBuildDefinition( List<Project> projects, int buildDefinitionId )
800 throws ContinuumException, NoBuildAgentException, NoBuildAgentInGroupException
801 {
802 Collection<Project> filteredProjectsList = getProjectsNotInReleaseStage( projects );
803
804 prepareBuildProjects( filteredProjectsList, buildDefinitionId, new BuildTrigger(
805 ContinuumProjectState.TRIGGER_FORCED, "" ) );
806 }
807
808
809
810
811
812
813
814
815 public void buildProjects( BuildTrigger buildTrigger )
816 throws ContinuumException, NoBuildAgentException, NoBuildAgentInGroupException
817 {
818 Collection<Project> projectsList = getProjectsInBuildOrder();
819
820 Collection<Project> filteredProjectsList = getProjectsNotInReleaseStage( projectsList );
821
822 prepareBuildProjects( filteredProjectsList, null, true, buildTrigger );
823 }
824
825
826
827
828
829
830
831
832 public void buildProjectGroup( int projectGroupId, BuildTrigger buildTrigger )
833 throws ContinuumException, NoBuildAgentException, NoBuildAgentInGroupException
834 {
835 List<BuildDefinition> groupDefaultBDs;
836
837 if ( !isAnyProjectInGroupInReleaseStage( projectGroupId ) )
838 {
839 groupDefaultBDs = getDefaultBuildDefinitionsForProjectGroup( projectGroupId );
840
841 buildProjectGroupWithBuildDefinition( projectGroupId, groupDefaultBDs, true, buildTrigger );
842 }
843 }
844
845
846
847
848
849
850
851
852
853 public void buildProjectGroupWithBuildDefinition( int projectGroupId, int buildDefinitionId,
854 BuildTrigger buildTrigger )
855 throws ContinuumException, NoBuildAgentException, NoBuildAgentInGroupException
856 {
857 if ( !isAnyProjectInGroupInReleaseStage( projectGroupId ) )
858 {
859 List<BuildDefinition> bds = new ArrayList<BuildDefinition>();
860 BuildDefinition bd = getBuildDefinition( buildDefinitionId );
861 if ( bd != null )
862 {
863 bds.add( bd );
864 }
865 buildProjectGroupWithBuildDefinition( projectGroupId, bds, false, buildTrigger );
866 }
867 }
868
869
870
871
872
873
874
875
876
877
878
879 private void buildProjectGroupWithBuildDefinition( int projectGroupId, List<BuildDefinition> bds,
880 boolean checkDefaultBuildDefinitionForProject,
881 BuildTrigger buildTrigger )
882 throws ContinuumException, NoBuildAgentException, NoBuildAgentInGroupException
883 {
884 if ( !isAnyProjectInGroupInReleaseStage( projectGroupId ) )
885 {
886 Collection<Project> projectsList;
887
888 projectsList = getProjectsInBuildOrder( projectDao.getProjectsWithDependenciesByGroupId( projectGroupId ) );
889
890 buildTrigger.setTrigger( ContinuumProjectState.TRIGGER_FORCED );
891
892 prepareBuildProjects( projectsList, bds, checkDefaultBuildDefinitionForProject, buildTrigger );
893 }
894 }
895
896
897
898
899
900
901
902
903
904 public void buildProjects( Schedule schedule )
905 throws ContinuumException
906 {
907 Collection<Project> projectsList;
908
909 Map<Integer, Object> projectsMap;
910
911 try
912 {
913 projectsMap = daoUtils.getAggregatedProjectIdsAndBuildDefinitionIdsBySchedule( schedule.getId() );
914
915 if ( projectsMap == null || projectsMap.size() == 0 )
916 {
917 log.debug( "no builds attached to schedule" );
918 try
919 {
920 schedulesActivator.unactivateOrphanBuildSchedule( schedule );
921 }
922 catch ( SchedulesActivationException e )
923 {
924 log.debug( "Can't unactivate orphan shcedule for buildDefinitions" );
925 }
926
927
928 return;
929 }
930
931
932
933 projectsList = getProjectsInBuildOrder();
934 }
935 catch ( ContinuumStoreException e )
936 {
937 throw new ContinuumException( "Can't get project list for schedule " + schedule.getName(), e );
938 }
939
940 Map<ProjectScmRoot, Map<Integer, Integer>> map = new HashMap<ProjectScmRoot, Map<Integer, Integer>>();
941 List<ProjectScmRoot> sortedScmRoot = new ArrayList<ProjectScmRoot>();
942
943 for ( Project project : projectsList )
944 {
945 List<Integer> buildDefIds = (List<Integer>) projectsMap.get( project.getId() );
946 int projectId = project.getId();
947
948 if ( buildDefIds != null && !buildDefIds.isEmpty() )
949 {
950 for ( Integer buildDefId : buildDefIds )
951 {
952 if ( isProjectOkToBuild( project.getId(), buildDefId ) )
953 {
954 ProjectScmRoot scmRoot = getProjectScmRootByProject( project.getId() );
955
956 Map<Integer, Integer> projectsAndBuildDefinitionsMap = map.get( scmRoot );
957
958 if ( projectsAndBuildDefinitionsMap == null )
959 {
960 projectsAndBuildDefinitionsMap = new HashMap<Integer, Integer>();
961 }
962
963 projectsAndBuildDefinitionsMap.put( projectId, buildDefId );
964
965 map.put( scmRoot, projectsAndBuildDefinitionsMap );
966
967 if ( !sortedScmRoot.contains( scmRoot ) )
968 {
969 sortedScmRoot.add( scmRoot );
970 }
971 }
972 else
973 {
974 log.info(
975 "Not queueing the build with projectId={} and buildDefinitionId={} because it is already building",
976 projectId, buildDefId );
977 }
978 }
979 }
980 }
981
982 BuildTrigger buildTrigger = new BuildTrigger( ContinuumProjectState.TRIGGER_SCHEDULED, schedule.getName() );
983
984 for ( ProjectScmRoot scmRoot : sortedScmRoot )
985 {
986 try
987 {
988 prepareBuildProjects( map.get( scmRoot ), buildTrigger, scmRoot.getScmRootAddress(),
989 scmRoot.getProjectGroup().getId(), scmRoot.getId(), sortedScmRoot );
990 }
991 catch ( NoBuildAgentException e )
992 {
993 log.error( "Unable to build projects in project group " + scmRoot.getProjectGroup().getName() +
994 " because there is no build agent configured" );
995 }
996 catch ( NoBuildAgentInGroupException e )
997 {
998 log.error( "Unable to build projects in project group " + scmRoot.getProjectGroup().getName() +
999 " because there is no build agent configured in build agent group" );
1000 }
1001 }
1002 }
1003
1004 public void buildProject( int projectId, String username )
1005 throws ContinuumException, NoBuildAgentException, NoBuildAgentInGroupException
1006 {
1007 buildProject( projectId, new BuildTrigger( ContinuumProjectState.TRIGGER_FORCED, username ) );
1008 }
1009
1010 public void buildProjectWithBuildDefinition( int projectId, int buildDefinitionId, BuildTrigger buildTrigger )
1011 throws ContinuumException, NoBuildAgentException, NoBuildAgentInGroupException
1012 {
1013 buildTrigger.setTrigger( ContinuumProjectState.TRIGGER_FORCED );
1014 buildProject( projectId, buildDefinitionId, buildTrigger );
1015 }
1016
1017 public void buildProject( int projectId, BuildTrigger buildTrigger )
1018 throws ContinuumException, NoBuildAgentException, NoBuildAgentInGroupException
1019 {
1020 Project project = getProject( projectId );
1021 if ( isProjectInReleaseStage( project ) )
1022 {
1023 throw new ContinuumException( "Project (id=" + projectId + ") is currently in release stage." );
1024 }
1025
1026 BuildDefinition buildDef = getDefaultBuildDefinition( projectId );
1027
1028 if ( buildDef == null )
1029 {
1030 throw new ContinuumException( "Project (id=" + projectId + ") doesn't have a default build definition." );
1031 }
1032
1033 if ( !isProjectOkToBuild( projectId, buildDef.getId() ) )
1034 {
1035 log.info(
1036 "Not queueing the build with projectId={} and buildDefinitionId={} because it is already building",
1037 projectId, buildDef.getId() );
1038 return;
1039 }
1040
1041 Map<Integer, Integer> projectsBuildDefinitionsMap = new HashMap<Integer, Integer>();
1042 projectsBuildDefinitionsMap.put( projectId, buildDef.getId() );
1043
1044 ProjectScmRoot scmRoot = getProjectScmRootByProject( projectId );
1045 List<ProjectScmRoot> sortedScmRoot = new ArrayList<ProjectScmRoot>();
1046 sortedScmRoot.add( scmRoot );
1047
1048 prepareBuildProjects( projectsBuildDefinitionsMap, buildTrigger, scmRoot.getScmRootAddress(),
1049 scmRoot.getProjectGroup().getId(), scmRoot.getId(), sortedScmRoot );
1050 }
1051
1052 public void buildProject( int projectId, int buildDefinitionId, BuildTrigger buildTrigger )
1053 throws ContinuumException, NoBuildAgentException, NoBuildAgentInGroupException
1054 {
1055 Project project = getProject( projectId );
1056 if ( isProjectInReleaseStage( project ) )
1057 {
1058 throw new ContinuumException( "Project (id=" + projectId + ") is currently in release stage." );
1059 }
1060
1061 if ( !isProjectOkToBuild( projectId, buildDefinitionId ) )
1062 {
1063 log.info(
1064 "Not queueing the build with projectId={} and buildDefinitionId={} because it is already building",
1065 projectId, buildDefinitionId );
1066 return;
1067 }
1068
1069 Map<Integer, Integer> projectsBuildDefinitionsMap = new HashMap<Integer, Integer>();
1070 projectsBuildDefinitionsMap.put( projectId, buildDefinitionId );
1071
1072 ProjectScmRoot scmRoot = getProjectScmRootByProject( projectId );
1073 List<ProjectScmRoot> sortedScmRoot = new ArrayList<ProjectScmRoot>();
1074 sortedScmRoot.add( scmRoot );
1075
1076 prepareBuildProjects( projectsBuildDefinitionsMap, buildTrigger, scmRoot.getScmRootAddress(),
1077 scmRoot.getProjectGroup().getId(), scmRoot.getId(), sortedScmRoot );
1078 }
1079
1080 public BuildResult getBuildResult( int buildId )
1081 throws ContinuumException
1082 {
1083 try
1084 {
1085 return buildResultDao.getBuildResult( buildId );
1086 }
1087 catch ( ContinuumStoreException e )
1088 {
1089 throw logAndCreateException( "Exception while getting build result for project.", e );
1090 }
1091 }
1092
1093 public void removeBuildResult( int buildId )
1094 throws ContinuumException
1095 {
1096 BuildResult buildResult = getBuildResult( buildId );
1097
1098
1099 Project project = buildResult.getProject();
1100 BuildResult bResult = getLatestBuildResultForProject( project.getId() );
1101
1102 try
1103 {
1104 if ( bResult != null && buildResult.getId() == bResult.getId() &&
1105 parallelBuildsManager.isProjectInAnyCurrentBuild( project.getId() ) )
1106 {
1107 throw new ContinuumException(
1108 "Unable to remove build result because it is currently being used by" + "a building project " +
1109 project.getId() );
1110 }
1111 }
1112 catch ( BuildManagerException e )
1113 {
1114 throw new ContinuumException( e.getMessage(), e );
1115 }
1116
1117 buildResult.getModifiedDependencies().clear();
1118 buildResult.setBuildDefinition( null );
1119
1120 try
1121 {
1122 buildResultDao.updateBuildResult( buildResult );
1123 }
1124 catch ( ContinuumStoreException e )
1125 {
1126 throw logAndCreateException( "Error while removing build result in database.", e );
1127 }
1128 removeBuildResult( buildResult );
1129 }
1130
1131
1132 private void removeBuildResult( BuildResult buildResult )
1133 {
1134 buildResultDao.removeBuildResult( buildResult );
1135
1136
1137 try
1138 {
1139 File buildOutputDirectory = getConfiguration().getBuildOutputDirectory( buildResult.getProject().getId() );
1140 File buildDirectory = new File( buildOutputDirectory, Integer.toString( buildResult.getId() ) );
1141
1142 if ( buildDirectory.exists() )
1143 {
1144 FileUtils.deleteDirectory( buildDirectory );
1145 }
1146 File buildOutputFile = getConfiguration().getBuildOutputFile( buildResult.getId(),
1147 buildResult.getProject().getId() );
1148 if ( buildOutputFile.exists() )
1149 {
1150 FileUtils.forceDelete( buildOutputFile );
1151 }
1152 }
1153 catch ( ConfigurationException e )
1154 {
1155 log.info( "skip error during cleanup build files " + e.getMessage(), e );
1156 }
1157 catch ( IOException e )
1158 {
1159 log.info( "skip IOException during cleanup build files " + e.getMessage(), e );
1160 }
1161
1162 }
1163
1164 public String getBuildOutput( int projectId, int buildId )
1165 throws ContinuumException
1166 {
1167 try
1168 {
1169 return configurationService.getBuildOutput( buildId, projectId );
1170 }
1171 catch ( ConfigurationException e )
1172 {
1173 throw logAndCreateException( "Exception while getting build result for project.", e );
1174 }
1175 }
1176
1177
1178
1179
1180 public List<ChangeSet> getChangesSinceLastSuccess( int projectId, int buildResultId )
1181 throws ContinuumException
1182 {
1183 BuildResult previousBuildResult = null;
1184 try
1185 {
1186 previousBuildResult = buildResultDao.getPreviousBuildResultInSuccess( projectId, buildResultId );
1187 }
1188 catch ( ContinuumStoreException e )
1189 {
1190
1191 }
1192 long startTime = previousBuildResult == null ? 0 : previousBuildResult.getStartTime();
1193 ArrayList<BuildResult> buildResults = new ArrayList<BuildResult>(
1194 buildResultDao.getBuildResultsForProjectWithDetails( projectId, startTime, buildResultId ) );
1195
1196 Collections.reverse( buildResults );
1197
1198 Iterator<BuildResult> buildResultsIterator = buildResults.iterator();
1199
1200 boolean stop = false;
1201
1202
1203 while ( !stop )
1204 {
1205 if ( buildResultsIterator.hasNext() )
1206 {
1207 BuildResult buildResult = buildResultsIterator.next();
1208
1209 if ( buildResult.getId() == buildResultId )
1210 {
1211 stop = true;
1212 }
1213 }
1214 else
1215 {
1216 stop = true;
1217 }
1218 }
1219
1220 if ( !buildResultsIterator.hasNext() )
1221 {
1222 return null;
1223 }
1224
1225 BuildResult buildResult = buildResultsIterator.next();
1226
1227 List<ChangeSet> changes = null;
1228
1229 while ( buildResult.getState() != ContinuumProjectState.OK )
1230 {
1231 if ( changes == null )
1232 {
1233 changes = new ArrayList<ChangeSet>();
1234 }
1235
1236 ScmResult scmResult = buildResult.getScmResult();
1237
1238 if ( scmResult != null )
1239 {
1240 changes.addAll( scmResult.getChanges() );
1241 }
1242
1243 if ( !buildResultsIterator.hasNext() )
1244 {
1245 return changes;
1246 }
1247
1248 buildResult = buildResultsIterator.next();
1249 }
1250
1251 if ( changes == null )
1252 {
1253 changes = Collections.EMPTY_LIST;
1254 }
1255
1256 return changes;
1257 }
1258
1259
1260
1261
1262
1263
1264
1265
1266 private List<Project> getProjectsInBuildOrder()
1267 throws ContinuumException
1268 {
1269 return getProjectsInBuildOrder( getProjectsWithDependencies() );
1270 }
1271
1272
1273
1274
1275
1276
1277
1278 public List<Project> getProjectsInBuildOrder( Collection<Project> projects )
1279 {
1280 if ( projects == null || projects.isEmpty() )
1281 {
1282 return new ArrayList<Project>();
1283 }
1284
1285 return ProjectSorter.getSortedProjects( projects, log );
1286 }
1287
1288
1289
1290
1291
1292 public ContinuumProjectBuildingResult addMavenOneProject( String metadataUrl, int projectGroupId )
1293 throws ContinuumException
1294 {
1295 return addMavenOneProject( metadataUrl, projectGroupId, true );
1296 }
1297
1298 public ContinuumProjectBuildingResult addMavenOneProject( String metadataUrl, int projectGroupId,
1299 boolean checkProtocol )
1300 throws ContinuumException
1301 {
1302 return addMavenOneProject( metadataUrl, projectGroupId, checkProtocol, false );
1303 }
1304
1305 public ContinuumProjectBuildingResult addMavenOneProject( String metadataUrl, int projectGroupId,
1306 boolean checkProtocol, boolean useCredentialsCache )
1307 throws ContinuumException
1308 {
1309 try
1310 {
1311 return addMavenOneProject( metadataUrl, projectGroupId, checkProtocol, useCredentialsCache,
1312 buildDefinitionService.getDefaultMavenOneBuildDefinitionTemplate().getId() );
1313 }
1314 catch ( BuildDefinitionServiceException e )
1315 {
1316 throw new ContinuumException( e.getMessage(), e );
1317 }
1318 }
1319
1320 public ContinuumProjectBuildingResult addMavenOneProject( String metadataUrl, int projectGroupId,
1321 boolean checkProtocol, boolean useCredentialsCache,
1322 int buildDefinitionTemplateId )
1323 throws ContinuumException
1324 {
1325 return executeAddProjectsFromMetadataActivity( metadataUrl, MavenOneContinuumProjectBuilder.ID, projectGroupId,
1326 checkProtocol, useCredentialsCache, true,
1327 buildDefinitionTemplateId, false );
1328 }
1329
1330
1331
1332
1333
1334 public ContinuumProjectBuildingResult addMavenTwoProject( String metadataUrl )
1335 throws ContinuumException
1336 {
1337 return addMavenTwoProject( metadataUrl, true );
1338 }
1339
1340 public ContinuumProjectBuildingResult addMavenTwoProject( String metadataUrl, boolean checkProtocol )
1341 throws ContinuumException
1342 {
1343 try
1344 {
1345 return executeAddProjectsFromMetadataActivity( metadataUrl, MavenTwoContinuumProjectBuilder.ID, -1,
1346 checkProtocol,
1347 buildDefinitionService.getDefaultMavenTwoBuildDefinitionTemplate().getId() );
1348 }
1349 catch ( BuildDefinitionServiceException e )
1350 {
1351 throw new ContinuumException( e.getMessage(), e );
1352 }
1353 }
1354
1355 public ContinuumProjectBuildingResult addMavenTwoProject( String metadataUrl, int projectGroupId )
1356 throws ContinuumException
1357 {
1358 return addMavenTwoProject( metadataUrl, projectGroupId, true );
1359 }
1360
1361 public ContinuumProjectBuildingResult addMavenTwoProject( String metadataUrl, int projectGroupId,
1362 boolean checkProtocol )
1363 throws ContinuumException
1364 {
1365 return addMavenTwoProject( metadataUrl, projectGroupId, checkProtocol, false );
1366 }
1367
1368 public ContinuumProjectBuildingResult addMavenTwoProject( String metadataUrl, int projectGroupId,
1369 boolean checkProtocol, boolean useCredentialsCache )
1370 throws ContinuumException
1371 {
1372 try
1373 {
1374 return executeAddProjectsFromMetadataActivity( metadataUrl, MavenTwoContinuumProjectBuilder.ID,
1375 projectGroupId, checkProtocol, useCredentialsCache, true,
1376 buildDefinitionService.getDefaultMavenTwoBuildDefinitionTemplate().getId(),
1377 false );
1378 }
1379 catch ( BuildDefinitionServiceException e )
1380 {
1381 throw new ContinuumException( e.getMessage(), e );
1382 }
1383 }
1384
1385 public ContinuumProjectBuildingResult addMavenTwoProject( String metadataUrl, int projectGroupId,
1386 boolean checkProtocol, boolean useCredentialsCache,
1387 boolean recursiveProjects )
1388 throws ContinuumException
1389 {
1390 try
1391 {
1392 return executeAddProjectsFromMetadataActivity( metadataUrl, MavenTwoContinuumProjectBuilder.ID,
1393 projectGroupId, checkProtocol, useCredentialsCache,
1394 recursiveProjects,
1395 buildDefinitionService.getDefaultMavenTwoBuildDefinitionTemplate().getId(),
1396 false );
1397 }
1398 catch ( BuildDefinitionServiceException e )
1399 {
1400 throw new ContinuumException( e.getMessage(), e );
1401 }
1402 }
1403
1404 public ContinuumProjectBuildingResult addMavenTwoProject( String metadataUrl, int projectGroupId,
1405 boolean checkProtocol, boolean useCredentialsCache,
1406 boolean recursiveProjects, int buildDefinitionTemplateId,
1407 boolean checkoutInSingleDirectory )
1408 throws ContinuumException
1409 {
1410 return executeAddProjectsFromMetadataActivity( metadataUrl, MavenTwoContinuumProjectBuilder.ID, projectGroupId,
1411 checkProtocol, useCredentialsCache, recursiveProjects,
1412 buildDefinitionTemplateId, checkoutInSingleDirectory );
1413 }
1414
1415
1416
1417
1418
1419 public int addProject( Project project, String executorId, int groupId )
1420 throws ContinuumException
1421 {
1422 return addProject( project, executorId, groupId, -1 );
1423 }
1424
1425
1426
1427
1428 public int addProject( Project project, String executorId, int groupId, int buildDefinitionTemplateId )
1429 throws ContinuumException
1430 {
1431 project.setExecutorId( executorId );
1432
1433 return executeAddProjectFromScmActivity( project, groupId, buildDefinitionTemplateId );
1434 }
1435
1436
1437
1438
1439
1440 private int executeAddProjectFromScmActivity( Project project, int groupId, int buildDefinitionTemplateId )
1441 throws ContinuumException
1442 {
1443 String executorId = project.getExecutorId();
1444
1445 ProjectGroup projectGroup = getProjectGroupWithBuildDetails( groupId );
1446
1447 Map<String, Object> context = new HashMap<String, Object>();
1448
1449 String scmUrl = project.getScmUrl();
1450
1451 List<ProjectScmRoot> scmRoots = getProjectScmRootByProjectGroup( groupId );
1452
1453 boolean found = false;
1454
1455 for ( ProjectScmRoot scmRoot : scmRoots )
1456 {
1457 if ( scmUrl.startsWith( scmRoot.getScmRootAddress() ) )
1458 {
1459 found = true;
1460 break;
1461 }
1462 }
1463
1464 if ( !found )
1465 {
1466 createProjectScmRoot( projectGroup, scmUrl );
1467 }
1468
1469
1470
1471
1472
1473 AbstractContinuumAction.setWorkingDirectory( context, getWorkingDirectory() );
1474
1475 AbstractContinuumAction.setUnvalidatedProject( context, project );
1476
1477 AbstractContinuumAction.setUnvalidatedProjectGroup( context, projectGroup );
1478
1479 AbstractContinuumAction.setProjectGroupId( context, projectGroup.getId() );
1480
1481 StoreProjectAction.setUseScmCredentialsCache( context, project.isScmUseCache() );
1482
1483
1484 String scmUsername = project.getScmUsername();
1485 String scmPassword = project.getScmPassword();
1486
1487 if ( scmUsername != null && !StringUtils.isEmpty( scmUsername ) )
1488 {
1489 CheckoutProjectContinuumAction.setScmUsername( context, scmUsername );
1490 }
1491
1492 if ( scmPassword != null && !StringUtils.isEmpty( scmPassword ) )
1493 {
1494 CheckoutProjectContinuumAction.setScmPassword( context, scmPassword );
1495 }
1496
1497 executeAction( "validate-project", context );
1498
1499 executeAction( "store-project", context );
1500
1501 try
1502 {
1503 BuildDefinitionTemplate bdt;
1504
1505 if ( executorId.equalsIgnoreCase( ContinuumBuildExecutorConstants.ANT_BUILD_EXECUTOR ) )
1506 {
1507 if ( buildDefinitionTemplateId <= 0 )
1508 {
1509 bdt = buildDefinitionService.getDefaultAntBuildDefinitionTemplate();
1510 }
1511 else
1512 {
1513 bdt = buildDefinitionService.getBuildDefinitionTemplate( buildDefinitionTemplateId );
1514 }
1515 }
1516 else
1517 {
1518
1519 if ( buildDefinitionTemplateId <= 0 )
1520 {
1521 bdt = buildDefinitionService.getDefaultShellBuildDefinitionTemplate();
1522 }
1523 else
1524 {
1525 bdt = buildDefinitionService.getBuildDefinitionTemplate( buildDefinitionTemplateId );
1526 }
1527 }
1528
1529 buildDefinitionService.addTemplateInProject( bdt.getId(), getProject( AbstractContinuumAction.getProjectId(
1530 context ) ) );
1531 }
1532 catch ( BuildDefinitionServiceException e )
1533 {
1534 throw new ContinuumException( e.getMessage(), e );
1535 }
1536
1537 if ( !configurationService.isDistributedBuildEnabled() )
1538 {
1539
1540 BuildDefinition bd = (BuildDefinition) getProjectWithBuildDetails( AbstractContinuumAction.getProjectId(
1541 context ) ).getBuildDefinitions().get( 0 );
1542 AbstractContinuumAction.setBuildDefinition( context, bd );
1543
1544 executeAction( "add-project-to-checkout-queue", context );
1545 }
1546
1547 executeAction( "add-assignable-roles", context );
1548
1549 return AbstractContinuumAction.getProjectId( context );
1550 }
1551
1552 private ContinuumProjectBuildingResult executeAddProjectsFromMetadataActivity( String metadataUrl,
1553 String projectBuilderId,
1554 int projectGroupId,
1555 boolean checkProtocol,
1556 int buildDefinitionTemplateId )
1557 throws ContinuumException
1558 {
1559 return executeAddProjectsFromMetadataActivity( metadataUrl, projectBuilderId, projectGroupId, checkProtocol,
1560 false, false, buildDefinitionTemplateId, false );
1561 }
1562
1563
1564 protected ContinuumProjectBuildingResult executeAddProjectsFromMetadataActivity( String metadataUrl,
1565 String projectBuilderId,
1566 int projectGroupId,
1567 boolean checkProtocol,
1568 boolean useCredentialsCache,
1569 boolean loadRecursiveProjects,
1570 int buildDefinitionTemplateId,
1571 boolean addAssignableRoles,
1572 boolean checkoutInSingleDirectory )
1573 throws ContinuumException
1574 {
1575 if ( checkProtocol )
1576 {
1577 if ( !urlValidator.validate( metadataUrl ) )
1578 {
1579 ContinuumProjectBuildingResult res = new ContinuumProjectBuildingResult();
1580 res.addError( ContinuumProjectBuildingResult.ERROR_PROTOCOL_NOT_ALLOWED );
1581 return res;
1582 }
1583 }
1584
1585 Map<String, Object> context = new HashMap<String, Object>();
1586
1587 CreateProjectsFromMetadataAction.setProjectBuilderId( context, projectBuilderId );
1588
1589 CreateProjectsFromMetadataAction.setUrl( context, metadataUrl );
1590
1591 CreateProjectsFromMetadataAction.setLoadRecursiveProject( context, loadRecursiveProjects );
1592
1593 StoreProjectAction.setUseScmCredentialsCache( context, useCredentialsCache );
1594
1595 AbstractContinuumAction.setWorkingDirectory( context, getWorkingDirectory() );
1596
1597 CreateProjectsFromMetadataAction.setCheckoutProjectsInSingleDirectory( context, checkoutInSingleDirectory );
1598
1599
1600 if ( buildDefinitionTemplateId > 0 )
1601 {
1602 try
1603 {
1604 AbstractContinuumAction.setBuildDefinitionTemplate( context,
1605 buildDefinitionService.getBuildDefinitionTemplate(
1606 buildDefinitionTemplateId ) );
1607 }
1608 catch ( BuildDefinitionServiceException e )
1609 {
1610 throw new ContinuumException( e.getMessage(), e );
1611 }
1612 }
1613
1614
1615
1616
1617 ProjectGroup projectGroup;
1618
1619 if ( projectGroupId != -1 )
1620 {
1621 CreateProjectsFromMetadataAction.setProjectGroupId( context, projectGroupId );
1622 }
1623
1624 executeAction( "create-projects-from-metadata", context );
1625
1626 ContinuumProjectBuildingResult result = CreateProjectsFromMetadataAction.getProjectBuildingResult( context );
1627
1628 if ( log.isInfoEnabled() )
1629 {
1630 if ( result.getProjects() != null )
1631 {
1632 log.info( "Created " + result.getProjects().size() + " projects." );
1633 }
1634 if ( result.getProjectGroups() != null )
1635 {
1636 log.info( "Created " + result.getProjectGroups().size() + " project groups." );
1637 }
1638 log.info( result.getErrors().size() + " errors." );
1639
1640
1641
1642
1643
1644 if ( result.hasErrors() )
1645 {
1646 log.info( result.getErrors().size() + " errors during project add: " );
1647 log.info( result.getErrorsAsString() );
1648 return result;
1649 }
1650 }
1651
1652
1653
1654
1655
1656
1657 if ( result.getProjectGroups().size() != 1 )
1658 {
1659 throw new ContinuumException( "The project building result has to contain exactly one project group." );
1660 }
1661
1662 boolean projectGroupCreation = false;
1663
1664 try
1665 {
1666 if ( projectGroupId == -1 )
1667 {
1668 projectGroup = result.getProjectGroups().iterator().next();
1669
1670 try
1671 {
1672 projectGroup = projectGroupDao.getProjectGroupByGroupId( projectGroup.getGroupId() );
1673
1674 projectGroupId = projectGroup.getId();
1675
1676 log.info( "Using existing project group with the group id: '" + projectGroup.getGroupId() + "'." );
1677 }
1678 catch ( ContinuumObjectNotFoundException e )
1679 {
1680 log.info( "Creating project group with the group id: '" + projectGroup.getGroupId() + "'." );
1681
1682 Map<String, Object> pgContext = new HashMap<String, Object>();
1683
1684 AbstractContinuumAction.setWorkingDirectory( pgContext, getWorkingDirectory() );
1685
1686 AbstractContinuumAction.setUnvalidatedProjectGroup( pgContext, projectGroup );
1687
1688 executeAction( "validate-project-group", pgContext );
1689
1690 executeAction( "store-project-group", pgContext );
1691
1692 projectGroupId = AbstractContinuumAction.getProjectGroupId( pgContext );
1693
1694 projectGroupCreation = true;
1695 }
1696 }
1697
1698 projectGroup = projectGroupDao.getProjectGroupWithBuildDetailsByProjectGroupId( projectGroupId );
1699
1700
1701 String url = AbstractContinuumAction.getProjectScmRootUrl( context, null );
1702
1703 List<ProjectScmRoot> scmRoots = getProjectScmRootByProjectGroup( projectGroup.getId() );
1704
1705 boolean found = false;
1706
1707 for ( ProjectScmRoot scmRoot : scmRoots )
1708 {
1709 if ( url.startsWith( scmRoot.getScmRootAddress() ) )
1710 {
1711 found = true;
1712 break;
1713 }
1714 }
1715
1716 if ( !found )
1717 {
1718 createProjectScmRoot( projectGroup, url );
1719 }
1720
1721
1722 result.getProjectGroups().remove( 0 );
1723 result.getProjectGroups().add( projectGroup );
1724 }
1725 catch ( ContinuumStoreException e )
1726 {
1727 throw new ContinuumException( "Error while querying for project group.", e );
1728 }
1729
1730
1731
1732
1733
1734
1735 List<Project> projects = result.getProjects();
1736
1737 String scmUserName = null;
1738 String scmPassword = null;
1739
1740 for ( Project project : projects )
1741 {
1742 checkForDuplicateProjectInGroup( projectGroup, project, result );
1743
1744 if ( result.hasErrors() )
1745 {
1746 log.info( result.getErrors().size() + " errors during project add: " );
1747 log.info( result.getErrorsAsString() );
1748 return result;
1749 }
1750
1751 project.setScmUseCache( useCredentialsCache );
1752
1753
1754 scmUserName = project.getScmUsername();
1755 scmPassword = project.getScmPassword();
1756
1757 if ( useCredentialsCache )
1758 {
1759 project.setScmUsername( null );
1760 project.setScmPassword( null );
1761 }
1762
1763 projectGroup.addProject( project );
1764 }
1765
1766 try
1767 {
1768 projectGroupDao.updateProjectGroup( projectGroup );
1769
1770 if ( !checkoutInSingleDirectory )
1771 {
1772 for ( Project project : projects )
1773 {
1774 context = new HashMap<String, Object>();
1775
1776 Project fetchedProject = projectDao.getProjectWithBuildDetails( project.getId() );
1777
1778 addProjectToCheckoutQueue( projectBuilderId, buildDefinitionTemplateId, context,
1779 projectGroupCreation, scmUserName, scmPassword, project,
1780 isDefaultProjectBuildDefSet( fetchedProject ) );
1781 }
1782 }
1783 else
1784 {
1785 Project project = result.getRootProject();
1786
1787 if ( project != null )
1788 {
1789 String scmRootUrl = AbstractContinuumAction.getProjectScmRootUrl( context, null );
1790 context = new HashMap<String, Object>();
1791
1792 AbstractContinuumAction.setProjectScmRootUrl( context, scmRootUrl );
1793
1794 List<Project> projectsWithSimilarScmRoot = new ArrayList<Project>();
1795 for ( Project projectWithSimilarScmRoot : projects )
1796 {
1797 projectsWithSimilarScmRoot.add( projectWithSimilarScmRoot );
1798 }
1799
1800 AbstractContinuumAction.setListOfProjectsInGroupWithCommonScmRoot( context,
1801 projectsWithSimilarScmRoot );
1802
1803 Project fetchedProject = projectDao.getProjectWithBuildDetails( project.getId() );
1804
1805 addProjectToCheckoutQueue( projectBuilderId, buildDefinitionTemplateId, context,
1806 projectGroupCreation, scmUserName, scmPassword, project,
1807 isDefaultProjectBuildDefSet( fetchedProject ) );
1808 }
1809 }
1810 }
1811 catch ( BuildDefinitionServiceException e )
1812 {
1813 throw new ContinuumException( "Error attaching buildDefintionTemplate to project ", e );
1814 }
1815 catch ( ContinuumStoreException e )
1816 {
1817 throw new ContinuumException( "Error adding projects from modules", e );
1818 }
1819
1820 AbstractContinuumAction.setProjectGroupId( context, projectGroup.getId() );
1821
1822 if ( addAssignableRoles )
1823 {
1824 executeAction( "add-assignable-roles", context );
1825 }
1826 return result;
1827 }
1828
1829 private boolean isDefaultProjectBuildDefSet( Project project )
1830 {
1831 for ( BuildDefinition bd : project.getBuildDefinitions() )
1832 {
1833 if ( bd.isDefaultForProject() )
1834 {
1835 return true;
1836 }
1837 }
1838
1839 return false;
1840 }
1841
1842 private void addProjectToCheckoutQueue( String projectBuilderId, int buildDefinitionTemplateId,
1843 Map<String, Object> context, boolean projectGroupCreation,
1844 String scmUserName, String scmPassword, Project project,
1845 boolean defaultProjectBuildDefSet )
1846 throws BuildDefinitionServiceException, ContinuumStoreException, ContinuumException
1847 {
1848
1849
1850 if ( !projectGroupCreation && buildDefinitionTemplateId > 0 && !defaultProjectBuildDefSet )
1851 {
1852 buildDefinitionService.addTemplateInProject( buildDefinitionTemplateId, projectDao.getProject(
1853 project.getId() ) );
1854 }
1855
1856 AbstractContinuumAction.setUnvalidatedProject( context, project );
1857
1858
1859
1860
1861
1862
1863 AbstractContinuumAction.setProjectId( context, project.getId() );
1864
1865
1866 if ( !StringUtils.isEmpty( scmUserName ) )
1867 {
1868 project.setScmUsername( scmUserName );
1869 CheckoutProjectContinuumAction.setScmUsername( context, scmUserName );
1870 }
1871 if ( !StringUtils.isEmpty( scmPassword ) )
1872 {
1873 project.setScmPassword( scmPassword );
1874 CheckoutProjectContinuumAction.setScmPassword( context, scmPassword );
1875 }
1876
1877
1878
1879 AbstractContinuumAction.setProject( context, projectDao.getProject( project.getId() ) );
1880
1881 BuildDefinition defaultBuildDefinition = null;
1882 BuildDefinitionTemplate template = null;
1883 if ( projectBuilderId.equals( MavenTwoContinuumProjectBuilder.ID ) )
1884 {
1885 template = buildDefinitionService.getDefaultMavenTwoBuildDefinitionTemplate();
1886
1887 if ( template != null && template.getBuildDefinitions().size() > 0 )
1888 {
1889 defaultBuildDefinition = template.getBuildDefinitions().get( 0 );
1890 }
1891 }
1892 else if ( projectBuilderId.equals( MavenOneContinuumProjectBuilder.ID ) )
1893 {
1894 template = buildDefinitionService.getDefaultMavenOneBuildDefinitionTemplate();
1895
1896 if ( template != null && template.getBuildDefinitions().size() > 0 )
1897 {
1898 defaultBuildDefinition = template.getBuildDefinitions().get( 0 );
1899 }
1900 }
1901
1902 if ( defaultBuildDefinition == null )
1903 {
1904
1905
1906 log.warn( "No default build definition found in the template. Project cannot be checked out." );
1907 }
1908 else
1909 {
1910
1911 AbstractContinuumAction.setBuildDefinition( context, defaultBuildDefinition );
1912
1913 if ( !configurationService.isDistributedBuildEnabled() )
1914 {
1915 executeAction( "add-project-to-checkout-queue", context );
1916 }
1917 }
1918 }
1919
1920 private ContinuumProjectBuildingResult executeAddProjectsFromMetadataActivity( String metadataUrl,
1921 String projectBuilderId,
1922 int projectGroupId,
1923 boolean checkProtocol,
1924 boolean useCredentialsCache,
1925 boolean loadRecursiveProjects,
1926 int buildDefinitionTemplateId,
1927 boolean checkoutInSingleDirectory )
1928 throws ContinuumException
1929 {
1930 return executeAddProjectsFromMetadataActivity( metadataUrl, projectBuilderId, projectGroupId, checkProtocol,
1931 useCredentialsCache, loadRecursiveProjects,
1932 buildDefinitionTemplateId, true, checkoutInSingleDirectory );
1933 }
1934
1935
1936
1937
1938
1939
1940
1941
1942 public ProjectNotifier getNotifier( int projectId, int notifierId )
1943 throws ContinuumException
1944 {
1945 Project project = getProjectWithAllDetails( projectId );
1946
1947 List<ProjectNotifier> notifiers = project.getNotifiers();
1948
1949 ProjectNotifier notifier = null;
1950
1951 for ( ProjectNotifier notif : notifiers )
1952 {
1953 notifier = notif;
1954
1955 if ( notifier.getId() == notifierId )
1956 {
1957 break;
1958 }
1959 }
1960
1961 return notifier;
1962 }
1963
1964 public ProjectNotifier getGroupNotifier( int projectGroupId, int notifierId )
1965 throws ContinuumException
1966 {
1967 ProjectGroup projectGroup = getProjectGroupWithBuildDetails( projectGroupId );
1968
1969 List<ProjectNotifier> notifiers = projectGroup.getNotifiers();
1970
1971 ProjectNotifier notifier = null;
1972
1973 for ( ProjectNotifier notif : notifiers )
1974 {
1975 notifier = notif;
1976
1977 if ( notifier.getId() == notifierId )
1978 {
1979 break;
1980 }
1981 }
1982
1983 return notifier;
1984 }
1985
1986 public ProjectNotifier updateNotifier( int projectId, ProjectNotifier notifier )
1987 throws ContinuumException
1988 {
1989 Project project = getProjectWithAllDetails( projectId );
1990
1991 ProjectNotifier notif = getNotifier( projectId, notifier.getId() );
1992
1993
1994 project.removeNotifier( notif );
1995
1996 updateProject( project );
1997
1998 return addNotifier( projectId, notifier );
1999 }
2000
2001 public ProjectNotifier updateGroupNotifier( int projectGroupId, ProjectNotifier notifier )
2002 throws ContinuumException
2003 {
2004 ProjectGroup projectGroup = getProjectGroupWithBuildDetails( projectGroupId );
2005
2006 ProjectNotifier notif = getGroupNotifier( projectGroupId, notifier.getId() );
2007
2008
2009 projectGroup.removeNotifier( notif );
2010
2011 try
2012 {
2013 projectGroupDao.updateProjectGroup( projectGroup );
2014 }
2015 catch ( ContinuumStoreException cse )
2016 {
2017 throw new ContinuumException( "Unable to update project group.", cse );
2018 }
2019
2020 return addGroupNotifier( projectGroupId, notifier );
2021 }
2022
2023 public ProjectNotifier addNotifier( int projectId, ProjectNotifier notifier )
2024 throws ContinuumException
2025 {
2026 ProjectNotifier notif = new ProjectNotifier();
2027
2028 notif.setSendOnSuccess( notifier.isSendOnSuccess() );
2029
2030 notif.setSendOnFailure( notifier.isSendOnFailure() );
2031
2032 notif.setSendOnError( notifier.isSendOnError() );
2033
2034 notif.setSendOnWarning( notifier.isSendOnWarning() );
2035
2036 notif.setSendOnScmFailure( notifier.isSendOnScmFailure() );
2037
2038 notif.setConfiguration( notifier.getConfiguration() );
2039
2040 notif.setType( notifier.getType() );
2041
2042 notif.setFrom( ProjectNotifier.FROM_USER );
2043
2044 Project project = getProjectWithAllDetails( projectId );
2045
2046 project.addNotifier( notif );
2047
2048 updateProject( project );
2049
2050 return notif;
2051 }
2052
2053 public ProjectNotifier addGroupNotifier( int projectGroupId, ProjectNotifier notifier )
2054 throws ContinuumException
2055 {
2056 ProjectNotifier notif = new ProjectNotifier();
2057
2058 notif.setSendOnSuccess( notifier.isSendOnSuccess() );
2059
2060 notif.setSendOnFailure( notifier.isSendOnFailure() );
2061
2062 notif.setSendOnError( notifier.isSendOnError() );
2063
2064 notif.setSendOnWarning( notifier.isSendOnWarning() );
2065
2066 notif.setSendOnScmFailure( notifier.isSendOnScmFailure() );
2067
2068 notif.setConfiguration( notifier.getConfiguration() );
2069
2070 notif.setType( notifier.getType() );
2071
2072 notif.setFrom( ProjectNotifier.FROM_USER );
2073
2074 ProjectGroup projectGroup = getProjectGroupWithBuildDetails( projectGroupId );
2075
2076 projectGroup.addNotifier( notif );
2077 try
2078 {
2079 projectGroupDao.updateProjectGroup( projectGroup );
2080 }
2081 catch ( ContinuumStoreException cse )
2082 {
2083 throw new ContinuumException( "unable to add notifier to project group", cse );
2084 }
2085
2086 return notif;
2087 }
2088
2089 public void removeNotifier( int projectId, int notifierId )
2090 throws ContinuumException
2091 {
2092 Project project = getProjectWithAllDetails( projectId );
2093
2094 ProjectNotifier n = getNotifier( projectId, notifierId );
2095
2096 if ( n != null )
2097 {
2098 if ( n.isFromProject() )
2099 {
2100 n.setEnabled( false );
2101
2102 storeNotifier( n );
2103 }
2104 else
2105 {
2106 project.removeNotifier( n );
2107
2108 updateProject( project );
2109 }
2110 }
2111 }
2112
2113 public void removeGroupNotifier( int projectGroupId, int notifierId )
2114 throws ContinuumException
2115 {
2116 ProjectGroup projectGroup = getProjectGroupWithBuildDetails( projectGroupId );
2117
2118 ProjectNotifier n = getGroupNotifier( projectGroupId, notifierId );
2119
2120 if ( n != null )
2121 {
2122 if ( n.isFromProject() )
2123 {
2124 n.setEnabled( false );
2125
2126 storeNotifier( n );
2127 }
2128 else
2129 {
2130 projectGroup.removeNotifier( n );
2131
2132 try
2133 {
2134 projectGroupDao.updateProjectGroup( projectGroup );
2135 }
2136 catch ( ContinuumStoreException cse )
2137 {
2138 throw new ContinuumException( "Unable to remove notifer from project group.", cse );
2139 }
2140 }
2141 }
2142 }
2143
2144
2145
2146
2147
2148 public List<BuildDefinition> getBuildDefinitions( int projectId )
2149 throws ContinuumException
2150 {
2151 Project project = getProjectWithAllDetails( projectId );
2152
2153 return project.getBuildDefinitions();
2154 }
2155
2156 public BuildDefinition getBuildDefinition( int projectId, int buildDefinitionId )
2157 throws ContinuumException
2158 {
2159 List<BuildDefinition> buildDefinitions = getBuildDefinitions( projectId );
2160
2161 BuildDefinition buildDefinition = null;
2162
2163 for ( BuildDefinition bd : buildDefinitions )
2164 {
2165 if ( bd.getId() == buildDefinitionId )
2166 {
2167 buildDefinition = bd;
2168 break;
2169 }
2170 }
2171
2172 return buildDefinition;
2173 }
2174
2175 public BuildDefinition getDefaultBuildDefinition( int projectId )
2176 throws ContinuumException
2177 {
2178 try
2179 {
2180 return buildDefinitionDao.getDefaultBuildDefinition( projectId );
2181 }
2182 catch ( ContinuumObjectNotFoundException cne )
2183 {
2184 throw new ContinuumException( "no default build definition for project", cne );
2185 }
2186 catch ( ContinuumStoreException cse )
2187 {
2188 throw new ContinuumException(
2189 "error attempting to access default build definition for project " + projectId, cse );
2190 }
2191 }
2192
2193 public List<BuildDefinition> getDefaultBuildDefinitionsForProjectGroup( int projectGroupId )
2194 throws ContinuumException
2195 {
2196 try
2197 {
2198 return buildDefinitionDao.getDefaultBuildDefinitionsForProjectGroup( projectGroupId );
2199 }
2200 catch ( ContinuumObjectNotFoundException cne )
2201 {
2202 throw new ContinuumException( "Project Group (id=" + projectGroupId +
2203 ") doesn't have a default build definition, this should be impossible, it should always have a default definition set." );
2204 }
2205 catch ( ContinuumStoreException cse )
2206 {
2207 throw new ContinuumException( "Project Group (id=" + projectGroupId +
2208 ") doesn't have a default build definition, this should be impossible, it should always have a default definition set." );
2209 }
2210 }
2211
2212 public BuildDefinition getBuildDefinition( int buildDefinitionId )
2213 throws ContinuumException
2214 {
2215 try
2216 {
2217 return buildDefinitionDao.getBuildDefinition( buildDefinitionId );
2218 }
2219 catch ( ContinuumObjectNotFoundException cne )
2220 {
2221 throw new ContinuumException( "no build definition found", cne );
2222 }
2223 catch ( ContinuumStoreException cse )
2224 {
2225 throw new ContinuumException( "error attempting to access build definition", cse );
2226 }
2227 }
2228
2229 public List<BuildDefinition> getBuildDefinitionsForProject( int projectId )
2230 throws ContinuumException
2231 {
2232 Project project = getProjectWithAllDetails( projectId );
2233
2234 return project.getBuildDefinitions();
2235 }
2236
2237 public List<BuildDefinition> getBuildDefinitionsForProjectGroup( int projectGroupId )
2238 throws ContinuumException
2239 {
2240
2241 ProjectGroup projectGroup = getProjectGroupWithBuildDetails( projectGroupId );
2242
2243 return projectGroup.getBuildDefinitions();
2244 }
2245
2246 public BuildDefinition addBuildDefinitionToProject( int projectId, BuildDefinition buildDefinition )
2247 throws ContinuumException
2248 {
2249 HashMap<String, Object> context = new HashMap<String, Object>();
2250 Schedule schedule = buildDefinition.getSchedule();
2251
2252 AbstractContinuumAction.setBuildDefinition( context, buildDefinition );
2253 AbstractContinuumAction.setProjectId( context, projectId );
2254
2255 executeAction( "add-build-definition-to-project", context );
2256
2257 activeBuildDefinitionSchedule( schedule );
2258
2259 return AbstractContinuumAction.getBuildDefinition( context );
2260 }
2261
2262 public void removeBuildDefinitionFromProject( int projectId, int buildDefinitionId )
2263 throws ContinuumException
2264 {
2265 HashMap<String, Object> context = new HashMap<String, Object>();
2266 BuildDefinition buildDefinition = getBuildDefinition( buildDefinitionId );
2267
2268 AbstractContinuumAction.setBuildDefinition( context, buildDefinition );
2269 AbstractContinuumAction.setProjectId( context, projectId );
2270
2271 executeAction( "remove-build-definition-from-project", context );
2272 }
2273
2274 public BuildDefinition updateBuildDefinitionForProject( int projectId, BuildDefinition buildDefinition )
2275 throws ContinuumException
2276 {
2277 HashMap<String, Object> context = new HashMap<String, Object>();
2278 Schedule schedule = buildDefinition.getSchedule();
2279
2280 AbstractContinuumAction.setBuildDefinition( context, buildDefinition );
2281 AbstractContinuumAction.setProjectId( context, projectId );
2282
2283 executeAction( "update-build-definition-from-project", context );
2284
2285 activeBuildDefinitionSchedule( schedule );
2286
2287 return AbstractContinuumAction.getBuildDefinition( context );
2288 }
2289
2290 public BuildDefinition addBuildDefinitionToProjectGroup( int projectGroupId, BuildDefinition buildDefinition )
2291 throws ContinuumException
2292 {
2293 HashMap<String, Object> context = new HashMap<String, Object>();
2294 Schedule schedule = buildDefinition.getSchedule();
2295
2296 AbstractContinuumAction.setBuildDefinition( context, buildDefinition );
2297 AbstractContinuumAction.setProjectGroupId( context, projectGroupId );
2298
2299 executeAction( "add-build-definition-to-project-group", context );
2300
2301 activeBuildDefinitionSchedule( schedule );
2302
2303 return AbstractContinuumAction.getBuildDefinition( context );
2304 }
2305
2306 public void removeBuildDefinitionFromProjectGroup( int projectGroupId, int buildDefinitionId )
2307 throws ContinuumException
2308 {
2309 HashMap<String, Object> context = new HashMap<String, Object>();
2310
2311 AbstractContinuumAction.setBuildDefinition( context, getBuildDefinition( buildDefinitionId ) );
2312 AbstractContinuumAction.setProjectGroupId( context, projectGroupId );
2313
2314 executeAction( "remove-build-definition-from-project-group", context );
2315 }
2316
2317 public BuildDefinition updateBuildDefinitionForProjectGroup( int projectGroupId, BuildDefinition buildDefinition )
2318 throws ContinuumException
2319 {
2320 HashMap<String, Object> context = new HashMap<String, Object>();
2321 Schedule schedule = buildDefinition.getSchedule();
2322
2323 AbstractContinuumAction.setBuildDefinition( context, buildDefinition );
2324 AbstractContinuumAction.setProjectGroupId( context, projectGroupId );
2325
2326 executeAction( "update-build-definition-from-project-group", context );
2327
2328 activeBuildDefinitionSchedule( schedule );
2329
2330 return AbstractContinuumAction.getBuildDefinition( context );
2331 }
2332
2333 public void removeBuildDefinition( int projectId, int buildDefinitionId )
2334 throws ContinuumException
2335 {
2336 Project project = getProjectWithAllDetails( projectId );
2337
2338 BuildDefinition buildDefinition = getBuildDefinition( projectId, buildDefinitionId );
2339
2340 if ( buildDefinition != null )
2341 {
2342 project.removeBuildDefinition( buildDefinition );
2343
2344 updateProject( project );
2345 }
2346 }
2347
2348
2349
2350
2351
2352 public Schedule getSchedule( int scheduleId )
2353 throws ContinuumException
2354 {
2355 try
2356 {
2357 return scheduleDao.getSchedule( scheduleId );
2358 }
2359 catch ( Exception ex )
2360 {
2361 throw logAndCreateException( "Error while getting schedule.", ex );
2362 }
2363 }
2364
2365 public Schedule getScheduleByName( String scheduleName )
2366 throws ContinuumException
2367 {
2368 try
2369 {
2370 return scheduleDao.getScheduleByName( scheduleName );
2371 }
2372 catch ( ContinuumStoreException e )
2373 {
2374 throw logAndCreateException( "Error while accessing the store.", e );
2375 }
2376 }
2377
2378 public Collection<Schedule> getSchedules()
2379 throws ContinuumException
2380 {
2381 return scheduleDao.getAllSchedulesByName();
2382 }
2383
2384 public void addSchedule( Schedule schedule )
2385 throws ContinuumException
2386 {
2387 Schedule s;
2388
2389 s = getScheduleByName( schedule.getName() );
2390
2391 if ( s != null )
2392 {
2393 throw logAndCreateException( "Can't create schedule. A schedule with the same name already exists.", null );
2394 }
2395
2396 s = scheduleDao.addSchedule( schedule );
2397
2398 try
2399 {
2400 schedulesActivator.activateSchedule( s, this );
2401 }
2402 catch ( SchedulesActivationException e )
2403 {
2404 throw new ContinuumException( "Error activating schedule " + s.getName() + ".", e );
2405 }
2406 }
2407
2408 public void updateSchedule( Schedule schedule )
2409 throws ContinuumException
2410 {
2411 updateSchedule( schedule, true );
2412 }
2413
2414 private void updateSchedule( Schedule schedule, boolean updateScheduler )
2415 throws ContinuumException
2416 {
2417
2418 Schedule old = getSchedule( schedule.getId() );
2419
2420 storeSchedule( schedule );
2421
2422 if ( updateScheduler )
2423 {
2424 try
2425 {
2426 if ( schedule.isActive() )
2427 {
2428
2429 schedulesActivator.unactivateSchedule( old, this );
2430
2431 schedulesActivator.activateSchedule( schedule, this );
2432 }
2433 else
2434 {
2435
2436 schedulesActivator.unactivateSchedule( old, this );
2437 }
2438 }
2439 catch ( SchedulesActivationException e )
2440 {
2441 log.error( "Can't unactivate schedule. You need to restart Continuum.", e );
2442 }
2443 }
2444 }
2445
2446 public void updateSchedule( int scheduleId, Map<String, String> configuration )
2447 throws ContinuumException
2448 {
2449 Schedule schedule = getSchedule( scheduleId );
2450
2451 schedule.setName( configuration.get( "schedule.name" ) );
2452
2453 schedule.setDescription( configuration.get( "schedule.description" ) );
2454
2455 schedule.setCronExpression( configuration.get( "schedule.cronExpression" ) );
2456
2457 schedule.setDelay( Integer.parseInt( configuration.get( "schedule.delay" ) ) );
2458
2459 schedule.setActive( Boolean.valueOf( configuration.get( "schedule.active" ) ) );
2460
2461 updateSchedule( schedule, true );
2462 }
2463
2464 public void removeSchedule( int scheduleId )
2465 throws ContinuumException
2466 {
2467 Schedule schedule = getSchedule( scheduleId );
2468
2469 try
2470 {
2471 schedulesActivator.unactivateSchedule( schedule, this );
2472 }
2473 catch ( SchedulesActivationException e )
2474 {
2475 log.error( "Can't unactivate the schedule. You need to restart Continuum.", e );
2476 }
2477
2478 try
2479 {
2480 scheduleDao.removeSchedule( schedule );
2481 }
2482 catch ( Exception e )
2483 {
2484 log.error( "Can't remove the schedule.", e );
2485
2486 try
2487 {
2488 schedulesActivator.activateSchedule( schedule, this );
2489 }
2490 catch ( SchedulesActivationException sae )
2491 {
2492 log.error( "Can't reactivate the schedule. You need to restart Continuum.", e );
2493 }
2494 throw new ContinuumException( "Can't remove the schedule", e );
2495 }
2496 }
2497
2498 private Schedule storeSchedule( Schedule schedule )
2499 throws ContinuumException
2500 {
2501 try
2502 {
2503 return scheduleDao.storeSchedule( schedule );
2504 }
2505 catch ( ContinuumStoreException ex )
2506 {
2507 throw logAndCreateException( "Error while storing schedule.", ex );
2508 }
2509 }
2510
2511 public void activePurgeSchedule( Schedule schedule )
2512 {
2513 try
2514 {
2515 schedulesActivator.activatePurgeSchedule( schedule, this );
2516 }
2517 catch ( SchedulesActivationException e )
2518 {
2519 log.error( "Can't activate schedule for purgeConfiguration" );
2520 }
2521 }
2522
2523 public void activeBuildDefinitionSchedule( Schedule schedule )
2524 {
2525 try
2526 {
2527 schedulesActivator.activateBuildSchedule( schedule, this );
2528 }
2529 catch ( SchedulesActivationException e )
2530 {
2531 log.error( "Can't activate schedule for buildDefinition" );
2532 }
2533 }
2534
2535
2536
2537
2538 public File getWorkingDirectory( int projectId )
2539 throws ContinuumException
2540 {
2541 try
2542 {
2543 return workingDirectoryService.getWorkingDirectory( projectDao.getProject( projectId ) );
2544 }
2545 catch ( ContinuumStoreException e )
2546 {
2547 throw new ContinuumException( "Can't get files list.", e );
2548 }
2549 }
2550
2551 public String getFileContent( int projectId, String directory, String filename )
2552 throws ContinuumException
2553 {
2554 String relativePath = "\\.\\./";
2555 Pattern pattern = Pattern.compile( relativePath );
2556 Matcher matcher = pattern.matcher( directory );
2557 String filteredDirectory = matcher.replaceAll( "" );
2558
2559 matcher = pattern.matcher( filename );
2560 String filteredFilename = matcher.replaceAll( "" );
2561
2562 File workingDirectory = getWorkingDirectory( projectId );
2563
2564 File fileDirectory = new File( workingDirectory, filteredDirectory );
2565
2566 File userFile = new File( fileDirectory, filteredFilename );
2567
2568 try
2569 {
2570 return FileUtils.fileRead( userFile );
2571 }
2572 catch ( IOException e )
2573 {
2574 throw new ContinuumException( "Can't read file " + filename, e );
2575 }
2576 }
2577
2578 public List<File> getFiles( int projectId, String userDirectory )
2579 throws ContinuumException
2580 {
2581 File workingDirectory = getWorkingDirectory( projectId );
2582
2583 return getFiles( workingDirectory, null, userDirectory );
2584 }
2585
2586 private List<File> getFiles( File baseDirectory, String currentSubDirectory, String userDirectory )
2587 {
2588 List<File> dirs = new ArrayList<File>();
2589
2590 File workingDirectory;
2591
2592 if ( currentSubDirectory != null )
2593 {
2594 workingDirectory = new File( baseDirectory, currentSubDirectory );
2595 }
2596 else
2597 {
2598 workingDirectory = baseDirectory;
2599 }
2600
2601 String[] files = workingDirectory.list();
2602 Arrays.sort( files, String.CASE_INSENSITIVE_ORDER );
2603
2604 if ( files != null )
2605 {
2606 for ( String file : files )
2607 {
2608 File current = new File( workingDirectory, file );
2609
2610 String currentFile;
2611
2612 if ( currentSubDirectory == null )
2613 {
2614 currentFile = file;
2615 }
2616 else
2617 {
2618 currentFile = currentSubDirectory + "/" + file;
2619 }
2620
2621 if ( userDirectory != null && current.isDirectory() && userDirectory.startsWith( currentFile ) )
2622 {
2623 dirs.add( current );
2624
2625 dirs.addAll( getFiles( baseDirectory, currentFile, userDirectory ) );
2626 }
2627 else
2628 {
2629 dirs.add( current );
2630 }
2631 }
2632 }
2633
2634 return dirs;
2635 }
2636
2637
2638
2639
2640
2641 public ConfigurationService getConfiguration()
2642 {
2643 return configurationService;
2644 }
2645
2646 public void reloadConfiguration()
2647 throws ContinuumException
2648 {
2649 try
2650 {
2651 configurationService.reload();
2652 }
2653 catch ( Exception e )
2654 {
2655 throw new ContinuumException( "Can't reload configuration.", e );
2656 }
2657 }
2658
2659
2660
2661
2662
2663 public void initialize()
2664 throws InitializationException
2665 {
2666 log.info( "Initializing Continuum." );
2667
2668 log.info( "Showing all groups:" );
2669 try
2670 {
2671 for ( ProjectGroup group : projectGroupDao.getAllProjectGroups() )
2672 {
2673 createProjectScmRootForProjectGroup( group );
2674 }
2675 }
2676 catch ( ContinuumException e )
2677 {
2678 throw new InitializationException( "Error while creating project scm root for the project group", e );
2679 }
2680
2681 log.info( "Showing all projects: " );
2682
2683 for ( Project project : projectDao.getAllProjectsByNameWithBuildDetails() )
2684 {
2685 for ( ProjectNotifier notifier : (List<ProjectNotifier>) project.getNotifiers() )
2686 {
2687 if ( StringUtils.isEmpty( notifier.getType() ) )
2688 {
2689 try
2690 {
2691 removeNotifier( project.getId(), notifier.getId() );
2692 }
2693 catch ( ContinuumException e )
2694 {
2695 throw new InitializationException( "Database is corrupted.", e );
2696 }
2697 }
2698 }
2699
2700 if ( project.getState() != ContinuumProjectState.NEW &&
2701 project.getState() != ContinuumProjectState.CHECKEDOUT &&
2702 project.getState() != ContinuumProjectState.OK && project.getState() != ContinuumProjectState.FAILED &&
2703 project.getState() != ContinuumProjectState.ERROR )
2704 {
2705 int state = project.getState();
2706
2707 project.setState( project.getOldState() );
2708
2709 project.setOldState( 0 );
2710
2711 try
2712 {
2713 log.info( "Fix project state for project " + project.getId() + ":" + project.getName() + ":" +
2714 project.getVersion() );
2715
2716 projectDao.updateProject( project );
2717
2718 Project p = projectDao.getProject( project.getId() );
2719
2720 if ( state == p.getState() )
2721 {
2722 log.info( "Can't fix the project state." );
2723 }
2724 }
2725 catch ( ContinuumStoreException e )
2726 {
2727 throw new InitializationException( "Database is corrupted.", e );
2728 }
2729 }
2730
2731 log.info( " " + project.getId() + ":" + project.getName() + ":" + project.getVersion() + ":" +
2732 project.getExecutorId() );
2733 }
2734
2735 for ( ProjectScmRoot projectScmRoot : projectScmRootDao.getAllProjectScmRoots() )
2736 {
2737 if ( projectScmRoot.getState() == ContinuumProjectState.UPDATING )
2738 {
2739 projectScmRoot.setState( projectScmRoot.getOldState() );
2740
2741 projectScmRoot.setOldState( 0 );
2742
2743 try
2744 {
2745 log.info( "Fix state for projectScmRoot " + projectScmRoot.getScmRootAddress() );
2746
2747 projectScmRootDao.updateProjectScmRoot( projectScmRoot );
2748 }
2749 catch ( ContinuumStoreException e )
2750 {
2751 throw new InitializationException( "Database is corrupted.", e );
2752 }
2753 }
2754 }
2755 }
2756
2757
2758
2759
2760 public void start()
2761 throws StartingException
2762 {
2763 startMessage();
2764
2765 try
2766 {
2767 initializer.initialize();
2768
2769 configurationService.reload();
2770 }
2771 catch ( ConfigurationLoadingException e )
2772 {
2773 throw new StartingException( "Error loading the Continuum configuration.", e );
2774 }
2775 catch ( ContinuumConfigurationException e )
2776 {
2777 throw new StartingException( "Error loading the Continuum configuration.", e );
2778 }
2779 catch ( ContinuumInitializationException e )
2780 {
2781 throw new StartingException( "Cannot initializing Continuum for the first time.", e );
2782 }
2783
2784 try
2785 {
2786
2787
2788
2789 schedulesActivator.activateSchedules( this );
2790 }
2791 catch ( SchedulesActivationException e )
2792 {
2793
2794 log.error( "Error activating schedules.", e );
2795 }
2796 }
2797
2798 public void stop()
2799 throws StoppingException
2800 {
2801 stopContinuum();
2802 }
2803
2804 private void closeStore()
2805 {
2806 if ( daoUtils != null )
2807 {
2808 daoUtils.closeStore();
2809 }
2810 }
2811
2812
2813 public void startup()
2814 throws ContinuumException
2815 {
2816 try
2817 {
2818 this.start();
2819 }
2820 catch ( StartingException e )
2821 {
2822 throw new ContinuumException( e.getMessage(), e );
2823 }
2824 }
2825
2826 private void stopContinuum()
2827 {
2828
2829 if ( stopped )
2830 {
2831 return;
2832 }
2833
2834 try
2835 {
2836 if ( configurationService != null )
2837 {
2838 configurationService.store();
2839 }
2840 }
2841 catch ( Exception e )
2842 {
2843 log.info( "Error storing the Continuum configuration.", e );
2844 }
2845
2846 closeStore();
2847
2848 stopMessage();
2849
2850 stopped = true;
2851 }
2852
2853 public long getNbBuildResultsForProject( int projectId )
2854 {
2855 return buildResultDao.getNbBuildResultsForProject( projectId );
2856 }
2857
2858 public Collection<BuildResult> getBuildResultsForProject( int projectId )
2859 throws ContinuumException
2860 {
2861 return buildResultDao.getBuildResultsForProject( projectId );
2862 }
2863
2864
2865
2866
2867
2868 protected void executeAction( String actionName, Map<String, Object> context )
2869 throws ContinuumException
2870 {
2871 try
2872 {
2873 Action action = actionManager.lookup( actionName );
2874
2875 action.execute( context );
2876 }
2877 catch ( ActionNotFoundException e )
2878 {
2879 e.printStackTrace();
2880 throw new ContinuumException( "Error while executing the action '" + actionName + "'.", e );
2881 }
2882 catch ( ContinuumException e )
2883 {
2884 throw e;
2885 }
2886 catch ( Exception e )
2887 {
2888 log.info( "exception", e );
2889 throw new ContinuumException( "Error while executing the action '" + actionName + "'.", e );
2890 }
2891 }
2892
2893
2894
2895
2896
2897 private ContinuumException logAndCreateException( String message, Throwable cause )
2898 {
2899 if ( cause instanceof ContinuumObjectNotFoundException )
2900 {
2901 return new ContinuumException( "No such object.", cause );
2902 }
2903
2904 log.error( message, cause );
2905
2906 return new ContinuumException( message, cause );
2907 }
2908
2909
2910
2911
2912
2913
2914
2915 public void updateProject( Project project )
2916 throws ContinuumException
2917 {
2918 try
2919 {
2920 boolean removeWorkingDirectory = false;
2921
2922 Project p = projectDao.getProject( project.getId() );
2923 ProjectScmRoot projectScmRoot = null;
2924
2925 if ( !p.getScmUrl().equals( project.getScmUrl() ) )
2926 {
2927 removeWorkingDirectory = true;
2928 projectScmRoot = getProjectScmRootByProject( project.getId() );
2929 }
2930
2931 if ( !p.getProjectGroup().equals( project.getProjectGroup() ) )
2932 {
2933 projectScmRoot = getProjectScmRootByProject( project.getId() );
2934 }
2935
2936 if ( StringUtils.isEmpty( p.getScmTag() ) && !StringUtils.isEmpty( project.getScmTag() ) )
2937 {
2938 removeWorkingDirectory = true;
2939 }
2940 else if ( !StringUtils.isEmpty( p.getScmTag() ) && StringUtils.isEmpty( project.getScmTag() ) )
2941 {
2942 removeWorkingDirectory = true;
2943 }
2944 else if ( !StringUtils.isEmpty( p.getScmTag() ) && !p.getScmTag().equals( project.getScmTag() ) )
2945 {
2946 removeWorkingDirectory = true;
2947 }
2948
2949 if ( removeWorkingDirectory )
2950 {
2951 File workingDirectory = getWorkingDirectory( project.getId() );
2952
2953 FileUtils.deleteDirectory( workingDirectory );
2954 }
2955
2956 if ( StringUtils.isEmpty( project.getScmTag() ) )
2957 {
2958 project.setScmTag( null );
2959 }
2960
2961 projectDao.updateProject( project );
2962
2963 if ( projectScmRoot != null )
2964 {
2965 updateProjectScmRoot( projectScmRoot, project );
2966 }
2967 }
2968 catch ( ContinuumStoreException ex )
2969 {
2970 throw logAndCreateException( "Error while updating project.", ex );
2971 }
2972 catch ( IOException ex )
2973 {
2974 throw logAndCreateException( "Error while updating project.", ex );
2975 }
2976 }
2977
2978 public void updateProjectGroup( ProjectGroup projectGroup )
2979 throws ContinuumException
2980 {
2981
2982 projectGroup.setName( projectGroup.getName().trim() );
2983 try
2984 {
2985 projectGroupDao.updateProjectGroup( projectGroup );
2986 }
2987 catch ( ContinuumStoreException cse )
2988 {
2989 throw logAndCreateException( "Error while updating project group.", cse );
2990 }
2991 }
2992
2993 private ProjectNotifier storeNotifier( ProjectNotifier notifier )
2994 throws ContinuumException
2995 {
2996 try
2997 {
2998 return notifierDao.storeNotifier( notifier );
2999 }
3000 catch ( ContinuumStoreException ex )
3001 {
3002 throw logAndCreateException( "Error while storing notifier.", ex );
3003 }
3004 }
3005
3006 private String getWorkingDirectory()
3007 {
3008 return configurationService.getWorkingDirectory().getAbsolutePath();
3009 }
3010
3011 public Project getProjectWithCheckoutResult( int projectId )
3012 throws ContinuumException
3013 {
3014 try
3015 {
3016 return projectDao.getProjectWithCheckoutResult( projectId );
3017 }
3018 catch ( ContinuumObjectNotFoundException e )
3019 {
3020 throw new ContinuumException( "Unable to find the requested project", e );
3021 }
3022 catch ( ContinuumStoreException e )
3023 {
3024 throw new ContinuumException( "Error retrieving the requested project", e );
3025 }
3026 }
3027
3028 public Project getProjectWithAllDetails( int projectId )
3029 throws ContinuumException
3030 {
3031 try
3032 {
3033 return projectDao.getProjectWithAllDetails( projectId );
3034 }
3035 catch ( ContinuumObjectNotFoundException e )
3036 {
3037 throw new ContinuumException( "Unable to find the requested project", e );
3038 }
3039 catch ( ContinuumStoreException e )
3040 {
3041 throw new ContinuumException( "Error retrieving the requested project", e );
3042 }
3043 }
3044
3045 public ProjectGroup getProjectGroupWithBuildDetails( int projectGroupId )
3046 throws ContinuumException
3047 {
3048 try
3049 {
3050 return projectGroupDao.getProjectGroupWithBuildDetailsByProjectGroupId( projectGroupId );
3051 }
3052 catch ( ContinuumObjectNotFoundException e )
3053 {
3054 throw new ContinuumException( "Unable to find the requested project", e );
3055 }
3056 catch ( ContinuumStoreException e )
3057 {
3058 throw new ContinuumException( "Error retrieving the requested project", e );
3059 }
3060 }
3061
3062 public Project getProjectWithBuilds( int projectId )
3063 throws ContinuumException
3064 {
3065 try
3066 {
3067 return projectDao.getProjectWithBuilds( projectId );
3068 }
3069 catch ( ContinuumObjectNotFoundException e )
3070 {
3071 throw new ContinuumException( "Unable to find the requested project", e );
3072 }
3073 catch ( ContinuumStoreException e )
3074 {
3075 throw new ContinuumException( "Error retrieving the requested project", e );
3076 }
3077 }
3078
3079 public List<ProjectGroup> getAllProjectGroupsWithBuildDetails()
3080 {
3081 return projectGroupDao.getAllProjectGroupsWithBuildDetails();
3082 }
3083
3084 public Collection<Project> getProjectsInGroup( int projectGroupId )
3085 throws ContinuumException
3086 {
3087 try
3088 {
3089 return projectDao.getProjectsInGroup( projectGroupId );
3090 }
3091 catch ( ContinuumObjectNotFoundException e )
3092 {
3093 throw new ContinuumException( "Unable to find the requested project", e );
3094 }
3095 catch ( ContinuumStoreException e )
3096 {
3097 throw new ContinuumException( "Error retrieving the requested project", e );
3098 }
3099 }
3100
3101 public Collection<Project> getProjectsInGroupWithDependencies( int projectGroupId )
3102 throws ContinuumException
3103 {
3104 try
3105 {
3106 return projectDao.getProjectsInGroupWithDependencies( projectGroupId );
3107 }
3108 catch ( ContinuumObjectNotFoundException e )
3109 {
3110 throw new ContinuumException( "Unable to find the requested project", e );
3111 }
3112 catch ( ContinuumStoreException e )
3113 {
3114 throw new ContinuumException( "Error retrieving the requested project", e );
3115 }
3116 }
3117
3118
3119
3120
3121
3122 private void startMessage()
3123 {
3124 log.info( "Starting Continuum." );
3125
3126
3127
3128
3129
3130 String banner = StringUtils.repeat( "-", getVersion().length() );
3131
3132 log.info( "" );
3133 log.info( "" );
3134 log.info( "< Continuum " + getVersion() + " started! >" );
3135 log.info( "-----------------------" + banner );
3136 log.info( " \\ ^__^" );
3137 log.info( " \\ (oo)\\_______" );
3138 log.info( " (__)\\ )\\/\\" );
3139 log.info( " ||----w |" );
3140 log.info( " || ||" );
3141 log.info( "" );
3142 log.info( "" );
3143 }
3144
3145 private void stopMessage()
3146 {
3147
3148 if ( log != null )
3149 {
3150 log.info( "Stopping Continuum." );
3151
3152 log.info( "Continuum stopped." );
3153 }
3154 }
3155
3156 private String getVersion()
3157 {
3158 InputStream resourceAsStream = null;
3159 try
3160 {
3161 Properties properties = new Properties();
3162
3163 String name = "META-INF/maven/org.apache.continuum/continuum-core/pom.properties";
3164
3165 resourceAsStream = getClass().getClassLoader().getResourceAsStream( name );
3166
3167 if ( resourceAsStream == null )
3168 {
3169 return "unknown";
3170 }
3171
3172 properties.load( resourceAsStream );
3173
3174 return properties.getProperty( "version", "unknown" );
3175 }
3176 catch ( IOException e )
3177 {
3178 return "unknown";
3179 }
3180 finally
3181 {
3182 if ( resourceAsStream != null )
3183 {
3184 IOUtil.close( resourceAsStream );
3185 }
3186 }
3187 }
3188
3189 public InstallationService getInstallationService()
3190 {
3191 return installationService;
3192 }
3193
3194 public ProfileService getProfileService()
3195 {
3196 return profileService;
3197 }
3198
3199 public BuildDefinitionService getBuildDefinitionService()
3200 {
3201 return buildDefinitionService;
3202 }
3203
3204 public ContinuumReleaseResult addContinuumReleaseResult( int projectId, String releaseId, String releaseType )
3205 throws ContinuumException
3206 {
3207 ReleaseResult result;
3208 String releaseBy = "";
3209
3210 if ( getConfiguration().isDistributedBuildEnabled() )
3211 {
3212 try
3213 {
3214 result = (ReleaseResult) distributedReleaseManager.getReleaseResult( releaseId );
3215 PreparedRelease preparedRelease = distributedReleaseManager.getPreparedRelease( releaseId,
3216 releaseType );
3217 if ( preparedRelease != null )
3218 {
3219 releaseBy = preparedRelease.getReleaseBy();
3220 }
3221 }
3222 catch ( ContinuumReleaseException e )
3223 {
3224 throw new ContinuumException( "Failed to release project: " + projectId, e );
3225 }
3226 catch ( BuildAgentConfigurationException e )
3227 {
3228 throw new ContinuumException( "Failed to release project: " + projectId, e );
3229 }
3230 }
3231 else
3232 {
3233 result = (ReleaseResult) releaseManager.getReleaseResults().get( releaseId );
3234 ContinuumReleaseDescriptor descriptor =
3235 (ContinuumReleaseDescriptor) releaseManager.getPreparedReleases().get( releaseId );
3236 if ( descriptor != null )
3237 {
3238 releaseBy = descriptor.getReleaseBy();
3239 }
3240 }
3241
3242 if ( result != null && getContinuumReleaseResult( projectId, releaseType, result.getStartTime(),
3243 result.getEndTime() ) == null )
3244 {
3245 ContinuumReleaseResult releaseResult = createContinuumReleaseResult( projectId, releaseType, result,
3246 releaseBy );
3247 return addContinuumReleaseResult( releaseResult );
3248 }
3249
3250 return null;
3251 }
3252
3253 private ContinuumReleaseResult createContinuumReleaseResult( int projectId, String releaseGoals,
3254 ReleaseResult result, String releaseBy )
3255 throws ContinuumException
3256 {
3257 ContinuumReleaseResult releaseResult = new ContinuumReleaseResult();
3258 releaseResult.setStartTime( result.getStartTime() );
3259 releaseResult.setEndTime( result.getEndTime() );
3260 releaseResult.setResultCode( result.getResultCode() );
3261
3262 Project project = getProject( projectId );
3263 ProjectGroup projectGroup = project.getProjectGroup();
3264 releaseResult.setProjectGroup( projectGroup );
3265 releaseResult.setProject( project );
3266 releaseResult.setReleaseGoal( releaseGoals );
3267 releaseResult.setUsername( releaseBy );
3268
3269 String releaseName = "releases-" + result.getStartTime();
3270
3271 try
3272 {
3273 File logFile = getConfiguration().getReleaseOutputFile( projectGroup.getId(), releaseName );
3274
3275 PrintWriter writer = new PrintWriter( new FileWriter( logFile ) );
3276 writer.write( result.getOutput() );
3277 writer.close();
3278 }
3279 catch ( ConfigurationException e )
3280 {
3281 throw new ContinuumException( e.getMessage(), e );
3282 }
3283 catch ( IOException e )
3284 {
3285 throw new ContinuumException( "Unable to write output to file", e );
3286 }
3287
3288 return releaseResult;
3289 }
3290
3291 public ContinuumReleaseResult addContinuumReleaseResult( ContinuumReleaseResult releaseResult )
3292 throws ContinuumException
3293 {
3294 try
3295 {
3296 return releaseResultDao.addContinuumReleaseResult( releaseResult );
3297 }
3298 catch ( ContinuumStoreException e )
3299 {
3300 throw new ContinuumException( "Error while adding continuumReleaseResult", e );
3301 }
3302 }
3303
3304 public void removeContinuumReleaseResult( int releaseResultId )
3305 throws ContinuumException
3306 {
3307 ContinuumReleaseResult releaseResult = getContinuumReleaseResult( releaseResultId );
3308
3309 try
3310 {
3311 releaseResultDao.removeContinuumReleaseResult( releaseResult );
3312 }
3313 catch ( ContinuumStoreException e )
3314 {
3315 throw new ContinuumException( "Error while deleting continuumReleaseResult: " + releaseResultId, e );
3316 }
3317
3318 try
3319 {
3320 int projectGroupId = releaseResult.getProjectGroup().getId();
3321
3322 String name = "releases-" + releaseResult.getStartTime();
3323
3324 File releaseFile = getConfiguration().getReleaseOutputFile( projectGroupId, name );
3325
3326 if ( releaseFile.exists() )
3327 {
3328 try
3329 {
3330 FileUtils.forceDelete( releaseFile );
3331 }
3332 catch ( IOException e )
3333 {
3334 throw new ContinuumException( "Can't delete " + releaseFile.getAbsolutePath(), e );
3335 }
3336 }
3337 }
3338 catch ( ConfigurationException e )
3339 {
3340 log.info( "skip error during cleanup release files " + e.getMessage(), e );
3341 }
3342 }
3343
3344 public ContinuumReleaseResult getContinuumReleaseResult( int releaseResultId )
3345 throws ContinuumException
3346 {
3347 try
3348 {
3349 return releaseResultDao.getContinuumReleaseResult( releaseResultId );
3350 }
3351 catch ( ContinuumObjectNotFoundException e )
3352 {
3353 throw new ContinuumException( "No continuumReleaseResult found: " + releaseResultId );
3354 }
3355 catch ( ContinuumStoreException e )
3356 {
3357 throw new ContinuumException( "Error while retrieving continuumReleaseResult: " + releaseResultId, e );
3358 }
3359 }
3360
3361 public List<ContinuumReleaseResult> getAllContinuumReleaseResults()
3362 {
3363 return releaseResultDao.getAllContinuumReleaseResults();
3364 }
3365
3366 public List<ContinuumReleaseResult> getContinuumReleaseResultsByProjectGroup( int projectGroupId )
3367 {
3368 return releaseResultDao.getContinuumReleaseResultsByProjectGroup( projectGroupId );
3369 }
3370
3371 public ContinuumReleaseResult getContinuumReleaseResult( int projectId, String releaseGoal, long startTime,
3372 long endTime )
3373 throws ContinuumException
3374 {
3375 try
3376 {
3377 return releaseResultDao.getContinuumReleaseResult( projectId, releaseGoal, startTime, endTime );
3378 }
3379 catch ( ContinuumStoreException e )
3380 {
3381 throw new ContinuumException(
3382 "Error while retrieving continuumReleaseResult of projectId " + projectId + " with releaseGoal: " +
3383 releaseGoal, e );
3384 }
3385 }
3386
3387 public String getReleaseOutput( int releaseResultId )
3388 throws ContinuumException
3389 {
3390 ContinuumReleaseResult releaseResult = getContinuumReleaseResult( releaseResultId );
3391
3392 ProjectGroup projectGroup = releaseResult.getProjectGroup();
3393
3394 try
3395 {
3396 return configurationService.getReleaseOutput( projectGroup.getId(),
3397 "releases-" + releaseResult.getStartTime() );
3398 }
3399 catch ( ConfigurationException e )
3400 {
3401 throw new ContinuumException( "Error while retrieving release output for release: " + releaseResultId );
3402 }
3403 }
3404
3405 public List<ProjectScmRoot> getProjectScmRootByProjectGroup( int projectGroupId )
3406 {
3407 return projectScmRootDao.getProjectScmRootByProjectGroup( projectGroupId );
3408 }
3409
3410 public ProjectScmRoot getProjectScmRoot( int projectScmRootId )
3411 throws ContinuumException
3412 {
3413 try
3414 {
3415 return projectScmRootDao.getProjectScmRoot( projectScmRootId );
3416 }
3417 catch ( ContinuumObjectNotFoundException e )
3418 {
3419 throw new ContinuumException( "No projectScmRoot found with the given id: " + projectScmRootId );
3420 }
3421 catch ( ContinuumStoreException e )
3422 {
3423 throw new ContinuumException( "Error while retrieving projectScmRoot ", e );
3424 }
3425 }
3426
3427 public ProjectScmRoot getProjectScmRootByProject( int projectId )
3428 throws ContinuumException
3429 {
3430 Project project = getProject( projectId );
3431 ProjectGroup group = getProjectGroupByProjectId( projectId );
3432
3433 List<ProjectScmRoot> scmRoots = getProjectScmRootByProjectGroup( group.getId() );
3434
3435 for ( ProjectScmRoot scmRoot : scmRoots )
3436 {
3437 if ( project.getScmUrl() != null && project.getScmUrl().startsWith( scmRoot.getScmRootAddress() ) )
3438 {
3439 return scmRoot;
3440 }
3441 }
3442 return null;
3443 }
3444
3445 public ProjectScmRoot getProjectScmRootByProjectGroupAndScmRootAddress( int projectGroupId, String scmRootAddress )
3446 throws ContinuumException
3447 {
3448 try
3449 {
3450 return projectScmRootDao.getProjectScmRootByProjectGroupAndScmRootAddress( projectGroupId, scmRootAddress );
3451 }
3452 catch ( ContinuumStoreException e )
3453 {
3454 throw new ContinuumException( "Error while retrieving project scm root for " + projectGroupId, e );
3455 }
3456 }
3457
3458 private void removeProjectScmRoot( ProjectScmRoot projectScmRoot )
3459 throws ContinuumException
3460 {
3461 if ( projectScmRoot == null )
3462 {
3463 return;
3464 }
3465
3466
3467 ProjectGroup group = getProjectGroupWithProjects( projectScmRoot.getProjectGroup().getId() );
3468
3469 List<Project> projects = group.getProjects();
3470
3471 boolean found = false;
3472 for ( Project project : projects )
3473 {
3474 if ( project.getScmUrl() != null && project.getScmUrl().startsWith( projectScmRoot.getScmRootAddress() ) )
3475 {
3476 found = true;
3477 break;
3478 }
3479 }
3480
3481 if ( !found )
3482 {
3483 log.info( "Removing project scm root '" + projectScmRoot.getScmRootAddress() + "'" );
3484 try
3485 {
3486 projectScmRootDao.removeProjectScmRoot( projectScmRoot );
3487 }
3488 catch ( ContinuumStoreException e )
3489 {
3490 log.error( "Failed to remove project scm root '" + projectScmRoot.getScmRootAddress() + "'", e );
3491 throw new ContinuumException(
3492 "Error while removing project scm root '" + projectScmRoot.getScmRootAddress() + "'", e );
3493 }
3494 }
3495 else
3496 {
3497 log.info(
3498 "Project scm root '" + projectScmRoot.getScmRootAddress() + "' still has projects, not removing" );
3499 }
3500 }
3501
3502 public BuildQueue addBuildQueue( BuildQueue buildQueue )
3503 throws ContinuumException
3504 {
3505 try
3506 {
3507 return buildQueueService.addBuildQueue( buildQueue );
3508 }
3509 catch ( BuildQueueServiceException e )
3510 {
3511 throw new ContinuumException( "Error adding build queue to the database.", e );
3512 }
3513 }
3514
3515 public BuildQueue getBuildQueue( int buildQueueId )
3516 throws ContinuumException
3517 {
3518 try
3519 {
3520 return buildQueueService.getBuildQueue( buildQueueId );
3521 }
3522 catch ( BuildQueueServiceException e )
3523 {
3524 throw new ContinuumException( "Error retrieving build queue.", e );
3525 }
3526 }
3527
3528 public BuildQueue getBuildQueueByName( String buildQueueName )
3529 throws ContinuumException
3530 {
3531 try
3532 {
3533 return buildQueueService.getBuildQueueByName( buildQueueName );
3534 }
3535 catch ( BuildQueueServiceException e )
3536 {
3537 throw new ContinuumException( "Error retrieving build queue.", e );
3538 }
3539 }
3540
3541 public void removeBuildQueue( BuildQueue buildQueue )
3542 throws ContinuumException
3543 {
3544 try
3545 {
3546 buildQueueService.removeBuildQueue( buildQueue );
3547 }
3548 catch ( BuildQueueServiceException e )
3549 {
3550 throw new ContinuumException( "Error deleting build queue from database.", e );
3551 }
3552 }
3553
3554 public BuildQueue storeBuildQueue( BuildQueue buildQueue )
3555 throws ContinuumException
3556 {
3557 try
3558 {
3559 return buildQueueService.updateBuildQueue( buildQueue );
3560 }
3561 catch ( BuildQueueServiceException e )
3562 {
3563 throw new ContinuumException( "Error updating build queue.", e );
3564 }
3565 }
3566
3567 public List<BuildQueue> getAllBuildQueues()
3568 throws ContinuumException
3569 {
3570 try
3571 {
3572 return buildQueueService.getAllBuildQueues();
3573 }
3574 catch ( BuildQueueServiceException e )
3575 {
3576 throw new ContinuumException( "Error adding build queue.", e );
3577 }
3578 }
3579
3580 private void prepareBuildProjects( Collection<Project> projects, List<BuildDefinition> bds,
3581 boolean checkDefaultBuildDefinitionForProject, BuildTrigger buildTrigger )
3582 throws ContinuumException, NoBuildAgentException, NoBuildAgentInGroupException
3583 {
3584 Map<ProjectScmRoot, Map<Integer, Integer>> map = new HashMap<ProjectScmRoot, Map<Integer, Integer>>();
3585 List<ProjectScmRoot> sortedScmRoot = new ArrayList<ProjectScmRoot>();
3586
3587 for ( Project project : projects )
3588 {
3589 int projectId = project.getId();
3590
3591 int buildDefId = -1;
3592
3593 if ( bds != null )
3594 {
3595 for ( BuildDefinition bd : bds )
3596 {
3597 if ( project.getExecutorId().equals( bd.getType() ) || ( StringUtils.isEmpty( bd.getType() ) &&
3598 ContinuumBuildExecutorConstants.MAVEN_TWO_BUILD_EXECUTOR.equals( project.getExecutorId() ) ) )
3599 {
3600 buildDefId = bd.getId();
3601 break;
3602 }
3603 }
3604 }
3605
3606 if ( checkDefaultBuildDefinitionForProject )
3607 {
3608 BuildDefinition projectDefaultBD = null;
3609 try
3610 {
3611 projectDefaultBD = buildDefinitionDao.getDefaultBuildDefinitionForProject( projectId );
3612 }
3613 catch ( ContinuumObjectNotFoundException e )
3614 {
3615 log.debug( e.getMessage() );
3616 }
3617 catch ( ContinuumStoreException e )
3618 {
3619 log.debug( e.getMessage() );
3620 }
3621
3622 if ( projectDefaultBD != null )
3623 {
3624 buildDefId = projectDefaultBD.getId();
3625 log.debug( "Project " + project.getId() +
3626 " has own default build definition, will use it instead of group's." );
3627 }
3628 }
3629
3630 if ( buildDefId == -1 )
3631 {
3632 log.info( "Project " + projectId +
3633 " don't have a default build definition defined in the project or project group, will not be included in group build." );
3634 continue;
3635 }
3636
3637
3638 if ( !isProjectOkToBuild( projectId, buildDefId ) )
3639 {
3640 log.info(
3641 "Not queueing the build with projectId={} and buildDefinitionId={} because it is already building",
3642 projectId, buildDefId );
3643 continue;
3644 }
3645
3646 ProjectScmRoot scmRoot = getProjectScmRootByProject( projectId );
3647
3648 Map<Integer, Integer> projectsAndBuildDefinitionsMap = map.get( scmRoot );
3649
3650 if ( projectsAndBuildDefinitionsMap == null )
3651 {
3652 projectsAndBuildDefinitionsMap = new HashMap<Integer, Integer>();
3653 }
3654
3655 projectsAndBuildDefinitionsMap.put( projectId, buildDefId );
3656
3657 map.put( scmRoot, projectsAndBuildDefinitionsMap );
3658
3659 if ( !sortedScmRoot.contains( scmRoot ) )
3660 {
3661 sortedScmRoot.add( scmRoot );
3662 }
3663 }
3664
3665 prepareBuildProjects( map, buildTrigger, sortedScmRoot );
3666 }
3667
3668 private void prepareBuildProjects( Collection<Project> projects, int buildDefinitionId, BuildTrigger buildTrigger )
3669 throws ContinuumException, NoBuildAgentException, NoBuildAgentInGroupException
3670 {
3671 Map<ProjectScmRoot, Map<Integer, Integer>> map = new HashMap<ProjectScmRoot, Map<Integer, Integer>>();
3672 List<ProjectScmRoot> sortedScmRoot = new ArrayList<ProjectScmRoot>();
3673
3674 for ( Project project : projects )
3675 {
3676 int projectId = project.getId();
3677
3678
3679 if ( !isProjectOkToBuild( projectId, buildDefinitionId ) )
3680 {
3681 log.info(
3682 "Not queueing the build with projectId={} and buildDefinitionId={} because it is already building",
3683 projectId, buildDefinitionId );
3684 continue;
3685 }
3686
3687 ProjectScmRoot scmRoot = getProjectScmRootByProject( projectId );
3688
3689 Map<Integer, Integer> projectsAndBuildDefinitionsMap = map.get( scmRoot );
3690
3691 if ( projectsAndBuildDefinitionsMap == null )
3692 {
3693 projectsAndBuildDefinitionsMap = new HashMap<Integer, Integer>();
3694 }
3695
3696 projectsAndBuildDefinitionsMap.put( projectId, buildDefinitionId );
3697
3698 map.put( scmRoot, projectsAndBuildDefinitionsMap );
3699
3700 if ( !sortedScmRoot.contains( scmRoot ) )
3701 {
3702 sortedScmRoot.add( scmRoot );
3703 }
3704 }
3705
3706 prepareBuildProjects( map, buildTrigger, sortedScmRoot );
3707 }
3708
3709 private void prepareBuildProjects( Map<ProjectScmRoot, Map<Integer, Integer>> map, BuildTrigger buildTrigger,
3710 List<ProjectScmRoot> scmRoots )
3711 throws ContinuumException, NoBuildAgentException, NoBuildAgentInGroupException
3712 {
3713 for ( ProjectScmRoot scmRoot : scmRoots )
3714 {
3715 prepareBuildProjects( map.get( scmRoot ), buildTrigger, scmRoot.getScmRootAddress(),
3716 scmRoot.getProjectGroup().getId(), scmRoot.getId(), scmRoots );
3717 }
3718 }
3719
3720 private void prepareBuildProjects( Map<Integer, Integer> projectsBuildDefinitionsMap, BuildTrigger buildTrigger,
3721 String scmRootAddress, int projectGroupId, int scmRootId,
3722 List<ProjectScmRoot> scmRoots )
3723 throws ContinuumException, NoBuildAgentException, NoBuildAgentInGroupException
3724 {
3725 ProjectGroup group = getProjectGroup( projectGroupId );
3726
3727 try
3728 {
3729 if ( configurationService.isDistributedBuildEnabled() )
3730 {
3731 distributedBuildManager.prepareBuildProjects( projectsBuildDefinitionsMap, buildTrigger, projectGroupId,
3732 group.getName(), scmRootAddress, scmRootId, scmRoots );
3733 }
3734 else
3735 {
3736 parallelBuildsManager.prepareBuildProjects( projectsBuildDefinitionsMap, buildTrigger, projectGroupId,
3737 group.getName(), scmRootAddress, scmRootId );
3738 }
3739 }
3740 catch ( BuildManagerException e )
3741 {
3742 throw logAndCreateException( "Error while creating enqueuing object.", e );
3743 }
3744 }
3745
3746 private void createProjectScmRootForProjectGroup( ProjectGroup projectGroup )
3747 throws ContinuumException
3748 {
3749 List<Project> projectsList;
3750
3751 projectsList = getProjectsInBuildOrder( projectDao.getProjectsWithDependenciesByGroupId(
3752 projectGroup.getId() ) );
3753
3754 List<ProjectScmRoot> scmRoots = getProjectScmRootByProjectGroup( projectGroup.getId() );
3755
3756 String url = "";
3757
3758 for ( Project project : projectsList )
3759 {
3760 boolean found = false;
3761
3762 if ( StringUtils.isEmpty( url ) || !project.getScmUrl().startsWith( url ) )
3763 {
3764
3765 url = project.getScmUrl();
3766
3767
3768 for ( ProjectScmRoot scmRoot : scmRoots )
3769 {
3770 if ( url.startsWith( scmRoot.getScmRootAddress() ) )
3771 {
3772 found = true;
3773 }
3774 }
3775
3776 if ( !found )
3777 {
3778 createProjectScmRoot( projectGroup, url );
3779 }
3780 }
3781 }
3782 }
3783
3784 private ProjectScmRoot createProjectScmRoot( ProjectGroup projectGroup, String url )
3785 throws ContinuumException
3786 {
3787 if ( StringUtils.isEmpty( url ) )
3788 {
3789 return null;
3790 }
3791
3792 try
3793 {
3794 ProjectScmRoot scmRoot = projectScmRootDao.getProjectScmRootByProjectGroupAndScmRootAddress(
3795 projectGroup.getId(), url );
3796
3797 if ( scmRoot != null )
3798 {
3799 return null;
3800 }
3801
3802 ProjectScmRoot projectScmRoot = new ProjectScmRoot();
3803
3804 projectScmRoot.setProjectGroup( projectGroup );
3805
3806 projectScmRoot.setScmRootAddress( url );
3807
3808 return projectScmRootDao.addProjectScmRoot( projectScmRoot );
3809 }
3810 catch ( ContinuumStoreException e )
3811 {
3812 throw new ContinuumException( "Error while creating project scm root with scm root address:" + url );
3813 }
3814 }
3815
3816 private void updateProjectScmRoot( ProjectScmRoot oldScmRoot, Project project )
3817 throws ContinuumException
3818 {
3819 try
3820 {
3821 removeProjectScmRoot( oldScmRoot );
3822 ProjectScmRoot scmRoot = projectScmRootDao.getProjectScmRootByProjectGroupAndScmRootAddress(
3823 project.getProjectGroup().getId(), project.getScmUrl() );
3824 if ( scmRoot == null )
3825 {
3826 ProjectScmRoot newScmRoot = new ProjectScmRoot();
3827 if ( project.getScmUrl().equals( oldScmRoot.getScmRootAddress() ) )
3828 {
3829 BeanUtils.copyProperties( oldScmRoot, newScmRoot, new String[]{"id", "projectGroup"} );
3830 }
3831 else
3832 {
3833 newScmRoot.setScmRootAddress( project.getScmUrl() );
3834 }
3835 newScmRoot.setProjectGroup( project.getProjectGroup() );
3836 projectScmRootDao.addProjectScmRoot( newScmRoot );
3837 }
3838 }
3839 catch ( ContinuumStoreException ex )
3840 {
3841 throw logAndCreateException( "Error while updating project.", ex );
3842 }
3843 }
3844
3845 private boolean isProjectInReleaseStage( Project project )
3846 throws ContinuumException
3847 {
3848 String releaseId = project.getGroupId() + ":" + project.getArtifactId();
3849 try
3850 {
3851 return taskQueueManager.isProjectInReleaseStage( releaseId );
3852 }
3853 catch ( TaskQueueManagerException e )
3854 {
3855 throw new ContinuumException( "Error occurred while checking if project is currently being released.", e );
3856 }
3857 }
3858
3859 private boolean isAnyProjectInGroupInReleaseStage( int projectGroupId )
3860 throws ContinuumException
3861 {
3862 Collection<Project> projects = getProjectsInGroup( projectGroupId );
3863 for ( Project project : projects )
3864 {
3865 if ( isProjectInReleaseStage( project ) )
3866 {
3867 throw new ContinuumException( "Cannot build project group. Project (id=" + project.getId() +
3868 ") in group is currently in release stage." );
3869 }
3870 }
3871 return false;
3872 }
3873
3874 private boolean isAnyProjectsInReleaseStage( List<Project> projects )
3875 throws ContinuumException
3876 {
3877 for ( Project project : projects )
3878 {
3879 if ( isProjectInReleaseStage( project ) )
3880 {
3881 return true;
3882 }
3883 }
3884
3885 return false;
3886 }
3887
3888 private Collection<Project> getProjectsNotInReleaseStage( Collection<Project> projectsList )
3889 throws ContinuumException
3890 {
3891
3892
3893 Collection<Project> filteredProjectsList = new ArrayList<Project>();
3894 for ( Project project : projectsList )
3895 {
3896 if ( !isProjectInReleaseStage( project ) )
3897 {
3898 filteredProjectsList.add( project );
3899 }
3900 else
3901 {
3902 log.warn(
3903 "Project (id=" + project.getId() + ") will not be built. It is currently in the release stage." );
3904 }
3905 }
3906 return filteredProjectsList;
3907 }
3908
3909 private void checkForDuplicateProjectInGroup( ProjectGroup projectGroup, Project projectToCheck,
3910 ContinuumProjectBuildingResult result )
3911 {
3912 List<Project> projectsInGroup = projectGroup.getProjects();
3913
3914 if ( projectsInGroup == null )
3915 {
3916 return;
3917 }
3918
3919 for ( Project project : projectGroup.getProjects() )
3920 {
3921
3922
3923 if ( projectToCheck.getGroupId().equals( project.getGroupId() ) && projectToCheck.getArtifactId().equals(
3924 project.getArtifactId() ) && projectToCheck.getVersion().equals( project.getVersion() ) )
3925 {
3926 result.addError( ContinuumProjectBuildingResult.ERROR_DUPLICATE_PROJECTS );
3927 return;
3928 }
3929 }
3930 }
3931
3932 private boolean isProjectOkToBuild( int projectId, int buildDefinitionId )
3933 throws ContinuumException
3934 {
3935 if ( configurationService.isDistributedBuildEnabled() )
3936 {
3937 if ( !distributedBuildManager.isProjectInAnyPrepareBuildQueue( projectId, buildDefinitionId ) &&
3938 !distributedBuildManager.isProjectInAnyBuildQueue( projectId, buildDefinitionId ) &&
3939 !distributedBuildManager.isProjectCurrentlyPreparingBuild( projectId, buildDefinitionId ) &&
3940 !distributedBuildManager.isProjectCurrentlyBuilding( projectId, buildDefinitionId ) )
3941 {
3942 return true;
3943 }
3944 }
3945 else
3946 {
3947 try
3948 {
3949 if ( !parallelBuildsManager.isInAnyBuildQueue( projectId, buildDefinitionId ) &&
3950 !parallelBuildsManager.isInAnyCheckoutQueue( projectId ) &&
3951 !parallelBuildsManager.isInPrepareBuildQueue( projectId ) &&
3952 !parallelBuildsManager.isProjectCurrentlyPreparingBuild( projectId ) )
3953 {
3954 if ( parallelBuildsManager.isInAnyCheckoutQueue( projectId ) )
3955 {
3956 parallelBuildsManager.removeProjectFromCheckoutQueue( projectId );
3957 }
3958
3959 return true;
3960 }
3961 }
3962 catch ( BuildManagerException e )
3963 {
3964 throw new ContinuumException( e.getMessage(), e );
3965 }
3966 }
3967
3968 return false;
3969 }
3970
3971 void setTaskQueueManager( TaskQueueManager taskQueueManager )
3972 {
3973 this.taskQueueManager = taskQueueManager;
3974 }
3975
3976 void setProjectDao( ProjectDao projectDao )
3977 {
3978 this.projectDao = projectDao;
3979 }
3980
3981 public DistributedBuildManager getDistributedBuildManager()
3982 {
3983 return distributedBuildManager;
3984 }
3985 }