| /******************************************************************************* |
| * Copyright (c) 2004, 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 |
| * yyyymmdd bug Email and other contact information |
| * -------- -------- ----------------------------------------------------------- |
| * IBM Corporation - Initial API and implementation |
| * Jens Lukowski/Innoopract - initial renaming/restructuring |
| * 20071205 211262 ericdp@ca.ibm.com - Eric Peters, CopyWSDLTreeCommand fails to copy ?wsdl |
| *******************************************************************************/ |
| 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.FileLocator; |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.core.runtime.Path; |
| |
| |
| 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 ensureURIProtocolFormat(String uri) { |
| String protocol = getProtocol(uri); |
| if (protocol != null) { |
| if (protocol.equals(FILE_PROTOCOL)) { |
| return ensureFileURIProtocolFormat(uri); |
| } |
| } |
| return uri; |
| } |
| |
| |
| /** |
| * This method takes a file URI in String format and ensures the protocol is followed by three slashes. |
| * For example, files "file:D:/XXX", "file:/D:/XXX" and "file://D:/XXX" are corrected to: |
| * "file:///D:/XXX". |
| * If the input is not a file URI (does not start with "file:"), the String is returned unmodified. |
| */ |
| public static String ensureFileURIProtocolFormat(String uri) { |
| if (uri.startsWith(FILE_PROTOCOL) && !uri.startsWith(FILE_PROTOCOL + "///")) //$NON-NLS-1$ |
| { |
| if (uri.startsWith(FILE_PROTOCOL + "//")) { |
| uri = FILE_PROTOCOL + "/" + uri.substring(FILE_PROTOCOL.length()); //$NON-NLS-1$ |
| } else if (uri.startsWith(FILE_PROTOCOL + "/")) { |
| uri = FILE_PROTOCOL + "//" + uri.substring(FILE_PROTOCOL.length()); //$NON-NLS-1$ |
| } else { |
| uri = FILE_PROTOCOL + "///" + uri.substring(FILE_PROTOCOL.length()); //$NON-NLS-1$ |
| } |
| } |
| return uri; |
| } |
| |
| 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 = FileLocator.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("/") || 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); |
| } |
| |
| public static boolean isProtocolFile(String uri) |
| { |
| return uri != null && uri.startsWith(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(org.eclipse.wst.common.uriresolver.internal.URI.decode(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; |
| } |
| } |