KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sourceforge > cruisecontrol > sourcecontrols > Compound


1 /********************************************************************************
2  * CruiseControl, a Continuous Integration Toolkit
3  * Copyright (c) 2001-2003, ThoughtWorks, Inc.
4  * 651 W Washington Ave. Suite 600
5  * Chicago, IL 60661 USA
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * + Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  *
15  * + Redistributions in binary form must reproduce the above
16  * copyright notice, this list of conditions and the following
17  * disclaimer in the documentation and/or other materials provided
18  * with the distribution.
19  *
20  * + Neither the name of ThoughtWorks, Inc., CruiseControl, nor the
21  * names of its contributors may be used to endorse or promote
22  * products derived from this software without specific prior
23  * written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
29  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36  ********************************************************************************/

37 package net.sourceforge.cruisecontrol.sourcecontrols;
38
39 import java.util.ArrayList JavaDoc;
40 import java.util.Date JavaDoc;
41 import java.util.Hashtable JavaDoc;
42 import java.util.Iterator JavaDoc;
43 import java.util.List JavaDoc;
44 import java.util.Map JavaDoc;
45
46 import net.sourceforge.cruisecontrol.CruiseControlException;
47 import net.sourceforge.cruisecontrol.SourceControl;
48 import net.sourceforge.cruisecontrol.util.ValidationHelper;
49
50 /**
51  * This class implements a Compound source control with one triggers
52  * section and one targets section.
53  *
54  * The triggers section contains one or more source controls that act
55  * as triggers for the modifications, i.e. the modificationset
56  * returned will be empty unless one or more of the source
57  * controls in the triggers section returns a non-empty
58  * modification list.
59  *
60  * The targets section contains source controls for targets that will
61  * be built (if modified) if and only if any of the source controls
62  * in the triggers section is modified.
63  *
64  * It is possible to add the trigger modifications to the list of
65  * returned modifications if the "includeTriggerChanges"
66  * attribute is set to true in the <compound...> tag corresponding to
67  * this class.
68  *
69  * The following is an example of how to use this source control in
70  * the config.xml file:
71  *
72  * &lt;modificationset quietperiod="1" &gt;
73  * &lt;compound includeTriggerChanges="false"&gt;
74  * &lt;triggers&gt;
75  * &lt;filesystem folder="./mod_file.txt" /&gt;
76  * &lt;/triggers&gt;
77  * &lt;targets&gt;
78  * &lt;cvs
79  * cvsroot=":pserver:user@cvs_repo.com:/cvs"
80  * /&gt;
81  * &lt;/targets&gt;
82  * &lt;/compound&gt;
83  * &lt;/modificationset&gt;
84  *
85  * @author <a HREF="mailto:will.gwaltney@sas.com">Will Gwaltney</a>
86  */

87 public class Compound implements SourceControl {
88     
89     private Hashtable JavaDoc properties = new Hashtable JavaDoc();
90
91     private Triggers triggers = null;
92     private Targets targets = null;
93     private boolean includeTriggerChanges = false;
94     
95     public Map JavaDoc getProperties() {
96         return this.properties;
97     }
98     
99     /**
100      * Returns a list of modifications since the last build.
101      * First check for any modifications from the triggers.
102      * If there are none, then return an empty list. Otherwise
103      * return the modifications from the targets, and from the
104      * triggers also if the includeTriggerChanges member variable
105      * is true.
106      *
107      * @param lastBuild the date and time of the last build
108      * @param now the current date and time
109      *
110      * @return a list of the modifications
111      */

112     public List JavaDoc getModifications(Date JavaDoc lastBuild, Date JavaDoc now) {
113         List JavaDoc triggerMods;
114         List JavaDoc targetMods = new ArrayList JavaDoc();
115         
116         triggerMods = triggers.getModifications(lastBuild, now);
117         
118         if (!triggerMods.isEmpty()) {
119             targetMods = targets.getModifications(lastBuild, now);
120             // make sure we also pass the properties from the underlying targets
121
properties.putAll(targets.getProperties());
122         }
123
124         if (includeTriggerChanges) {
125             targetMods.addAll(triggerMods);
126             // make sure we also pass the properties from the underlying triggers
127
// TODO: do we really only want this when includeTriggerChanges is set?
128
properties.putAll(triggers.getProperties());
129         }
130         
131         return targetMods;
132     }
133     
134     /**
135      * Confirms that there is exactly one triggers block and one targets
136      * block even if the triggers mods are included and the target
137      * block is empty (otherwise you wouldn't need a compound block
138      * to begin with).
139      *
140      * @throws CruiseControlException if the validation fails
141      */

142     public void validate() throws CruiseControlException {
143         ValidationHelper.assertTrue(triggers != null,
144             "Error: there must be exactly one \"triggers\" block in a compound block.");
145         ValidationHelper.assertTrue(targets != null,
146             "Error: there must be exactly one \"targets\" block in a compound block.");
147     }
148     
149     /**
150      * Creates an empty Triggers object and returns it to
151      * the calling routine to be filled.
152      *
153      * @return an empty Triggers object
154      */

155     public Object JavaDoc createTriggers() {
156         Triggers tr = new Triggers(this);
157         this.triggers = tr;
158         return tr;
159     }
160     
161     /**
162      * Creates an empty Targets object and returns it to
163      * the calling routine to be filled.
164      *
165      * @return an empty Targets object
166      */

167     public Object JavaDoc createTargets() {
168         Targets targ = new Targets(this);
169         this.targets = targ;
170         return targ;
171     }
172     
173     /**
174      * Sets whether to include modifications from the triggers
175      * when getModifications() returns the mods list.
176      *
177      * @param changes true to include trigger changes, false otherwise
178      */

179     public void setIncludeTriggerChanges(String JavaDoc changes) {
180         this.includeTriggerChanges = changes.equalsIgnoreCase("true");
181     }
182     
183     /**
184      * Static inner class, used to define a basis for the Targets and Triggers
185      * classes that are used inside the &lt;compound&gt;-tag.
186      */

187     protected static class Entry implements SourceControl {
188         
189         private Hashtable JavaDoc properties = new Hashtable JavaDoc();
190
191         private List JavaDoc sourceControls = new ArrayList JavaDoc();
192         private Compound parent;
193         
194         /**
195          * Public constructor for reflection purposes.
196          *
197          */

198         public Entry() {
199         }
200         
201         /**
202          * Constructor that the Compound class uses to create
203          * an object of this class.
204          *
205          * @param parent the parent of this object (an
206          * object of class Compound)
207          */

208         public Entry(Compound parent) {
209             this.parent = parent;
210         }
211         
212         public Map JavaDoc getProperties() {
213             return this.properties;
214         }
215
216         /**
217          * Returns a list of modifications since the last build
218          * by querying the sourceControl that this object contains.
219          *
220          * @param lastBuild the date and time of the last build
221          * @param now the current date and time
222          *
223          * @return a list of the modifications
224          */

225         public List JavaDoc getModifications(Date JavaDoc lastBuild, Date JavaDoc now) {
226             List JavaDoc retVal = new ArrayList JavaDoc();
227             
228             for (Iterator JavaDoc it = sourceControls.iterator(); it.hasNext(); ) {
229                 SourceControl sourceControl = (SourceControl) it.next();
230                 retVal.addAll(sourceControl.getModifications(lastBuild, now));
231                 // make sure we also pass the properties from the underlying sourcecontrol
232
properties.putAll(sourceControl.getProperties());
233             }
234             
235             return retVal;
236         }
237         
238         /**
239          * Confirms that the sourceControl that this object wraps
240          * has been set.
241          *
242          * @throws CruiseControlException if the validation fails
243          */

244         public void validate() throws CruiseControlException {
245             if (sourceControls.isEmpty()) {
246                 throw new CruiseControlException("Error: there must be at least one source control in a "
247                         + getEntryName() + " block.");
248             }
249             if (parent == null) {
250                 throw new CruiseControlException("Error: " + getEntryName()
251                         + " blocks must be contained within compound blocks.");
252             }
253         }
254         
255         /**
256          * Adds a sourcecontrol to the list of sourcecontrols that
257          * this object contains.
258          *
259          * @param sc the sourceControl object to add
260          */

261         public void add(SourceControl sc) {
262             sourceControls.add(sc);
263         }
264         
265         /**
266          * Used by validate() to create a subclass-specific error-message.
267          * @return lower-case version of classname without package, e.g. 'triggers'.
268          */

269         private String JavaDoc getEntryName() {
270             String JavaDoc classname = getClass().getName();
271             int index = classname.lastIndexOf('.');
272             if (index != -1) {
273                 return classname.substring(index + 1).toLowerCase();
274             } else {
275                 return classname.toLowerCase();
276             }
277         }
278     }
279
280 }
Popular Tags