Index: ant/manifest.mf =================================================================== RCS file: /cvs/ant/manifest.mf,v retrieving revision 1.62 retrieving revision 1.62.6.1 diff -u -r1.62 -r1.62.6.1 --- ant/manifest.mf 14 Nov 2003 12:18:26 -0000 1.62 +++ ant/manifest.mf 24 Dec 2003 00:37:46 -0000 1.62.6.1 @@ -1,7 +1,7 @@ Manifest-Version: 1.0 OpenIDE-Module: org.apache.tools.ant.module/3 OpenIDE-Module-Localizing-Bundle: org/apache/tools/ant/module/Bundle.properties -OpenIDE-Module-Specification-Version: 3.4 +OpenIDE-Module-Specification-Version: 3.6 OpenIDE-Module-Implementation-Version: @BUILD_NUMBER_SUBST@ OpenIDE-Module-Public-Packages: org.apache.tools.ant.module.api.*, org.apache.tools.ant.module.spi.* OpenIDE-Module-Install: org/apache/tools/ant/module/AntModule.class Index: ant/api/doc/changes/apichanges.xml =================================================================== RCS file: /cvs/ant/api/doc/changes/apichanges.xml,v retrieving revision 1.6 retrieving revision 1.6.10.1 diff -u -r1.6 -r1.6.10.1 --- ant/api/doc/changes/apichanges.xml 9 Nov 2003 16:02:08 -0000 1.6 +++ ant/api/doc/changes/apichanges.xml 24 Dec 2003 00:37:45 -0000 1.6.10.1 @@ -77,6 +77,27 @@ + + + + Format of ant/nblib/*.jar changed to use antlib.xml + + + + + Existing modules installing taskdef JARs in this directory must change their format. + The previous format was however introduced after NetBeans 3.5 in the trunk. + + + ant/nblib/*.jar taskdef (or typedef) JARs must now + be named according to the code name base of the module, and must + define their tasks (or types etc.) using the standard + antlib.xml syntax rather than + META-INF/taskdefs.properties and/or + META-INF/typedefs.properties. + + + Index: ant/api/doc/org/apache/tools/ant/module/api/package.html =================================================================== RCS file: /cvs/ant/api/doc/org/apache/tools/ant/module/api/package.html,v retrieving revision 1.2 retrieving revision 1.2.42.2 diff -u -r1.2 -r1.2.42.2 --- ant/api/doc/org/apache/tools/ant/module/api/package.html 7 Jul 2003 16:22:54 -0000 1.2 +++ ant/api/doc/org/apache/tools/ant/module/api/package.html 24 Dec 2003 18:09:06 -0000 1.2.42.2 @@ -41,15 +41,34 @@ reloading a NetBeans test module, attaching the NetBeans debugger to a running application, etc. You could consider these things IDE scripting using Ant.

-

Registration is simple. Create a JAR file containing the task class(es). -To define tasks, create an entry META-INF/taskdefs.properties -listing the tasks in the usual format: the key is the task name as it appears in -the script, and the value is the class name. META-INF/typedefs.properties -may similarly be used to register custom data types.

+

Registration is simple. +(Assume for sake of illustration that the code name base of the host module is +org.netbeans.modules.foo; in the following text, replace this package +sequence with the actual code name base of your module, using whatever separator +character is indicated.) +Create a JAR file containing the task class(es), named +org-netbeans-modules-foo.jar. +Create an entry in that JAR org/netbeans/modules/foo/antlib.xml +listing tasks (or types, macrodefs, etc.) you wish to define, in the +standard Antlib format. +For example:

+ +
+<?xml version="1.0" encoding="UTF-8"?>
+<antlib>
+    <taskdef name="mytask1" classname="org.netbeans.modules.foo.MyTask1"/>
+    <taskdef name="mytask2" classname="org.netbeans.modules.foo.MyTask2"/>
+</antlib>
+
+ +

(Note that when using Ant 1.5, only <taskdef> +and <typedef> elements are supported, and only +using the name and classname +attributes.)

Place the JAR file in the ant/nblib/ directory of the NetBeans distribution, i.e. bundle it in your NBM as -netbeans/ant/nblib/something.jar. NetBeans will +netbeans/ant/nblib/org-netbeans-modules-foo.jar. NetBeans will automatically load your task/type definitions and make them available to build scripts.

@@ -58,17 +77,45 @@
    -
  1. the JRE and JDK libraries
  2. +
  3. The JRE and JDK libraries.
  4. -
  5. any module or module extension enabled in the NetBeans VM, including all of -the Open APIs and all packages of your module
  6. +
  7. The installed copy of Ant, including any user-configured Ant classpath.
  8. -
  9. the installed copy of Ant, including any user-configured Ant classpath
  10. +
  11. Your module, including any extension JARs and anything your module +can directly refer to, such as other modules it depends on.

Do not include copies of your task or type definitions in the module JAR. They must reside only in ant/nblib/*.jar.

+ +

Now whenever your module is enabled, Ant projects run inside +NetBeans will have access to the definitions you provided. When running +Ant 1.5, the definitions will be +available with no namespace qualification, e.g.:

+ +
+<project default="all">
+    <target name="all">
+        <mytask1 arg="val"/>
+    </target>
+</project>
+
+ +

When running Ant 1.6, the definitions will still be available with no namespace +qualification. However it is recommended in 1.6 to namespace-qualify everything; so +the antlib is loaded in the namespace you would expect, ensuring that +there is no possibility of name clashes with unrelated tasks:

+ +
+<project default="all"
+         xmlns="antlib:org.apache.tools.ant"
+         xmlns:foo="antlib:org.netbeans.modules.foo">
+    <target name="all">
+        <foo:mytask1 arg="val"/>
+    </target>
+</project>
+

Complete working example of task registration: ant/browsetask Index: ant/browsetask/build.xml =================================================================== RCS file: /cvs/ant/browsetask/build.xml,v retrieving revision 1.4 retrieving revision 1.4.14.1 diff -u -r1.4 -r1.4.14.1 --- ant/browsetask/build.xml 1 Nov 2003 16:25:23 -0000 1.4 +++ ant/browsetask/build.xml 24 Dec 2003 00:37:44 -0000 1.4.14.1 @@ -41,15 +41,15 @@ - + - + - + Index: ant/browsetask/manifest.mf =================================================================== RCS file: /cvs/ant/browsetask/manifest.mf,v retrieving revision 1.3 retrieving revision 1.3.14.2 diff -u -r1.3 -r1.3.14.2 --- ant/browsetask/manifest.mf 1 Nov 2003 16:25:23 -0000 1.3 +++ ant/browsetask/manifest.mf 24 Dec 2003 00:40:29 -0000 1.3.14.2 @@ -1,8 +1,8 @@ Manifest-Version: 1.0 OpenIDE-Module: org.netbeans.modules.ant.browsetask -OpenIDE-Module-Specification-Version: 1.4 +OpenIDE-Module-Specification-Version: 1.5 OpenIDE-Module-Implementation-Version: @BUILD_NUMBER_SUBST@ -OpenIDE-Module-Module-Dependencies: org.apache.tools.ant.module/3 > 3.1 +OpenIDE-Module-Module-Dependencies: org.apache.tools.ant.module/3 > 3.6 OpenIDE-Module-IDE-Dependencies: IDE/1 > 3.31 OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/ant/browsetask/Bundle.properties Index: ant/browsetask/src/META-INF/taskdefs.properties =================================================================== RCS file: ant/browsetask/src/META-INF/taskdefs.properties diff -N ant/browsetask/src/META-INF/taskdefs.properties --- ant/browsetask/src/META-INF/taskdefs.properties 7 Jul 2003 16:22:56 -0000 1.2 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1 +0,0 @@ -nbbrowse=org.netbeans.modules.ant.browsetask.NbBrowse Index: ant/browsetask/src/org/netbeans/modules/ant/browsetask/antlib.xml =================================================================== RCS file: ant/browsetask/src/org/netbeans/modules/ant/browsetask/antlib.xml diff -N ant/browsetask/src/org/netbeans/modules/ant/browsetask/antlib.xml --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ ant/browsetask/src/org/netbeans/modules/ant/browsetask/antlib.xml 26 Dec 2003 18:05:34 -0000 1.1.2.2 @@ -0,0 +1,4 @@ + + + + Index: ant/src/org/apache/tools/ant/module/api/IntrospectedInfo.java =================================================================== RCS file: /cvs/ant/src/org/apache/tools/ant/module/api/IntrospectedInfo.java,v retrieving revision 1.18 retrieving revision 1.18.10.1 diff -u -r1.18 -r1.18.10.1 --- ant/src/org/apache/tools/ant/module/api/IntrospectedInfo.java 9 Nov 2003 16:02:08 -0000 1.18 +++ ant/src/org/apache/tools/ant/module/api/IntrospectedInfo.java 24 Dec 2003 18:09:05 -0000 1.18.10.1 @@ -30,12 +30,27 @@ import org.apache.tools.ant.module.bridge.*; import org.openide.util.Utilities; +// XXX in order to support Ant 1.6 interface addition types, need to keep +// track of which classes implement a given interface + /** Represents Ant-style introspection info for a set of classes. * There should be one instance which is loaded automatically * from defaults.properties files, i.e. standard tasks/datatypes. * A second is loaded from settings and represents custom tasks/datatypes. * Uses Ant's IntrospectionHelper for the actual work, but manages the results * and makes them safely serializable (stores only classnames, etc.). + *

+ * All task and type names may be namespace-qualified for use + * in Ant 1.6: a name of the form nsuri:localname refers to + * an XML element with namespace nsuri and local name localname. + * Attribute names could also be similarly qualified, but in practice attributes + * used in Ant never have a defined namespace. The prefix antlib:org.apache.tools.ant: + * is implied, not expressed, on Ant core element names (for backwards compatibility). + * Subelement names are *not* namespace-qualified here, even though in the script + * they would be - because the namespace used in the script will actually vary + * according to how an antlib is imported and used. An unqualified subelement name + * should be understood to inherit a namespace from its parent element. + * (Namespace support since org.apache.tools.ant.module/3 3.6) */ public final class IntrospectedInfo implements Serializable { @@ -340,7 +355,14 @@ } private void loadNetBeansSpecificDefinitions() { - Map defsByKind = AntBridge.getCustomDefs(); + loadNetBeansSpecificDefinitions0(AntBridge.getCustomDefsNoNamespace()); + if (AntBridge.getInterface().isAnt16()) { + // Define both. + loadNetBeansSpecificDefinitions0(AntBridge.getCustomDefsWithNamespace()); + } + } + + private void loadNetBeansSpecificDefinitions0(Map defsByKind) { Iterator kindIt = defsByKind.entrySet().iterator(); while (kindIt.hasNext()) { Map.Entry kindE = (Map.Entry)kindIt.next(); Index: ant/src/org/apache/tools/ant/module/bridge/AntBridge.java =================================================================== RCS file: /cvs/ant/src/org/apache/tools/ant/module/bridge/AntBridge.java,v retrieving revision 1.7 retrieving revision 1.7.6.3 diff -u -r1.7 -r1.7.6.3 --- ant/src/org/apache/tools/ant/module/bridge/AntBridge.java 24 Nov 2003 18:18:36 -0000 1.7 +++ ant/src/org/apache/tools/ant/module/bridge/AntBridge.java 26 Dec 2003 18:07:16 -0000 1.7.6.3 @@ -30,7 +30,15 @@ import org.openide.filesystems.FileObject; import org.openide.filesystems.FileStateInvalidException; import org.openide.modules.InstalledFileLocator; +import org.openide.modules.ModuleInfo; import org.openide.util.*; +import org.openide.xml.XMLUtil; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; /** * Utility class providing entry points to the bridging functionality. @@ -41,33 +49,62 @@ private AntBridge() {} private static final String KEY_MAIN_CLASS_LOADER = "mainClassLoader"; // NOI18N - private static final String KEY_AUX_CLASS_LOADER = "auxClassLoader"; // NOI18N + private static final String KEY_BRIDGE_CLASS_LOADER = "bridgeClassLoader"; // NOI18N private static final String KEY_BRIDGE = "bridge"; // NOI18N - private static final String KEY_CUSTOM_DEFS = "customDefs"; + private static final String KEY_CUSTOM_DEFS = "customDefs"; // NOI18N + private static final String KEY_CUSTOM_DEF_CLASS_LOADERS = "customDefClassLoaders"; // NOI18N private static Reference stuff = null; // Reference private static List listeners = new ArrayList(); // List private static final class MiscListener implements PropertyChangeListener, LookupListener { + MiscListener() {} + private ModuleInfo[] modules = null; public void propertyChange(PropertyChangeEvent ev) { String prop = ev.getPropertyName(); - if (prop == null || - AntSettings.PROP_ANT_HOME.equals(prop) || + if (AntSettings.PROP_ANT_HOME.equals(prop) || AntSettings.PROP_EXTRA_CLASSPATH.equals(prop)) { AntModule.err.log("AntBridge got settings change in " + prop); fireChange(); + } else if (ModuleInfo.PROP_ENABLED.equals(prop)) { + AntModule.err.log("AntBridge got module enablement change on " + ev.getSource()); + fireChange(); } } public void resultChanged(LookupEvent ev) { - AntModule.err.log("AntModule got ClassLoader change"); + AntModule.err.log("AntModule got ModuleInfo change"); + synchronized (this) { + if (modules != null) { + for (int i = 0; i < modules.length; i++) { + modules[i].removePropertyChangeListener(this); + } + modules = null; + } + } fireChange(); } + public synchronized ModuleInfo[] getEnabledModules() { + if (modules == null) { + Collection c = modulesResult.allInstances(); + modules = (ModuleInfo[])c.toArray(new ModuleInfo[c.size()]); + for (int i = 0; i < modules.length; i++) { + modules[i].addPropertyChangeListener(this); + } + } + List/**/ enabledModules = new ArrayList(modules.length); + for (int i = 0; i < modules.length; i++) { + if (modules[i].isEnabled()) { + enabledModules.add(modules[i]); + } + } + return (ModuleInfo[])enabledModules.toArray(new ModuleInfo[enabledModules.size()]); + } } private static MiscListener miscListener = new MiscListener(); - private static Lookup.Result classpathResult = Lookup.getDefault().lookup(new Lookup.Template(ClassLoader.class)); + private static Lookup.Result modulesResult = Lookup.getDefault().lookup(new Lookup.Template(ModuleInfo.class)); static { AntSettings.getDefault().addPropertyChangeListener(miscListener); - classpathResult.addLookupListener(miscListener); + modulesResult.addLookupListener(miscListener); } /** @@ -106,22 +143,64 @@ } /** - * Get the loader which contains the bridge code as well as any - * custom-defined tasks. + * Get the loader which contains the bridge code. */ - private static ClassLoader getAuxClassLoader() { - return (ClassLoader)getStuff().get(KEY_AUX_CLASS_LOADER); + private static ClassLoader getBridgeClassLoader() { + return (ClassLoader)getStuff().get(KEY_BRIDGE_CLASS_LOADER); } /** * Get any custom task/type definitions stored in $nbhome/ant/nblib/*.jar. * Some of the classes might not be fully resolvable, so beware. + * The names will include namespace prefixes. + *

+ * Only minimal antlib syntax is currently interpreted here: + * only <taskdef> and <typedef>, + * and only the name and classname attributes. */ - public static Map/*>*/ getCustomDefs() { + public static Map/*>*/ getCustomDefsWithNamespace() { return (Map)getStuff().get(KEY_CUSTOM_DEFS); } /** + * Same as {@link #getCustomDefsWithNamespace} but without any namespace prefixes. + */ + public static Map/*>*/ getCustomDefsNoNamespace() { + Map/*>*/ m = new HashMap(); + Iterator it = getCustomDefsWithNamespace().entrySet().iterator(); + while (it.hasNext()) { + Map.Entry entry = (Map.Entry)it.next(); + String type = (String)entry.getKey(); + Map defs = (Map)entry.getValue(); + Map/*Map*/ m2 = new HashMap(); + Iterator it2 = defs.entrySet().iterator(); + while (it2.hasNext()) { + Map.Entry entry2 = (Map.Entry)it2.next(); + String fqn = (String)entry2.getKey(); + Class clazz = (Class)entry2.getValue(); + String name; + int idx = fqn.lastIndexOf(':'); + if (idx != -1) { + name = fqn.substring(idx + 1); + } else { + name = fqn; + } + m2.put(name, clazz); + } + m.put(type, m2); + } + return m; + } + + /** + * Get a map from enabled module code name bases to class loaders containing + * JARs from ant/nblib/*.jar. + */ + public static Map/**/ getCustomDefClassLoaders() throws IOException { + return (Map)getStuff().get(KEY_CUSTOM_DEF_CLASS_LOADERS); + } + + /** * Return a class loader which can load from Ant JARs as well the user * development class path. It is not cached, since user classes can * change quickly. Similar to NbClassLoader. @@ -177,12 +256,13 @@ // Ensures that the loader is functional, and that it is at least 1.5.x // so that our classes can link against it successfully: main.loadClass("org.apache.tools.ant.input.InputHandler"); // NOI18N - File[] nblibs = getNblibs(); - ClassLoader aux = createAuxClassLoader(nblibs, main); - m.put(KEY_AUX_CLASS_LOADER, aux); - Class impl = aux.loadClass("org.apache.tools.ant.module.bridge.impl.BridgeImpl"); // NOI18N + ClassLoader bridgeLoader = createBridgeClassLoader(main); + m.put(KEY_BRIDGE_CLASS_LOADER, bridgeLoader); + Class impl = bridgeLoader.loadClass("org.apache.tools.ant.module.bridge.impl.BridgeImpl"); // NOI18N m.put(KEY_BRIDGE, (BridgeInterface)impl.newInstance()); - m.put(KEY_CUSTOM_DEFS, createCustomDefs(nblibs, aux)); + Map cDCLs = createCustomDefClassLoaders(main); + m.put(KEY_CUSTOM_DEF_CLASS_LOADERS, cDCLs); + m.put(KEY_CUSTOM_DEFS, createCustomDefs(cDCLs)); } catch (Exception e) { fallback(m, e); } catch (LinkageError e) { @@ -195,12 +275,13 @@ m.clear(); ClassLoader dummy = ClassLoader.getSystemClassLoader(); m.put(KEY_MAIN_CLASS_LOADER, dummy); - m.put(KEY_AUX_CLASS_LOADER, dummy); + m.put(KEY_BRIDGE_CLASS_LOADER, dummy); m.put(KEY_BRIDGE, new DummyBridgeImpl(e)); Map defs = new HashMap(); defs.put("task", new HashMap()); // NOI18N defs.put("type", new HashMap()); // NOI18N m.put(KEY_CUSTOM_DEFS, defs); + m.put(KEY_CUSTOM_DEF_CLASS_LOADERS, Collections.EMPTY_MAP); } private static final class JarFilter implements FilenameFilter { @@ -239,62 +320,107 @@ return new AllPermissionURLClassLoader((URL[])cp.toArray(new URL[cp.size()]), ClassLoader.getSystemClassLoader()); } - private static File[] getNblibs() throws IOException { - // XXX this will not work for modules installed in the user dir... - // pending stronger semantics from IFL re. directories - // (cf. #36701) - // -> when this is fixed, remove ant/nblib check from org.netbeans.modules.autoupdate.ModuleUpdate - File nblibdir = InstalledFileLocator.getDefault().locate("ant/nblib", "org.apache.tools.ant.module", false); // NOI18N - File bridgeJar = new File(nblibdir, "bridge.jar"); - if (!bridgeJar.isFile()) throw new IOException("No such Ant bridge JAR: " + bridgeJar); // NOI18N - File[] libs = nblibdir.listFiles(new JarFilter()); - if (libs == null) throw new IOException("Listing: " + nblibdir); // NOI18N - return libs; + private static ClassLoader createBridgeClassLoader(ClassLoader main) throws Exception { + File bridgeJar = InstalledFileLocator.getDefault().locate("ant/nblib/bridge.jar", "org.apache.tools.ant.module", false); // NOI18N + if (bridgeJar == null) { + throw new IllegalStateException("no ant/nblib/bridge.jar found"); // NOI18N + } + return createAuxClassLoader(bridgeJar, main, AntBridge.class.getClassLoader()); } - private static ClassLoader createAuxClassLoader(File[] libs, ClassLoader main) throws Exception { - List cp = new ArrayList(); // List - for (int i = 0; i < libs.length; i++) { - cp.add(libs[i].toURI().toURL()); + private static ClassLoader createAuxClassLoader(File lib, ClassLoader main, ClassLoader moduleLoader) throws IOException { + return new AuxClassLoader(moduleLoader, main, lib.toURI().toURL()); + } + + /** + * Get a map from enabled module code name bases to class loaders containing + * JARs from ant/nblib/*.jar. + */ + private static Map/**/ createCustomDefClassLoaders(ClassLoader main) throws IOException { + Map/**/ m = new HashMap(); + ModuleInfo[] modules = miscListener.getEnabledModules(); + InstalledFileLocator ifl = InstalledFileLocator.getDefault(); + for (int i = 0; i < modules.length; i++) { + String cnb = modules[i].getCodeNameBase(); + String cnbDashes = cnb.replace('.', '-'); + File lib = ifl.locate("ant/nblib/" + cnbDashes + ".jar", cnb, false); // NOI18N + if (lib == null) { + continue; + } + ClassLoader l = createAuxClassLoader(lib, main, modules[i].getClassLoader()); + m.put(cnb, l); } - ClassLoader nbLoader = (ClassLoader)Lookup.getDefault().lookup(ClassLoader.class); - return new AuxClassLoader(nbLoader, main, (URL[])cp.toArray(new URL[cp.size()])); + return m; } - private static Map/*>*/ createCustomDefs(File[] libs, ClassLoader aux) throws IOException { + private static Map/*>*/ createCustomDefs(Map cDCLs) throws IOException { Map m = new HashMap(); Map tasks = new HashMap(); Map types = new HashMap(); + // XXX #36776: should eventually support s here m.put("task", tasks); // NOI18N m.put("type", types); // NOI18N - for (int i = 0; i < libs.length; i++) { - JarFile j = new JarFile(libs[i]); + Iterator it = cDCLs.entrySet().iterator(); + while (it.hasNext()) { + Map.Entry entry = (Map.Entry)it.next(); + String cnb = (String)entry.getKey(); + ClassLoader l = (ClassLoader)entry.getValue(); + String resource = cnb.replace('.', '/') + "/antlib.xml"; // NOI18N + URL antlib = l.getResource(resource); + if (antlib == null) { + throw new IOException("Could not find " + antlib + " in ant/nblib/" + cnb.replace('.', '-') + ".jar"); // NOI18N + } + Document doc; try { - JarEntry e = j.getJarEntry("META-INF/taskdefs.properties"); // NOI18N - if (e != null) { - AntModule.err.log("Loading custom taskdefs from " + libs[i]); - loadDefs(j.getInputStream(e), tasks, aux); + doc = XMLUtil.parse(new InputSource(antlib.toExternalForm()), false, true, /*XXX needed?*/null, null); + } catch (SAXException e) { + throw (IOException)new IOException(e.toString()).initCause(e); + } + Element docEl = doc.getDocumentElement(); + if (!docEl.getLocalName().equals("antlib")) { // NOI18N + throw new IOException("Bad root element for " + antlib + ": " + docEl); // NOI18N + } + NodeList nl = docEl.getChildNodes(); + Properties newTaskDefs = new Properties(); + Properties newTypeDefs = new Properties(); + for (int i = 0; i < nl.getLength(); i++) { + Node n = nl.item(i); + if (n.getNodeType() != Node.ELEMENT_NODE) { + continue; } - e = j.getJarEntry("META-INF/typedefs.properties"); // NOI18N - if (e != null) { - AntModule.err.log("Loading custom typedefs from " + libs[i]); - loadDefs(j.getInputStream(e), tasks, aux); + Element def = (Element)n; + boolean type; + if (def.getNodeName().equals("taskdef")) { // NOI18N + type = false; + } else if (def.getNodeName().equals("typedef")) { // NOI18N + type = true; + } else { + AntModule.err.log(ErrorManager.WARNING, "Warning: unrecognized definition " + def + " in " + antlib); + continue; } - } finally { - j.close(); + String name = def.getAttribute("name"); // NOI18N + if (name == null) { + // Not a hard error since there might be e.g. here + // which we do not parse but which is permitted in antlib by Ant. + AntModule.err.log(ErrorManager.WARNING, "Warning: skipping definition " + def + " with no 'name' in " + antlib); + continue; + } + String classname = def.getAttribute("classname"); // NOI18N + if (classname == null) { + // But this is a hard error. + throw new IOException("No 'classname' attr on def of " + name + " in " + antlib); // NOI18N + } + // XXX would be good to handle at least onerror attr too + (type ? newTypeDefs : newTaskDefs).setProperty(name, classname); } + loadDefs(newTaskDefs, tasks, l); + loadDefs(newTypeDefs, types, l); } return m; } - private static void loadDefs(InputStream is, Map defs, ClassLoader l) throws IOException { - // Similar to IntrospectedInfo.load, but just picks up the classes. - Properties p = new Properties(); - try { - p.load(is); - } finally { - is.close(); - } + private static void loadDefs(Properties p, Map defs, ClassLoader l) throws IOException { + // Similar to IntrospectedInfo.load, after having parsed the properties. Iterator it = p.entrySet().iterator(); while (it.hasNext()) { Map.Entry entry = (Map.Entry)it.next(); Index: ant/src/org/apache/tools/ant/module/bridge/AuxClassLoader.java =================================================================== RCS file: /cvs/ant/src/org/apache/tools/ant/module/bridge/AuxClassLoader.java,v retrieving revision 1.3 retrieving revision 1.3.6.1 diff -u -r1.3 -r1.3.6.1 --- ant/src/org/apache/tools/ant/module/bridge/AuxClassLoader.java 14 Nov 2003 12:18:25 -0000 1.3 +++ ant/src/org/apache/tools/ant/module/bridge/AuxClassLoader.java 24 Dec 2003 18:09:03 -0000 1.3.6.1 @@ -14,7 +14,7 @@ package org.apache.tools.ant.module.bridge; import java.io.IOException; -import java.net.*; +import java.net.URL; import java.util.Enumeration; import org.openide.util.enum.*; @@ -22,8 +22,8 @@ * Loads classes in the following order: * 1. JRE * 2. Ant JARs - whatever is in the "main" class loader. - * 3. NetBeans JARs - modules etc. - * 4. Contents of $nbhome/ant/nblib/*.jar, incl. bridge.jar and special tasks. + * 3. Some NetBeans module class loader. + * 4. Some other JAR from $nbhome/ant/nblib/*.jar. * Lightly inspired by ProxyClassLoader, but much less complex. * @author Jesse Glick */ @@ -31,8 +31,8 @@ private final ClassLoader nbLoader; - public AuxClassLoader(ClassLoader nbLoader, ClassLoader antLoader, URL[] urls) { - super(urls, antLoader); + public AuxClassLoader(ClassLoader nbLoader, ClassLoader antLoader, URL extraJar) { + super(new URL[] {extraJar}, antLoader); this.nbLoader = nbLoader; } Index: ant/src/org/apache/tools/ant/module/bridge/BridgeInterface.java =================================================================== RCS file: /cvs/ant/src/org/apache/tools/ant/module/bridge/BridgeInterface.java,v retrieving revision 1.2 retrieving revision 1.2.40.1 diff -u -r1.2 -r1.2.40.1 --- ant/src/org/apache/tools/ant/module/bridge/BridgeInterface.java 7 Jul 2003 16:23:03 -0000 1.2 +++ ant/src/org/apache/tools/ant/module/bridge/BridgeInterface.java 24 Dec 2003 18:09:03 -0000 1.2.40.1 @@ -39,6 +39,12 @@ String getAntVersion(); /** + * Check whether Ant 1.6 is loaded. + * If so, additional abilities may be possible, such as namespace support. + */ + boolean isAnt16(); + + /** * Get a proxy for IntrospectionHelper, to introspect task + type structure. */ IntrospectionHelperProxy getIntrospectionHelper(Class clazz); Index: ant/src/org/apache/tools/ant/module/bridge/DummyBridgeImpl.java =================================================================== RCS file: /cvs/ant/src/org/apache/tools/ant/module/bridge/DummyBridgeImpl.java,v retrieving revision 1.2 retrieving revision 1.2.40.1 diff -u -r1.2 -r1.2.40.1 --- ant/src/org/apache/tools/ant/module/bridge/DummyBridgeImpl.java 7 Jul 2003 16:23:04 -0000 1.2 +++ ant/src/org/apache/tools/ant/module/bridge/DummyBridgeImpl.java 24 Dec 2003 18:09:02 -0000 1.2.40.1 @@ -38,6 +38,10 @@ return NbBundle.getMessage(DummyBridgeImpl.class, "ERR_ant_not_loadable", problem); } + public boolean isAnt16() { + return false; + } + public IntrospectionHelperProxy getIntrospectionHelper(Class clazz) { return this; } Index: ant/src/org/apache/tools/ant/module/resources/mime-resolver.xml =================================================================== RCS file: /cvs/ant/src/org/apache/tools/ant/module/resources/mime-resolver.xml,v retrieving revision 1.3 retrieving revision 1.3.184.1 diff -u -r1.3 -r1.3.184.1 --- ant/src/org/apache/tools/ant/module/resources/mime-resolver.xml 23 Oct 2001 15:55:45 -0000 1.3 +++ ant/src/org/apache/tools/ant/module/resources/mime-resolver.xml 23 Dec 2003 23:42:55 -0000 1.3.184.1 @@ -8,7 +8,7 @@ http://www.sun.com/ The Original Code is NetBeans. The Initial Developer of the Original -Code is Sun Microsystems, Inc. Portions Copyright 1997-2001 Sun +Code is Sun Microsystems, Inc. Portions Copyright 1997-2003 Sun Microsystems, Inc. All Rights Reserved. --> @@ -25,6 +25,15 @@ + + + + + + + + + Index: ant/src-bridge/org/apache/tools/ant/module/bridge/impl/BridgeImpl.java =================================================================== RCS file: /cvs/ant/src-bridge/org/apache/tools/ant/module/bridge/impl/BridgeImpl.java,v retrieving revision 1.6 retrieving revision 1.6.6.3 diff -u -r1.6 -r1.6.6.3 --- ant/src-bridge/org/apache/tools/ant/module/bridge/impl/BridgeImpl.java 14 Nov 2003 12:17:01 -0000 1.6 +++ ant/src-bridge/org/apache/tools/ant/module/bridge/impl/BridgeImpl.java 26 Dec 2003 18:07:17 -0000 1.6.6.3 @@ -16,6 +16,7 @@ import java.io.*; import java.lang.reflect.Field; import java.lang.reflect.Modifier; +import java.net.URL; import java.util.*; import org.apache.tools.ant.*; import org.apache.tools.ant.input.InputHandler; @@ -49,6 +50,16 @@ } } + public boolean isAnt16() { + try { + Class.forName("org.apache.tools.ant.taskdefs.Antlib"); // NOI18N + return true; + } catch (ClassNotFoundException e) { + // Fine, 1.5 + return false; + } + } + public IntrospectionHelperProxy getIntrospectionHelper(Class clazz) { return new IntrospectionHelperImpl(clazz); } @@ -90,16 +101,10 @@ try { project = new Project(); project.init(); - Map customDefs = AntBridge.getCustomDefs(); - Iterator defs = ((Map)customDefs.get("task")).entrySet().iterator(); // NOI18N - while (defs.hasNext()) { - Map.Entry entry = (Map.Entry)defs.next(); - project.addTaskDefinition((String)entry.getKey(), (Class)entry.getValue()); - } - defs = ((Map)customDefs.get("type")).entrySet().iterator(); // NOI18N - while (defs.hasNext()) { - Map.Entry entry = (Map.Entry)defs.next(); - project.addDataTypeDefinition((String)entry.getKey(), (Class)entry.getValue()); + try { + addCustomDefs(project); + } catch (IOException e) { + throw new BuildException(e); } project.setUserProperty("ant.file", buildFile.getAbsolutePath()); // NOI18N // #14993: @@ -228,6 +233,45 @@ } return ok; + } + + private static void addCustomDefs(Project project) throws BuildException, IOException { + long start = System.currentTimeMillis(); + if (AntBridge.getInterface().isAnt16()) { + Map/**/ antlibLoaders = AntBridge.getCustomDefClassLoaders(); + Iterator it = antlibLoaders.entrySet().iterator(); + while (it.hasNext()) { + Map.Entry entry = (Map.Entry)it.next(); + String cnb = (String)entry.getKey(); + ClassLoader l = (ClassLoader)entry.getValue(); + String resource = cnb.replace('.', '/') + "/antlib.xml"; // NOI18N + URL antlib = l.getResource(resource); + if (antlib == null) { + throw new IOException("Could not find " + antlib + " in ant/nblib/" + cnb.replace('.', '-') + ".jar"); // NOI18N + } + // Once with no namespaces. + NbAntlib.process(project, antlib, null, l); + // Once with. + String antlibUri = "antlib:" + cnb; // NOI18N + NbAntlib.process(project, antlib, antlibUri, l); + } + } else { + // For Ant 1.5, just dump in old-style defs in the simplest manner. + Map customDefs = AntBridge.getCustomDefsNoNamespace(); + Iterator defs = ((Map)customDefs.get("task")).entrySet().iterator(); // NOI18N + while (defs.hasNext()) { + Map.Entry entry = (Map.Entry)defs.next(); + project.addTaskDefinition((String)entry.getKey(), (Class)entry.getValue()); + } + defs = ((Map)customDefs.get("type")).entrySet().iterator(); // NOI18N + while (defs.hasNext()) { + Map.Entry entry = (Map.Entry)defs.next(); + project.addDataTypeDefinition((String)entry.getKey(), (Class)entry.getValue()); + } + } + if (AntModule.err.isLoggable(ErrorManager.INFORMATIONAL)) { + AntModule.err.log("addCustomDefs took " + (System.currentTimeMillis() - start) + "msec"); + } } private static boolean doHack36393 = true; Index: ant/src-bridge/org/apache/tools/ant/module/bridge/impl/NbAntlib.java =================================================================== RCS file: ant/src-bridge/org/apache/tools/ant/module/bridge/impl/NbAntlib.java diff -N ant/src-bridge/org/apache/tools/ant/module/bridge/impl/NbAntlib.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ ant/src-bridge/org/apache/tools/ant/module/bridge/impl/NbAntlib.java 26 Dec 2003 03:12:36 -0000 1.1.2.1 @@ -0,0 +1,64 @@ +/* + * Sun Public License Notice + * + * The contents of this file are subject to the Sun Public License + * Version 1.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://www.sun.com/ + * + * The Original Code is NetBeans. The Initial Developer of the Original + * Code is Sun Microsystems, Inc. Portions Copyright 1997-2003 Sun + * Microsystems, Inc. All Rights Reserved. + */ + +package org.apache.tools.ant.module.bridge.impl; + +import java.io.IOException; +import java.net.URL; +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.ComponentHelper; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.UnknownElement; +import org.apache.tools.ant.helper.ProjectHelper2; +import org.apache.tools.ant.taskdefs.Antlib; + +/** + * Antlib subclass used to define custom tasks inside NetBeans. + * Needs to be a subclass to access {@link Antlib#setClassLoader} + * and {@link Antlib#setURI}. + * @author Jesse Glick + */ +public final class NbAntlib extends Antlib { + + /** + * Process antlib.xml definitions. + * @param p a project to add definitions to + * @param antlib location of antlib.xml to load + * @param uri a URI to add definitions in, or null + * @param l a class loader to load defined classes from + */ + public static void process(Project p, URL antlib, String uri, ClassLoader l) throws IOException, BuildException { + ComponentHelper helper = ComponentHelper.getComponentHelper(p); + helper.enterAntLib(uri); + Antlib al; + try { + UnknownElement antlibElement = new ProjectHelper2().parseUnknownElement(p, antlib); + al = new NbAntlib(uri, l); + al.setProject(p); + al.setLocation(antlibElement.getLocation()); + al.init(); + antlibElement.configure(al); + } finally { + helper.exitAntLib(); + } + al.execute(); + } + + private NbAntlib(String uri, ClassLoader l) { + if (uri != null) { + setURI(uri); + } + setClassLoader(l); + } + +} Index: apisupport/ant/build.xml =================================================================== RCS file: /cvs/apisupport/ant/build.xml,v retrieving revision 1.17 retrieving revision 1.17.2.1 diff -u -r1.17 -r1.17.2.1 --- apisupport/ant/build.xml 22 Dec 2003 15:20:03 -0000 1.17 +++ apisupport/ant/build.xml 24 Dec 2003 00:37:41 -0000 1.17.2.1 @@ -44,14 +44,14 @@ - + - + - + Index: apisupport/ant/manifest.mf =================================================================== RCS file: /cvs/apisupport/ant/manifest.mf,v retrieving revision 1.12 retrieving revision 1.12.22.2 diff -u -r1.12 -r1.12.22.2 --- apisupport/ant/manifest.mf 6 Sep 2003 15:48:26 -0000 1.12 +++ apisupport/ant/manifest.mf 24 Dec 2003 00:40:27 -0000 1.12.22.2 @@ -2,8 +2,8 @@ OpenIDE-Module: org.netbeans.modules.apisupport.ant OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/apisupport/ant/TemplateNames.properties OpenIDE-Module-Layer: org/netbeans/modules/apisupport/ant/mf-layer.xml -OpenIDE-Module-Specification-Version: 2.19 +OpenIDE-Module-Specification-Version: 2.20 OpenIDE-Module-Implementation-Version: @BUILD_NUMBER_SUBST@ -OpenIDE-Module-Module-Dependencies: org.apache.tools.ant.module/3 > 3.1, org.netbeans.core/1 > 1.1 +OpenIDE-Module-Module-Dependencies: org.apache.tools.ant.module/3 > 3.6, org.netbeans.core/1 > 1.1 OpenIDE-Module-IDE-Dependencies: IDE/1 > 3.17 Index: apisupport/ant/src/META-INF/taskdefs.properties =================================================================== RCS file: apisupport/ant/src/META-INF/taskdefs.properties diff -N apisupport/ant/src/META-INF/taskdefs.properties --- apisupport/ant/src/META-INF/taskdefs.properties 7 Jul 2003 16:23:09 -0000 1.2 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1 +0,0 @@ -nbinstaller=org.netbeans.modules.apisupport.ant.InstallModuleTask Index: apisupport/ant/src/org/netbeans/modules/apisupport/ant/antlib.xml =================================================================== RCS file: apisupport/ant/src/org/netbeans/modules/apisupport/ant/antlib.xml diff -N apisupport/ant/src/org/netbeans/modules/apisupport/ant/antlib.xml --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ apisupport/ant/src/org/netbeans/modules/apisupport/ant/antlib.xml 26 Dec 2003 18:05:33 -0000 1.1.2.2 @@ -0,0 +1,4 @@ + + + + Index: debuggerjpda/ant/build.xml =================================================================== RCS file: /cvs/debuggerjpda/ant/build.xml,v retrieving revision 1.2 retrieving revision 1.2.2.1 diff -u -r1.2 -r1.2.2.1 --- debuggerjpda/ant/build.xml 22 Dec 2003 15:20:03 -0000 1.2 +++ debuggerjpda/ant/build.xml 24 Dec 2003 00:37:38 -0000 1.2.2.1 @@ -45,15 +45,15 @@ - + - + - + Index: debuggerjpda/ant/manifest.mf =================================================================== RCS file: /cvs/debuggerjpda/ant/manifest.mf,v retrieving revision 1.1 retrieving revision 1.1.8.2 diff -u -r1.1 -r1.1.8.2 --- debuggerjpda/ant/manifest.mf 9 Nov 2003 15:51:54 -0000 1.1 +++ debuggerjpda/ant/manifest.mf 24 Dec 2003 00:40:26 -0000 1.1.8.2 @@ -1,9 +1,9 @@ Manifest-Version: 1.0 OpenIDE-Module: org.netbeans.modules.debugger.jpda.ant -OpenIDE-Module-Specification-Version: 1.0.7 +OpenIDE-Module-Specification-Version: 1.1 OpenIDE-Module-Implementation-Version: @BUILD_NUMBER_SUBST@ OpenIDE-Module-Module-Dependencies: - org.apache.tools.ant.module/3 > 3.1, + org.apache.tools.ant.module/3 > 3.6, org.netbeans.modules.debugger.jpda/1 > 1.16, org.netbeans.modules.debugger.core/3 > 2.10, org.openide.debugger > 1.0 Index: debuggerjpda/ant/src/META-INF/taskdefs.properties =================================================================== RCS file: debuggerjpda/ant/src/META-INF/taskdefs.properties diff -N debuggerjpda/ant/src/META-INF/taskdefs.properties --- debuggerjpda/ant/src/META-INF/taskdefs.properties 9 Nov 2003 15:51:55 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1 +0,0 @@ -nbjpdaconnect=org.netbeans.modules.debugger.jpda.ant.JPDAConnect Index: debuggerjpda/ant/src/org/netbeans/modules/debugger/jpda/ant/antlib.xml =================================================================== RCS file: debuggerjpda/ant/src/org/netbeans/modules/debugger/jpda/ant/antlib.xml diff -N debuggerjpda/ant/src/org/netbeans/modules/debugger/jpda/ant/antlib.xml --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ debuggerjpda/ant/src/org/netbeans/modules/debugger/jpda/ant/antlib.xml 26 Dec 2003 18:05:33 -0000 1.1.2.2 @@ -0,0 +1,4 @@ + + + + Index: autoupdate/src/org/netbeans/modules/autoupdate/SignVerifier.java =================================================================== RCS file: /cvs/autoupdate/src/org/netbeans/modules/autoupdate/SignVerifier.java,v retrieving revision 1.25 diff -u -r1.25 SignVerifier.java --- autoupdate/src/org/netbeans/modules/autoupdate/SignVerifier.java 7 Jul 2003 16:23:11 -0000 1.25 +++ autoupdate/src/org/netbeans/modules/autoupdate/SignVerifier.java 26 Dec 2003 18:13:34 -0000 @@ -36,7 +36,6 @@ private static final String ENTRY_SEPARATOR = "/"; // NOI18N private static final String NBM_BIN = "netbeans/bin"; // NOI18N private static final String NBM_LIB = "netbeans/lib"; // NOI18N - private static final String NBM_ANT_NBLIB = "netbeans/ant/nblib"; // NOI18N private static final String NBM_MAIN = "main"; // NOI18N private static final String NBM_MODULES = "netbeans/modules"; // NOI18N private static final String NBM_AUTOLOAD = NBM_MODULES + ENTRY_SEPARATOR + SafeModule.PROP_AUTOLOAD; // NOI18N @@ -239,7 +238,7 @@ JarEntry entry = (JarEntry)entries.nextElement(); // dangerous modules should be updated into install directory - if ( entry.getName().startsWith( NBM_LIB ) || entry.getName().startsWith( NBM_BIN ) || entry.getName().startsWith( NBM_ANT_NBLIB )) + if ( entry.getName().startsWith( NBM_LIB ) || entry.getName().startsWith( NBM_BIN )) mu.setDepending( true ); if ( entry.getName().startsWith( NBM_MAIN ) )