KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > net > protocol > njar > Handler


1 /*
2   * JBoss, Home of Professional Open Source
3   * Copyright 2005, JBoss Inc., and individual contributors as indicated
4   * by the @authors tag. See the copyright.txt in the distribution for a
5   * full listing of individual contributors.
6   *
7   * This is free software; you can redistribute it and/or modify it
8   * under the terms of the GNU Lesser General Public License as
9   * published by the Free Software Foundation; either version 2.1 of
10   * the License, or (at your option) any later version.
11   *
12   * This software is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15   * Lesser General Public License for more details.
16   *
17   * You should have received a copy of the GNU Lesser General Public
18   * License along with this software; if not, write to the Free
19   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21   */

22 package org.jboss.net.protocol.njar;
23
24 import java.net.URL JavaDoc;
25 import java.net.URLConnection JavaDoc;
26 import java.net.URLStreamHandler JavaDoc;
27
28 import java.io.File JavaDoc;
29 import java.io.FileOutputStream JavaDoc;
30 import java.io.IOException JavaDoc;
31 import java.io.InputStream JavaDoc;
32 import java.io.OutputStream JavaDoc;
33
34 import java.util.HashMap JavaDoc;
35 import java.util.Map JavaDoc;
36
37 import org.jboss.logging.Logger;
38
39 import org.jboss.util.stream.Streams;
40 import org.jboss.util.ThrowableHandler;
41
42 /**
43  * A protocol handler for the n(ested)jar protocol.
44  *
45  * <p>
46  * This is class allows you to use the njar: URL protocol. It is very
47  * similar to it's jar: cusin. The difference being that jars can be
48  * nested.
49  *
50  * <p>
51  * An example of how to use this class is:
52  * <pre>
53  *
54  * URL url = new URL("njar:njar:file:c:/test1.zip^/test2.zip^/hello.txt");
55  * url.openStream();
56  *
57  * </pre>
58  *
59  * <p>
60  * Please be aware that the njar protocol caches it's jar in temporary
61  * storage when connections are opened into them. So for the above
62  * example, 2 files would cached a temp files names similar to nested-xxxx.jar
63  *
64  * @todo Add accessors so that the cache can be flushed.
65  *
66  * @version <tt>$Revision: 1958 $</tt>
67  * @author <a HREF="mailto:cojonudo14@hotmail.com">Hiram Chirino</a>
68  */

69 public class Handler
70    extends URLStreamHandler JavaDoc
71 {
72    // URL protocol designations
73
public static final String JavaDoc PROTOCOL = "njar";
74    public static final String JavaDoc NJAR_SEPARATOR = "^/";
75    public static final String JavaDoc JAR_SEPARATOR = "!/";
76
77    private static final Logger log = Logger.getLogger(Handler.class);
78
79    protected Map JavaDoc savedJars = new HashMap JavaDoc();
80
81    public URLConnection JavaDoc openConnection(final URL JavaDoc url)
82       throws IOException JavaDoc
83    {
84       String JavaDoc file = url.getFile();
85       String JavaDoc embeddedURL = file;
86       String JavaDoc jarPath = "";
87
88       boolean trace = log.isTraceEnabled();
89       
90       int pos = file.lastIndexOf(NJAR_SEPARATOR);
91       if (pos >= 0)
92       {
93          embeddedURL = file.substring(0, pos);
94          if (file.length() > pos + NJAR_SEPARATOR.length())
95             jarPath = file.substring(pos + NJAR_SEPARATOR.length());
96       }
97
98       if (embeddedURL.startsWith(PROTOCOL))
99       {
100          if (trace) log.trace("Opening next nested jar: " + embeddedURL);
101          File JavaDoc tempJar = (File JavaDoc) savedJars.get(embeddedURL);
102          if (tempJar == null)
103          {
104             URLConnection JavaDoc embededDataConnection = new URL JavaDoc(embeddedURL).openConnection();
105             if (trace) log.trace("Content length: " + embededDataConnection.getContentLength());
106             
107             InputStream JavaDoc embededData = embededDataConnection.getInputStream();
108             tempJar = File.createTempFile("nested-", ".jar");
109             tempJar.deleteOnExit();
110             
111             if (trace) log.trace("temp file location : " + tempJar);
112             OutputStream JavaDoc output = new FileOutputStream JavaDoc(tempJar);
113             
114             try {
115                // copyb will buffer the streams for us
116
long bytes = Streams.copyb(embededData, output);
117                if (trace) log.trace("copied " + bytes + " bytes");
118             }
119             finally {
120                Streams.flush(output);
121                
122                // close an pass errors to throwable handler (we don't care about them)
123
Streams.close(embededData);
124                Streams.close(output);
125             }
126             
127             savedJars.put(embeddedURL, tempJar);
128          }
129
130          String JavaDoc t = tempJar.getCanonicalFile().toURL().toExternalForm();
131          if (trace) log.trace("file URL : " + t);
132          
133          t = "njar:" + t + NJAR_SEPARATOR + jarPath;
134          if (trace) log.trace("Opening saved jar: " + t);
135
136          URL JavaDoc u = new URL JavaDoc(t);
137          if (trace) log.trace("Using URL: " + u);
138          
139          return u.openConnection();
140       }
141       else
142       {
143          if (trace) log.trace("Opening final nested jar: " + embeddedURL);
144
145          URL JavaDoc u = new URL JavaDoc("jar:" + embeddedURL + JAR_SEPARATOR + jarPath);
146          if (trace) log.trace("Using URL: " + u);
147          
148          return u.openConnection();
149       }
150    }
151
152    public static URL JavaDoc njarToFile(URL JavaDoc url)
153    {
154       if (url.getProtocol().equals(PROTOCOL))
155       {
156          try
157          {
158             // force the resource we are after to be unpacked - thanks
159
// Jan & David...!
160
URL JavaDoc dummy=new URL JavaDoc(PROTOCOL+":"+url.toString()+NJAR_SEPARATOR+"dummy.jar");
161             String JavaDoc tmp=dummy.openConnection().getURL().toString();
162             tmp=tmp.substring("jar:".length());
163             tmp=tmp.substring(0, tmp.length()-(JAR_SEPARATOR+"dummy.jar").length());
164             return new URL JavaDoc(tmp);
165          }
166          catch (Exception JavaDoc ignore)
167          {
168             ThrowableHandler.addWarning(ignore);
169          }
170       }
171
172       return url;
173    }
174 }
175
176
Popular Tags