001: /*---------------------------------------------------------------------------*\
002: $Id: AbstractXMLEditPlugIn.java 7041 2007-09-09 01:04:47Z bmc $
003: ---------------------------------------------------------------------------
004: This software is released under a BSD-style license:
005:
006: Copyright (c) 2004-2007 Brian M. Clapper. 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 are
010: met:
011:
012: 1. Redistributions of source code must retain the above copyright notice,
013: this list of conditions and the following disclaimer.
014:
015: 2. The end-user documentation included with the redistribution, if any,
016: must include the following acknowlegement:
017:
018: "This product includes software developed by Brian M. Clapper
019: (bmc@clapper.org, http://www.clapper.org/bmc/). That software is
020: copyright (c) 2004-2007 Brian M. Clapper."
021:
022: Alternately, this acknowlegement may appear in the software itself,
023: if wherever such third-party acknowlegements normally appear.
024:
025: 3. Neither the names "clapper.org", "curn", nor any of the names of the
026: project contributors may be used to endorse or promote products
027: derived from this software without prior written permission. For
028: written permission, please contact bmc@clapper.org.
029:
030: 4. Products derived from this software may not be called "curn", nor may
031: "clapper.org" appear in their names without prior written permission
032: of Brian M. Clapper.
033:
034: THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
035: WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
036: MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
037: NO EVENT SHALL BRIAN M. CLAPPER BE LIABLE FOR ANY DIRECT, INDIRECT,
038: INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
039: NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
040: DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
041: THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
042: (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
043: THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
044: \*---------------------------------------------------------------------------*/
045:
046: package org.clapper.curn.plugins;
047:
048: import org.clapper.curn.CurnException;
049: import org.clapper.curn.FeedInfo;
050: import org.clapper.curn.CurnUtil;
051:
052: import org.clapper.util.io.FileUtil;
053: import org.clapper.util.logging.Logger;
054: import org.clapper.util.regex.RegexUtil;
055: import org.clapper.util.regex.RegexException;
056:
057: import java.io.BufferedReader;
058: import java.io.File;
059: import java.io.FileInputStream;
060: import java.io.FileOutputStream;
061: import java.io.FileReader;
062: import java.io.FileWriter;
063: import java.io.InputStreamReader;
064: import java.io.IOException;
065: import java.io.OutputStreamWriter;
066: import java.io.PrintWriter;
067:
068: import java.util.List;
069:
070: /**
071: * Useful common base class for plug-ins that perform regular expression-based
072: * edits on raw XML.
073: *
074: * @version <tt>$Revision: 7041 $</tt>
075: */
076: public abstract class AbstractXMLEditPlugIn {
077: /*----------------------------------------------------------------------*\
078: Private Instance Data
079: \*----------------------------------------------------------------------*/
080:
081: /**
082: * Regular expression helper
083: */
084: private RegexUtil regexUtil = new RegexUtil();
085:
086: /*----------------------------------------------------------------------*\
087: Constructor
088: \*----------------------------------------------------------------------*/
089:
090: /**
091: * Default constructor (required).
092: */
093: protected AbstractXMLEditPlugIn() {
094: // Nothing to do
095: }
096:
097: /*----------------------------------------------------------------------*\
098: Public Methods
099: \*----------------------------------------------------------------------*/
100:
101: /*----------------------------------------------------------------------*\
102: Protected Methods
103: \*----------------------------------------------------------------------*/
104:
105: /**
106: * Get the <tt>Logger</tt> object created for this object.
107: *
108: * @return the <tt>Logger</tt>
109: */
110: protected abstract Logger getLogger();
111:
112: /**
113: * Perform an edit on a feed, overwriting the data file at completion.
114: *
115: * @param feedInfo the feed
116: * @param feedDataFile the downloaded feed XML
117: * @param encoding the encoding to use when reading/writing the XML
118: * @param editCommands list of 's///' edit commands, suitable for use
119: * with {@link RegexUtil#substitute}
120: *
121: * @throws CurnException on error
122: */
123: protected void editXML(FeedInfo feedInfo, File feedDataFile,
124: String encoding, List<String> editCommands)
125: throws CurnException {
126: String feedURL = feedInfo.getURL().toString();
127: BufferedReader in = null;
128: PrintWriter out = null;
129: Logger log = getLogger();
130:
131: try {
132: File tempOutputFile = CurnUtil.createTempXMLFile();
133:
134: if (encoding != null) {
135: in = new BufferedReader(new InputStreamReader(
136: new FileInputStream(feedDataFile), encoding));
137: out = new PrintWriter(new OutputStreamWriter(
138: new FileOutputStream(tempOutputFile), encoding));
139: }
140:
141: else {
142: in = new BufferedReader(new FileReader(feedDataFile));
143: out = new PrintWriter(new FileWriter(tempOutputFile));
144: }
145:
146: String line;
147: int lineNumber = 0;
148:
149: while ((line = in.readLine()) != null) {
150: lineNumber++;
151: for (String editCommand : editCommands) {
152: if (log.isDebugEnabled() && (lineNumber == 1)) {
153: log.debug("Applying edit command \""
154: + editCommand
155: + "\" to downloaded XML for feed \""
156: + feedURL + ", line " + lineNumber);
157: }
158:
159: line = regexUtil.substitute(editCommand, line);
160: }
161:
162: out.println(line);
163: }
164:
165: in.close();
166: in = null;
167:
168: out.flush();
169: out.close();
170: out = null;
171:
172: log.debug("Copying temporary (edited) file \""
173: + tempOutputFile.getPath()
174: + "\" back over top of file \""
175: + feedDataFile.getPath() + "\".");
176: FileUtil.copyTextFile(tempOutputFile, encoding,
177: feedDataFile, encoding);
178:
179: tempOutputFile.delete();
180: }
181:
182: catch (IOException ex) {
183: throw new CurnException(ex);
184: }
185:
186: catch (RegexException ex) {
187: throw new CurnException(ex);
188: }
189:
190: finally {
191: try {
192: if (in != null)
193: in.close();
194:
195: if (out != null)
196: out.close();
197: }
198:
199: catch (IOException ex) {
200: log.error("I/O error", ex);
201: }
202: }
203: }
204: }
|