diff --git a/maven.j2ee/nbproject/project.xml b/maven.j2ee/nbproject/project.xml --- a/maven.j2ee/nbproject/project.xml +++ b/maven.j2ee/nbproject/project.xml @@ -299,7 +299,7 @@ 1 - 1.18 + 1.56 diff --git a/maven.j2ee/src/org/netbeans/modules/maven/j2ee/Bundle.properties b/maven.j2ee/src/org/netbeans/modules/maven/j2ee/Bundle.properties --- a/maven.j2ee/src/org/netbeans/modules/maven/j2ee/Bundle.properties +++ b/maven.j2ee/src/org/netbeans/modules/maven/j2ee/Bundle.properties @@ -42,7 +42,6 @@ OpenIDE-Module-Name=Maven Java EE OpenIDE-Module-Long-Description=Java EE-related parts of the Maven project type. -LBL_WebPages=Web Pages # Usage logging when an Maven enterprise project is opened # {0} Server name diff --git a/maven.j2ee/src/org/netbeans/modules/maven/j2ee/J2eeMavenSourcesImpl.java b/maven.j2ee/src/org/netbeans/modules/maven/j2ee/J2eeMavenSourcesImpl.java --- a/maven.j2ee/src/org/netbeans/modules/maven/j2ee/J2eeMavenSourcesImpl.java +++ b/maven.j2ee/src/org/netbeans/modules/maven/j2ee/J2eeMavenSourcesImpl.java @@ -44,21 +44,28 @@ import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; import javax.swing.event.ChangeListener; -import org.netbeans.modules.maven.api.FileUtilities; import org.netbeans.modules.maven.api.NbMavenProject; import org.netbeans.api.project.Project; import org.netbeans.api.project.SourceGroup; import org.netbeans.api.project.Sources; import org.netbeans.modules.maven.spi.nodes.OtherSourcesExclude; +import org.netbeans.modules.web.common.spi.ProjectWebRootProvider; import org.netbeans.spi.project.ProjectServiceProvider; import org.netbeans.spi.project.support.GenericSources; import org.openide.filesystems.FileObject; import org.openide.util.ChangeSupport; import org.openide.util.NbBundle; +import static org.netbeans.modules.maven.j2ee.Bundle.*; /** - * Implementation of Sources interface for Java EE Maven projects + * Implementation of {@link Sources} interface for Java EE Maven projects. + * + * This class is thread safe. + * * @author Milos Kleint */ @ProjectServiceProvider( @@ -77,17 +84,17 @@ ) public class J2eeMavenSourcesImpl implements Sources, OtherSourcesExclude { - public static final String TYPE_DOC_ROOT="doc_root"; //NOI18N - public static final String TYPE_WEB_INF="web_inf"; //NOI18N - - private final Object lock = new Object(); + public static final String TYPE_DOC_ROOT = "doc_root"; // NOI18N + public static final String TYPE_WEB_INF = "web_inf"; // NOI18N + private final Project project; private final ChangeSupport cs = new ChangeSupport(this); private final PropertyChangeListener pcl; - - private SourceGroup webDocSrcGroup; - + // @GuardedBy("this") + private List webResourceRoots; + + public J2eeMavenSourcesImpl(Project project) { this.project = project; this.pcl = new PropertyChangeListener() { @@ -95,22 +102,28 @@ @Override public void propertyChange(PropertyChangeEvent event) { if (NbMavenProject.PROP_PROJECT.equals(event.getPropertyName())) { - checkChanges(); + if (hasChanged()) { + cs.fireChange(); + } } } }; } - - private void checkChanges() { - boolean changed; - synchronized (lock) { - changed = checkWebDocGroupCache(getWebAppDir()); + + private boolean hasChanged() { + List resourceRoots = getWebSourceGroups(); + + synchronized (this) { + if (!this.webResourceRoots.equals(resourceRoots)) { + // Set the cached value to the current resource roots + this.webResourceRoots = resourceRoots; + return true; + } } - if (changed) { - cs.fireChange(); - } + + return false; } - + @Override public void addChangeListener(ChangeListener changeListener) { // If no listener were registered until now, start listening at project changes @@ -129,56 +142,46 @@ NbMavenProject.removePropertyChangeListener(project, pcl); } } - + @Override public SourceGroup[] getSourceGroups(String str) { if (TYPE_DOC_ROOT.equals(str)) { - return createWebDocRoot(); + synchronized (this) { + if (webResourceRoots == null) { + webResourceRoots = getWebSourceGroups(); + } + return webResourceRoots.toArray(new SourceGroup[webResourceRoots.size()]); + } } return new SourceGroup[0]; } - - private SourceGroup[] createWebDocRoot() { - FileObject folder = getWebAppDir(); - SourceGroup grp; - synchronized (lock) { - checkWebDocGroupCache(folder); - grp = webDocSrcGroup; + + private List getWebSourceGroups() { + List sourceGroups = new ArrayList<>(); + + ProjectWebRootProvider webRootProvider = project.getLookup().lookup(ProjectWebRootProvider.class); + if (webRootProvider != null) { + Collection webRoots = webRootProvider.getWebRoots(); + for (FileObject webRoot : webRoots) { + sourceGroups.add(GenericSources.group(project, webRoot, TYPE_DOC_ROOT, getDisplayName(webRoot), null, null)); + } } - if (grp != null) { - return new SourceGroup[] {grp}; + + return sourceGroups; + } + + @NbBundle.Messages("LBL_WebPages=Web Pages") + private String getDisplayName(FileObject webRoot) { + // To preserve current behavior, don't show web root name in the node name for default "webapp" + if ("webapp".equals(webRoot.getName())) { // NOI18N + return LBL_WebPages(); } else { - return new SourceGroup[0]; + return LBL_WebPages() + " (" + webRoot.getName() + ")"; // NOI18N } } - - private FileObject getWebAppDir() { - NbMavenProject mavenproject = project.getLookup().lookup(NbMavenProject.class); - return FileUtilities.convertURItoFileObject(mavenproject.getWebAppDirectory()); - } - - /** - * consult the SourceGroup cache, return true if anything changed.. - */ - private boolean checkWebDocGroupCache(FileObject root) { - if (root == null && webDocSrcGroup != null) { - webDocSrcGroup = null; - return true; - } - if (root == null) { - return false; - } - boolean changed = false; - if (webDocSrcGroup == null || !webDocSrcGroup.getRootFolder().equals(root)) { - webDocSrcGroup = GenericSources.group(project, root, TYPE_DOC_ROOT, NbBundle.getMessage(J2eeMavenSourcesImpl.class, "LBL_WebPages"), null, null); - changed = true; - } - return changed; - } @Override public String folderName() { - return "webapp"; + return "webapp"; // NOI18N } - } diff --git a/maven.j2ee/src/org/netbeans/modules/maven/j2ee/ui/nodes/Bundle.properties b/maven.j2ee/src/org/netbeans/modules/maven/j2ee/ui/nodes/Bundle.properties deleted file mode 100644 --- a/maven.j2ee/src/org/netbeans/modules/maven/j2ee/ui/nodes/Bundle.properties +++ /dev/null @@ -1,41 +0,0 @@ -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. -# -# Copyright 2013 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 2013 Sun Microsystems, Inc. - -LBL_Web_Pages=Web Pages \ No newline at end of file diff --git a/maven.j2ee/src/org/netbeans/modules/maven/j2ee/ui/nodes/WebPagesNode.java b/maven.j2ee/src/org/netbeans/modules/maven/j2ee/ui/nodes/WebPagesNode.java --- a/maven.j2ee/src/org/netbeans/modules/maven/j2ee/ui/nodes/WebPagesNode.java +++ b/maven.j2ee/src/org/netbeans/modules/maven/j2ee/ui/nodes/WebPagesNode.java @@ -55,12 +55,14 @@ import org.openide.nodes.Node; import org.openide.util.ImageUtilities; import org.openide.util.NbBundle; +import static org.netbeans.modules.maven.j2ee.ui.nodes.Bundle.*; /** * filter node for display of web sources * @author Milos Kleint */ +@NbBundle.Messages("LBL_Web_Pages=Web Pages") class WebPagesNode extends FilterNode { private boolean isTopLevelNode = false; private FileObject file; @@ -81,15 +83,23 @@ @Override public String getDisplayName() { if (isTopLevelNode) { - String s = NbBundle.getMessage(WebPagesNode.class, "LBL_Web_Pages"); - + String webRootName = file.getName(); + String displayName; + + // To preserve current behavior, don't show web root name in the node name for default "webapp" + if ("webapp".equals(webRootName)) { // NOI18N + displayName = LBL_Web_Pages(); + } else { + displayName = LBL_Web_Pages() + " (" + file.getName() + ")"; // NOI18N + } + try { - s = file.getFileSystem().getStatus().annotateName(s, Collections.singleton(file)); + displayName = file.getFileSystem().getStatus().annotateName(displayName, Collections.singleton(file)); } catch (FileStateInvalidException e) { ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e); } - return s; + return displayName; } return getOriginal().getDisplayName(); @@ -105,7 +115,7 @@ if (stat instanceof FileSystem.HtmlStatus) { FileSystem.HtmlStatus hstat = (FileSystem.HtmlStatus) stat; - String s = NbBundle.getMessage(WebPagesNode.class, "LBL_Web_Pages"); + String s = LBL_Web_Pages(); String result = hstat.annotateNameHtml ( s, Collections.singleton(file)); diff --git a/maven.j2ee/src/org/netbeans/modules/maven/j2ee/web/WebProjectWebRootProvider.java b/maven.j2ee/src/org/netbeans/modules/maven/j2ee/web/WebProjectWebRootProvider.java --- a/maven.j2ee/src/org/netbeans/modules/maven/j2ee/web/WebProjectWebRootProvider.java +++ b/maven.j2ee/src/org/netbeans/modules/maven/j2ee/web/WebProjectWebRootProvider.java @@ -51,15 +51,13 @@ import org.netbeans.api.project.Project; import org.netbeans.modules.maven.api.NbMavenProject; import org.netbeans.modules.maven.api.PluginPropertyUtils; -import org.netbeans.modules.web.api.webmodule.WebModule; import org.netbeans.modules.web.common.spi.ProjectWebRootProvider; -import org.netbeans.modules.web.spi.webmodule.WebModuleProvider; import org.netbeans.spi.project.ProjectServiceProvider; import org.openide.filesystems.FileObject; import org.openide.util.Exceptions; /** - * This class is thread safe. + * This class is immutable and thus thread safe. * * @author marekfukala * @author Martin Janicek @@ -77,8 +75,6 @@ private final Project project; private final FileObject projectDir; - // @GuardedBy("this") - private WebModuleProvider webModuleProvider; public WebProjectWebRootProvider(Project project) { @@ -86,18 +82,9 @@ this.projectDir = project.getProjectDirectory(); } - private synchronized WebModuleProvider getProvider() { - if (webModuleProvider == null) { - webModuleProvider = project.getLookup().lookup(WebModuleProvider.class); - } - return webModuleProvider; - } - @Override public FileObject getWebRoot(FileObject file) { - WebModuleProvider provider = getProvider(); - WebModule wm = provider != null ? provider.findWebModule(file) : null; - return wm != null ? wm.getDocumentBase() : null; + return getDefaultWebRoot(); } @Override @@ -130,19 +117,11 @@ } private FileObject getDefaultWebRoot() { - WebModuleProvider provider = getProvider(); - if (provider == null) { - return null; + String webSourceDir = WebProjectUtils.getPluginProperty(project, "warSourceDirectory"); // NOI18N + if (webSourceDir == null) { + webSourceDir = "src/main/webapp"; // NOI18N } - WebModule webModule = provider.findWebModule(project.getProjectDirectory()); - if (webModule == null) { - return null; - } - FileObject documentBase = webModule.getDocumentBase(); - if (documentBase == null) { - return null; - } - return documentBase; + return projectDir.getFileObject(webSourceDir); } /** diff --git a/projectapi/manifest.mf b/projectapi/manifest.mf --- a/projectapi/manifest.mf +++ b/projectapi/manifest.mf @@ -1,6 +1,6 @@ Manifest-Version: 1.0 OpenIDE-Module: org.netbeans.modules.projectapi/1 -OpenIDE-Module-Specification-Version: 1.55 +OpenIDE-Module-Specification-Version: 1.56 OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/projectapi/Bundle.properties OpenIDE-Module-Layer: org/netbeans/modules/projectapi/layer.xml diff --git a/projectapi/src/org/netbeans/spi/project/support/GenericSources.java b/projectapi/src/org/netbeans/spi/project/support/GenericSources.java --- a/projectapi/src/org/netbeans/spi/project/support/GenericSources.java +++ b/projectapi/src/org/netbeans/spi/project/support/GenericSources.java @@ -193,7 +193,40 @@ public String toString() { return "GenericSources.Group[name=" + name + ",rootFolder=" + rootFolder + "]"; // NOI18N } - + + @Override + public int hashCode() { + int hash = 7; + hash = 89 * hash + (this.p != null ? this.p.hashCode() : 0); + hash = 89 * hash + (this.rootFolder != null ? this.rootFolder.hashCode() : 0); + hash = 89 * hash + (this.name != null ? this.name.hashCode() : 0); + hash = 89 * hash + (this.displayName != null ? this.displayName.hashCode() : 0); + return hash; + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final Group other = (Group) obj; + if (this.p != other.p && (this.p == null || !this.p.equals(other.p))) { + return false; + } + if (this.rootFolder != other.rootFolder && (this.rootFolder == null || !this.rootFolder.equals(other.rootFolder))) { + return false; + } + if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) { + return false; + } + if ((this.displayName == null) ? (other.displayName != null) : !this.displayName.equals(other.displayName)) { + return false; + } + return true; + } } }