org.eclipse.wst.common.uriresolver_1.1.401.v201004280700

16:48:56.289 INFO  jd.cli.Main - Decompiling org.eclipse.wst.common.uriresolver_1.1.401.v201004280700.jar
package org.eclipse.wst.common.uriresolver.internal;

import java.util.Iterator;
import java.util.List;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.wst.common.uriresolver.internal.provisional.URIResolver;
import org.eclipse.wst.common.uriresolver.internal.provisional.URIResolverExtension;
import org.eclipse.wst.common.uriresolver.internal.provisional.URIResolverPlugin;
import org.osgi.framework.Bundle;

public class ExtensibleURIResolver
  implements URIResolver
{
  private static final boolean logExceptions = false;
  
  public String resolve(String baseLocation, String publicId, String systemId)
  {
    String result = systemId;
    
    IFile file = computeFile(baseLocation);
    IProject project = file != null ? file.getProject() : null;
    
    URIResolverExtensionRegistry resolverRegistry = URIResolverExtensionRegistry.getIntance();
    List list = resolverRegistry.getExtensionDescriptors(project);
    for (Iterator i = resolverRegistry.getMatchingURIResolvers(list, 1).iterator(); i.hasNext();)
    {
      URIResolverExtension resolver = (URIResolverExtension)i.next();
      String tempresult = resolver.resolve(file, baseLocation, publicId, result);
      if (tempresult != null) {
        result = tempresult;
      }
    }
    result = normalize(baseLocation, result);
    for (Iterator i = resolverRegistry.getMatchingURIResolvers(list, 2).iterator(); i.hasNext();)
    {
      URIResolverExtension resolver = (URIResolverExtension)i.next();
      String tempresult = resolver.resolve(file, baseLocation, publicId, result);
      if (tempresult != null) {
        result = tempresult;
      }
    }
    return result;
  }
  
  public String resolvePhysicalLocation(String baseLocation, String publicId, String logicalLocation)
  {
    String result = logicalLocation;
    URIResolverExtensionRegistry resolverRegistry = URIResolverExtensionRegistry.getIntance();
    IFile file = computeFile(baseLocation);
    
    IProject project = file != null ? file.getProject() : null;
    List list = resolverRegistry.getExtensionDescriptors(project);
    for (Iterator i = resolverRegistry.getMatchingURIResolvers(list, 3).iterator(); i.hasNext(); i.hasNext())
    {
      continue;URIResolverExtension resolver = (URIResolverExtension)i.next();
      String tempresult = resolver.resolve(file, baseLocation, publicId, result);
      if (tempresult != null) {
        result = tempresult;
      }
    }
    return result;
  }
  
  protected String normalize(String baseLocation, String systemId)
  {
    if (systemId == null) {
      return null;
    }
    result = systemId;
    try
    {
      URI systemURI = URI.createURI(systemId);
      if (systemURI.isRelative())
      {
        baseLocation = baseLocation.replace('\\', '/');
        URI baseURI = URI.createURI(baseLocation);
        try
        {
          result = systemURI.resolve(baseURI).toString();
        }
        catch (IllegalArgumentException localIllegalArgumentException2)
        {
          Bundle bundle = URIResolverPlugin.getInstance().getBundle();
          IStatus statusObj = null;
          java.net.URI baseURI2 = null;
          try
          {
            baseURI2 = java.net.URI.create(baseLocation);
          }
          catch (IllegalArgumentException localIllegalArgumentException) {}
          try
          {
            if (baseURI2 != null)
            {
              java.net.URI resultURI = baseURI2.resolve(systemId);
              result = resultURI.toString();
            }
          }
          catch (IllegalArgumentException localIllegalArgumentException1) {}
        }
      }
      return result;
    }
    catch (Exception localException) {}
  }
  
  protected IFile computeFile(String baseLocation)
  {
    IFile file = null;
    if (baseLocation != null)
    {
      String pattern = "file:///";
      if (baseLocation.startsWith(pattern)) {
        baseLocation = baseLocation.substring(pattern.length());
      }
      IPath path = new Path(baseLocation);
      file = ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(path);
    }
    return file;
  }
}

/* Location:
 * Qualified Name:     org.eclipse.wst.common.uriresolver.internal.ExtensibleURIResolver
 * Java Class Version: 1.2 (46.0)
 * JD-Core Version:    0.7.1
 */
package org.eclipse.wst.common.uriresolver.internal;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

public final class URI
{
  private final int hashCode;
  private final boolean hierarchical;
  private final String scheme;
  private final String authority;
  private final String fragment;
  private URI cachedTrimFragment;
  private String cachedToString;
  private final String device;
  private final boolean absolutePath;
  private final String[] segments;
  private final String query;
  private static final Map uriCache = Collections.synchronizedMap(new HashMap());
  private static final Set archiveSchemes;
  private static final String SCHEME_FILE = "file";
  private static final String SCHEME_JAR = "jar";
  private static final String SCHEME_ZIP = "zip";
  private static final String SCHEME_ARCHIVE = "archive";
  private static final String SEGMENT_EMPTY = "";
  private static final String SEGMENT_SELF = ".";
  private static final String SEGMENT_PARENT = "..";
  private static final String[] NO_SEGMENTS = new String[0];
  private static final char SCHEME_SEPARATOR = ':';
  private static final String AUTHORITY_SEPARATOR = "//";
  private static final char DEVICE_IDENTIFIER = ':';
  private static final char SEGMENT_SEPARATOR = '/';
  private static final char QUERY_SEPARATOR = '?';
  private static final char FRAGMENT_SEPARATOR = '#';
  private static final char USER_INFO_SEPARATOR = '@';
  private static final char PORT_SEPARATOR = ':';
  private static final char FILE_EXTENSION_SEPARATOR = '.';
  private static final char ARCHIVE_IDENTIFIER = '!';
  private static final String ARCHIVE_SEPARATOR = "!/";
  private static final char ESCAPE = '%';
  private static final char[] HEX_DIGITS = {
    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
  private static final long ALPHA_HI = highBitmask('a', 'z') | highBitmask('A', 'Z');
  private static final long ALPHA_LO = lowBitmask('a', 'z') | lowBitmask('A', 'Z');
  private static final long DIGIT_HI = highBitmask('0', '9');
  private static final long DIGIT_LO = lowBitmask('0', '9');
  private static final long ALPHANUM_HI = ALPHA_HI | DIGIT_HI;
  private static final long ALPHANUM_LO = ALPHA_LO | DIGIT_LO;
  private static final long HEX_HI = DIGIT_HI | highBitmask('A', 'F') | highBitmask('a', 'f');
  private static final long HEX_LO = DIGIT_LO | lowBitmask('A', 'F') | lowBitmask('a', 'f');
  private static final long UNRESERVED_HI = ALPHANUM_HI | highBitmask("-_.!~*'()");
  private static final long UNRESERVED_LO = ALPHANUM_LO | lowBitmask("-_.!~*'()");
  private static final long RESERVED_HI = highBitmask(";/?:@&=+$,");
  private static final long RESERVED_LO = lowBitmask(";/?:@&=+$,");
  private static final long URIC_HI = RESERVED_HI | UNRESERVED_HI;
  private static final long URIC_LO = RESERVED_LO | UNRESERVED_LO;
  private static final long SEGMENT_CHAR_HI = UNRESERVED_HI | highBitmask(";:@&=+$,");
  private static final long SEGMENT_CHAR_LO = UNRESERVED_LO | lowBitmask(";:@&=+$,");
  private static final long PATH_CHAR_HI = SEGMENT_CHAR_HI | highBitmask('/');
  private static final long PATH_CHAR_LO = SEGMENT_CHAR_LO | lowBitmask('/');
  private static final long MAJOR_SEPARATOR_HI = highBitmask(":/?#");
  private static final long MAJOR_SEPARATOR_LO = lowBitmask(":/?#");
  private static final long SEGMENT_END_HI = highBitmask("/?#");
  private static final long SEGMENT_END_LO = lowBitmask("/?#");
  
  static
  {
    Set set = new HashSet();
    set.add("jar");
    set.add("zip");
    set.add("archive");
    
    archiveSchemes = Collections.unmodifiableSet(set);
  }
  
  private static long lowBitmask(char c)
  {
    return c < '@' ? 1L << c : 0L;
  }
  
  private static long highBitmask(char c)
  {
    return (c >= '@') && (c < '?') ? 1L << c - '@' : 0L;
  }
  
  private static long lowBitmask(char from, char to)
  {
    long result = 0L;
    if ((from < '@') && (from <= to))
    {
      to = to < '@' ? to : '?';
      for (char c = from; c <= to; c = (char)(c + '\001')) {
        result |= 1L << c;
      }
    }
    return result;
  }
  
  private static long highBitmask(char from, char to)
  {
    return to < '@' ? 0L : lowBitmask((char)(from < '@' ? 0 : from - '@'), (char)(to - '@'));
  }
  
  private static long lowBitmask(String chars)
  {
    long result = 0L;
    int i = 0;
    for (int len = chars.length(); i < len; i++)
    {
      char c = chars.charAt(i);
      if (c < '@') {
        result |= 1L << c;
      }
    }
    return result;
  }
  
  private static long highBitmask(String chars)
  {
    long result = 0L;
    int i = 0;
    for (int len = chars.length(); i < len; i++)
    {
      char c = chars.charAt(i);
      if ((c >= '@') && (c < '?')) {
        result |= 1L << c - '@';
      }
    }
    return result;
  }
  
  private static boolean matches(char c, long highBitmask, long lowBitmask)
  {
    if (c >= '?') {
      return false;
    }
    return 
      (1L << c & lowBitmask) != 0L;
  }
  
  public static URI createGenericURI(String scheme, String opaquePart, String fragment)
  {
    if (scheme == null) {
      throw new IllegalArgumentException("relative non-hierarchical URI");
    }
    if (isArchiveScheme(scheme)) {
      throw new IllegalArgumentException("non-hierarchical archive URI");
    }
    validateURI(false, scheme, opaquePart, null, false, NO_SEGMENTS, null, fragment);
    return new URI(false, scheme, opaquePart, null, false, NO_SEGMENTS, null, fragment);
  }
  
  public static URI createHierarchicalURI(String scheme, String authority, String device, String query, String fragment)
  {
    if ((scheme != null) && (authority == null) && (device == null)) {
      throw new IllegalArgumentException(
        "absolute hierarchical URI without authority, device, path");
    }
    if (isArchiveScheme(scheme)) {
      throw new IllegalArgumentException("archive URI with no path");
    }
    validateURI(true, scheme, authority, device, false, NO_SEGMENTS, query, fragment);
    return new URI(true, scheme, authority, device, false, NO_SEGMENTS, query, fragment);
  }
  
  public static URI createHierarchicalURI(String scheme, String authority, String device, String[] segments, String query, String fragment)
  {
    if ((isArchiveScheme(scheme)) && (device != null)) {
      throw new IllegalArgumentException("archive URI with device");
    }
    segments = fix(segments);
    validateURI(true, scheme, authority, device, true, segments, query, fragment);
    return new URI(true, scheme, authority, device, true, segments, query, fragment);
  }
  
  public static URI createHierarchicalURI(String[] segments, String query, String fragment)
  {
    segments = fix(segments);
    validateURI(true, null, null, null, false, segments, query, fragment);
    return new URI(true, null, null, null, false, segments, query, fragment);
  }
  
  private static String[] fix(String[] segments)
  {
    return segments == null ? NO_SEGMENTS : (String[])segments.clone();
  }
  
  public static URI createURI(String uri)
  {
    return createURIWithCache(uri);
  }
  
  public static URI createURI(String uri, boolean ignoreEscaped)
  {
    return createURIWithCache(encodeURI(uri, ignoreEscaped));
  }
  
  /**
   * @deprecated
   */
  public static URI createDeviceURI(String uri)
  {
    return createURIWithCache(uri);
  }
  
  /**
   * @deprecated
   */
  public static URI createURIWithCache(String uri)
  {
    int i = uri.indexOf('#');
    String base = i == -1 ? uri : uri.substring(0, i);
    String fragment = i == -1 ? null : uri.substring(i + 1);
    
    URI result = (URI)uriCache.get(base);
    if (result == null)
    {
      result = parseIntoURI(base);
      uriCache.put(base, result);
    }
    if (fragment != null) {
      result = result.appendFragment(fragment);
    }
    return result;
  }
  
  private static URI parseIntoURI(String uri)
  {
    boolean hierarchical = true;
    String scheme = null;
    String authority = null;
    String device = null;
    boolean absolutePath = false;
    String[] segments = NO_SEGMENTS;
    String query = null;
    String fragment = null;
    
    int i = 0;
    int j = find(uri, i, MAJOR_SEPARATOR_HI, MAJOR_SEPARATOR_LO);
    if ((j < uri.length()) && (uri.charAt(j) == ':'))
    {
      scheme = uri.substring(i, j);
      i = j + 1;
    }
    boolean archiveScheme = isArchiveScheme(scheme);
    if (archiveScheme)
    {
      j = uri.lastIndexOf("!/");
      if (j == -1) {
        throw new IllegalArgumentException("no archive separator");
      }
      hierarchical = true;
      authority = uri.substring(i, ++j);
      i = j;
    }
    else if (uri.startsWith("//", i))
    {
      i += "//".length();
      j = find(uri, i, SEGMENT_END_HI, SEGMENT_END_LO);
      authority = uri.substring(i, j);
      i = j;
    }
    else if ((scheme != null) && (
      (i == uri.length()) || (uri.charAt(i) != '/')))
    {
      hierarchical = false;
      j = uri.indexOf('#', i);
      if (j == -1) {
        j = uri.length();
      }
      authority = uri.substring(i, j);
      i = j;
    }
    if ((!archiveScheme) && (i < uri.length()) && (uri.charAt(i) == '/'))
    {
      j = find(uri, i + 1, SEGMENT_END_HI, SEGMENT_END_LO);
      String s = uri.substring(i + 1, j);
      if ((s.length() > 0) && (s.charAt(s.length() - 1) == ':'))
      {
        device = s;
        i = j;
      }
    }
    if ((i < uri.length()) && (uri.charAt(i) == '/'))
    {
      i++;
      absolutePath = true;
    }
    if (segmentsRemain(uri, i))
    {
      List segmentList = new ArrayList();
      while (segmentsRemain(uri, i))
      {
        j = find(uri, i, SEGMENT_END_HI, SEGMENT_END_LO);
        segmentList.add(uri.substring(i, j));
        i = j;
        if ((i < uri.length()) && (uri.charAt(i) == '/')) {
          if (!segmentsRemain(uri, ++i)) {
            segmentList.add("");
          }
        }
      }
      segments = new String[segmentList.size()];
      segmentList.toArray(segments);
    }
    if ((i < uri.length()) && (uri.charAt(i) == '?'))
    {
      j = uri.indexOf('#', ++i);
      if (j == -1) {
        j = uri.length();
      }
      query = uri.substring(i, j);
      i = j;
    }
    if (i < uri.length()) {
      fragment = uri.substring(++i);
    }
    validateURI(hierarchical, scheme, authority, device, absolutePath, segments, query, fragment);
    return new URI(hierarchical, scheme, authority, device, absolutePath, segments, query, fragment);
  }
  
  private static boolean segmentsRemain(String uri, int i)
  {
    return (i < uri.length()) && (uri.charAt(i) != '?') && (uri.charAt(i) != '#');
  }
  
  private static int find(String s, int i, long highBitmask, long lowBitmask)
  {
    int len = s.length();
    if (i >= len) {
      return len;
    }
    for (i = i > 0 ? i : 0; i < len; i++) {
      if (matches(s.charAt(i), highBitmask, lowBitmask)) {
        break;
      }
    }
    return i;
  }
  
  public static URI createFileURI(String pathName)
  {
    File file = new File(pathName);
    String uri = File.separatorChar != '/' ? pathName.replace(File.separatorChar, '/') : pathName;
    uri = encode(uri, PATH_CHAR_HI, PATH_CHAR_LO, false);
    if (file.isAbsolute())
    {
      URI result = createURI((uri.charAt(0) == '/' ? "file:" : "file:/") + uri);
      return result;
    }
    URI result = createURI(uri);
    if (result.scheme() != null) {
      throw new IllegalArgumentException("invalid relative pathName: " + pathName);
    }
    return result;
  }
  
  public static URI createPlatformResourceURI(String pathName)
  {
    return createPlatformResourceURI(pathName, false);
  }
  
  public static URI createPlatformResourceURI(String pathName, boolean encode)
  {
    if (File.separatorChar != '/') {
      pathName = pathName.replace(File.separatorChar, '/');
    }
    if (encode) {
      pathName = encode(pathName, PATH_CHAR_HI, PATH_CHAR_LO, false);
    }
    URI result = createURI((pathName.charAt(0) == '/' ? "platform:/resource" : "platform:/resource/") + pathName);
    return result;
  }
  
  private URI(boolean hierarchical, String scheme, String authority, String device, boolean absolutePath, String[] segments, String query, String fragment)
  {
    int hashCode = 0;
    if (hierarchical) {
      hashCode++;
    }
    if (absolutePath) {
      hashCode += 2;
    }
    if (scheme != null) {
      hashCode ^= scheme.toLowerCase().hashCode();
    }
    if (authority != null) {
      hashCode ^= authority.hashCode();
    }
    if (device != null) {
      hashCode ^= device.hashCode();
    }
    if (query != null) {
      hashCode ^= query.hashCode();
    }
    if (fragment != null) {
      hashCode ^= fragment.hashCode();
    }
    int i = 0;
    for (int len = segments.length; i < len; i++) {
      hashCode ^= segments[i].hashCode();
    }
    this.hashCode = hashCode;
    
    this.hierarchical = hierarchical;
    this.scheme = (scheme == null ? null : scheme.intern());
    this.authority = authority;
    this.device = device;
    this.absolutePath = absolutePath;
    this.segments = segments;
    this.query = query;
    this.fragment = fragment;
  }
  
  private static void validateURI(boolean hierarchical, String scheme, String authority, String device, boolean absolutePath, String[] segments, String query, String fragment)
  {
    if (!validScheme(scheme)) {
      throw new IllegalArgumentException("invalid scheme: " + scheme);
    }
    if ((!hierarchical) && (!validOpaquePart(authority))) {
      throw new IllegalArgumentException("invalid opaquePart: " + authority);
    }
    if ((hierarchical) && (!isArchiveScheme(scheme)) && (!validAuthority(authority))) {
      throw new IllegalArgumentException("invalid authority: " + authority);
    }
    if ((hierarchical) && (isArchiveScheme(scheme)) && (!validArchiveAuthority(authority))) {
      throw new IllegalArgumentException("invalid authority: " + authority);
    }
    if (!validDevice(device)) {
      throw new IllegalArgumentException("invalid device: " + device);
    }
    if (!validSegments(segments))
    {
      String s = 
        "invalid segment: " + firstInvalidSegment(segments);
      throw new IllegalArgumentException(s);
    }
    if (!validQuery(query)) {
      throw new IllegalArgumentException("invalid query: " + query);
    }
    if (!validFragment(fragment)) {
      throw new IllegalArgumentException("invalid fragment: " + fragment);
    }
  }
  
  public static boolean validScheme(String value)
  {
    return (value == null) || (!contains(value, MAJOR_SEPARATOR_HI, MAJOR_SEPARATOR_LO));
  }
  
  public static boolean validOpaquePart(String value)
  {
    return (value != null) && (value.indexOf('#') == -1) && (value.length() > 0) && (value.charAt(0) != '/');
  }
  
  public static boolean validAuthority(String value)
  {
    return (value == null) || (!contains(value, SEGMENT_END_HI, SEGMENT_END_LO));
  }
  
  public static boolean validArchiveAuthority(String value)
  {
    if ((value != null) && (value.length() > 0) && 
      (value.charAt(value.length() - 1) == '!')) {
      try
      {
        URI archiveURI = createURI(value.substring(0, value.length() - 1));
        return !archiveURI.hasFragment();
      }
      catch (IllegalArgumentException localIllegalArgumentException) {}
    }
    return false;
  }
  
  public static boolean validDevice(String value)
  {
    if (value == null) {
      return true;
    }
    int len = value.length();
    
    return (len > 0) && (value.charAt(len - 1) == ':') && (!contains(value, SEGMENT_END_HI, SEGMENT_END_LO));
  }
  
  public static boolean validSegment(String value)
  {
    return (value != null) && (!contains(value, SEGMENT_END_HI, SEGMENT_END_LO));
  }
  
  public static boolean validSegments(String[] value)
  {
    if (value == null) {
      return false;
    }
    int i = 0;
    for (int len = value.length; i < len; i++) {
      if (!validSegment(value[i])) {
        return false;
      }
    }
    return true;
  }
  
  private static String firstInvalidSegment(String[] value)
  {
    if (value == null) {
      return null;
    }
    int i = 0;
    for (int len = value.length; i < len; i++) {
      if (!validSegment(value[i])) {
        return value[i];
      }
    }
    return null;
  }
  
  public static boolean validQuery(String value)
  {
    return (value == null) || (value.indexOf('#') == -1);
  }
  
  public static boolean validFragment(String value)
  {
    return true;
  }
  
  private static boolean contains(String s, long highBitmask, long lowBitmask)
  {
    int i = 0;
    for (int len = s.length(); i < len; i++) {
      if (matches(s.charAt(i), highBitmask, lowBitmask)) {
        return true;
      }
    }
    return false;
  }
  
  public boolean isRelative()
  {
    return scheme == null;
  }
  
  public boolean isHierarchical()
  {
    return hierarchical;
  }
  
  public boolean hasAuthority()
  {
    return (hierarchical) && (authority != null);
  }
  
  public boolean hasOpaquePart()
  {
    return !hierarchical;
  }
  
  public boolean hasDevice()
  {
    return device != null;
  }
  
  public boolean hasPath()
  {
    return (absolutePath) || ((authority == null) && (device == null));
  }
  
  public boolean hasAbsolutePath()
  {
    return absolutePath;
  }
  
  public boolean hasRelativePath()
  {
    return (authority == null) && (device == null) && (!absolutePath);
  }
  
  public boolean hasEmptyPath()
  {
    return (authority == null) && (device == null) && (!absolutePath) && (segments.length == 0);
  }
  
  public boolean hasQuery()
  {
    return query != null;
  }
  
  public boolean hasFragment()
  {
    return fragment != null;
  }
  
  public boolean isCurrentDocumentReference()
  {
    return (authority == null) && (device == null) && (!absolutePath) && (segments.length == 0) && (query == null);
  }
  
  public boolean isEmpty()
  {
    return (authority == null) && (device == null) && (!absolutePath) && (segments.length == 0) && (query == null) && (fragment == null);
  }
  
  public boolean isFile()
  {
    return (isHierarchical()) && (((isRelative()) && (!hasQuery())) || ("file".equalsIgnoreCase(scheme)));
  }
  
  private boolean isArchive()
  {
    return isArchiveScheme(scheme);
  }
  
  public static boolean isArchiveScheme(String value)
  {
    return (value != null) && (archiveSchemes.contains(value.toLowerCase()));
  }
  
  public int hashCode()
  {
    return hashCode;
  }
  
  public boolean equals(Object obj)
  {
    if (this == obj) {
      return true;
    }
    if (!(obj instanceof URI)) {
      return false;
    }
    URI uri = (URI)obj;
    if ((hashCode == uri.hashCode()) && 
      (hierarchical == uri.isHierarchical()) && 
      (absolutePath == uri.hasAbsolutePath()) && 
      (equals(scheme, uri.scheme(), true))) {
      if ((equals(authority, hierarchical ? uri.authority() : uri.opaquePart())) && 
        (equals(device, uri.device())) && 
        (equals(query, uri.query())) && 
        (equals(fragment, uri.fragment())) && 
        (segmentsEqual(uri))) {
        return true;
      }
    }
    return 
    
      false;
  }
  
  private boolean segmentsEqual(URI uri)
  {
    if (segments.length != uri.segmentCount()) {
      return false;
    }
    int i = 0;
    for (int len = segments.length; i < len; i++) {
      if (!segments[i].equals(uri.segment(i))) {
        return false;
      }
    }
    return true;
  }
  
  private static boolean equals(Object o1, Object o2)
  {
    return o1 == null ? false : o2 == null ? true : o1.equals(o2);
  }
  
  private static boolean equals(String s1, String s2, boolean ignoreCase)
  {
    return 
      ignoreCase ? s1.equalsIgnoreCase(s2) : s1 == null ? false : s2 == null ? true : s1.equals(s2);
  }
  
  public String scheme()
  {
    return scheme;
  }
  
  public String opaquePart()
  {
    return isHierarchical() ? null : authority;
  }
  
  public String authority()
  {
    return isHierarchical() ? authority : null;
  }
  
  public String userInfo()
  {
    if (!hasAuthority()) {
      return null;
    }
    int i = authority.indexOf('@');
    return i < 0 ? null : authority.substring(0, i);
  }
  
  public String host()
  {
    if (!hasAuthority()) {
      return null;
    }
    int i = authority.indexOf('@');
    int j = authority.indexOf(':');
    return j < 0 ? authority.substring(i + 1) : authority.substring(i + 1, j);
  }
  
  public String port()
  {
    if (!hasAuthority()) {
      return null;
    }
    int i = authority.indexOf(':');
    return i < 0 ? null : authority.substring(i + 1);
  }
  
  public String device()
  {
    return device;
  }
  
  public String[] segments()
  {
    return (String[])segments.clone();
  }
  
  public List segmentsList()
  {
    return Collections.unmodifiableList(Arrays.asList(segments));
  }
  
  public int segmentCount()
  {
    return segments.length;
  }
  
  public String segment(int i)
  {
    return segments[i];
  }
  
  public String lastSegment()
  {
    int len = segments.length;
    if (len == 0) {
      return null;
    }
    return segments[(len - 1)];
  }
  
  public String path()
  {
    if (!hasPath()) {
      return null;
    }
    StringBuffer result = new StringBuffer();
    if (hasAbsolutePath()) {
      result.append('/');
    }
    int i = 0;
    for (int len = segments.length; i < len; i++)
    {
      if (i != 0) {
        result.append('/');
      }
      result.append(segments[i]);
    }
    return result.toString();
  }
  
  public String devicePath()
  {
    if (!hasPath()) {
      return null;
    }
    StringBuffer result = new StringBuffer();
    if (hasAuthority())
    {
      if (!isArchive()) {
        result.append("//");
      }
      result.append(authority);
      if (hasDevice()) {
        result.append('/');
      }
    }
    if (hasDevice()) {
      result.append(device);
    }
    if (hasAbsolutePath()) {
      result.append('/');
    }
    int i = 0;
    for (int len = segments.length; i < len; i++)
    {
      if (i != 0) {
        result.append('/');
      }
      result.append(segments[i]);
    }
    return result.toString();
  }
  
  public String query()
  {
    return query;
  }
  
  public URI appendQuery(String query)
  {
    if (!validQuery(query)) {
      throw new IllegalArgumentException(
        "invalid query portion: " + query);
    }
    return new URI(hierarchical, scheme, authority, device, absolutePath, segments, query, fragment);
  }
  
  public URI trimQuery()
  {
    if (query == null) {
      return this;
    }
    return new URI(hierarchical, scheme, authority, device, absolutePath, segments, null, fragment);
  }
  
  public String fragment()
  {
    return fragment;
  }
  
  public URI appendFragment(String fragment)
  {
    if (!validFragment(fragment)) {
      throw new IllegalArgumentException(
        "invalid fragment portion: " + fragment);
    }
    URI result = new URI(hierarchical, scheme, authority, device, absolutePath, segments, query, fragment);
    if (!hasFragment()) {
      cachedTrimFragment = this;
    }
    return result;
  }
  
  public URI trimFragment()
  {
    if (fragment == null) {
      return this;
    }
    if (cachedTrimFragment == null) {
      cachedTrimFragment = new URI(hierarchical, scheme, authority, device, absolutePath, segments, query, null);
    }
    return cachedTrimFragment;
  }
  
  public URI resolve(URI base)
  {
    return resolve(base, true);
  }
  
  public URI resolve(URI base, boolean preserveRootParents)
  {
    if ((!base.isHierarchical()) || (base.isRelative())) {
      throw new IllegalArgumentException(
        "resolve against non-hierarchical or relative base");
    }
    if (!isRelative()) {
      return this;
    }
    String newAuthority = authority;
    String newDevice = device;
    boolean newAbsolutePath = absolutePath;
    String[] newSegments = segments;
    String newQuery = query;
    if (authority == null)
    {
      newAuthority = base.authority();
      if (device == null)
      {
        newDevice = base.device();
        if ((hasEmptyPath()) && (query == null))
        {
          newAbsolutePath = base.hasAbsolutePath();
          newSegments = base.segments();
          newQuery = base.query();
        }
        else if (hasRelativePath())
        {
          newAbsolutePath = (base.hasAbsolutePath()) || (!hasEmptyPath());
          newSegments = newAbsolutePath ? mergePath(base, preserveRootParents) : 
            NO_SEGMENTS;
        }
      }
    }
    return new URI(true, base.scheme(), newAuthority, newDevice, 
      newAbsolutePath, newSegments, newQuery, fragment);
  }
  
  private String[] mergePath(URI base, boolean preserveRootParents)
  {
    if (base.hasRelativePath()) {
      throw new IllegalArgumentException("merge against relative path");
    }
    if (!hasRelativePath()) {
      throw new IllegalStateException("merge non-relative path");
    }
    int baseSegmentCount = base.segmentCount();
    int segmentCount = segments.length;
    String[] stack = new String[baseSegmentCount + segmentCount];
    int sp = 0;
    for (int i = 0; i < baseSegmentCount - 1; i++) {
      sp = accumulate(stack, sp, base.segment(i), preserveRootParents);
    }
    for (int i = 0; i < segmentCount; i++) {
      sp = accumulate(stack, sp, segments[i], preserveRootParents);
    }
    if ((sp > 0) && ((segmentCount == 0) || 
      ("".equals(segments[(segmentCount - 1)])) || 
      ("..".equals(segments[(segmentCount - 1)])) || 
      (".".equals(segments[(segmentCount - 1)])))) {
      stack[(sp++)] = "";
    }
    String[] result = new String[sp];
    System.arraycopy(stack, 0, result, 0, sp);
    return result;
  }
  
  private static int accumulate(String[] stack, int sp, String segment, boolean preserveRootParents)
  {
    if ("..".equals(segment))
    {
      if (sp == 0)
      {
        if (preserveRootParents) {
          stack[(sp++)] = segment;
        }
      }
      else if ("..".equals(stack[(sp - 1)])) {
        stack[(sp++)] = segment;
      } else {
        sp--;
      }
    }
    else if ((!"".equals(segment)) && (!".".equals(segment))) {
      stack[(sp++)] = segment;
    }
    return sp;
  }
  
  public URI deresolve(URI base)
  {
    return deresolve(base, true, false, true);
  }
  
  public URI deresolve(URI base, boolean preserveRootParents, boolean anyRelPath, boolean shorterRelPath)
  {
    if ((!base.isHierarchical()) || (base.isRelative())) {
      throw new IllegalArgumentException(
        "deresolve against non-hierarchical or relative base");
    }
    if (isRelative()) {
      throw new IllegalStateException("deresolve relative URI");
    }
    if (!scheme.equalsIgnoreCase(base.scheme())) {
      return this;
    }
    if (!isHierarchical()) {
      return this;
    }
    String newAuthority = authority;
    String newDevice = device;
    boolean newAbsolutePath = absolutePath;
    String[] newSegments = segments;
    String newQuery = query;
    if ((equals(authority, base.authority())) && (
      (hasDevice()) || (hasPath()) || ((!base.hasDevice()) && (!base.hasPath()))))
    {
      newAuthority = null;
      if ((equals(device, base.device())) && ((hasPath()) || (!base.hasPath())))
      {
        newDevice = null;
        if ((anyRelPath) || (shorterRelPath)) {
          if ((hasPath() == base.hasPath()) && (segmentsEqual(base)) && 
            (equals(query, base.query())))
          {
            newAbsolutePath = false;
            newSegments = NO_SEGMENTS;
            newQuery = null;
          }
          else if ((!hasPath()) && (!base.hasPath()))
          {
            newAbsolutePath = false;
            newSegments = NO_SEGMENTS;
          }
          else if (!hasCollapsableSegments(preserveRootParents))
          {
            String[] rel = findRelativePath(base, preserveRootParents);
            if ((anyRelPath) || (segments.length > rel.length))
            {
              newAbsolutePath = false;
              newSegments = rel;
            }
          }
        }
      }
    }
    return new URI(true, null, newAuthority, newDevice, newAbsolutePath, 
      newSegments, newQuery, fragment);
  }
  
  private boolean hasCollapsableSegments(boolean preserveRootParents)
  {
    if (hasRelativePath()) {
      throw new IllegalStateException("test collapsability of relative path");
    }
    int i = 0;
    for (int len = segments.length; i < len; i++)
    {
      String segment = segments[i];
      if (((i < len - 1) && ("".equals(segment))) || 
        (".".equals(segment)) || (
        ("..".equals(segment)) && (
        (!preserveRootParents) || (
        (i != 0) && (!"..".equals(segments[(i - 1)])))))) {
        return true;
      }
    }
    return false;
  }
  
  private String[] findRelativePath(URI base, boolean preserveRootParents)
  {
    if (base.hasRelativePath()) {
      throw new IllegalArgumentException(
        "find relative path against base with relative path");
    }
    if (!hasAbsolutePath()) {
      throw new IllegalArgumentException(
        "find relative path of non-absolute path");
    }
    String[] startPath = base.collapseSegments(preserveRootParents);
    String[] endPath = segments;
    
    int startCount = startPath.length > 0 ? startPath.length - 1 : 0;
    int endCount = endPath.length;
    
    int diff = 0;
    
    int count = startCount < endCount ? startCount : endCount - 1;
    while ((diff < count) && (startPath[diff].equals(endPath[diff]))) {
      diff++;
    }
    int upCount = startCount - diff;
    int downCount = endCount - diff;
    if ((downCount == 1) && ("".equals(endPath[(endCount - 1)]))) {
      downCount = 0;
    }
    if (upCount + downCount == 0)
    {
      if (query == null) {
        return new String[] { "." };
      }
      return NO_SEGMENTS;
    }
    String[] result = new String[upCount + downCount];
    Arrays.fill(result, 0, upCount, "..");
    System.arraycopy(endPath, diff, result, upCount, downCount);
    return result;
  }
  
  String[] collapseSegments(boolean preserveRootParents)
  {
    if (hasRelativePath()) {
      throw new IllegalStateException("collapse relative path");
    }
    if (!hasCollapsableSegments(preserveRootParents)) {
      return segments();
    }
    int segmentCount = segments.length;
    String[] stack = new String[segmentCount];
    int sp = 0;
    for (int i = 0; i < segmentCount; i++) {
      sp = accumulate(stack, sp, segments[i], preserveRootParents);
    }
    if ((sp > 0) && (("".equals(segments[(segmentCount - 1)])) || 
      ("..".equals(segments[(segmentCount - 1)])) || 
      (".".equals(segments[(segmentCount - 1)])))) {
      stack[(sp++)] = "";
    }
    String[] result = new String[sp];
    System.arraycopy(stack, 0, result, 0, sp);
    return result;
  }
  
  public String toString()
  {
    if (cachedToString == null)
    {
      StringBuffer result = new StringBuffer();
      if (!isRelative())
      {
        result.append(scheme);
        result.append(':');
      }
      if (isHierarchical())
      {
        if (hasAuthority())
        {
          if (!isArchive()) {
            result.append("//");
          }
          result.append(authority);
        }
        if (hasDevice())
        {
          result.append('/');
          result.append(device);
        }
        if (hasAbsolutePath()) {
          result.append('/');
        }
        int i = 0;
        for (int len = segments.length; i < len; i++)
        {
          if (i != 0) {
            result.append('/');
          }
          result.append(segments[i]);
        }
        if (hasQuery())
        {
          result.append('?');
          result.append(query);
        }
      }
      else
      {
        result.append(authority);
      }
      if (hasFragment())
      {
        result.append('#');
        result.append(fragment);
      }
      cachedToString = result.toString();
    }
    return cachedToString;
  }
  
  String toString(boolean includeSimpleForm)
  {
    StringBuffer result = new StringBuffer();
    if (includeSimpleForm) {
      result.append(toString());
    }
    result.append("\n hierarchical: ");
    result.append(hierarchical);
    result.append("\n       scheme: ");
    result.append(scheme);
    result.append("\n    authority: ");
    result.append(authority);
    result.append("\n       device: ");
    result.append(device);
    result.append("\n absolutePath: ");
    result.append(absolutePath);
    result.append("\n     segments: ");
    if (segments.length == 0) {
      result.append("<empty>");
    }
    int i = 0;
    for (int len = segments.length; i < len; i++)
    {
      if (i > 0) {
        result.append("\n               ");
      }
      result.append(segments[i]);
    }
    result.append("\n        query: ");
    result.append(query);
    result.append("\n     fragment: ");
    result.append(fragment);
    return result.toString();
  }
  
  public String toFileString()
  {
    if (!isFile()) {
      return null;
    }
    StringBuffer result = new StringBuffer();
    char separator = File.separatorChar;
    if (hasAuthority())
    {
      result.append(separator);
      result.append(separator);
      result.append(authority);
      if (hasDevice()) {
        result.append(separator);
      }
    }
    if (hasDevice()) {
      result.append(device);
    }
    if (hasAbsolutePath()) {
      result.append(separator);
    }
    int i = 0;
    for (int len = segments.length; i < len; i++)
    {
      if (i != 0) {
        result.append(separator);
      }
      result.append(segments[i]);
    }
    return decode(result.toString());
  }
  
  public URI appendSegment(String segment)
  {
    if (!validSegment(segment)) {
      throw new IllegalArgumentException("invalid segment: " + segment);
    }
    if (!isHierarchical()) {
      return this;
    }
    boolean newAbsolutePath = !hasRelativePath();
    
    int len = segments.length;
    String[] newSegments = new String[len + 1];
    System.arraycopy(segments, 0, newSegments, 0, len);
    newSegments[len] = segment;
    
    return new URI(true, scheme, authority, device, newAbsolutePath, 
      newSegments, query, fragment);
  }
  
  public URI appendSegments(String[] segments)
  {
    if (!validSegments(segments))
    {
      String s = 
        "invalid segment: " + firstInvalidSegment(segments);
      throw new IllegalArgumentException(s);
    }
    if (!isHierarchical()) {
      return this;
    }
    boolean newAbsolutePath = !hasRelativePath();
    
    int len = this.segments.length;
    int segmentsCount = segments.length;
    String[] newSegments = new String[len + segmentsCount];
    System.arraycopy(this.segments, 0, newSegments, 0, len);
    System.arraycopy(segments, 0, newSegments, len, segmentsCount);
    
    return new URI(true, scheme, authority, device, newAbsolutePath, 
      newSegments, query, fragment);
  }
  
  public URI trimSegments(int i)
  {
    if ((!isHierarchical()) || (i < 1)) {
      return this;
    }
    String[] newSegments = NO_SEGMENTS;
    int len = segments.length - i;
    if (len > 0)
    {
      newSegments = new String[len];
      System.arraycopy(
1 2

Further reading...

For more information on Java 1.5 Tiger, you may find Java 1.5 Tiger, A developer's Notebook by D. Flanagan and B. McLaughlin from O'Reilly of interest.

New!JAR listings


Copyright 2006-2019. Infinite Loop Ltd