blob: b7c4707a575faa957807ef6aaa6398d2bb30f42f [file] [log] [blame]
/*
* Copyright (c) 2002 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM - Initial API and implementation
* Jens Lukowski/Innoopract - initial renaming/restructuring
*
*/
package org.eclipse.wst.common.uriresolver.internal.util;
import java.io.File;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URL;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
public class URIHelper
{
protected static final String FILE_PROTOCOL = "file:";
protected static final String PLATFORM_RESOURCE_PROTOCOL = "platform:/resource/";
protected static final String PROTOCOL_PATTERN = ":";
public static String normalize(String uri)
{
if (uri != null)
{
String protocol = getProtocol(uri);
String file = uri;
if (protocol != null)
{
try
{
//
URL url = new URL(uri);
// we use a 'Path' on the 'file' part of the url in order to normalize the '.' and '..' segments
IPath path = new Path(url.getFile());
URL url2 = new URL(url.getProtocol(), url.getHost(), url.getPort(), path.toString());
uri = url2.toString();
}
catch (Exception e)
{
}
}
else
{
IPath path = new Path(file);
uri = path.toString();
}
}
return uri;
}
/**
* a 'null' rootLocation argument will causes uri that begins with a '/' to be treated as a workspace relative resource
* (i.e. the string "platform:/resource" is prepended and the uri is resolved via the Platform object)
*/
public static String normalize(String uri, String resourceLocation, String rootLocation)
{
String result = null;
if (uri != null)
{
// is the uri a url
if (hasProtocol(uri))
{
if (isPlatformResourceProtocol(uri))
{
result = resolvePlatformUrl(uri);
}
else
{
result = uri;
}
}
// is uri absolute
//
if (result == null)
{
if (uri.indexOf(":") != -1 || uri.startsWith("/") || uri.startsWith("\\"))
{
result = uri;
}
}
// if uri is relative to the resourceLocation
//
if (result == null && resourceLocation != null)
{
if (resourceLocation.endsWith("/"))
{
result = resourceLocation + uri;
}
else
{
result = resourceLocation + "/../" + uri;
}
}
if (result == null)
{
result = uri;
}
result = normalize(result);
}
//System.out.println("normalize(" + uri + ", " + resourceLocation + ", " + rootLocation + ") = " + result);
return result;
}
public static boolean isURL(String uri)
{
return uri.indexOf(":/") > 2; // test that the index is > 2 so that C:/ is not considered a protocol
}
public static String getLastSegment(String uri)
{
String result = uri;
int index = Math.max(uri.lastIndexOf("/"), uri.lastIndexOf("\\"));
if (index != -1)
{
result = uri.substring(index + 1);
}
return result;
}
public static String getFileExtension(String uri)
{
String result = null;
int dotIndex = getExtensionDotIndex(uri);
if (dotIndex != -1)
{
result = uri.substring(dotIndex + 1);
}
return result;
}
public static String removeFileExtension(String uri)
{
String result = null;
int dotIndex = getExtensionDotIndex(uri);
if (dotIndex != -1)
{
result = uri.substring(0, dotIndex);
}
return result;
}
// here we use the Platform to resolve a workspace relative path to an actual url
//
protected static String resolvePlatformUrl(String urlspec)
{
String result = null;
try
{
urlspec = urlspec.replace('\\', '/');
URL url = new URL(urlspec);
URL resolvedURL = Platform.resolve(url);
result = resolvedURL.toString();
}
catch (Exception e)
{
}
return result;
}
protected static int getExtensionDotIndex(String uri)
{
int result = -1;
int dotIndex = uri.lastIndexOf(".");
int slashIndex = Math.max(uri.lastIndexOf("/"), uri.lastIndexOf("\\"));
if (dotIndex != -1 && dotIndex > slashIndex)
{
result = dotIndex;
}
return result;
}
public static boolean isPlatformResourceProtocol(String uri)
{
return uri != null && uri.startsWith(PLATFORM_RESOURCE_PROTOCOL);
}
public static String removePlatformResourceProtocol(String uri)
{
if (uri != null && uri.startsWith(PLATFORM_RESOURCE_PROTOCOL))
{
uri = uri.substring(PLATFORM_RESOURCE_PROTOCOL.length());
}
return uri;
}
public static String prependPlatformResourceProtocol(String uri)
{
if (uri != null && !uri.startsWith(PLATFORM_RESOURCE_PROTOCOL))
{
uri = PLATFORM_RESOURCE_PROTOCOL + uri;
}
return uri;
}
public static String prependFileProtocol(String uri)
{
if (uri != null && !uri.startsWith(FILE_PROTOCOL))
{
uri = FILE_PROTOCOL + uri;
}
return uri;
}
public static boolean hasProtocol(String uri)
{
boolean result = false;
if (uri != null)
{
int index = uri.indexOf(PROTOCOL_PATTERN);
if (index != -1 && index > 2) // assume protocol with be length 3 so that the'C' in 'C:/' is not interpreted as a protocol
{
result = true;
}
}
return result;
}
public static boolean isAbsolute(String uri)
{
boolean result = false;
if (uri != null)
{
int index = uri.indexOf(PROTOCOL_PATTERN);
if (index != -1 || uri.startsWith("/"))
{
result = true;
}
}
return result;
}
public static String addImpliedFileProtocol(String uri)
{
if (!hasProtocol(uri))
{
String prefix = FILE_PROTOCOL;
prefix += uri.startsWith("/") ? "//" : "///";
uri = prefix + uri;
}
return uri;
}
// todo... need to revisit this before we publicize it
//
protected static String getProtocol(String uri)
{
String result = null;
if (uri != null)
{
int index = uri.indexOf(PROTOCOL_PATTERN);
if (index > 2) // assume protocol with be length 3 so that the'C' in 'C:/' is not interpreted as a protocol
{
result = uri.substring(0, index + PROTOCOL_PATTERN.length());
}
}
return result;
}
public static String removeProtocol(String uri)
{
String result = uri;
if (uri != null)
{
int index = uri.indexOf(PROTOCOL_PATTERN);
if (index > 2)
{
result = result.substring(index + PROTOCOL_PATTERN.length());
}
}
return result;
}
protected static boolean isProtocolFileOrNull(String uri)
{
String protocol = getProtocol(uri);
return protocol == null || protocol.equals(FILE_PROTOCOL);
}
protected static boolean isMatchingProtocol(String uri1, String uri2)
{
boolean result = false;
String protocol1 = getProtocol(uri1);
String protocol2 = getProtocol(uri2);
if (isProtocolFileOrNull(protocol1) && isProtocolFileOrNull(protocol2))
{
result = true;
}
else
{
result = protocol1 != null && protocol2 != null && protocol1.equals(protocol2);
}
return result;
}
/**
* warning... this method not fully tested yet
*/
public static String getRelativeURI(String uri, String resourceLocation)
{
String result = uri;
if (isMatchingProtocol(uri, resourceLocation))
{
result = getRelativeURI(new Path(removeProtocol(uri)),
new Path(removeProtocol(resourceLocation)));
}
return result;
}
/**
* warning... this method not fully tested yet
*/
public static String getRelativeURI(IPath uri, IPath resourceLocation)
{
String result = null;
int nMatchingSegments = 0;
resourceLocation = resourceLocation.removeLastSegments(1);
while (true)
{
String a = uri.segment(nMatchingSegments);
String b = resourceLocation.segment(nMatchingSegments);
if (a != null && b != null && a.equals(b))
{
nMatchingSegments++;
}
else
{
break;
}
}
if (nMatchingSegments == 0)
{
result = uri.toOSString();
}
else
{
result = "";
boolean isFirst = true;
String[] segments = resourceLocation.segments();
for (int i = nMatchingSegments; i < segments.length; i++)
{
result += isFirst ? ".." : "/..";
if (isFirst)
{
isFirst = false;
}
}
//
segments = uri.segments();
for (int i = nMatchingSegments; i < segments.length; i++)
{
result += isFirst ? segments[i] : ("/" + segments[i]);
if (isFirst)
{
isFirst = false;
}
}
}
return result;
}
public static String getPlatformURI(IResource resource)
{
String fullPath = resource.getFullPath().toString();
if (fullPath.startsWith("/"))
{
fullPath = fullPath.substring(1);
}
return PLATFORM_RESOURCE_PROTOCOL + fullPath;
}
/**
* This methods is used as a quick test to see if a uri can be resolved to an existing resource.
*/
public static boolean isReadableURI(String uri, boolean testRemoteURI)
{
boolean result = true;
if (uri != null)
{
try
{
uri = normalize(uri, null, null);
if (isProtocolFileOrNull(uri))
{
uri = removeProtocol(uri);
File file = new File(uri);
result = file.exists() && file.isFile();
}
else if (isPlatformResourceProtocol(uri))
{
// Note - If we are here, uri has been failed to resolve
// relative to the Platform. See normalize() to find why.
result = false;
}
else if (testRemoteURI)
{
URL url = new URL(uri);
InputStream is = url.openConnection().getInputStream();
is.close();
// the uri is readable if we reach here.
result = true;
}
}
catch (Exception e)
{
result = false;
}
}
else // uri is null
result = false;
return result;
}
/**
* return true if this is a valid uri
*/
public static boolean isValidURI(String uri)
{
boolean result = false;
try
{
new URI(uri);
result = true;
}
catch (Exception e)
{
}
return result;
}
/**
* returns an acceptable URI for a file path
*/
public static String getURIForFilePath(String filePath)
{
String result = addImpliedFileProtocol(filePath);
if (!isValidURI(result))
{
try
{
result = URIEncoder.encode(result, "UTF8");
}
catch(UnsupportedEncodingException e)
{
// Do nothing as long as UTF8 is used. This is supported.
}
}
return result;
}
}