001: /*
002: * @(#)XMLFileParserGenerator.java
003: *
004: * Copyright (C) 2002-2003 Matt Albrecht
005: * groboclown@users.sourceforge.net
006: * http://groboutils.sourceforge.net
007: *
008: * Part of the GroboUtils package at:
009: * http://groboutils.sourceforge.net
010: *
011: * Permission is hereby granted, free of charge, to any person obtaining a
012: * copy of this software and associated documentation files (the "Software"),
013: * to deal in the Software without restriction, including without limitation
014: * the rights to use, copy, modify, merge, publish, distribute, sublicense,
015: * and/or sell copies of the Software, and to permit persons to whom the
016: * Software is furnished to do so, subject to the following conditions:
017: *
018: * The above copyright notice and this permission notice shall be included in
019: * all copies or substantial portions of the Software.
020: *
021: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
022: * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
023: * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
024: * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
025: * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
026: * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
027: * DEALINGS IN THE SOFTWARE.
028: */
029: package net.sourceforge.groboutils.pmti.v1.autodoc.v1.xml;
030:
031: import java.io.File;
032: import java.io.Writer;
033: import java.io.StringWriter;
034: import java.io.PrintWriter;
035: import java.io.IOException;
036: import java.io.FilenameFilter;
037:
038: import java.util.Vector;
039: import java.util.Enumeration;
040:
041: import net.sourceforge.groboutils.pmti.v1.itf.parser.IParserGenerator;
042: import net.sourceforge.groboutils.pmti.v1.itf.parser.IParser;
043: import net.sourceforge.groboutils.pmti.v1.itf.IIssueRecord;
044: import net.sourceforge.groboutils.pmti.v1.itf.ITestIssueRecord;
045:
046: import org.xml.sax.Parser;
047:
048: /**
049: * Parses the directory or directories containing the output of XMLFileServer
050: * into individual IParsers, one for each file.
051: *
052: * @author Matt Albrecht <a href="mailto:groboclown@users.sourceforge.net">groboclown@users.sourceforge.net</a>
053: * @since March 17, 2002
054: * @version $Date: 2003/02/10 22:51:57 $
055: */
056: public class XMLFileParserGenerator implements IParserGenerator {
057: public static final String DEFAULT_PREFIX = "ISSUES-";
058: public static final String DEFAULT_POSTFIX = ".xml";
059:
060: private Vector sourceDirs = new Vector();
061: private String filePrefix;
062: private String filePostfix;
063: private Parser parser;
064:
065: /**
066: * Case-insensitive file filter.
067: */
068: private static class PrefixPostfixFilter implements FilenameFilter {
069: private String pre;
070: private String post;
071:
072: public PrefixPostfixFilter(String pre, String post) {
073: this .pre = pre.toLowerCase();
074: this .post = post.toLowerCase();
075: }
076:
077: public boolean accept(File dir, String name) {
078: String n = name.toLowerCase();
079: return (n.startsWith(this .pre) && n.endsWith(this .post));
080: }
081: }
082:
083: public XMLFileParserGenerator() {
084: this ((File[]) null, null, null);
085: }
086:
087: public XMLFileParserGenerator(File dir) {
088: this (new File[] { dir }, null, null);
089: }
090:
091: public XMLFileParserGenerator(File dir, String prefix,
092: String postfix) {
093: this (new File[] { dir }, prefix, postfix);
094: }
095:
096: public XMLFileParserGenerator(File dirs[]) {
097: this (dirs, null, null);
098: }
099:
100: public XMLFileParserGenerator(File dirs[], String prefix,
101: String postfix) {
102: addSourceDirs(dirs);
103: setFilePrefix(prefix);
104: setFilePostfix(postfix);
105: }
106:
107: /**
108: * Sets the SAX 1.0 parser.
109: */
110: public void setSAXParser(Parser p) {
111: if (p != null) {
112: this .parser = p;
113: }
114: }
115:
116: /**
117: * Set the text that all XML Issue file names must begin with. Unlike the
118: * <tt>XMLFileServer</tt>, the prefix must not contain path information
119: * due to the detection methods used. If a <tt>null</tt> is passed in,
120: * then the default value ("ISSUE-") is used instead. The string will
121: * be considered case-insensitive for searching purposes.
122: *
123: * @param prefix the new prefix value to use.
124: */
125: public void setFilePrefix(String prefix) {
126: if (prefix == null) {
127: prefix = DEFAULT_PREFIX;
128: }
129: this .filePrefix = prefix;
130: }
131:
132: /**
133: * Set the text that all XML Issue file names must end with.
134: * If a <tt>null</tt> is passed in,
135: * then the default value (".xml") is used instead. The string will
136: * be considered case-insensitive for searching purposes.
137: *
138: * @param postfix the new postfix value to use.
139: */
140: public void setFilePostfix(String postfix) {
141: if (postfix == null) {
142: postfix = DEFAULT_POSTFIX;
143: }
144: this .filePostfix = postfix;
145: }
146:
147: /**
148: * Adds <tt>dir</tt> to the internal list of directories to check
149: * for issue XML files. Subdirectories will not be inspected, unless they
150: * are explicitly added.
151: *
152: * @param dir additional directory to search for issue files.
153: * <tt>null</tt> values, non-directories, and non-existent files will
154: * be ignored.
155: * @see #addSourceDirs( File[] )
156: */
157: public void addSourceDir(File dir) {
158: addSourceDirs(new File[] { dir });
159: }
160:
161: /**
162: * Adds the given directories to the internal list of directories to check
163: * for issue XML files. Subdirectories will not be inspected, unless they
164: * are explicitly added.
165: *
166: * @param dirs additional directories to search for issue files.
167: * <tt>null</tt> values, non-directories, and non-existent files will
168: * be ignored.
169: * @see #addSourceDir( File )
170: */
171: public void addSourceDirs(File dirs[]) {
172: if (dirs == null) {
173: return;
174: }
175:
176: // Get only the valid dirs
177: for (int i = 0; i < dirs.length; ++i) {
178: if (dirs[i] != null && dirs[i].exists()
179: && dirs[i].isDirectory()) {
180: this .sourceDirs.addElement(dirs[i]);
181: }
182: }
183: }
184:
185: /**
186: * Generate a collection of parsers which know how to create test records.
187: */
188: public IParser[] createParsers() {
189: Vector parsers = new Vector();
190:
191: Enumeration dirs = this .sourceDirs.elements();
192: while (dirs.hasMoreElements()) {
193: File f[] = findIssueFiles((File) dirs.nextElement());
194: for (int i = 0; i < f.length; ++i) {
195: IParser p = createParser(f[i]);
196: if (p != null) {
197: parsers.addElement(p);
198: }
199: }
200: }
201:
202: IParser p[] = new IParser[parsers.size()];
203: parsers.copyInto(p);
204:
205: return p;
206: }
207:
208: protected File[] findIssueFiles(File dir) {
209: FilenameFilter filter = createFilter();
210: String found[] = dir.list(filter);
211:
212: File ret[] = new File[found.length];
213: for (int i = 0; i < found.length; ++i) {
214: ret[i] = new File(dir, found[i]);
215: }
216: return ret;
217: }
218:
219: protected IParser createParser(File issueFile) {
220: return new XMLFileParser(issueFile, this .parser);
221: }
222:
223: protected FilenameFilter createFilter() {
224: return new PrefixPostfixFilter(this.filePrefix,
225: this.filePostfix);
226: }
227: }
|