001: /*
002: $Id: RootLoaderRef.java 3836 2006-06-15 13:31:42Z blackdrag $
003:
004: Copyright 2003 (C) Jochen Theodorou. All Rights Reserved.
005:
006: Redistribution and use of this software and associated documentation
007: ("Software"), with or without modification, are permitted provided
008: that the following conditions are met:
009:
010: 1. Redistributions of source code must retain copyright
011: statements and notices. Redistributions must also contain a
012: copy of this document.
013:
014: 2. Redistributions in binary form must reproduce the
015: above copyright notice, this list of conditions and the
016: following disclaimer in the documentation and/or other
017: materials provided with the distribution.
018:
019: 3. The name "groovy" must not be used to endorse or promote
020: products derived from this Software without prior written
021: permission of The Codehaus. For written permission,
022: please contact info@codehaus.org.
023:
024: 4. Products derived from this Software may not be called "groovy"
025: nor may "groovy" appear in their names without prior written
026: permission of The Codehaus. "groovy" is a registered
027: trademark of The Codehaus.
028:
029: 5. Due credit should be given to The Codehaus -
030: http://groovy.codehaus.org/
031:
032: THIS SOFTWARE IS PROVIDED BY THE CODEHAUS AND CONTRIBUTORS
033: ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
034: NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
035: FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
036: THE CODEHAUS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
037: INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
038: (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
039: SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
040: HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
041: STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
042: ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
043: OF THE POSSIBILITY OF SUCH DAMAGE.
044:
045: */
046:
047: package org.codehaus.groovy.ant;
048:
049: import org.apache.tools.ant.AntClassLoader;
050: import org.apache.tools.ant.BuildException;
051: import org.apache.tools.ant.Project;
052: import org.apache.tools.ant.taskdefs.MatchingTask;
053: import org.apache.tools.ant.types.Path;
054: import org.apache.tools.ant.types.Reference;
055: import org.codehaus.groovy.tools.LoaderConfiguration;
056: import org.codehaus.groovy.tools.RootLoader;
057:
058: /**
059: * Sets the RootLoader as reference.
060: * Reexecution of this task will set a new instance of RootLoader for
061: * the reference.
062: *
063: * arguments:
064: * <ul>
065: * <li>ref</li>
066: * <li>classpath</li>
067: * </ul>
068: *
069: * all arguments are requiered.
070: *
071: * As ant requieres an AntClassLoader as reference, this will create a RootLoader
072: * and set an AntClassLoader as child and stored in the reference. The AntClassLoader
073: * instance will not have a classpath nor will it have access to the classpath somehow,
074: * all loading is done by the RootLoader parent. To avoid problems with loading classes
075: * multiple times and using them at the same time, this task will filter out the ant jars
076: * and the commons-logging jars. This only works if the ant jars are starting with "ant-" and
077: * the logging jar starts with "commons-logging-".
078: *
079: * This was needed because if ant wants to access a task argument that uses for example a Path
080: * it look for a matching method which includes a matching class. But two classes of the same name
081: * with different classloaders are different, so ant would not be able to find the method.
082: *
083: * @see org.codehaus.groovy.tools.RootLoader
084: * @author Jochen Theodorou
085: * @version $Revision: 3836 $
086: */
087: public class RootLoaderRef extends MatchingTask {
088: private String name;
089: private Path taskClasspath;
090:
091: /**
092: * sets the name of the reference which should store the Loader
093: */
094: public void setRef(String n) {
095: name = n;
096: }
097:
098: public void execute() throws BuildException {
099: if (taskClasspath == null || taskClasspath.size() == 0) {
100: throw new BuildException("no classpath given");
101: }
102: Project project = getProject();
103: AntClassLoader loader = new AntClassLoader(makeRoot(), true);
104: project.addReference(name, loader);
105: }
106:
107: private RootLoader makeRoot() {
108: String[] list = taskClasspath.list();
109: LoaderConfiguration lc = new LoaderConfiguration();
110: for (int i = 0; i < list.length; i++) {
111: if (list[i].matches(".*ant-[^/]*jar$")) {
112: continue;
113: }
114: if (list[i].matches(".*commons-logging-[^/]*jar$")) {
115: continue;
116: }
117: if (list[i].matches(".*xerces-[^/]*jar$")) {
118: continue;
119: }
120: lc.addFile(list[i]);
121: }
122: return new RootLoader(lc);
123: }
124:
125: /**
126: * Set the classpath to be used for this compilation.
127: *
128: * @param classpath an Ant Path object containing the compilation classpath.
129: */
130: public void setClasspath(Path classpath) {
131: if (taskClasspath == null) {
132: taskClasspath = classpath;
133: } else {
134: taskClasspath.append(classpath);
135: }
136: }
137:
138: /**
139: * Adds a reference to a classpath defined elsewhere.
140: * @param r a reference to a classpath
141: */
142: public void setClasspathRef(Reference r) {
143: createClasspath().setRefid(r);
144: }
145:
146: /**
147: * Adds a path to the classpath.
148: * @return a class path to be configured
149: */
150: public Path createClasspath() {
151: if (taskClasspath == null) {
152: taskClasspath = new Path(getProject());
153: }
154: return taskClasspath.createPath();
155: }
156: }
|