KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sourceforge > cruisecontrol > sourcecontrols > MKS


1 /********************************************************************************
2  * CruiseControl, a Continuous Integration Toolkit
3  * Copyright (c) 2001-2003, 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.sourcecontrols;
38
39 import java.io.BufferedReader JavaDoc;
40 import java.io.File JavaDoc;
41 import java.io.InputStream JavaDoc;
42 import java.io.InputStreamReader JavaDoc;
43 import java.io.OutputStream JavaDoc;
44 import java.io.PrintWriter JavaDoc;
45 import java.util.ArrayList JavaDoc;
46 import java.util.Date JavaDoc;
47 import java.util.Hashtable JavaDoc;
48 import java.util.List JavaDoc;
49 import java.util.Map JavaDoc;
50
51 import net.sourceforge.cruisecontrol.CruiseControlException;
52 import net.sourceforge.cruisecontrol.Modification;
53 import net.sourceforge.cruisecontrol.SourceControl;
54 import net.sourceforge.cruisecontrol.util.ValidationHelper;
55 import net.sourceforge.cruisecontrol.util.StreamPumper;
56 import net.sourceforge.cruisecontrol.util.Commandline;
57
58 import org.apache.log4j.Logger;
59
60 /**
61  * This class implements the SourceControlElement methods for a MKS repository.
62  * The call to MKS is assumed to work with any setup:
63  * The call to MKS login should be done prior to calling this class.
64  * *
65  * attributes:
66  * localWorkingDir - local directory for the sandbox
67  * project - the name and path to the MKS project
68  * doNothing - if this attribute is set to true, no mks command is executed. This is for
69  * testing purposes, if a potentially slow mks server connection should avoid
70  *
71  * @author Suresh K Bathala Skila, Inc.
72  * @author Dominik Hirt, Wincor-Nixdorf International GmbH, Leipzig
73  */

74 public class MKS implements SourceControl {
75     private static final Logger LOG = Logger.getLogger(MKS.class);
76
77     private Hashtable JavaDoc properties = new Hashtable JavaDoc();
78
79     private String JavaDoc property;
80
81     private String JavaDoc project;
82
83     private File JavaDoc localWorkingDir;
84
85     /**
86      * if this attribute is set to true, no mks command is executed. This is for
87      * testing purposes, if a potentially slow mks server connection should
88      * avoid
89      */

90     private boolean doNothing;
91
92     /**
93      * This is the workaround for the missing feature of MKS to return differences
94      * for a given time period. If a modification is detected during the quietperiod,
95      * CruiseControl calls <code>getModifications</code> of this sourcecontrol object
96      * again, with the new values for <code>Date now</code>. In that case, and if all
97      * modification are already found in the first cycle, the list of modifications
98      * becomes empty. Therefor, we have to return the summarized list of modifications:
99      * the values from the last run, and -maybe- results return by MKS for this run.
100      */

101     private List JavaDoc listOfModifications = new ArrayList JavaDoc();
102     
103     public void setProject(String JavaDoc project) {
104         this.project = project;
105     }
106
107     /**
108      * Sets the local working copy to use when making calls to MKS.
109      *
110      * @param local
111      * String indicating the relative or absolute path to the local
112      * working copy of the module of which to find the log history.
113      */

114     public void setLocalWorkingDir(String JavaDoc local) {
115         localWorkingDir = new File JavaDoc(local);
116     }
117
118     public void setProperty(String JavaDoc property) {
119         this.property = property;
120     }
121
122     public Map JavaDoc getProperties() {
123         return properties;
124     }
125
126     public void setDoNothing(String JavaDoc doNothing) {
127         this.doNothing = new Boolean JavaDoc(doNothing).booleanValue();
128     }
129
130     public void validate() throws CruiseControlException {
131         ValidationHelper.assertIsSet(localWorkingDir, "localWorkingDir", this.getClass());
132         ValidationHelper.assertIsSet(project, "project", this.getClass());
133     }
134
135     /**
136      * Returns an ArrayList of Modifications.
137      * MKS ignores dates for such a range so therefor ALL
138      * modifications since the last resynch step are returned.
139      *
140      * @param lastBuild
141      * Last build time.
142      * @param now
143      * Time now, or time to check.
144      * @return maybe empty, never null.
145      */

146     public List JavaDoc getModifications(Date JavaDoc lastBuild, Date JavaDoc now) {
147         
148         int numberOfFilesForDot = 0;
149         boolean printCR = false;
150         
151         if (doNothing) {
152             if (property != null) {
153                 properties.put(property, "true");
154             }
155             return listOfModifications;
156         }
157         String JavaDoc cmd;
158
159         String JavaDoc projectFilePath = localWorkingDir.getAbsolutePath() + File.separator + project;
160         if (!new File JavaDoc(projectFilePath).exists()) {
161             throw new RuntimeException JavaDoc("project file not found at " + projectFilePath);
162         }
163         cmd = new String JavaDoc("si resync -f -R -S " + projectFilePath);
164
165         /* Sample output:
166          * output: Connecting to baswmks1:7001 ... Connecting to baswmks1:7001
167          * as dominik.hirt ... Resynchronizing files...
168          * c:\temp\test\Admin\ComponentBuild\antfile.xml
169          * c:\temp\test\Admin\PCEAdminCommand\projectbuild.properties: checked
170          * out revision 1.1
171          */

172
173         try {
174             LOG.debug(cmd);
175             Process JavaDoc proc = Runtime.getRuntime()
176                     .exec(cmd, null, localWorkingDir);
177             logStream(proc.getInputStream(), System.out);
178             InputStream JavaDoc in = proc.getErrorStream();
179             BufferedReader JavaDoc reader = new BufferedReader JavaDoc(
180                     new InputStreamReader JavaDoc(in));
181             String JavaDoc line = reader.readLine();
182
183             while (line != null) {
184                 int idxCheckedOutRevision = line
185                         .indexOf(": checked out revision");
186
187                 if (idxCheckedOutRevision == -1) {
188                     numberOfFilesForDot++;
189                     if (numberOfFilesForDot == 20) {
190                         System.out.print("."); // don't use LOG, avoid linefeed
191
numberOfFilesForDot = 0;
192                         printCR = true;
193                     }
194                     line = reader.readLine();
195                     continue;
196                 }
197                 if (printCR) {
198                     System.out.println(""); // avoid LOG prefix 'MKS - '
199
printCR = false;
200                 }
201                 LOG.info(line);
202
203                 int idxSeparator = line.lastIndexOf(File.separator);
204                 String JavaDoc folderName = line.substring(0, idxSeparator);
205                 String JavaDoc fileName = line.substring(idxSeparator + 1,
206                         idxCheckedOutRevision);
207                 Modification modification = new Modification();
208                 Modification.ModifiedFile modFile = modification
209                         .createModifiedFile(fileName, folderName);
210                 modification.modifiedTime = new Date JavaDoc(new File JavaDoc(folderName,
211                         fileName).lastModified());
212                 modFile.revision = line.substring(idxCheckedOutRevision + 23);
213                 modification.revision = modFile.revision;
214                 setUserNameAndComment(modification, folderName, fileName);
215
216                 listOfModifications.add(modification);
217
218                 line = reader.readLine();
219
220                 if (property != null) {
221                     properties.put(property, "true");
222                 }
223             }
224             proc.waitFor();
225             proc.getInputStream().close();
226             proc.getOutputStream().close();
227             proc.getErrorStream().close();
228
229         } catch (Exception JavaDoc ex) {
230             LOG.warn(ex.getMessage(), ex);
231         }
232         System.out.println(); // finishing dotted line, avoid LOG prefix 'MKS - '
233
LOG.info("resync finished");
234
235         return listOfModifications;
236     }
237
238     /**
239      * Sample output:
240      * dominik.hirt;add forceDeploy peter.neumcke;path to properties file fixed,
241      * copy generated properties Member added to project
242      * d:/MKS/PCE_Usedom/Products/Info/Info.pj
243      *
244      * @param fileName
245      */

246     private void setUserNameAndComment(Modification modification,
247             String JavaDoc folderName, String JavaDoc fileName) {
248                 
249         try {
250             Commandline commandLine = new Commandline();
251             commandLine.setExecutable("si");
252     
253             if (localWorkingDir != null) {
254                 commandLine.setWorkingDirectory(localWorkingDir.getAbsolutePath());
255             }
256     
257             commandLine.createArgument().setValue("rlog");
258             commandLine.createArgument().setValue("--format={author};{description}");
259             commandLine.createArgument().setValue("--noHeaderFormat");
260             commandLine.createArgument().setValue("--noTrailerFormat");
261             commandLine.createArgument().setValue("-r");
262             commandLine.createArgument().setValue(modification.revision);
263             commandLine.createArgument().setValue(folderName + File.separator + fileName);
264               
265             LOG.debug(commandLine.toString());
266             
267             Process JavaDoc proc = commandLine.execute();
268             
269             logStream(proc.getErrorStream(), System.err);
270             InputStream JavaDoc in = proc.getInputStream();
271             BufferedReader JavaDoc reader = new BufferedReader JavaDoc(
272                     new InputStreamReader JavaDoc(in));
273             String JavaDoc line = reader.readLine();
274             LOG.debug(line);
275
276             int idx = line.indexOf(";");
277             while (idx == -1) {
278                 line = reader.readLine(); // unknown output, read again
279
LOG.debug(line);
280                 idx = line.indexOf(";");
281             }
282
283             modification.userName = line.substring(0, idx);
284             modification.comment = line.substring(idx + 1);
285             
286             proc.waitFor();
287             proc.getInputStream().close();
288             proc.getOutputStream().close();
289             proc.getErrorStream().close();
290         } catch (Exception JavaDoc e) {
291             LOG.warn(e.getMessage(), e);
292             modification.userName = "";
293             modification.comment = "";
294         }
295     }
296
297     private static void logStream(InputStream JavaDoc inStream, OutputStream JavaDoc outStream) {
298         StreamPumper errorPumper = new StreamPumper(inStream, new PrintWriter JavaDoc(
299                 outStream, true));
300         new Thread JavaDoc(errorPumper).start();
301     }
302 }
303
Popular Tags