001: /*
002: * @(#)Handler.java 1.24 06/10/10
003: *
004: * Copyright 1990-2006 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: *
026: */
027:
028: package sun.net.www.protocol.jar;
029:
030: import java.io.*;
031: import java.net.*;
032: import java.util.*;
033: import sun.net.www.ParseUtil;
034:
035: /*
036: * Jar URL Handler
037: */
038: public class Handler extends java.net.URLStreamHandler {
039:
040: private static final String separator = "!/";
041:
042: protected java.net.URLConnection openConnection(URL u)
043: throws IOException {
044: return new JarURLConnection(u, this );
045: }
046:
047: private int indexOfBangSlash(String spec) {
048: int indexOfBang = spec.length();
049: while ((indexOfBang = spec.lastIndexOf('!', indexOfBang)) != -1) {
050: if ((indexOfBang != (spec.length() - 1))
051: && (spec.charAt(indexOfBang + 1) == '/')) {
052: return indexOfBang + 1;
053: } else {
054: indexOfBang--;
055: }
056: }
057: return -1;
058: }
059:
060: protected void parseURL(URL url, String spec, int start, int limit) {
061: String file = null;
062: String ref = null;
063: // first figure out if there is an anchor
064: int refPos = spec.indexOf('#', limit);
065: boolean refOnly = refPos == start;
066: if (refPos > -1) {
067: ref = spec.substring(refPos + 1, spec.length());
068: if (refOnly) {
069: file = url.getFile();
070: }
071: }
072: // then figure out if the spec is
073: // 1. absolute (jar:)
074: // 2. relative (i.e. url + foo/bar/baz.ext)
075: // 3. anchor-only (i.e. url + #foo), which we already did (refOnly)
076: boolean absoluteSpec = false;
077: if (spec.length() >= 4) {
078: absoluteSpec = spec.substring(0, 4)
079: .equalsIgnoreCase("jar:");
080: }
081: spec = spec.substring(start, limit);
082:
083: if (absoluteSpec) {
084: file = parseAbsoluteSpec(spec);
085: } else if (!refOnly) {
086: file = parseContextSpec(url, spec);
087:
088: // Canonize the result after the bangslash
089: int bangSlash = indexOfBangSlash(file);
090: String toBangSlash = file.substring(0, bangSlash);
091: String afterBangSlash = file.substring(bangSlash);
092: sun.net.www.ParseUtil canonizer = new ParseUtil();
093: afterBangSlash = canonizer.canonizeString(afterBangSlash);
094: file = toBangSlash + afterBangSlash;
095: }
096: setURL(url, "jar", "", -1, null, null, file, null, ref);
097: }
098:
099: private String parseAbsoluteSpec(String spec) {
100: URL url = null;
101: int index = -1;
102: // check for !/
103: if ((index = indexOfBangSlash(spec)) == -1) {
104: throw new NullPointerException("no !/ in spec");
105: }
106: // test the inner URL
107: try {
108: String innerSpec = spec.substring(0, index - 1);
109: url = new URL(innerSpec);
110: } catch (MalformedURLException e) {
111: throw new NullPointerException("invalid url: " + spec
112: + " (" + e + ")");
113: }
114: return spec;
115: }
116:
117: private String parseContextSpec(URL url, String spec) {
118: String ctxFile = url.getFile();
119: // if the spec begins with /, chop up the jar back !/
120: if (spec.startsWith("/")) {
121: int bangSlash = indexOfBangSlash(ctxFile);
122: if (bangSlash == -1) {
123: throw new NullPointerException("malformed "
124: + "context url:" + url + ": no !/");
125: }
126: ctxFile = ctxFile.substring(0, bangSlash);
127: }
128: if (!ctxFile.endsWith("/") && (!spec.startsWith("/"))) {
129: // chop up the last component
130: int lastSlash = ctxFile.lastIndexOf('/');
131: if (lastSlash == -1) {
132: throw new NullPointerException("malformed "
133: + "context url:" + url);
134: }
135: ctxFile = ctxFile.substring(0, lastSlash + 1);
136: }
137: return (ctxFile + spec);
138: }
139: }
|