diff --git a/java.j2seproject/src/org/netbeans/modules/java/j2seproject/J2SEProject.java b/java.j2seproject/src/org/netbeans/modules/java/j2seproject/J2SEProject.java --- a/java.j2seproject/src/org/netbeans/modules/java/j2seproject/J2SEProject.java +++ b/java.j2seproject/src/org/netbeans/modules/java/j2seproject/J2SEProject.java @@ -159,7 +159,7 @@ } } refHelper = new ReferenceHelper(helper, aux, eval); - buildExtender = AntBuildExtenderFactory.createAntExtender(new J2SEExtenderImplementation()); + buildExtender = AntBuildExtenderFactory.createAntExtender(new J2SEExtenderImplementation(), refHelper); /// TODO replace this GeneratedFilesHelper with the default one when fixing #101710 genFilesHelper = new GeneratedFilesHelper(helper, buildExtender); UpdateImplementation updateProject = new UpdateProjectImpl(this, helper, aux); @@ -733,7 +733,7 @@ public Project getOwningProject() { return J2SEProject.this; } - + } private static final String ENDORSED_DIR_PROPERTY="jaxws.endorsed.dir"; //NOI18N diff --git a/java.j2seproject/src/org/netbeans/modules/java/j2seproject/ui/customizer/CustomizerLibraries.java b/java.j2seproject/src/org/netbeans/modules/java/j2seproject/ui/customizer/CustomizerLibraries.java --- a/java.j2seproject/src/org/netbeans/modules/java/j2seproject/ui/customizer/CustomizerLibraries.java +++ b/java.j2seproject/src/org/netbeans/modules/java/j2seproject/ui/customizer/CustomizerLibraries.java @@ -55,9 +55,11 @@ import org.netbeans.api.java.platform.PlatformsCustomizer; import org.netbeans.api.project.libraries.LibraryManager; import org.netbeans.modules.java.api.common.ui.PlatformUiSupport; +import org.netbeans.modules.java.j2seproject.api.J2SEPropertyEvaluator; import org.netbeans.modules.java.j2seproject.classpath.ClassPathSupport; import org.netbeans.modules.java.j2seproject.ui.J2SELogicalViewProvider; import org.netbeans.spi.java.project.support.ui.SharableLibrariesUtils; +import org.netbeans.spi.project.support.ant.PropertyEvaluator; import org.netbeans.spi.project.support.ant.PropertyUtils; import org.openide.awt.Mnemonics; import org.openide.filesystems.FileUtil; @@ -813,6 +815,14 @@ collectLibs(uiProperties.JAVAC_TEST_CLASSPATH_MODEL, libs, jars); collectLibs(uiProperties.RUN_CLASSPATH_MODEL, libs, jars); collectLibs(uiProperties.RUN_TEST_CLASSPATH_MODEL, libs, jars); + libs.add("CopyLibs"); // #132201 - copylibs is integral part of j2seproject + String customTasksLibs = uiProperties.getProject().evaluator().getProperty("ant.customtasks.libs"); + if (customTasksLibs != null) { + String libIDs[] = PropertyUtils.tokenizePath(customTasksLibs); + for (String libID : libIDs) { + libs.add(libID.trim()); + } + } boolean result = SharableLibrariesUtils.showMakeSharableWizard(uiProperties.getProject().getAntProjectHelper(), uiProperties.getProject().getReferenceHelper(), libs, jars); if (result) { isSharable = true; diff --git a/project.ant/apichanges.xml b/project.ant/apichanges.xml --- a/project.ant/apichanges.xml +++ b/project.ant/apichanges.xml @@ -102,6 +102,27 @@ + + + + + + Support for adding/copying libraries used by build process only + + + + + +

+ Added methods for adding/copying global libraries that are needed + for Ant build script. Added methods: + AntBuildExtender.addLibrary, + AntBuildExtender.removeLibrary +

+
+ + +
diff --git a/project.ant/manifest.mf b/project.ant/manifest.mf --- a/project.ant/manifest.mf +++ b/project.ant/manifest.mf @@ -1,6 +1,6 @@ Manifest-Version: 1.0 OpenIDE-Module: org.netbeans.modules.project.ant/1 -OpenIDE-Module-Specification-Version: 1.20 +OpenIDE-Module-Specification-Version: 1.21 OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/project/ant/Bundle.properties OpenIDE-Module-Install: org/netbeans/modules/project/ant/AntProjectModule.class diff --git a/project.ant/src/org/netbeans/api/project/ant/AntBuildExtender.java b/project.ant/src/org/netbeans/api/project/ant/AntBuildExtender.java --- a/project.ant/src/org/netbeans/api/project/ant/AntBuildExtender.java +++ b/project.ant/src/org/netbeans/api/project/ant/AntBuildExtender.java @@ -41,8 +41,11 @@ package org.netbeans.api.project.ant; -import org.netbeans.spi.project.ant.AntBuildExtenderImplementation; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; @@ -51,16 +54,27 @@ import java.util.Map; import java.util.Set; import java.util.TreeMap; +import java.util.TreeSet; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.netbeans.api.project.FileOwnerQuery; +import org.netbeans.api.project.ProjectManager; +import org.netbeans.api.project.libraries.Library; +import org.netbeans.api.project.libraries.LibraryManager; import org.netbeans.modules.project.ant.AntBuildExtenderAccessor; import org.netbeans.spi.project.AuxiliaryConfiguration; import org.netbeans.spi.project.ant.AntBuildExtenderImplementation; import org.netbeans.spi.project.support.ant.AntProjectHelper; +import org.netbeans.spi.project.support.ant.EditableProperties; +import org.netbeans.spi.project.support.ant.PropertyUtils; +import org.netbeans.spi.project.support.ant.ReferenceHelper; +import org.openide.filesystems.FileLock; import org.openide.filesystems.FileObject; import org.openide.filesystems.FileUtil; +import org.openide.util.Exceptions; +import org.openide.util.Mutex; +import org.openide.util.MutexException; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; @@ -87,15 +101,22 @@ * @since org.netbeans.modules.project.ant 1.16 */ public final class AntBuildExtender { + private HashMap extensions; private AntBuildExtenderImplementation implementation; - + private ReferenceHelper refHelper; + static { AntBuildExtenderAccessorImpl.createAccesor(); } AntBuildExtender(AntBuildExtenderImplementation implementation) { this.implementation = implementation; + } + + AntBuildExtender(AntBuildExtenderImplementation implementation, ReferenceHelper refHlpr) { + this.implementation = implementation; + this.refHelper = refHlpr; } /** @@ -135,6 +156,7 @@ updateProjectMetadata(); return ex; } + /** * Remove an existing build script extension. Make sure to remove the extension's script file * before/after removing the extension. @@ -172,6 +194,104 @@ } ext.addAll(extensions.values()); return ext; + } + + /** + * Copies global library to the shared library folder of the project if the + * project is sharable and adds library name to the list of libraries needed + * to run Ant script. In the case of non-sharable project only the name is + * added to the list and the library is copied when the project is made sharable. + * + * @param library global library to be copied to shared library folder of the project + * @throws java.io.IOException exception thrown when properties cannot be loaded or saved + */ + public void addLibrary(Library library) throws IOException { + if (library == null) { + throw new NullPointerException("null library passed to addLibrary"); + } + setValueOfProperty("ant.customtasks.libs", library.getName(), true); + if (refHelper != null && refHelper.getProjectLibraryManager() != null) { + if (refHelper.getProjectLibraryManager().getLibrary(library.getName()) == null) { + try { + refHelper.copyLibrary(library); + } catch (IOException ex) { + Exceptions.printStackTrace(ex); + } + } + } + } + + /** + * Removes library name from the list of libraries needed to run Ant script + * + * @param library either global or shared library to be removed from list of + * libraries needed for running Ant script; cannot be null + * @throws java.io.IOException exception thrown when properties cannot be loaded or saved + */ + public void removeLibrary(Library library) throws IOException { + if (library == null) { + throw new NullPointerException("null library passed to removeLibrary"); + } + setValueOfProperty("ant.customtasks.libs", library.getName(), false); + } + + private void setValueOfProperty(final String propName, final String value, final boolean add) throws IOException { + try { + final FileObject projPropsFO = implementation.getOwningProject().getProjectDirectory().getFileObject(AntProjectHelper.PROJECT_PROPERTIES_PATH); + final InputStream is = projPropsFO.getInputStream(); + ProjectManager.mutex().writeAccess(new Mutex.ExceptionAction() { + public Void run() throws Exception { + EditableProperties editableProps = new EditableProperties(true); + + try { + editableProps.load(is); + } finally { + if (is != null) { + is.close(); + } + } + + String libIDs[] = new String[0]; + String savedPropVal = editableProps.getProperty(propName); + if (savedPropVal != null) { + libIDs = PropertyUtils.tokenizePath(savedPropVal); + } + Set libIDSet = new TreeSet(Arrays.asList(libIDs)); + if (add) { + libIDSet.add(value); + } else { + libIDSet.remove(value); + } + String newLibIDs[] = (String[]) libIDSet.toArray(new String[libIDSet.size()]); + StringBuilder propValue = new StringBuilder(); + for (String newLibID : newLibIDs) { + propValue.append(newLibID); + propValue.append(";"); + } + propValue.delete(propValue.length() - 1, propValue.length()); + + editableProps.setProperty(propName, propValue.toString()); + + OutputStream os = null; + FileLock lock = null; + try { + lock = projPropsFO.lock(); + os = projPropsFO.getOutputStream(lock); + editableProps.store(os); + } finally { + if (lock != null) { + lock.releaseLock(); + } + if (os != null) { + os.close(); + } + } + return null; + } + }); + } catch (MutexException mux) { + throw (IOException) mux.getException(); + } } private static final DocumentBuilder db; diff --git a/project.ant/src/org/netbeans/api/project/ant/AntBuildExtenderAccessorImpl.java b/project.ant/src/org/netbeans/api/project/ant/AntBuildExtenderAccessorImpl.java --- a/project.ant/src/org/netbeans/api/project/ant/AntBuildExtenderAccessorImpl.java +++ b/project.ant/src/org/netbeans/api/project/ant/AntBuildExtenderAccessorImpl.java @@ -40,13 +40,13 @@ */ package org.netbeans.api.project.ant; -import org.netbeans.spi.project.ant.AntBuildExtenderImplementation; import java.util.Collection; import java.util.Map; import java.util.Set; import org.netbeans.api.project.ant.AntBuildExtender.Extension; import org.netbeans.modules.project.ant.AntBuildExtenderAccessor; import org.netbeans.spi.project.ant.AntBuildExtenderImplementation; +import org.netbeans.spi.project.support.ant.ReferenceHelper; /** * @@ -67,7 +67,11 @@ public AntBuildExtender createExtender(AntBuildExtenderImplementation impl) { return new AntBuildExtender(impl); } - + + public AntBuildExtender createExtender(AntBuildExtenderImplementation impl, ReferenceHelper refHelper) { + return new AntBuildExtender(impl, refHelper); + } + public Set getExtensions(AntBuildExtender ext) { return ext.getExtensions(); } diff --git a/project.ant/src/org/netbeans/modules/project/ant/AntBuildExtenderAccessor.java b/project.ant/src/org/netbeans/modules/project/ant/AntBuildExtenderAccessor.java --- a/project.ant/src/org/netbeans/modules/project/ant/AntBuildExtenderAccessor.java +++ b/project.ant/src/org/netbeans/modules/project/ant/AntBuildExtenderAccessor.java @@ -41,12 +41,12 @@ package org.netbeans.modules.project.ant; -import org.netbeans.spi.project.ant.AntBuildExtenderImplementation; import java.util.Collection; import java.util.Map; import java.util.Set; import org.netbeans.api.project.ant.AntBuildExtender; import org.netbeans.spi.project.ant.AntBuildExtenderImplementation; +import org.netbeans.spi.project.support.ant.ReferenceHelper; /** @@ -105,6 +105,8 @@ public abstract AntBuildExtender createExtender(AntBuildExtenderImplementation impl); + public abstract AntBuildExtender createExtender(AntBuildExtenderImplementation impl, ReferenceHelper refHelper); + public abstract Set getExtensions(AntBuildExtender ext); public abstract String getPath(AntBuildExtender.Extension extension); diff --git a/project.ant/src/org/netbeans/spi/project/ant/AntBuildExtenderFactory.java b/project.ant/src/org/netbeans/spi/project/ant/AntBuildExtenderFactory.java --- a/project.ant/src/org/netbeans/spi/project/ant/AntBuildExtenderFactory.java +++ b/project.ant/src/org/netbeans/spi/project/ant/AntBuildExtenderFactory.java @@ -41,9 +41,9 @@ package org.netbeans.spi.project.ant; -import org.netbeans.spi.project.ant.AntBuildExtenderImplementation; import org.netbeans.api.project.ant.AntBuildExtender; import org.netbeans.modules.project.ant.AntBuildExtenderAccessor; +import org.netbeans.spi.project.support.ant.ReferenceHelper; /** * Factory class for creation of AntBuildExtender instances @@ -61,9 +61,23 @@ * to be included in project's lookup. * @param implementation project type's spi implementation * @return resulting AntBuildExtender instance + * @deprecated + * @see createAntExtender(AntBuildExtenderImplementation, ReferenceHelper) */ public static AntBuildExtender createAntExtender(AntBuildExtenderImplementation implementation) { return AntBuildExtenderAccessor.DEFAULT.createExtender(implementation); } + /** + * Create instance of {@link org.netbeans.api.project.ant.AntBuildExtender} that is + * to be included in project's lookup. + * @param implementation project type's spi implementation + * @param refHelper project related reference helper + * @return resulting AntBuildExtender instance + * @since 1.21 + */ + public static AntBuildExtender createAntExtender(AntBuildExtenderImplementation implementation, ReferenceHelper refHelper) { + return AntBuildExtenderAccessor.DEFAULT.createExtender(implementation, refHelper); + } + }