aboutsummaryrefslogtreecommitdiffstats
path: root/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/util/ChainReaderHelper.java
diff options
context:
space:
mode:
Diffstat (limited to 'framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/util/ChainReaderHelper.java')
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/util/ChainReaderHelper.java288
1 files changed, 288 insertions, 0 deletions
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/util/ChainReaderHelper.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/util/ChainReaderHelper.java
new file mode 100644
index 00000000..f176c331
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/util/ChainReaderHelper.java
@@ -0,0 +1,288 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.filters.util;
+
+import java.io.FilterReader;
+import java.io.IOException;
+import java.io.Reader;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Vector;
+
+import org.apache.tools.ant.AntClassLoader;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.filters.BaseFilterReader;
+import org.apache.tools.ant.filters.ChainableReader;
+import org.apache.tools.ant.types.AntFilterReader;
+import org.apache.tools.ant.types.FilterChain;
+import org.apache.tools.ant.types.Parameter;
+import org.apache.tools.ant.types.Parameterizable;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.util.FileUtils;
+
+/**
+ * Process a FilterReader chain.
+ *
+ */
+public final class ChainReaderHelper {
+
+ // default buffer size
+ private static final int DEFAULT_BUFFER_SIZE = 8192;
+ // CheckStyle:VisibilityModifier OFF - bc
+ /**
+ * The primary reader to which the reader chain is to be attached.
+ */
+ public Reader primaryReader;
+
+ /**
+ * The size of the buffer to be used.
+ */
+ public int bufferSize = DEFAULT_BUFFER_SIZE;
+
+ /**
+ * Chain of filters
+ */
+ public Vector<FilterChain> filterChains = new Vector<FilterChain>();
+
+ /** The Ant project */
+ private Project project = null;
+
+ // CheckStyle:VisibilityModifier ON
+
+ /**
+ * Sets the primary reader
+ * @param rdr the reader object
+ */
+ public void setPrimaryReader(Reader rdr) {
+ primaryReader = rdr;
+ }
+
+ /**
+ * Set the project to work with
+ * @param project the current project
+ */
+ public void setProject(final Project project) {
+ this.project = project;
+ }
+
+ /**
+ * Get the project
+ *
+ * @return the current project
+ */
+ public Project getProject() {
+ return project;
+ }
+
+ /**
+ * Sets the buffer size to be used. Defaults to 8192,
+ * if this method is not invoked.
+ * @param size the buffer size to use
+ */
+ public void setBufferSize(int size) {
+ bufferSize = size;
+ }
+
+ /**
+ * Sets the collection of filter reader sets
+ *
+ * @param fchain the filter chains collection
+ */
+ public void setFilterChains(Vector<FilterChain> fchain) {
+ filterChains = fchain;
+ }
+
+ /**
+ * Assemble the reader
+ * @return the assembled reader
+ * @exception BuildException if an error occurs
+ */
+ public Reader getAssembledReader() throws BuildException {
+ if (primaryReader == null) {
+ throw new BuildException("primaryReader must not be null.");
+ }
+
+ Reader instream = primaryReader;
+ final int filterReadersCount = filterChains.size();
+ final Vector<Object> finalFilters = new Vector<Object>();
+ final ArrayList<AntClassLoader> classLoadersToCleanUp =
+ new ArrayList<AntClassLoader>();
+
+ for (int i = 0; i < filterReadersCount; i++) {
+ final FilterChain filterchain =
+ filterChains.elementAt(i);
+ final Vector<Object> filterReaders = filterchain.getFilterReaders();
+ final int readerCount = filterReaders.size();
+ for (int j = 0; j < readerCount; j++) {
+ finalFilters.addElement(filterReaders.elementAt(j));
+ }
+ }
+
+ final int filtersCount = finalFilters.size();
+
+ if (filtersCount > 0) {
+ boolean success = false;
+ try {
+ for (int i = 0; i < filtersCount; i++) {
+ Object o = finalFilters.elementAt(i);
+
+ if (o instanceof AntFilterReader) {
+ instream =
+ expandReader((AntFilterReader) finalFilters.elementAt(i),
+ instream, classLoadersToCleanUp);
+ } else if (o instanceof ChainableReader) {
+ setProjectOnObject(o);
+ instream = ((ChainableReader) o).chain(instream);
+ setProjectOnObject(instream);
+ }
+ }
+ success = true;
+ } finally {
+ if (!success && classLoadersToCleanUp.size() > 0) {
+ cleanUpClassLoaders(classLoadersToCleanUp);
+ }
+ }
+ }
+ final Reader finalReader = instream;
+ return classLoadersToCleanUp.size() == 0 ? finalReader
+ : new FilterReader(finalReader) {
+ public void close() throws IOException {
+ FileUtils.close(in);
+ cleanUpClassLoaders(classLoadersToCleanUp);
+ }
+ protected void finalize() throws Throwable {
+ try {
+ close();
+ } finally {
+ super.finalize();
+ }
+ }
+ };
+ }
+
+ /**
+ * helper method to set the project on an object.
+ * the reflection setProject does not work for anonymous/protected/private
+ * classes, even if they have public methods.
+ */
+ private void setProjectOnObject(Object obj) {
+ if (project == null) {
+ return;
+ }
+ if (obj instanceof BaseFilterReader) {
+ ((BaseFilterReader) obj).setProject(project);
+ return;
+ }
+ project.setProjectReference(obj);
+ }
+
+ /**
+ * Deregisters Classloaders from the project so GC can remove them later.
+ */
+ private static void cleanUpClassLoaders(List<AntClassLoader> loaders) {
+ for (Iterator<AntClassLoader> it = loaders.iterator(); it.hasNext();) {
+ it.next().cleanup();
+ }
+ }
+
+ /**
+ * Read data from the reader and return the
+ * contents as a string.
+ * @param rdr the reader object
+ * @return the contents of the file as a string
+ * @exception IOException if an error occurs
+ */
+ public String readFully(Reader rdr)
+ throws IOException {
+ return FileUtils.readFully(rdr, bufferSize);
+ }
+
+ /**
+ * Creates and parameterizes a new FilterReader from a
+ * &lt;filterreader&gt; element.
+ *
+ * @since Ant 1.8.0
+ */
+ private Reader expandReader(final AntFilterReader filter,
+ final Reader ancestor,
+ final List<AntClassLoader> classLoadersToCleanUp) {
+ final String className = filter.getClassName();
+ final Path classpath = filter.getClasspath();
+ final Project pro = filter.getProject();
+ if (className != null) {
+ try {
+ Class<?> clazz = null;
+ if (classpath == null) {
+ clazz = Class.forName(className);
+ } else {
+ AntClassLoader al = pro.createClassLoader(classpath);
+ classLoadersToCleanUp.add(al);
+ clazz = Class.forName(className, true, al);
+ }
+ if (clazz != null) {
+ if (!FilterReader.class.isAssignableFrom(clazz)) {
+ throw new BuildException(className + " does not extend"
+ + " java.io.FilterReader");
+ }
+ final Constructor<?>[] constructors = clazz.getConstructors();
+ int j = 0;
+ boolean consPresent = false;
+ for (; j < constructors.length; j++) {
+ Class<?>[] types = constructors[j].getParameterTypes();
+ if (types.length == 1
+ && types[0].isAssignableFrom(Reader.class)) {
+ consPresent = true;
+ break;
+ }
+ }
+ if (!consPresent) {
+ throw new BuildException(className + " does not define"
+ + " a public constructor"
+ + " that takes in a Reader"
+ + " as its single argument.");
+ }
+ final Reader[] rdr = {ancestor};
+ Reader instream =
+ (Reader) constructors[j].newInstance((Object[]) rdr);
+ setProjectOnObject(instream);
+ if (Parameterizable.class.isAssignableFrom(clazz)) {
+ final Parameter[] params = filter.getParams();
+ ((Parameterizable) instream).setParameters(params);
+ }
+ return instream;
+ }
+ } catch (final ClassNotFoundException cnfe) {
+ throw new BuildException(cnfe);
+ } catch (final InstantiationException ie) {
+ throw new BuildException(ie);
+ } catch (final IllegalAccessException iae) {
+ throw new BuildException(iae);
+ } catch (final InvocationTargetException ite) {
+ throw new BuildException(ite);
+ }
+ }
+ // Ant 1.7.1 and earlier ignore <filterreader> without a
+ // classname attribute, not sure this is a good idea -
+ // backwards compatibility makes it hard to change, though.
+ return ancestor;
+ }
+}