EMMA Coverage Report (generated Sun Sep 18 11:34:27 PHT 2011)
[all classes][org.apache.maven.continuum.buildcontroller]

COVERAGE SUMMARY FOR SOURCE FILE [DefaultBuildController.java]

nameclass, %method, %block, %line, %
DefaultBuildController.java100% (1/1)73%  (11/15)55%  (586/1063)53%  (125.7/238)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class DefaultBuildController100% (1/1)73%  (11/15)55%  (586/1063)53%  (125.7/238)
getValidationMessages (ScmRepositoryException): String 0%   (0/1)0%   (0/36)0%   (0/8)
makeAndStoreBuildResult (BuildContext, String): BuildResult 0%   (0/1)0%   (0/59)0%   (0/16)
updateBuildResult (BuildContext, String): void 0%   (0/1)0%   (0/58)0%   (0/17)
updateBuildResult (BuildResult, BuildContext): void 0%   (0/1)0%   (0/21)0%   (0/5)
performAction (String, BuildContext): void 100% (1/1)15%  (18/122)14%  (3/22)
checkAllChangesUnknown (List): boolean 100% (1/1)24%  (8/34)20%  (1.4/7)
build (int, int, int, ScmResult): void 100% (1/1)64%  (79/124)62%  (19.3/31)
shouldBuild (BuildContext): boolean 100% (1/1)68%  (148/218)68%  (33.5/49)
endBuild (BuildContext): void 100% (1/1)75%  (62/83)76%  (9.9/13)
startBuild (BuildContext): void 100% (1/1)76%  (22/29)78%  (7/9)
initializeBuildContext (int, int, int, ScmResult): BuildContext 100% (1/1)85%  (68/80)87%  (20/23)
checkProjectDependencies (BuildContext): void 100% (1/1)90%  (140/155)82%  (23/28)
checkScmResult (BuildContext): boolean 100% (1/1)92%  (34/37)83%  (6.7/8)
<static initializer> 100% (1/1)100% (4/4)100% (1/1)
DefaultBuildController (): void 100% (1/1)100% (3/3)100% (1/1)

1package org.apache.maven.continuum.buildcontroller;
2 
3/*
4 * Licensed to the Apache Software Foundation (ASF) under one
5 * or more contributor license agreements.  See the NOTICE file
6 * distributed with this work for additional information
7 * regarding copyright ownership.  The ASF licenses this file
8 * to you under the Apache License, Version 2.0 (the
9 * "License"); you may not use this file except in compliance
10 * with the License.  You may obtain a copy of the License at
11 *
12 *   http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing,
15 * software distributed under the License is distributed on an
16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 * KIND, either express or implied.  See the License for the
18 * specific language governing permissions and limitations
19 * under the License.
20 */
21 
22import java.util.ArrayList;
23import java.util.Iterator;
24import java.util.List;
25import java.util.Map;
26 
27import org.apache.continuum.dao.BuildDefinitionDao;
28import org.apache.continuum.dao.BuildResultDao;
29import org.apache.continuum.dao.ProjectDao;
30import org.apache.continuum.dao.ProjectScmRootDao;
31import org.apache.continuum.model.project.ProjectScmRoot;
32import org.apache.continuum.utils.ContinuumUtils;
33import org.apache.maven.continuum.core.action.AbstractContinuumAction;
34import org.apache.maven.continuum.core.action.ExecuteBuilderContinuumAction;
35import org.apache.maven.continuum.execution.ContinuumBuildExecutor;
36import org.apache.maven.continuum.execution.ContinuumBuildExecutorConstants;
37import org.apache.maven.continuum.execution.manager.BuildExecutorManager;
38import org.apache.maven.continuum.model.project.BuildDefinition;
39import org.apache.maven.continuum.model.project.BuildResult;
40import org.apache.maven.continuum.model.project.Project;
41import org.apache.maven.continuum.model.project.ProjectDependency;
42import org.apache.maven.continuum.model.scm.ChangeFile;
43import org.apache.maven.continuum.model.scm.ChangeSet;
44import org.apache.maven.continuum.model.scm.ScmResult;
45import org.apache.maven.continuum.notification.ContinuumNotificationDispatcher;
46import org.apache.maven.continuum.project.ContinuumProjectState;
47import org.apache.maven.continuum.store.ContinuumObjectNotFoundException;
48import org.apache.maven.continuum.store.ContinuumStoreException;
49import org.apache.maven.continuum.utils.WorkingDirectoryService;
50import org.apache.maven.scm.ScmException;
51import org.apache.maven.scm.repository.ScmRepositoryException;
52import org.codehaus.plexus.action.ActionManager;
53import org.codehaus.plexus.action.ActionNotFoundException;
54import org.codehaus.plexus.taskqueue.execution.TaskExecutionException;
55import org.slf4j.Logger;
56import org.slf4j.LoggerFactory;
57 
58/**
59 * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l</a>
60 * @version $Id: DefaultBuildController.java 793475 2009-07-13 07:37:50Z ctan $
61 * @plexus.component role="org.apache.maven.continuum.buildcontroller.BuildController" role-hint="default"
62 */
63public class DefaultBuildController
64    implements BuildController
65{
66    private static final Logger log = LoggerFactory.getLogger( DefaultBuildController.class );
67 
68    /**
69     * @plexus.requirement
70     */
71    private BuildDefinitionDao buildDefinitionDao;
72 
73    /**
74     * @plexus.requirement
75     */
76    private BuildResultDao buildResultDao;
77 
78    /**
79     * @plexus.requirement
80     */
81    private ProjectDao projectDao;
82 
83    /**
84     * @plexus.requirement
85     */
86    private ProjectScmRootDao projectScmRootDao;
87 
88    /**
89     * @plexus.requirement
90     */
91    private ContinuumNotificationDispatcher notifierDispatcher;
92 
93    /**
94     * @plexus.requirement
95     */
96    private ActionManager actionManager;
97 
98    /**
99     * @plexus.requirement
100     */
101    private WorkingDirectoryService workingDirectoryService;
102 
103    /**
104     * @plexus.requirement
105     */
106    private BuildExecutorManager buildExecutorManager;
107 
108    // ----------------------------------------------------------------------
109    // BuildController Implementation
110    // ----------------------------------------------------------------------
111 
112    /**
113     * @param projectId
114     * @param buildDefinitionId
115     * @param trigger
116     * @throws TaskExecutionException
117     */
118    public void build( int projectId, int buildDefinitionId, int trigger, ScmResult scmResult )
119        throws TaskExecutionException
120    {
121        log.info( "Initializing build" );
122        BuildContext context = initializeBuildContext( projectId, buildDefinitionId, trigger, scmResult );
123 
124        // ignore this if AlwaysBuild ?
125        if ( !checkScmResult( context ) )
126        {
127            log.info( "Error updating from SCM, not building" );
128            return;
129        }
130 
131        log.info( "Starting build of " + context.getProject().getName() );
132        startBuild( context );
133 
134        try
135        {
136            checkProjectDependencies( context );
137 
138            if ( !shouldBuild( context ) )
139            {
140                return;
141            }
142 
143            Map<String, Object> actionContext = context.getActionContext();
144 
145            try
146            {
147                performAction( "update-project-from-working-directory", context );
148            }
149            catch ( TaskExecutionException e )
150            {
151                updateBuildResult( context, ContinuumUtils.throwableToString( e ) );
152 
153                //just log the error but don't stop the build from progressing in order not to suppress any build result messages there
154                log.error( "Error executing action update-project-from-working-directory '", e );
155            }
156 
157            performAction( "execute-builder", context );
158 
159            performAction( "deploy-artifact", context );
160 
161            context.setCancelled( ExecuteBuilderContinuumAction.isCancelled( actionContext ) );
162 
163            String s = AbstractContinuumAction.getBuildId( actionContext, null );
164 
165            if ( s != null && !context.isCancelled() )
166            {
167                try
168                {
169                    context.setBuildResult( buildResultDao.getBuildResult( Integer.valueOf( s ) ) );
170                }
171                catch ( NumberFormatException e )
172                {
173                    throw new TaskExecutionException( "Internal error: build id not an integer", e );
174                }
175                catch ( ContinuumObjectNotFoundException e )
176                {
177                    throw new TaskExecutionException( "Internal error: Cannot find build result", e );
178                }
179                catch ( ContinuumStoreException e )
180                {
181                    throw new TaskExecutionException( "Error loading build result", e );
182                }
183            }
184        }
185        finally
186        {
187            endBuild( context );
188        }
189    }
190 
191    /**
192     * Checks if the build should be marked as ERROR and notifies the end of the build.
193     *
194     * @param context
195     * @throws TaskExecutionException
196     */
197    private void endBuild( BuildContext context )
198        throws TaskExecutionException
199    {
200        Project project = context.getProject();
201 
202        try
203        {
204            if ( project.getState() != ContinuumProjectState.NEW &&
205                project.getState() != ContinuumProjectState.CHECKEDOUT &&
206                project.getState() != ContinuumProjectState.OK && project.getState() != ContinuumProjectState.FAILED &&
207                project.getState() != ContinuumProjectState.ERROR && !context.isCancelled() )
208            {
209                try
210                {
211                    String s = AbstractContinuumAction.getBuildId( context.getActionContext(), null );
212 
213                    if ( s != null )
214                    {
215                        BuildResult buildResult = buildResultDao.getBuildResult( Integer.valueOf( s ) );
216                        project.setState( buildResult.getState() );
217                        projectDao.updateProject( project );
218                    }
219                }
220                catch ( ContinuumStoreException e )
221                {
222                    throw new TaskExecutionException( "Error storing the project", e );
223                }
224            }
225        }
226        finally
227        {
228            if ( !context.isCancelled() )
229            {
230                notifierDispatcher.buildComplete( project, context.getBuildDefinition(), context.getBuildResult() );
231            }
232        }
233    }
234 
235    private void updateBuildResult( BuildContext context, String error )
236        throws TaskExecutionException
237    {
238        BuildResult build = context.getBuildResult();
239 
240        if ( build == null )
241        {
242            build = makeAndStoreBuildResult( context, error );
243        }
244        else
245        {
246            updateBuildResult( build, context );
247 
248            build.setError( error );
249 
250            try
251            {
252                buildResultDao.updateBuildResult( build );
253 
254                build = buildResultDao.getBuildResult( build.getId() );
255 
256                context.setBuildResult( build );
257            }
258            catch ( ContinuumStoreException e )
259            {
260                throw new TaskExecutionException( "Error updating build result", e );
261            }
262        }
263 
264        context.getProject().setState( build.getState() );
265 
266        try
267        {
268            projectDao.updateProject( context.getProject() );
269        }
270        catch ( ContinuumStoreException e )
271        {
272            throw new TaskExecutionException( "Error updating project", e );
273        }
274    }
275 
276    private void updateBuildResult( BuildResult build, BuildContext context )
277    {
278        if ( build.getScmResult() == null && context.getScmResult() != null )
279        {
280            build.setScmResult( context.getScmResult() );
281        }
282 
283        if ( build.getModifiedDependencies() == null && context.getModifiedDependencies() != null )
284        {
285            build.setModifiedDependencies( context.getModifiedDependencies() );
286        }
287    }
288 
289    private void startBuild( BuildContext context )
290        throws TaskExecutionException
291    {
292 
293        Project project = context.getProject();
294 
295        project.setOldState( project.getState() );
296 
297        project.setState( ContinuumProjectState.BUILDING );
298 
299        try
300        {
301            projectDao.updateProject( project );
302        }
303        catch ( ContinuumStoreException e )
304        {
305            throw new TaskExecutionException( "Error persisting project", e );
306        }
307 
308        notifierDispatcher.buildStarted( project, context.getBuildDefinition() );
309 
310    }
311 
312    /**
313     * Initializes a BuildContext for the build.
314     *
315     * @param projectId
316     * @param buildDefinitionId
317     * @param trigger
318     * @return
319     * @throws TaskExecutionException
320     */
321    protected BuildContext initializeBuildContext( int projectId, int buildDefinitionId, int trigger,
322                                                   ScmResult scmResult )
323        throws TaskExecutionException
324    {
325        BuildContext context = new BuildContext();
326 
327        context.setStartTime( System.currentTimeMillis() );
328 
329        context.setTrigger( trigger );
330 
331        try
332        {
333            Project project = projectDao.getProject( projectId );
334 
335            context.setProject( project );
336 
337            BuildDefinition buildDefinition = buildDefinitionDao.getBuildDefinition( buildDefinitionId );
338 
339            context.setBuildDefinition( buildDefinition );
340 
341            BuildResult oldBuildResult =
342                buildResultDao.getLatestBuildResultForBuildDefinition( projectId, buildDefinitionId );
343 
344            context.setOldBuildResult( oldBuildResult );
345 
346            context.setScmResult( scmResult );
347 
348            // CONTINUUM-1871 olamy if continuum is killed during building oldBuildResult will have a endTime 0
349            // this means all changes since the project has been loaded in continuum will be in memory
350            // now we will load all BuildResult with an Id bigger or equals than the oldBuildResult one
351            //if ( oldBuildResult != null )
352            //{
353            //    context.setOldScmResult(
354            //        getOldScmResults( projectId, oldBuildResult.getBuildNumber(), oldBuildResult.getEndTime() ) );
355            //}
356        }
357        catch ( ContinuumStoreException e )
358        {
359            throw new TaskExecutionException( "Error initializing the build context", e );
360        }
361 
362        Map<String, Object> actionContext = context.getActionContext();
363 
364        AbstractContinuumAction.setProjectId( actionContext, projectId );
365 
366        AbstractContinuumAction.setProject( actionContext, context.getProject() );
367 
368        AbstractContinuumAction.setBuildDefinitionId( actionContext, buildDefinitionId );
369 
370        AbstractContinuumAction.setBuildDefinition( actionContext, context.getBuildDefinition() );
371 
372        AbstractContinuumAction.setTrigger( actionContext, trigger );
373 
374        AbstractContinuumAction.setScmResult( actionContext, context.getScmResult() );
375 
376        if ( context.getOldBuildResult() != null )
377        {
378            AbstractContinuumAction.setOldBuildId( actionContext, context.getOldBuildResult().getId() );
379        }
380 
381        return context;
382    }
383 
384    private void performAction( String actionName, BuildContext context )
385        throws TaskExecutionException
386    {
387        String error;
388        TaskExecutionException exception;
389 
390        try
391        {
392            log.info( "Performing action " + actionName );
393            actionManager.lookup( actionName ).execute( context.getActionContext() );
394            return;
395        }
396        catch ( ActionNotFoundException e )
397        {
398            error = ContinuumUtils.throwableToString( e );
399            exception = new TaskExecutionException( "Error looking up action '" + actionName + "'", e );
400        }
401        catch ( ScmRepositoryException e )
402        {
403            error = getValidationMessages( e ) + "\n" + ContinuumUtils.throwableToString( e );
404 
405            exception = new TaskExecutionException( "SCM error while executing '" + actionName + "'", e );
406        }
407        catch ( ScmException e )
408        {
409            error = ContinuumUtils.throwableToString( e );
410 
411            exception = new TaskExecutionException( "SCM error while executing '" + actionName + "'", e );
412        }
413        catch ( Exception e )
414        {
415            exception = new TaskExecutionException( "Error executing action '" + actionName + "'", e );
416            error = ContinuumUtils.throwableToString( exception );
417        }
418 
419        // TODO: clean this up. We catch the original exception from the action, and then update the buildresult
420        // for it - we need to because of the specialized error message for SCM.
421        // If updating the buildresult fails, log the previous error and throw the new one.
422        // If updating the buildresult succeeds, throw the original exception. The build result should NOT
423        // be updated again - a TaskExecutionException is final, no further action should be taken upon it.
424 
425        try
426        {
427            updateBuildResult( context, error );
428        }
429        catch ( TaskExecutionException e )
430        {
431            log.error( "Error updating build result after receiving the following exception: ", exception );
432            throw e;
433        }
434 
435        throw exception;
436    }
437 
438    protected boolean shouldBuild( BuildContext context )
439        throws TaskExecutionException
440    {
441        BuildDefinition buildDefinition = context.getBuildDefinition();
442        if ( buildDefinition.isBuildFresh() )
443        {
444            log.info( "FreshBuild configured, building" );
445            return true;
446        }
447        if ( buildDefinition.isAlwaysBuild() )
448        {
449            log.info( "AlwaysBuild configured, building" );
450            return true;
451        }
452        if ( context.getOldBuildResult() == null )
453        {
454            log.info( "The project was never be built with the current build definition, building" );
455            return true;
456        }
457 
458        Project project = context.getProject();
459 
460        //CONTINUUM-1428
461        if ( project.getOldState() == ContinuumProjectState.ERROR ||
462            context.getOldBuildResult().getState() == ContinuumProjectState.ERROR )
463        {
464            log.info( "Latest state was 'ERROR', building" );
465            return true;
466        }
467 
468        if ( context.getTrigger() == ContinuumProjectState.TRIGGER_FORCED )
469        {
470            log.info( "The project build is forced, building" );
471            return true;
472        }
473 
474        boolean shouldBuild = false;
475 
476        boolean allChangesUnknown = true;
477 
478        if ( project.getOldState() != ContinuumProjectState.NEW &&
479            project.getOldState() != ContinuumProjectState.CHECKEDOUT &&
480            context.getTrigger() != ContinuumProjectState.TRIGGER_FORCED &&
481            project.getState() != ContinuumProjectState.NEW && project.getState() != ContinuumProjectState.CHECKEDOUT )
482        {
483            // Check SCM changes
484            if ( context.getScmResult() != null )
485            {
486                allChangesUnknown = checkAllChangesUnknown( context.getScmResult().getChanges() );
487            }
488 
489            if ( allChangesUnknown )
490            {
491                if ( context.getScmResult() != null && !context.getScmResult().getChanges().isEmpty() )
492                {
493                    log.info(
494                        "The project was not built because all changes are unknown (maybe local modifications or ignored files not defined in your SCM tool." );
495                }
496                else
497                {
498                    log.info(
499                        "The project was not built because no changes were detected in sources since the last build." );
500                }
501            }
502 
503            // Check dependencies changes
504            if ( context.getModifiedDependencies() != null && !context.getModifiedDependencies().isEmpty() )
505            {
506                log.info( "Found dependencies changes, building" );
507                shouldBuild = true;
508            }
509        }
510 
511        // Check changes
512        if ( !shouldBuild && ( ( !allChangesUnknown && context.getScmResult() != null && !context.getScmResult().getChanges().isEmpty() ) ||
513            project.getExecutorId().equals( ContinuumBuildExecutorConstants.MAVEN_TWO_BUILD_EXECUTOR ) ) )
514        {
515            try
516            {
517                ContinuumBuildExecutor executor = buildExecutorManager.getBuildExecutor( project.getExecutorId() );
518 
519                if ( executor == null )
520                {
521                    log.warn( "No continuum build executor found for project " + project.getId() + 
522                              " with executor '" + project.getExecutorId() + "'" );
523                }
524                else if ( context.getScmResult() != null )
525                {
526                    shouldBuild = executor.shouldBuild( context.getScmResult().getChanges(), project,
527                                                        workingDirectoryService.getWorkingDirectory( project ),
528                                                        context.getBuildDefinition() );
529                }
530            }
531            catch ( Exception e )
532            {
533                updateBuildResult( context, ContinuumUtils.throwableToString( e ) );
534                throw new TaskExecutionException( "Can't determine if the project should build or not", e );
535            }
536        }
537 
538        if ( shouldBuild )
539        {
540            log.info( "Changes found in the current project, building" );
541        }
542        else
543        {
544            project.setState( project.getOldState() );
545 
546            project.setOldState( 0 );
547 
548            try
549            {
550                projectDao.updateProject( project );
551            }
552            catch ( ContinuumStoreException e )
553            {
554                throw new TaskExecutionException( "Error storing project", e );
555            }
556            log.info( "No changes in the current project, not building" );
557 
558        }
559 
560        return shouldBuild;
561    }
562 
563    private boolean checkAllChangesUnknown( List<ChangeSet> changes )
564    {
565        for ( ChangeSet changeSet : changes )
566        {
567            List<ChangeFile> changeFiles = changeSet.getFiles();
568 
569            for ( ChangeFile changeFile : changeFiles )
570            {
571                if ( !"unknown".equalsIgnoreCase( changeFile.getStatus() ) )
572                {
573                    return false;
574                }
575            }
576        }
577 
578        return true;
579    }
580 
581    private String getValidationMessages( ScmRepositoryException ex )
582    {
583        List<String> messages = ex.getValidationMessages();
584 
585        StringBuffer message = new StringBuffer();
586 
587        if ( messages != null && !messages.isEmpty() )
588        {
589            for ( Iterator<String> i = messages.iterator(); i.hasNext(); )
590            {
591                message.append( i.next() );
592 
593                if ( i.hasNext() )
594                {
595                    message.append( System.getProperty( "line.separator" ) );
596                }
597            }
598        }
599        return message.toString();
600    }
601 
602    protected void checkProjectDependencies( BuildContext context )
603    {
604        if ( context.getOldBuildResult() == null )
605        {
606            return;
607        }
608 
609        try
610        {
611            Project project = projectDao.getProjectWithDependencies( context.getProject().getId() );
612            List<ProjectDependency> dependencies = project.getDependencies();
613 
614            if ( dependencies == null )
615            {
616                dependencies = new ArrayList<ProjectDependency>();
617            }
618 
619            if ( project.getParent() != null )
620            {
621                dependencies.add( project.getParent() );
622            }
623 
624            if ( dependencies.isEmpty() )
625            {
626                return;
627            }
628 
629            List<ProjectDependency> modifiedDependencies = new ArrayList<ProjectDependency>();
630 
631            for ( ProjectDependency dep : dependencies )
632            {
633                Project dependencyProject =
634                    projectDao.getProject( dep.getGroupId(), dep.getArtifactId(), dep.getVersion() );
635 
636                if ( dependencyProject != null )
637                {
638                    long nbBuild = buildResultDao.getNbBuildResultsInSuccessForProject( dependencyProject.getId(),
639                                                                                        context.getOldBuildResult().getEndTime() );
640                    if ( nbBuild > 0 )
641                    {
642                        log.debug( "Dependency changed: " + dep.getGroupId() + ":" + dep.getArtifactId() + ":" +
643                            dep.getVersion() );
644                        modifiedDependencies.add( dep );
645                    }
646                    else
647                    {
648                        log.debug( "Dependency not changed: " + dep.getGroupId() + ":" + dep.getArtifactId() + ":" +
649                            dep.getVersion() );
650                    }
651                }
652                else
653                {
654                    log.debug( "Skip non Continuum project: " + dep.getGroupId() + ":" + dep.getArtifactId() + ":" +
655                        dep.getVersion() );
656                }
657            }
658 
659            context.setModifiedDependencies( modifiedDependencies );
660            AbstractContinuumAction.setUpdatedDependencies( context.getActionContext(), modifiedDependencies );
661        }
662        catch ( ContinuumStoreException e )
663        {
664            log.warn( "Can't get the project dependencies", e );
665        }
666    }
667 
668    // ----------------------------------------------------------------------
669    //
670    // ----------------------------------------------------------------------
671 
672    private BuildResult makeAndStoreBuildResult( BuildContext context, String error )
673        throws TaskExecutionException
674    {
675        // Project project, ScmResult scmResult, long startTime, int trigger )
676        // project, scmResult, startTime, trigger );
677 
678        BuildResult build = new BuildResult();
679 
680        build.setState( ContinuumProjectState.ERROR );
681 
682        build.setTrigger( context.getTrigger() );
683 
684        build.setStartTime( context.getStartTime() );
685 
686        build.setEndTime( System.currentTimeMillis() );
687 
688        updateBuildResult( build, context );
689 
690        build.setScmResult( context.getScmResult() );
691 
692        build.setBuildDefinition( context.getBuildDefinition() );
693 
694        if ( error != null )
695        {
696            build.setError( error );
697        }
698 
699        try
700        {
701            buildResultDao.addBuildResult( context.getProject(), build );
702 
703            build = buildResultDao.getBuildResult( build.getId() );
704 
705            context.setBuildResult( build );
706 
707            return build;
708        }
709        catch ( ContinuumStoreException e )
710        {
711            throw new TaskExecutionException( "Error storing build result", e );
712        }
713    }
714 
715    /**
716     * Check to see if there was a error while checking out/updating the project
717     *
718     * @param context The build context
719     * @return true if scm result is ok
720     * @throws TaskExecutionException
721     */
722    private boolean checkScmResult( BuildContext context )
723        throws TaskExecutionException
724    {
725        Project project = context.getProject();
726 
727        int projectGroupId = project.getProjectGroup().getId();
728 
729        List<ProjectScmRoot> scmRoots = projectScmRootDao.getProjectScmRootByProjectGroup( projectGroupId );
730 
731        for ( ProjectScmRoot projectScmRoot : scmRoots )
732        {
733            if ( project.getScmUrl().startsWith( projectScmRoot.getScmRootAddress() ) )
734            {
735                if ( projectScmRoot.getState() == ContinuumProjectState.UPDATED )
736                {
737                    return true;
738                }
739 
740                break;
741            }
742        }
743 
744        return false;
745    }
746}

[all classes][org.apache.maven.continuum.buildcontroller]
EMMA 2.0.5312 (C) Vladimir Roubtsov