KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sourceforge > cruisecontrol > publishers > CMSynergyBaselinePublisher


1 /********************************************************************************
2  * CruiseControl, a Continuous Integration Toolkit
3  * Copyright (c) 2001, 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.publishers;
38
39 import java.util.Properties JavaDoc;
40
41 import org.apache.log4j.Logger;
42 import org.apache.oro.text.regex.MalformedPatternException;
43 import org.apache.oro.text.regex.MatchResult;
44 import org.apache.oro.text.regex.Pattern;
45 import org.apache.oro.text.regex.PatternCompiler;
46 import org.apache.oro.text.regex.PatternMatcher;
47 import org.apache.oro.text.regex.Perl5Compiler;
48 import org.apache.oro.text.regex.Perl5Matcher;
49 import org.jdom.Element;
50
51 import net.sourceforge.cruisecontrol.CruiseControlException;
52 import net.sourceforge.cruisecontrol.sourcecontrols.CMSynergy;
53 import net.sourceforge.cruisecontrol.util.ManagedCommandline;
54 import net.sourceforge.cruisecontrol.util.ValidationHelper;
55
56 /**
57  * Creates an intermediate baseline encompasing the given project and all
58  * subprojects. <br>
59  * <b>Note: This publisher requires CM Synergy version 6.3 or later. </b>
60  *
61  * @author <a HREF="mailto:rjmpsmith@gmail.com">Robert J. Smith</a>
62  */

63 public class CMSynergyBaselinePublisher extends CMSynergyPublisher {
64     
65     /**
66      * The default CM Synergy project purpose for the baseline
67      */

68     public static final String JavaDoc CCM_BASELINE_PURPOSE = "Integration Testing";
69     
70     private static final Logger LOG = Logger.getLogger(CMSynergyBaselinePublisher.class);
71     private static final Pattern LOG_PROPERTY_PATTERN;
72     private String JavaDoc purpose = CCM_BASELINE_PURPOSE;
73     private String JavaDoc name;
74     private String JavaDoc description;
75     
76     static {
77         // Create a Perl 5 pattern matcher to find embedded properties
78
PatternCompiler compiler = new Perl5Compiler();
79         try {
80             // 1 2 3
81
LOG_PROPERTY_PATTERN = compiler.compile("(.*)\\@\\{([^@{}]+)\\}(.*)");
82         } catch (MalformedPatternException e) {
83             // shouldn't happen
84
LOG.fatal("Error compiling pattern for property matching", e);
85             throw new IllegalStateException JavaDoc();
86         }
87
88     }
89     
90     /**
91      * Sets the purpose of the baseline. Default is "Integration Testing".
92      *
93      * @param purpose The baseline's purpose
94      */

95     public void setPurpose(String JavaDoc purpose) {
96         this.purpose = purpose;
97     }
98     
99     /**
100      * Sets the name (version label) which will be given to the newly created
101      * project versions. You may use macros to specify any of the
102      * default properties set by CruiseControl (i.e. those which appear in the
103      * info section of the log file).
104      * <p>
105      * example:
106      * <br><br>
107      * name="BUILD_@{cctimestamp}"
108      *
109      * @param name The name of the baseline
110      */

111     public void setBaselineName(String JavaDoc name) {
112         this.name = name;
113     }
114     
115     /**
116      * Sets the description of the baseline.
117      *
118      * @param description The description
119      */

120     public void setDescription(String JavaDoc description) {
121         this.description = description;
122     }
123     
124     /* (non-Javadoc)
125      * @see net.sourceforge.cruisecontrol.Publisher#publish(org.jdom.Element)
126      */

127     public void publish(Element log) throws CruiseControlException {
128         
129         // Only publish upon a successful build which includes new tasks.
130
if (!shouldPublish(log)) {
131             return;
132         }
133                 
134         // Extract the build properties from the log
135
Properties JavaDoc logProperties = getBuildProperties(log);
136         
137         // If a baseline name was provided, parse it
138
String JavaDoc baselineName = null;
139         if (name != null) {
140             baselineName = parsePropertiesInString(name, logProperties);
141         }
142
143         // Create the CM Synergy command line
144
ManagedCommandline cmd = CMSynergy.createCcmCommand(
145                 getCcmExe(), getSessionName(), getSessionFile());
146         
147         cmd.createArgument().setValue("baseline");
148         cmd.createArgument().setValue("-create");
149         if (baselineName != null) {
150             cmd.createArgument().setValue(baselineName);
151         }
152         if (description != null) {
153             cmd.createArgument().setValue("-description");
154             cmd.createArgument().setValue(description);
155         }
156         cmd.createArgument().setValue("-release");
157         cmd.createArgument().setValue(getProjectRelease());
158         cmd.createArgument().setValue("-purpose");
159         cmd.createArgument().setValue(purpose);
160         cmd.createArgument().setValue("-project");
161         cmd.createArgument().setValue(getProject());
162         cmd.createArgument().setValue("-subprojects");
163
164         // Create the baseline
165
try {
166             cmd.execute();
167             cmd.assertExitCode(0);
168         } catch (Exception JavaDoc e) {
169             StringBuffer JavaDoc error = new StringBuffer JavaDoc(
170                     "Failed to create intermediate baseline for project \"");
171             error.append(getProject());
172             error.append("\".");
173             throw new CruiseControlException(error.toString(), e);
174         }
175         
176         // Log the success
177
StringBuffer JavaDoc message = new StringBuffer JavaDoc("Created baseline");
178         if (baselineName != null) {
179             message.append(" ").append(baselineName);
180         }
181         message.append(".");
182         LOG.info(message.toString());
183     }
184     
185     /* (non-Javadoc)
186      * @see net.sourceforge.cruisecontrol.Publisher#validate()
187      */

188     public void validate() throws CruiseControlException {
189         ValidationHelper.assertIsSet(getProject(), "project", this.getClass());
190     }
191     
192     /**
193      * Queries CM Synergy for the release value of the project
194      *
195      * @return The release value of the project.
196      */

197     private String JavaDoc getProjectRelease() throws CruiseControlException {
198         String JavaDoc release;
199         
200         // Create the CM Synergy command line
201
ManagedCommandline cmd = CMSynergy.createCcmCommand(
202                 getCcmExe(), getSessionName(), getSessionFile());
203         cmd.createArgument().setValue("attribute");
204         cmd.createArgument().setValue("-show");
205         cmd.createArgument().setValue("release");
206         cmd.createArgument().setValue("-project");
207         cmd.createArgument().setValue(getProject());
208
209         try {
210             cmd.execute();
211             cmd.assertExitCode(0);
212             release = cmd.getStdoutAsString().trim();
213         } catch (Exception JavaDoc e) {
214             throw new CruiseControlException(
215                     "Could not determine the release value of project \""
216                             + getProject() + "\".", e);
217         }
218         
219         return release;
220     }
221     
222     /**
223      * Parses a string by replacing all occurences of a property macro with
224      * the resolved value of the property (from the info section of the log
225      * file). Nested macros are allowed - the
226      * inner most macro will be resolved first, moving out from there.
227      * <br/>
228      * Macros are of the form @{property}, so that they will not conflict with
229      * properties support built into CC.
230      *
231      * @param string The string to be parsed
232      * @return The parsed string
233      */

234     private String JavaDoc parsePropertiesInString(String JavaDoc string, Properties JavaDoc buildProperties) {
235
236         PatternMatcher matcher = new Perl5Matcher();
237
238         // Expand all (possibly nested) properties
239
while (matcher.contains(string, LOG_PROPERTY_PATTERN)) {
240             MatchResult result = matcher.getMatch();
241             String JavaDoc pre = result.group(1);
242             String JavaDoc propertyName = result.group(2);
243             String JavaDoc post = result.group(3);
244             String JavaDoc value = buildProperties.getProperty(propertyName);
245             if (value == null) {
246                 LOG.warn("Could not resolve property \"" + propertyName
247                         + "\".");
248                 value = "_";
249             }
250             string = pre + value + post;
251         }
252         
253         return string;
254     }
255 }
256
Popular Tags