blob: 46330f56ee380638c9a1797df37430e3ab962dff [file] [log] [blame]
/*******************************************************************************
* 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.getWebContentFolder(_project) == null) {
return;
}
IFolder webinf = WebrootUtil.getWebContentFolder(_project).getFolder(
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.getWebContentFolder(_project)
.getFolder(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;
}
}