[563352] Implement support for resolving filepaths in multi-root web-fragment projects Signed-off-by: Nitin Dahyabhai <thatnitind@gmail.com> Change-Id: Ib10a3d2778e1dc2283cd7c9371a6e091807dc330
diff --git a/web/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/util/FacetModuleCoreSupportDelegate.java b/web/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/util/FacetModuleCoreSupportDelegate.java index 9d23d62..1ad6d42 100644 --- a/web/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/util/FacetModuleCoreSupportDelegate.java +++ b/web/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/util/FacetModuleCoreSupportDelegate.java
@@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2016 IBM Corporation and others. + * Copyright (c) 2007, 2020 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 * which accompanies this distribution, and is available at @@ -179,6 +179,9 @@ return false; } + /* + * Handle resolution in a required web fragment + */ private static IPath resolveInReferenced(IProject project, IPath runtimeReference) { IVirtualReference[] references = ComponentCore.createComponent(project).getReferences(); if (references != null) { @@ -199,10 +202,32 @@ * See Servlet 3.0, section 4.6, web fragments as required * projects */ + /* https://bugs.eclipse.org/398698 */ IPath resolved = referencedPathRoot.append(FacetModuleCoreSupport.META_INF_RESOURCES).append(runtimeReference); if (resolved != null && component.getProject().findMember(resolved.removeFirstSegments(1)) != null) { return resolved; } + /* + * Handle multi-root fragments, and ones where the default root marked for deployment doesn't exist + */ + IVirtualFile virtualFile = ComponentCore.createFile(component.getProject(), FacetModuleCoreSupport.META_INF_RESOURCES_PATH.append(runtimeReference)); + if (virtualFile != null) { + IFile[] underlyingFiles = virtualFile.getUnderlyingFiles(); + for (int j = 0; j < underlyingFiles.length; j++) { + if (underlyingFiles[i].isAccessible()) { + return underlyingFiles[i].getFullPath(); + } + } + } + IVirtualFolder virtualFolder = ComponentCore.createFolder(component.getProject(), FacetModuleCoreSupport.META_INF_RESOURCES_PATH.append(runtimeReference)); + if (virtualFolder != null) { + IContainer[] underlyingFolders = virtualFolder.getUnderlyingFolders(); + for (int j = 0; j < underlyingFolders.length; j++) { + if (underlyingFolders[i].isAccessible()) { + return underlyingFolders[i].getFullPath(); + } + } + } } // overlay? IVirtualResource member = rootFolder.findMember(runtimeReference); @@ -293,7 +318,7 @@ return new IPath[]{project.getFullPath()}; } - List paths = new ArrayList(); + List<IPath> paths = new ArrayList<>(); IVirtualFolder componentFolder = ComponentCore.createFolder(project, Path.ROOT); if (componentFolder != null && componentFolder.exists()) { IContainer[] workspaceFolders = componentFolder.getUnderlyingFolders(); @@ -335,7 +360,7 @@ else { paths.add(project.getFullPath()); } - return (IPath[]) paths.toArray(new IPath[paths.size()]); + return paths.toArray(new IPath[paths.size()]); } static IPath getDefaultRoot(IProject project) { @@ -352,7 +377,7 @@ if (!ModuleCoreNature.isFlexibleProject(current)) return new IProject[0]; - Set projects = new HashSet(); + Set<IProject> projects = new HashSet<IProject>(); IVirtualReference[] references = ComponentCore.createComponent(current).getReferences(); if (references != null) { for (int i = 0; i < references.length; i++) { @@ -365,7 +390,7 @@ projects.add(project); } } - return (IProject[]) projects.toArray(new IProject[projects.size()]); + return projects.toArray(new IProject[projects.size()]); } static IPath getRootContainerForPath(IProject project, IPath path) {
diff --git a/web/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/internal/contentassist/resources/AbstractWebResourcesCompletionProposalComputer.java b/web/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/internal/contentassist/resources/AbstractWebResourcesCompletionProposalComputer.java index 72190df..fbd0489 100644 --- a/web/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/internal/contentassist/resources/AbstractWebResourcesCompletionProposalComputer.java +++ b/web/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/internal/contentassist/resources/AbstractWebResourcesCompletionProposalComputer.java
@@ -1,5 +1,5 @@ /** - * Copyright (c) 2013, 2019 Angelo ZERR and others + * Copyright (c) 2013, 2020 Angelo ZERR and others * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 * which accompanies this distribution, and is available at @@ -72,7 +72,8 @@ // this.completionComputerJob = new Job("Compute completion proposals") { // @Override // protected IStatus run(IProgressMonitor arg0) { - for (IPath path : findMatchingPaths(file)) { + IPath[] matchingPaths = findMatchingPaths(file); + for (IPath path : matchingPaths) { if (!referencePath.equals(path)) { String proposalText = null; try { @@ -116,7 +117,7 @@ protected IPath[] findMatchingPaths(IResource referenceResource) { ContentTypeSpecs fileMatcher = createFilenameMatcher(); final List<IPath> res = new ArrayList<>(); - IWorkspaceRoot root = referenceResource.getWorkspace().getRoot(); + IWorkspaceRoot workspaceRoot = referenceResource.getWorkspace().getRoot(); IPath referencePath = referenceResource.getFullPath(); IPath[] roots = FacetModuleCoreSupport.getAcceptableRootPaths(referenceResource.getProject()); /* @@ -134,7 +135,7 @@ } for (int i = 0; i < roots.length; i++) { try { - root.findMember(roots[i]).accept(new IResourceProxyVisitor() { + workspaceRoot.findMember(roots[i]).accept(new IResourceProxyVisitor() { @Override public boolean visit(IResourceProxy proxy) throws CoreException { if (proxy.getType() == IResource.FILE && fileMatcher.matches(proxy.getName())) {
diff --git a/web/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/internal/contentassist/resources/CSSWebResourcesCompletionProposalComputer.java b/web/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/internal/contentassist/resources/CSSWebResourcesCompletionProposalComputer.java index bde000f..3ffbd11 100644 --- a/web/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/internal/contentassist/resources/CSSWebResourcesCompletionProposalComputer.java +++ b/web/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/internal/contentassist/resources/CSSWebResourcesCompletionProposalComputer.java
@@ -1,5 +1,5 @@ /** - * Copyright (c) 2013, 2019 Angelo ZERR and others + * Copyright (c) 2013, 2020 Angelo ZERR and others * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 * which accompanies this distribution, and is available at @@ -14,13 +14,17 @@ */ package org.eclipse.wst.html.ui.internal.contentassist.resources; -import org.eclipse.wst.css.core.internal.provisional.contenttype.ContentTypeIdForCSS; +import org.eclipse.core.runtime.Platform; import org.eclipse.wst.xml.ui.internal.contentassist.ContentAssistRequest; import org.w3c.dom.Node; public class CSSWebResourcesCompletionProposalComputer extends AbstractWebResourcesCompletionProposalComputer { - ContentTypeSpecs fileMatcher = ContentTypeSpecs.createFor(ContentTypeIdForCSS.ContentTypeID_CSS); + ContentTypeSpecs fileMatcher = null; + + public CSSWebResourcesCompletionProposalComputer () { + fileMatcher = ContentTypeSpecs.createFor(Platform.getContentTypeManager().findContentTypesFor("file.css")); + } @Override ContentTypeSpecs createFilenameMatcher() {
diff --git a/web/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/internal/contentassist/resources/ContentTypeSpecs.java b/web/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/internal/contentassist/resources/ContentTypeSpecs.java index 203cd64..7f28306 100644 --- a/web/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/internal/contentassist/resources/ContentTypeSpecs.java +++ b/web/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/internal/contentassist/resources/ContentTypeSpecs.java
@@ -27,16 +27,19 @@ * type and all of its descendants */ public class ContentTypeSpecs { + /** + * @param contentTypeId - the registered content type's ID + * @return + */ public static ContentTypeSpecs createFor(String contentTypeId) { - return createFor(new String[]{contentTypeId}); + return createFor(new IContentType[]{Platform.getContentTypeManager().getContentType(contentTypeId)}); } - public static ContentTypeSpecs createFor(String[] contentTypeIds) { + public static ContentTypeSpecs createFor(IContentType[] contentTypes) { // long startTime = System.currentTimeMillis(); List<String> filenameExtensions = new ArrayList<String>(); Set<String> filenames = new HashSet<>(); - for (String contentTypeId: contentTypeIds) { - IContentType baseContentType = Platform.getContentTypeManager().getContentType(contentTypeId); + for (IContentType baseContentType: contentTypes) { String[] baseExtensions = baseContentType.getFileSpecs(IContentType.FILE_EXTENSION_SPEC); for (int i = 0; i < baseExtensions.length; i++) { filenameExtensions.add(baseExtensions[i]); @@ -46,16 +49,16 @@ filenames.add(names[j]); } Arrays.sort(baseExtensions); - IContentType[] contentTypes = Platform.getContentTypeManager().getAllContentTypes(); - for (int i = 0, length = contentTypes.length; i < length; i++) { - if (contentTypes[i].isKindOf(baseContentType)) { - String[] fileExtension = contentTypes[i].getFileSpecs(IContentType.FILE_EXTENSION_SPEC); + IContentType[] allContentTypes1 = Platform.getContentTypeManager().getAllContentTypes(); + for (int i = 0, length = allContentTypes1.length; i < length; i++) { + if (allContentTypes1[i].isKindOf(baseContentType)) { + String[] fileExtension = allContentTypes1[i].getFileSpecs(IContentType.FILE_EXTENSION_SPEC); for (int j = 0; j < fileExtension.length; j++) { if (!filenameExtensions.contains(fileExtension[j])) { filenameExtensions.add(fileExtension[j]); } } - names = contentTypes[i].getFileSpecs(IContentType.FILE_NAME_SPEC); + names = allContentTypes1[i].getFileSpecs(IContentType.FILE_NAME_SPEC); for (int j = 0; j < names.length; j++) { filenames.add(names[j]); }
diff --git a/web/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/internal/contentassist/resources/ScriptWebResourcesCompletionProposalComputer.java b/web/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/internal/contentassist/resources/ScriptWebResourcesCompletionProposalComputer.java index 3a58223..0b92a51 100644 --- a/web/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/internal/contentassist/resources/ScriptWebResourcesCompletionProposalComputer.java +++ b/web/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/internal/contentassist/resources/ScriptWebResourcesCompletionProposalComputer.java
@@ -15,7 +15,6 @@ package org.eclipse.wst.html.ui.internal.contentassist.resources; import org.eclipse.core.runtime.Platform; -import org.eclipse.core.runtime.content.IContentType; import org.eclipse.wst.xml.ui.internal.contentassist.ContentAssistRequest; import org.w3c.dom.Node; @@ -24,12 +23,7 @@ ContentTypeSpecs fileMatcher = null; public ScriptWebResourcesCompletionProposalComputer() { - IContentType[] types = Platform.getContentTypeManager().findContentTypesFor("file.js"); - String[] typeNames = new String[types.length]; - for (int i = 0; i < typeNames.length; i++) { - typeNames[i] = types[i].getId(); - } - fileMatcher = ContentTypeSpecs.createFor(typeNames); + fileMatcher = ContentTypeSpecs.createFor(Platform.getContentTypeManager().findContentTypesFor("file.js")); } @Override
diff --git a/web/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/internal/wizard/FacetModuleCoreSupportDelegate.java b/web/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/internal/wizard/FacetModuleCoreSupportDelegate.java index 0c1f2ca..ea900bf 100644 --- a/web/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/internal/wizard/FacetModuleCoreSupportDelegate.java +++ b/web/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/internal/wizard/FacetModuleCoreSupportDelegate.java
@@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2019 IBM Corporation and others. + * Copyright (c) 2007, 2020 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 * which accompanies this distribution, and is available at @@ -127,16 +127,18 @@ IVirtualFolder rootFolder = component.getRootFolder(); if (rootFolder == null) continue; - IPath referencedPathRoot = rootFolder.getWorkspaceRelativePath(); /* http://bugs.eclipse.org/410161 */ - if (referencedPathRoot != null) { - /* - * See Servlet 3.0, section 4.6 ; this is the only - * referenced module/component type we support - */ - IPath resources = referencedPathRoot.append(FacetModuleCoreSupport.META_INF_RESOURCES); - if (resources != null && component.getProject().findMember(resources.removeFirstSegments(1)) != null) { - paths.add(resources); + /* + * See Servlet 3.0, section 4.6 ; this is the only + * referenced module/component type we support + */ + IVirtualFolder virtualFolder = ComponentCore.createFolder(component.getProject(), FacetModuleCoreSupport.META_INF_RESOURCES_PATH); + if (virtualFolder != null) { + IContainer[] underlyingFolders = virtualFolder.getUnderlyingFolders(); + for (int j = 0; j < underlyingFolders.length; j++) { + if (underlyingFolders[i].isAccessible()) { + paths.add(underlyingFolders[i].getFullPath()); + } } } }
diff --git a/web/tests/org.eclipse.wst.html.ui.tests/src/org/eclipse/wst/html/ui/tests/contentassist/TestHTMLContentAssistComputers.java b/web/tests/org.eclipse.wst.html.ui.tests/src/org/eclipse/wst/html/ui/tests/contentassist/TestHTMLContentAssistComputers.java index 8fea014..5412601 100644 --- a/web/tests/org.eclipse.wst.html.ui.tests/src/org/eclipse/wst/html/ui/tests/contentassist/TestHTMLContentAssistComputers.java +++ b/web/tests/org.eclipse.wst.html.ui.tests/src/org/eclipse/wst/html/ui/tests/contentassist/TestHTMLContentAssistComputers.java
@@ -211,9 +211,9 @@ strings[i] = paths[i].toString(); } assertEquals(String.valueOf(paths.length).concat(StringUtils.pack(strings)), 3, paths.length); - assertTrue(Arrays.asList(paths).stream().map((proposedPath)->proposedPath.toString()).anyMatch((pathAsString)->pathAsString.endsWith("/alsoempty.png"))); - assertTrue(Arrays.asList(paths).stream().map((proposedPath)->proposedPath.toString()).anyMatch((pathAsString)->pathAsString.endsWith("/empty.gif"))); - assertTrue(Arrays.asList(paths).stream().map((proposedPath)->proposedPath.toString()).anyMatch((pathAsString)->pathAsString.endsWith("/empty.png"))); + assertTrue(Arrays.asList(paths).stream().map((proposedPath)->proposedPath.toString()).anyMatch((pathAsString)->pathAsString.equals("/TestHTMLContentAssistComputers/targets/alsoempty.png"))); + assertTrue(Arrays.asList(paths).stream().map((proposedPath)->proposedPath.toString()).anyMatch((pathAsString)->pathAsString.equals("/TestHTMLContentAssistComputers/targets/empty.gif"))); + assertTrue(Arrays.asList(paths).stream().map((proposedPath)->proposedPath.toString()).anyMatch((pathAsString)->pathAsString.equals("/TestHTMLContentAssistComputers/targets/empty.png"))); } public void testResourceProposalsForLinkHref() throws Exception {