001: /********************************************************************************
002: * CruiseControl, a Continuous Integration Toolkit
003: * Copyright (c) 2005 ThoughtWorks, Inc.
004: * 200 E. Randolph, 25th Floor
005: * Chicago, IL 60601 USA
006: * All rights reserved.
007: *
008: * Redistribution and use in source and binary forms, with or without
009: * modification, are permitted provided that the following conditions
010: * are met:
011: *
012: * + Redistributions of source code must retain the above copyright
013: * notice, this list of conditions and the following disclaimer.
014: *
015: * + Redistributions in binary form must reproduce the above
016: * copyright notice, this list of conditions and the following
017: * disclaimer in the documentation and/or other materials provided
018: * with the distribution.
019: *
020: * + Neither the name of ThoughtWorks, Inc., CruiseControl, nor the
021: * names of its contributors may be used to endorse or promote
022: * products derived from this software without specific prior
023: * written permission.
024: *
025: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
026: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
027: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
028: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
029: * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
030: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
031: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
032: * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
033: * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
034: * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
035: * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
036: ********************************************************************************/package net.sourceforge.cruisecontrol;
037:
038: import java.io.ByteArrayInputStream;
039: import java.io.IOException;
040: import java.io.StringReader;
041: import java.util.Arrays;
042: import java.util.Collection;
043: import java.util.HashMap;
044: import java.util.Iterator;
045: import java.util.LinkedList;
046: import java.util.List;
047: import java.util.Map;
048:
049: import javax.management.Attribute;
050: import javax.management.AttributeNotFoundException;
051: import javax.management.InstanceNotFoundException;
052: import javax.management.InvalidAttributeValueException;
053: import javax.management.MBeanException;
054: import javax.management.MBeanServerConnection;
055: import javax.management.MalformedObjectNameException;
056: import javax.management.ObjectName;
057: import javax.management.ReflectionException;
058: import javax.management.remote.JMXConnector;
059: import javax.management.remote.JMXConnectorFactory;
060: import javax.management.remote.JMXServiceURL;
061: import javax.naming.Context;
062:
063: import net.sourceforge.cruisecontrol.util.Util;
064:
065: import org.apache.commons.lang.StringUtils;
066: import org.jdom.Document;
067: import org.jdom.Element;
068: import org.jdom.JDOMException;
069: import org.jdom.input.SAXBuilder;
070: import org.jdom.output.Format;
071: import org.jdom.output.XMLOutputter;
072:
073: /**
074: * Communicates with the CruiseControl JMX server to allow CRUD operations on
075: * the CruiseControl configuration.
076: */
077: public class Configuration {
078: private MBeanServerConnection server;
079: private ObjectName ccMgr;
080: private String configuration;
081: private PluginDetail[] pluginDetails;
082:
083: public Configuration(String jmxServer, int rmiPort)
084: throws IOException, MalformedObjectNameException {
085: JMXServiceURL address = new JMXServiceURL("service:jmx:rmi://"
086: + jmxServer + ":" + rmiPort + "/jndi/jrmp");
087:
088: Map environment = new HashMap();
089: environment.put(Context.INITIAL_CONTEXT_FACTORY,
090: "com.sun.jndi.rmi.registry.RegistryContextFactory");
091: environment.put(Context.PROVIDER_URL, "rmi://" + jmxServer
092: + ":" + rmiPort);
093:
094: JMXConnector cntor = JMXConnectorFactory.connect(address,
095: environment);
096: server = cntor.getMBeanServerConnection();
097: ccMgr = ObjectName
098: .getInstance("CruiseControl Manager:id=unique");
099: }
100:
101: public String getConfiguration() throws AttributeNotFoundException,
102: InstanceNotFoundException, MBeanException,
103: ReflectionException, IOException, JDOMException {
104: if (configuration == null) {
105: load();
106: }
107:
108: return configuration;
109: }
110:
111: public Document getDocument() throws ReflectionException,
112: IOException, InstanceNotFoundException, MBeanException,
113: AttributeNotFoundException, JDOMException {
114: return stringToDoc(getConfiguration());
115: }
116:
117: public Element getElement(String name) throws ReflectionException,
118: InstanceNotFoundException, IOException, MBeanException,
119: AttributeNotFoundException, JDOMException {
120: return JDOMSearcher.getElement(getDocument(), name);
121: }
122:
123: public PluginDetail[] getPluginDetails()
124: throws AttributeNotFoundException,
125: InstanceNotFoundException, MBeanException,
126: ReflectionException, IOException {
127: if (pluginDetails == null) {
128: pluginDetails = (PluginDetail[]) server.getAttribute(ccMgr,
129: "AvailablePlugins");
130: }
131:
132: return pluginDetails;
133: }
134:
135: public PluginDetail[] getConfiguredBootstrappers(String project)
136: throws CruiseControlException, AttributeNotFoundException,
137: InstanceNotFoundException, MBeanException,
138: ReflectionException, IOException, JDOMException {
139: return getConfiguredPluginDetails(project, getProjectConfig(
140: project).getBootstrappers());
141: }
142:
143: public PluginDetail[] getConfiguredBuilders(String project)
144: throws AttributeNotFoundException,
145: InstanceNotFoundException, MBeanException,
146: ReflectionException, IOException, CruiseControlException,
147: JDOMException {
148: return getConfiguredPluginDetails(project, getProjectConfig(
149: project).getSchedule().getBuilders());
150: }
151:
152: public PluginDetail[] getConfiguredListeners(String project)
153: throws AttributeNotFoundException,
154: InstanceNotFoundException, MBeanException,
155: ReflectionException, IOException, CruiseControlException,
156: JDOMException {
157: return getConfiguredPluginDetails(project, getProjectConfig(
158: project).getListeners());
159: }
160:
161: public PluginDetail[] getConfiguredLoggers(String project)
162: throws AttributeNotFoundException,
163: InstanceNotFoundException, MBeanException,
164: ReflectionException, IOException, CruiseControlException,
165: JDOMException {
166: return getConfiguredPluginDetails(project,
167: Arrays.asList(getProjectConfig(project).getLog()
168: .getLoggers()));
169: }
170:
171: public PluginDetail[] getConfiguredPublishers(String project)
172: throws AttributeNotFoundException,
173: InstanceNotFoundException, MBeanException,
174: ReflectionException, IOException, CruiseControlException,
175: JDOMException {
176: return getConfiguredPluginDetails(project, getProjectConfig(
177: project).getPublishers());
178: }
179:
180: public PluginDetail[] getConfiguredSourceControls(String project)
181: throws AttributeNotFoundException,
182: InstanceNotFoundException, MBeanException,
183: ReflectionException, IOException, CruiseControlException,
184: JDOMException {
185: return getConfiguredPluginDetails(project, getProjectConfig(
186: project).getModificationSet().getSourceControls());
187: }
188:
189: public void load() throws MBeanException,
190: AttributeNotFoundException, InstanceNotFoundException,
191: ReflectionException, IOException, JDOMException {
192: // Ensure xml is well-formed
193: configuration = docToString(stringToDoc(loadConfiguration()));
194: }
195:
196: public void save() throws InstanceNotFoundException,
197: AttributeNotFoundException, InvalidAttributeValueException,
198: MBeanException, ReflectionException, IOException {
199: server.setAttribute(ccMgr, new Attribute("ConfigFileContents",
200: configuration));
201: }
202:
203: public void setConfiguration(String configuration) {
204: this .configuration = configuration;
205: }
206:
207: public void setConfiguration(Document doc) {
208: setConfiguration(docToString(doc));
209: }
210:
211: public void updatePluginConfiguration(
212: PluginConfiguration pluginConfiguration)
213: throws AttributeNotFoundException,
214: InstanceNotFoundException, MBeanException,
215: ReflectionException, IOException, JDOMException,
216: InvalidAttributeValueException {
217: Element plugin = new Element(pluginConfiguration.getName());
218: for (Iterator i = pluginConfiguration.getDetails().entrySet()
219: .iterator(); i.hasNext();) {
220: Map.Entry element = (Map.Entry) i.next();
221: String key = (String) element.getKey();
222: String value = (String) element.getValue();
223: if (StringUtils.isNotBlank(value)) {
224: plugin.setAttribute(key, value);
225: }
226: }
227:
228: Document doc = getDocument();
229: Element parent = JDOMSearcher.getElement(doc,
230: pluginConfiguration.getParentElementName());
231: parent.removeChild(plugin.getName());
232: parent.addContent(plugin);
233:
234: setConfiguration(doc);
235: }
236:
237: private static String docToString(Document doc) {
238: return new XMLOutputter(Format.getPrettyFormat()).outputString(
239: doc).trim();
240: }
241:
242: private static Document stringToDoc(String configuration)
243: throws JDOMException, IOException {
244: return new SAXBuilder().build(new StringReader(configuration));
245: }
246:
247: private PluginDetail[] getConfiguredPluginDetails(String project,
248: List plugins) throws AttributeNotFoundException,
249: InstanceNotFoundException, MBeanException,
250: ReflectionException, IOException, CruiseControlException {
251: Collection details = new LinkedList();
252: PluginRegistry registry = getPluginRegistry();
253:
254: for (Iterator i = plugins.iterator(); i.hasNext();) {
255: Class nextClass = i.next().getClass();
256: details.add(new GenericPluginDetail(registry
257: .getPluginName(nextClass), nextClass));
258: }
259:
260: return (PluginDetail[]) details
261: .toArray(new PluginDetail[details.size()]);
262: }
263:
264: private PluginRegistry getPluginRegistry()
265: throws AttributeNotFoundException,
266: InstanceNotFoundException, MBeanException,
267: ReflectionException, IOException {
268: return (PluginRegistry) server.getAttribute(ccMgr,
269: "PluginRegistry");
270: }
271:
272: private ProjectConfig getProjectConfig(String project)
273: throws CruiseControlException, AttributeNotFoundException,
274: InstanceNotFoundException, MBeanException,
275: ReflectionException, IOException, JDOMException {
276: Element element = Util
277: .loadRootElement(new ByteArrayInputStream(
278: getConfiguration().getBytes()));
279: CruiseControlConfig config = new CruiseControlConfig(element);
280: return (ProjectConfig) config.getProject(project);
281: }
282:
283: private String loadConfiguration() throws MBeanException,
284: AttributeNotFoundException, InstanceNotFoundException,
285: ReflectionException, IOException {
286: return (String) server
287: .getAttribute(ccMgr, "ConfigFileContents");
288: }
289: }
|