KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > osgi > framework > internal > core > BundleResourceHandler


1 /*******************************************************************************
2  * Copyright (c) 2004, 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11
12 package org.eclipse.osgi.framework.internal.core;
13
14 import java.io.IOException JavaDoc;
15 import java.net.*;
16 import org.eclipse.osgi.baseadaptor.bundlefile.BundleEntry;
17 import org.eclipse.osgi.baseadaptor.loader.BaseClassLoader;
18 import org.eclipse.osgi.internal.baseadaptor.AdaptorMsg;
19 import org.eclipse.osgi.util.NLS;
20 import org.osgi.framework.*;
21
22 /**
23  * URLStreamHandler the bundleentry and bundleresource protocols.
24  */

25
26 public abstract class BundleResourceHandler extends URLStreamHandler {
27     public static final String JavaDoc SECURITY_AUTHORIZED = "SECURITY_AUTHORIZED"; //$NON-NLS-1$
28
protected static BundleContext context;
29     protected BundleEntry bundleEntry;
30
31     /**
32      * Constructor for a bundle protocol resource URLStreamHandler.
33      */

34     public BundleResourceHandler() {
35         this(null);
36     }
37
38     public BundleResourceHandler(BundleEntry bundleEntry) {
39         this.bundleEntry = bundleEntry;
40     }
41
42     /**
43      * Parse reference URL.
44      */

45     protected void parseURL(URL url, String JavaDoc str, int start, int end) {
46         if (end < start)
47             return;
48         if (url.getPath() != null)
49             // A call to a URL constructor has been made that uses an authorized URL as its context.
50
// Null out bundleEntry because it will not be valid for the new path
51
bundleEntry = null;
52         String JavaDoc spec = ""; //$NON-NLS-1$
53
if (start < end)
54             spec = str.substring(start, end);
55         end -= start;
56         //Default is to use path and bundleId from context
57
String JavaDoc path = url.getPath();
58         String JavaDoc bundleId = url.getHost();
59         int resIndex = 0; // must start at 0 index if using a context
60
int pathIdx = 0;
61         if (spec.startsWith("//")) { //$NON-NLS-1$
62
int bundleIdIdx = 2;
63             pathIdx = spec.indexOf('/', bundleIdIdx);
64             if (pathIdx == -1) {
65                 pathIdx = end;
66                 // Use default
67
path = ""; //$NON-NLS-1$
68
}
69             int bundleIdEnd = spec.indexOf(':', bundleIdIdx);
70             if (bundleIdEnd > pathIdx || bundleIdEnd == -1)
71                 bundleIdEnd = pathIdx;
72             if (bundleIdEnd < pathIdx - 1)
73                 try {
74                     resIndex = Integer.parseInt(spec.substring(bundleIdEnd + 1, pathIdx));
75                 } catch (NumberFormatException JavaDoc e) {
76                     // do nothing; results in resIndex == 0
77
}
78             bundleId = spec.substring(bundleIdIdx, bundleIdEnd);
79         }
80         if (pathIdx < end && spec.charAt(pathIdx) == '/')
81             path = spec.substring(pathIdx, end);
82         else if (end > pathIdx) {
83             if (path == null || path.equals("")) //$NON-NLS-1$
84
path = "/"; //$NON-NLS-1$
85
int last = path.lastIndexOf('/') + 1;
86             if (last == 0)
87                 path = spec.substring(pathIdx, end);
88             else
89                 path = path.substring(0, last) + spec.substring(pathIdx, end);
90         }
91         if (path == null)
92             path = ""; //$NON-NLS-1$
93
//modify path if there's any relative references
94
// see RFC2396 Section 5.2
95
// Note: For ".." references above the root the approach taken is removing them from the resolved path
96
if (path.endsWith("/.") || path.endsWith("/..")) //$NON-NLS-1$ //$NON-NLS-2$
97
path = path + '/';
98         int dotIndex;
99         while ((dotIndex = path.indexOf("/./")) >= 0) //$NON-NLS-1$
100
path = path.substring(0, dotIndex + 1) + path.substring(dotIndex + 3);
101         while ((dotIndex = path.indexOf("/../")) >= 0) { //$NON-NLS-1$
102
if (dotIndex != 0)
103                 path = path.substring(0, path.lastIndexOf('/', dotIndex - 1)) + path.substring(dotIndex + 3);
104             else
105                 path = path.substring(dotIndex + 3);
106         }
107         while ((dotIndex = path.indexOf("//")) >= 0) //$NON-NLS-1$
108
path = path.substring(0, dotIndex + 1) + path.substring(dotIndex + 2);
109
110         // Check the permission of the caller to see if they
111
// are allowed access to the resource.
112
checkAdminPermission(context.getBundle(Long.parseLong(bundleId)));
113
114         // Setting the authority portion of the URL to SECURITY_ATHORIZED
115
// ensures that this URL was created by using this parseURL
116
// method. The openConnection method will only open URLs
117
// that have the authority set to this.
118
setURL(url, url.getProtocol(), bundleId, resIndex, SECURITY_AUTHORIZED, null, path, null, url.getRef());
119     }
120
121     /**
122      * Establishes a connection to the resource specified by <code>URL</code>.
123      * Since different protocols may have unique ways of connecting, it must be
124      * overridden by the subclass.
125      *
126      * @return java.net.URLConnection
127      * @param url java.net.URL
128      *
129      * @exception IOException thrown if an IO error occurs during connection establishment
130      */

131     protected URLConnection openConnection(URL url) throws IOException JavaDoc {
132         if (bundleEntry != null) // if the bundleEntry is not null then return quick
133
return (new BundleURLConnection(url, bundleEntry));
134
135         String JavaDoc bidString = url.getHost();
136         if (bidString == null) {
137             throw new IOException JavaDoc(NLS.bind(AdaptorMsg.URL_NO_BUNDLE_ID, url.toExternalForm()));
138         }
139         AbstractBundle bundle = null;
140         long bundleID;
141         try {
142             bundleID = Long.parseLong(bidString);
143         } catch (NumberFormatException JavaDoc nfe) {
144             throw new MalformedURLException(NLS.bind(AdaptorMsg.URL_INVALID_BUNDLE_ID, bidString));
145         }
146         bundle = (AbstractBundle) context.getBundle(bundleID);
147         // check to make sure that this URL was created using the
148
// parseURL method. This ensures the security check was done
149
// at URL construction.
150
if (!url.getAuthority().equals(SECURITY_AUTHORIZED)) {
151             // No admin security check was made better check now.
152
checkAdminPermission(bundle);
153         }
154
155         if (bundle == null) {
156             throw new IOException JavaDoc(NLS.bind(AdaptorMsg.URL_NO_BUNDLE_FOUND, url.toExternalForm()));
157         }
158         return (new BundleURLConnection(url, findBundleEntry(url, bundle)));
159     }
160
161     /**
162      * Finds the bundle entry for this protocal. This is handled
163      * differently for Bundle.gerResource() and Bundle.getEntry()
164      * because getResource uses the bundle classloader and getEntry
165      * only used the base bundle file.
166      * @param url The URL to find the BundleEntry for.
167      * @return the bundle entry
168      */

169     abstract protected BundleEntry findBundleEntry(URL url, AbstractBundle bundle) throws IOException JavaDoc;
170
171     /**
172      * Converts a bundle URL to a String.
173      *
174      * @param url the URL.
175      * @return a string representation of the URL.
176      */

177     protected String JavaDoc toExternalForm(URL url) {
178         StringBuffer JavaDoc result = new StringBuffer JavaDoc(url.getProtocol());
179         result.append("://"); //$NON-NLS-1$
180

181         String JavaDoc bundleId = url.getHost();
182         if ((bundleId != null) && (bundleId.length() > 0))
183             result.append(bundleId);
184         int index = url.getPort();
185         if (index > 0)
186             result.append(':').append(index);
187
188         String JavaDoc path = url.getPath();
189         if (path != null) {
190             if ((path.length() > 0) && (path.charAt(0) != '/')) /* if name doesn't have a leading slash */
191             {
192                 result.append("/"); //$NON-NLS-1$
193
}
194
195             result.append(path);
196         }
197         String JavaDoc ref = url.getRef();
198         if (ref != null && ref.length() > 0)
199             result.append('#').append(ref);
200
201         return (result.toString());
202     }
203
204     public static void setContext(BundleContext context) {
205         BundleResourceHandler.context = context;
206     }
207
208     protected int hashCode(URL url) {
209         int hash = 0;
210         String JavaDoc protocol = url.getProtocol();
211         if (protocol != null)
212             hash += protocol.hashCode();
213
214         String JavaDoc host = url.getHost();
215         if (host != null)
216             hash += host.hashCode();
217
218         String JavaDoc path = url.getPath();
219         if (path != null)
220             hash += path.hashCode();
221         return hash;
222     }
223
224     protected boolean equals(URL url1, URL url2) {
225         return sameFile(url1, url2);
226     }
227
228     protected synchronized InetAddress getHostAddress(URL url) {
229         return null;
230     }
231
232     protected boolean hostsEqual(URL url1, URL url2) {
233         String JavaDoc host1 = url1.getHost();
234         String JavaDoc host2 = url2.getHost();
235         if (host1 != null && host2 != null)
236             return host1.equalsIgnoreCase(host2);
237         return (host1 == null && host2 == null);
238     }
239
240     protected boolean sameFile(URL url1, URL url2) {
241         String JavaDoc p1 = url1.getProtocol();
242         String JavaDoc p2 = url2.getProtocol();
243         if (!((p1 == p2) || (p1 != null && p1.equalsIgnoreCase(p2))))
244             return false;
245
246         if (!hostsEqual(url1, url2))
247             return false;
248
249         if (url1.getPort() != url2.getPort())
250             return false;
251
252         String JavaDoc a1 = url1.getAuthority();
253         String JavaDoc a2 = url2.getAuthority();
254         if (!((a1 == a2) || (a1 != null && a1.equals(a2))))
255             return false;
256
257         String JavaDoc path1 = url1.getPath();
258         String JavaDoc path2 = url2.getPath();
259         if (!((path1 == path2) || (path1 != null && path1.equals(path2))))
260             return false;
261
262         return true;
263     }
264
265     protected void checkAdminPermission(Bundle bundle) {
266         SecurityManager JavaDoc sm = System.getSecurityManager();
267
268         if (sm != null) {
269             sm.checkPermission(new AdminPermission(bundle, AdminPermission.RESOURCE));
270         }
271     }
272
273     protected static BaseClassLoader getBundleClassLoader(AbstractBundle bundle) {
274         BundleLoader loader = bundle.getBundleLoader();
275         if (loader == null)
276             return null;
277         return (BaseClassLoader) loader.createClassLoader();
278     }
279 }
280
Popular Tags