1 19 20 package org.netbeans.core.startup; 21 22 import java.io.IOException ; 23 import java.io.InputStream ; 24 import java.io.OutputStream ; 25 import java.lang.reflect.Field ; 26 import java.net.URL ; 27 import java.net.URLConnection ; 28 import java.net.URLStreamHandler ; 29 import java.net.URLStreamHandlerFactory ; 30 import java.util.Collection ; 31 import java.util.Iterator ; 32 import java.util.logging.Level ; 33 import java.util.logging.Logger ; 34 import org.openide.filesystems.FileUtil; 35 import org.openide.util.Lookup; 36 import org.openide.util.LookupEvent; 37 import org.openide.util.LookupListener; 38 import org.openide.util.NbBundle; 39 40 46 final class NbURLStreamHandlerFactory implements URLStreamHandlerFactory , LookupListener { 47 private static Logger LOG = Logger.getLogger(NbURLStreamHandlerFactory.class.getName()); 48 49 private Lookup.Result<URLStreamHandlerFactory > r = null; 50 private URLStreamHandlerFactory [] handlers = null; 51 private URLStreamHandlerFactory delegate; 52 53 public NbURLStreamHandlerFactory() {} 54 55 public URLStreamHandler createURLStreamHandler(String protocol) { 56 if (protocol.equals("jar") || protocol.equals("file") || protocol.equals("http") || protocol.equals("resource")) { return null; 60 } 61 62 if (protocol.equals("nbfs")) { return FileUtil.nbfsURLStreamHandler(); 64 } 65 66 if (protocol.equals(NbResourceStreamHandler.PROTOCOL_SYSTEM_RESOURCE) || 67 protocol.equals(NbResourceStreamHandler.PROTOCOL_LOCALIZED_SYSTEM_RESOURCE)) { 68 return new NbResourceStreamHandler(); 69 } 70 71 URLStreamHandlerFactory d = delegate; 72 if (d != null) { 73 URLStreamHandler h = d.createURLStreamHandler(protocol); 74 if (h != null) { 75 return h; 76 } 77 } 78 79 URLStreamHandlerFactory [] _handlers; 80 synchronized (this) { 81 if (r == null) { 82 r = Lookup.getDefault().lookupResult(URLStreamHandlerFactory .class); 83 r.addLookupListener(this); 84 resultChanged(null); 85 } 86 _handlers = handlers; 87 } 88 if (_handlers == null) { 89 return null; 91 } 92 for (int i = 0; i < _handlers.length; i++) { 93 URLStreamHandler h = _handlers[i].createURLStreamHandler(protocol); 94 if (h != null) { 95 return h; 96 } 97 } 98 return null; 99 } 100 101 public void resultChanged(LookupEvent ev) { 102 Collection <? extends URLStreamHandlerFactory > c = r.allInstances(); 103 synchronized (this) { 104 handlers = c.toArray(new URLStreamHandlerFactory [0]); 105 } 106 } 107 108 void registerUsingReflection(Error e) { 109 LOG.log(Level.CONFIG, "Problems registering URLStreamHandlerFactory, trying reflection", e); try { 111 URLStreamHandlerFactory prev = null; 112 for (Field f : URL .class.getDeclaredFields()) { 113 LOG.log(Level.FINEST, "Found field {0}", f); 114 if (f.getType() == URLStreamHandlerFactory .class) { 115 LOG.log(Level.FINEST, "Clearing field {0}"); 116 f.setAccessible(true); 117 prev = (URLStreamHandlerFactory )f.get(null); 118 LOG.log(Level.CONFIG, "Previous value was {0}", prev); 119 f.set(null, null); 120 LOG.config("Field is supposed to be empty"); 121 break; 122 } 123 } 124 URL.setURLStreamHandlerFactory(this); 125 delegate = prev; 126 } catch (Throwable t) { 127 LOG.log(Level.SEVERE, 128 "No way to register URLStreamHandlerFactory; NetBeans is unlikely to work", 129 t 130 ); } 132 } 133 134 139 private static final class NbResourceStreamHandler extends URLStreamHandler { 140 141 public NbResourceStreamHandler() {} 142 143 public static final String PROTOCOL_SYSTEM_RESOURCE = "nbres"; public static final String PROTOCOL_LOCALIZED_SYSTEM_RESOURCE = "nbresloc"; 146 public URLConnection openConnection(URL u) throws IOException { 147 if (u.getProtocol().equals(PROTOCOL_SYSTEM_RESOURCE)) { 148 return new Connection (u, false); 149 } else if (u.getProtocol().equals(PROTOCOL_LOCALIZED_SYSTEM_RESOURCE)) { 150 return new Connection (u, true); 151 } else { 152 throw new IOException ("Bad protocol: " + u.getProtocol()); } 154 } 155 156 private static class Connection extends URLConnection { 157 158 private final boolean localized; 159 160 private URLConnection real; 162 163 private IOException exception = null; 164 165 public Connection(URL u, boolean localized) { 166 super(u); 167 this.localized = localized; 168 } 169 170 175 public synchronized void connect() throws IOException { 176 if (exception != null) { 177 IOException e = exception; 179 exception = null; 180 throw e; 181 } 182 if (! connected) { 183 String resource = url.getPath(); 184 if (resource.length() > 0 && resource.charAt(0) == '/') resource = resource.substring(1); ClassLoader loader = Lookup.getDefault().lookup(ClassLoader .class); 186 URL target; 187 URL t1 = loader.getResource(resource); 188 if (localized) { 189 int dotIndex = resource.lastIndexOf('.'); 192 if (dotIndex < resource.lastIndexOf('/')) { 193 dotIndex = -1; 194 } 195 String base, ext; 196 if (dotIndex != -1) { 197 base = resource.substring(0, dotIndex); 198 ext = resource.substring(dotIndex); 199 } else { 200 base = resource; 201 ext = ""; 202 } 203 target = null; 204 Iterator <String > suffixes = NbBundle.getLocalizingSuffixes(); 205 while (suffixes.hasNext()) { 206 String suffix = suffixes.next(); 207 target = "".equals(suffix)? t1: loader.getResource(base + suffix + ext); 208 if (target != null) { 209 break; 210 } 211 } 212 } else { 213 target = t1; 214 } 215 if (target == null) { 216 throw new IOException (NbBundle.getMessage(NbURLStreamHandlerFactory.class, "EXC_nbres_cannot_connect", url)); 217 } 218 real = target.openConnection(); 219 real.connect(); 220 connected = true; 221 } 222 } 223 224 237 private void tryToConnect() { 238 if (connected || exception != null) return; 239 try { 240 connect(); 241 } catch (IOException ioe) { 242 exception = ioe; 243 } 244 } 245 246 public String getHeaderField(int n) { 247 tryToConnect(); 248 if (connected) 249 return real.getHeaderField(n); 250 else 251 return null; 252 } 253 254 public String getHeaderFieldKey(int n) { 255 tryToConnect(); 256 if (connected) 257 return real.getHeaderFieldKey(n); 258 else 259 return null; 260 } 261 262 public String getHeaderField(String key) { 263 tryToConnect(); 264 if (connected) { 265 return real.getHeaderField(key); 266 } 267 return null; 268 } 269 270 public InputStream getInputStream() throws IOException { 271 connect(); 272 return real.getInputStream(); 273 } 274 275 public OutputStream getOutputStream() throws IOException { 276 connect(); 277 return real.getOutputStream(); 278 } 279 280 282 public String getContentType() { 283 tryToConnect(); 284 if (connected) 285 return real.getContentType(); 286 else 287 return "application/octet-stream"; } 289 290 public int getContentLength() { 291 tryToConnect(); 292 if (connected) 293 return real.getContentLength(); 294 else 295 return 0; 296 } 297 298 300 } 301 302 } 303 304 } 305 | Popular Tags |