/******************************************************************************* * Copyright (c) 2006 Sybase, Inc. 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: * Sybase, Inc. - initial API and implementation *******************************************************************************/ package org.eclipse.jst.pagedesigner.utils; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.net.MalformedURLException; import java.net.URL; import java.net.URLDecoder; import java.util.HashMap; import java.util.Map; import java.util.StringTokenizer; 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.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; import org.eclipse.jst.jsf.common.ui.IFileFolderConstants; import org.eclipse.jst.jsf.common.ui.internal.logging.Logger; import org.eclipse.jst.jsf.common.ui.internal.utils.ResourceUtils; import org.eclipse.jst.jsf.common.ui.internal.utils.WebrootUtil; import org.eclipse.jst.pagedesigner.PDPlugin; import org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyID; import org.eclipse.wst.common.uriresolver.internal.util.URIHelper; import org.eclipse.wst.sse.core.StructuredModelManager; import org.eclipse.wst.sse.core.internal.provisional.IModelManager; import org.eclipse.wst.sse.core.internal.util.URIResolver; import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel; import org.w3c.dom.DOMException; import org.w3c.dom.Node; import org.w3c.dom.NodeList; /** * A URIResolver implementation * */ public class ProjectResolver implements URIResolver { private static final String TLD_TAG_URI = "uri"; //$NON-NLS-1$ private static final String URI_PREFIX_HTTP = "http"; //$NON-NLS-1$ private static final String FILE_PROTOCOL = "file"; //$NON-NLS-1$ /** Create the logger for this class */ private static Logger _log = PDPlugin.getLogger(ProjectResolver.class); private IProject _project = null; private String _fileBaseLocation = null; private static Map _uriMap = null; /** * It is strongly recommended that clients use * project.getAdapter(URIResolver.class) to obtain a URIResolver aware of * the Project's special requirements. Note that a URIResolver may not be * returned at all so manually creating this object may still be required. * @param project */ public ProjectResolver(IProject project) { super(); _project = project; } /** * @param path */ public void seekTld(IFolder path) { if (path == null) { return; } if (_uriMap == null) { _uriMap = new HashMap(); } try { IResource[] res = path.members(); if (null == res) { return; } for (int i = 0; i < res.length; i++) { if (res[i] instanceof IFolder) { seekTld((IFolder) res[i]); } String ext = res[i].getFileExtension(); if (IFileFolderConstants.EXT_TAGLIB.equalsIgnoreCase(ext)) { IFile tldFile = (IFile) res[i]; String uri = getURIfromTLD(tldFile); String locate = tldFile.getLocation().toOSString(); if (uri != null && _uriMap.get(uri) == null) { _uriMap.put(uri, locate); } } } } catch (CoreException e) { _log.error("Error.ProjectResolver.GetlocationByURI.0", e); //$NON-NLS-1$ } } /** * @param path */ public void seekTld(File path) { if (path == null || !path.isDirectory()) { return; } if (_uriMap == null) { _uriMap = new HashMap(); } try { File[] res = path.listFiles(); if (null == res) { return; } for (int i = 0; i < res.length; i++) { if (res[i] instanceof IFolder) { seekTld(res[i]); } if (res[i].getName().endsWith( IFileFolderConstants.DOT + IFileFolderConstants.EXT_TAGLIB)) { String uri = getURIfromTLD(res[i]); String locate; locate = res[i].getCanonicalPath(); if (uri != null && _uriMap.get(uri) == null) { _uriMap.put(uri, locate); } } } } catch (IOException e1) { _log.error("Error.ProjectResolver.GetlocationByURI.0", e1); //$NON-NLS-1$ } } /** * @param tldFile * @return the uri for the tld in tldFile or null */ public String getURIfromTLD(File tldFile) { if (tldFile == null) { return null; } IDOMModel tldModel = null; InputStream in = null; try { in = new FileInputStream(tldFile); } catch (FileNotFoundException e) { _log.error("RenderingTraverser.Error.FileNotFound", e); //$NON-NLS-1$ return null; } // IDOMModel xmlModel = null; try { tldModel = (IDOMModel) StructuredModelManager.getModelManager().getModelForRead( tldFile.getAbsolutePath(), in, null); NodeList uriList = tldModel.getDocument().getElementsByTagName( TLD_TAG_URI); for (int i = 0, n = uriList.getLength(); i < n; i++) { Node uri = uriList.item(i); return uri.getChildNodes().item(0).getNodeValue(); } } catch (UnsupportedEncodingException e1) { _log.error("RenderingTraverser.Error.UnsupportedEncoding", e1); //$NON-NLS-1$ } catch (IOException e1) { _log.error("RenderingTraverser.Error.IO", e1); //$NON-NLS-1$ } finally { ResourceUtils.ensureClosed(in); if (tldModel != null) { tldModel.releaseFromRead(); } } return null; } /** * @param tldFile * @return the URI for the TLD in tldFile or null */ public String getURIfromTLD(IFile tldFile) { if (tldFile == null) { return null; } IDOMModel tldModel; try { tldModel = (IDOMModel) getModelManager().getModelForRead(tldFile); NodeList uriList = tldModel.getDocument().getElementsByTagName( TLD_TAG_URI); for (int i = 0, n = uriList.getLength(); i < n; i++) { Node uri = uriList.item(i); return uri.getChildNodes().item(0).getNodeValue(); } } catch (IOException e) { // Error in taglib locating. _log.error("Error.ProjectResolver.GetlocationByURI.0", e); //$NON-NLS-1$ } catch (CoreException e1) { _log.error("Error.ProjectResolver.GetlocationByURI.0", e1); //$NON-NLS-1$ } return null; } /** * initialize the map of tlds */ public void initTldMap() { if (_uriMap == null) { _uriMap = new HashMap(); } if (_project == null) { return; } if (WebrootUtil.getWebContentContainer(_project) == null) { return; } IFolder webinf = WebrootUtil.getWebContentContainer(_project).getFolder( new Path(IFileFolderConstants.FOLDER_WEBINF)); if (webinf != null && webinf.exists()) { seekTld(webinf); } String locate = PDPlugin.getInstallLocation().append("/jsf-tld") //$NON-NLS-1$ .toString(); File jsfDir = new File(locate); seekTld(jsfDir); } public java.lang.String getFileBaseLocation() { return _fileBaseLocation; } public java.lang.String getLocationByURI(String uri) { // System.out.println(getLocationByURI(uri, getFileBaseLocation())); return getLocationByURI(uri, getFileBaseLocation()); } private IModelManager getModelManager() { return StructuredModelManager.getModelManager(); } private String getLocationFromWEBXML(String uri, String baseReference) { if (uri == null) { return null; } try { // if (_project.hasNature(ICommonConstants.NATURE_WEBAPP)) // { if (uri.startsWith(IFileFolderConstants.PATH_SEPARATOR)) { uri = _project.getProject().getLocation().toString() + IFileFolderConstants.PATH_SEPARATOR + WebrootUtil.getWebContentFolderName(_project) + uri; } if (uri.startsWith(URI_PREFIX_HTTP)) { IFile webxml = WebrootUtil.getWebContentContainer(_project) .getFolder(new Path(IFileFolderConstants.FOLDER_WEBINF)).getFile( IFileFolderConstants.FILE_WEB_XML); IDOMModel xmlModel; if (webxml.exists()) { try { xmlModel = (IDOMModel) getModelManager() .getModelForRead(webxml); NodeList taglibNodeList = xmlModel .getDocument() .getElementsByTagName(ICSSPropertyID.TAG_TAGLIB); for (int i = 0, size = taglibNodeList.getLength(); i < size; i++) { Node taglibNode = taglibNodeList.item(i); NodeList childList = taglibNode.getChildNodes(); String taguri = ""; //$NON-NLS-1$ String taglocation = ""; //$NON-NLS-1$ for (int j = 0, childSize = childList.getLength(); j < childSize; j++) { Node childTaglibNode = childList.item(j); if (ICSSPropertyID.ATTR_TAGLIB_URI .equalsIgnoreCase(childTaglibNode .getNodeName())) { taguri = childTaglibNode.getChildNodes() .item(0).getNodeValue(); } if (ICSSPropertyID.ATTR_TAGLIB_LOCATION .equalsIgnoreCase(childTaglibNode .getNodeName())) { taglocation = childTaglibNode .getChildNodes().item(0) .getNodeValue(); } } if (uri.equalsIgnoreCase(taguri)) uri = _project.getProject().getLocation() .toString() + IFileFolderConstants.PATH_SEPARATOR + WebrootUtil .getWebContentFolderName(_project) + taglocation; } xmlModel.releaseFromRead(); } catch (IOException e) { // Error in taglib locating. _log.error( "Error.ProjectResolver.GetlocationByURI.0", e); //$NON-NLS-1$ } catch (CoreException e1) { e1.printStackTrace(); _log.error("Error.ProjectResolver.GetlocationByURI.0", //$NON-NLS-1$ e1); } } } // } } catch (DOMException e1) { // Error in taglib locating. _log.error("Error.ProjectResolver.GetlocationByURI.0", e1); //$NON-NLS-1$ } // catch (CoreException e1) // { // // _log.error("Error.ProjectResolver.GetlocationByURI.0", e1); // } if (isFileURL(uri)) { try { URL url = new URL(uri); return getPath(url); } catch (MalformedURLException e) { _log.error("Error.ProjectResolver.GetlocationByURI.0", e); //$NON-NLS-1$ } } // defect 244817 end return URIHelper.normalize(uri, baseReference, getRootLocationString()); } public String getLocationByURI(String uri, String baseReference) { // DataWindow may generate URL like "d:\somefile" (dos path). We may // need some // special support. (lium) int columnIndex = uri.indexOf(":"); //$NON-NLS-1$ int slashIndex = uri.indexOf("/"); //$NON-NLS-1$ if (columnIndex != -1 && (slashIndex == -1 || columnIndex < slashIndex)) { return uri; } try { uri = URLDecoder.decode(uri, "UTF-8"); //$NON-NLS-1$ } catch (UnsupportedEncodingException e) { // suppress this. the user's data may be invalid. } String result = getLocationFromWEBXML(uri, baseReference); if (result != null && !result.equals(uri)) { return result; } if (_uriMap == null) { initTldMap(); } if (_uriMap != null) { return (String) _uriMap.get(uri); } return null; } // defect 244817 start /** * @param passedSpec * @return boolean */ private boolean isFileURL(String passedSpec) { if (passedSpec == null) { return false; } final String spec = passedSpec.trim(); if (spec.length() == 0) { return false; } String newProtocol = null; for (int index = 0, limit = spec.length(); index < limit; index++) { final char p = spec.charAt(index); if (p == '/') { //$NON-NLS-1$ break; } if (p == ':') { //$NON-NLS-1$ newProtocol = spec.substring(0, index); break; } } return (newProtocol != null && newProtocol .compareToIgnoreCase(FILE_PROTOCOL) == 0); } /** * @param url * @return String */ private String getPath(URL url) { String ref = url.getRef() == null ? "" : "#" + url.getRef(); //$NON-NLS-1$ //$NON-NLS-2$ String strPath = url.getFile() + ref; IPath path; if (strPath.length() == 0) { path = Path.ROOT; } else { path = new Path(strPath); String query = null; StringTokenizer parser = new StringTokenizer(strPath, "?"); //$NON-NLS-1$ int tokenCount = parser.countTokens(); if (tokenCount == 2) { path = new Path((String) parser.nextElement()); query = (String) parser.nextElement(); } if (query == null) { parser = new StringTokenizer(path.toString(), "#"); //$NON-NLS-1$ tokenCount = parser.countTokens(); if (tokenCount == 2) { path = new Path((String) parser.nextElement()); } } } return getPath(path, url.getHost()); } /** * @param path * @param host * @return String */ private String getPath(IPath path, String host) { IPath newPath = path; // They are potentially for only Windows operating system. // a.) if path has a device, and if it begins with IPath.SEPARATOR, // remove it final String device = path.getDevice(); if (device != null && device.length() > 0) { if (device.charAt(0) == IPath.SEPARATOR) { final String newDevice = device.substring(1); newPath = path.setDevice(newDevice); } } // b.) if it has a hostname, it is UNC name... Any java or eclipse api // helps it ?? if (newPath != null && host != null && host.length() != 0) { IPath uncPath = new Path(host); uncPath = uncPath.append(path); newPath = uncPath.makeUNC(true); } if (newPath != null) { return newPath.toString(); } return path.toString(); } /** * Resolve the (possibly relative) URI acording to RFC1808 using the default * file base location. Resolves resource references into absolute resource * locations without ensuring that the resource actually exists. Note: * currently resolveCrossProjectLinks is ignored in this implementation. */ public java.lang.String getLocationByURI(String uri, boolean resolveCrossProjectLinks) { return getLocationByURI(uri, getFileBaseLocation(), resolveCrossProjectLinks); } /** * Perform the getLocationByURI action using the baseReference as the point * of reference instead of the default for this resolver Note: currently * resolveCrossProjectLinks is ignored in this implementation. */ public java.lang.String getLocationByURI(String uri, String baseReference, boolean resolveCrossProjectLinks) { return getLocationByURI(uri, baseReference); } public org.eclipse.core.resources.IProject getProject() { return _project; } public org.eclipse.core.resources.IContainer getRootLocation() { return _project; } private String getRootLocationString() { return null; } public void setFileBaseLocation(java.lang.String newFileBaseLocation) { _fileBaseLocation = newFileBaseLocation; } public void setProject(org.eclipse.core.resources.IProject newProject) { _project = newProject; } public InputStream getURIStream(String uri) { return null; } }