CruiseControlController.java
| Index Score | ||
|---|---|---|
![]() |
![]() |
net.sourceforge.cruisecontrol |
![]() |
![]() |
CruiseControl |
View: Reasons, Metrics, Source Code
These are the metrics that contribute to the Enerjy Score for this file, ranked by impact. So the metrics listed at the top influence the score to a greater extent that the metrics listed at the bottom.
/********************************************************************************
* CruiseControl, a Continuous Integration Toolkit
* Copyright (c) 2001-2003, 2006, ThoughtWorks, Inc.
* 200 E. Randolph, 25th Floor
* Chicago, IL 60601 USA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* + Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* + Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* + Neither the name of ThoughtWorks, Inc., CruiseControl, nor the
* names of its contributors may be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
********************************************************************************/
package net.sourceforge.cruisecontrol;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.EventListener;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.util.Set;
import net.sourceforge.cruisecontrol.config.XMLConfigManager;
import org.apache.log4j.Logger;
/**
* @author <a href="mailto:robertdw@users.sourceforge.net">Robert Watkins</a>
*/
public class CruiseControlController {
private static final Logger LOG = Logger.getLogger(CruiseControlController.class);
public static final String DEFAULT_CONFIG_FILE_NAME = "config.xml";
private File configFile;
private List projects = new ArrayList();
private BuildQueue buildQueue = new BuildQueue();
private Properties versionProperties;
private List listeners = new ArrayList();
private XMLConfigManager configManager;
private ParsingConfigMutex parsingConfigMutex = new ParsingConfigMutex();
public CruiseControlController() {
buildQueue.addListener(new BuildQueueListener());
}
public File getConfigFile() {
return configFile;
}
public void setVersionProperties(Properties versionProperties) {
this.versionProperties = versionProperties;
}
public Properties getVersionProperties() {
return versionProperties;
}
public void setConfigFile(File configFile) throws CruiseControlException {
if (configFile == null) {
throw new CruiseControlException("No config file");
}
if (!configFile.isFile()) {
throw new CruiseControlException("Config file not found: " + configFile.getAbsolutePath());
}
if (!configFile.equals(this.configFile)) {
this.configFile = configFile;
configManager = new XMLConfigManager(configFile, this);
}
loadConfig();
}
private void addProject(ProjectInterface project) throws CruiseControlException {
project.configureProject();
projects.add(project);
for (Iterator listenIter = listeners.iterator(); listenIter.hasNext();) {
LOG.debug("Informing listener of added project " + project.getName());
Listener listener = (Listener) listenIter.next();
listener.projectAdded(project);
}
project.setBuildQueue(buildQueue);
project.start();
}
private void removeProject(ProjectInterface project) {
projects.remove(project);
for (Iterator listenIter = listeners.iterator(); listenIter.hasNext();) {
LOG.debug("Informing listener of removed project " + project.getName());
Listener listener = (Listener) listenIter.next();
listener.projectRemoved(project);
}
project.stop();
}
public void resume() {
buildQueue.start();
for (Iterator iterator = projects.iterator(); iterator.hasNext();) {
ProjectInterface currentProject = (ProjectInterface) iterator.next();
currentProject.setBuildQueue(buildQueue);
currentProject.start();
}
}
public void pause() {
buildQueue.stop();
for (Iterator iterator = projects.iterator(); iterator.hasNext();) {
ProjectInterface currentProject = (ProjectInterface) iterator.next();
currentProject.stop();
}
}
public void halt() {
pause();
System.exit(0);
}
public String getBuildQueueStatus() {
if (buildQueue.isAlive()) {
if (buildQueue.isWaiting()) {
return "waiting";
} else {
return "alive";
}
} else {
return "dead";
}
}
public List getProjects() {
return Collections.unmodifiableList(projects);
}
private List getAllProjects(XMLConfigManager configManager) {
Set projectNames = configManager.getCruiseControlConfig().getProjectNames();
List allProjects = new ArrayList(projectNames.size());
for (Iterator it = projectNames.iterator(); it.hasNext();) {
String projectName = (String) it.next();
LOG.info("projectName = [" + projectName + "]");
ProjectInterface projectConfig = getConfigManager().getProject(projectName);
allProjects.add(projectConfig);
}
if (allProjects.size() == 0) {
LOG.warn("no projects found in config file");
}
return allProjects;
}
protected XMLConfigManager getConfigManager() {
return configManager;
}
public void addListener(Listener listener) {
LOG.debug("Listener added");
listeners.add(listener);
}
public void reloadConfigFile() {
LOG.debug("reload config file called");
parseConfigFileIfNecessary();
}
/**
* @return true if the config file was parsed.
*/
public boolean parseConfigFileIfNecessary() {
boolean reloaded = false;
if (parsingConfigMutex.getPermissionToParse()) {
try {
try {
reloaded = configManager.reloadIfNecessary();
} catch (CruiseControlException e) {
LOG.error("error parsing config file " + configFile.getAbsolutePath(), e);
return reloaded;
}
if (reloaded) {
LOG.debug("config file changed");
loadConfig();
} else {
LOG.debug("config file didn't change.");
}
} finally {
parsingConfigMutex.doneParsing();
}
}
return reloaded;
}
private void loadConfig() {
try {
List projectsFromFile = getAllProjects(configManager);
List removedProjects = new ArrayList(projects);
removedProjects.removeAll(projectsFromFile);
List newProjects = new ArrayList(projectsFromFile);
newProjects.removeAll(projects);
List retainedProjects = new ArrayList(projects);
retainedProjects.removeAll(removedProjects);
//Handled removed projects
Iterator removed = removedProjects.iterator();
while (removed.hasNext()) {
removeProject((ProjectInterface) removed.next());
}
//Handle added projects
Iterator added = newProjects.iterator();
while (added.hasNext()) {
addProject((ProjectInterface) added.next());
}
//Handle retained projects
Iterator retained = retainedProjects.iterator();
while (retained.hasNext()) {
updateProject((ProjectInterface) retained.next());
}
} catch (CruiseControlException e) {
LOG.error("error parsing config file " + configFile.getAbsolutePath(), e);
}
}
private void updateProject(ProjectInterface oldProject) throws CruiseControlException {
ProjectInterface newProject = getConfigManager().getProject(oldProject.getName());
projects.remove(oldProject);
newProject.getStateFromOldProject(oldProject);
projects.add(newProject);
}
public static interface Listener extends EventListener {
void projectAdded(ProjectInterface project);
void projectRemoved(ProjectInterface project);
}
private class BuildQueueListener implements BuildQueue.Listener {
public void buildRequested() {
parseConfigFileIfNecessary();
}
}
public PluginDetail[] getAvailableBootstrappers() {
return getPluginsByType(getAvailablePlugins(), PluginType.BOOTSTRAPPER);
}
public PluginDetail[] getAvailablePublishers() {
return getPluginsByType(getAvailablePlugins(), PluginType.PUBLISHER);
}
public PluginDetail[] getAvailableSourceControls() {
return getPluginsByType(getAvailablePlugins(), PluginType.SOURCE_CONTROL);
}
public PluginDetail[] getAvailablePlugins() {
try {
return getPluginRegistry().getPluginDetails();
} catch (CruiseControlException e) {
return new PluginDetail[0];
}
}
public PluginType[] getAvailablePluginTypes() {
return getPluginRegistry().getPluginTypes();
}
public PluginRegistry getPluginRegistry() {
return configManager.getCruiseControlConfig().getRootPlugins();
}
private static PluginDetail[] getPluginsByType(PluginDetail[] details, PluginType type) {
List plugins = new ArrayList();
for (int i = 0; i < details.length; i++) {
if (details[i].getType().equals(type)) {
plugins.add(details[i]);
}
}
return (PluginDetail[]) plugins.toArray(new PluginDetail[plugins.size()]);
}
private class ParsingConfigMutex {
private Object mutex = new Object();
private boolean inUse;
boolean getPermissionToParse() {
synchronized (mutex) {
if (inUse) {
LOG.debug("permission denied to parse config");
return false;
}
inUse = true;
LOG.debug("permission granted to parse config");
return true;
}
}
void doneParsing() {
LOG.debug("done parsing, allow next request permission to parse");
inUse = false;
}
}
}
The table below shows all metrics for CruiseControlController.java.



