1 19 20 package org.netbeans.modules.javahelp; 21 22 import java.io.*; 23 import java.net.*; 24 import java.util.*; 25 26 import org.openide.modules.InstalledFileLocator; 27 import org.openide.modules.ModuleInfo; 28 import org.openide.util.Exceptions; 29 import org.openide.util.Lookup; 30 import org.openide.util.NbBundle; 31 32 35 final class NbDocsStreamHandler extends URLStreamHandler { 36 37 public static final class Factory implements URLStreamHandlerFactory { 38 public URLStreamHandler createURLStreamHandler(String protocol) { 39 if (protocol.equals("nbdocs")) { return new NbDocsStreamHandler(); 41 } else { 42 return null; 43 } 44 } 45 } 46 47 52 protected URLConnection openConnection(URL u) throws IOException { 53 if (u.getProtocol().equals("nbdocs")) { return new NbDocsURLConnection(u); 55 } else { 56 throw new IOException("mismatched protocol"); } 58 } 59 60 62 private static final class NbDocsURLConnection extends URLConnection { 63 64 66 private URLConnection real = null; 67 68 70 private IOException exception = null; 71 72 75 public NbDocsURLConnection(URL u) { 76 super(u); 77 } 78 79 83 public synchronized void connect() throws IOException { 84 if (exception != null) { 85 IOException e = exception; 86 exception = null; 87 throw e; 88 } 89 if (! connected) { 90 String host = url.getHost(); 91 if (host.length() > 0) { 92 ModuleInfo moduleInfo = findModule(host); 93 if (moduleInfo != null) { 94 if (!moduleInfo.isEnabled()) { 95 URL info = new URL("nbdocs:/org/netbeans/modules/javahelp/resources/notEnabledModule.html"); String moduleName = moduleInfo.getDisplayName(); 97 real = new InfoURLConnection(info,moduleName); 98 real.connect(); 99 connected = true; 100 return; 101 } 102 } else { 103 URL info = new URL("nbdocs:/org/netbeans/modules/javahelp/resources/notInstalledModule.html"); String moduleName = ""; try { 106 moduleName = NbBundle.getMessage(NbDocsStreamHandler.class,host); 107 } catch (MissingResourceException exc) { 108 moduleName = host; 109 } 110 real = new InfoURLConnection(info,moduleName); 111 real.connect(); 112 connected = true; 113 return; 114 } 115 } 116 String resource = url.getFile(); 117 if (resource.startsWith("/")) resource = resource.substring(1); URL target; 119 String ext, basename; 120 int index = resource.lastIndexOf('.'); 121 if (index != -1 && index > resource.lastIndexOf('/')) { 122 ext = resource.substring(index + 1); 123 basename = resource.substring(0, index).replace('/', '.'); 124 } else { 125 ext = null; 126 basename = resource.replace('/', '.'); 127 } 128 try { 129 target = NbBundle.getLocalizedFile(basename, ext); 130 } catch (MissingResourceException mre) { 131 File f = InstalledFileLocator.getDefault().locate("docs/" + resource, null, true); if (f != null) { 134 target = f.toURI().toURL(); 135 } else { 136 IOException ioe = new IOException("cannot connect to " + url + ": " + mre); 137 ioe.initCause(mre); 138 Exceptions.attachLocalizedMessage(ioe, 139 NbBundle.getMessage(NbDocsStreamHandler.class, 140 "EXC_nbdocs_cannot_connect", 141 url)); 142 throw ioe; 143 } 144 } 145 real = target.openConnection(); 147 real.connect(); 148 connected = true; 149 } 150 } 151 152 161 private static ModuleInfo findModule (String codeNameBase) { 162 Lookup.Result<ModuleInfo> modulesResult = 163 Lookup.getDefault().lookup(new Lookup.Template<ModuleInfo>(ModuleInfo.class)); 164 for (ModuleInfo curInfo: modulesResult.allInstances()) { 165 if (curInfo.getCodeNameBase().equals(codeNameBase)) { 166 return curInfo; 167 } 168 } 169 return null; 170 } 171 172 174 private void tryToConnect() { 175 if (connected || exception != null) return; 176 try { 177 connect(); 178 } catch (IOException ioe) { 179 exception = ioe; 180 } 181 } 182 183 187 public String getHeaderField(int n) { 188 tryToConnect(); 189 if (connected) 190 return real.getHeaderField(n); 191 else 192 return null; 193 } 194 195 199 public String getHeaderFieldKey(int n) { 200 tryToConnect(); 201 if (connected) 202 return real.getHeaderFieldKey(n); 203 else 204 return null; 205 } 206 207 211 public String getHeaderField(String key) { 212 tryToConnect(); 213 if (connected) 214 return real.getHeaderField(key); 215 else 216 return null; 217 } 218 219 223 public InputStream getInputStream() throws IOException { 224 connect(); 225 return real.getInputStream(); 226 } 227 228 232 public OutputStream getOutputStream() throws IOException { 233 connect(); 234 return real.getOutputStream(); 235 } 236 237 240 public String getContentType() { 241 tryToConnect(); 242 if (connected) 243 return real.getContentType(); 244 else 245 return "application/octet-stream"; } 247 248 251 public int getContentLength() { 252 tryToConnect(); 253 if (connected) 254 return real.getContentLength(); 255 else 256 return 0; 257 } 258 259 } 260 261 267 private static final class InfoURLConnection extends URLConnection { 268 269 private ByteArrayInputStream stream; 270 271 private String moduleName; 272 273 276 public InfoURLConnection (URL u, String moduleName) { 277 super(u); 278 this.moduleName = moduleName; 279 } 280 281 285 public synchronized void connect() throws IOException { 286 if (!connected) { 287 InputStream is = url.openStream(); 289 if (is != null) { 290 byte [] arr; 291 arr = readData(is); 292 String s1 = new String (arr,"UTF-8"); String s2 = s1.replaceAll("\\{0\\}",moduleName); arr = s2.getBytes("UTF-8"); 295 stream = new ByteArrayInputStream(arr); 296 } else { 297 throw new IOException("Info file not found."); } 299 connected = true; 300 } 301 } 302 303 305 private byte [] readData (InputStream is) throws IOException { 306 int step = 4096; 307 byte[] buff = new byte[step]; 308 byte[] sum = new byte[0]; 309 byte[] result; 310 int len = -1, readLen = 0, allocLen = 0; 311 312 for (;;) { 313 len = is.read(buff); 314 if (len == -1) { 315 result = new byte[readLen]; 316 System.arraycopy(sum,0,result,0,readLen); 317 return result; 318 } 319 if (allocLen < (readLen + len)) { 320 byte [] tmp = new byte[sum.length]; 321 System.arraycopy(sum,0,tmp,0,readLen); 322 sum = new byte[allocLen + step]; 323 allocLen = allocLen + step; 324 System.arraycopy(tmp,0,sum,0,readLen); 325 } 326 System.arraycopy(buff,0,sum,readLen,len); 327 readLen = readLen + len; 328 } 329 } 330 331 333 private void tryToConnect() { 334 if (connected) { 335 return; 336 } 337 try { 338 connect(); 339 } catch (IOException ioe) { 340 } 341 } 342 343 347 public InputStream getInputStream() throws IOException { 348 connect(); 349 return stream; 350 } 351 352 353 356 public String getContentType() { 357 return "text/html"; } 359 360 363 public int getContentLength() { 364 tryToConnect(); 365 if (connected) { 366 return stream.available(); 367 } else { 368 return 0; 369 } 370 } 371 } 372 } 373 | Popular Tags |