001: /*
002: * This file is part of PFIXCORE.
003: *
004: * PFIXCORE is free software; you can redistribute it and/or modify
005: * it under the terms of the GNU Lesser General Public License as published by
006: * the Free Software Foundation; either version 2 of the License, or
007: * (at your option) any later version.
008: *
009: * PFIXCORE is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
012: * GNU Lesser General Public License for more details.
013: *
014: * You should have received a copy of the GNU Lesser General Public License
015: * along with PFIXCORE; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
017: *
018: */
019: package de.schlund.pfixcore.util;
020:
021: import java.io.File;
022: import java.io.IOException;
023:
024: import org.apache.tools.ant.BuildException;
025: import org.apache.tools.ant.DirectoryScanner;
026: import org.apache.tools.ant.taskdefs.MatchingTask;
027: import org.w3c.dom.Comment;
028: import org.w3c.dom.Document;
029: import org.w3c.dom.Element;
030:
031: import de.schlund.pfixxml.util.FileUtils;
032: import de.schlund.pfixxml.util.Xml;
033:
034: /**
035: * This ant task iterates over all statusmessage files included from a source directory
036: * and creates or merges changes into an according merge file in the destination directory.
037: * Source and destination directory are used as base directories, i.e. a statusmessage file
038: * in a source sub directory will produce a merge file in an according sub directory of
039: * the destination directory. You additionally can define a filename suffix for this file,
040: * which is added after the name but before the file extension.
041: *
042: * @author mleidig@schlund.de
043: */
044: public class MergeTask extends MatchingTask {
045:
046: private File srcDir;
047: private File destDir;
048: private String suffix;
049: private String selection;
050:
051: /**
052: * Iterate over all included files and create according merge file or,
053: * if already existing, merge included file into the merge file.
054: */
055: @Override
056: public void execute() throws BuildException {
057: int createNo = 0;
058: int mergeNo = 0;
059: if (srcDir.exists()) {
060: DirectoryScanner scanner = getDirectoryScanner(srcDir);
061: String[] files = scanner.getIncludedFiles();
062: for (String file : files) {
063: File srcFile = new File(srcDir, file);
064: File destFile = new File(destDir, file);
065: if (suffix != null) {
066: String name = destFile.getName();
067: int ind = name.indexOf('.');
068: if (ind > -1) {
069: name = name.substring(0, ind) + suffix
070: + name.substring(ind);
071: } else
072: throw new BuildException(
073: "Expected file name containing file extension: "
074: + destFile.getAbsolutePath());
075: destFile = new File(destFile.getParentFile(), name);
076: }
077: boolean destExists = destFile.exists();
078: if (!destExists) {
079: try {
080: if (!destFile.getParentFile().exists())
081: destFile.getParentFile().mkdirs();
082: FileUtils.copyFile(srcFile, destFile);
083: } catch (IOException x) {
084: throw new BuildException(
085: "Error copying statusmessages from '"
086: + srcFile.getAbsolutePath()
087: + "' to '"
088: + destFile.getAbsolutePath()
089: + "'.", x);
090: }
091: try {
092: Document doc = Xml.parseMutable(destFile);
093: addComment(doc, file);
094: Xml.serialize(doc, destFile, true, true);
095: } catch (Exception x) {
096: throw new BuildException(
097: "Error adding comment to statusmessages file '"
098: + destFile.getAbsolutePath()
099: + "'.", x);
100: }
101: createNo++;
102: } else if (srcFile.lastModified() > destFile
103: .lastModified()) {
104: try {
105: Merge merge = new Merge(srcFile, selection,
106: destFile, false);
107: merge.run();
108: } catch (Exception x) {
109: throw new BuildException("Merging to file "
110: + destFile.getAbsolutePath()
111: + " failed.", x);
112: }
113: mergeNo++;
114: }
115: }
116: }
117: if (createNo > 0)
118: log("Created " + createNo + " statusmessage merge file"
119: + (createNo > 1 ? "s" : "") + ".");
120: if (mergeNo > 0)
121: log("Merged " + mergeNo + " statusmessage file"
122: + (mergeNo > 1 ? "s" : "") + ".");
123: }
124:
125: //Task properties:
126:
127: /**
128: * Set source base directory (where originating statusmessages can be found).
129: */
130: public void setSrcDir(File srcDir) {
131: this .srcDir = srcDir;
132: }
133:
134: /**
135: * Set destination base directory (where merged statusmessage are written).
136: */
137: public void setDestDir(File destDir) {
138: this .destDir = destDir;
139: }
140:
141: /**
142: * Set optional filename suffix for merged statusmessage file.
143: */
144: public void setSuffix(String suffix) {
145: this .suffix = suffix;
146: }
147:
148: /**
149: * Set XPath selecting the nodes to be merged.
150: */
151: public void setSelection(String selection) {
152: this .selection = selection;
153: }
154:
155: //--
156:
157: /**
158: * Insert a comment at the beginning of the statusmessage document.
159: */
160: private void addComment(Document doc, String mergeSource) {
161: Comment comment = doc
162: .createComment("\nThis file contains merged statusmessages from '"
163: + mergeSource
164: + "'.\n"
165: + "You can modify this file to change the messages for exisiting statuscodes.\n"
166: + "Adding new statuscodes has to be done within the originating module.\n");
167: Element element = doc.getDocumentElement();
168: if (element.hasChildNodes()) {
169: element.insertBefore(comment, element.getFirstChild());
170: element.insertBefore(doc.createTextNode(" \n \n"), element
171: .getFirstChild());
172: } else {
173: element.appendChild(doc.createTextNode("\n"));
174: element.appendChild(comment);
175: }
176: }
177:
178: }
|