KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > javahelp > NbDocsStreamHandler


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

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 /** Handler & connection cribbed from NbResourceStreamHandler.
33  * @author Jesse Glick
34  */

35 final class NbDocsStreamHandler extends URLStreamHandler {
36
37     public static final class Factory implements URLStreamHandlerFactory {
38         public URLStreamHandler createURLStreamHandler(String JavaDoc protocol) {
39             if (protocol.equals("nbdocs")) { // NOI18N
40
return new NbDocsStreamHandler();
41             } else {
42                 return null;
43             }
44         }
45     }
46     
47     /** Make a URLConnection for nbdocs: URLs.
48      * @param u the URL
49      * @throws IOException if the wrong protocol
50      * @return the connection
51      */

52     protected URLConnection openConnection(URL u) throws IOException {
53         if (u.getProtocol().equals("nbdocs")) { // NOI18N
54
return new NbDocsURLConnection(u);
55         } else {
56             throw new IOException("mismatched protocol"); // NOI18N
57
}
58     }
59     
60     /** A URL connection that reads from the docs classloader.
61      */

62     private static final class NbDocsURLConnection extends URLConnection {
63         
64         /** underlying URL connection
65          */

66         private URLConnection real = null;
67         
68         /** any associated exception while handling
69          */

70         private IOException exception = null;
71         
72         /** Make the connection.
73          * @param u URL to connect to
74          */

75         public NbDocsURLConnection(URL u) {
76             super(u);
77         }
78         
79         /** Connect to the URL.
80          * Actually look up and open the underlying connection.
81          * @throws IOException for the usual reasons
82          */

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 JavaDoc 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"); // NOI18N
96
String JavaDoc 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"); // NOI18N
104
String JavaDoc moduleName = ""; // NOI18N
105
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 JavaDoc resource = url.getFile();
117                 if (resource.startsWith("/")) resource = resource.substring(1); //NOI18N
118
URL target;
119                 String JavaDoc 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                     // OK, try file.
132
File f = InstalledFileLocator.getDefault().locate("docs/" + resource, null, true); // NOI18N
133
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                 //System.err.println("loading from " + target);
146
real = target.openConnection();
147                 real.connect();
148                 connected = true;
149             }
150         }
151         
152         /** Searches for module with given code name.
153          * @param codeNameBase unique string base name of the module
154          * (without release number)
155          *
156          * @return module info of found module or null if module is not found
157          * (not installed).
158          * @deprecated will be replaced by similar method in Modules Open APIs in
159          * future releases
160          */

161         private static ModuleInfo findModule (String JavaDoc 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         /** Maybe connect, if not keep track of the problem.
173          */

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         /** Get a URL header.
184          * @param n index of the header
185          * @return the header value
186          */

187         public String JavaDoc getHeaderField(int n) {
188             tryToConnect();
189             if (connected)
190                 return real.getHeaderField(n);
191             else
192                 return null;
193         }
194         
195         /** Get the name of a header.
196          * @param n the index
197          * @return the header name
198          */

199         public String JavaDoc getHeaderFieldKey(int n) {
200             tryToConnect();
201             if (connected)
202                 return real.getHeaderFieldKey(n);
203             else
204                 return null;
205         }
206         
207         /** Get a header by name.
208          * @param key the header name
209          * @return the value
210          */

211         public String JavaDoc getHeaderField(String JavaDoc key) {
212             tryToConnect();
213             if (connected)
214                 return real.getHeaderField(key);
215             else
216                 return null;
217         }
218         
219         /** Get an input stream on the connection.
220          * @throws IOException for the usual reasons
221          * @return a stream to the object
222          */

223         public InputStream getInputStream() throws IOException {
224             connect();
225             return real.getInputStream();
226         }
227         
228         /** Get an output stream on the object.
229          * @throws IOException for the usual reasons
230          * @return an output stream writing to it
231          */

232         public OutputStream getOutputStream() throws IOException {
233             connect();
234             return real.getOutputStream();
235         }
236         
237         /** Get the type of the content.
238          * @return the MIME type
239          */

240         public String JavaDoc getContentType() {
241             tryToConnect();
242             if (connected)
243                 return real.getContentType();
244             else
245                 return "application/octet-stream"; // NOI18N
246
}
247         
248         /** Get the length of content.
249          * @return the length in bytes
250          */

251         public int getContentLength() {
252             tryToConnect();
253             if (connected)
254                 return real.getContentLength();
255             else
256                 return 0;
257         }
258         
259     }
260     
261     /** A URL connection that reads from the info files. It displays
262      * help page when referred module is not enabled or installed.
263      * It also takes module display name from bundle when available.
264      * Module base name is key to retrieve module display name
265      * eg.: org.netbeans.modules.web.monitor=HTTP Monitor
266      */

267     private static final class InfoURLConnection extends URLConnection {
268         /** Provides input stream for this connection. */
269         private ByteArrayInputStream stream;
270         /** Module display name */
271         private String JavaDoc moduleName;
272         
273         /** Make the connection.
274          * @param u URL to connect to
275          */

276         public InfoURLConnection (URL u, String JavaDoc moduleName) {
277             super(u);
278             this.moduleName = moduleName;
279         }
280         
281         /** Connect to the URL.
282          * Actually look up and open the underlying connection.
283          * @throws IOException for the usual reasons
284          */

285         public synchronized void connect() throws IOException {
286             if (!connected) {
287                 //Prepare data
288
InputStream is = url.openStream();
289                 if (is != null) {
290                     byte [] arr;
291                     arr = readData(is);
292                     String JavaDoc s1 = new String JavaDoc(arr,"UTF-8"); // NOI18N
293
String JavaDoc s2 = s1.replaceAll("\\{0\\}",moduleName); // NOI18N
294
arr = s2.getBytes("UTF-8");
295                     stream = new ByteArrayInputStream(arr);
296                 } else {
297                     throw new IOException("Info file not found."); // NOI18N
298
}
299                 connected = true;
300             }
301         }
302         
303         /** Reads all available data from input steram to byte array. It is workaround
304          * to avoid usage of InputStream.available which might be unreliable on URL. */

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         /** Maybe connect, if not keep track of the problem.
332          */

333         private void tryToConnect() {
334             if (connected) {
335                 return;
336             }
337             try {
338                 connect();
339             } catch (IOException ioe) {
340             }
341         }
342         
343         /** Get an input stream on the connection.
344          * @throws IOException for the usual reasons
345          * @return a stream to the object
346          */

347         public InputStream getInputStream() throws IOException {
348             connect();
349             return stream;
350         }
351         
352         
353         /** Get the type of the content.
354          * @return the MIME type
355          */

356         public String JavaDoc getContentType() {
357             return "text/html"; // NOI18N
358
}
359         
360         /** Get the length of content.
361          * @return the length in bytes
362          */

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