| /******************************************************************************* |
| * Copyright (c) 2003, 2004 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.j2ee.internal.web.locator; |
| |
| import java.io.IOException; |
| import java.util.ArrayList; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.zip.ZipEntry; |
| import java.util.zip.ZipException; |
| import java.util.zip.ZipFile; |
| |
| import org.eclipse.core.resources.IContainer; |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.resources.IProject; |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.core.runtime.Path; |
| import org.eclipse.jdt.core.IJavaProject; |
| import org.eclipse.jdt.core.JavaCore; |
| import org.eclipse.jdt.core.JavaModelException; |
| import org.eclipse.jst.j2ee.internal.J2EEConstants; |
| import org.eclipse.jst.j2ee.internal.J2EEVersionConstants; |
| import org.eclipse.jst.j2ee.internal.web.operations.J2EEWebNatureRuntime; |
| import org.eclipse.jst.j2ee.internal.web.operations.J2EEWebNatureRuntimeUtilities; |
| import org.eclipse.jst.j2ee.internal.web.operations.WebEditModel; |
| import org.eclipse.jst.j2ee.internal.web.taglib.TLDDigester; |
| import org.eclipse.jst.j2ee.internal.web.taglib.TaglibInfo; |
| import org.eclipse.jst.j2ee.internal.web.taglib.WebXMLTaglibInfo; |
| import org.eclipse.jst.j2ee.jsp.JSPConfig; |
| import org.eclipse.jst.j2ee.jsp.TagLibRefType; |
| import org.eclipse.jst.j2ee.web.taglib.ITaglibInfo; |
| import org.eclipse.jst.j2ee.webapplication.TagLibRef; |
| import org.eclipse.jst.j2ee.webapplication.WebApp; |
| import org.eclipse.wst.web.internal.operation.ILibModule; |
| |
| /** |
| * @version 1.0 |
| * @author |
| */ |
| public class WebXMLTaglibLocator extends AbstractWebTaglibLocator { |
| |
| public WebXMLTaglibLocator(IProject project) { |
| super(project); |
| } |
| |
| protected ILibModule findLibModule(String jarFile) { |
| String fileName = new Path(jarFile).lastSegment(); |
| ILibModule[] libModules = getWebNature().getLibModules(); |
| for (int i = 0; i < libModules.length; i++) { |
| ILibModule iLibModule = libModules[i]; |
| if (iLibModule.getJarName().equals(fileName)) |
| return iLibModule; |
| } |
| return null; |
| } |
| |
| protected IFile findWebAppRelativeFile(IPath path) { |
| if (path != null) { |
| IResource resource = getWebNature().getModuleServerRoot().findMember(path); |
| if (resource != null && resource.getType() == IResource.FILE) |
| return (IFile) resource; |
| } |
| return null; |
| } |
| |
| protected IPath[] findTLDsInJar(IFile jarFile) { |
| ZipFile zFile = null; |
| IPath[] results = new IPath[0]; |
| |
| try { |
| zFile = new ZipFile(jarFile.getLocation().toFile()); |
| ZipEntry[] entries = findTLDEntriesInZip(zFile); |
| results = new IPath[entries.length]; |
| for (int i = 0; i < entries.length; i++) { |
| ZipEntry entry = entries[i]; |
| results[i] = new Path(entry.getName()); |
| } |
| } catch (ZipException e) { |
| } catch (IOException e) { |
| } finally { |
| if (zFile != null) { |
| try { |
| zFile.close(); |
| } catch (IOException e) { |
| } |
| } |
| } |
| return results; |
| } |
| |
| /* |
| * @see ITaglibLocator#search(IResource) |
| */ |
| public ITaglibInfo[] searchFile(IFile file) { |
| // This locator only looks at web.xml files. |
| if (!getWebNature().getWebXMLPath().equals(file.getFullPath())) |
| return EMPTY_TAGLIBINFO_ARRAY; |
| |
| J2EEWebNatureRuntime webNature = getWebNature(); |
| WebEditModel editModel = null; |
| ArrayList results = new ArrayList(); |
| |
| try { |
| editModel = webNature.getWebAppEditModelForRead(this); |
| WebApp webApp = editModel.getWebApp(); |
| if (webApp == null) |
| return EMPTY_TAGLIBINFO_ARRAY; |
| |
| List taglibs = new ArrayList(); |
| if (webApp.getVersionID() >= J2EEVersionConstants.WEB_2_4_ID) { |
| JSPConfig config = webApp.getJspConfig(); |
| if (config != null) |
| taglibs = config.getTagLibs(); |
| } else { |
| taglibs = webApp.getTagLibs(); |
| } |
| |
| for (Iterator iter = taglibs.iterator(); iter.hasNext();) { |
| TagLibRef taglibRef13; |
| TagLibRefType taglibRef14; |
| String uri; |
| String taglibLocation; |
| if (webApp.getVersionID() >= J2EEVersionConstants.WEB_2_4_ID) { |
| taglibRef14 = (TagLibRefType) iter.next(); |
| uri = taglibRef14.getTaglibURI(); |
| taglibLocation = taglibRef14.getTaglibLocation(); |
| } else { |
| taglibRef13 = (TagLibRef) iter.next(); |
| uri = taglibRef13.getTaglibURI(); |
| taglibLocation = taglibRef13.getTaglibLocation(); |
| } |
| |
| IPath projectRelativeLocation = new Path(taglibLocation); |
| IPath webModuleRelativeLocation = getWebAppRelativePath(taglibLocation); |
| if (webModuleRelativeLocation != null) { |
| projectRelativeLocation = webNature.getModuleServerRoot().getProjectRelativePath().append(webModuleRelativeLocation); |
| } |
| WebXMLTaglibInfo taglibInfo = null; |
| IFile locationFile = findWebAppRelativeFile(webModuleRelativeLocation); |
| boolean isLocationResolved = true; |
| if (hasJarExtension(taglibLocation)) { |
| if (locationFile == null) { |
| // If the location file is null it means that the file could not |
| // be found in this project, check to see if it is referencing |
| // a TLD in a lib module |
| IResource resource = findLibModuleRelativeFile(webModuleRelativeLocation); |
| if (resource == null || !resource.exists()) { |
| // Go ahead and create an entry which cannot be resolved |
| // Only the /META-INF/taglib.tld file can be specified in web.xml |
| isLocationResolved = false; |
| taglibInfo = (WebXMLTaglibInfo) createTaglibForJar(uri, projectRelativeLocation, new Path("META-INF/taglib.tld")); //$NON-NLS-1$ |
| } else { |
| locationFile = (IFile) resource; |
| taglibInfo = (WebXMLTaglibInfo) createTaglibForLibModuleJar(uri, projectRelativeLocation, resource); |
| setPrefix(taglibInfo, locationFile); |
| } |
| } else { |
| isLocationResolved = true; |
| // Only the /META-INF/taglib.tld file can be specified in web.xml |
| taglibInfo = (WebXMLTaglibInfo) createTaglibForJar(uri, projectRelativeLocation, new Path("META-INF/taglib.tld")); //$NON-NLS-1$ |
| setPrefix(taglibInfo, locationFile); |
| } |
| } else { |
| if (locationFile == null) |
| isLocationResolved = false; |
| taglibInfo = (WebXMLTaglibInfo) createTaglibForTLD(uri, projectRelativeLocation); |
| setPrefix(taglibInfo, locationFile); |
| |
| } |
| if (taglibInfo != null) { |
| taglibInfo.setIsWebXMLEntry(true); |
| taglibInfo.setWebXMLLocation(new Path(taglibLocation)); |
| taglibInfo.setIsLocationResolved(isLocationResolved); |
| // If the location cannot be resolved, set the taglibInfo to be invalid |
| if (!isLocationResolved) |
| taglibInfo.setIsValid(false); |
| results.add(taglibInfo); |
| } |
| } |
| } finally { |
| if (editModel != null) |
| editModel.releaseAccess(this); |
| } |
| return (ITaglibInfo[]) results.toArray(new ITaglibInfo[results.size()]); |
| } |
| |
| /** |
| * This method retrieves the short-name from the tld file and adds it as a prefix to the |
| * ITaglibInfo entry |
| * |
| * @param taglibInfo |
| * @param locationFile |
| */ |
| private void setPrefix(ITaglibInfo taglibInfo, IFile locationFile) { |
| if (locationFile != null && locationFile.exists()) { |
| TLDDigester digester = null; |
| try { |
| if (isTaglibJar(locationFile)) { |
| digester = getTLDDigester(locationFile, new Path("META-INF/taglib.tld")); //$NON-NLS-1$ |
| ((TaglibInfo) taglibInfo).setPrefix(digester); |
| } else if (hasTLDExtension(locationFile.getFullPath())) { |
| digester = getTLDDigester(locationFile); |
| ((TaglibInfo) taglibInfo).setPrefix(digester); |
| } |
| } finally { |
| if (digester != null) |
| digester.close(); |
| } |
| } |
| } |
| |
| protected ITaglibInfo createTaglibForTLD(String uri, IPath file) { |
| return new WebXMLTaglibInfo(this.project, uri, file); |
| } |
| |
| protected ITaglibInfo createTaglibForJar(String uri, IPath jarfile, IPath tldLocation) { |
| WebXMLTaglibInfo taglibInfo = new WebXMLTaglibInfo(this.project, uri, jarfile, tldLocation); |
| return taglibInfo; |
| } |
| |
| |
| protected ITaglibInfo createTaglibForLibModuleJar(String uri, IPath jarfile, IResource tldFile) { |
| WebXMLTaglibInfo taglibInfo = new WebXMLTaglibInfo(tldFile.getProject(), uri, jarfile, tldFile.getProjectRelativePath()); |
| taglibInfo.setIsLibModule(true); |
| return taglibInfo; |
| } |
| |
| |
| /** |
| * Method findLibModuleRelativeFile. |
| * |
| * @param location |
| * @return String |
| */ |
| private IResource findLibModuleRelativeFile(IPath location) { |
| if (location != null) { |
| ILibModule libModule = findLibModule(location.lastSegment()); |
| if (libModule != null) { |
| IProject tProject = libModule.getProject(); |
| if (tProject.isOpen()) { |
| try { |
| IJavaProject javaProject = JavaCore.create(tProject); |
| IPath outputLocation = javaProject.getOutputLocation(); |
| IPath searchPath = outputLocation.removeFirstSegments(1); |
| searchPath = searchPath.append(J2EEConstants.META_INF); |
| searchPath = searchPath.append("taglib.tld"); //$NON-NLS-1$ |
| IResource searchResource = tProject.findMember(searchPath); |
| if (searchResource != null) |
| return searchResource; |
| } catch (JavaModelException e) { |
| } |
| } |
| } |
| } |
| return null; |
| } |
| |
| /** |
| * Method getWebAppRelativePath. This method resolves a location specified in a taglib uri to a |
| * project relative IPath |
| * |
| * @return null if the relative path cannot be resolved to an actual resource or a web library |
| * project |
| * @param location |
| * @return IPath |
| */ |
| private IPath getWebAppRelativePath(String location) { |
| IPath resolvedPath = null; |
| if (location != null && !location.trim().equals("")) { //$NON-NLS-1$ |
| IPath preResolvePath = new Path(location); |
| J2EEWebNatureRuntime webNature = (J2EEWebNatureRuntime) J2EEWebNatureRuntimeUtilities.getRuntime(this.project); |
| IContainer webModuleFolder = webNature.getModuleServerRoot(); |
| IContainer webLibraryFolder = webNature.getLibraryFolder(); |
| IContainer webInfFolder = webLibraryFolder.getParent(); |
| if (preResolvePath.getDevice() == null && !preResolvePath.isEmpty()) { |
| IContainer searchContainer = webModuleFolder; |
| if (!preResolvePath.isAbsolute()) { |
| searchContainer = webInfFolder; |
| } |
| for (int i = 0; i < preResolvePath.segmentCount(); i++) { |
| String pathSegment = preResolvePath.segment(i); |
| if (pathSegment.equals(".")) //$NON-NLS-1$ |
| continue; |
| else if (pathSegment.equals("..")) { //$NON-NLS-1$ |
| searchContainer = searchContainer.getParent(); |
| if (searchContainer.getFullPath().equals(webModuleFolder.getParent().getFullPath())) |
| break; // path must be confined to webModuleFolder |
| } else { |
| IResource resourceFound = searchContainer.findMember(pathSegment); |
| if (resourceFound instanceof IContainer) { |
| searchContainer = (IContainer) resourceFound; |
| } else if (i == preResolvePath.segmentCount() - 1) { |
| if (resourceFound != null) { |
| if (resourceFound.getType() == IResource.FILE) { |
| resolvedPath = resourceFound.getFullPath().removeFirstSegments(webModuleFolder.getFullPath().segmentCount()); |
| break; // for readability |
| } |
| } else { |
| // maybe its a web library project, so let us check if the current |
| // container is the lib folder |
| if (webLibraryFolder.getFullPath().equals(searchContainer.getFullPath())) { |
| // the last segment could be the name of the jar for the web |
| // library project |
| if (findLibModule(pathSegment) != null) { |
| resolvedPath = searchContainer.getFullPath().removeFirstSegments(webModuleFolder.getFullPath().segmentCount()); |
| resolvedPath = resolvedPath.append(pathSegment); |
| } |
| } |
| } |
| } else |
| break;// not a container, not the last segment either so its an invalid |
| // path |
| } |
| } |
| } |
| } |
| return resolvedPath; |
| } |
| |
| } |