001: /*
002: * ====================================================================
003: * JAFFA - Java Application Framework For All
004: *
005: * Copyright (C) 2002 JAFFA Development Group
006: *
007: * This library is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU Lesser General Public
009: * License as published by the Free Software Foundation; either
010: * version 2.1 of the License, or (at your option) any later version.
011: *
012: * This library is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this library; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
020: *
021: * Redistribution and use of this software and associated documentation ("Software"),
022: * with or without modification, are permitted provided that the following conditions are met:
023: * 1. Redistributions of source code must retain copyright statements and notices.
024: * Redistributions must also contain a copy of this document.
025: * 2. Redistributions in binary form must reproduce the above copyright notice,
026: * this list of conditions and the following disclaimer in the documentation
027: * and/or other materials provided with the distribution.
028: * 3. The name "JAFFA" must not be used to endorse or promote products derived from
029: * this Software without prior written permission. For written permission,
030: * please contact mail to: jaffagroup@yahoo.com.
031: * 4. Products derived from this Software may not be called "JAFFA" nor may "JAFFA"
032: * appear in their names without prior written permission.
033: * 5. Due credit should be given to the JAFFA Project (http://jaffa.sourceforge.net).
034: *
035: * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
036: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
037: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
038: * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
039: * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
040: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
041: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
042: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
043: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
044: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
045: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
046: * SUCH DAMAGE.
047: * ====================================================================
048: */
049:
050: /*
051: * ConfigMerge.java
052: *
053: * Created on October 29, 2001, 3:03 PM
054: */
055:
056: package org.jaffa.tools.build;
057:
058: import java.io.*;
059: import java.util.*;
060: import java.net.*;
061: import org.jaffa.util.URLHelper;
062: import org.jaffa.tools.common.SourceDecomposer;
063: import org.jaffa.tools.common.SourceDecomposerException;
064: import org.jaffa.util.StringHelper;
065: import org.jaffa.util.FindFiles;
066:
067: /** This will update the input configFile re-writing with the contents of fragment files from the searchpath.
068: * The configFile will be decomposed. The key for each GuardedBlock will correspond to the name of a particular type of fragment file.
069: * The fragment files will be searched in the input searchpath (the classpath will be used, if no searchpath is specified).
070: * The non-GuardedBlocks of the input file will be left as is.
071: */
072: public class ConfigFileUpdate {
073:
074: /** Updates a config file with fragments for each of the guarded block.
075: * This will use the classpath to search the fragments.
076: * @param configFileName The configuration file, relative to the classpath.
077: * @throws IOException if any IO error occurs.
078: * @throws SourceDecomposerException if the file is malformed or if it cannot be decomposed.
079: * @throws URISyntaxException if the input configFileName is an invalid URI.
080: * @throws MalformedURLException if the input configFileName is an invalid URL.
081: */
082: public static void performMerge(String configFileName)
083: throws IOException, SourceDecomposerException,
084: URISyntaxException, MalformedURLException {
085: performMerge(configFileName, System
086: .getProperty("java.class.path"));
087: }
088:
089: /** Updates a config file with fragments for each of the guarded block.
090: * @param configFileName The configuration file, relative to the classpath.
091: * @param searchPath The path to be used for searching the fragment files.
092: * @throws IOException if any IO error occurs.
093: * @throws SourceDecomposerException if the file is malformed or if it cannot be decomposed.
094: * @throws URISyntaxException if the input configFileName is an invalid URI.
095: * @throws MalformedURLException if the input configFileName is an invalid URL.
096: */
097: public static void performMerge(String configFileName,
098: String searchPath) throws IOException,
099: SourceDecomposerException, URISyntaxException,
100: MalformedURLException {
101: URL configFileUrl = URLHelper.newExtendedURL(configFileName);
102: URI configFileUri = new URI(configFileUrl.toExternalForm());
103: File configFile = new File(configFileUri);
104:
105: System.out.println("Decomposing Config File : " + configFile);
106:
107: StringBuffer buf = new StringBuffer();
108: SourceDecomposer sdConfig = new SourceDecomposer(
109: new BufferedReader(new FileReader(configFile)));
110: Collection elements = sdConfig.getCollection();
111: if (elements != null) {
112: for (Iterator itr = elements.iterator(); itr.hasNext();) {
113: Object obj = itr.next();
114: if (obj instanceof SourceDecomposer.PlainText) {
115: buf.append(((SourceDecomposer.PlainText) obj)
116: .getContents());
117: } else if (obj instanceof SourceDecomposer.GuardedBlock) {
118: buf.append(getGuardedBlockContents(
119: (SourceDecomposer.GuardedBlock) obj,
120: searchPath));
121: } else if (obj instanceof SourceDecomposer.GuardedBorder) {
122: buf.append(((SourceDecomposer.GuardedBorder) obj)
123: .getContents());
124: } else {
125: // do nothing
126: }
127:
128: }
129: }
130: Writer writer = new BufferedWriter(new FileWriter(configFile,
131: false));
132:
133: writer.write(buf.toString());
134: writer.close();
135:
136: }
137:
138: private static String getGuardedBlockContents(
139: SourceDecomposer.GuardedBlock gb, String searchPath)
140: throws IOException {
141: StringBuffer buf = new StringBuffer();
142: PushbackReader existingContents = new PushbackReader(
143: new StringReader(gb.getContents()));
144:
145: // get the first line from the guarded block & add to the buffer
146: buf.append(getFirstLine(existingContents));
147:
148: // find all the files which match the KEY
149: FindFiles ff = new FindFiles(searchPath, gb.getKey());
150: List files = ff.getList();
151:
152: // Add the contents of each file to the buffer
153: if (files != null) {
154: for (Iterator itr = files.iterator(); itr.hasNext();) {
155: File file = (File) itr.next();
156: PushbackReader reader = new PushbackReader(
157: new BufferedReader(new FileReader(file)));
158: StringHelper.Line line = null;
159: while ((line = StringHelper.readLine(reader)) != null)
160: buf.append(line);
161: buf.append('\n');
162: System.out.println("Added the contents of "
163: + file.getName());
164: reader.close();
165: }
166: }
167:
168: // get the last line from the guarded block & add to the buffer
169: buf.append(getLastLine(existingContents));
170:
171: return buf.toString();
172: }
173:
174: private static String getFirstLine(PushbackReader reader)
175: throws IOException {
176: return StringHelper.readLine(reader).toString();
177: }
178:
179: private static String getLastLine(PushbackReader reader)
180: throws IOException {
181: StringHelper.Line line = null;
182: StringHelper.Line lastLine = null;
183: while ((line = StringHelper.readLine(reader)) != null)
184: lastLine = line;
185: return lastLine.toString();
186: }
187:
188: /** This will invoke the performMerge method, passing the input arguments.
189: * @param args the command line arguments. The first argument will be the ConfigFileName relative to ClassPath. The optional second argument will be the search path.
190: */
191: public static void main(String args[]) {
192: try {
193: if (args.length == 1) {
194: performMerge(args[0]);
195: } else if (args.length == 2) {
196: performMerge(args[0], args[1]);
197: } else {
198: usage();
199: }
200: } catch (Exception e) {
201: e.printStackTrace();
202: System.exit(1);
203: }
204: }
205:
206: private static void usage() {
207: System.err
208: .println("Usage: ConfigFileUpdate <ConfigFileName relative to ClassPath> [<Search Path>]");
209: System.exit(1);
210: }
211: }
|