1 | /*
|
---|
2 | * Copyright 2002-2004 The Apache Software Foundation
|
---|
3 | *
|
---|
4 | * Licensed under the Apache License, Version 2.0 (the "License");
|
---|
5 | * you may not use this file except in compliance with the License.
|
---|
6 | * You may obtain a copy of the License at
|
---|
7 | *
|
---|
8 | * http://www.apache.org/licenses/LICENSE-2.0
|
---|
9 | *
|
---|
10 | * Unless required by applicable law or agreed to in writing, software
|
---|
11 | * distributed under the License is distributed on an "AS IS" BASIS,
|
---|
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
---|
13 | * See the License for the specific language governing permissions and
|
---|
14 | * limitations under the License.
|
---|
15 | *
|
---|
16 | */
|
---|
17 | package org.apache.tools.ant.filters.util;
|
---|
18 |
|
---|
19 | import java.io.FilterReader;
|
---|
20 | import java.io.IOException;
|
---|
21 | import java.io.Reader;
|
---|
22 | import java.lang.reflect.Constructor;
|
---|
23 | import java.lang.reflect.InvocationTargetException;
|
---|
24 | import java.util.Vector;
|
---|
25 | import org.apache.tools.ant.AntClassLoader;
|
---|
26 | import org.apache.tools.ant.BuildException;
|
---|
27 | import org.apache.tools.ant.Project;
|
---|
28 | import org.apache.tools.ant.filters.BaseFilterReader;
|
---|
29 | import org.apache.tools.ant.filters.ChainableReader;
|
---|
30 | import org.apache.tools.ant.types.AntFilterReader;
|
---|
31 | import org.apache.tools.ant.types.FilterChain;
|
---|
32 | import org.apache.tools.ant.types.Parameter;
|
---|
33 | import org.apache.tools.ant.types.Parameterizable;
|
---|
34 | import org.apache.tools.ant.types.Path;
|
---|
35 | import org.apache.tools.ant.util.FileUtils;
|
---|
36 |
|
---|
37 | /**
|
---|
38 | * Process a FilterReader chain.
|
---|
39 | *
|
---|
40 | */
|
---|
41 | public final class ChainReaderHelper {
|
---|
42 |
|
---|
43 | // default buffer size
|
---|
44 | private static final int DEFAULT_BUFFER_SIZE = 8192;
|
---|
45 | /**
|
---|
46 | * The primary reader to which the reader chain is to be attached.
|
---|
47 | */
|
---|
48 | public Reader primaryReader;
|
---|
49 |
|
---|
50 | /**
|
---|
51 | * The size of the buffer to be used.
|
---|
52 | */
|
---|
53 | public int bufferSize = DEFAULT_BUFFER_SIZE;
|
---|
54 |
|
---|
55 | /**
|
---|
56 | * Chain of filters
|
---|
57 | */
|
---|
58 | public Vector filterChains = new Vector();
|
---|
59 |
|
---|
60 | /** The Ant project */
|
---|
61 | private Project project = null;
|
---|
62 |
|
---|
63 | /**
|
---|
64 | * Sets the primary reader
|
---|
65 | * @param rdr the reader object
|
---|
66 | */
|
---|
67 | public final void setPrimaryReader(Reader rdr) {
|
---|
68 | primaryReader = rdr;
|
---|
69 | }
|
---|
70 |
|
---|
71 | /**
|
---|
72 | * Set the project to work with
|
---|
73 | * @param project the current project
|
---|
74 | */
|
---|
75 | public final void setProject(final Project project) {
|
---|
76 | this.project = project;
|
---|
77 | }
|
---|
78 |
|
---|
79 | /**
|
---|
80 | * Get the project
|
---|
81 | *
|
---|
82 | * @return the current project
|
---|
83 | */
|
---|
84 | public final Project getProject() {
|
---|
85 | return project;
|
---|
86 | }
|
---|
87 |
|
---|
88 | /**
|
---|
89 | * Sets the buffer size to be used. Defaults to 4096,
|
---|
90 | * if this method is not invoked.
|
---|
91 | * @param size the buffer size to use
|
---|
92 | */
|
---|
93 | public final void setBufferSize(int size) {
|
---|
94 | bufferSize = size;
|
---|
95 | }
|
---|
96 |
|
---|
97 | /**
|
---|
98 | * Sets the collection of filter reader sets
|
---|
99 | *
|
---|
100 | * @param fchain the filter chains collection
|
---|
101 | */
|
---|
102 | public final void setFilterChains(Vector fchain) {
|
---|
103 | filterChains = fchain;
|
---|
104 | }
|
---|
105 |
|
---|
106 | /**
|
---|
107 | * Assemble the reader
|
---|
108 | * @return the assembled reader
|
---|
109 | * @exception BuildException if an error occurs
|
---|
110 | */
|
---|
111 | public final Reader getAssembledReader() throws BuildException {
|
---|
112 | if (primaryReader == null) {
|
---|
113 | throw new BuildException("primaryReader must not be null.");
|
---|
114 | }
|
---|
115 |
|
---|
116 | Reader instream = primaryReader;
|
---|
117 | final int filterReadersCount = filterChains.size();
|
---|
118 | final Vector finalFilters = new Vector();
|
---|
119 |
|
---|
120 | for (int i = 0; i < filterReadersCount; i++) {
|
---|
121 | final FilterChain filterchain =
|
---|
122 | (FilterChain) filterChains.elementAt(i);
|
---|
123 | final Vector filterReaders = filterchain.getFilterReaders();
|
---|
124 | final int readerCount = filterReaders.size();
|
---|
125 | for (int j = 0; j < readerCount; j++) {
|
---|
126 | finalFilters.addElement(filterReaders.elementAt(j));
|
---|
127 | }
|
---|
128 | }
|
---|
129 |
|
---|
130 | final int filtersCount = finalFilters.size();
|
---|
131 |
|
---|
132 | if (filtersCount > 0) {
|
---|
133 | for (int i = 0; i < filtersCount; i++) {
|
---|
134 | Object o = finalFilters.elementAt(i);
|
---|
135 |
|
---|
136 | if (o instanceof AntFilterReader) {
|
---|
137 | final AntFilterReader filter
|
---|
138 | = (AntFilterReader) finalFilters.elementAt(i);
|
---|
139 | final String className = filter.getClassName();
|
---|
140 | final Path classpath = filter.getClasspath();
|
---|
141 | final Project project = filter.getProject();
|
---|
142 | if (className != null) {
|
---|
143 | try {
|
---|
144 | Class clazz = null;
|
---|
145 | if (classpath == null) {
|
---|
146 | clazz = Class.forName(className);
|
---|
147 | } else {
|
---|
148 | AntClassLoader al
|
---|
149 | = project.createClassLoader(classpath);
|
---|
150 | clazz = Class.forName(className, true, al);
|
---|
151 | }
|
---|
152 | if (clazz != null) {
|
---|
153 | if (!FilterReader.class.isAssignableFrom(clazz)) {
|
---|
154 | throw new BuildException(className
|
---|
155 | + " does not extend java.io.FilterReader");
|
---|
156 | }
|
---|
157 | final Constructor[] constructors =
|
---|
158 | clazz.getConstructors();
|
---|
159 | int j = 0;
|
---|
160 | boolean consPresent = false;
|
---|
161 | for (; j < constructors.length; j++) {
|
---|
162 | Class[] types = constructors[j]
|
---|
163 | .getParameterTypes();
|
---|
164 | if (types.length == 1
|
---|
165 | && types[0].isAssignableFrom(Reader.class)) {
|
---|
166 | consPresent = true;
|
---|
167 | break;
|
---|
168 | }
|
---|
169 | }
|
---|
170 | if (!consPresent) {
|
---|
171 | throw new BuildException(className
|
---|
172 | + " does not define a public constructor"
|
---|
173 | + " that takes in a Reader as its "
|
---|
174 | + "single argument.");
|
---|
175 | }
|
---|
176 | final Reader[] rdr = {instream};
|
---|
177 | instream =
|
---|
178 | (Reader) constructors[j].newInstance(rdr);
|
---|
179 | setProjectOnObject(instream);
|
---|
180 | if (Parameterizable.class.isAssignableFrom(clazz)) {
|
---|
181 | final Parameter[] params = filter.getParams();
|
---|
182 | ((Parameterizable)
|
---|
183 | instream).setParameters(params);
|
---|
184 | }
|
---|
185 | }
|
---|
186 | } catch (final ClassNotFoundException cnfe) {
|
---|
187 | throw new BuildException(cnfe);
|
---|
188 | } catch (final InstantiationException ie) {
|
---|
189 | throw new BuildException(ie);
|
---|
190 | } catch (final IllegalAccessException iae) {
|
---|
191 | throw new BuildException(iae);
|
---|
192 | } catch (final InvocationTargetException ite) {
|
---|
193 | throw new BuildException(ite);
|
---|
194 | }
|
---|
195 | }
|
---|
196 | } else if (o instanceof ChainableReader) {
|
---|
197 | setProjectOnObject(o);
|
---|
198 | instream = ((ChainableReader) o).chain(instream);
|
---|
199 | setProjectOnObject(instream);
|
---|
200 | }
|
---|
201 | }
|
---|
202 | }
|
---|
203 | return instream;
|
---|
204 | }
|
---|
205 |
|
---|
206 | /**
|
---|
207 | * helper method to set the project on an object.
|
---|
208 | * the reflection setProject does not work for anonymous/protected/private
|
---|
209 | * classes, even if they have public methods.
|
---|
210 | */
|
---|
211 | private void setProjectOnObject(Object obj) {
|
---|
212 | if (project == null) {
|
---|
213 | return;
|
---|
214 | }
|
---|
215 | if (obj instanceof BaseFilterReader) {
|
---|
216 | ((BaseFilterReader) obj).setProject(project);
|
---|
217 | return;
|
---|
218 | }
|
---|
219 | project.setProjectReference(obj);
|
---|
220 | }
|
---|
221 |
|
---|
222 | /**
|
---|
223 | * Read data from the reader and return the
|
---|
224 | * contents as a string.
|
---|
225 | * @param rdr the reader object
|
---|
226 | * @return the contents of the file as a string
|
---|
227 | * @exception IOException if an error occurs
|
---|
228 | */
|
---|
229 | public final String readFully(Reader rdr)
|
---|
230 | throws IOException {
|
---|
231 | return FileUtils.readFully(rdr, bufferSize);
|
---|
232 | }
|
---|
233 | }
|
---|