1 37 package net.sourceforge.cruisecontrol; 38 39 import java.io.File ; 40 import java.io.FileInputStream ; 41 import java.io.ObjectInputStream ; 42 import java.util.ArrayList ; 43 import java.util.Collections ; 44 import java.util.EventListener ; 45 import java.util.Iterator ; 46 import java.util.List ; 47 import java.util.Properties ; 48 import java.util.Set ; 49 50 import net.sourceforge.cruisecontrol.config.XMLConfigManager; 51 52 import org.apache.log4j.Logger; 53 54 57 public class CruiseControlController { 58 private static final Logger LOG = Logger.getLogger(CruiseControlController.class); 59 public static final String DEFAULT_CONFIG_FILE_NAME = "config.xml"; 60 private File configFile; 61 private List projects = new ArrayList (); 62 private BuildQueue buildQueue = new BuildQueue(); 63 private Properties versionProperties; 64 65 private List listeners = new ArrayList (); 66 private ConfigManager configManager; 67 68 public CruiseControlController() { 69 buildQueue.addListener(new BuildQueueListener()); 70 } 71 72 public File getConfigFile() { 73 return configFile; 74 } 75 76 public void setVersionProperties(Properties versionProperties) { 77 this.versionProperties = versionProperties; 78 } 79 80 public Properties getVersionProperties() { 81 return versionProperties; 82 } 83 84 public void setConfigFile(File 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 loadConfigFromConfigManager(); 101 } 102 103 private List parseConfigFile() throws CruiseControlException { 104 List 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 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 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 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 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 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 getProjects() { 167 return Collections.unmodifiableList(projects); 168 } 169 170 private List getAllProjects(ConfigManager configManager) throws CruiseControlException { 171 Set projectNames = configManager.getProjectNames(); 172 List allProjects = new ArrayList (projectNames.size()); 173 for (Iterator it = projectNames.iterator(); it.hasNext();) { 174 String projectName = (String ) 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 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 203 Project readProject(String projectName) { 204 File serializedProjectFile = new File (projectName + ".ser"); 206 LOG.debug("Reading serialized project from: " + serializedProjectFile.getAbsolutePath()); 207 208 if (!serializedProjectFile.exists() || !serializedProjectFile.canRead()) { 209 serializedProjectFile = new File (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 s = new ObjectInputStream (new FileInputStream (serializedProjectFile)); 230 return (Project) s.readObject(); 231 } catch (Exception 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 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 projectsFromFile = parseConfigFile(); 272 273 List removedProjects = new ArrayList (projects); 274 removedProjects.removeAll(projectsFromFile); 275 276 List newProjects = new ArrayList (projectsFromFile); 277 newProjects.removeAll(projects); 278 279 List retainedProjects = new ArrayList (projectsFromFile); 280 retainedProjects.removeAll(newProjects); 281 282 Iterator removed = removedProjects.iterator(); 284 while (removed.hasNext()) { 285 removeProject((Project) removed.next()); 286 } 287 288 Iterator added = newProjects.iterator(); 290 while (added.hasNext()) { 291 addProject((Project) added.next()); 292 } 293 294 Iterator 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 { 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 plugins = new ArrayList (); 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 |