📄 classpathutils.java
字号:
/* * 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.util;import org.apache.tools.ant.AntClassLoader;import org.apache.tools.ant.BuildException;import org.apache.tools.ant.Project;import org.apache.tools.ant.ProjectComponent;import org.apache.tools.ant.MagicNames;import org.apache.tools.ant.types.Path;import org.apache.tools.ant.types.Reference;// CheckStyle:HideUtilityClassConstructorCheck OFF - bc/** * Offers some helper methods on the Path structure in ant. * * <p>The basic idea behind this utility class is to use it from inside the * different Ant objects (and user defined objects) that need classLoading * for their operation. * Normally those would have a setClasspathRef() {for the @classpathref} * and/or a createClasspath() {for the nested <classpath>} * Typically one would have in your Ant Task or DataType</p> * * <pre><code> * ClasspathUtils.Delegate cpDelegate; * * public void init() { * this.cpDelegate = ClasspathUtils.getDelegate(this); * super.init(); * } * * public void setClasspathRef(Reference r) { * this.cpDelegate.setClasspathRef(r); * } * * public Path createClasspath() { * return this.cpDelegate.createClasspath(); * } * * public void setClassname(String fqcn) { * this.cpDelegate.setClassname(fqcn); * } * </code></pre> * * <p>At execution time, when you actually need the classloading * you can just:</p> * * <pre><code> * Object o = this.cpDelegate.newInstance(); * </code></pre> * * @since Ant 1.6 */public class ClasspathUtils { /** * Name of the magic property that controls classloader reuse in Ant 1.4. */ public static final String REUSE_LOADER_REF = MagicNames.REFID_CLASSPATH_REUSE_LOADER; /** * Convenience overloaded version of {@link * #getClassLoaderForPath(Project, Reference, boolean)}. * * <p>Assumes the logical 'false' for the reverseLoader.</p> * * @param p the project * @param ref the reference * @return The class loader */ public static ClassLoader getClassLoaderForPath( Project p, Reference ref) { return getClassLoaderForPath(p, ref, false); } /** * Convenience overloaded version of {@link #getClassLoaderForPath(Project, Path, * String, boolean)}. * * <p>Delegates to the other one after extracting the referenced * Path from the Project. This checks also that the passed * Reference is pointing to a Path all right.</p> * @param p current Ant project * @param ref Reference to Path structure * @param reverseLoader if set to true this new loader will take * precedence over its parent (which is contra the regular * classloader behaviour) * @return The class loader */ public static ClassLoader getClassLoaderForPath( Project p, Reference ref, boolean reverseLoader) { String pathId = ref.getRefId(); Object path = p.getReference(pathId); if (!(path instanceof Path)) { throw new BuildException( "The specified classpathref " + pathId + " does not reference a Path."); } String loaderId = MagicNames.REFID_CLASSPATH_LOADER_PREFIX + pathId; return getClassLoaderForPath(p, (Path) path, loaderId, reverseLoader); } /** * Convenience overloaded version of {@link * #getClassLoaderForPath(Project, Path, String, boolean)}. * * <p>Assumes the logical 'false' for the reverseLoader.</p> * * @param p current Ant project * @param path the path * @param loaderId the loader id string * @return The class loader */ public static ClassLoader getClassLoaderForPath( Project p, Path path, String loaderId) { return getClassLoaderForPath(p, path, loaderId, false); } /** * Convenience overloaded version of {@link * #getClassLoaderForPath(Project, Path, String, boolean, boolean)}. * * <p>Sets value for 'reuseLoader' to true if the magic property * has been set.</p> * * @param p the project * @param path the path * @param loaderId the loader id string * @param reverseLoader if set to true this new loader will take * precedence over its parent (which is contra the regular * classloader behaviour) * @return The class loader */ public static ClassLoader getClassLoaderForPath( Project p, Path path, String loaderId, boolean reverseLoader) { return getClassLoaderForPath(p, path, loaderId, reverseLoader, isMagicPropertySet(p)); } /** * Gets a classloader that loads classes from the classpath * defined in the path argument. * * <p>Based on the setting of the magic property * 'ant.reuse.loader' this will try to reuse the previously * created loader with that id, and of course store it there upon * creation.</p> * @param p Ant Project where the handled components are living in. * @param path Path object to be used as classpath for this classloader * @param loaderId identification for this Loader, * @param reverseLoader if set to true this new loader will take * precedence over its parent (which is contra the regular * classloader behaviour) * @param reuseLoader if true reuse the loader if it is found * @return ClassLoader that uses the Path as its classpath. */ public static ClassLoader getClassLoaderForPath( Project p, Path path, String loaderId, boolean reverseLoader, boolean reuseLoader) { ClassLoader cl = null; // magic property if (loaderId != null && reuseLoader) { Object reusedLoader = p.getReference(loaderId); if (reusedLoader != null && !(reusedLoader instanceof ClassLoader)) { throw new BuildException("The specified loader id " + loaderId + " does not reference a class loader"); } cl = (ClassLoader) reusedLoader; } if (cl == null) { cl = getUniqueClassLoaderForPath(p, path, reverseLoader); if (loaderId != null && reuseLoader) { p.addReference(loaderId, cl); } } return cl; } /** * Gets a fresh, different, previously unused classloader that uses the * passed path as its classpath. * * <p>This method completely ignores the ant.reuse.loader magic * property and should be used with caution.</p> * @param p Ant Project where the handled components are living in. * @param path the classpath for this loader * @param reverseLoader if set to true this new loader will take * precedence over its parent (which is contra the regular * classloader behaviour) * @return The fresh, different, previously unused class loader. */ public static ClassLoader getUniqueClassLoaderForPath( Project p, Path path, boolean reverseLoader) { AntClassLoader acl = p.createClassLoader(path); if (reverseLoader) { acl.setParentFirst(false); acl.addJavaLibraries(); } return acl; } /** * Creates a fresh object instance of the specified classname. * * <p> This uses the userDefinedLoader to load the specified class, * and then makes an instance using the default no-argument constructor. * </p> * * @param className the full qualified class name to load. * @param userDefinedLoader the classloader to use. * @return The fresh object instance * @throws BuildException when loading or instantiation failed. */ public static Object newInstance( String className, ClassLoader userDefinedLoader) { return newInstance(className, userDefinedLoader, Object.class); } /** * Creates a fresh object instance of the specified classname. * * <p> This uses the userDefinedLoader to load the specified class, * and then makes an instance using the default no-argument constructor. * </p>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -