/** * Copyright 2005-2014 Restlet * * The contents of this file are subject to the terms of one of the following * open source licenses: Apache 2.0 or or EPL 1.0 (the "Licenses"). You can * select the license that you prefer but you may not use this file except in * compliance with one of these Licenses. * * You can obtain a copy of the Apache 2.0 license at * http://www.opensource.org/licenses/apache-2.0 * * You can obtain a copy of the EPL 1.0 license at * http://www.opensource.org/licenses/eclipse-1.0 * * See the Licenses for the specific language governing permissions and * limitations under the Licenses. * * Alternatively, you can obtain a royalty free commercial license with less * limitations, transferable or non-transferable, directly at * http://restlet.com/products/restlet-framework * * Restlet is a registered trademark of Restlet S.A.S. */ package org.restlet.data; import java.io.File; /** * Reference to a local resource. It has helper methods for the three following * schemes: {@link Protocol#CLAP}, {@link Protocol#FILE}, {@link Protocol#JAR} * and {@link Protocol#RIAP}. * * @author Jerome Louvel */ public final class LocalReference extends Reference { /** * The resources will be resolved from the classloader associated with the * local class. This is the same as the {@link #CLAP_CLASS} authority. * Examples: clap:///rootPkg/subPkg/myClass.class or * clap:///rootPkg/file.html * * @see java.lang.Class#getClassLoader() */ public static final int CLAP_DEFAULT = 0; /** * The resources will be resolved from the classloader associated with the * local class. This is the default CLAP authority. Examples: * clap://class/rootPkg/subPkg/myClass.class or * clap://class/rootPkg/file.html or clap:///rootPkg/file.html * * @see java.lang.Class#getClassLoader() */ public static final int CLAP_CLASS = 1; /** * The resources will be resolved from the system's classloader. Examples: * clap://system/rootPkg/subPkg/myClass.class or * clap://system/rootPkg/file.html * * @see java.lang.ClassLoader#getSystemClassLoader() */ public static final int CLAP_SYSTEM = 2; /** * The resources will be resolved from the current thread's classloader. * Examples: clap://thread/rootPkg/subPkg/myClass.class or * clap://thread/rootPkg/file.html * * @see java.lang.Thread#getContextClassLoader() */ public static final int CLAP_THREAD = 3; /** * The resources will be resolved from the current application's root * Restlet. Example riap://application/myPath/myResource */ public static final int RIAP_APPLICATION = 4; /** * The resources will be resolved from the current component's internal * (private) router. Example riap://component/myAppPath/myResource */ public static final int RIAP_COMPONENT = 5; /** * The resources will be resolved from the current component's virtual host. * Example riap://host/myAppPath/myResource */ public static final int RIAP_HOST = 6; /** * Constructor. * * @param pkg * The package to identify. */ public static LocalReference createClapReference(Package pkg) { return createClapReference(CLAP_DEFAULT, pkg); } /** * Constructor for CLAP URIs to a given package. * * @param authorityType * The authority type for the resource path. * @param pkg * The package to identify. */ public static LocalReference createClapReference(int authorityType, Package pkg) { String pkgPath = pkg.getName().replaceAll("\\.", "/"); return new LocalReference("clap://" + getAuthorityName(authorityType) + "/" + pkgPath); } /** * Constructor. * * @param path * The resource path. */ public static LocalReference createClapReference(String path) { return createClapReference(CLAP_DEFAULT, path); } /** * Constructor. * * @param authorityType * The authority type for the resource path. * @param path * The resource path. */ public static LocalReference createClapReference(int authorityType, String path) { return new LocalReference("clap://" + getAuthorityName(authorityType) + path); } /** * Constructor. * * @param file * The file whose path must be used. * @return The new local reference. * @see #createFileReference(String) */ public static LocalReference createFileReference(File file) { return createFileReference(file.getAbsolutePath()); } /** * Constructor. * * @param filePath * The local file path. * @see #createFileReference(String, String) */ public static LocalReference createFileReference(String filePath) { return createFileReference("", filePath); } /** * Constructor. * * @param hostName * The authority (can be a host name or the special "localhost" * or an empty value). * @param filePath * The file path. */ public static LocalReference createFileReference(String hostName, String filePath) { return new LocalReference("file://" + hostName + "/" + normalizePath(filePath)); } /** * Constructor. * * @param jarFile * The JAR file reference. * @param entryPath * The entry path inside the JAR file. */ public static LocalReference createJarReference(Reference jarFile, String entryPath) { return new LocalReference("jar:" + jarFile.getTargetRef().toString() + "!/" + entryPath); } /** * Constructor. * * @param authorityType * The authority type for the resource path. * @param path * The resource path. */ public static LocalReference createRiapReference(int authorityType, String path) { return new LocalReference("riap://" + getAuthorityName(authorityType) + path); } /** * Constructor. * * @param zipFile * The Zip file reference. * @param entryPath * The entry path inside the Zip file. */ public static LocalReference createZipReference(Reference zipFile, String entryPath) { return new LocalReference("zip:" + zipFile.getTargetRef().toString() + "!/" + entryPath); } /** * Returns an authority name. * * @param authority * The authority. * @return The name. */ public static String getAuthorityName(int authority) { String result = null; switch (authority) { case CLAP_DEFAULT: result = ""; break; case CLAP_CLASS: result = "class"; break; case CLAP_SYSTEM: result = "system"; break; case CLAP_THREAD: result = "thread"; break; case RIAP_APPLICATION: result = "application"; break; case RIAP_COMPONENT: result = "component"; break; case RIAP_HOST: result = "host"; break; } return result; } /** * Localize a path by converting all the separator characters to the * system-dependent separator character. * * @param path * The path to localize. * @return The localized path. */ public static String localizePath(String path) { final StringBuilder result = new StringBuilder(); char nextChar; for (int i = 0; i < path.length(); i++) { nextChar = path.charAt(i); if (nextChar == '/') { // Convert the URI separator to // the system dependent path separator result.append(File.separatorChar); } else { result.append(nextChar); } } return result.toString(); } /** * Normalize a path by converting all the system-dependent separator * characters to the standard '/' separator character. * * @param path * The path to normalize. * @return The normalize path. */ public static String normalizePath(String path) { final StringBuilder result = new StringBuilder(); char nextChar; for (int i = 0; i < path.length(); i++) { nextChar = path.charAt(i); if ((nextChar == File.separatorChar)) { // Convert the Windows style path separator // to the standard path separator result.append('/'); } else if (!isUnreserved(nextChar)) { result.append(Reference.encode("" + nextChar)); } else { result.append(nextChar); } } return result.toString(); } /** * Constructor. * * @param localRef * The local reference. */ public LocalReference(Reference localRef) { super(localRef.getTargetRef().toString()); } /** * Constructor. * * @param localUri * The local URI. */ public LocalReference(String localUri) { super(localUri); } /** * Returns the type of authority. * * @return The type of authority. */ public int getClapAuthorityType() { int result = 0; if (Protocol.CLAP.equals(getSchemeProtocol())) { final String authority = getAuthority(); if (authority != null) { if (authority.equalsIgnoreCase(getAuthorityName(CLAP_CLASS))) { result = CLAP_CLASS; } else if (authority .equalsIgnoreCase(getAuthorityName(CLAP_SYSTEM))) { result = CLAP_SYSTEM; } else if (authority .equalsIgnoreCase(getAuthorityName(CLAP_THREAD))) { result = CLAP_THREAD; } else { result = CLAP_DEFAULT; } } } return result; } /** * Gets the local file corresponding to the reference. Only URIs referring * to the "localhost" or to an empty authority are supported. * * @return The local file corresponding to the reference. */ public File getFile() { File result = null; if (Protocol.FILE.equals(getSchemeProtocol())) { final String hostName = getAuthority(); if ((hostName == null) || hostName.equals("") || hostName.equalsIgnoreCase("localhost")) { final String filePath = Reference.decode(getPath()); result = new File(filePath); } else { throw new RuntimeException( "Can't resolve files on remote host machines"); } } return result; } /** * Returns the JAR entry path. * * @return The JAR entry path. */ public String getJarEntryPath() { String result = null; if (Protocol.JAR.equals(getSchemeProtocol())) { final String ssp = getSchemeSpecificPart(); if (ssp != null) { final int separatorIndex = ssp.indexOf("!/"); if (separatorIndex != -1) { result = ssp.substring(separatorIndex + 2); } } } return result; } /** * Returns the JAR file reference. * * @return The JAR file reference. */ public Reference getJarFileRef() { Reference result = null; if (Protocol.JAR.equals(getSchemeProtocol())) { final String ssp = getSchemeSpecificPart(); if (ssp != null) { final int separatorIndex = ssp.indexOf("!/"); if (separatorIndex != -1) { result = new Reference(ssp.substring(0, separatorIndex)); } } } return result; } /** * Returns the type of authority. * * @return The type of authority. */ public int getRiapAuthorityType() { int result = 0; if (Protocol.RIAP.equals(getSchemeProtocol())) { final String authority = getAuthority(); if (authority != null) { if (authority .equalsIgnoreCase(getAuthorityName(RIAP_APPLICATION))) { result = RIAP_APPLICATION; } else if (authority .equalsIgnoreCase(getAuthorityName(RIAP_COMPONENT))) { result = RIAP_COMPONENT; } else if (authority .equalsIgnoreCase(getAuthorityName(RIAP_HOST))) { result = RIAP_HOST; } } } return result; } }