00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 package org.knopflerfish.framework;
00036
00037 import java.net.*;
00038
00039
00045 public class BundleURLStreamHandler extends URLStreamHandler {
00046
00047 final public static String PROTOCOL = "bundle";
00048
00049 final public static String PERM_OK = "P";
00050
00051 private Bundles bundles;
00052
00053 private PermissionOps secure;
00054
00055
00056
00057
00058 BundleURLStreamHandler(Bundles b, PermissionOps s) {
00059 bundles = b;
00060 secure = s;
00061 }
00062
00063
00064 public URLConnection openConnection(URL u) {
00065 if (u.getAuthority() != PERM_OK) {
00066 secure.checkResourceAdminPerm(bundles.getBundle(getId(u.getHost())));
00067 }
00068 return new BundleURLConnection(u, bundles);
00069 }
00070
00071
00072 protected void parseURL(URL u, String s, int start, int limit) {
00073 String path = u.getPath();
00074 String host = u.getHost();
00075 long id = -1;
00076 int cpElem = u.getPort();
00077 if (limit > start) {
00078 int len = limit - start;
00079 char [] sc = new char[len];
00080 s.getChars(start, limit, sc, 0);
00081 int pos = 0;
00082 if (len >= 2 && sc[0] == '/' && sc[1] == '/') {
00083 for (pos = 2; pos < len; pos++) {
00084 if (sc[pos] == ':' || sc[pos] == '/') {
00085 break;
00086 } else if (sc[pos] == '.' || sc[pos] == '_') {
00087 if (id == -1) {
00088 id = Long.parseLong(new String(sc, 2, pos - 2));
00089 }
00090 } else if (!Character.isDigit(sc[pos])) {
00091 throw new IllegalArgumentException("Illegal chars in bundle id specification");
00092 }
00093 }
00094 host = new String(sc, 2, pos - 2);
00095 if (pos < len && sc[pos] == ':') {
00096 ++pos;
00097 cpElem = 0;
00098 while (pos < len) {
00099 if (sc[pos] == '/') {
00100 break;
00101 } else if (!Character.isDigit(sc[pos])) {
00102 throw new IllegalArgumentException("Illegal chars in bundle port specification");
00103 }
00104 cpElem = 10 * cpElem + (sc[pos++] - '0');
00105 }
00106 } else {
00107 cpElem = -1;
00108 }
00109 }
00110 if (pos < len) {
00111 int pstart;
00112 if (sc[pos] != '/') {
00113 if (path != null) {
00114 int dirend = path.lastIndexOf('/') + 1;
00115 if (dirend > 0) {
00116 int plen = len - pos;
00117 pstart = path.startsWith("/") ? 0 : 1;
00118 len = dirend + plen + pstart;
00119 if (len > sc.length) {
00120 char [] newsc = new char [len];
00121 System.arraycopy(sc, pos, newsc, dirend + pstart, plen);
00122 sc = newsc;
00123 } else if (pos != dirend) {
00124 System.arraycopy(sc, pos, sc, dirend + pstart, plen);
00125 }
00126 path.getChars(1 - pstart, dirend, sc, 1);
00127 } else {
00128 len = 1;
00129 }
00130 } else {
00131 len = 1;
00132 }
00133 sc[0] = '/';
00134 pstart = 0;
00135 pos = 0;
00136 } else {
00137 pstart = pos;
00138 }
00139 int dots = 0;
00140 int ipos = pstart - 1;
00141 boolean slash = false;
00142 for (; pos < len; pos++) {
00143 if (sc[pos] == '/') {
00144 if (slash) {
00145 continue;
00146 }
00147 slash = true;
00148 if (dots == 1) {
00149 dots = 0;
00150 continue;
00151 } else if (dots == 2) {
00152 while (ipos > pstart && sc[--ipos] != '/')
00153 ;
00154 }
00155 } else if (sc[pos] == '.') {
00156 if (slash) {
00157 dots = 1;
00158 slash = false;
00159 continue;
00160 } else if (dots == 1) {
00161 dots = 2;
00162 continue;
00163 }
00164 } else {
00165 slash = false;
00166 }
00167 while (dots-- > 0) {
00168 sc[++ipos] = '.';
00169 }
00170 if (++ipos != pos) {
00171 sc[ipos] = sc[pos];
00172 }
00173 }
00174 if (dots == 2) {
00175 while (ipos > pstart && sc[--ipos] != '/')
00176 ;
00177 }
00178 path = new String(sc, pstart, ipos - pstart + 1);
00179 }
00180 }
00181 if (id == -1) {
00182 id = getId(host);
00183 }
00184 secure.checkResourceAdminPerm(bundles.getBundle(id));
00185 setURL(u, u.getProtocol(), host, cpElem, PERM_OK, null, path, null, null);
00186 }
00187
00188
00196 protected boolean equals(URL u1, URL u2) {
00197 return sameFile(u1, u2);
00198 }
00199
00200
00205 protected int hashCode(URL u) {
00206 int h = 0;
00207
00208 if (PROTOCOL.equals(u.getProtocol())) {
00209 String host = u.getHost();
00210 if (host != null)
00211 h = host.hashCode();
00212
00213 String file = u.getFile();
00214 if (file != null)
00215 h += file.hashCode();
00216
00217 h += u.getPort();
00218 } else {
00219 h = u.hashCode();
00220 }
00221 return h;
00222 }
00223
00229 protected boolean sameFile(URL u1, URL u2) {
00230 String p1 = u1.getProtocol();
00231 if (PROTOCOL.equals(p1)) {
00232 if (!p1.equals(u2.getProtocol()))
00233 return false;
00234
00235 if (!hostsEqual(u1, u2))
00236 return false;
00237
00238 if (!(u1.getFile() == u2.getFile() ||
00239 (u1.getFile() != null && u1.getFile().equals(u2.getFile()))))
00240 return false;
00241
00242 if (u1.getPort() != u2.getPort())
00243 return false;
00244
00245 return true;
00246 } else {
00247 return u1.equals(u2);
00248 }
00249 }
00250
00251
00259 protected boolean hostsEqual(URL u1, URL u2) {
00260 String s1 = u1.getHost();
00261 String s2 = u2.getHost();
00262 return (s1 == s2) || (s1 != null && s1.equals(s2));
00263 }
00264
00265
00272 protected String toExternalForm(URL url) {
00273 StringBuffer res = new StringBuffer(url.getProtocol());
00274 res.append("://");
00275 res.append(url.getHost());
00276 int port = url.getPort();
00277 if (port >= 0) {
00278 res.append(":").append(port);
00279 }
00280 res.append(url.getPath());
00281 return res.toString();
00282 }
00283
00284
00285 protected synchronized InetAddress getHostAddress(URL url) {
00286 return null;
00287 }
00288
00289
00290
00291
00292
00293 private long getId(String host) {
00294 int i = host.indexOf(".");
00295 if (i == -1) {
00296 i = host.indexOf("_");
00297 }
00298 if (i >= 0) {
00299 host = host.substring(0, i);
00300 }
00301 return Long.parseLong(host);
00302 }
00303
00304 }