KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > tools > ant > taskdefs > Classloader


1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */

18
19 package org.apache.tools.ant.taskdefs;
20
21 import org.apache.tools.ant.Project;
22 import org.apache.tools.ant.Task;
23 import org.apache.tools.ant.MagicNames;
24 import org.apache.tools.ant.BuildException;
25 import org.apache.tools.ant.AntClassLoader;
26 import org.apache.tools.ant.types.Reference;
27 import org.apache.tools.ant.types.Path;
28
29 import java.io.File JavaDoc;
30
31 /**
32  * EXPERIMENTAL
33  * Create or modifies ClassLoader. The required pathRef parameter
34  * will be used to add classpath elements.
35  *
36  * The classpath is a regular path. Currently only file components are
37  * supported (future extensions may allow URLs).
38  *
39  * You can modify the core loader by not specifying any name or using
40  * "ant.coreLoader". (the core loader is used to load system ant
41  * tasks and for taskdefs that don't specify an explicit path).
42  *
43  * Taskdef and typedef can use the loader you create if the name follows
44  * the "ant.loader.NAME" pattern. NAME will be used as a pathref when
45  * calling taskdef.
46  *
47  * This tasks will not modify the core loader if "build.sysclasspath=only"
48  *
49  * The typical use is:
50  * <pre>
51  * &lt;path id="ant.deps" &gt;
52  * &lt;fileset dir="myDir" &gt;
53  * &lt;include name="junit.jar, bsf.jar, js.jar, etc"/&gt;
54  * &lt;/fileset&gt;
55  * &lt;/path&gt;
56  *
57  * &lt;classloader pathRef="ant.deps" /&gt;
58  *
59  * </pre>
60  *
61  */

62 public class Classloader extends Task {
63     /** @see MagicNames#SYSTEM_LOADER_REF */
64     public static final String JavaDoc SYSTEM_LOADER_REF = MagicNames.SYSTEM_LOADER_REF;
65
66     private String JavaDoc name = null;
67     private Path classpath;
68     private boolean reset = false;
69     private boolean parentFirst = true;
70     private String JavaDoc parentName = null;
71
72     /**
73      * Default constructor
74      */

75     public Classloader() {
76     }
77
78     /** Name of the loader. If none, the default loader will be modified
79      *
80      * @param name the name of this loader
81      */

82     public void setName(String JavaDoc name) {
83         this.name = name;
84     }
85
86     /**
87      * Reset the classloader, if it already exists. A new loader will
88      * be created and all the references to the old one will be removed.
89      * (it is not possible to remove paths from a loader). The new
90      * path will be used.
91      *
92      * @param b true if the loader is to be reset.
93      */

94     public void setReset(boolean b) {
95         this.reset = b;
96     }
97
98     /**
99      * Set reverse attribute.
100      * @param b if true reverse the normal classloader lookup.
101      */

102     public void setReverse(boolean b) {
103         this.parentFirst = !b;
104     }
105
106     /**
107      * Set reverse attribute.
108      * @param b if true reverse the normal classloader lookup.
109      */

110     public void setParentFirst(boolean b) {
111         this.parentFirst = b;
112     }
113
114     /**
115      * Set the name of the parent.
116      * @param name the parent name.
117      */

118     public void setParentName(String JavaDoc name) {
119         this.parentName = name;
120     }
121
122
123     /** Specify which path will be used. If the loader already exists
124      * and is an AntClassLoader (or any other loader we can extend),
125      * the path will be added to the loader.
126      * @param pathRef a reference to a path.
127      * @throws BuildException if there is a problem.
128      */

129     public void setClasspathRef(Reference pathRef) throws BuildException {
130         classpath = (Path) pathRef.getReferencedObject(getProject());
131     }
132
133     /**
134      * Set the classpath to be used when searching for component being defined
135      *
136      * @param classpath an Ant Path object containing the classpath.
137      */

138     public void setClasspath(Path classpath) {
139         if (this.classpath == null) {
140             this.classpath = classpath;
141         } else {
142             this.classpath.append(classpath);
143         }
144     }
145
146     /**
147      * Create a classpath.
148      * @return a path for configuration.
149      */

150     public Path createClasspath() {
151         if (this.classpath == null) {
152             this.classpath = new Path(null);
153         }
154         return this.classpath.createPath();
155     }
156
157
158     /**
159      * do the classloader manipulation.
160      */

161     public void execute() {
162         try {
163             // Gump friendly - don't mess with the core loader if only classpath
164
if ("only".equals(getProject().getProperty("build.sysclasspath"))
165                 && (name == null || SYSTEM_LOADER_REF.equals(name))) {
166                 log("Changing the system loader is disabled "
167                     + "by build.sysclasspath=only", Project.MSG_WARN);
168                 return;
169             }
170
171             String JavaDoc loaderName = (name == null) ? SYSTEM_LOADER_REF : name;
172
173             Object JavaDoc obj = getProject().getReference(loaderName);
174             if (reset) {
175                 // Are any other references held ? Can we 'close' the loader
176
// so it removes the locks on jars ?
177
obj = null; // a new one will be created.
178
}
179
180             // XXX maybe use reflection to addPathElement (other patterns ?)
181
if (obj != null && !(obj instanceof AntClassLoader)) {
182                 log("Referenced object is not an AntClassLoader",
183                         Project.MSG_ERR);
184                 return;
185             }
186
187             AntClassLoader acl = (AntClassLoader) obj;
188
189             if (acl == null) {
190                 // Construct a new class loader
191
Object JavaDoc parent = null;
192                 if (parentName != null) {
193                     parent = getProject().getReference(parentName);
194                     if (!(parent instanceof ClassLoader JavaDoc)) {
195                         parent = null;
196                     }
197                 }
198                 // TODO: allow user to request the system or no parent
199
if (parent == null) {
200                     parent = this.getClass().getClassLoader();
201                 }
202
203                 if (name == null) {
204                     // The core loader must be reverse
205
//reverse=true;
206
}
207                 getProject().log("Setting parent loader " + name + " "
208                     + parent + " " + parentFirst, Project.MSG_DEBUG);
209
210                 // The param is "parentFirst"
211
acl = new AntClassLoader((ClassLoader JavaDoc) parent,
212                          getProject(), classpath, parentFirst);
213
214                 getProject().addReference(loaderName, acl);
215
216                 if (name == null) {
217                     // This allows the core loader to load optional tasks
218
// without delegating
219
acl.addLoaderPackageRoot("org.apache.tools.ant.taskdefs.optional");
220                     getProject().setCoreLoader(acl);
221                 }
222             }
223             if (classpath != null) {
224                 String JavaDoc[] list = classpath.list();
225                 for (int i = 0; i < list.length; i++) {
226                     File JavaDoc f = new File JavaDoc(list[i]);
227                     if (f.exists()) {
228                         acl.addPathElement(f.getAbsolutePath());
229                         log("Adding to class loader " + acl + " " + f.getAbsolutePath(),
230                                 Project.MSG_DEBUG);
231                     }
232                 }
233             }
234
235             // XXX add exceptions
236

237         } catch (Exception JavaDoc ex) {
238             ex.printStackTrace();
239         }
240     }
241 }
242
Popular Tags