001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: *
017: */
018: package org.apache.tools.ant.filters;
019:
020: import java.io.IOException;
021: import java.io.Reader;
022: import java.io.File;
023: import java.io.BufferedReader;
024: import java.io.FileReader;
025: import org.apache.tools.ant.types.Parameter;
026:
027: /**
028: * Concats a file before and/or after the file.
029: *
030: * <p>Example:<pre>
031: * <copy todir="build">
032: * <fileset dir="src" includes="*.java"/>
033: * <filterchain>
034: * <concatfilter prepend="apache-license-java.txt"/>
035: * </filterchain>
036: * </copy>
037: * </pre>
038: * Copies all java sources from <i>src</i> to <i>build</i> and adds the
039: * content of <i>apache-license-java.txt</i> add the beginning of each
040: * file.</p>
041: *
042: * @since 1.6
043: * @version 2003-09-23
044: */
045: public final class ConcatFilter extends BaseParamFilterReader implements
046: ChainableReader {
047:
048: /** File to add before the content. */
049: private File prepend;
050:
051: /** File to add after the content. */
052: private File append;
053:
054: /** Reader for prepend-file. */
055: private Reader prependReader = null;
056:
057: /** Reader for append-file. */
058: private Reader appendReader = null;
059:
060: /**
061: * Constructor for "dummy" instances.
062: *
063: * @see BaseFilterReader#BaseFilterReader()
064: */
065: public ConcatFilter() {
066: super ();
067: }
068:
069: /**
070: * Creates a new filtered reader.
071: *
072: * @param in A Reader object providing the underlying stream.
073: * Must not be <code>null</code>.
074: */
075: public ConcatFilter(final Reader in) {
076: super (in);
077: }
078:
079: /**
080: * Returns the next character in the filtered stream. If the desired
081: * number of lines have already been read, the resulting stream is
082: * effectively at an end. Otherwise, the next character from the
083: * underlying stream is read and returned.
084: *
085: * @return the next character in the resulting stream, or -1
086: * if the end of the resulting stream has been reached
087: *
088: * @exception IOException if the underlying stream throws an IOException
089: * during reading
090: */
091: public int read() throws IOException {
092: // do the "singleton" initialization
093: if (!getInitialized()) {
094: initialize();
095: setInitialized(true);
096: }
097:
098: int ch = -1;
099:
100: // The readers return -1 if they end. So simply read the "prepend"
101: // after that the "content" and at the end the "append" file.
102: if (prependReader != null) {
103: ch = prependReader.read();
104: if (ch == -1) {
105: // I am the only one so I have to close the reader
106: prependReader.close();
107: prependReader = null;
108: }
109: }
110: if (ch == -1) {
111: ch = super .read();
112: }
113: if (ch == -1) {
114: // don't call super.close() because that reader is used
115: // on other places ...
116: if (appendReader != null) {
117: ch = appendReader.read();
118: if (ch == -1) {
119: // I am the only one so I have to close the reader
120: appendReader.close();
121: appendReader = null;
122: }
123: }
124: }
125:
126: return ch;
127: }
128:
129: /**
130: * Sets <i>prepend</i> attribute.
131: * @param prepend new value
132: */
133: public void setPrepend(final File prepend) {
134: this .prepend = prepend;
135: }
136:
137: /**
138: * Returns <i>prepend</i> attribute.
139: * @return prepend attribute
140: */
141: public File getPrepend() {
142: return prepend;
143: }
144:
145: /**
146: * Sets <i>append</i> attribute.
147: * @param append new value
148: */
149: public void setAppend(final File append) {
150: this .append = append;
151: }
152:
153: /**
154: * Returns <i>append</i> attribute.
155: * @return append attribute
156: */
157: public File getAppend() {
158: return append;
159: }
160:
161: /**
162: * Creates a new ConcatReader using the passed in
163: * Reader for instantiation.
164: *
165: * @param rdr A Reader object providing the underlying stream.
166: * Must not be <code>null</code>.
167: *
168: * @return a new filter based on this configuration, but filtering
169: * the specified reader
170: */
171: public Reader chain(final Reader rdr) {
172: ConcatFilter newFilter = new ConcatFilter(rdr);
173: newFilter.setPrepend(getPrepend());
174: newFilter.setAppend(getAppend());
175: // Usually the initialized is set to true. But here it must not.
176: // Because the prepend and append readers have to be instantiated
177: // on runtime
178: //newFilter.setInitialized(true);
179: return newFilter;
180: }
181:
182: /**
183: * Scans the parameters list for the "lines" parameter and uses
184: * it to set the number of lines to be returned in the filtered stream.
185: * also scan for skip parameter.
186: */
187: private void initialize() throws IOException {
188: // get parameters
189: Parameter[] params = getParameters();
190: if (params != null) {
191: for (int i = 0; i < params.length; i++) {
192: if ("prepend".equals(params[i].getName())) {
193: setPrepend(new File(params[i].getValue()));
194: continue;
195: }
196: if ("append".equals(params[i].getName())) {
197: setAppend(new File(params[i].getValue()));
198: continue;
199: }
200: }
201: }
202: if (prepend != null) {
203: if (!prepend.isAbsolute()) {
204: prepend = new File(getProject().getBaseDir(), prepend
205: .getPath());
206: }
207: prependReader = new BufferedReader(new FileReader(prepend));
208: }
209: if (append != null) {
210: if (!append.isAbsolute()) {
211: append = new File(getProject().getBaseDir(), append
212: .getPath());
213: }
214: appendReader = new BufferedReader(new FileReader(append));
215: }
216: }
217: }
|