blob: 3ac18c7cb31b3a6212ba1a9c81c8043357339de6 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 1997-2000 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26package sun.net.www.protocol.jar;
27
28import java.io.*;
29import java.net.*;
30import java.util.*;
31import sun.net.www.ParseUtil;
32
33/*
34 * Jar URL Handler
35 */
36public class Handler extends java.net.URLStreamHandler {
37
38 private static final String separator = "!/";
39
40 protected java.net.URLConnection openConnection(URL u)
41 throws IOException {
42 return new JarURLConnection(u, this);
43 }
44
45 private int indexOfBangSlash(String spec) {
46 int indexOfBang = spec.length();
47 while((indexOfBang = spec.lastIndexOf('!', indexOfBang)) != -1) {
48 if ((indexOfBang != (spec.length() - 1)) &&
49 (spec.charAt(indexOfBang + 1) == '/')) {
50 return indexOfBang + 1;
51 } else {
52 indexOfBang--;
53 }
54 }
55 return -1;
56 }
57
58 protected void parseURL(URL url, String spec,
59 int start, int limit) {
60 String file = null;
61 String ref = null;
62 // first figure out if there is an anchor
63 int refPos = spec.indexOf('#', limit);
64 boolean refOnly = refPos == start;
65 if (refPos > -1) {
66 ref = spec.substring(refPos + 1, spec.length());
67 if (refOnly) {
68 file = url.getFile();
69 }
70 }
71 // then figure out if the spec is
72 // 1. absolute (jar:)
73 // 2. relative (i.e. url + foo/bar/baz.ext)
74 // 3. anchor-only (i.e. url + #foo), which we already did (refOnly)
75 boolean absoluteSpec = false;
76 if (spec.length() >= 4) {
77 absoluteSpec = spec.substring(0, 4).equalsIgnoreCase("jar:");
78 }
79 spec = spec.substring(start, limit);
80
81 if (absoluteSpec) {
82 file = parseAbsoluteSpec(spec);
83 } else if (!refOnly) {
84 file = parseContextSpec(url, spec);
85
86 // Canonize the result after the bangslash
87 int bangSlash = indexOfBangSlash(file);
88 String toBangSlash = file.substring(0, bangSlash);
89 String afterBangSlash = file.substring(bangSlash);
90 sun.net.www.ParseUtil canonizer = new ParseUtil();
91 afterBangSlash = canonizer.canonizeString(afterBangSlash);
92 file = toBangSlash + afterBangSlash;
93 }
94 setURL(url, "jar", "", -1, file, ref);
95 }
96
97 private String parseAbsoluteSpec(String spec) {
98 URL url = null;
99 int index = -1;
100 // check for !/
101 if ((index = indexOfBangSlash(spec)) == -1) {
102 throw new NullPointerException("no !/ in spec");
103 }
104 // test the inner URL
105 try {
106 String innerSpec = spec.substring(0, index - 1);
107 url = new URL(innerSpec);
108 } catch (MalformedURLException e) {
109 throw new NullPointerException("invalid url: " +
110 spec + " (" + e + ")");
111 }
112 return spec;
113 }
114
115 private String parseContextSpec(URL url, String spec) {
116 String ctxFile = url.getFile();
117 // if the spec begins with /, chop up the jar back !/
118 if (spec.startsWith("/")) {
119 int bangSlash = indexOfBangSlash(ctxFile);
120 if (bangSlash == -1) {
121 throw new NullPointerException("malformed " +
122 "context url:" +
123 url +
124 ": 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:" +
134 url);
135 }
136 ctxFile = ctxFile.substring(0, lastSlash + 1);
137 }
138 return (ctxFile + spec);
139 }
140}