--- a/j2ee.common/nbproject/project.xml Fri May 28 12:20:35 2010 +0200 +++ a/j2ee.common/nbproject/project.xml Fri Jun 11 10:20:14 2010 +0200 @@ -193,7 +193,7 @@ 4 - 1.58 + 1.68 --- a/j2ee.common/src/org/netbeans/modules/j2ee/common/Util.java Fri May 28 12:20:35 2010 +0200 +++ a/j2ee.common/src/org/netbeans/modules/j2ee/common/Util.java Fri Jun 11 10:20:14 2010 +0200 @@ -63,6 +63,7 @@ import org.netbeans.api.j2ee.core.Profile; import org.netbeans.api.java.classpath.ClassPath; import org.netbeans.api.project.Project; +import org.netbeans.modules.j2ee.deployment.common.api.ConfigurationException; import org.netbeans.modules.j2ee.deployment.devmodules.api.Deployment; import org.netbeans.modules.j2ee.deployment.devmodules.api.InstanceRemovedException; import org.netbeans.modules.j2ee.deployment.devmodules.api.J2eeModule; @@ -75,6 +76,7 @@ import org.openide.filesystems.FileObject; import org.openide.filesystems.FileUtil; import org.openide.filesystems.URLMapper; +import org.openide.util.Exceptions; import org.openide.util.NbBundle; import org.openide.util.Parameters; import org.w3c.dom.Element; @@ -298,7 +300,20 @@ if (j2eeModuleProvider != null) { J2eePlatform j2eePlatform = Deployment.getDefault().getJ2eePlatform(j2eeModuleProvider.getServerInstanceID()); if (j2eePlatform != null) { - return j2eePlatform.getClasspathEntries(); + File[] platformClasspath = j2eePlatform.getClasspathEntries(); + File[] libraryClasspath = null; + try { + libraryClasspath = j2eePlatform.getClasspathEntries(j2eeModuleProvider.getConfigSupport().getLibraries()); + } catch (ConfigurationException ex) { + // noop + } + if (libraryClasspath == null) { + return platformClasspath; + } + File[] result = new File[platformClasspath.length + libraryClasspath.length]; + System.arraycopy(platformClasspath, 0, result, 0, platformClasspath.length); + System.arraycopy(libraryClasspath, 0, result, platformClasspath.length, libraryClasspath.length); + return result; } } } --- a/j2ee.common/src/org/netbeans/modules/j2ee/common/project/ui/J2EEProjectProperties.java Fri May 28 12:20:35 2010 +0200 +++ a/j2ee.common/src/org/netbeans/modules/j2ee/common/project/ui/J2EEProjectProperties.java Fri Jun 11 10:20:14 2010 +0200 @@ -53,6 +53,7 @@ import java.util.logging.Logger; import org.netbeans.api.j2ee.core.Profile; import org.netbeans.api.project.Project; +import org.netbeans.modules.j2ee.common.Util; import org.netbeans.modules.j2ee.deployment.devmodules.api.AntDeploymentHelper; import org.netbeans.modules.j2ee.deployment.devmodules.api.Deployment; import org.netbeans.modules.j2ee.deployment.devmodules.api.J2eeModule; @@ -129,10 +130,16 @@ (items !=null && !getServerLibraries(items).isEmpty()); } + public static void setServerProperties(EditableProperties ep, EditableProperties epPriv, + String serverLibraryName, ClassPathSupport cs, Iterable items, + String serverInstanceID, Profile j2eeProfile, J2eeModule.Type moduleType) { + setServerProperties(null, ep, epPriv, serverLibraryName, cs, items, serverInstanceID, j2eeProfile, moduleType); + } + /** * Sets all server related properties. */ - public static void setServerProperties(EditableProperties ep, EditableProperties epPriv, + public static void setServerProperties(Project project, EditableProperties ep, EditableProperties epPriv, String serverLibraryName, ClassPathSupport cs, Iterable items, String serverInstanceID, Profile j2eeProfile, J2eeModule.Type moduleType) { Deployment deployment = Deployment.getDefault(); @@ -163,10 +170,10 @@ String root = extractPlatformLibrariesRoot(j2eePlatform); if (root != null) { // path will be relative and therefore stored in project.properties: - setLocalServerProperties(epPriv, ep, j2eePlatform, root); + setLocalServerProperties(project, epPriv, ep, j2eePlatform, root); } else { // store absolute paths in private.properties: - setLocalServerProperties(ep, epPriv, j2eePlatform, null); + setLocalServerProperties(project, ep, epPriv, j2eePlatform, null); } } @@ -238,7 +245,7 @@ } callback.registerJ2eePlatformListener(j2eePlatform); - setServerProperties(projectProps, privateProps, null, cs, items, newServInstID, profile, moduleType); + setServerProperties(proj, projectProps, privateProps, null, cs, items, newServInstID, profile, moduleType); // ant deployment support createDeploymentScript(proj.getProjectDirectory(), projectProps, privateProps, newServInstID, moduleType); @@ -323,13 +330,15 @@ ep.remove(J2EE_PLATFORM_WSIT_CLASSPATH); ep.remove(J2EE_PLATFORM_JWSDP_CLASSPATH); ep.remove(J2EE_SERVER_HOME); - } + } - private static void setLocalServerProperties(EditableProperties epToClean, EditableProperties epTarget, J2eePlatform j2eePlatform, String root) { + private static void setLocalServerProperties(Project project, EditableProperties epToClean, EditableProperties epTarget, J2eePlatform j2eePlatform, String root) { // remove all props first: removeServerClasspathProperties(epTarget); - String classpath = toClasspathString(j2eePlatform.getClasspathEntries(), root); + String classpath = project == null + ? toClasspathString(j2eePlatform.getClasspathEntries(), root) + : toClasspathString(Util.getJ2eePlatformClasspathEntries(project), root); epTarget.setProperty(J2EE_PLATFORM_CLASSPATH, classpath); // set j2ee.platform.embeddableejb.classpath --- a/j2ee.common/src/org/netbeans/modules/j2ee/common/project/ui/J2eePlatformNode.java Fri May 28 12:20:35 2010 +0200 +++ a/j2ee.common/src/org/netbeans/modules/j2ee/common/project/ui/J2eePlatformNode.java Fri Jun 11 10:20:14 2010 +0200 @@ -45,6 +45,7 @@ package org.netbeans.modules.j2ee.common.project.ui; +import org.netbeans.modules.j2ee.deployment.common.api.ConfigurationException; import org.netbeans.modules.java.api.common.project.ui.LibrariesNode; import java.awt.Image; import java.beans.PropertyChangeEvent; @@ -53,6 +54,8 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; import javax.swing.Action; import javax.swing.Icon; import javax.swing.ImageIcon; @@ -61,6 +64,7 @@ import org.openide.nodes.Children; import org.openide.nodes.AbstractNode; import org.openide.nodes.Node; +import org.openide.util.Exceptions; import org.openide.util.ImageUtilities; import org.openide.util.WeakListeners; import org.netbeans.api.project.SourceGroup; @@ -86,6 +90,8 @@ */ class J2eePlatformNode extends AbstractNode implements PropertyChangeListener, InstanceListener { + private static final Logger LOGGER = Logger.getLogger(J2eePlatformNode.class.getName()); + private static final String ARCHIVE_ICON = "org/netbeans/modules/j2ee/common/project/ui/resources/jar.gif"; //NOI18N private static final String DEFAULT_ICON = "org/netbeans/modules/j2ee/common/project/ui/resources/j2eeServer.gif"; //NOI18N private static final String BROKEN_PROJECT_BADGE = "org/netbeans/modules/j2ee/common/project/ui/resources/brokenProjectBadge.gif"; //NOI18N @@ -115,7 +121,7 @@ private PropertyChangeListener weakPlatformListener; private J2eePlatformNode(Project project, PropertyEvaluator evaluator, String platformPropName, ClassPathSupport cs) { - super(new PlatformContentChildren(cs)); + super(new PlatformContentChildren(project, cs)); this.evaluator = evaluator; this.platformPropName = platformPropName; evaluator.addPropertyChangeListener(WeakListeners.propertyChange(this, evaluator)); @@ -234,7 +240,10 @@ private static class PlatformContentChildren extends Children.Keys { - PlatformContentChildren (ClassPathSupport cs) { + private final J2eeModuleProvider j2eeModuleProvider; + + PlatformContentChildren(Project project, ClassPathSupport cs) { + j2eeModuleProvider = project.getLookup().lookup(J2eeModuleProvider.class); } @Override @@ -258,13 +267,14 @@ if (j2eePlatform != null) { File[] classpathEntries = j2eePlatform.getClasspathEntries(); result = new ArrayList(classpathEntries.length); - for (int i = 0; i < classpathEntries.length; i++) { - FileObject file = FileUtil.toFileObject(classpathEntries[i]); - if (file != null) { - FileObject archiveFile = FileUtil.getArchiveRoot(file); - if (archiveFile != null) { - result.add(ProjectUISupport.createLibrariesSourceGroup(archiveFile, file.getNameExt(), icon, icon)); - } + addToSourceGroups(classpathEntries, result); + if (j2eeModuleProvider != null) { + try { + classpathEntries = j2eePlatform.getClasspathEntries(j2eeModuleProvider.getConfigSupport().getLibraries()); + addToSourceGroups(classpathEntries, result); + } catch (ConfigurationException ex) { + // noop + LOGGER.log(Level.INFO, null, ex); } } } else { @@ -273,5 +283,18 @@ return result; } + + private void addToSourceGroups(File[] classpathEntries, List sourceGroups) { + for (int i = 0; i < classpathEntries.length; i++) { + FileObject file = FileUtil.toFileObject(classpathEntries[i]); + if (file != null) { + FileObject archiveFile = FileUtil.getArchiveRoot(file); + if (archiveFile != null) { + sourceGroups.add(ProjectUISupport.createLibrariesSourceGroup(archiveFile, file.getNameExt(), icon, icon)); + } + } + } + } } + } --- a/j2ee.weblogic9/nbproject/project.xml Fri May 28 12:20:35 2010 +0200 +++ a/j2ee.weblogic9/nbproject/project.xml Fri Jun 11 10:20:14 2010 +0200 @@ -140,7 +140,7 @@ 4 - 1.66 + 1.68 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ 5eda48228ef2 Fri Jun 11 10:20:14 2010 +0200 @@ -0,0 +1,79 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Contributor(s): + * + * Portions Copyrighted 2010 Sun Microsystems, Inc. + */ + +package org.netbeans.modules.j2ee.weblogic9; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import javax.enterprise.deploy.spi.status.ProgressEvent; +import javax.enterprise.deploy.spi.status.ProgressListener; +import javax.enterprise.deploy.spi.status.ProgressObject; +import org.netbeans.modules.j2ee.weblogic9.deploy.WLDeploymentManager; + +/** + * + * @author Petr Hejl + */ +public final class ProgressObjectSupport { + + private ProgressObjectSupport() { + super(); + } + + public static void waitFor(ProgressObject obj) { + final CountDownLatch latch = new CountDownLatch(1); + obj.addProgressListener(new ProgressListener() { + + @Override + public void handleProgressEvent(ProgressEvent pe) { + if (pe.getDeploymentStatus().isCompleted() || pe.getDeploymentStatus().isFailed()) { + latch.countDown(); + } + } + }); + if (obj.getDeploymentStatus().isCompleted() || obj.getDeploymentStatus().isFailed()) { + return; + } + try { + latch.await(WLDeploymentManager.MANAGER_TIMEOUT, TimeUnit.MILLISECONDS); + } catch (InterruptedException ex) { + Thread.currentThread().interrupt(); + } + } +} --- a/j2ee.weblogic9/src/org/netbeans/modules/j2ee/weblogic9/WLPluginProperties.java Fri May 28 12:20:35 2010 +0200 +++ a/j2ee.weblogic9/src/org/netbeans/modules/j2ee/weblogic9/WLPluginProperties.java Fri Jun 11 10:20:14 2010 +0200 @@ -55,6 +55,7 @@ import java.util.logging.Level; import java.util.logging.Logger; import org.netbeans.api.annotations.common.CheckForNull; +import org.netbeans.modules.j2ee.deployment.common.api.Version; import org.netbeans.modules.j2ee.weblogic9.deploy.WLDeploymentManager; import org.openide.filesystems.FileLock; import org.openide.filesystems.FileObject; @@ -227,7 +228,8 @@ * Checks whether the server root contains weblogic.jar of version 9 or 10. */ public static boolean isSupportedVersion(Version version) { - return version != null && ("9".equals(version.getMajorNumber()) || "10".equals(version.getMajorNumber())); // NOI18N + return version != null && (Integer.valueOf(9).equals(version.getMajor()) + || Integer.valueOf(10).equals(version.getMajor())); } public static Version getVersion(File serverRoot) { @@ -247,7 +249,7 @@ } if (implementationVersion != null) { // NOI18N implementationVersion = implementationVersion.trim(); - return new Version(implementationVersion); + return Version.fromJsr277NotationWithFallback(implementationVersion); } } finally { try { @@ -321,161 +323,4 @@ return this.installLocation; } - /** - * Class representing the WebLogic version. - *

- * Immutable - * - * @author Petr Hejl - */ - public static final class Version implements Comparable { - - private String majorNumber = "0"; - - private String minorNumber = "0"; - - private String microNumber = "0"; - - private String update = ""; - - /** - * Constructs the version from the spec version string. - * Expected format is MAJOR_NUMBER[.MINOR_NUMBER[.MICRO_NUMBER[.UPDATE]]]. - * - * @param version spec version string with the following format: - * MAJOR_NUMBER[.MINOR_NUMBER[.MICRO_NUMBER[.UPDATE]]] - */ - public Version(String version) { - assert version != null : "Version can't be null"; // NOI18N - - String[] tokens = version.split("\\."); - - if (tokens.length >= 4) { - update = tokens[3]; - } - if (tokens.length >= 3) { - microNumber = tokens[2]; - } - if (tokens.length >= 2) { - minorNumber = tokens[1]; - } - majorNumber = tokens[0]; - } - - /** - * Returns the major number. - * - * @return the major number. Never returns null. - */ - public String getMajorNumber() { - return majorNumber; - } - - /** - * Returns the minor number. - * - * @return the minor number. Never returns null. - */ - public String getMinorNumber() { - return minorNumber; - } - - /** - * Returns the micro number. - * - * @return the micro number. Never returns null. - */ - public String getMicroNumber() { - return microNumber; - } - - /** - * Returns the update. - * - * @return the update. Never returns null. - */ - public String getUpdate() { - return update; - } - - /** - * {@inheritDoc}

- * Two versions are equal if and only if they have same major, minor, - * micro number and update. - */ - @Override - public boolean equals(Object obj) { - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - final Version other = (Version) obj; - if (this.majorNumber != other.majorNumber - && (this.majorNumber == null || !this.majorNumber.equals(other.majorNumber))) { - return false; - } - if (this.minorNumber != other.minorNumber - && (this.minorNumber == null || !this.minorNumber.equals(other.minorNumber))) { - return false; - } - if (this.microNumber != other.microNumber - && (this.microNumber == null || !this.microNumber.equals(other.microNumber))) { - return false; - } - if (this.update != other.update - && (this.update == null || !this.update.equals(other.update))) { - return false; - } - return true; - } - - /** - * {@inheritDoc}

- * The implementation consistent with {@link #equals(Object)}. - */ - @Override - public int hashCode() { - int hash = 7; - hash = 17 * hash + (this.majorNumber != null ? this.majorNumber.hashCode() : 0); - hash = 17 * hash + (this.minorNumber != null ? this.minorNumber.hashCode() : 0); - hash = 17 * hash + (this.microNumber != null ? this.microNumber.hashCode() : 0); - hash = 17 * hash + (this.update != null ? this.update.hashCode() : 0); - return hash; - } - - /** - * {@inheritDoc}

- * Compares the versions based on its major, minor, micro and update. - * Major number is the most significant. Implementation is consistent - * with {@link #equals(Object)}. - */ - public int compareTo(Version o) { - int comparison = compareToIgnoreUpdate(o); - if (comparison != 0) { - return comparison; - } - return update.compareTo(o.update); - } - - /** - * Compares the versions based on its major, minor, micro. Update field - * is ignored. Major number is the most significant. - * - * @param o version to compare with - */ - public int compareToIgnoreUpdate(Version o) { - int comparison = majorNumber.compareTo(o.majorNumber); - if (comparison != 0) { - return comparison; - } - comparison = minorNumber.compareTo(o.minorNumber); - if (comparison != 0) { - return comparison; - } - return microNumber.compareTo(o.microNumber); - } - - } } --- a/j2ee.weblogic9/src/org/netbeans/modules/j2ee/weblogic9/config/Bundle.properties Fri May 28 12:20:35 2010 +0200 +++ a/j2ee.weblogic9/src/org/netbeans/modules/j2ee/weblogic9/config/Bundle.properties Fri Jun 11 10:20:14 2010 +0200 @@ -68,4 +68,8 @@ have write access to this file. MSG_FailedToCreateConfigFolder=The {0} folder could not be created. -MSG_FailedToDeployDatasource=One or more datasources could not be deployed. Check project configuration. +MSG_FailedToDeployDatasource=One or more datasources could not be deployed. Check project configuration. +MSG_FailedToDeployLibrary=One or more libraries could not be deployed. Check project configuration. + +MSG_CannotReaderServerLibraries=Cannot read the server libraries value since the {0} file is not parseable. +MSG_DidNotFindServerLibraries=Some server libraries could not be find on server or deployed. --- a/j2ee.weblogic9/src/org/netbeans/modules/j2ee/weblogic9/config/WLDatasourceManager.java Fri May 28 12:20:35 2010 +0200 +++ a/j2ee.weblogic9/src/org/netbeans/modules/j2ee/weblogic9/config/WLDatasourceManager.java Fri Jun 11 10:20:14 2010 +0200 @@ -49,17 +49,14 @@ import java.util.LinkedList; import java.util.Map; import java.util.Set; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; import java.util.logging.Level; import java.util.logging.Logger; -import javax.enterprise.deploy.spi.status.ProgressEvent; -import javax.enterprise.deploy.spi.status.ProgressListener; import javax.enterprise.deploy.spi.status.ProgressObject; import org.netbeans.modules.j2ee.deployment.common.api.ConfigurationException; import org.netbeans.modules.j2ee.deployment.common.api.Datasource; import org.netbeans.modules.j2ee.deployment.common.api.DatasourceAlreadyExistsException; import org.netbeans.modules.j2ee.deployment.plugins.spi.DatasourceManager; +import org.netbeans.modules.j2ee.weblogic9.ProgressObjectSupport; import org.netbeans.modules.j2ee.weblogic9.WLDeploymentFactory; import org.netbeans.modules.j2ee.weblogic9.WLPluginProperties; import org.netbeans.modules.j2ee.weblogic9.deploy.WLCommandDeployer; @@ -131,7 +128,7 @@ WLCommandDeployer deployer = new WLCommandDeployer(WLDeploymentFactory.getInstance(), manager.getInstanceProperties()); ProgressObject po = deployer.deployDatasource(toDeploy.values()); - waitFor(po); + ProgressObjectSupport.waitFor(po); if (po.getDeploymentStatus().isFailed()) { String msg = NbBundle.getMessage(WLDatasourceManager.class, "MSG_FailedToDeployDatasource"); throw new ConfigurationException(msg); @@ -162,22 +159,4 @@ } return map; } - - private void waitFor(ProgressObject obj) { - final CountDownLatch latch = new CountDownLatch(1); - obj.addProgressListener(new ProgressListener() { - - @Override - public void handleProgressEvent(ProgressEvent pe) { - if (pe.getDeploymentStatus().isCompleted() || pe.getDeploymentStatus().isFailed()) { - latch.countDown(); - } - } - }); - try { - latch.await(WLDeploymentManager.MANAGER_TIMEOUT, TimeUnit.MILLISECONDS); - } catch (InterruptedException ex) { - Thread.currentThread().interrupt(); - } - } } --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ 5eda48228ef2 Fri Jun 11 10:20:14 2010 +0200 @@ -0,0 +1,141 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Contributor(s): + * + * Portions Copyrighted 2010 Sun Microsystems, Inc. + */ + +package org.netbeans.modules.j2ee.weblogic9.config; + +import java.io.File; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import java.util.logging.Logger; +import javax.enterprise.deploy.spi.status.ProgressObject; +import org.netbeans.modules.j2ee.deployment.common.api.ConfigurationException; +import org.netbeans.modules.j2ee.deployment.plugins.api.ServerLibrary; +import org.netbeans.modules.j2ee.deployment.plugins.api.ServerLibraryDependency; +import org.netbeans.modules.j2ee.deployment.plugins.spi.ServerLibraryFactory; +import org.netbeans.modules.j2ee.deployment.plugins.spi.ServerLibraryManager; +import org.netbeans.modules.j2ee.weblogic9.ProgressObjectSupport; +import org.netbeans.modules.j2ee.weblogic9.WLDeploymentFactory; +import org.netbeans.modules.j2ee.weblogic9.WLPluginProperties; +import org.netbeans.modules.j2ee.weblogic9.deploy.WLCommandDeployer; +import org.netbeans.modules.j2ee.weblogic9.deploy.WLDeploymentManager; +import org.openide.util.NbBundle; + +/** + * + * @author Petr Hejl + */ +public class WLServerLibraryManager implements ServerLibraryManager { + + private static final Logger LOGGER = Logger.getLogger(WLServerLibraryManager.class.getName()); + + private final WLDeploymentManager manager; + + private final WLServerLibrarySupport support; + + public WLServerLibraryManager(WLDeploymentManager manager) { + this.manager = manager; + String domainDir = manager.getInstanceProperties().getProperty(WLPluginProperties.DOMAIN_ROOT_ATTR); + assert domainDir != null; + String serverDir = manager.getInstanceProperties().getProperty(WLPluginProperties.SERVER_ROOT_ATTR); + assert serverDir != null; + this.support = new WLServerLibrarySupport(new File(serverDir), new File(domainDir)); + } + + @Override + public void deployLibraries(Set libraries) throws ConfigurationException { + Set notHandled = new HashSet(libraries); + Set deployed = getDeployedLibraries(); + + for (ServerLibraryDependency range : libraries) { + for (ServerLibrary lib : deployed) { + if (range.versionMatches(lib)) { + notHandled.remove(range); + break; + } + } + } + + Set toDeploy = new HashSet(); + Map deployable = support.getDeployableFiles(); + for (Iterator it = notHandled.iterator(); it.hasNext(); ) { + ServerLibraryDependency range = it.next(); + for (Map.Entry entry : deployable.entrySet()) { + if (range.versionMatches(entry.getKey())) { + it.remove(); + toDeploy.add(entry.getValue()); + break; + } + } + } + + if (!notHandled.isEmpty()) { + throw new ConfigurationException(NbBundle.getMessage(WLServerLibraryManager.class, "MSG_DidNotFindServerLibraries")); + } + + deployFiles(toDeploy); + } + + // this handles only archives + @Override + public Set getDeployableLibraries() { + return support.getDeployableFiles().keySet(); + } + + @Override + public Set getDeployedLibraries() { + Set result = new HashSet(); + for (WLServerLibrarySupport.WLServerLibrary lib : support.getDeployedLibraries()) { + result.add(ServerLibraryFactory.createServerLibrary(lib)); + } + return result; + } + + private void deployFiles(Set libraries) throws ConfigurationException { + WLCommandDeployer deployer = new WLCommandDeployer(WLDeploymentFactory.getInstance(), + manager.getInstanceProperties()); + ProgressObject po = deployer.deployLibraries(libraries); + ProgressObjectSupport.waitFor(po); + if (po.getDeploymentStatus().isFailed()) { + String msg = NbBundle.getMessage(WLDatasourceManager.class, "MSG_FailedToDeployLibrary"); + throw new ConfigurationException(msg); + } + } +} --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ 5eda48228ef2 Fri Jun 11 10:20:14 2010 +0200 @@ -0,0 +1,502 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Contributor(s): + * + * Portions Copyrighted 2010 Sun Microsystems, Inc. + */ + +package org.netbeans.modules.j2ee.weblogic9.config; + +import java.beans.PropertyVetoException; +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FilenameFilter; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.jar.Attributes; +import java.util.jar.Manifest; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.enterprise.deploy.spi.exceptions.ConfigurationException; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; +import org.netbeans.api.annotations.common.CheckForNull; +import org.netbeans.modules.j2ee.deployment.common.api.Version; +import org.netbeans.modules.j2ee.deployment.plugins.api.ServerLibrary; +import org.netbeans.modules.j2ee.deployment.plugins.api.ServerLibraryDependency; +import org.netbeans.modules.j2ee.deployment.plugins.spi.ServerLibraryFactory; +import org.netbeans.modules.j2ee.deployment.plugins.spi.ServerLibraryImplementation; +import org.openide.filesystems.FileObject; +import org.openide.filesystems.FileUtil; +import org.openide.filesystems.JarFileSystem; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.DefaultHandler; + +/** + * + * @author Petr Hejl + */ +public class WLServerLibrarySupport { + + private static final Logger LOGGER = Logger.getLogger(WLServerLibrarySupport.class.getName()); + + private static final FilenameFilter LIBRARY_FILTER = new FilenameFilter() { + + @Override + public boolean accept(File dir, String name) { + return name.endsWith(".jar") // NOI18N + || name.endsWith(".war") // NOI18N + || name.endsWith(".ear"); // NOI18N + } + }; + + private static final FilenameFilter JAR_FILTER = new FilenameFilter() { + + @Override + public boolean accept(File dir, String name) { + return name.endsWith(".jar"); // NOI18N + } + }; + + private final File domainPath; + + private final File serverRoot; + + public WLServerLibrarySupport(File serverRoot, File domainPath) { + this.domainPath = domainPath; + this.serverRoot = serverRoot; + } + + public File[] getClasspathEntries(Set libraries) throws ConfigurationException { + Set deployed = getDeployedLibraries(); + Set classpath = new HashSet(); + + for (ServerLibraryDependency range : libraries) { + for (WLServerLibrary lib : deployed) { + // optimize + if (range.versionMatches(ServerLibraryFactory.createServerLibrary(lib))) { + classpath.add((WLServerLibrary) lib); + break; + } + } + } + + // TODO deployable files + + List result = new ArrayList(); + // XXX optimize collection of libs on same server and/or same name + for (WLServerLibrary lib : classpath) { + String server = lib.getServer(); + // XXX is this path always the same ?? + File tmpPath = new File(domainPath, "servers" + File.separator + server + File.separator + "tmp" // NOI18N + + File.separator + "_WL_user" + File.separator + lib.getName()); // NOI18N + if (tmpPath.exists() && tmpPath.isDirectory()) { + File[] subDirs = tmpPath.listFiles(); + if (subDirs != null) { + for (File subdir : subDirs) { + WLServerLibrary parsed = readFromFile(subdir); + if (parsed != null) { + if (sameLibraries(lib, parsed)) { + // FIXME other libs ? + File webInfLib = new File(subdir, "WEB-INF" + File.separator + "lib"); // NOI18N + if (webInfLib.exists() && webInfLib.isDirectory()) { + File[] children = webInfLib.listFiles(JAR_FILTER); + if (children != null) { + result.addAll(Arrays.asList(children)); + } + } + } + } + } + } + } + } + + return result.toArray(new File[result.size()]); + } + + Set getDeployedLibraries() { + FileObject domain = FileUtil.toFileObject(domainPath); + FileObject domainConfig = null; + if (domain != null) { + domainConfig = domain.getFileObject("config/config.xml"); // NOI18N + } + if (domainConfig == null) { + return Collections.emptySet(); + } + + try { + SAXParserFactory factory = SAXParserFactory.newInstance(); + SAXParser parser = factory.newSAXParser(); + LibraryHandler handler = new LibraryHandler(domainPath); + parser.parse(new BufferedInputStream(domainConfig.getInputStream()), handler); + + Set libs = new HashSet(); + for (Library library : handler.getLibraries()) { + File file = library.resolveFile(); + WLServerLibrary parsed = readFromFile(file); + if (parsed != null) { + // checking the version - maybe we can avoid it + if (parsed.getSpecificationVersion() != library.getSpecificationVersion() + && (parsed.getSpecificationVersion() == null + || !parsed.getSpecificationVersion().equals(library.getSpecificationVersion()))) { + LOGGER.log(Level.INFO, "Inconsistent specification version for {0}", library.getName()); + } else if (parsed.getImplementationVersion() != library.getImplementationVersion() + && (parsed.getImplementationVersion() == null + || !parsed.getImplementationVersion().equals(library.getImplementationVersion()))) { + LOGGER.log(Level.INFO, "Inconsistent implementation version for {0}", library.getName()); + } else { + libs.add(new WLServerLibrary( + parsed.getSpecificationTitle(), parsed.getSpecificationVersion(), + parsed.getImplementationTitle(), parsed.getImplementationVersion(), + library.getTarget(), library.getName())); + } + } else { + LOGGER.log(Level.INFO, "Source path does not exists for {0}", library.getName()); + // XXX we use name as spec title + libs.add(new WLServerLibrary( + null, library.getSpecificationVersion(), + null, library.getImplementationVersion(), library.getTarget(), library.getName())); + } + } + + return libs; + } catch (IOException ex) { + return Collections.emptySet(); + } catch (ParserConfigurationException ex) { + return Collections.emptySet(); + } catch (SAXException ex) { + return Collections.emptySet(); + } + } + + Map getDeployableFiles() { + File libPath = FileUtil.normalizeFile(new File(serverRoot, + "common" + File.separator + "deployable-libraries")); // NOI18N + if (!libPath.exists() || !libPath.isDirectory()) { + return Collections.emptyMap(); + } + + Map res = new HashMap(); + for (File file : libPath.listFiles(LIBRARY_FILTER)) { + WLServerLibrary lib = readFromFile(file); + if (lib != null) { + res.put(ServerLibraryFactory.createServerLibrary(lib), file); + } + } + return res; + } + + // consider implementation of equals in WLServerLibrary + private static boolean sameLibraries(WLServerLibrary first, WLServerLibrary second) { + if ((first.specTitle == null) ? (second.specTitle != null) : !first.specTitle.equals(second.specTitle)) { + return false; + } + if (first.specVersion != second.specVersion + && (first.specVersion == null || !first.specVersion.equals(second.specVersion))) { + return false; + } + if ((first.implTitle == null) ? (second.implTitle != null) : !first.implTitle.equals(second.implTitle)) { + return false; + } + if (first.implVersion != second.implVersion + && (first.implVersion == null || !first.implVersion.equals(second.implVersion))) { + return false; + } + if ((first.name == null) ? (second.name != null) : !first.name.equals(second.name)) { + return false; + } + return true; + } + + private static WLServerLibrary readFromFile(File file) { + if (file == null || !file.exists() || !file.canRead()) { + return null; + } + + Attributes attributes = null; + + if (file.isDirectory()) { + File manifestFile = new File(file, "META-INF" + File.separator + "MANIFEST.MF"); + if (manifestFile.exists() && manifestFile.isFile()) { + Manifest manifest = new Manifest(); + try { + InputStream is = new BufferedInputStream(new FileInputStream(manifestFile)); + try { + manifest.read(is); + attributes = manifest.getMainAttributes(); + } finally { + is.close(); + } + } catch (IOException ex) { + LOGGER.log(Level.INFO, null, ex); + } + } + } else { + try { + JarFileSystem jar = new JarFileSystem(); + jar.setJarFile(file); + attributes = jar.getManifest().getMainAttributes(); + } catch (IOException ex) { + LOGGER.log(Level.INFO, null, ex); + } catch (PropertyVetoException ex) { + LOGGER.log(Level.INFO, null, ex); + } + } + + if (attributes == null) { + return null; + } + + String specVersionValue = attributes.getValue("Specification-Version"); // NOI18N + String implVersionValue = attributes.getValue("Implementation-Version"); // NOI18N + String specTitle = attributes.getValue("Specification-Title"); // NOI18N + String implTitle = attributes.getValue("Implementation-Title"); // NOI18N + String name = attributes.getValue("Extension-Name"); // NOI18N + + Version specVersion = specVersionValue == null + ? null + : Version.fromJsr277NotationWithFallback(specVersionValue); + Version implVersion = implVersionValue == null + ? null + : Version.fromJsr277NotationWithFallback(implVersionValue); + + return new WLServerLibrary(specTitle, specVersion, implTitle, implVersion, null, name); + } + + static class WLServerLibrary implements ServerLibraryImplementation { + + private final String specTitle; + + private final Version specVersion; + + private final String implTitle; + + private final Version implVersion; + + private final String server; + + private final String name; + + public WLServerLibrary(String specTitle, Version specVersion, + String implTitle, Version implVersion, String server, String name) { + this.specTitle = specTitle; + this.specVersion = specVersion; + this.implTitle = implTitle; + this.implVersion = implVersion; + this.server = server; + this.name = name; + } + + @Override + public String getSpecificationTitle() { + return specTitle; + } + + @Override + public Version getSpecificationVersion() { + return specVersion; + } + + @Override + public String getImplementationTitle() { + return implTitle; + } + + @Override + public Version getImplementationVersion() { + return implVersion; + } + + @Override + public String getName() { + return name; + } + + public String getServer() { + return server; + } + } + + private static class LibraryHandler extends DefaultHandler { + + private final List libraries = new ArrayList(); + + private final File domainDir; + + private Library library; + + private String value; + + public LibraryHandler(File domainDir) { + this.domainDir = domainDir; + } + + @Override + public void startElement(String uri, String localName, String qName, org.xml.sax.Attributes attributes) throws SAXException { + value = null; + if ("library".equals(qName)) { // NOI18N + library = new Library(domainDir); + } + } + + @Override + public void endElement(String uri, String localName, String qName) { + if (library == null) { + return; + } + + if ("library".equals(qName)) { // NOI18N + libraries.add(library); + library = null; + } else if("name".equals(qName)) { // NOI18N + String[] splitted = value.split("#"); // NOI18N + if (splitted.length > 1) { + library.setName(splitted[0]); + splitted = splitted[1].split("@"); // NOI18N + library.setSpecificationVersion(Version.fromJsr277NotationWithFallback(splitted[0])); + if (splitted.length > 1) { + library.setImplementationVersion(Version.fromJsr277NotationWithFallback(splitted[1])); + } + } else { + library.setName(value); + } + } else if ("target".equals(qName)) { // NOI18N + library.setTarget(value); + } else if ("source-path".equals(qName)) { // NOI18N + library.setFile(value); + } + } + + @Override + public void characters(char[] ch, int start, int length) { + value = new String(ch, start, length); + } + + public List getLibraries() { + return libraries; + } + } + + private static class Library { + + private final File baseFile; + + private String name; + + private Version specVersion; + + private Version implVersion; + + private String file; + + private String target; + + public Library(File baseFile) { + this.baseFile = baseFile; + } + + @CheckForNull + public File resolveFile() { + if (file == null) { + return null; + } + + File config = new File(file); + if (!config.isAbsolute()) { + if (baseFile != null) { + config = new File(baseFile, file); + } else { + return null; + } + } + if (config.exists() && config.isFile() && config.canRead()) { + return config; + } + return null; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Version getSpecificationVersion() { + return specVersion; + } + + public void setSpecificationVersion(Version specVersion) { + this.specVersion = specVersion; + } + + public Version getImplementationVersion() { + return implVersion; + } + + public void setImplementationVersion(Version implVersion) { + this.implVersion = implVersion; + } + + public String getTarget() { + return target; + } + + public void setTarget(String target) { + this.target = target; + } + + public String getFile() { + return file; + } + + public void setFile(String file) { + this.file = file; + } + + } +} --- a/j2ee.weblogic9/src/org/netbeans/modules/j2ee/weblogic9/config/WarDeploymentConfiguration.java Fri May 28 12:20:35 2010 +0200 +++ a/j2ee.weblogic9/src/org/netbeans/modules/j2ee/weblogic9/config/WarDeploymentConfiguration.java Fri Jun 11 10:20:14 2010 +0200 @@ -51,13 +51,22 @@ import java.io.File; import java.io.IOException; import java.io.OutputStream; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; +import javax.swing.event.ChangeListener; import javax.swing.text.BadLocationException; import javax.swing.text.StyledDocument; +import org.netbeans.api.annotations.common.NonNull; import org.netbeans.modules.j2ee.deployment.common.api.ConfigurationException; +import org.netbeans.modules.j2ee.deployment.common.api.Version; import org.netbeans.modules.j2ee.deployment.devmodules.api.J2eeModule; +import org.netbeans.modules.j2ee.deployment.plugins.api.ServerLibraryDependency; import org.netbeans.modules.j2ee.deployment.plugins.spi.config.ContextRootConfiguration; import org.netbeans.modules.j2ee.deployment.plugins.spi.config.DeploymentPlanConfiguration; import org.netbeans.modules.j2ee.deployment.plugins.spi.config.ModuleConfiguration; +import org.netbeans.modules.j2ee.deployment.plugins.spi.config.ServerLibraryConfiguration; +import org.netbeans.modules.j2ee.weblogic9.config.gen.LibraryRefType; import org.netbeans.modules.j2ee.weblogic9.config.gen.WeblogicWebApp; import org.netbeans.modules.schema2beans.AttrProp; import org.netbeans.modules.schema2beans.BaseBean; @@ -65,13 +74,19 @@ import org.openide.NotifyDescriptor; import org.openide.cookies.EditorCookie; import org.openide.cookies.SaveCookie; +import org.openide.filesystems.FileAttributeEvent; +import org.openide.filesystems.FileChangeListener; +import org.openide.filesystems.FileEvent; +import org.openide.filesystems.FileRenameEvent; import org.openide.filesystems.FileUtil; import org.openide.loaders.DataObject; import org.openide.loaders.DataObjectNotFoundException; import org.openide.text.NbDocument; +import org.openide.util.ChangeSupport; import org.openide.util.Exceptions; import org.openide.util.Lookup; import org.openide.util.NbBundle; +import org.openide.util.Parameters; import org.openide.util.lookup.Lookups; /** @@ -81,12 +96,23 @@ * @author sherold */ public class WarDeploymentConfiguration extends WLDeploymentConfiguration - implements ModuleConfiguration, ContextRootConfiguration, DeploymentPlanConfiguration, PropertyChangeListener { - + implements ServerLibraryConfiguration, ModuleConfiguration, + ContextRootConfiguration, DeploymentPlanConfiguration, PropertyChangeListener { + + + private final ChangeSupport serverLibraryChangeSupport = new ChangeSupport(this); + private final File file; + private final J2eeModule j2eeModule; + private final DataObject dataObject; + + private final FileChangeListener weblogicXmlListener = new WeblogicXmlListener(); + private WeblogicWebApp webLogicWebApp; + + private Set originalDeps; /** * Creates a new instance of WarDeploymentConfiguration @@ -95,6 +121,8 @@ super(j2eeModule); this.j2eeModule = j2eeModule; file = j2eeModule.getDeploymentConfigurationFile("WEB-INF/weblogic.xml"); // NOI18N + FileUtil.addFileChangeListener(weblogicXmlListener, file); + getWeblogicWebApp(); DataObject dataObject = null; try { @@ -106,7 +134,6 @@ this.dataObject = dataObject; } - public Lookup getLookup() { return Lookups.fixed(this); } @@ -141,7 +168,7 @@ * * @return WeblogicWebApp graph or null if the weblogic.xml file is not parseable. */ - public synchronized WeblogicWebApp getWeblogicWebApp() { + public final synchronized WeblogicWebApp getWeblogicWebApp() { if (webLogicWebApp == null) { try { if (file.exists()) { @@ -328,10 +355,168 @@ } }); } - - + + @Override + public void configureLibrary(@NonNull final ServerLibraryDependency library) throws ConfigurationException { + assert library != null; + + modifyWeblogicWebApp(new WeblogicWebAppModifier() { + public void modify(WeblogicWebApp webLogicWebApp) { + for (LibraryRefType libRef : webLogicWebApp.getLibraryRef()) { + ServerLibraryDependency lib = getServerLibraryRange(libRef); + if (library.equals(lib)) { + return; + } + } + + setServerLibraryRange(webLogicWebApp, library); + } + }); + } + + @Override + public Set getLibraries() throws ConfigurationException { + WeblogicWebApp webLogicWebApp = getWeblogicWebApp(); + if (webLogicWebApp == null) { // graph not parseable + String msg = NbBundle.getMessage(WarDeploymentConfiguration.class, "MSG_CannotReadServerLibraries", file.getPath()); + throw new ConfigurationException(msg); + } + + Set ranges = new HashSet(); + for (LibraryRefType libRef : webLogicWebApp.getLibraryRef()) { + ranges.add(getServerLibraryRange(libRef)); + } + + return ranges; + } + + @Override + public void addLibraryChangeListener(@NonNull ChangeListener listener) { + Parameters.notNull("listener", listener); + + boolean load = false; + synchronized (this) { + load = originalDeps == null; + } + if (load) { + Set deps = null; + try { + deps = getLibraries(); + } catch(ConfigurationException ex) { + deps = Collections.emptySet(); + } + synchronized (this) { + if (originalDeps == null) { + originalDeps = deps; + } + } + } + + serverLibraryChangeSupport.addChangeListener(listener); + } + + @Override + public void removeLibraryChangeListener(@NonNull ChangeListener listener) { + Parameters.notNull("listener", listener); + serverLibraryChangeSupport.removeChangeListener(listener); + } + + private void fireChange() { + Set oldDeps = null; + synchronized (this) { + if (originalDeps == null) { + // nobody is listening + return; + } + oldDeps = new HashSet(originalDeps); + } + + Set deps = new HashSet(); + try { + deps.addAll(getLibraries()); + } catch (ConfigurationException ex) { + // noop - empty set + } + boolean fire = false; + for (ServerLibraryDependency old : oldDeps) { + if (!deps.remove(old)) { + fire = true; + break; + } + } + if (!deps.isEmpty()) { + fire = true; + } + if (fire) { + serverLibraryChangeSupport.fireChange(); + } + } + + private ServerLibraryDependency getServerLibraryRange(LibraryRefType libRef) { + String name = libRef.getLibraryName(); + String specVersionString = libRef.getSpecificationVersion(); + String implVersionString = libRef.getImplementationVersion(); + boolean exactMatch = libRef.isExactMatch(); + + Version spec = specVersionString == null ? null : Version.fromJsr277NotationWithFallback(specVersionString); + Version impl = implVersionString == null ? null : Version.fromJsr277NotationWithFallback(implVersionString); + if (exactMatch) { + return ServerLibraryDependency.exactVersion(name, spec, impl); + } else { + return ServerLibraryDependency.minimalVersion(name, spec, impl); + } + } + + private void setServerLibraryRange(WeblogicWebApp webApp, ServerLibraryDependency library) { + LibraryRefType libRef = new LibraryRefType(); + libRef.setLibraryName(library.getName()); + if (library.isExactMatch()) { + libRef.setExactMatch(true); + } + if (library.getSpecificationVersion() != null) { + libRef.setSpecificationVersion(library.getSpecificationVersion().toString()); + } + if (library.getImplementationVersion() != null) { + libRef.setImplementationVersion(library.getImplementationVersion().toString()); + } + webApp.setLibraryRef(new LibraryRefType[] {libRef}); + } + // private helper interface ----------------------------------------------- - + + private class WeblogicXmlListener implements FileChangeListener { + + @Override + public void fileFolderCreated(FileEvent fe) { + // noop + } + + @Override + public void fileDataCreated(FileEvent fe) { + fireChange(); + } + + @Override + public void fileChanged(FileEvent fe) { + fireChange(); + } + + @Override + public void fileDeleted(FileEvent fe) { + fireChange(); + } + + @Override + public void fileRenamed(FileRenameEvent fe) { + fireChange(); + } + + @Override + public void fileAttributeChanged(FileAttributeEvent fe) { + // noop + } + } + private interface WeblogicWebAppModifier { void modify(WeblogicWebApp context); } --- a/j2ee.weblogic9/src/org/netbeans/modules/j2ee/weblogic9/deploy/Bundle.properties Fri May 28 12:20:35 2010 +0200 +++ a/j2ee.weblogic9/src/org/netbeans/modules/j2ee/weblogic9/deploy/Bundle.properties Fri Jun 11 10:20:14 2010 +0200 @@ -89,3 +89,10 @@ MSG_Datasource_Failed_Interrupted=Datasource deployment failed. The deployment was interrupted. MSG_Datasource_Failed=Datasource deployment failed. Check the configured credentials. MSG_Datasource_Completed=Datasource deployment completed. + +MSG_Library_Started=Library deployment started. +MSG_Library_Failed=Library deployment failed. Check the configured credentials. +MSG_Library_Completed=Library deployment completed. +MSG_Library_Failed_With_Message=Library deployment failed. Message was: {0} +MSG_Library_Failed_Timeout=Library deployment failed. The timeout expired. +MSG_Library_Failed_Interrupted=Library deployment failed. The deployment was interrupted. --- a/j2ee.weblogic9/src/org/netbeans/modules/j2ee/weblogic9/deploy/WLCommandDeployer.java Fri May 28 12:20:35 2010 +0200 +++ a/j2ee.weblogic9/src/org/netbeans/modules/j2ee/weblogic9/deploy/WLCommandDeployer.java Fri Jun 11 10:20:14 2010 +0200 @@ -51,6 +51,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; +import java.util.Set; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; @@ -81,6 +82,7 @@ import org.netbeans.modules.j2ee.dd.api.application.DDProvider; import org.netbeans.modules.j2ee.dd.api.application.Module; import org.netbeans.modules.j2ee.deployment.plugins.api.InstanceProperties; +import org.netbeans.modules.j2ee.deployment.plugins.api.ServerLibrary; import org.netbeans.modules.j2ee.weblogic9.URLWait; import org.netbeans.modules.j2ee.weblogic9.WLDeploymentFactory; import org.netbeans.modules.j2ee.weblogic9.WLPluginProperties; @@ -442,6 +444,67 @@ return progress; } + public ProgressObject deployLibraries(final Set libraries) { + final WLProgressObject progress = new WLProgressObject(new TargetModuleID[0]); + + progress.fireProgressEvent(null, new WLDeploymentStatus( + ActionType.EXECUTE, CommandType.DISTRIBUTE, StateType.RUNNING, + NbBundle.getMessage(WLCommandDeployer.class, "MSG_Library_Started"))); + + factory.getExecutorService().submit(new Runnable() { + + @Override + public void run() { + boolean failed = false; + for (File library : libraries) { + ExecutionService service = createService("-deploy", null, + "-library" , library.getAbsolutePath()); // NOI18N + Future result = service.run(); + try { + Integer value = result.get(TIMEOUT, TimeUnit.MILLISECONDS); + if (value.intValue() != 0) { + failed = true; + progress.fireProgressEvent(null, new WLDeploymentStatus( + ActionType.EXECUTE, CommandType.DISTRIBUTE, StateType.FAILED, + NbBundle.getMessage(WLCommandDeployer.class, "MSG_Library_Failed"))); + break; + } else { + continue; + } + } catch (InterruptedException ex) { + failed = true; + progress.fireProgressEvent(null, new WLDeploymentStatus( + ActionType.EXECUTE, CommandType.DISTRIBUTE, StateType.FAILED, + NbBundle.getMessage(WLCommandDeployer.class, "MSG_Library_Failed_Interrupted"))); + result.cancel(true); + Thread.currentThread().interrupt(); + break; + } catch (TimeoutException ex) { + failed = true; + progress.fireProgressEvent(null, new WLDeploymentStatus( + ActionType.EXECUTE, CommandType.DISTRIBUTE, StateType.FAILED, + NbBundle.getMessage(WLCommandDeployer.class, "MSG_Library_Failed_Timeout"))); + result.cancel(true); + break; + } catch (ExecutionException ex) { + failed = true; + progress.fireProgressEvent(null, new WLDeploymentStatus( + ActionType.EXECUTE, CommandType.DISTRIBUTE, StateType.FAILED, + NbBundle.getMessage(WLCommandDeployer.class, "MSG_Library_Failed_With_Message"))); + break; + } + } + if (!failed) { + progress.fireProgressEvent(null, new WLDeploymentStatus( + ActionType.EXECUTE, CommandType.START, StateType.COMPLETED, + NbBundle.getMessage(WLCommandDeployer.class, "MSG_Library_Completed"))); + } + } + }); + + return progress; + } + public TargetModuleID[] getAvailableModules(ModuleType moduleType, Target[] target) { assert !SwingUtilities.isEventDispatchThread() : "Should not be executed in EDT"; --- a/j2ee.weblogic9/src/org/netbeans/modules/j2ee/weblogic9/j2ee/WLJ2eePlatformFactory.java Fri May 28 12:20:35 2010 +0200 +++ a/j2ee.weblogic9/src/org/netbeans/modules/j2ee/weblogic9/j2ee/WLJ2eePlatformFactory.java Fri Jun 11 10:20:14 2010 +0200 @@ -60,8 +60,10 @@ import java.util.logging.Level; import java.util.logging.Logger; import javax.enterprise.deploy.spi.DeploymentManager; +import javax.enterprise.deploy.spi.exceptions.ConfigurationException; import org.netbeans.api.j2ee.core.Profile; import org.netbeans.modules.j2ee.deployment.devmodules.api.J2eeModule.Type; +import org.netbeans.modules.j2ee.deployment.plugins.api.ServerLibraryDependency; import org.netbeans.modules.j2ee.deployment.plugins.spi.support.LookupProviderSupport; import org.openide.modules.InstalledFileLocator; import org.netbeans.api.java.platform.JavaPlatform; @@ -72,7 +74,7 @@ import org.netbeans.modules.j2ee.deployment.plugins.spi.J2eePlatformImpl; import org.netbeans.modules.j2ee.weblogic9.deploy.WLDeploymentManager; import org.netbeans.modules.j2ee.weblogic9.WLPluginProperties; -import org.netbeans.modules.j2ee.weblogic9.WLProductProperties; +import org.netbeans.modules.j2ee.weblogic9.config.WLServerLibrarySupport; import org.netbeans.spi.project.libraries.LibraryImplementation; import org.openide.filesystems.FileObject; import org.openide.filesystems.FileUtil; @@ -108,8 +110,7 @@ } private final Set PROFILES = new HashSet(); - -// private String platformRoot = WLPluginProperties.getInstance().getInstallLocation(); + private String platformRoot; private LibraryImplementation[] libraries = null; @@ -183,7 +184,14 @@ } public java.io.File[] getPlatformRoots() { - return new File[]{new File(getPlatformRoot())}; + File server = new File(getPlatformRoot()); + File domain = new File(dm.getInstanceProperties().getProperty( + WLPluginProperties.DOMAIN_ROOT_ATTR)); + + assert server.isAbsolute(); + assert domain.isAbsolute(); + + return new File[] {server, domain}; } public LibraryImplementation[] getLibraries() { @@ -192,6 +200,22 @@ } return libraries; } + + @Override + public File[] getClasspathEntries(Set libraries) { + String domainDir = dm.getInstanceProperties().getProperty(WLPluginProperties.DOMAIN_ROOT_ATTR); + assert domainDir != null; + String serverDir = dm.getInstanceProperties().getProperty(WLPluginProperties.SERVER_ROOT_ATTR); + assert serverDir != null; + WLServerLibrarySupport support = new WLServerLibrarySupport(new File(serverDir), new File(domainDir)); + + try { + return support.getClasspathEntries(libraries); + } catch (ConfigurationException ex) { + LOGGER.log(Level.INFO, null, ex); + return new File[] {}; + } + } private void initLibraries() { @@ -345,9 +369,9 @@ } private String getPlatformRoot() { - if (platformRoot == null) + if (platformRoot == null) { platformRoot = dm.getInstanceProperties().getProperty(WLPluginProperties.SERVER_ROOT_ATTR); - + } return platformRoot; } --- a/j2ee.weblogic9/src/org/netbeans/modules/j2ee/weblogic9/optional/WLOptionalDeploymentManagerFactory.java Fri May 28 12:20:35 2010 +0200 +++ a/j2ee.weblogic9/src/org/netbeans/modules/j2ee/weblogic9/optional/WLOptionalDeploymentManagerFactory.java Fri Jun 11 10:20:14 2010 +0200 @@ -51,9 +51,11 @@ import org.netbeans.modules.j2ee.deployment.plugins.spi.JDBCDriverDeployer; import org.netbeans.modules.j2ee.deployment.plugins.spi.OptionalDeploymentManagerFactory; import org.netbeans.modules.j2ee.deployment.plugins.spi.ServerInstanceDescriptor; +import org.netbeans.modules.j2ee.deployment.plugins.spi.ServerLibraryManager; import org.netbeans.modules.j2ee.deployment.plugins.spi.StartServer; import org.netbeans.modules.j2ee.weblogic9.WLDeploymentFactory; import org.netbeans.modules.j2ee.weblogic9.config.WLDatasourceManager; +import org.netbeans.modules.j2ee.weblogic9.config.WLServerLibraryManager; import org.netbeans.modules.j2ee.weblogic9.deploy.WLDeploymentManager; import org.netbeans.modules.j2ee.weblogic9.deploy.WLDriverDeployer; import org.netbeans.modules.j2ee.weblogic9.ui.wizard.WLInstantiatingIterator; @@ -138,6 +140,11 @@ return new WLServerInstanceDescriptor((WLDeploymentManager) dm); } + @Override + public ServerLibraryManager getServerLibraryManager(DeploymentManager dm) { + return new WLServerLibraryManager((WLDeploymentManager) dm); + } + private static class WLServerInstanceDescriptor implements ServerInstanceDescriptor { private final String host; --- a/j2ee.weblogic9/src/org/netbeans/modules/j2ee/weblogic9/ui/wizard/ServerLocationVisual.java Fri May 28 12:20:35 2010 +0200 +++ a/j2ee.weblogic9/src/org/netbeans/modules/j2ee/weblogic9/ui/wizard/ServerLocationVisual.java Fri Jun 11 10:20:14 2010 +0200 @@ -61,6 +61,7 @@ import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import javax.swing.filechooser.FileFilter; +import org.netbeans.modules.j2ee.deployment.common.api.Version; import org.netbeans.modules.j2ee.weblogic9.WLPluginProperties; import org.openide.WizardDescriptor; import org.openide.util.NbBundle; @@ -107,7 +108,7 @@ } File serverRoot = new File(location); - WLPluginProperties.Version version = WLPluginProperties.getVersion(serverRoot); + Version version = WLPluginProperties.getVersion(serverRoot); if (!WLPluginProperties.isSupportedVersion(version)) { String msg = NbBundle.getMessage(ServerLocationVisual.class, "ERR_INVALID_SERVER_VERSION"); // NOI18N --- a/j2eeserver/apichanges.xml Fri May 28 12:20:35 2010 +0200 +++ a/j2eeserver/apichanges.xml Fri Jun 11 10:20:14 2010 +0200 @@ -116,6 +116,34 @@ + +

+ Implemented support for handling the server libraries. + + + + + + +

+ Implemented both SPI and API to provide support for server + libraries management. +

+
+ + + + + + + + + + + + + + --- a/j2eeserver/nbproject/project.properties Fri May 28 12:20:35 2010 +0200 +++ a/j2eeserver/nbproject/project.properties Fri Jun 11 10:20:14 2010 +0200 @@ -42,7 +42,7 @@ is.autoload=true javac.source=1.6 -spec.version.base=1.67.0 +spec.version.base=1.68.0 javadoc.arch=${basedir}/arch.xml javadoc.apichanges=${basedir}/apichanges.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ 5eda48228ef2 Fri Jun 11 10:20:14 2010 +0200 @@ -0,0 +1,299 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Contributor(s): + * + * Portions Copyrighted 2010 Sun Microsystems, Inc. + */ + +package org.netbeans.modules.j2ee.deployment.common.api; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import org.netbeans.api.annotations.common.CheckForNull; +import org.netbeans.api.annotations.common.NonNull; +import org.openide.util.Parameters; + +/** + * Represents the generic version. Useful for libraries, products etc. + *

+ * This class is Immutable. + * + * @author Petr Hejl + * @since 1.68 + */ +// TODO add JBoss notation parsing MAJOR.MINOR.MICRO.QUALIFIER +public final class Version { + + private static final Pattern JSR277_PATTERN = Pattern.compile( + "(\\d+)(\\.(\\d+)(\\.(\\d+)(\\.(\\d+))?)?)?(-((\\w|-)+))?"); + + private final String version; + + private final Integer majorNumber; + + private final Integer minorNumber; + + private final Integer microNumber; + + private final Integer updateNumber; + + private final String qualifier; + + private Version(String version, Integer majorNumber, Integer minorNumber, + Integer microNumber, Integer updateNumber, String qualifier) { + this.version = version; + this.majorNumber = majorNumber; + this.minorNumber = minorNumber; + this.microNumber = microNumber; + this.updateNumber = updateNumber; + this.qualifier = qualifier; + } + + /** + * Creates the version from the spec version string. + * Expected format is MAJOR_NUMBER[.MINOR_NUMBER[.MICRO_NUMBER[.UPDATE_NUMBER]]][-QUALIFIER] + * or GENERIC_VERSION_STRING. + * + * @param version spec version string with the following format: + * MAJOR_NUMBER[.MINOR_NUMBER[.MICRO_NUMBER[.UPDATE_NUMBER]]][-QUALIFIER] + * or GENERIC_VERSION_STRING + */ + public static @NonNull Version fromJsr277NotationWithFallback(@NonNull String version) { + Parameters.notNull("version", version); + + Matcher matcher = JSR277_PATTERN.matcher(version); + if (matcher.matches()) { + String fragment = matcher.group(1); + Integer majorNumber = fragment != null ? Integer.valueOf(fragment) : null; + fragment = matcher.group(3); + Integer minorNumber = fragment != null ? Integer.valueOf(fragment) : null; + fragment = matcher.group(5); + Integer microNumber = fragment != null ? Integer.valueOf(fragment) : null; + fragment = matcher.group(7); + Integer updateNumber = fragment != null ? Integer.valueOf(fragment) : null; + String qualifier = matcher.group(9); + + return new Version(version, majorNumber, minorNumber, + microNumber, updateNumber, qualifier); + } else { + return new Version(version, null, null, null, null, null); + } + } + + /** + * Returns the major number. May return null. + * + * @return the major number; may return null + */ + @CheckForNull + public Integer getMajor() { + return majorNumber; + } + + /** + * Returns the minor number. May return null. + * + * @return the minor number; may return null + */ + @CheckForNull + public Integer getMinor() { + return minorNumber; + } + + /** + * Returns the micro number. May return null. + * + * @return the micro number; may return null + */ + @CheckForNull + public Integer getMicro() { + return microNumber; + } + + /** + * Returns the update. May return null. + * + * @return the update; may return null + */ + @CheckForNull + public Integer getUpdate() { + return updateNumber; + } + + /** + * Returns the qualifier. May return null. + * + * @return the qualifier; may return null + */ + @CheckForNull + public String getQualifier() { + return qualifier; + } + + /** + * {@inheritDoc} + *

+ * Two versions are equal if and only if they have same major, minor, + * micro, update number and qualifier. If the version does not conform to + * notation the versions are equal only if the version strings exactly + * matches. + */ + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final Version other = (Version) obj; + + // non conform + if ((this.majorNumber == null && other.majorNumber != null) + || (this.majorNumber != null && other.majorNumber == null)) { + return false; + } else if (this.majorNumber == null && other.majorNumber == null) { + return this.version.equals(other.version); + } + + // standard + if (this.majorNumber != other.majorNumber && (this.majorNumber == null || !this.majorNumber.equals(other.majorNumber))) { + return false; + } + if (this.minorNumber != other.minorNumber && (this.minorNumber == null || !this.minorNumber.equals(other.minorNumber))) { + return false; + } + if (this.microNumber != other.microNumber && (this.microNumber == null || !this.microNumber.equals(other.microNumber))) { + return false; + } + if (this.updateNumber != other.updateNumber && (this.updateNumber == null || !this.updateNumber.equals(other.updateNumber))) { + return false; + } + if ((this.qualifier == null) ? (other.qualifier != null) : !this.qualifier.equals(other.qualifier)) { + return false; + } + return true; + } + + /** + * {@inheritDoc} + *

+ * The implementation consistent with {@link #equals(Object)}. + */ + @Override + public int hashCode() { + // non conform + if (this.majorNumber == null) { + return this.version.hashCode(); + } + + // standard + int hash = 7; + hash = 97 * hash + (this.majorNumber != null ? this.majorNumber.hashCode() : 0); + hash = 97 * hash + (this.minorNumber != null ? this.minorNumber.hashCode() : 0); + hash = 97 * hash + (this.microNumber != null ? this.microNumber.hashCode() : 0); + hash = 97 * hash + (this.updateNumber != null ? this.updateNumber.hashCode() : 0); + hash = 97 * hash + (this.qualifier != null ? this.qualifier.hashCode() : 0); + return hash; + } + + public boolean isAboveOrEqual(Version other) { + if (this.majorNumber == null || other.majorNumber == null) { + return this.equals(other); + } + + return compareTo(other) >= 0; + } + + public boolean isBelowOrEqual(Version other) { + if (this.majorNumber == null || other.majorNumber == null) { + return this.equals(other); + } + + return compareTo(other) <= 0; + } + + @Override + public String toString() { + return version; + } + + private int compareTo(Version o) { + int comparison = compare(majorNumber, o.majorNumber); + if (comparison != 0) { + return comparison; + } + comparison = compare(minorNumber, o.minorNumber); + if (comparison != 0) { + return comparison; + } + comparison = compare(microNumber, o.microNumber); + if (comparison != 0) { + return comparison; + } + comparison = compare(updateNumber, o.updateNumber); + if (comparison != 0) { + return comparison; + } + return compare(qualifier, o.qualifier); + } + + private static int compare(Integer o1, Integer o2) { + if (o1 == null && o2 == null) { + return 0; + } + if (o1 == null) { + return Integer.valueOf(0).compareTo(o2); + } + if (o2 == null) { + return o1.compareTo(Integer.valueOf(0)); + } + return o1.compareTo(o2); + } + + private static int compare(String o1, String o2) { + if (o1 == null && o2 == null) { + return 0; + } + if (o1 == null) { + return "".compareTo(o2); + } + if (o2 == null) { + return o1.compareTo(""); + } + return o1.compareTo(o2); + } + +} --- a/j2eeserver/src/org/netbeans/modules/j2ee/deployment/config/ConfigSupportImpl.java Fri May 28 12:20:35 2010 +0200 +++ a/j2eeserver/src/org/netbeans/modules/j2ee/deployment/config/ConfigSupportImpl.java Fri Jun 11 10:20:14 2010 +0200 @@ -56,6 +56,9 @@ import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; +import javax.swing.event.ChangeListener; +import org.netbeans.api.annotations.common.CheckForNull; +import org.netbeans.api.annotations.common.NonNull; import org.netbeans.modules.j2ee.deployment.common.api.OriginalCMPMapping; import org.netbeans.modules.j2ee.deployment.devmodules.api.J2eeApplication; import org.netbeans.modules.j2ee.deployment.devmodules.spi.J2eeModuleProvider; @@ -66,6 +69,7 @@ import org.netbeans.modules.j2ee.deployment.impl.ServerRegistry; import org.netbeans.modules.j2ee.deployment.common.api.Datasource; import org.netbeans.modules.j2ee.deployment.common.api.DatasourceAlreadyExistsException; +import org.netbeans.modules.j2ee.deployment.plugins.api.ServerLibraryDependency; import org.netbeans.modules.j2ee.deployment.plugins.spi.config.ContextRootConfiguration; import org.netbeans.modules.j2ee.deployment.plugins.spi.config.DatasourceConfiguration; import org.netbeans.modules.j2ee.deployment.plugins.spi.config.DeploymentPlanConfiguration; @@ -84,6 +88,7 @@ import org.netbeans.modules.j2ee.deployment.common.api.MessageDestination; import org.netbeans.modules.j2ee.deployment.execution.ModuleConfigurationProvider; import org.netbeans.modules.j2ee.deployment.plugins.spi.config.MessageDestinationConfiguration; +import org.netbeans.modules.j2ee.deployment.plugins.spi.config.ServerLibraryConfiguration; import org.openide.util.Mutex.Action; import org.openide.util.Parameters; @@ -334,7 +339,42 @@ mappingConfiguration.setCMPResource(ejbName, jndiName); } } - + + @Override + public void configureLibrary(@NonNull ServerLibraryDependency library) throws ConfigurationException { + ServerLibraryConfiguration libraryConfiguration = getServerLibraryConfiguration(); + if (libraryConfiguration != null) { + libraryConfiguration.configureLibrary(library); + } + } + + @Override + public Set getLibraries() throws ConfigurationException { + Set libs = Collections.emptySet(); + + ServerLibraryConfiguration libraryConfiguration = getServerLibraryConfiguration(); + if (libraryConfiguration != null) { + libs = libraryConfiguration.getLibraries(); + } + return libs; + } + + @Override + public void addLibraryChangeListener(ChangeListener listener) { + ServerLibraryConfiguration libraryConfiguration = getServerLibraryConfiguration(); + if (libraryConfiguration != null) { + libraryConfiguration.addLibraryChangeListener(listener); + } + } + + @Override + public void removeLibraryChangeListener(ChangeListener listener) { + ServerLibraryConfiguration libraryConfiguration = getServerLibraryConfiguration(); + if (libraryConfiguration != null) { + libraryConfiguration.removeLibraryChangeListener(listener); + } + } + public Set getDatasources() throws ConfigurationException { Set projectDS = Collections.emptySet(); @@ -761,6 +801,17 @@ // private helpers -------------------------------------------------------- + @CheckForNull + private ServerLibraryConfiguration getServerLibraryConfiguration() { + if (server != null) { + ModuleConfiguration config = getModuleConfiguration(); + if (config != null) { + return config.getLookup().lookup(ServerLibraryConfiguration.class); + } + } + return null; + } + /** * Return list of server specific configuration files. */ --- a/j2eeserver/src/org/netbeans/modules/j2ee/deployment/devmodules/api/Deployment.java Fri May 28 12:20:35 2010 +0200 +++ a/j2eeserver/src/org/netbeans/modules/j2ee/deployment/devmodules/api/Deployment.java Fri Jun 11 10:20:14 2010 +0200 @@ -166,6 +166,7 @@ server.getServerInstance().start(progress); } + DeploymentHelper.deployServerLibraries(jmp); DeploymentHelper.deployDatasources(jmp); DeploymentHelper.deployMessageDestinations(jmp); --- a/j2eeserver/src/org/netbeans/modules/j2ee/deployment/devmodules/api/J2eePlatform.java Fri May 28 12:20:35 2010 +0200 +++ a/j2eeserver/src/org/netbeans/modules/j2ee/deployment/devmodules/api/J2eePlatform.java Fri Jun 11 10:20:14 2010 +0200 @@ -71,6 +71,8 @@ import org.netbeans.modules.j2ee.deployment.common.api.J2eeLibraryTypeProvider; import org.netbeans.modules.j2ee.deployment.config.J2eeModuleAccessor; import org.netbeans.modules.j2ee.deployment.impl.sharability.ServerLibraryTypeProvider; +import org.netbeans.modules.j2ee.deployment.plugins.api.ServerLibrary; +import org.netbeans.modules.j2ee.deployment.plugins.api.ServerLibraryDependency; import org.netbeans.spi.project.libraries.LibraryImplementation; import org.netbeans.spi.project.libraries.support.LibrariesSupport; import org.openide.filesystems.FileObject; @@ -311,6 +313,10 @@ return classpathCache; } + public File[] getClasspathEntries(Set libraries) { + return impl.getClasspathEntries(libraries); + } + /** * Return classpath for the specified tool. Use the tool constants declared * in this class. @@ -817,7 +823,7 @@ private String getClasspathAsString() { File[] classpathEntr = getClasspathEntries(); - StringBuffer classpath = new StringBuffer(); + StringBuilder classpath = new StringBuilder(); final String PATH_SEPARATOR = System.getProperty("path.separator"); // NOI18N for (int i = 0; i < classpathEntr.length; i++) { classpath.append(classpathEntr[i].getAbsolutePath()); --- a/j2eeserver/src/org/netbeans/modules/j2ee/deployment/devmodules/api/ServerInstance.java Fri May 28 12:20:35 2010 +0200 +++ a/j2eeserver/src/org/netbeans/modules/j2ee/deployment/devmodules/api/ServerInstance.java Fri Jun 11 10:20:14 2010 +0200 @@ -42,9 +42,10 @@ package org.netbeans.modules.j2ee.deployment.devmodules.api; -import java.io.IOException; +import java.util.Set; +import org.netbeans.api.annotations.common.NonNull; import org.netbeans.modules.j2ee.deployment.impl.ServerRegistry; -import org.netbeans.modules.j2ee.deployment.impl.TargetServer; +import org.netbeans.modules.j2ee.deployment.plugins.api.ServerLibrary; import org.netbeans.modules.j2ee.deployment.plugins.spi.IncrementalDeployment; /** @@ -200,6 +201,26 @@ return null; } + /** + * Returns manager providing the access to server libraries. May + * return null if the server does not support this. + * + * @return manager providing the access to server libraries or null + * @throws InstanceRemovedException if the instance is not available anymore + * @since 1.68 + */ + public LibraryManager getLibraryManager() throws InstanceRemovedException { + final ServerRegistry registry = ServerRegistry.getInstance(); + // see comment at the beginning of the class + synchronized (registry) { + org.netbeans.modules.j2ee.deployment.impl.ServerInstance inst = getInstanceFromRegistry(registry); + if (inst.isServerLibraryManagementSupported()) { + return new LibraryManager(); + } + } + return null; + } + private org.netbeans.modules.j2ee.deployment.impl.ServerInstance getInstanceFromRegistry(ServerRegistry registry) throws InstanceRemovedException { @@ -251,4 +272,33 @@ return getInstanceFromRegistry(ServerRegistry.getInstance()).getServerInstanceDescriptor().isLocal(); } } + + /** + * The manager providing the access to server libraries. + * + * @since 1.68 + */ + public final class LibraryManager { + + /** + * Returns the set of libraries the server has access to and can be deployed + * on request (by call to {@link #deployRequiredLibraries(java.util.Set)}. + * + * @return the set of libraries which can be deployed on server + */ + @NonNull + public Set getDeployableLibraries() throws InstanceRemovedException { + return getInstanceFromRegistry(ServerRegistry.getInstance()).getDeployableLibraries(); + } + + /** + * Returns the set of libraries already deployed to the server. + * + * @return the set of libraries already deployed to the server + */ + @NonNull + public Set getDeployedLibraries() throws InstanceRemovedException { + return getInstanceFromRegistry(ServerRegistry.getInstance()).getDeployedLibraries(); + } + } } --- a/j2eeserver/src/org/netbeans/modules/j2ee/deployment/devmodules/spi/J2eeModuleProvider.java Fri May 28 12:20:35 2010 +0200 +++ a/j2eeserver/src/org/netbeans/modules/j2ee/deployment/devmodules/spi/J2eeModuleProvider.java Fri Jun 11 10:20:14 2010 +0200 @@ -75,9 +75,12 @@ import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; +import javax.swing.event.ChangeListener; import org.netbeans.api.annotations.common.CheckForNull; +import org.netbeans.api.annotations.common.NonNull; import org.netbeans.modules.j2ee.deployment.common.api.MessageDestination; import org.netbeans.modules.j2ee.deployment.impl.projects.J2eeModuleProviderAccessor; +import org.netbeans.modules.j2ee.deployment.plugins.api.ServerLibraryDependency; /** This object must be implemented by J2EE module support and an instance * added into project lookup. @@ -181,7 +184,7 @@ } return si.getStartServer().getDebugInfo(target); } - + /** * Gets the data sources deployed on the target server instance. * @@ -300,6 +303,7 @@ * The setters and getters work with server specific data on the server returned by * {@link #getServerID} method. */ + // FIXME replace this with final class - this is not deigned to be implemented by anybody public static interface ConfigSupport { /** * Create an initial fresh configuration for the current module. Do nothing if configuration already exists. @@ -485,6 +489,37 @@ public Datasource findDatasource(String jndiName) throws ConfigurationException; /** + * Configure the library (dependency) the enterprise module needs in order + * to work properly. + *

+ * Once library is configured it should be present in the result + * of the {@link #getRequiredLibraries()} call. + * + * @param library the library the enterprise module needs in order to work + * properly + * @throws ConfigurationException if there was a problem writing + * configuration + * @since 1.68 + */ + public void configureLibrary(@NonNull ServerLibraryDependency library) throws ConfigurationException; + + /** + * Returns the server library dependencies the enterprise module needs + * to work properly. + * + * @return the server library dependencies + * @throws ConfigurationException if there was a problem reading + * configuration + * @since 1.68 + */ + @NonNull + public Set getLibraries() throws ConfigurationException; + + void addLibraryChangeListener(@NonNull ChangeListener listener); + + void removeLibraryChangeListener(@NonNull ChangeListener listener); + + /** * Retrieves message destinations stored in the module. * * @return set of message destinations --- a/j2eeserver/src/org/netbeans/modules/j2ee/deployment/impl/DeployOnSaveManager.java Fri May 28 12:20:35 2010 +0200 +++ a/j2eeserver/src/org/netbeans/modules/j2ee/deployment/impl/DeployOnSaveManager.java Fri Jun 11 10:20:14 2010 +0200 @@ -392,6 +392,7 @@ "MSG_DeployOnSave", provider.getDeploymentName()), false); ui.start(Integer.valueOf(PROGRESS_DELAY)); try { + DeploymentHelper.deployServerLibraries(provider); DeploymentHelper.deployDatasources(provider); DeploymentHelper.deployMessageDestinations(provider); --- a/j2eeserver/src/org/netbeans/modules/j2ee/deployment/impl/DeploymentHelper.java Fri May 28 12:20:35 2010 +0200 +++ a/j2eeserver/src/org/netbeans/modules/j2ee/deployment/impl/DeploymentHelper.java Fri Jun 11 10:20:14 2010 +0200 @@ -52,6 +52,7 @@ import org.netbeans.modules.j2ee.deployment.common.api.DatasourceAlreadyExistsException; import org.netbeans.modules.j2ee.deployment.devmodules.spi.J2eeModuleProvider; import org.netbeans.modules.j2ee.deployment.impl.ui.ProgressUI; +import org.netbeans.modules.j2ee.deployment.plugins.api.ServerLibraryDependency; import org.netbeans.modules.j2ee.deployment.plugins.spi.JDBCDriverDeployer; /** @@ -114,4 +115,15 @@ "The data sources cannot be deployed because the server instance cannot be found."); } } + + public static void deployServerLibraries(J2eeModuleProvider jmp) throws ConfigurationException { + ServerInstance si = ServerRegistry.getInstance ().getServerInstance (jmp.getServerInstanceID ()); + if (si != null) { + Set libraries = jmp.getConfigSupport().getLibraries(); + si.deployLibraries(libraries); + } else { + LOGGER.log(Level.WARNING, + "The libraries cannot be deployed because the server instance cannot be found."); + } + } } --- a/j2eeserver/src/org/netbeans/modules/j2ee/deployment/impl/ServerInstance.java Fri May 28 12:20:35 2010 +0200 +++ a/j2eeserver/src/org/netbeans/modules/j2ee/deployment/impl/ServerInstance.java Fri Jun 11 10:20:14 2010 +0200 @@ -47,6 +47,7 @@ import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; +import java.io.File; import java.net.InetAddress; import java.net.NetworkInterface; import java.net.SocketException; @@ -78,6 +79,8 @@ import org.netbeans.modules.j2ee.deployment.plugins.api.InstanceProperties; import org.netbeans.modules.j2ee.deployment.plugins.spi.J2eePlatformImpl; import org.netbeans.modules.j2ee.deployment.plugins.api.ServerDebugInfo; +import org.netbeans.modules.j2ee.deployment.plugins.api.ServerLibrary; +import org.netbeans.modules.j2ee.deployment.plugins.api.ServerLibraryDependency; import org.netbeans.modules.j2ee.deployment.plugins.spi.StartServer; import org.netbeans.modules.j2ee.deployment.plugins.spi.TargetModuleIDResolver; import org.netbeans.modules.j2ee.deployment.plugins.api.UISupport; @@ -88,6 +91,7 @@ import org.netbeans.modules.j2ee.deployment.plugins.spi.J2eePlatformFactory; import org.netbeans.modules.j2ee.deployment.plugins.spi.MessageDestinationDeployment; import org.netbeans.modules.j2ee.deployment.plugins.spi.ServerInstanceDescriptor; +import org.netbeans.modules.j2ee.deployment.plugins.spi.ServerLibraryManager; import org.netbeans.modules.j2ee.deployment.profiler.api.ProfilerServerSettings; import org.netbeans.modules.j2ee.deployment.profiler.api.ProfilerSupport; import org.netbeans.modules.j2ee.deployment.profiler.spi.Profiler; @@ -145,6 +149,8 @@ private J2eePlatformImpl j2eePlatformImpl; private StartServer startServer; private FindJSPServlet findJSPServlet; + private ServerLibraryManager libraryManager; + private ServerLibraryManager disconnectedLibraryManager; private DatasourceManager dsMgr; private DatasourceManager ddsMgr; private MessageDestinationDeployment msgDestDeploymentConnected; @@ -685,7 +691,32 @@ return ddsMgr; } } - + + private ServerLibraryManager getServerLibraryManager() { + DeploymentManager dm = getDeploymentManager(); + synchronized (this) { + if (libraryManager == null) { + libraryManager = server.getOptionalFactory().getServerLibraryManager(dm); + } + return libraryManager; + } + } + + private ServerLibraryManager getDisconnectedServerLibraryManager() { + DeploymentManager dm = null; + try { + dm = getDisconnectedDeploymentManager(); + } catch (DeploymentManagerCreationException dmce) { + throw new RuntimeException(dmce); + } + synchronized (this) { + if (disconnectedLibraryManager == null) { + disconnectedLibraryManager = server.getOptionalFactory().getServerLibraryManager(dm); + } + return disconnectedLibraryManager; + } + } + /** * Gets the data sources deployed on the this server instance. * @@ -716,7 +747,41 @@ if (dsMgr != null) dsMgr.deployDatasources(datasources); } - + + public boolean isServerLibraryManagementSupported() { + return getDisconnectedServerLibraryManager() != null; + } + + public Set getDeployableLibraries() { + ServerLibraryManager libraryManager = getDisconnectedServerLibraryManager(); + + Set libraries = Collections.emptySet(); + if (libraryManager != null) { + libraries = libraryManager.getDeployableLibraries(); + } + + return libraries; + } + + public Set getDeployedLibraries() { + ServerLibraryManager libraryManager = getDisconnectedServerLibraryManager(); + + Set libraries = Collections.emptySet(); + if (libraryManager != null) { + libraries = libraryManager.getDeployedLibraries(); + } + + return libraries; + } + + public void deployLibraries(Set libraries) throws ConfigurationException { + ServerLibraryManager libraryManager = getServerLibraryManager(); + + if (libraryManager != null) { + libraryManager.deployLibraries(libraries); + } + } + private synchronized MessageDestinationDeployment getMessageDestinationDeploymentConnected() { if (msgDestDeploymentConnected == null) { msgDestDeploymentConnected = server.getOptionalFactory(). --- a/j2eeserver/src/org/netbeans/modules/j2ee/deployment/impl/TargetServer.java Fri May 28 12:20:35 2010 +0200 +++ a/j2eeserver/src/org/netbeans/modules/j2ee/deployment/impl/TargetServer.java Fri Jun 11 10:20:14 2010 +0200 @@ -784,7 +784,10 @@ } try { + // FIXME libraries stored in server specific descriptor + // do not match server resources if (serverResources) { + DeploymentHelper.deployServerLibraries(provider); DeploymentHelper.deployDatasources(provider); DeploymentHelper.deployMessageDestinations(provider); } --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ 5eda48228ef2 Fri Jun 11 10:20:14 2010 +0200 @@ -0,0 +1,138 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Contributor(s): + * + * Portions Copyrighted 2010 Sun Microsystems, Inc. + */ + +package org.netbeans.modules.j2ee.deployment.plugins.api; + +import java.io.File; +import org.netbeans.api.annotations.common.CheckForNull; +import org.netbeans.api.annotations.common.NonNull; +import org.netbeans.modules.j2ee.deployment.common.api.Version; +import org.netbeans.modules.j2ee.deployment.plugins.spi.ServerLibraryFactory; +import org.netbeans.modules.j2ee.deployment.plugins.spi.ServerLibraryImplementation; + +/** + * The representation of the server library. This means the library server + * manages not the jars deployed along with the application. + * + * @since 1.68 + * @author Petr Hejl + */ +public final class ServerLibrary { + + static { + ServerLibraryFactory.Accessor.DEFAULT = new ServerLibraryFactory.Accessor() { + + @Override + public ServerLibrary createServerLibrary(ServerLibraryImplementation impl) { + return new ServerLibrary(impl); + } + }; + } + + private final ServerLibraryImplementation impl; + + private ServerLibrary(@NonNull ServerLibraryImplementation impl) { + this.impl = impl; + } + + /** + * Returns the specification title of the library. May return + * null. + *

+ *

+ * For example specification title for JSF would be JavaServer Faces. + *
+ * + * @return the specification title of the library; may return null + */ + @CheckForNull + public String getSpecificationTitle() { + return impl.getSpecificationTitle(); + } + + /** + * Returns the specification version of the library. May return + * null. + * + * @return the specification version of the library; may return null + */ + @CheckForNull + public Version getSpecificationVersion() { + return impl.getSpecificationVersion(); + } + + /** + * Returns the implementation title of the library. May return + * null. + *

+ *

+ * For example specification title for MyFaces implementation of JSF + * this would be something like MyFaces. + *
+ * + * @return the implementation title of the library; may return null + */ + @CheckForNull + public String getImplementationTitle() { + return impl.getImplementationTitle(); + } + + /** + * Returns the implementation version of the library. May return + * null. + * + * @return the implementation version of the library; may return null + */ + @CheckForNull + public Version getImplementationVersion() { + return impl.getImplementationVersion(); + } + + /** + * Returns the library name. May return null. + * + * @return the library name; may return null + */ + @CheckForNull + public String getName() { + return impl.getName(); + } + + // TODO should we implement equals and hashCode ? +} --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ 5eda48228ef2 Fri Jun 11 10:20:14 2010 +0200 @@ -0,0 +1,232 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Contributor(s): + * + * Portions Copyrighted 2010 Sun Microsystems, Inc. + */ + +package org.netbeans.modules.j2ee.deployment.plugins.api; + +import org.netbeans.api.annotations.common.CheckForNull; +import org.netbeans.api.annotations.common.NonNull; +import org.netbeans.api.annotations.common.NullAllowed; +import org.netbeans.modules.j2ee.deployment.common.api.Version; +import org.openide.util.Parameters; + +/** + * Represents the library dependency. For example library version required by + * the enterprise module. + * + * @since 1.68 + * @author Petr Hejl + */ +public final class ServerLibraryDependency { + + private final String name; + + private final Version specificationVersion; + + private final Version implementationVersion; + + private boolean exactMatch; + + private ServerLibraryDependency(String name, Version specificationVersion, + Version implementationVersion, boolean exactMatch) { + this.name = name; + this.specificationVersion = specificationVersion; + this.implementationVersion = implementationVersion; + this.exactMatch = exactMatch; + } + + /** + * Creates the library dependency which specifies the minimal specification + * and implementation version. + *

+ * When both specification and implementation version is null + * it has the meaning of any version. + * + * @param name name of the library + * @param specificationVersion the minimal specification version, may be null + * @param implementationVersion the minimal implementation version, may be null + * @return the library dependency which specifies the minimal specification + * and implementation version + */ + public static ServerLibraryDependency minimalVersion(@NonNull String name, + @NullAllowed Version specificationVersion, @NullAllowed Version implementationVersion) { + + Parameters.notNull("name", name); + + return new ServerLibraryDependency(name, specificationVersion, implementationVersion, false); + } + + /** + * Creates the library dependency which specifies the exact specification and + * implementation version. + * + * @param name name of the library + * @param specificationVersion the minimal specification version, may be null + * @param implementationVersion the minimal implementation version, may be null + * @return the library dependency which specifies the exact specification + * and implementation version + */ + public static ServerLibraryDependency exactVersion(@NonNull String name, + @NullAllowed Version specificationVersion, @NullAllowed Version implementationVersion) { + + Parameters.notNull("name", name); + Parameters.notNull("specificationVersion", name); + + return new ServerLibraryDependency(name, specificationVersion, implementationVersion, true); + } + + /** + * Returns true if the given library matches the dependency. + *

+ * The library matches the dependency if the dependency specify the minimal + * versions (specification and/or implementation) and corresponding versions + * of the library are equal or greater. If the dependency specify the exact + * version the corresponding versions of library must be the same as those + * specified for dependency. + * + * @param library the library to check + * @return true if the given library matches the dependency + * @see Version#isAboveOrEqual(org.netbeans.modules.j2ee.deployment.common.api.Version) + * @see Version#isBelowOrEqual(org.netbeans.modules.j2ee.deployment.common.api.Version) + */ + public boolean versionMatches(@NonNull ServerLibrary library) { + Parameters.notNull("library", library); + + if (exactMatch) { + return (library.getName() != null && library.getName().equals(name)) + && (specificationVersion == null + || specificationVersion.equals(library.getSpecificationVersion())) + && (implementationVersion == null + || implementationVersion.equals(library.getImplementationVersion())); + } + + return (library.getName() != null && library.getName().equals(name)) + && (specificationVersion == null + || (library.getSpecificationVersion() != null && specificationVersion.isBelowOrEqual(library.getSpecificationVersion()))) + && (implementationVersion == null + || (library.getImplementationVersion() != null && implementationVersion.isBelowOrEqual(library.getImplementationVersion()))); + } + + /** + * Returns the name of the required library. + * + * @return the name of the required library + */ + @NonNull + public String getName() { + return name; + } + + /** + * Returns the specification version. May be null. + * + * @return the specification version; may be null + */ + @CheckForNull + public Version getSpecificationVersion() { + return specificationVersion; + } + + /** + * Returns the implementation version. May be null. + * + * @return the implementation version; may be null + */ + @CheckForNull + public Version getImplementationVersion() { + return implementationVersion; + } + + /** + * Returns true if the exactly the same version are required + * by the dependency to match the library. + * + * @return true if the exactly the same version are required + * by the dependency to match the library + */ + public boolean isExactMatch() { + return exactMatch; + } + + /** + * @{@inheritDoc} + * + * Dependencies are equal if they have the same name, specification version, + * implementation version and exact match flag. + */ + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final ServerLibraryDependency other = (ServerLibraryDependency) obj; + if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) { + return false; + } + if (this.specificationVersion != other.specificationVersion && (this.specificationVersion == null || !this.specificationVersion.equals(other.specificationVersion))) { + return false; + } + if (this.implementationVersion != other.implementationVersion && (this.implementationVersion == null || !this.implementationVersion.equals(other.implementationVersion))) { + return false; + } + if (this.exactMatch != other.exactMatch) { + return false; + } + return true; + } + + /** + * @{@inheritDoc} + *

+ * Implementation consistent with {@link #equals(java.lang.Object)}. + * @see #equals(java.lang.Object) + */ + @Override + public int hashCode() { + int hash = 5; + hash = 53 * hash + (this.name != null ? this.name.hashCode() : 0); + hash = 53 * hash + (this.specificationVersion != null ? this.specificationVersion.hashCode() : 0); + hash = 53 * hash + (this.implementationVersion != null ? this.implementationVersion.hashCode() : 0); + hash = 53 * hash + (this.exactMatch ? 1 : 0); + return hash; + } + +} --- a/j2eeserver/src/org/netbeans/modules/j2ee/deployment/plugins/spi/J2eePlatformImpl.java Fri May 28 12:20:35 2010 +0200 +++ a/j2eeserver/src/org/netbeans/modules/j2ee/deployment/plugins/spi/J2eePlatformImpl.java Fri Jun 11 10:20:14 2010 +0200 @@ -56,6 +56,7 @@ import org.netbeans.modules.j2ee.deployment.config.J2eeModuleAccessor; import org.netbeans.modules.j2ee.deployment.devmodules.api.J2eeModule; import org.netbeans.api.j2ee.core.Profile; +import org.netbeans.modules.j2ee.deployment.plugins.api.ServerLibraryDependency; import org.netbeans.spi.project.libraries.LibraryImplementation; import org.openide.util.Lookup; @@ -84,7 +85,11 @@ * @return platform's libraries. */ public abstract LibraryImplementation[] getLibraries(); - + + public File[] getClasspathEntries(Set libraries) { + return new File[] {}; + } + /** * Return platform's display name. * --- a/j2eeserver/src/org/netbeans/modules/j2ee/deployment/plugins/spi/OptionalDeploymentManagerFactory.java Fri May 28 12:20:35 2010 +0200 +++ a/j2eeserver/src/org/netbeans/modules/j2ee/deployment/plugins/spi/OptionalDeploymentManagerFactory.java Fri Jun 11 10:20:14 2010 +0200 @@ -46,6 +46,7 @@ package org.netbeans.modules.j2ee.deployment.plugins.spi; import javax.enterprise.deploy.spi.DeploymentManager; +import org.netbeans.api.annotations.common.CheckForNull; import org.openide.WizardDescriptor; /** @@ -179,4 +180,17 @@ public void finishServerInitialization() throws ServerInitializationException { } + /** + * Return the manager handling the server libraries. May return + * null if the functionality is not supported by the plugin. + * + * @param dm the deployment manager + * @return the manager handling the server libraries + * @since 1.68 + * @see ServerLibraryManager + */ + @CheckForNull + public ServerLibraryManager getServerLibraryManager(DeploymentManager dm) { + return null; + } } --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ 5eda48228ef2 Fri Jun 11 10:20:14 2010 +0200 @@ -0,0 +1,97 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Contributor(s): + * + * Portions Copyrighted 2008 Sun Microsystems, Inc. + */ + +package org.netbeans.modules.j2ee.deployment.plugins.spi; + +import org.netbeans.modules.j2ee.deployment.plugins.api.ServerLibrary; + +/** + * Factory creating the API representation of the library provided in SPI. + * + * @since 1.68 + * @author Petr Hejl + */ +public final class ServerLibraryFactory { + + private ServerLibraryFactory() { + super(); + } + + /** + * Creates the API representation of the provided SPI instance. + * + * @param impl the SPI instance + * @return the API server instance representation + */ + public static ServerLibrary createServerLibrary(ServerLibraryImplementation impl) { + return Accessor.DEFAULT.createServerLibrary(impl); + } + + /** + * The accessor pattern class. + */ + public abstract static class Accessor { + + /** The default accessor. */ + public static Accessor DEFAULT; + + static { + // invokes static initializer of ServerLibrary.class + // that will assign value to the DEFAULT field above + Class c = ServerLibrary.class; + try { + Class.forName(c.getName(), true, c.getClassLoader()); + } catch (ClassNotFoundException ex) { + assert false : ex; + } + } + + /** + * Creates the API instance. + * + * @param impl the SPI instance + * @return the API instance + */ + public abstract ServerLibrary createServerLibrary(ServerLibraryImplementation impl); + + } +} --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ 5eda48228ef2 Fri Jun 11 10:20:14 2010 +0200 @@ -0,0 +1,107 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Contributor(s): + * + * Portions Copyrighted 2010 Sun Microsystems, Inc. + */ + +package org.netbeans.modules.j2ee.deployment.plugins.spi; + +import java.io.File; +import org.netbeans.api.annotations.common.CheckForNull; +import org.netbeans.modules.j2ee.deployment.common.api.Version; + +/** + * The representation of the server library. This means the library server + * manages not the jars deployed along with the application. + * + * @since 1.68 + * @author Petr Hejl + */ +public interface ServerLibraryImplementation { + + /** + * Returns the specification title of the library. May return + * null. + *

+ *

+ * For example specification title for JSF would be JavaServer Faces. + *
+ * + * @return the specification title of the library; may return null + */ + @CheckForNull + String getSpecificationTitle(); + + /** + * Returns the implementation title of the library. May return + * null. + *

+ *

+ * For example specification title for MyFaces implementation of JSF + * this would be something like MyFaces. + *
+ * + * @return the implementation title of the library; may return null + */ + @CheckForNull + String getImplementationTitle(); + + /** + * Returns the specification version of the library. May return + * null. + * + * @return the specification version of the library; may return null + */ + @CheckForNull + Version getSpecificationVersion(); + + /** + * Returns the implementation version of the library. May return + * null. + * + * @return the implementation version of the library; may return null + */ + @CheckForNull + Version getImplementationVersion(); + + /** + * Returns the library name. May return null. + * + * @return the library name; may return null + */ + @CheckForNull + String getName(); +} --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ 5eda48228ef2 Fri Jun 11 10:20:14 2010 +0200 @@ -0,0 +1,87 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Contributor(s): + * + * Portions Copyrighted 2010 Sun Microsystems, Inc. + */ + +package org.netbeans.modules.j2ee.deployment.plugins.spi; + +import java.io.File; +import java.util.Set; +import org.netbeans.api.annotations.common.NonNull; +import org.netbeans.modules.j2ee.deployment.common.api.ConfigurationException; +import org.netbeans.modules.j2ee.deployment.plugins.api.ServerLibrary; +import org.netbeans.modules.j2ee.deployment.plugins.api.ServerLibraryDependency; + +/** + * The interface that should serverplugin should implement in order to + * support the server library management. + * + * @since 1.68 + * @author Petr Hejl + * @see org.netbeans.modules.j2ee.deployment.plugins.spi.config.ServerLibraryConfiguration + */ +public interface ServerLibraryManager { + + /** + * Returns the set of libraries the server has access to and can be deployed + * on request (by call to {@link #deployRequiredLibraries(java.util.Set)}. + * + * @return the set of libraries which can be deployed on server + */ + @NonNull + Set getDeployableLibraries(); + + /** + * Returns the set of libraries already deployed to the server. + * + * @return the set of libraries already deployed to the server + */ + @NonNull + Set getDeployedLibraries(); + + /** + * Deploys all the required libraries passed to the method. The libraries + * passed to the method may be already deployed and it is up to implementor + * to handle such case. + * + * @param libraries the libraries to deploy + * @throws ConfigurationException if there was a problem during + * the deployment + */ + void deployLibraries(@NonNull Set libraries) throws ConfigurationException; + +} --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ 5eda48228ef2 Fri Jun 11 10:20:14 2010 +0200 @@ -0,0 +1,89 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Contributor(s): + * + * Portions Copyrighted 2010 Sun Microsystems, Inc. + */ + +package org.netbeans.modules.j2ee.deployment.plugins.spi.config; + +import java.util.Set; +import javax.swing.event.ChangeListener; +import org.netbeans.api.annotations.common.NonNull; +import org.netbeans.modules.j2ee.deployment.common.api.ConfigurationException; +import org.netbeans.modules.j2ee.deployment.plugins.api.ServerLibraryDependency; + +/** + * The interface defining the methods that can handle the server libraries in + * scope of enterprise module. + *

+ * This interface is typically looked up in {@link ModuleConfiguration}'s + * lookup. + * + * @since 1.68 + * @author Petr Hejl + */ +public interface ServerLibraryConfiguration { + + /** + * Configure the library (dependency) the enterprise module needs in order + * to work properly. + *

+ * Once library is configured it should be present in the result + * of the {@link #getRequiredLibraries()} call. + * + * @param library the library the enterprise module needs in order to work + * properly + * @throws ConfigurationException if there was a problem writing + * configuration + */ + void configureLibrary(@NonNull ServerLibraryDependency library) throws ConfigurationException; + + /** + * Returns the server library dependencies the enterprise module needs + * to work properly. + * + * @return the server library dependencies + * @throws ConfigurationException if there was a problem reading + * configuration + */ + @NonNull + Set getLibraries() throws ConfigurationException; + + void addLibraryChangeListener(@NonNull ChangeListener listener); + + void removeLibraryChangeListener(@NonNull ChangeListener listener); + +} --- a/j2eeserver/src/org/netbeans/modules/j2ee/deployment/plugins/spi/support/ProxyOptionalFactory.java Fri May 28 12:20:35 2010 +0200 +++ a/j2eeserver/src/org/netbeans/modules/j2ee/deployment/plugins/spi/support/ProxyOptionalFactory.java Fri Jun 11 10:20:14 2010 +0200 @@ -53,6 +53,7 @@ import org.netbeans.modules.j2ee.deployment.plugins.spi.OptionalDeploymentManagerFactory; import org.netbeans.modules.j2ee.deployment.plugins.spi.ServerInitializationException; import org.netbeans.modules.j2ee.deployment.plugins.spi.ServerInstanceDescriptor; +import org.netbeans.modules.j2ee.deployment.plugins.spi.ServerLibraryManager; import org.netbeans.modules.j2ee.deployment.plugins.spi.StartServer; import org.netbeans.modules.j2ee.deployment.plugins.spi.TargetModuleIDResolver; import org.openide.WizardDescriptor.InstantiatingIterator; @@ -151,6 +152,11 @@ } } + @Override + public ServerLibraryManager getServerLibraryManager(DeploymentManager dm) { + return getDelegate().getServerLibraryManager(dm); + } + private OptionalDeploymentManagerFactory getDelegate() { synchronized (this) { if (delegate != null) { --- a/web.jsf/nbproject/project.xml Fri May 28 12:20:35 2010 +0200 +++ a/web.jsf/nbproject/project.xml Fri Jun 11 10:20:14 2010 +0200 @@ -309,7 +309,7 @@ 4 - 1.21 + 1.68 --- a/web.jsf/src/org/netbeans/modules/web/jsf/JSFFrameworkProvider.java Fri May 28 12:20:35 2010 +0200 +++ a/web.jsf/src/org/netbeans/modules/web/jsf/JSFFrameworkProvider.java Fri Jun 11 10:20:14 2010 +0200 @@ -83,7 +83,12 @@ import org.netbeans.modules.j2ee.common.Util; import org.netbeans.modules.j2ee.common.dd.DDHelper; import org.netbeans.modules.j2ee.dd.api.common.InitParam; +import org.netbeans.modules.j2ee.deployment.common.api.ConfigurationException; +import org.netbeans.modules.j2ee.deployment.common.api.Version; import org.netbeans.modules.j2ee.deployment.devmodules.api.Deployment; +import org.netbeans.modules.j2ee.deployment.devmodules.spi.J2eeModuleProvider; +import org.netbeans.modules.j2ee.deployment.plugins.api.ServerLibrary; +import org.netbeans.modules.j2ee.deployment.plugins.api.ServerLibraryDependency; import org.netbeans.modules.web.api.webmodule.ExtenderController; import org.netbeans.modules.web.spi.webmodule.WebFrameworkProvider; import org.netbeans.modules.web.api.webmodule.WebModule; @@ -200,6 +205,24 @@ webInf = FileUtil.createFolder(webModule.getDocumentBase(), "WEB-INF"); //NOI18N } assert webInf != null; + + // configure server library + ServerLibrary serverLibrary = panel.getServerLibrary(); + if (serverLibrary != null) { + String implementationTitle = serverLibrary.getImplementationTitle(); + isMyFaces = implementationTitle != null && implementationTitle.contains("MyFaces"); // NOI18N + Project prj = FileOwnerQuery.getOwner(webInf); + if (prj != null) { + J2eeModuleProvider provider = prj.getLookup().lookup(J2eeModuleProvider.class); + if (provider != null) { + provider.getConfigSupport().configureLibrary( + ServerLibraryDependency.minimalVersion(serverLibrary.getName(), + serverLibrary.getSpecificationVersion(), + serverLibrary.getImplementationVersion())); + } + } + } + FileSystem fileSystem = webInf.getFileSystem(); fileSystem.runAtomicAction(new CreateFacesConfig(webModule, isMyFaces)); @@ -208,7 +231,9 @@ if (welcomeFile != null) { result.add(welcomeFile); } - } catch (IOException exception) { + } catch (IOException exception) { + LOGGER.log(Level.WARNING, "Exception during extending an web project", exception); //NOI18N + } catch (ConfigurationException exception) { LOGGER.log(Level.WARNING, "Exception during extending an web project", exception); //NOI18N } createWelcome = true; @@ -373,12 +398,17 @@ jsfLibrary = LibraryManager.getDefault().getLibrary(panel.getNewLibraryName()); } - if (jsfLibrary !=null) { + if (jsfLibrary != null) { List content = jsfLibrary.getContent("classpath"); //NOI18N isJSF20 = Util.containsClass(content, JSFUtils.JSF_2_0__API_SPECIFIC_CLASS); } else { - ClassPath classpath = ClassPath.getClassPath(webModule.getDocumentBase(), ClassPath.COMPILE); - isJSF20 = classpath.findResource(JSFUtils.JSF_2_0__API_SPECIFIC_CLASS.replace('.', '/')+".class")!=null; //NOI18N + if (panel.getLibraryType() == JSFConfigurationPanel.LibraryType.SERVER && panel.getServerLibrary() != null) { + isJSF20 = Version.fromJsr277NotationWithFallback("2.0").isBelowOrEqual( + panel.getServerLibrary().getSpecificationVersion()); + } else { + ClassPath classpath = ClassPath.getClassPath(webModule.getDocumentBase(), ClassPath.COMPILE); + isJSF20 = classpath.findResource(JSFUtils.JSF_2_0__API_SPECIFIC_CLASS.replace('.', '/')+".class")!=null; //NOI18N + } } WebApp ddRoot = DDProvider.getDefault().getDDRoot(dd); @@ -549,6 +579,7 @@ application.addViewHandler(viewHandler); } ClassPath cp = ClassPath.getClassPath(webModule.getDocumentBase(), ClassPath.COMPILE); + // FIXME icefaces on server if (panel.getLibrary()!=null && panel.getLibrary().getName().indexOf("facelets-icefaces") != -1 //NOI18N && cp != null && cp.findResource("com/icesoft/faces/facelets/D2DFaceletViewHandler.class") != null){ //NOI18N ViewHandler iceViewHandler = model.getFactory().createViewHandler(); --- a/web.jsf/src/org/netbeans/modules/web/jsf/wizards/Bundle.properties Fri May 28 12:20:35 2010 +0200 +++ a/web.jsf/src/org/netbeans/modules/web/jsf/wizards/Bundle.properties Fri Jun 11 10:20:14 2010 +0200 @@ -175,7 +175,7 @@ MSG_CreatingLibraries=When you finish this wizard, JSF Library will be added to the IDE's Library Manager. \n\\nThis library will contain the appropriate JARs from the JSF folder. HINT_Version=Write the JSF version (e.g. "1.1") LBL_INSTALL_DIR=JSF Folder\: -LBL_Any_Library=Use default library which comes with Server ({0}). +LBL_Any_Library=Server Library: HINT_JSF_Directory=Choose JSF folder. LBL_TAB_Configuration=Configuration @@ -298,4 +298,3 @@ MSG_From=from -LBL_Weblogic_Warning=Make sure JSF shared server library is deployed on the server. --- a/web.jsf/src/org/netbeans/modules/web/jsf/wizards/JSFConfigurationPanel.java Fri May 28 12:20:35 2010 +0200 +++ a/web.jsf/src/org/netbeans/modules/web/jsf/wizards/JSFConfigurationPanel.java Fri Jun 11 10:20:14 2010 +0200 @@ -55,6 +55,7 @@ import org.netbeans.api.project.Project; import org.netbeans.api.project.ProjectUtils; import org.netbeans.api.project.libraries.Library; +import org.netbeans.modules.j2ee.deployment.plugins.api.ServerLibrary; import org.netbeans.modules.web.api.webmodule.ExtenderController; import org.netbeans.modules.web.api.webmodule.WebModule; import org.netbeans.modules.web.jsf.JSFFrameworkProvider; @@ -75,9 +76,10 @@ private Preferences preferences; - public enum LibraryType {USED, NEW, NONE}; + public enum LibraryType {USED, NEW, SERVER}; private LibraryType libraryType; private Library jsfCoreLibrary; + private ServerLibrary serverLibrary; private String newLibraryName; private File installedFolder; @@ -323,6 +325,15 @@ fireChangeEvent(); } + public ServerLibrary getServerLibrary() { + return serverLibrary; + } + + protected void setServerLibrary(ServerLibrary library){ + this.serverLibrary = library; + fireChangeEvent(); + } + protected static class PreferredLanguage { private String name; --- a/web.jsf/src/org/netbeans/modules/web/jsf/wizards/JSFConfigurationPanelVisual.form Fri May 28 12:20:35 2010 +0200 +++ a/web.jsf/src/org/netbeans/modules/web/jsf/wizards/JSFConfigurationPanelVisual.form Fri Jun 11 10:20:14 2010 +0200 @@ -1,4 +1,4 @@ - +

@@ -61,28 +61,31 @@ - + - + + + + + + + + + + + - + - - + + - - - - - - - - + @@ -93,9 +96,12 @@ - - - + + + + + + @@ -111,13 +117,13 @@ - + - + @@ -130,7 +136,7 @@ - + @@ -246,6 +252,11 @@ + + + + + @@ -268,7 +279,7 @@ - + --- a/web.jsf/src/org/netbeans/modules/web/jsf/wizards/JSFConfigurationPanelVisual.java Fri May 28 12:20:35 2010 +0200 +++ a/web.jsf/src/org/netbeans/modules/web/jsf/wizards/JSFConfigurationPanelVisual.java Fri Jun 11 10:20:14 2010 +0200 @@ -50,21 +50,30 @@ import java.net.URL; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; import java.util.List; +import java.util.Set; +import java.util.SortedSet; +import java.util.TreeSet; import java.util.Vector; import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Pattern; import javax.swing.DefaultComboBoxModel; import javax.swing.JFileChooser; +import javax.swing.SwingUtilities; import javax.swing.event.DocumentListener; import org.netbeans.api.j2ee.core.Profile; import org.netbeans.api.project.libraries.Library; import org.netbeans.api.project.libraries.LibraryManager; import org.netbeans.modules.j2ee.common.Util; +import org.netbeans.modules.j2ee.deployment.common.api.Version; import org.netbeans.modules.j2ee.deployment.devmodules.api.Deployment; import org.netbeans.modules.j2ee.deployment.devmodules.api.InstanceRemovedException; import org.netbeans.modules.j2ee.deployment.devmodules.api.J2eePlatform; +import org.netbeans.modules.j2ee.deployment.devmodules.api.ServerInstance; +import org.netbeans.modules.j2ee.deployment.plugins.api.ServerLibrary; import org.netbeans.modules.web.api.webmodule.ExtenderController; import org.netbeans.modules.web.api.webmodule.ExtenderController.Properties; import org.netbeans.modules.web.jsf.JSFUtils; @@ -89,6 +98,7 @@ private boolean customizer; private final List jsfLibraries = new ArrayList(); + private final Set serverJsfLibraries = new TreeSet(); private boolean libsInitialized; private String serverInstanceID; private final List preferredLanguages = new ArrayList(); @@ -124,8 +134,12 @@ return; } - final Vector items = new Vector (); + // init server libraries first + initServerLibraries(); + + final Vector registeredItems = new Vector(); jsfLibraries.clear(); + final Runnable libraryFinder = new Runnable() { @Override @@ -140,7 +154,7 @@ if (library.getName().startsWith("facelets-") && !library.getName().endsWith("el-api") //NOI18N && !library.getName().endsWith("jsf-ri") && !library.getName().endsWith("myfaces")){ //NOI18N String displayName = library.getDisplayName(); - items.add(displayName); + registeredItems.add(displayName); //TODO XX Add correct version jsfLibraries.add(new LibraryItem(library, JSFVersion.JSF_1_2)); } @@ -148,7 +162,7 @@ content = library.getContent("classpath"); //NOI18N try { if (Util.containsClass(content, JSFUtils.FACES_EXCEPTION) && !excludeLibs.contains(library.getName())) { - items.add(library.getDisplayName()); + registeredItems.add(library.getDisplayName()); boolean isJSF12 = Util.containsClass(content, JSFUtils.JSF_1_2__API_SPECIFIC_CLASS); boolean isJSF20 = Util.containsClass(content, JSFUtils.JSF_2_0__API_SPECIFIC_CLASS); if (isJSF12 && !isJSF20) { @@ -163,8 +177,14 @@ Exceptions.printStackTrace(exception); } } - setLibraryModel(items); - updatePreferredLanguages(); + + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + setRegisteredLibraryModel(registeredItems); + updatePreferredLanguages(); + } + }); LOG.finest("Time spent in initLibraries in Runnable = "+(System.currentTimeMillis()-time) +" ms"); //NOI18N } } @@ -176,14 +196,106 @@ LOG.finest("Time spent in "+this.getClass().getName() +" initLibraries = "+(System.currentTimeMillis()-time) +" ms"); //NOI18N } - private void setLibraryModel(Vector items) { + private void initServerLibraries() { + serverJsfLibraries.clear(); + +// final Runnable libraryFinder = new Runnable() { +// +// @Override +// public void run() { + synchronized (this) { + boolean serverLib = false; + if (serverInstanceID != null && !"".equals(serverInstanceID)) { + try { + ServerInstance.LibraryManager libManager = Deployment.getDefault().getServerInstance(serverInstanceID).getLibraryManager(); + if (libManager != null) { + serverLib = true; + Set libs = new HashSet(); + libs.addAll(libManager.getDeployedLibraries()); + libs.addAll(libManager.getDeployableLibraries()); + + for (ServerLibrary lib : libs) { + // FIXME optimize + if ("JavaServer Faces".equals(lib.getSpecificationTitle())) { // NOI18N + if (Version.fromJsr277NotationWithFallback("2.0").equals(lib.getSpecificationVersion())) { // NOI18N + serverJsfLibraries.add(new ServerLibraryItem(lib, JSFVersion.JSF_2_0)); + } else if (Version.fromJsr277NotationWithFallback("1.2").equals(lib.getSpecificationVersion())) { // NOI18N + serverJsfLibraries.add(new ServerLibraryItem(lib, JSFVersion.JSF_1_2)); + } else if (Version.fromJsr277NotationWithFallback("1.1").equals(lib.getSpecificationVersion())) { // NOI18N + serverJsfLibraries.add(new ServerLibraryItem(lib, JSFVersion.JSF_1_1)); + } else { + LOG.log(Level.INFO, "Unknown JSF version {0}", lib.getSpecificationVersion()); + } + } + } + } + } catch (InstanceRemovedException ex) { + LOG.log(Level.INFO, null, ex); + // use the old way + } + } + + if (!serverLib) { + File[] cp; + J2eePlatform platform = null; + try { + if (serverInstanceID != null) { + platform = Deployment.getDefault().getServerInstance(serverInstanceID).getJ2eePlatform(); + } + } catch (InstanceRemovedException ex) { + platform = null; + LOG.log(Level.INFO, org.openide.util.NbBundle.getMessage(JSFConfigurationPanelVisual.class, "SERVER_INSTANCE_REMOVED"), ex); + } + // j2eeplatform can be null, when the target server is not accessible. + if (platform != null) { + cp = platform.getClasspathEntries(); + } else { + cp = new File[0]; + } + + try { + // XXX: there should be a utility class for this: + boolean isJSF = Util.containsClass(Arrays.asList(cp), JSFUtils.FACES_EXCEPTION); + boolean isJSF12 = Util.containsClass(Arrays.asList(cp), JSFUtils.JSF_1_2__API_SPECIFIC_CLASS); + boolean isJSF20 = Util.containsClass(Arrays.asList(cp), JSFUtils.JSF_2_0__API_SPECIFIC_CLASS); + + JSFVersion jsfVersion = null; + if (isJSF20) { + jsfVersion = JSFVersion.JSF_2_0; + } else if (isJSF12) { + jsfVersion = JSFVersion.JSF_1_2; + } else if (isJSF) { + jsfVersion = JSFVersion.JSF_1_1; + } + if (jsfVersion != null) { + serverJsfLibraries.add(new ServerLibraryItem(null, jsfVersion)); + } + } catch (IOException ex) { + Exceptions.printStackTrace(ex); + } + } + +// SwingUtilities.invokeLater(new Runnable() { +// @Override +// public void run() { + setServerLibraryModel(serverJsfLibraries); + updatePreferredLanguages(); +// } +// }); + } +// } +// }; +// RequestProcessor.getDefault().post(libraryFinder); + } + + private void setRegisteredLibraryModel(Vector items) { long time = System.currentTimeMillis(); cbLibraries.setModel(new DefaultComboBoxModel(items)); if (items.size() == 0) { rbRegisteredLibrary.setEnabled(false); cbLibraries.setEnabled(false); rbNewLibrary.setSelected(true); - panel.setLibrary(null); + panel.setLibrary((Library) null); } else if (items.size() != 0 && panel.getLibraryType() == JSFConfigurationPanel.LibraryType.USED){ if (!customizer) { rbRegisteredLibrary.setEnabled(true); @@ -199,7 +311,31 @@ repaint(); LOG.finest("Time spent in "+this.getClass().getName() +" setLibraryModel = "+(System.currentTimeMillis()-time) +" ms"); //NOI18N } - + + private void setServerLibraryModel(Collection items) { + serverLibraries.setModel(new DefaultComboBoxModel(items.toArray())); + if (items.isEmpty()) { + rbServerLibrary.setEnabled(false); + serverLibraries.setEnabled(false); + rbRegisteredLibrary.setSelected(true); + panel.setServerLibrary((ServerLibrary) null); + } else if (!items.isEmpty() && panel.getLibraryType() == JSFConfigurationPanel.LibraryType.SERVER){ + if (!customizer) { + rbServerLibrary.setEnabled(true); + serverLibraries.setEnabled(true); + } + rbServerLibrary.setSelected(true); + if (!serverJsfLibraries.isEmpty()) { + ServerLibraryItem item = (ServerLibraryItem) serverLibraries.getSelectedItem(); + if (item != null) { + panel.setServerLibrary(item.getLibrary()); + } + } + } + + repaint(); + } + /** * Init Preferred Languages check box with "JSP" and/or "Facelets" * according to choosen library @@ -217,9 +353,10 @@ if (panel.getNewLibraryName()!=null) { jsfLibrary = LibraryManager.getDefault().getLibrary(panel.getNewLibraryName()); } - } else if (panel.getLibraryType() == JSFConfigurationPanel.LibraryType.NONE) { + } else if (panel.getLibraryType() == JSFConfigurationPanel.LibraryType.SERVER) { //XXX: need to find lib version - if (rbNoneLibrary.getText().indexOf("2.0")!=-1) { + ServerLibraryItem item = (ServerLibraryItem) serverLibraries.getSelectedItem(); + if (item != null && item.getVersion() == JSFVersion.JSF_2_0) { faceletsPresent = true; } } @@ -262,7 +399,7 @@ buttonGroup1 = new javax.swing.ButtonGroup(); jsfTabbedPane = new javax.swing.JTabbedPane(); libPanel = new javax.swing.JPanel(); - rbNoneLibrary = new javax.swing.JRadioButton(); + rbServerLibrary = new javax.swing.JRadioButton(); rbRegisteredLibrary = new javax.swing.JRadioButton(); cbLibraries = new javax.swing.JComboBox(); rbNewLibrary = new javax.swing.JRadioButton(); @@ -271,6 +408,7 @@ jbBrowse = new javax.swing.JButton(); lVersion = new javax.swing.JLabel(); jtNewLibraryName = new javax.swing.JTextField(); + serverLibraries = new javax.swing.JComboBox(); confPanel = new javax.swing.JPanel(); lURLPattern = new javax.swing.JLabel(); tURLPattern = new javax.swing.JTextField(); @@ -286,13 +424,13 @@ libPanel.setAlignmentX(0.2F); libPanel.setAlignmentY(0.2F); - buttonGroup1.add(rbNoneLibrary); - rbNoneLibrary.setMnemonic(java.util.ResourceBundle.getBundle("org/netbeans/modules/web/jsf/wizards/Bundle").getString("MNE_rbNoAppend").charAt(0)); + buttonGroup1.add(rbServerLibrary); + rbServerLibrary.setMnemonic(java.util.ResourceBundle.getBundle("org/netbeans/modules/web/jsf/wizards/Bundle").getString("MNE_rbNoAppend").charAt(0)); java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("org/netbeans/modules/web/jsf/wizards/Bundle"); // NOI18N - rbNoneLibrary.setText(bundle.getString("LBL_Any_Library")); // NOI18N - rbNoneLibrary.addItemListener(new java.awt.event.ItemListener() { + rbServerLibrary.setText(bundle.getString("LBL_Any_Library")); // NOI18N + rbServerLibrary.addItemListener(new java.awt.event.ItemListener() { public void itemStateChanged(java.awt.event.ItemEvent evt) { - rbNoneLibraryItemStateChanged(evt); + rbServerLibraryItemStateChanged(evt); } }); @@ -355,6 +493,12 @@ } }); + serverLibraries.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + serverLibrariesActionPerformed(evt); + } + }); + org.jdesktop.layout.GroupLayout libPanelLayout = new org.jdesktop.layout.GroupLayout(libPanel); libPanel.setLayout(libPanelLayout); libPanelLayout.setHorizontalGroup( @@ -362,31 +506,35 @@ .add(libPanelLayout.createSequentialGroup() .addContainerGap() .add(libPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) - .add(rbNoneLibrary, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 459, Short.MAX_VALUE) - .add(libPanelLayout.createSequentialGroup() - .add(rbRegisteredLibrary) - .addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED) - .add(libPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) - .add(cbLibraries, 0, 293, Short.MAX_VALUE) - .add(org.jdesktop.layout.GroupLayout.TRAILING, libPanelLayout.createSequentialGroup() - .add(libPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING) - .add(jtNewLibraryName, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 217, Short.MAX_VALUE) - .add(jtFolder, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 217, Short.MAX_VALUE)) - .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) - .add(jbBrowse)))) - .add(org.jdesktop.layout.GroupLayout.TRAILING, rbNewLibrary, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 459, Short.MAX_VALUE) + .add(org.jdesktop.layout.GroupLayout.TRAILING, rbNewLibrary, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 466, Short.MAX_VALUE) .add(libPanelLayout.createSequentialGroup() .add(22, 22, 22) .add(libPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) - .add(org.jdesktop.layout.GroupLayout.TRAILING, lVersion, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 437, Short.MAX_VALUE) - .add(lDirectory, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 437, Short.MAX_VALUE)))) + .add(org.jdesktop.layout.GroupLayout.TRAILING, lVersion, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 444, Short.MAX_VALUE) + .add(lDirectory, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 444, Short.MAX_VALUE))) + .add(libPanelLayout.createSequentialGroup() + .add(libPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING, false) + .add(org.jdesktop.layout.GroupLayout.LEADING, rbServerLibrary, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .add(org.jdesktop.layout.GroupLayout.LEADING, rbRegisteredLibrary, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED) + .add(libPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(cbLibraries, 0, 283, Short.MAX_VALUE) + .add(org.jdesktop.layout.GroupLayout.TRAILING, libPanelLayout.createSequentialGroup() + .add(libPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING) + .add(jtNewLibraryName, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 175, Short.MAX_VALUE) + .add(jtFolder, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 175, Short.MAX_VALUE)) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) + .add(jbBrowse)) + .add(serverLibraries, 0, 283, Short.MAX_VALUE)))) .addContainerGap()) ); libPanelLayout.setVerticalGroup( libPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) .add(org.jdesktop.layout.GroupLayout.TRAILING, libPanelLayout.createSequentialGroup() .addContainerGap() - .add(rbNoneLibrary) + .add(libPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE) + .add(rbServerLibrary) + .add(serverLibraries, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) .add(libPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE) .add(rbRegisteredLibrary) @@ -400,7 +548,7 @@ .add(libPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE) .add(jtNewLibraryName, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) .add(lVersion)) - .addContainerGap(27, Short.MAX_VALUE)) + .addContainerGap(59, Short.MAX_VALUE)) ); jsfTabbedPane.addTab(org.openide.util.NbBundle.getMessage(JSFConfigurationPanelVisual.class, "LBL_TAB_Libraries"), libPanel); // NOI18N @@ -434,7 +582,7 @@ .add(confPanelLayout.createSequentialGroup() .add(lURLPattern) .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) - .add(tURLPattern, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 295, Short.MAX_VALUE)) + .add(tURLPattern, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 280, Short.MAX_VALUE)) .add(confPanelLayout.createSequentialGroup() .add(jLabel1) .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) @@ -467,12 +615,12 @@ jsfTabbedPane.getAccessibleContext().setAccessibleName(""); }// //GEN-END:initComponents -private void rbNoneLibraryItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_rbNoneLibraryItemStateChanged +private void rbServerLibraryItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_rbServerLibraryItemStateChanged updateLibrary(); - if (rbNoneLibrary.isSelected()) { + if (rbServerLibrary.isSelected()) { panel.fireChangeEvent(); } -}//GEN-LAST:event_rbNoneLibraryItemStateChanged +}//GEN-LAST:event_rbServerLibraryItemStateChanged private void jtNewLibraryNameKeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_jtNewLibraryNameKeyReleased panel.setNewLibraryName(jtNewLibraryName.getText().trim()); @@ -520,6 +668,15 @@ } else panel.setEnableFacelets(false); }//GEN-LAST:event_cbPreferredLangActionPerformed + +private void serverLibrariesActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_serverLibrariesActionPerformed + // TODO add your handling code here: + ServerLibraryItem item = (ServerLibraryItem) serverLibraries.getSelectedItem(); + if (item != null) { + panel.setServerLibrary(item.getLibrary()); + } + updatePreferredLanguages(); +}//GEN-LAST:event_serverLibrariesActionPerformed // Variables declaration - do not modify//GEN-BEGIN:variables @@ -538,8 +695,9 @@ private javax.swing.JLabel lVersion; private javax.swing.JPanel libPanel; private javax.swing.JRadioButton rbNewLibrary; - private javax.swing.JRadioButton rbNoneLibrary; private javax.swing.JRadioButton rbRegisteredLibrary; + private javax.swing.JRadioButton rbServerLibrary; + private javax.swing.JComboBox serverLibraries; private javax.swing.JTextField tURLPattern; // End of variables declaration//GEN-END:variables @@ -577,11 +735,7 @@ return true; } - if (rbNoneLibrary.isSelected() && isWebLogicServer){ - controller.getProperties().setProperty(WizardDescriptor.PROP_INFO_MESSAGE, NbBundle.getMessage(JSFConfigurationPanelVisual.class, "LBL_Weblogic_Warning")); - } else { - controller.getProperties().setProperty(WizardDescriptor.PROP_INFO_MESSAGE, null); - } + controller.getProperties().setProperty(WizardDescriptor.PROP_INFO_MESSAGE, null); if (rbRegisteredLibrary.isSelected()) { if (jsfLibraries == null || jsfLibraries.size() == 0) { @@ -653,6 +807,7 @@ return true; return false; } + private boolean isWebLogic(String serverInstanceID) { if (serverInstanceID == null || "".equals(serverInstanceID)) { return false; @@ -682,73 +837,45 @@ * according web module version. */ private void initLibSettings(Profile profile, String serverInstanceID) { - if (panel==null || panel.getLibraryType() == null || isServerInstanceChanged()) { - try { - File[] cp; - J2eePlatform platform = null; - try { - if (serverInstanceID != null) - platform = Deployment.getDefault().getServerInstance(serverInstanceID).getJ2eePlatform(); - } catch (InstanceRemovedException ex) { - platform = null; - LOG.log(Level.INFO, org.openide.util.NbBundle.getMessage(JSFConfigurationPanelVisual.class, "SERVER_INSTANCE_REMOVED"), ex); - } - // j2eeplatform can be null, when the target server is not accessible. - if (platform != null) { - cp = platform.getClasspathEntries(); + boolean serverChanged = isServerInstanceChanged(); + if (serverChanged) { + initServerLibraries(); + } + + if (panel==null || panel.getLibraryType() == null || serverChanged) { + if (serverJsfLibraries.isEmpty()) { + rbServerLibrary.setVisible(false); + serverLibraries.setVisible(false); + Library preferredLibrary = null; + if (profile.equals(Profile.JAVA_EE_6_FULL) || profile.equals(Profile.JAVA_EE_6_WEB) || profile.equals(Profile.JAVA_EE_5)) { + preferredLibrary = LibraryManager.getDefault().getLibrary(JSFUtils.DEFAULT_JSF_2_0_NAME); } else { - cp = new File[0]; + preferredLibrary = LibraryManager.getDefault().getLibrary(JSFUtils.DEFAULT_JSF_1_2_NAME); } - // XXX: there should be a utility class for this: - boolean isJSF = Util.containsClass(Arrays.asList(cp), JSFUtils.FACES_EXCEPTION); - boolean isJSF12 = Util.containsClass(Arrays.asList(cp), JSFUtils.JSF_1_2__API_SPECIFIC_CLASS); - boolean isJSF20 = Util.containsClass(Arrays.asList(cp), JSFUtils.JSF_2_0__API_SPECIFIC_CLASS); - - String libName = null; //NOI18N - if (isJSF20) { - libName = "JSF 2.0"; //NOI18N - } else if (isJSF12) { - libName = "JSF 1.2"; //NOI18N - } else if (isJSF) { - libName = "JSF 1.1"; //NOI18N + if (preferredLibrary != null) { + // if there is a proffered library, select + rbRegisteredLibrary.setSelected(true); + cbLibraries.setSelectedItem(preferredLibrary.getDisplayName()); + updateLibrary(); } else { - rbNoneLibrary.setVisible(false); - Library preferredLibrary = null; - if (profile.equals(Profile.JAVA_EE_6_FULL) || profile.equals(Profile.JAVA_EE_6_WEB) || profile.equals(Profile.JAVA_EE_5)) { - preferredLibrary = LibraryManager.getDefault().getLibrary(JSFUtils.DEFAULT_JSF_2_0_NAME); - } else { - preferredLibrary = LibraryManager.getDefault().getLibrary(JSFUtils.DEFAULT_JSF_1_2_NAME); - } - - if (preferredLibrary != null) { - // if there is a proffered library, select - rbRegisteredLibrary.setSelected(true); - cbLibraries.setSelectedItem(preferredLibrary.getDisplayName()); - updateLibrary(); - } else { - // there is not a proffered library -> select one or select creating new one - if (jsfLibraries.size() == 0) { - rbNewLibrary.setSelected(true); - } + // there is not a proffered library -> select one or select creating new one + if (jsfLibraries.isEmpty()) { + rbNewLibrary.setSelected(true); } } - if (libName != null) { - if (!rbNoneLibrary.isVisible()) { - rbNoneLibrary.setVisible(true); - repaint(); - } - rbNoneLibrary.setText(NbBundle.getMessage(JSFConfigurationPanelVisual.class, "LBL_Any_Library", libName)); //NOI18N - rbNoneLibrary.setSelected(true); - if (panel !=null) - panel.setLibraryType(JSFConfigurationPanel.LibraryType.NONE); - enableNewLibraryComponent(false); - enableDefinedLibraryComponent(false); - isWebLogicServer = isWebLogic(serverInstanceID); + } else { + if (!rbServerLibrary.isVisible()) { + rbServerLibrary.setVisible(true); + serverLibraries.setVisible(true); + repaint(); } - - } catch (IOException exception) { - Exceptions.printStackTrace(exception); + rbServerLibrary.setSelected(true); + if (panel !=null) + panel.setLibraryType(JSFConfigurationPanel.LibraryType.SERVER); + enableNewLibraryComponent(false); + enableDefinedLibraryComponent(false); + isWebLogicServer = isWebLogic(serverInstanceID); } } else { switch( panel.getLibraryType()) { @@ -760,8 +887,8 @@ rbRegisteredLibrary.setSelected(true); break; } - case NONE: { - rbNoneLibrary.setSelected(true); + case SERVER: { + rbServerLibrary.setSelected(true); enableDefinedLibraryComponent(false); enableNewLibraryComponent(false); break; @@ -831,15 +958,23 @@ private void updateLibrary(){ if (cbLibraries.getItemCount() == 0) rbRegisteredLibrary.setEnabled(false); - - if (rbNoneLibrary.isSelected()){ + + if (rbServerLibrary.isSelected()){ enableNewLibraryComponent(false); enableDefinedLibraryComponent(false); - panel.setLibraryType(JSFConfigurationPanel.LibraryType.NONE); + enableServerLibraryComponent(true); + panel.setLibraryType(JSFConfigurationPanel.LibraryType.SERVER); + if (!serverJsfLibraries.isEmpty()) { + ServerLibraryItem item = (ServerLibraryItem) serverLibraries.getSelectedItem(); + if (item != null) { + panel.setServerLibrary(item.getLibrary()); + } + } panel.getController().setErrorMessage(null); } else if (rbRegisteredLibrary.isSelected()){ enableNewLibraryComponent(false); enableDefinedLibraryComponent(true); + enableServerLibraryComponent(false); panel.setLibraryType(JSFConfigurationPanel.LibraryType.USED); if (jsfLibraries.size() > 0){ panel.setLibrary(jsfLibraries.get(cbLibraries.getSelectedIndex()).getLibrary()); @@ -848,6 +983,7 @@ } else if (rbNewLibrary.isSelected()){ enableNewLibraryComponent(true); enableDefinedLibraryComponent(false); + enableServerLibraryComponent(false); panel.setLibraryType(JSFConfigurationPanel.LibraryType.NEW); setNewLibraryFolder(); } @@ -857,6 +993,10 @@ private void enableDefinedLibraryComponent(boolean enabled){ cbLibraries.setEnabled(enabled); } + + private void enableServerLibraryComponent(boolean enabled){ + serverLibraries.setEnabled(enabled); + } private void enableNewLibraryComponent(boolean enabled){ lDirectory.setEnabled(enabled); @@ -914,4 +1054,98 @@ return library.getDisplayName(); } } + + private static class ServerLibraryItem implements Comparable { + + private final ServerLibrary library; + + private final JSFVersion version; + + private String name; + + public ServerLibraryItem(ServerLibrary library, JSFVersion version) { + this.library = library; + this.version = version; + } + + public ServerLibrary getLibrary() { + return library; + } + + public JSFVersion getVersion() { + return version; + } + + @Override + public String toString() { + synchronized (this) { + if (name != null) { + return name; + } + } + + StringBuilder sb = new StringBuilder(); + switch (version) { + case JSF_1_0: + sb.append("JSF 1.0"); // NOI18N + break; + case JSF_1_1: + sb.append("JSF 1.1"); // NOI18N + break; + case JSF_1_2: + sb.append("JSF 1.2"); // NOI18N + break; + case JSF_2_0: + sb.append("JSF 2.0"); // NOI18N + break; + } + if (library != null && (library.getImplementationTitle() != null || library.getImplementationVersion() != null)) { + sb.append(" "); // NOI18N + sb.append("["); // NOI18N + if (library.getImplementationTitle() != null) { + sb.append(library.getImplementationTitle()); + } + if (library.getImplementationVersion() != null) { + if (library.getImplementationTitle() != null) { + sb.append(" - "); // NOI18N + } + sb.append(library.getImplementationVersion().toString()); + } + sb.append("]"); // NOI18N + } + // result is the same as all fields are final + synchronized (this) { + name = sb.toString(); + return name; + } + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final ServerLibraryItem other = (ServerLibraryItem) obj; + if ((this.toString() == null) ? (other.toString() != null) : !this.toString().equals(other.toString())) { + return false; + } + return true; + } + + @Override + public int hashCode() { + int hash = 7; + hash = 67 * hash + (this.toString() != null ? this.toString().hashCode() : 0); + return hash; + } + + @Override + public int compareTo(ServerLibraryItem o) { + return -this.toString().compareTo(o.toString()); + } + + } } --- a/web.project/src/org/netbeans/modules/web/project/WebProject.java Fri May 28 12:20:35 2010 +0200 +++ a/web.project/src/org/netbeans/modules/web/project/WebProject.java Fri Jun 11 10:20:14 2010 +0200 @@ -715,28 +715,7 @@ j2eePlatformListener = new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent evt) { if (evt.getPropertyName().equals(J2eePlatform.PROP_CLASSPATH)) { - ProjectManager.mutex().writeAccess(new Mutex.Action() { - public Void run() { - EditableProperties ep = helper.getProperties( - AntProjectHelper.PRIVATE_PROPERTIES_PATH); - EditableProperties projectProps = helper.getProperties( - AntProjectHelper.PROJECT_PROPERTIES_PATH); - - if (!J2EEProjectProperties.isUsingServerLibrary(projectProps, - WebProjectProperties.J2EE_PLATFORM_CLASSPATH)) { - String root = J2EEProjectProperties.extractPlatformLibrariesRoot(platform); - String classpath = J2EEProjectProperties.toClasspathString(platform.getClasspathEntries(), root); - ep.setProperty(WebProjectProperties.J2EE_PLATFORM_CLASSPATH, classpath); - } - helper.putProperties(AntProjectHelper.PRIVATE_PROPERTIES_PATH, ep); - try { - ProjectManager.getDefault().saveProject(WebProject.this); - } catch (IOException e) { - Exceptions.printStackTrace(e); - } - return null; - } - }); + updateClasspath(platform); } } }; @@ -748,6 +727,33 @@ platform.removePropertyChangeListener(j2eePlatformListener); } } + + private void updateClasspath(final J2eePlatform platform) { + ProjectManager.mutex().writeAccess(new Mutex.Action() { + public Void run() { + EditableProperties ep = helper.getProperties( + AntProjectHelper.PRIVATE_PROPERTIES_PATH); + EditableProperties projectProps = helper.getProperties( + AntProjectHelper.PROJECT_PROPERTIES_PATH); + + if (!J2EEProjectProperties.isUsingServerLibrary(projectProps, + WebProjectProperties.J2EE_PLATFORM_CLASSPATH)) { + String root = J2EEProjectProperties.extractPlatformLibrariesRoot(platform); + String classpath = J2EEProjectProperties.toClasspathString( + Util.getJ2eePlatformClasspathEntries(WebProject.this), root); + ep.setProperty(WebProjectProperties.J2EE_PLATFORM_CLASSPATH, classpath); + } + helper.putProperties(AntProjectHelper.PRIVATE_PROPERTIES_PATH, ep); + try { + ProjectManager.getDefault().saveProject(WebProject.this); + } catch (IOException e) { + Exceptions.printStackTrace(e); + } + return null; + } + }); + } + // Private innerclasses ---------------------------------------------------- //when #110886 gets implemented, this class is obsolete @@ -1006,6 +1012,32 @@ } catch (IOException e) { Logger.getLogger("global").log(Level.INFO, null, e); } + +// String servInstID = evaluator().getProperty(WebProjectProperties.J2EE_SERVER_INSTANCE); +// J2eePlatform platform = Deployment.getDefault().getJ2eePlatform(servInstID); +// if (platform != null) { +// String root = J2EEProjectProperties.extractPlatformLibrariesRoot(platform); +// String classpath = J2EEProjectProperties.toClasspathString( +// Util.getJ2eePlatformClasspathEntries(WebProject.this), root); +// +// EditableProperties ep = helper.getProperties(AntProjectHelper.PRIVATE_PROPERTIES_PATH); +// String oldClasspath = ep.getProperty(WebProjectProperties.J2EE_PLATFORM_CLASSPATH); +// if (!oldClasspath.equals(classpath)) { +// ep.setProperty(WebProjectProperties.J2EE_PLATFORM_CLASSPATH, classpath); +// } +// } + + webModule.getConfigSupport().addLibraryChangeListener(new ChangeListener() { + + @Override + public void stateChanged(ChangeEvent e) { + String servInstID = evaluator().getProperty(WebProjectProperties.J2EE_SERVER_INSTANCE); + J2eePlatform platform = Deployment.getDefault().getJ2eePlatform(servInstID); + if (platform != null) { + updateClasspath(platform); + } + } + }); // register project's classpaths to GlobalPathRegistry GlobalPathRegistry.getDefault().register(ClassPath.BOOT, cpProvider.getProjectClassPaths(ClassPath.BOOT));