diff options
Diffstat (limited to 'bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core')
8 files changed, 511 insertions, 220 deletions
diff --git a/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/contentmodel/tld/CMDocumentFactoryTLD.java b/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/contentmodel/tld/CMDocumentFactoryTLD.java index 7f080ced42..7ce7e6f9cb 100644 --- a/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/contentmodel/tld/CMDocumentFactoryTLD.java +++ b/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/contentmodel/tld/CMDocumentFactoryTLD.java @@ -45,12 +45,12 @@ import org.eclipse.jst.jsp.core.internal.provisional.JSP11Namespace; import org.eclipse.jst.jsp.core.internal.provisional.JSP20Namespace; import org.eclipse.jst.jsp.core.internal.regions.DOMJSPRegionContexts; import org.eclipse.jst.jsp.core.internal.util.DocumentProvider; +import org.eclipse.jst.jsp.core.internal.util.FacetModuleCoreSupport; import org.eclipse.jst.jsp.core.taglib.IJarRecord; import org.eclipse.jst.jsp.core.taglib.ITLDRecord; import org.eclipse.jst.jsp.core.taglib.ITagDirRecord; import org.eclipse.jst.jsp.core.taglib.ITaglibRecord; import org.eclipse.jst.jsp.core.taglib.IURLRecord; -import org.eclipse.jst.jsp.core.taglib.TaglibIndex; import org.eclipse.wst.common.uriresolver.internal.util.URIHelper; import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument; import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion; @@ -766,13 +766,7 @@ public class CMDocumentFactoryTLD implements CMDocumentFactory { IPath filePath = null; String text = attributes.getValue(JSP11Namespace.ATTR_NAME_FILE); if (text != null) { - if (text.startsWith("/")) { //$NON-NLS-1$ - IPath contextRoot = TaglibIndex.getContextRoot(new Path(((CMDocumentImpl) ed.getOwnerDocument()).getBaseLocation())); - filePath = contextRoot.append(text); - } - else { - filePath = new Path(((CMDocumentImpl) ed.getOwnerDocument()).getBaseLocation()).removeLastSegments(1).append(text); - } + filePath = FacetModuleCoreSupport.resolve(new Path(((CMDocumentImpl) ed.getOwnerDocument()).getBaseLocation()), text); IFile includedFile = ResourcesPlugin.getWorkspace().getRoot().getFile(filePath); if (includedFile.isAccessible()) { loadTagXFile(ed, includedFile, false); @@ -943,14 +937,8 @@ public class CMDocumentFactoryTLD implements CMDocumentFactory { else if (region.getType() == DOMRegionContext.XML_TAG_ATTRIBUTE_VALUE && attrName != null) { text = StringUtils.strip(text); if (JSP11Namespace.ATTR_NAME_FILE.equals(attrName)) { - IPath filePath = null; - if (text.startsWith("/")) { //$NON-NLS-1$ - IPath contextRoot = TaglibIndex.getContextRoot(new Path(((CMDocumentImpl) ed.getOwnerDocument()).getBaseLocation())); - filePath = contextRoot.append(text); - } - else { - filePath = new Path(((CMDocumentImpl) ed.getOwnerDocument()).getBaseLocation()).removeLastSegments(1).append(text); - } + IPath filePath = FacetModuleCoreSupport.resolve(new Path(((CMDocumentImpl) ed.getOwnerDocument()).getBaseLocation()), text); + IFile includedFile = ResourcesPlugin.getWorkspace().getRoot().getFile(filePath); if (includedFile.isAccessible()) { loadTagFile(ed, includedFile, false); diff --git a/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/contentmodel/tld/TLDCMDocumentManager.java b/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/contentmodel/tld/TLDCMDocumentManager.java index 8e4ef9d681..224ae1a2a2 100644 --- a/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/contentmodel/tld/TLDCMDocumentManager.java +++ b/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/contentmodel/tld/TLDCMDocumentManager.java @@ -40,6 +40,7 @@ import org.eclipse.jst.jsp.core.internal.contenttype.DeploymentDescriptorPropert import org.eclipse.jst.jsp.core.internal.parser.JSPSourceParser; import org.eclipse.jst.jsp.core.internal.provisional.JSP12Namespace; import org.eclipse.jst.jsp.core.internal.regions.DOMJSPRegionContexts; +import org.eclipse.jst.jsp.core.internal.util.FacetModuleCoreSupport; import org.eclipse.jst.jsp.core.internal.util.FileContentCache; import org.eclipse.jst.jsp.core.internal.util.ZeroStructuredDocumentRegion; import org.eclipse.jst.jsp.core.taglib.IJarRecord; @@ -245,16 +246,11 @@ public class TLDCMDocumentManager implements ITaglibIndexListener { // strip any extraneous quotes and white space includedFile = StringUtils.strip(includedFile).trim(); IPath filePath = null; - if (includedFile.startsWith("/")) { //$NON-NLS-1$ - IPath contextRoot = TaglibIndex.getContextRoot(TaglibController.getFileBuffer(TLDCMDocumentManager.this).getLocation()); - filePath = contextRoot.append(includedFile); - } - else { - if (getIncludes().isEmpty()) - filePath = TaglibController.getFileBuffer(TLDCMDocumentManager.this).getLocation().removeLastSegments(1).append(includedFile); - else - filePath = ((IPath) getIncludes().peek()).removeLastSegments(1).append(includedFile); - } + if (getIncludes().isEmpty()) + filePath = FacetModuleCoreSupport.resolve(TaglibController.getFileBuffer(TLDCMDocumentManager.this).getLocation(), includedFile); + else + filePath = FacetModuleCoreSupport.resolve((IPath) getIncludes().peek(), includedFile); + // check for "loops" if (filePath != null && !getIncludes().contains(filePath) && !filePath.equals(TaglibController.getFileBuffer(TLDCMDocumentManager.this).getLocation())) { /* diff --git a/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/contenttype/DeploymentDescriptorPropertyCache.java b/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/contenttype/DeploymentDescriptorPropertyCache.java index cad9f0b968..b8c7c79c04 100644 --- a/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/contenttype/DeploymentDescriptorPropertyCache.java +++ b/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/contenttype/DeploymentDescriptorPropertyCache.java @@ -13,7 +13,6 @@ package org.eclipse.jst.jsp.core.internal.contenttype; import java.io.ByteArrayInputStream; import java.io.IOException; -import java.io.InputStream; import java.io.StringReader; import java.lang.ref.Reference; import java.lang.ref.SoftReference; @@ -25,6 +24,7 @@ import java.util.Map; import javax.xml.parsers.DocumentBuilder; import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResourceChangeEvent; import org.eclipse.core.resources.IResourceChangeListener; @@ -39,8 +39,8 @@ import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.SubProgressMonitor; import org.eclipse.jst.jsp.core.internal.Logger; import org.eclipse.jst.jsp.core.internal.util.CommonXML; +import org.eclipse.jst.jsp.core.internal.util.FacetModuleCoreSupport; import org.eclipse.jst.jsp.core.internal.util.FileContentCache; -import org.eclipse.jst.jsp.core.taglib.TaglibIndex; import org.eclipse.wst.sse.core.StructuredModelManager; import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel; import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument; @@ -69,13 +69,8 @@ public class DeploymentDescriptorPropertyCache { Float version = new Float(defaultWebAppVersion); } - private static class FacetCore { - long modificationStamp; - float version = defaultWebAppVersion; - } - /** - * Represntation of the JSP 2.0 property-group definitions from a servlet + * Representation of the JSP 2.0 property-group definitions from a servlet * deployment descriptor. */ public static final class PropertyGroup { @@ -134,7 +129,7 @@ public class DeploymentDescriptorPropertyCache { private boolean scripting_invalid; String url_pattern; private IPath webxmlPath; - + int number; private PropertyGroup(IPath path, int number) { @@ -225,7 +220,7 @@ public class DeploymentDescriptorPropertyCache { this.matcher = new StringMatcher(url_pattern); } } - + public String toString() { return number + ":" + url_pattern; } @@ -539,10 +534,6 @@ public class DeploymentDescriptorPropertyCache { private static final float defaultWebAppVersion = 2.4f; private static String EL_IGNORED = "el-ignored"; - private static final String FACET_FACET = "facet"; - private static final String FACET_INSTALLED = "installed"; - private static final String FACET_VERSION = "version"; - private static final String FACET_WEB_APP = "jst.web"; private static String ID = "id"; private static String INCLUDE_CODA = "include-coda"; private static String INCLUDE_PRELUDE = "include-prelude"; @@ -559,7 +550,9 @@ public class DeploymentDescriptorPropertyCache { private static final String WEB_APP_VERSION_NAME = "version"; private static final String WEB_INF = "WEB-INF"; private static final String WEB_XML = "web.xml"; - private static final String WEB_INF_WEB_XML = WEB_INF + IPath.SEPARATOR + WEB_XML; + // private static final String WEB_INF_WEB_XML = WEB_INF + IPath.SEPARATOR + // + WEB_XML; + private static final String SLASH_WEB_INF_WEB_XML = Path.ROOT.toString() + WEB_INF + IPath.SEPARATOR + WEB_XML; static String getContainedText(Node parent) { NodeList children = parent.getChildNodes(); @@ -601,7 +594,6 @@ public class DeploymentDescriptorPropertyCache { private ResourceErrorHandler errorHandler; private Map fDeploymentDescriptors = new Hashtable(); - private Map fFacetCores = new Hashtable(); private IResourceChangeListener fResourceChangeListener = new ResourceChangeListener(); @@ -679,11 +671,10 @@ public class DeploymentDescriptorPropertyCache { DocumentBuilder builder = CommonXML.getDocumentBuilder(false); builder.setEntityResolver(getEntityResolver()); builder.setErrorHandler(getErrorHandler(file.getFullPath())); - InputStream is = null; - try { + try { InputSource inputSource = new InputSource(); - is = file.getContents(); - inputSource.setByteStream(is); + String s = FileContentCache.getInstance().getContents(file.getFullPath()); + inputSource.setCharacterStream(new StringReader(s)); inputSource.setSystemId(file.getFullPath().toString()); Document document = builder.parse(inputSource); _parseDocument(file, version, groupList, subMonitor, document); @@ -715,21 +706,7 @@ public class DeploymentDescriptorPropertyCache { catch (IOException e1) { /* file is unreadable, create no property groups */ } - catch (CoreException e) { - /* - * file is unreadable, create no property groups but log the - * exception - */ - Logger.logException(e); - } finally { - if (is != null) - try { - is.close(); - } - catch (IOException e) { - // nothing to do - } groups = (PropertyGroup[]) groupList.toArray(new PropertyGroup[groupList.size()]); subMonitor.done(); } @@ -747,45 +724,6 @@ public class DeploymentDescriptorPropertyCache { return deploymentDescriptor; } - private FacetCore fetchFacetCore(IFile facetConfigFile) { - FacetCore facetCore = new FacetCore(); - facetCore.modificationStamp = facetConfigFile.getModificationStamp(); - facetCore.version = defaultWebAppVersion; - - DocumentBuilder builder = CommonXML.getDocumentBuilder(false); - builder.setEntityResolver(getEntityResolver()); - builder.setErrorHandler(getErrorHandler(facetConfigFile.getFullPath())); - String input = null; - try { - InputSource inputSource = new InputSource(); - input = FileContentCache.getInstance().getContents(facetConfigFile.getFullPath()); - inputSource.setCharacterStream(new StringReader(input)); - inputSource.setSystemId(facetConfigFile.getFullPath().toString()); - Document document = builder.parse(inputSource); - NodeList installedList = document.getElementsByTagName(FACET_INSTALLED); - for (int i = 0; i < installedList.getLength(); i++) { - Element installed = (Element) installedList.item(i); - String facetName = installed.getAttribute(FACET_FACET); - if (FACET_WEB_APP.equals(facetName)) { - try { - facetCore.version = Float.valueOf(installed.getAttribute(FACET_VERSION)).floatValue(); - } - catch (NumberFormatException e) { - // badly written file - } - } - } - } - catch (SAXException e1) { - Logger.logException(e1); - } - catch (IOException e1) { - // unlikely - } - fFacetCores.put(facetConfigFile.getFullPath(), new SoftReference(facetCore)); - return facetCore; - } - private EntityResolver getEntityResolver() { if (resolver == null) { resolver = new EntityResolver() { @@ -819,9 +757,9 @@ public class DeploymentDescriptorPropertyCache { */ public float getJSPVersion(IPath fullPath) { float version = defaultWebAppVersion; - IPath contextRoot = TaglibIndex.getContextRoot(fullPath); - if (contextRoot != null) { - IPath webxmlPath = contextRoot.append(WEB_INF_WEB_XML); + /* try applicable web.xml file first */ + IPath webxmlPath = FacetModuleCoreSupport.resolve(fullPath, SLASH_WEB_INF_WEB_XML); + if (webxmlPath != null) { IFile webxmlFile = ResourcesPlugin.getWorkspace().getRoot().getFile(webxmlPath); if (webxmlFile.isAccessible()) { Reference descriptorHolder = (Reference) fDeploymentDescriptors.get(webxmlPath); @@ -837,18 +775,11 @@ public class DeploymentDescriptorPropertyCache { } } } - // Parse the .settings/org.eclipse.wst.common.project.facet.core.xml - IPath facetConfigPath = new Path(fullPath.makeAbsolute().segment(0)).append(".settings/org.eclipse.wst.common.project.facet.core.xml"); - IFile facetConfigFile = ResourcesPlugin.getWorkspace().getRoot().getFile(facetConfigPath); - if (facetConfigFile.isAccessible()) { - FacetCore facetCore = null; - Reference facetCoreHolder = (Reference) fFacetCores.get(facetConfigPath); - if (facetCoreHolder == null || ((facetCore = (FacetCore) facetCoreHolder.get()) == null) || (facetCore.modificationStamp == IResource.NULL_STAMP) || (facetCore.modificationStamp != facetConfigFile.getModificationStamp())) { - facetCore = fetchFacetCore(facetConfigFile); - version = facetCore.version; - } - } + /* check facet settings */ + IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(fullPath.segment(0)); + version = FacetModuleCoreSupport.getDynamicWebProjectVersion(project); + return convertSpecVersions(version); } @@ -861,11 +792,10 @@ public class DeploymentDescriptorPropertyCache { */ public PropertyGroup[] getPropertyGroups(IPath jspFilePath) { List matchingGroups = new ArrayList(1); - IPath contextRoot = TaglibIndex.getContextRoot(jspFilePath); - if (contextRoot == null) + IPath webxmlPath = FacetModuleCoreSupport.resolve(jspFilePath, SLASH_WEB_INF_WEB_XML); + if (webxmlPath == null) return NO_PROPERTY_GROUPS; - IPath webxmlPath = contextRoot.append(WEB_INF_WEB_XML); IFile webxmlFile = ResourcesPlugin.getWorkspace().getRoot().getFile(webxmlPath); if (!webxmlFile.isAccessible()) return NO_PROPERTY_GROUPS; @@ -878,13 +808,13 @@ public class DeploymentDescriptorPropertyCache { } for (int i = 0; i < descriptor.groups.length; i++) { - if (descriptor.groups[i].matches(jspFilePath.removeFirstSegments(contextRoot.segmentCount()).makeAbsolute().toString(), false)) { + if (descriptor.groups[i].matches(FacetModuleCoreSupport.getRuntimePath(jspFilePath).toString(), false)) { matchingGroups.add(descriptor.groups[i]); } } if (matchingGroups.isEmpty()) { for (int i = 0; i < descriptor.groups.length; i++) { - if (descriptor.groups[i].matches(jspFilePath.removeFirstSegments(contextRoot.segmentCount()).toString(), true)) { + if (descriptor.groups[i].matches(FacetModuleCoreSupport.getRuntimePath(jspFilePath).toString(), true)) { matchingGroups.add(descriptor.groups[i]); } } diff --git a/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/util/FacetModuleCoreSupport.java b/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/util/FacetModuleCoreSupport.java new file mode 100644 index 0000000000..d61c3a280d --- /dev/null +++ b/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/util/FacetModuleCoreSupport.java @@ -0,0 +1,198 @@ +/******************************************************************************* + * Copyright (c) 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jst.jsp.core.internal.util; + +import org.eclipse.core.filebuffers.FileBuffers; +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IFolder; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IWorkspaceRoot; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; + +/** + * This class encapsulates any used Module Core and Facets APIs along with + * fallbacks for use on non-compliant projects and when those services are not + * available at runtime. + * + * Because ModuleCore API calls can result in locks needing to be acquired, + * none of these methods should be called while other thread locks have + * already been acquired. + */ +public final class FacetModuleCoreSupport { + static final boolean _dump_NCDFE = true; + private static final String WEB_INF = "WEB-INF"; //$NON-NLS-1$ + private static final IPath WEB_INF_PATH = new Path(WEB_INF); + + /** + * @param project + * @return -1 if the project does not have the JST Web facet, the version + * number of it otherwise + * @throws CoreException + */ + public static float getDynamicWebProjectVersion(IProject project) { + // In the absence of any facet information, assume the highest level + float version = 2.5f; + try { + version = FacetModuleCoreSupportDelegate.getDynamicWebProjectVersion(project); + } + catch (NoClassDefFoundError e) { + if (_dump_NCDFE) + e.printStackTrace(); + } + return version; + } + + /** + * @param project + * @return the IPath to the "root" of the web contents + */ + public static IPath getWebContentRootPath(IProject project) { + IPath path = null; + try { + path = FacetModuleCoreSupportDelegate.getWebContentRootPath(project); + } + catch (NoClassDefFoundError e) { + if (_dump_NCDFE) + e.printStackTrace(); + } + return path; + } + + public static IPath getRuntimePath(IPath path) { + IPath result = null; + try { + result = FacetModuleCoreSupportDelegate.getRuntimePath(path); + } + catch (NoClassDefFoundError e) { + if (_dump_NCDFE) + e.printStackTrace(); + } + if (result == null) { + IPath root = getLocalRoot(path); + result = path.removeFirstSegments(root.segmentCount()).makeAbsolute(); + } + return result; + } + + /** + * @param project + * @return + * @throws CoreException + */ + public static boolean isDynamicWebProject(IProject project) { + try { + return FacetModuleCoreSupportDelegate.isDynamicWebProject(project); + } + catch (NoClassDefFoundError e) { + if (_dump_NCDFE) + e.printStackTrace(); + } + return true; + } + + /** + * @param basePath - + * the full path to a resource within the workspace + * @param reference - + * the reference string to resolve + * @return - the full path within the workspace that corresponds to the + * given reference according to the virtual pathing support + */ + public static IPath resolve(IPath basePath, String reference) { + IPath resolvedPath = null; + try { + resolvedPath = FacetModuleCoreSupportDelegate.resolve(basePath, reference); + } + catch (NoClassDefFoundError e) { + if (_dump_NCDFE) + e.printStackTrace(); + } + + if (resolvedPath == null) { + IPath rootPath = getLocalRoot(basePath); + if (reference.startsWith(Path.ROOT.toString())) { + resolvedPath = rootPath.append(reference); + } + else { + resolvedPath = basePath.removeLastSegments(1).append(reference); + } + } + + return resolvedPath; + } + + /** + * @param basePath + * @return the applicable Web context root path, if one exists + */ + private static IPath getLocalRoot(IPath basePath) { + IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot(); + + // existing workspace resources - this is the 93% case + IResource file = FileBuffers.getWorkspaceFileAtLocation(basePath); + + // Try the base path as a folder first + if (file == null && basePath.segmentCount() > 1) { + file = workspaceRoot.getFolder(basePath); + } + // If not a folder, then try base path as a file + if (file != null && !file.exists() && basePath.segmentCount() > 1) { + file = workspaceRoot.getFile(basePath); + } + + if (file == null && basePath.segmentCount() == 1) { + file = workspaceRoot.getProject(basePath.segment(0)); + } + + if (file == null) { + /* + * https://bugs.eclipse.org/bugs/show_bug.cgi?id=116529 + * + * This method produces a less accurate result, but doesn't + * require that the file exist yet. + */ + IFile[] files = ResourcesPlugin.getWorkspace().getRoot().findFilesForLocation(basePath); + if (files.length > 0) + file = files[0]; + } + + while (file != null) { + /** + * Treat any parent folder with a WEB-INF subfolder as a web-app + * root + */ + IContainer folder = null; + if ((file.getType() & IResource.FOLDER) != 0) { + folder = (IContainer) file; + } + else { + folder = file.getParent(); + } + // getFolder on a workspace root must use a full path, skip + if (folder != null && (folder.getType() & IResource.ROOT) == 0) { + IFolder webinf = folder.getFolder(WEB_INF_PATH); + if (webinf != null && webinf.exists()) { + return folder.getFullPath(); + } + } + file = file.getParent(); + } + + return basePath.uptoSegment(1); + } + + +} diff --git a/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/util/FacetModuleCoreSupportDelegate.java b/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/util/FacetModuleCoreSupportDelegate.java new file mode 100644 index 0000000000..fa38a28d2f --- /dev/null +++ b/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/util/FacetModuleCoreSupportDelegate.java @@ -0,0 +1,174 @@ +/******************************************************************************* + * Copyright (c) 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jst.jsp.core.internal.util; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; +import org.eclipse.jst.jsp.core.internal.Logger; +import org.eclipse.wst.common.componentcore.ComponentCore; +import org.eclipse.wst.common.componentcore.ModuleCoreNature; +import org.eclipse.wst.common.componentcore.resources.IVirtualComponent; +import org.eclipse.wst.common.componentcore.resources.IVirtualFile; +import org.eclipse.wst.common.componentcore.resources.IVirtualResource; +import org.eclipse.wst.common.project.facet.core.IFacetedProject; +import org.eclipse.wst.common.project.facet.core.IProjectFacet; +import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager; + +/** + * Wrapper class for all Facet-related calls. If the Facet or ModuleCore + * bundles are not available, this class will not load, or if it does, its + * methods will cause NoClassDefFoundErrors. This allows us to + * compartmentalize the dependencies. + * + */ +final class FacetModuleCoreSupportDelegate { + private static final String SLASH = "/"; + + /* + * org.eclipse.wst.common.componentcore.internal.util.IModuleConstants.JST_WEB_MODULE + */ + private final static String JST_WEB_MODULE = "jst.web"; //$NON-NLS-1$ + + /** + * @param project + * @return -1 if the project does not have the JST Web facet, the version + * number of it otherwise + * @throws CoreException + */ + static float getDynamicWebProjectVersion(IProject project) { + // In the absence of any facet information, assume the highest level + float version = 2.5f; + try { + IFacetedProject faceted = ProjectFacetsManager.create(project); + if (faceted != null) { + IProjectFacet webModuleFacet = ProjectFacetsManager.getProjectFacet(JST_WEB_MODULE); + if (faceted.hasProjectFacet(webModuleFacet)) { + version = Float.parseFloat(faceted.getInstalledVersion(webModuleFacet).getVersionString()); + } + } + } + catch (NumberFormatException e) { + Logger.logException(e); + } + catch (CoreException e) { + Logger.logException(e); + } + return version; + } + + /** + * @param path - + * the full path to a resource within the workspace + * @return - the runtime path of the resource if one exists, null + * otherwise + */ + static IPath getRuntimePath(IPath path) { + IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(path.segment(0)); + + if (!ModuleCoreNature.isFlexibleProject(project)) + return null; + + IVirtualResource[] virtualResources = ComponentCore.createResources(ResourcesPlugin.getWorkspace().getRoot().getFile(path)); + if (virtualResources != null && virtualResources.length > 0) { + return virtualResources[0].getRuntimePath(); + } + return null; + } + + /** + * @param project + * @return the IPath to the "root" of the web contents + */ + static IPath getWebContentRootPath(IProject project) { + if (!ModuleCoreNature.isFlexibleProject(project)) + return null; + + IPath path = null; + IVirtualComponent component = ComponentCore.createComponent(project); + if (component != null && component.exists()) { + path = component.getRootFolder().getWorkspaceRelativePath(); + } + return path; + } + + /** + * @param project + * @return + * @throws CoreException + */ + static boolean isDynamicWebProject(IProject project) { + try { + IFacetedProject faceted = ProjectFacetsManager.create(project); + IProjectFacet webModuleFacet = ProjectFacetsManager.getProjectFacet(JST_WEB_MODULE); + if (faceted != null && faceted.hasProjectFacet(webModuleFacet)) { + return true; + } + } + catch (CoreException e) { + Logger.logException(e); + } + return false; + } + + /** + * @param basePath - + * the full path to a resource within the workspace + * @param reference - + * the reference string to resolve + * @return - the full path within the workspace that corresponds to the + * given reference according to the virtual pathing support + */ + static IPath resolve(IPath basePath, String reference) { + if (reference == null || basePath == null || basePath.segmentCount() == 0) + return null; + + IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(basePath.segment(0)); + + if (!ModuleCoreNature.isFlexibleProject(project)) + return null; + + if (basePath.segmentCount() > 1) { + IFile baseFile = ResourcesPlugin.getWorkspace().getRoot().getFile(basePath); + IVirtualResource[] virtualResources = ComponentCore.createResources(baseFile); + for (int i = 0; i < virtualResources.length; i++) { + IPath baseRuntimePath = virtualResources[i].getRuntimePath(); + IPath referenceRuntimePath = null; + if (reference.startsWith(SLASH)) { + referenceRuntimePath = new Path(reference); + } + else { + referenceRuntimePath = baseRuntimePath.removeLastSegments(1).append(reference); + } + IVirtualFile virtualFile = ComponentCore.createFile(project, referenceRuntimePath); + if (virtualFile != null && virtualFile.exists()) { + IFile[] underlyingFiles = virtualFile.getUnderlyingFiles(); + for (int j = 0; j < underlyingFiles.length; j++) { + if (underlyingFiles[j].getProject().equals(project) && underlyingFiles[j].exists()) { + return underlyingFiles[j].getFullPath(); + } + + } + } + } + } + else { + IVirtualFile virtualFile = ComponentCore.createFile(project, new Path(reference)); + if (virtualFile != null && virtualFile.exists()) { + return virtualFile.getUnderlyingFile().getFullPath(); + } + } + return null; + } +} diff --git a/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/validation/JSPDirectiveValidator.java b/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/validation/JSPDirectiveValidator.java index 525180a0b2..5e09e15731 100644 --- a/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/validation/JSPDirectiveValidator.java +++ b/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/validation/JSPDirectiveValidator.java @@ -19,12 +19,12 @@ import java.util.Locale; import org.eclipse.core.resources.IFile; import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Platform; import org.eclipse.jst.jsp.core.internal.JSPCoreMessages; import org.eclipse.jst.jsp.core.internal.Logger; import org.eclipse.jst.jsp.core.internal.provisional.JSP11Namespace; import org.eclipse.jst.jsp.core.internal.regions.DOMJSPRegionContexts; +import org.eclipse.jst.jsp.core.internal.util.FacetModuleCoreSupport; import org.eclipse.jst.jsp.core.taglib.ITaglibRecord; import org.eclipse.jst.jsp.core.taglib.TaglibIndex; import org.eclipse.osgi.util.NLS; @@ -183,13 +183,8 @@ public class JSPDirectiveValidator extends JSPValidator { reporter.addMessage(fMessageOriginator, message); } else if (fSeverityIncludeFileMissing != NO_SEVERITY) { - IPath testPath = null; - if (fileValue.startsWith("/")) { - testPath = TaglibIndex.getContextRoot(file.getFullPath()).append(new Path(fileValue)); - } - else { - testPath = file.getFullPath().removeLastSegments(1).append(new Path(fileValue)); - } + IPath testPath = FacetModuleCoreSupport.resolve(file.getFullPath(), fileValue); + IFile testFile = file.getWorkspace().getRoot().getFile(testPath); if (!testFile.isAccessible()) { // File not found @@ -394,16 +389,14 @@ public class JSPDirectiveValidator extends JSPValidator { LocalizedMessage message = (file == null ? new LocalizedMessage(severity, msgText) : new LocalizedMessage(severity, msgText, file)); // if there's a message, there was an error found - if (message != null) { - int start = documentRegion.getStartOffset(valueRegion); - int length = valueRegion.getTextLength(); - int lineNo = document.getLineOfOffset(start); - message.setLineNo(lineNo); - message.setOffset(start); - message.setLength(length); + int start = documentRegion.getStartOffset(valueRegion); + int length = valueRegion.getTextLength(); + int lineNo = document.getLineOfOffset(start); + message.setLineNo(lineNo); + message.setOffset(start); + message.setLength(length); - reporter.addMessage(fMessageOriginator, message); - } + reporter.addMessage(fMessageOriginator, message); } } } diff --git a/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/taglib/ProjectDescription.java b/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/taglib/ProjectDescription.java index c4a9a863d8..e069f66aa7 100644 --- a/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/taglib/ProjectDescription.java +++ b/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/taglib/ProjectDescription.java @@ -57,6 +57,8 @@ import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.jobs.ILock; +import org.eclipse.core.runtime.jobs.Job; import org.eclipse.jdt.core.IClasspathContainer; import org.eclipse.jdt.core.IClasspathEntry; import org.eclipse.jdt.core.IJavaElement; @@ -70,6 +72,7 @@ import org.eclipse.jface.text.IRegion; import org.eclipse.jst.jsp.core.internal.Logger; import org.eclipse.jst.jsp.core.internal.contentmodel.tld.provisional.JSP11TLDNames; import org.eclipse.jst.jsp.core.internal.contentmodel.tld.provisional.JSP12TLDNames; +import org.eclipse.jst.jsp.core.internal.contenttype.DeploymentDescriptorPropertyCache; import org.eclipse.jst.jsp.core.internal.util.DocumentProvider; import org.eclipse.wst.common.uriresolver.internal.util.URIHelper; import org.eclipse.wst.sse.core.internal.util.JarUtilities; @@ -536,6 +539,8 @@ class ProjectDescription { IResourceDeltaVisitor fVisitor; Hashtable fWebXMLReferences; + ILock LOCK = Job.getJobManager().newLock(); + private long time0; ProjectDescription(IProject project, String saveStateFile) { @@ -606,7 +611,7 @@ class ProjectDescription { projectsProcessed.add(buildpathProjects[i]); ProjectDescription description = TaglibIndex.getInstance().createDescription(buildpathProjects[i]); description.addBuildPathReferences(references, projectsProcessed, true); - + /* * 199843 (183756) - JSP Validation Cannot Find Tag Library * Descriptor in Referenced Projects @@ -888,6 +893,8 @@ class ProjectDescription { } private void ensureUpTodate() { + LOCK.acquire(); + if (!fBuildPathIsDirty) { /* * Double-check that the number of build path entries has not @@ -909,6 +916,8 @@ class ProjectDescription { indexClasspath(); fBuildPathIsDirty = false; } + + LOCK.release(); } private TaglibInfo extractInfo(String basePath, InputStream tldContents) { @@ -957,24 +966,37 @@ class ProjectDescription { return info; } - synchronized List getAvailableTaglibRecords(IPath path) { + List getAvailableTaglibRecords(IPath path) { ensureUpTodate(); + float jspVersion = DeploymentDescriptorPropertyCache.getInstance().getJSPVersion(path); + + LOCK.acquire(); + Collection implicitReferences = new HashSet(getImplicitReferences(path.toString()).values()); Collection records = new ArrayList(fTLDReferences.size() + fTagDirReferences.size() + fJARReferences.size() + fWebXMLReferences.size()); records.addAll(fTLDReferences.values()); - records.addAll(fTagDirReferences.values()); - records.addAll(_getJSP11AndWebXMLJarReferences(fJARReferences.values())); - records.addAll(implicitReferences); + if (jspVersion >= 1.1) { + records.addAll(_getJSP11AndWebXMLJarReferences(fJARReferences.values())); + } - Map buildPathReferences = new HashMap(); - List projectsProcessed = new ArrayList(fClasspathProjects.size() + 1); - projectsProcessed.add(fProject); - addBuildPathReferences(buildPathReferences, projectsProcessed, false); - records.addAll(buildPathReferences.values()); + if (jspVersion >= 1.2) { + records.addAll(implicitReferences); + + Map buildPathReferences = new HashMap(); + List projectsProcessed = new ArrayList(fClasspathProjects.size() + 1); + projectsProcessed.add(fProject); + addBuildPathReferences(buildPathReferences, projectsProcessed, false); + records.addAll(buildPathReferences.values()); + } + if (jspVersion >= 2.0) { + records.addAll(fTagDirReferences.values()); + } records.addAll(getCatalogRecords()); + LOCK.release(); + return new ArrayList(records); } @@ -1079,6 +1101,7 @@ class ProjectDescription { /** * @param basePath * @return the applicable Web context root path, if one exists + * @deprecated */ IPath getLocalRoot(IPath basePath) { IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot(); @@ -1462,6 +1485,9 @@ class ProjectDescription { ITaglibRecord record = null; String path = null; + float jspVersion = DeploymentDescriptorPropertyCache.getInstance().getJSPVersion(new Path(basePath)); + + LOCK.acquire(); /** * Workaround for problem in URIHelper; uris starting with '/' are @@ -1473,33 +1499,30 @@ class ProjectDescription { else { path = URIHelper.normalize(reference, basePath, getLocalRoot(basePath)); } + // order dictated by JSP spec 2.0 section 7.2.3 - // if (record == null) { - // record = (ITaglibRecord) fWebXMLReferences.get(path); - // } - if (record == null) { - record = (ITaglibRecord) fJARReferences.get(path); - // only if 1.1 TLD was found - if (record instanceof JarRecord && !((JarRecord) record).has11TLD) { - record = null; - } + record = (ITaglibRecord) fJARReferences.get(path); + + // only if 1.1 TLD was found + if (jspVersion < 1.1 || (record instanceof JarRecord && !((JarRecord) record).has11TLD)) { + record = null; } if (record == null) { record = (ITaglibRecord) fTLDReferences.get(path); } - if (record == null) { + if (record == null && jspVersion >= 1.2) { record = (ITaglibRecord) getImplicitReferences(basePath).get(reference); } - if (record == null) { + if (record == null && jspVersion >= 2.0) { record = (ITaglibRecord) fTagDirReferences.get(path); } - if (record == null) { + if (record == null && jspVersion >= 1.2) { record = (ITaglibRecord) fClasspathReferences.get(reference); } - if (record == null) { + if (record == null && jspVersion >= 1.2) { Map buildPathReferences = new HashMap(); List projectsProcessed = new ArrayList(fClasspathProjects.size() + 1); projectsProcessed.add(fProject); @@ -1533,8 +1556,10 @@ class ProjectDescription { } } - // If no records were found and no local-root applies, check ALL of - // the web.xml files as a fallback + /* + * If no records were found and no local-root applies, check ALL + * of the web.xml files as a fallback + */ if (record == null && fProject.getFullPath().toString().equals(getLocalRoot(basePath))) { WebXMLRecord[] webxmls = (WebXMLRecord[]) fWebXMLReferences.values().toArray(new WebXMLRecord[0]); for (int i = 0; i < webxmls.length; i++) { @@ -1543,8 +1568,9 @@ class ProjectDescription { record = (ITaglibRecord) getImplicitReferences(webxmls[i].path.toString()).get(reference); } } - - + + LOCK.release(); + return record; } diff --git a/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/taglib/TaglibIndex.java b/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/taglib/TaglibIndex.java index b0e9e33085..564ca9db3e 100644 --- a/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/taglib/TaglibIndex.java +++ b/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/taglib/TaglibIndex.java @@ -35,6 +35,7 @@ import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.jobs.ILock; +import org.eclipse.core.runtime.jobs.Job; import org.eclipse.jdt.core.ElementChangedEvent; import org.eclipse.jdt.core.IElementChangedListener; import org.eclipse.jdt.core.IJavaElement; @@ -205,7 +206,7 @@ public final class TaglibIndex { IResourceDelta[] deltas = new IResourceDelta[]{event.getDelta()}; IProject[] projects = null; - if (deltas != null && deltas.length > 0) { + if (deltas.length > 0) { IResource resource = null; if (deltas[0] != null) { resource = deltas[0].getResource(); @@ -258,7 +259,7 @@ public final class TaglibIndex { IResourceDelta[] deltas = new IResourceDelta[]{event.getDelta()}; IProject[] projects = null; - if (deltas != null && deltas.length > 0) { + if (deltas.length > 0) { IResource resource = null; if (deltas[0] != null) { resource = deltas[0].getResource(); @@ -348,7 +349,7 @@ public final class TaglibIndex { private static final String DIRTY = "DIRTY"; static boolean ENABLED = false; - static ILock LOCK = Platform.getJobManager().newLock(); + static ILock LOCK = Job.getJobManager().newLock(); /** * NOT API. @@ -357,14 +358,8 @@ public final class TaglibIndex { * the listener to be added */ public static void addTaglibIndexListener(ITaglibIndexListener listener) { - try { - LOCK.acquire(); - if (getInstance().isInitialized()) - getInstance().internalAddTaglibIndexListener(listener); - } - finally { - LOCK.release(); - } + if (getInstance().isInitialized()) + getInstance().internalAddTaglibIndexListener(listener); } static void fireTaglibDelta(ITaglibIndexDelta delta) { @@ -418,9 +413,6 @@ public final class TaglibIndex { * Finds all of the visible ITaglibRecords for the given path in the * workspace. Taglib mappings from web.xml files are only visible to paths * within the web.xml's corresponding web content folder. - * <p> - * Values defined within the XML Catalog will not be returned. - * </p> * * @param fullPath - * a path within the workspace @@ -430,21 +422,15 @@ public final class TaglibIndex { if (!_instance.isInitialized()) { return new ITaglibRecord[0]; } - try { - LOCK.acquire(); - ITaglibRecord[] records = null; - if (getInstance().isInitialized()) { - records = getInstance().internalGetAvailableTaglibRecords(fullPath); - } - else { - records = new ITaglibRecord[0]; - } - return records; + ITaglibRecord[] records = null; + if (getInstance().isInitialized()) { + records = getInstance().internalGetAvailableTaglibRecords(fullPath); } - finally { - LOCK.release(); - getInstance().fireCurrentDelta("enumerate: " + fullPath); //$NON-NLS-1$ + else { + records = new ITaglibRecord[0]; } + getInstance().fireCurrentDelta("enumerate: " + fullPath); //$NON-NLS-1$ + return records; } /** @@ -484,14 +470,8 @@ public final class TaglibIndex { public static void removeTaglibIndexListener(ITaglibIndexListener listener) { if (!getInstance().isInitialized()) return; - try { - LOCK.acquire(); - if (getInstance().isInitialized()) - getInstance().internalRemoveTaglibIndexListener(listener); - } - finally { - LOCK.release(); - } + if (getInstance().isInitialized()) + getInstance().internalRemoveTaglibIndexListener(listener); } /** @@ -514,14 +494,8 @@ public final class TaglibIndex { */ public static ITaglibRecord resolve(String basePath, String reference, boolean crossProjects) { ITaglibRecord result = null; - try { - LOCK.acquire(); - if (getInstance().isInitialized()) { - result = getInstance().internalResolve(basePath, reference, crossProjects); - } - } - finally { - LOCK.release(); + if (getInstance().isInitialized()) { + result = getInstance().internalResolve(basePath, reference, crossProjects); } getInstance().fireCurrentDelta("resolve: " + reference); //$NON-NLS-1$ if (_debugResolution) { @@ -679,6 +653,7 @@ public final class TaglibIndex { */ ProjectDescription createDescription(IProject project) { ProjectDescription description = null; + LOCK.acquire(); description = (ProjectDescription) fProjectDescriptions.get(project); if (description == null) { // Once we've started indexing, we're dirty again @@ -688,6 +663,7 @@ public final class TaglibIndex { description = new ProjectDescription(project, computeIndexLocation(project.getFullPath())); fProjectDescriptions.put(project, description); } + LOCK.release(); return description; } @@ -747,15 +723,21 @@ public final class TaglibIndex { } private void internalAddTaglibIndexListener(ITaglibIndexListener listener) { - if (fTaglibIndexListeners == null) { - fTaglibIndexListeners = new ITaglibIndexListener[]{listener}; - } - else { - List listeners = new ArrayList(Arrays.asList(fTaglibIndexListeners)); - if (!listeners.contains(listener)) { - listeners.add(listener); + try { + LOCK.acquire(); + if (fTaglibIndexListeners == null) { + fTaglibIndexListeners = new ITaglibIndexListener[]{listener}; + } + else { + List listeners = new ArrayList(Arrays.asList(fTaglibIndexListeners)); + if (!listeners.contains(listener)) { + listeners.add(listener); + } + fTaglibIndexListeners = (ITaglibIndexListener[]) listeners.toArray(new ITaglibIndexListener[0]); } - fTaglibIndexListeners = (ITaglibIndexListener[]) listeners.toArray(new ITaglibIndexListener[0]); + } + finally { + LOCK.release(); } } @@ -802,16 +784,20 @@ public final class TaglibIndex { IPath root = path.makeAbsolute(); while (root.segmentCount() > 0 && !root.isRoot()) root = root.removeLastSegments(1); - if (root == null) - root = path; return root; } private void internalRemoveTaglibIndexListener(ITaglibIndexListener listener) { - if (fTaglibIndexListeners != null) { - List listeners = new ArrayList(Arrays.asList(fTaglibIndexListeners)); - listeners.remove(listener); - fTaglibIndexListeners = (ITaglibIndexListener[]) listeners.toArray(new ITaglibIndexListener[0]); + try { + LOCK.acquire(); + if (fTaglibIndexListeners != null) { + List listeners = new ArrayList(Arrays.asList(fTaglibIndexListeners)); + listeners.remove(listener); + fTaglibIndexListeners = (ITaglibIndexListener[]) listeners.toArray(new ITaglibIndexListener[0]); + } + } + finally { + LOCK.release(); } } @@ -825,7 +811,7 @@ public final class TaglibIndex { if (baseResource == null) { IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot(); // Try the base path as a folder first - if (baseResource == null && baseIPath.segmentCount() > 1) { + if (baseIPath.segmentCount() > 1) { baseResource = workspaceRoot.getFolder(baseIPath); } // If not a folder, then try base path as a file |