KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sourceforge > cruisecontrol > CruiseControlController


1 /********************************************************************************
2  * CruiseControl, a Continuous Integration Toolkit
3  * Copyright (c) 2001-2003, 2006, 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;
38
39 import java.io.File JavaDoc;
40 import java.io.FileInputStream JavaDoc;
41 import java.io.ObjectInputStream JavaDoc;
42 import java.util.ArrayList JavaDoc;
43 import java.util.Collections JavaDoc;
44 import java.util.EventListener JavaDoc;
45 import java.util.Iterator JavaDoc;
46 import java.util.List JavaDoc;
47 import java.util.Properties JavaDoc;
48 import java.util.Set JavaDoc;
49
50 import net.sourceforge.cruisecontrol.config.XMLConfigManager;
51
52 import org.apache.log4j.Logger;
53
54 /**
55  * @author <a HREF="mailto:robertdw@users.sourceforge.net">Robert Watkins</a>
56  */

57 public class CruiseControlController {
58     private static final Logger LOG = Logger.getLogger(CruiseControlController.class);
59     public static final String JavaDoc DEFAULT_CONFIG_FILE_NAME = "config.xml";
60     private File JavaDoc configFile;
61     private List JavaDoc projects = new ArrayList JavaDoc();
62     private BuildQueue buildQueue = new BuildQueue();
63     private Properties JavaDoc versionProperties;
64
65     private List JavaDoc listeners = new ArrayList JavaDoc();
66     private ConfigManager configManager;
67
68     public CruiseControlController() {
69         buildQueue.addListener(new BuildQueueListener());
70     }
71
72     public File JavaDoc getConfigFile() {
73         return configFile;
74     }
75
76     public void setVersionProperties(Properties JavaDoc versionProperties) {
77         this.versionProperties = versionProperties;
78     }
79
80     public Properties JavaDoc getVersionProperties() {
81        return versionProperties;
82     }
83
84     public void setConfigFile(File JavaDoc configFile) throws CruiseControlException {
85         if (configFile == null) {
86             throw new CruiseControlException("No config file");
87         }
88         if (!configFile.exists()) {
89             throw new CruiseControlException("Config file not found: " + configFile.getAbsolutePath());
90         }
91         
92         if (!configFile.equals(this.configFile)) {
93             this.configFile = configFile;
94         
95             configManager = new XMLConfigManager(configFile);
96         }
97
98         // If we're setting the config file to the one
99
// that's already being used, then force a reload.
100
loadConfigFromConfigManager();
101     }
102
103     private List JavaDoc parseConfigFile() throws CruiseControlException {
104         List JavaDoc allProjects = getAllProjects(configManager);
105         if (allProjects.size() == 0) {
106             LOG.warn("no projects found in config file");
107         }
108         return allProjects;
109     }
110
111     private void addProject(Project project) {
112         projects.add(project);
113         for (Iterator JavaDoc listenIter = listeners.iterator(); listenIter.hasNext();) {
114             LOG.debug("Informing listener of added project " + project.getName());
115             Listener listener = (Listener) listenIter.next();
116             listener.projectAdded(project);
117         }
118         project.setBuildQueue(buildQueue);
119         project.start();
120     }
121
122     private void removeProject(Project project) {
123         projects.remove(project);
124         for (Iterator JavaDoc listenIter = listeners.iterator(); listenIter.hasNext();) {
125             LOG.debug("Informing listener of removed project " + project.getName());
126             Listener listener = (Listener) listenIter.next();
127             listener.projectRemoved(project);
128         }
129         project.stop();
130     }
131
132     public void resume() {
133         buildQueue.start();
134         for (Iterator JavaDoc iterator = projects.iterator(); iterator.hasNext();) {
135             Project currentProject = (Project) iterator.next();
136             currentProject.setBuildQueue(buildQueue);
137             currentProject.start();
138         }
139     }
140
141     public void pause() {
142         buildQueue.stop();
143         for (Iterator JavaDoc iterator = projects.iterator(); iterator.hasNext();) {
144             Project currentProject = (Project) iterator.next();
145             currentProject.stop();
146         }
147     }
148
149     public void halt() {
150         pause();
151         System.exit(0);
152     }
153
154     public String JavaDoc getBuildQueueStatus() {
155         if (buildQueue.isAlive()) {
156             if (buildQueue.isWaiting()) {
157                 return "waiting";
158             } else {
159                 return "alive";
160             }
161         } else {
162             return "dead";
163         }
164     }
165
166     public List JavaDoc getProjects() {
167         return Collections.unmodifiableList(projects);
168     }
169
170     private List JavaDoc getAllProjects(ConfigManager configManager) throws CruiseControlException {
171         Set JavaDoc projectNames = configManager.getProjectNames();
172         List JavaDoc allProjects = new ArrayList JavaDoc(projectNames.size());
173         for (Iterator JavaDoc it = projectNames.iterator(); it.hasNext();) {
174             String JavaDoc projectName = (String JavaDoc) it.next();
175             LOG.info("projectName = [" + projectName + "]");
176             Project project = configureProject(projectName);
177             allProjects.add(project);
178         }
179         return allProjects;
180     }
181
182     protected Project configureProject(String JavaDoc projectName) throws CruiseControlException {
183         Project project = readProject(projectName);
184         project.setName(projectName);
185         project.setProjectConfig(getConfigManager().getConfig(projectName));
186         project.init();
187         return project;
188     }
189
190     protected ConfigManager getConfigManager() {
191         return configManager;
192     }
193
194     /**
195      * Reads project configuration from a previously serialized Project. The
196      * name of the serialized project file is equivalent to the name of the
197      * project.
198      *
199      * @param projectName name of the serialized project file
200      * @return Deserialized Project or a new Project if there are any problems
201      * reading the serialized Project; should never return null
202      */

203     Project readProject(String JavaDoc projectName) {
204         //look for fileName.ser first
205
File JavaDoc serializedProjectFile = new File JavaDoc(projectName + ".ser");
206         LOG.debug("Reading serialized project from: " + serializedProjectFile.getAbsolutePath());
207
208         if (!serializedProjectFile.exists() || !serializedProjectFile.canRead()) {
209             //filename.ser doesn't exist, try finding fileName
210
serializedProjectFile = new File JavaDoc(projectName);
211             LOG.debug(projectName + ".ser not found, looking for serialized project file: " + projectName);
212             if (!serializedProjectFile.exists()
213                     || !serializedProjectFile.canRead()
214                     || serializedProjectFile.isDirectory()) {
215                 Project temp = new Project();
216                 temp.setName(projectName);
217                 if (!projects.contains(temp)) {
218                     LOG.warn("No previously serialized project found ["
219                             + serializedProjectFile.getAbsolutePath()
220                             + ".ser], forcing a build.");
221                 }
222                 Project newProject = new Project();
223                 newProject.setBuildForced(true);
224                 return newProject;
225             }
226         }
227
228         try {
229             ObjectInputStream JavaDoc s = new ObjectInputStream JavaDoc(new FileInputStream JavaDoc(serializedProjectFile));
230             return (Project) s.readObject();
231         } catch (Exception JavaDoc e) {
232             LOG.warn("Error deserializing project file from " + serializedProjectFile.getAbsolutePath(), e);
233             return new Project();
234         }
235     }
236
237     public void addListener(Listener listener) {
238         LOG.debug("Listener added");
239         listeners.add(listener);
240     }
241
242     public void reloadConfigFile() {
243         LOG.debug("reload config file called");
244         parseConfigFileIfNecessary();
245     }
246
247     /**
248      * @return true if the config file was parsed.
249      */

250     public boolean parseConfigFileIfNecessary() {
251         boolean reloaded = false;
252         try {
253             reloaded = configManager.reloadIfNecessary();
254         } catch (CruiseControlException e) {
255             LOG.error("error parsing config file " + configFile.getAbsolutePath(), e);
256             return reloaded;
257         }
258
259         if (reloaded) {
260             LOG.debug("config file changed");
261             loadConfigFromConfigManager();
262         } else {
263             LOG.debug("config file didn't change.");
264         }
265
266         return reloaded;
267     }
268     
269     private void loadConfigFromConfigManager() {
270         try {
271             List JavaDoc projectsFromFile = parseConfigFile();
272
273             List JavaDoc removedProjects = new ArrayList JavaDoc(projects);
274             removedProjects.removeAll(projectsFromFile);
275
276             List JavaDoc newProjects = new ArrayList JavaDoc(projectsFromFile);
277             newProjects.removeAll(projects);
278
279             List JavaDoc retainedProjects = new ArrayList JavaDoc(projectsFromFile);
280             retainedProjects.removeAll(newProjects);
281
282             //Handled removed projects
283
Iterator JavaDoc removed = removedProjects.iterator();
284             while (removed.hasNext()) {
285                 removeProject((Project) removed.next());
286             }
287
288             //Handle added projects
289
Iterator JavaDoc added = newProjects.iterator();
290             while (added.hasNext()) {
291                 addProject((Project) added.next());
292             }
293
294             //Handle retained projects
295
Iterator JavaDoc retained = retainedProjects.iterator();
296             while (retained.hasNext()) {
297                 updateProject((Project) retained.next());
298             }
299
300         } catch (CruiseControlException e) {
301             LOG.error("error parsing config file " + configFile.getAbsolutePath(), e);
302         }
303     }
304
305     private void updateProject(Project project) throws CruiseControlException {
306         Project matchingProject = (Project) projects.get(projects.indexOf(project));
307         matchingProject.setProjectConfig(getConfigManager().getConfig(matchingProject.getName()));
308         matchingProject.init();
309     }
310
311     public static interface Listener extends EventListener JavaDoc {
312         void projectAdded(Project project);
313         void projectRemoved(Project project);
314     }
315
316     private class BuildQueueListener implements BuildQueue.Listener {
317         public void buildRequested() {
318             parseConfigFileIfNecessary();
319         }
320     }
321
322     public PluginDetail[] getAvailableBootstrappers() {
323         return getPluginsByType(getAvailablePlugins(), PluginType.BOOTSTRAPPER);
324     }
325
326     public PluginDetail[] getAvailablePublishers() {
327         return getPluginsByType(getAvailablePlugins(), PluginType.PUBLISHER);
328     }
329
330     public PluginDetail[] getAvailableSourceControls() {
331         return getPluginsByType(getAvailablePlugins(), PluginType.SOURCE_CONTROL);
332     }
333
334     public PluginDetail[] getAvailablePlugins() {
335         try {
336             return getPluginRegistry().getPluginDetails();
337         } catch (CruiseControlException e) {
338             return new PluginDetail[0];
339         }
340     }
341
342     public PluginType[] getAvailablePluginTypes() {
343         return getPluginRegistry().getPluginTypes();
344     }
345
346     public PluginRegistry getPluginRegistry() {
347         return ((XMLConfigManager) configManager).getCruiseControlConfig().getRootPlugins();
348     }
349
350     private static PluginDetail[] getPluginsByType(PluginDetail[] details, PluginType type) {
351         List JavaDoc plugins = new ArrayList JavaDoc();
352         for (int i = 0; i < details.length; i++) {
353             if (details[i].getType().equals(type)) {
354                 plugins.add(details[i]);
355             }
356         }
357
358         return (PluginDetail[]) plugins.toArray(new PluginDetail[plugins.size()]);
359     }
360 }
361
Popular Tags