1 package org.apache.maven.continuum.buildqueue.evaluator;
2
3 /*
4 * Licensed to the Apache Software Foundation (ASF) under one
5 * or more contributor license agreements. See the NOTICE file
6 * distributed with this work for additional information
7 * regarding copyright ownership. The ASF licenses this file
8 * to you under the Apache License, Version 2.0 (the
9 * "License"); you may not use this file except in compliance
10 * with the License. You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing,
15 * software distributed under the License is distributed on an
16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 * KIND, either express or implied. See the License for the
18 * specific language governing permissions and limitations
19 * under the License.
20 */
21
22 import org.apache.continuum.taskqueue.BuildProjectTask;
23 import org.apache.maven.continuum.project.ContinuumProjectState;
24 import org.codehaus.plexus.taskqueue.TaskViabilityEvaluator;
25
26 import java.util.ArrayList;
27 import java.util.Collection;
28 import java.util.HashMap;
29 import java.util.List;
30 import java.util.Map;
31
32 /**
33 * @author <a href="mailto:trygvis@inamo.no">Trygve Laugstøl</a>
34 * @version $Id: BuildProjectTaskViabilityEvaluator.java 1372260 2012-08-13 04:29:09Z brett $
35 */
36 public class BuildProjectTaskViabilityEvaluator
37 implements TaskViabilityEvaluator
38 {
39 /**
40 * @plexus.configuration
41 */
42 private long requiredBuildInterval;
43
44 // ----------------------------------------------------------------------
45 // TaskViabilityEvaluator Implementation
46 // ----------------------------------------------------------------------
47
48 /**
49 * Removes duplicate tasks from the list. A duplicate task is one with the same
50 * build definition and that's scheduled within the required build interval.
51 * <p/>
52 * <p/>
53 * ∀ <sub>t1, t2 ∈ tasks</sub> [ t1 ≠ t2 ∧ t2.buildDefinition = t2.buildDefinition]:
54 * if ( t2.timestamp - t1.timestamp < requiredBuildInterval ) remove( t2 ).
55 * </p>
56 *
57 * @param tasks A list of queued tasks to evaluate
58 * @return a list of tasks with duplicates removed
59 */
60 public Collection<BuildProjectTask> evaluate( Collection tasks )
61 {
62 // ----------------------------------------------------------------------
63 // This code makes a Map with Lists with one list per project. For each
64 // task in the list it puts it in the list for the project that's
65 // requested for a build. Then all each of the lists with tasks is
66 // checked for validity and a list of tasks to remove is returned.
67 // ----------------------------------------------------------------------
68
69 Map<Integer, List<BuildProjectTask>> projects = new HashMap<Integer, List<BuildProjectTask>>();
70
71 for ( BuildProjectTask task : (Collection<BuildProjectTask>) tasks )
72 {
73 int key = task.getProjectId();
74
75 List<BuildProjectTask> projectTasks = projects.get( key );
76
77 if ( projectTasks == null )
78 {
79 projectTasks = new ArrayList<BuildProjectTask>();
80
81 projects.put( key, projectTasks );
82 }
83
84 projectTasks.add( task );
85 }
86
87 List<BuildProjectTask> toBeRemoved = new ArrayList<BuildProjectTask>();
88
89 for ( List<BuildProjectTask> projectTasks : projects.values() )
90 {
91 toBeRemoved.addAll( checkTasks( projectTasks ) );
92 }
93
94 return toBeRemoved;
95 }
96
97 // ----------------------------------------------------------------------
98 //
99 // ----------------------------------------------------------------------
100
101 private List<BuildProjectTask> checkTasks( List<BuildProjectTask> list )
102 {
103 List<BuildProjectTask> toBeRemoved = new ArrayList<BuildProjectTask>();
104
105 for ( BuildProjectTask buildProjectTask : list )
106 {
107 for ( BuildProjectTask task : list )
108 {
109 // check if it's the same task
110 if ( buildProjectTask == task ||
111 buildProjectTask.getBuildDefinitionId() != task.getBuildDefinitionId() )
112 {
113 continue;
114 }
115
116 // ----------------------------------------------------------------------
117 // If this build is forces, don't remove it
118 // ----------------------------------------------------------------------
119
120 if ( task.getBuildTrigger().getTrigger() == ContinuumProjectState.TRIGGER_FORCED )
121 {
122 continue;
123 }
124
125 // ----------------------------------------------------------------------
126 //
127 // ----------------------------------------------------------------------
128
129 long interval = task.getTimestamp() - buildProjectTask.getTimestamp();
130
131 if ( interval < requiredBuildInterval )
132 {
133 toBeRemoved.add( buildProjectTask );
134 }
135 }
136 }
137
138 return toBeRemoved;
139 }
140 }