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:
019: package org.apache.tools.ant.types.selectors;
020:
021: import java.io.File;
022: import java.util.Vector;
023:
024: import org.apache.tools.ant.Project;
025: import org.apache.tools.ant.AntClassLoader;
026: import org.apache.tools.ant.BuildException;
027: import org.apache.tools.ant.types.Parameter;
028: import org.apache.tools.ant.types.Path;
029: import org.apache.tools.ant.types.Reference;
030:
031: /**
032: * Selector that selects files by forwarding the request on to other classes.
033: *
034: * @since 1.5
035: */
036: public class ExtendSelector extends BaseSelector {
037:
038: private String classname = null;
039: private FileSelector dynselector = null;
040: private Vector paramVec = new Vector();
041: private Path classpath = null;
042:
043: /**
044: * Default constructor.
045: */
046: public ExtendSelector() {
047: }
048:
049: /**
050: * Sets the classname of the custom selector.
051: *
052: * @param classname is the class which implements this selector
053: */
054: public void setClassname(String classname) {
055: this .classname = classname;
056: }
057:
058: /**
059: * Instantiates the identified custom selector class.
060: */
061: public void selectorCreate() {
062: if (classname != null && classname.length() > 0) {
063: try {
064: Class c = null;
065: if (classpath == null) {
066: c = Class.forName(classname);
067: } else {
068: AntClassLoader al = getProject().createClassLoader(
069: classpath);
070: c = Class.forName(classname, true, al);
071: }
072: dynselector = (FileSelector) c.newInstance();
073: final Project p = getProject();
074: if (p != null) {
075: p.setProjectReference(dynselector);
076: }
077: } catch (ClassNotFoundException cnfexcept) {
078: setError("Selector " + classname
079: + " not initialized, no such class");
080: } catch (InstantiationException iexcept) {
081: setError("Selector " + classname
082: + " not initialized, could not create class");
083: } catch (IllegalAccessException iaexcept) {
084: setError("Selector " + classname
085: + " not initialized, class not accessible");
086: }
087: } else {
088: setError("There is no classname specified");
089: }
090: }
091:
092: /**
093: * Create new parameters to pass to custom selector.
094: *
095: * @param p The new Parameter object
096: */
097: public void addParam(Parameter p) {
098: paramVec.addElement(p);
099: }
100:
101: /**
102: * Set the classpath to load the classname specified using an attribute.
103: * @param classpath the classpath to use
104: */
105: public final void setClasspath(Path classpath) {
106: if (isReference()) {
107: throw tooManyAttributes();
108: }
109: if (this .classpath == null) {
110: this .classpath = classpath;
111: } else {
112: this .classpath.append(classpath);
113: }
114: }
115:
116: /**
117: * Specify the classpath to use to load the Selector (nested element).
118: * @return a classpath to be configured
119: */
120: public final Path createClasspath() {
121: if (isReference()) {
122: throw noChildrenAllowed();
123: }
124: if (this .classpath == null) {
125: this .classpath = new Path(getProject());
126: }
127: return this .classpath.createPath();
128: }
129:
130: /**
131: * Get the classpath
132: * @return the classpath
133: */
134: public final Path getClasspath() {
135: return classpath;
136: }
137:
138: /**
139: * Set the classpath to use for loading a custom selector by using
140: * a reference.
141: * @param r a reference to the classpath
142: */
143: public void setClasspathref(Reference r) {
144: if (isReference()) {
145: throw tooManyAttributes();
146: }
147: createClasspath().setRefid(r);
148: }
149:
150: /**
151: * These are errors specific to ExtendSelector only. If there are
152: * errors in the custom selector, it should throw a BuildException
153: * when isSelected() is called.
154: */
155: public void verifySettings() {
156: // Creation is done here rather than in isSelected() because some
157: // containers may do a validation pass before running isSelected(),
158: // but we need to check for the existence of the created class.
159: if (dynselector == null) {
160: selectorCreate();
161: }
162: if (classname == null || classname.length() < 1) {
163: setError("The classname attribute is required");
164: } else if (dynselector == null) {
165: setError("Internal Error: The custom selector was not created");
166: } else if (!(dynselector instanceof ExtendFileSelector)
167: && (paramVec.size() > 0)) {
168: setError("Cannot set parameters on custom selector that does not "
169: + "implement ExtendFileSelector");
170: }
171: }
172:
173: /**
174: * Allows the custom selector to choose whether to select a file. This
175: * is also where the Parameters are passed to the custom selector,
176: * since we know we must have them all by now. And since we must know
177: * both classpath and classname, creating the class is deferred to here
178: * as well.
179: * @param basedir The the base directory.
180: * @param filename The name of the file to check.
181: * @param file A File object for this filename.
182: * @return whether the file should be selected or not.
183: * @exception BuildException if an error occurs.
184: */
185: public boolean isSelected(File basedir, String filename, File file)
186: throws BuildException {
187: validate();
188: if (paramVec.size() > 0
189: && dynselector instanceof ExtendFileSelector) {
190: Parameter[] paramArray = new Parameter[paramVec.size()];
191: paramVec.copyInto(paramArray);
192: // We know that dynselector must be non-null if no error message
193: ((ExtendFileSelector) dynselector)
194: .setParameters(paramArray);
195: }
196: return dynselector.isSelected(basedir, filename, file);
197: }
198:
199: }
|