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: // NOTE: do not use the 'GEN-LINE' as it causes a blank line to be added !!!
051: package org.jaffa.tools.common;
052:
053: import java.io.*;
054: import java.util.*;
055: import java.net.URL;
056: import org.jaffa.util.StringHelper;
057: import org.jaffa.util.URLHelper;
058:
059: /** This class will decompose a file into a collection of GuardedBlock, GuardedBorder and PlainText objects.
060: * The file will have to be created/views within NetBeans/Forte to appreciate the significance of these different objects.
061: * A GuardedBlock is a piece of text which cannot be modified in the NetBeans editor.
062: * A GuardedBorder marks a block where custom code can be entered in the NetBeans editor.
063: * A PlainText is just some text, which is not guarded.
064: */
065: public class SourceDecomposer {
066: static final String LINE = "//GEN-LINE";
067: static final String BEGIN = "//GEN-BEGIN";
068: static final String END = "//GEN-END";
069: static final String FIRST = "//GEN-FIRST";
070: static final String LAST = "//GEN-LAST";
071:
072: private Collection m_col = new ArrayList();
073: private Map m_guardedBorderMap = new HashMap();
074:
075: /** This will create an instance of the class. It will decompose the file passed via the input Reader.
076: * @param reader The input file passed as a stream.
077: * @throws IOException if any IO error occurs
078: * @throws SourceDecomposerException if the file is malformed or if it cannot be decomposed.
079: */
080: public SourceDecomposer(BufferedReader reader) throws IOException,
081: SourceDecomposerException {
082: decompose(new PushbackReader(reader));
083: }
084:
085: /** Returns the Collection of the decomposed stream elements.
086: * @return the Collection of the decomposed stream elements.
087: */
088: public Collection getCollection() {
089: return m_col;
090: }
091:
092: /** Returns a GuardedBorder object for the input key. A null will be returned if no such object exists.
093: * @param key the input.
094: * @return a GuardedBorder object for the input key.
095: */
096: public GuardedBorder getGuardedBorder(String key) {
097: return (GuardedBorder) m_guardedBorderMap.get(key);
098: }
099:
100: /** decompose the input stream into a Collection containing PlainText, GuardedBlock & GuardedBorder */
101: private void decompose(PushbackReader reader) throws IOException,
102: SourceDecomposerException {
103:
104: StringHelper.Line line = null;
105: StringBuffer buf = new StringBuffer();
106: boolean gotBegin = false;
107: boolean gotFirst = false;
108: String key = null;
109:
110: while ((line = StringHelper.readLine(reader)) != null) {
111: if (line.getContents().indexOf(LINE) >= 0) {
112: // check for errors
113: if (gotBegin || gotFirst)
114: throw new SourceDecomposerException(buf.toString()
115: + line);
116:
117: // create a PlainText if the buffer has contents
118: if (buf.length() >= 0) {
119: m_col.add(new PlainText(buf.toString()));
120: buf.setLength(0);
121: }
122:
123: // create a GuardedBlock
124: m_col.add(new GuardedBlock(getKey(line.getContents(),
125: LINE), line.toString()));
126:
127: } else if (line.getContents().indexOf(BEGIN) >= 0) {
128: // check for errors
129: if (gotBegin || gotFirst)
130: throw new SourceDecomposerException(buf.toString()
131: + line);
132:
133: // create a PlainText if the buffer has contents
134: if (buf.length() > 0) {
135: m_col.add(new PlainText(buf.toString()));
136: buf.setLength(0);
137: }
138:
139: // add to the buffer & set the context
140: buf.append(line);
141: gotBegin = true;
142: key = getKey(line.getContents(), BEGIN);
143:
144: } else if (line.getContents().indexOf(END) >= 0) {
145: // check for errors
146: if (!gotBegin
147: || (key == null ? getKey(line.getContents(),
148: END) != null : !key.equals(getKey(line
149: .getContents(), END))))
150: throw new SourceDecomposerException(buf.toString()
151: + line);
152:
153: buf.append(line);
154: m_col.add(new GuardedBlock(key, buf.toString()));
155: buf.setLength(0);
156: gotBegin = false;
157:
158: } else if (line.getContents().indexOf(FIRST) >= 0) {
159: // check for errors
160: if (gotBegin || gotFirst)
161: throw new SourceDecomposerException(buf.toString()
162: + line);
163:
164: // create a PlainText if the buffer has contents
165: if (buf.length() > 0) {
166: m_col.add(new PlainText(buf.toString()));
167: buf.setLength(0);
168: }
169:
170: // add to the buffer & set the context
171: buf.append(line);
172: gotFirst = true;
173: key = getKey(line.getContents(), FIRST);
174:
175: } else if (line.getContents().indexOf(LAST) >= 0) {
176: // check for errors
177: if (!gotFirst
178: || (key == null ? getKey(line.getContents(),
179: LAST) != null : !key.equals(getKey(line
180: .getContents(), LAST))))
181: throw new SourceDecomposerException(buf.toString()
182: + line);
183:
184: buf.append(line);
185: GuardedBorder gb = new GuardedBorder(key, buf
186: .toString());
187: m_col.add(gb);
188: m_guardedBorderMap.put(key, gb);
189: buf.setLength(0);
190: gotFirst = false;
191:
192: } else {
193: buf.append(line);
194: }
195: }
196:
197: if (buf.length() > 0) {
198: if (gotBegin || gotFirst)
199: throw new SourceDecomposerException(buf.toString()
200: + line);
201:
202: m_col.add(new PlainText(buf.toString()));
203: buf.setLength(0);
204: }
205: }
206:
207: private String getKey(String line, String searchStr) {
208: String key = null;
209: searchStr = searchStr + ":";
210: int i = line.indexOf(searchStr);
211: if (i >= 0 && (i + searchStr.length()) < line.length()) {
212: //key = line.substring( i + searchStr.length() );
213: StringTokenizer stz = new StringTokenizer(line.substring(i
214: + searchStr.length()));
215: if (stz.hasMoreTokens())
216: key = stz.nextToken();
217: }
218: return key;
219: }
220:
221: /** For the input file, a PlainText object will represent text, which is not guarded.
222: */
223: public static class PlainText {
224: private String m_contents = null;
225:
226: /** Creates an instance.
227: * @param contents The text that this object represents.
228: */
229: public PlainText(String contents) {
230: m_contents = contents;
231: }
232:
233: /** Returns the text that this object represents.
234: * @return the text that this object represents.
235: */
236: public String getContents() {
237: return m_contents;
238: }
239:
240: /** Sets the contents.
241: * @param contents the contents.
242: */
243: public void setContents(String contents) {
244: m_contents = contents;
245: }
246:
247: /** Returns debug info.
248: * @return debug info.
249: */
250: public String toString() {
251: StringBuffer buf = new StringBuffer();
252: buf.append("<PlainText>");
253: buf.append("<contents>");
254: if (m_contents != null)
255: buf.append(m_contents);
256: buf.append("</contents>");
257: buf.append("</PlainText>");
258: return buf.toString();
259: }
260: }
261:
262: /** For the input file, a GuardedBlock object will represent text, which cannot be modified in the NetBeans editor.
263: */
264: public static class GuardedBlock {
265: private String m_key = null;
266: private String m_contents = null;
267:
268: /** Creates an instance.
269: * @param key The key which indentifies this guarded block of text.
270: * @param contents The contents of the guarded block.
271: */
272: public GuardedBlock(String key, String contents) {
273: m_key = key;
274: m_contents = contents;
275: }
276:
277: /** Returns the key.
278: * @return the key.
279: */
280: public String getKey() {
281: return m_key;
282: }
283:
284: /** Returns the contents.
285: * @return the contents.
286: */
287: public String getContents() {
288: return m_contents;
289: }
290:
291: /** Sets the contents.
292: * @param contents the contents.
293: */
294: public void setContents(String contents) {
295: m_contents = contents;
296: }
297:
298: /** Returns debug info.
299: * @return debug info.
300: */
301: public String toString() {
302: StringBuffer buf = new StringBuffer();
303: buf.append("<GuardedBlock>");
304: buf.append("<key>");
305: if (m_key != null)
306: buf.append(m_key);
307: buf.append("</key>");
308: buf.append("<contents>");
309: if (m_contents != null)
310: buf.append(m_contents);
311: buf.append("</contents>");
312: buf.append("</GuardedBlock>");
313: return buf.toString();
314: }
315: }
316:
317: /** For the input file, a GuardedBorder object will represent a block where custom code can be entered in the NetBeans editor.
318: */
319: public static class GuardedBorder {
320: private String m_key = null;
321: private String m_contents = null;
322:
323: /** Creates an instance.
324: * @param key The key which indentifies this guarded border
325: * @param contents The contents of the guarded border.
326: */
327: public GuardedBorder(String key, String contents) {
328: m_key = key;
329: m_contents = contents;
330: }
331:
332: /** Returns the key.
333: * @return the key.
334: */
335: public String getKey() {
336: return m_key;
337: }
338:
339: /** Returns the contents.
340: * @return the contents.
341: */
342: public String getContents() {
343: return m_contents;
344: }
345:
346: /** Sets the contents.
347: * @param contents the contents.
348: */
349: public void setContents(String contents) {
350: m_contents = contents;
351: }
352:
353: /** Returns debug info.
354: * @return debug info.
355: */
356: public String toString() {
357: StringBuffer buf = new StringBuffer();
358: buf.append("<GuardedBorder>");
359: buf.append("<key>");
360: if (m_key != null)
361: buf.append(m_key);
362: buf.append("</key>");
363: buf.append("<contents>");
364: if (m_contents != null)
365: buf.append(m_contents);
366: buf.append("</contents>");
367: buf.append("</GuardedBorder>");
368: return buf.toString();
369: }
370: }
371:
372: }
|