KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sourceforge > cruisecontrol > buildloggers > MergeLogger


1 /********************************************************************************
2  * CruiseControl, a Continuous Integration Toolkit
3  * Copyright (c) 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.buildloggers;
38
39 import net.sourceforge.cruisecontrol.BuildLogger;
40 import net.sourceforge.cruisecontrol.CruiseControlException;
41 import net.sourceforge.cruisecontrol.util.PruneElementFilter;
42 import net.sourceforge.cruisecontrol.util.ValidationHelper;
43
44 import org.jdom.Element;
45 import org.jdom.JDOMException;
46 import org.jdom.input.SAXBuilder;
47 import org.apache.log4j.Logger;
48 import org.apache.oro.io.GlobFilenameFilter;
49 import org.apache.oro.text.MalformedCachePatternException;
50
51 import java.io.File JavaDoc;
52 import java.io.FileFilter JavaDoc;
53 import java.io.IOException JavaDoc;
54 import java.util.Arrays JavaDoc;
55
56 /**
57  * This BuildLogger implementation merges other XML logs into the CruiseControl
58  * main log. It can work with either a single file, or a directory. If a
59  * directory is specified, then all the XML files in that directory will be
60  * merged into the CruiseControl log.
61  *
62  */

63 public class MergeLogger implements BuildLogger {
64
65     private static final Logger LOG = Logger.getLogger(MergeLogger.class);
66
67     private String JavaDoc file;
68     private String JavaDoc dir;
69     private String JavaDoc pattern = "*.xml";
70     private GlobFilenameFilter fileNameFilter;
71     private boolean removeProperties = true;
72
73     public void setFile(String JavaDoc file) {
74         this.file = file;
75     }
76
77     public void setDir(String JavaDoc dir) {
78         this.dir = dir;
79     }
80
81     /**
82      * Sets the pattern which the filenames in a directory must match.
83      * Default pattern is "*.xml". Invalidates the current filename
84      * filter. The filename filter is compiled using compilePattern().
85      * @param pattern a valid Jakarta-ORO Glob pattern.
86      */

87     public void setPattern(String JavaDoc pattern) {
88         this.pattern = pattern;
89         this.fileNameFilter = null;
90     }
91
92     public void validate() throws CruiseControlException {
93         ValidationHelper.assertFalse(file == null && dir == null,
94             "one of file or dir are required attributes");
95         ValidationHelper.assertFalse(file != null && dir != null,
96             "only one of file or dir may be specified");
97
98         ValidationHelper.assertFalse(dir != null && pattern == null,
99             "no file pattern was specified");
100         compilePattern();
101     }
102
103     /**
104      * Compiles the pattern in the a filename filter. Only compiles
105      * if a pattern is specified and fileNameFilter == null.
106      * @throws CruiseControlException if an invalid pattern is specified.
107      */

108     private void compilePattern() throws CruiseControlException {
109         if (fileNameFilter == null && pattern != null) {
110             try {
111                fileNameFilter = new GlobFilenameFilter(pattern);
112             } catch (MalformedCachePatternException e) {
113                 ValidationHelper.fail("Invalid filename pattern " + pattern, e);
114             }
115         }
116     }
117
118     /**
119      * Note: the plugin must be {@link #validate() validated} before calling this method.
120      */

121     public void log(Element buildLog) throws CruiseControlException {
122         String JavaDoc nextLogFilename = ((file != null) ? file : dir);
123         mergeFile(new File JavaDoc(nextLogFilename), buildLog);
124     }
125
126     /**
127      * Recursive method that merges the specified file into the buildLog. If
128      * the file is a directory, then all it's children that are XML files
129      * are merged matching the specified pattern.
130      */

131     private void mergeFile(File JavaDoc nextLogFile, Element buildLog) {
132
133         if (!nextLogFile.exists()) {
134             LOG.info(nextLogFile.toString() + " does not exist. Skipping ...");
135         } else if (nextLogFile.isDirectory()) {
136             File JavaDoc[] children = nextLogFile.listFiles(new FileFilter JavaDoc() {
137                 public boolean accept(File JavaDoc file) {
138                     return file.isDirectory()
139                             || fileNameFilter.accept(file);
140                 }
141             });
142             Arrays.sort(children);
143             for (int j = 0; j < children.length; j++) {
144                 mergeFile(children[j], buildLog);
145             }
146         } else {
147             Element auxLogElement = getElement(nextLogFile);
148             if (auxLogElement != null) {
149                 buildLog.addContent(auxLogElement.detach());
150             }
151         }
152     }
153
154     /**
155      * Get a JDOM <code>Element</code> from an XML file.
156      *
157      * @param xmlFile The file name to read.
158      * @return JDOM <code>Element</code> representing that xml file.
159      */

160     Element getElement(File JavaDoc xmlFile) {
161         try {
162             SAXBuilder builder =
163                 new SAXBuilder("org.apache.xerces.parsers.SAXParser");
164             if (removeProperties) {
165                 builder.setXMLFilter(new PruneElementFilter("properties"));
166             }
167             return builder.build(xmlFile).getRootElement();
168         } catch (JDOMException e) {
169             LOG.warn("Could not read log: " + xmlFile + ". Skipping...", e);
170         } catch (IOException JavaDoc e) {
171             LOG.warn("Could not read log: " + xmlFile + ". Skipping...", e);
172         }
173
174         return null;
175     }
176
177     public void setRemoveProperties(boolean b) {
178         removeProperties = b;
179     }
180 }
181
Popular Tags