Mercurial Hosting > luan
comparison src/org/eclipse/jetty/util/resource/JarResource.java @ 802:3428c60d7cfc
replace jetty jars with source
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Wed, 07 Sep 2016 21:15:48 -0600 |
parents | |
children | 8e9db0bbf4f9 |
comparison
equal
deleted
inserted
replaced
801:6a21393191c1 | 802:3428c60d7cfc |
---|---|
1 // | |
2 // ======================================================================== | |
3 // Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. | |
4 // ------------------------------------------------------------------------ | |
5 // All rights reserved. This program and the accompanying materials | |
6 // are made available under the terms of the Eclipse Public License v1.0 | |
7 // and Apache License v2.0 which accompanies this distribution. | |
8 // | |
9 // The Eclipse Public License is available at | |
10 // http://www.eclipse.org/legal/epl-v10.html | |
11 // | |
12 // The Apache License v2.0 is available at | |
13 // http://www.opensource.org/licenses/apache2.0.php | |
14 // | |
15 // You may elect to redistribute this code under either of these licenses. | |
16 // ======================================================================== | |
17 // | |
18 | |
19 package org.eclipse.jetty.util.resource; | |
20 | |
21 import java.io.File; | |
22 import java.io.FileOutputStream; | |
23 import java.io.FilterInputStream; | |
24 import java.io.IOException; | |
25 import java.io.InputStream; | |
26 import java.net.JarURLConnection; | |
27 import java.net.URL; | |
28 import java.util.jar.JarEntry; | |
29 import java.util.jar.JarInputStream; | |
30 import java.util.jar.Manifest; | |
31 | |
32 import org.eclipse.jetty.util.IO; | |
33 import org.eclipse.jetty.util.URIUtil; | |
34 import org.eclipse.jetty.util.log.Log; | |
35 import org.eclipse.jetty.util.log.Logger; | |
36 | |
37 | |
38 /* ------------------------------------------------------------ */ | |
39 public class JarResource extends URLResource | |
40 { | |
41 private static final Logger LOG = Log.getLogger(JarResource.class); | |
42 protected JarURLConnection _jarConnection; | |
43 | |
44 /* -------------------------------------------------------- */ | |
45 JarResource(URL url) | |
46 { | |
47 super(url,null); | |
48 } | |
49 | |
50 /* ------------------------------------------------------------ */ | |
51 JarResource(URL url, boolean useCaches) | |
52 { | |
53 super(url, null, useCaches); | |
54 } | |
55 | |
56 /* ------------------------------------------------------------ */ | |
57 @Override | |
58 public synchronized void release() | |
59 { | |
60 _jarConnection=null; | |
61 super.release(); | |
62 } | |
63 | |
64 /* ------------------------------------------------------------ */ | |
65 @Override | |
66 protected synchronized boolean checkConnection() | |
67 { | |
68 super.checkConnection(); | |
69 try | |
70 { | |
71 if (_jarConnection!=_connection) | |
72 newConnection(); | |
73 } | |
74 catch(IOException e) | |
75 { | |
76 LOG.ignore(e); | |
77 _jarConnection=null; | |
78 } | |
79 | |
80 return _jarConnection!=null; | |
81 } | |
82 | |
83 /* ------------------------------------------------------------ */ | |
84 /** | |
85 * @throws IOException Sub-classes of <code>JarResource</code> may throw an IOException (or subclass) | |
86 */ | |
87 protected void newConnection() throws IOException | |
88 { | |
89 _jarConnection=(JarURLConnection)_connection; | |
90 } | |
91 | |
92 /* ------------------------------------------------------------ */ | |
93 /** | |
94 * Returns true if the respresenetd resource exists. | |
95 */ | |
96 @Override | |
97 public boolean exists() | |
98 { | |
99 if (_urlString.endsWith("!/")) | |
100 return checkConnection(); | |
101 else | |
102 return super.exists(); | |
103 } | |
104 | |
105 /* ------------------------------------------------------------ */ | |
106 @Override | |
107 public File getFile() | |
108 throws IOException | |
109 { | |
110 return null; | |
111 } | |
112 | |
113 /* ------------------------------------------------------------ */ | |
114 @Override | |
115 public InputStream getInputStream() | |
116 throws java.io.IOException | |
117 { | |
118 checkConnection(); | |
119 if (!_urlString.endsWith("!/")) | |
120 return new FilterInputStream(super.getInputStream()) | |
121 { | |
122 @Override | |
123 public void close() throws IOException {this.in=IO.getClosedStream();} | |
124 }; | |
125 | |
126 URL url = new URL(_urlString.substring(4,_urlString.length()-2)); | |
127 InputStream is = url.openStream(); | |
128 return is; | |
129 } | |
130 | |
131 /* ------------------------------------------------------------ */ | |
132 @Override | |
133 public void copyTo(File directory) | |
134 throws IOException | |
135 { | |
136 if (!exists()) | |
137 return; | |
138 | |
139 if(LOG.isDebugEnabled()) | |
140 LOG.debug("Extract "+this+" to "+directory); | |
141 | |
142 String urlString = this.getURL().toExternalForm().trim(); | |
143 int endOfJarUrl = urlString.indexOf("!/"); | |
144 int startOfJarUrl = (endOfJarUrl >= 0?4:0); | |
145 | |
146 if (endOfJarUrl < 0) | |
147 throw new IOException("Not a valid jar url: "+urlString); | |
148 | |
149 URL jarFileURL = new URL(urlString.substring(startOfJarUrl, endOfJarUrl)); | |
150 String subEntryName = (endOfJarUrl+2 < urlString.length() ? urlString.substring(endOfJarUrl + 2) : null); | |
151 boolean subEntryIsDir = (subEntryName != null && subEntryName.endsWith("/")?true:false); | |
152 | |
153 if (LOG.isDebugEnabled()) | |
154 LOG.debug("Extracting entry = "+subEntryName+" from jar "+jarFileURL); | |
155 | |
156 InputStream is = jarFileURL.openConnection().getInputStream(); | |
157 JarInputStream jin = new JarInputStream(is); | |
158 JarEntry entry; | |
159 boolean shouldExtract; | |
160 while((entry=jin.getNextJarEntry())!=null) | |
161 { | |
162 String entryName = entry.getName(); | |
163 if ((subEntryName != null) && (entryName.startsWith(subEntryName))) | |
164 { | |
165 // is the subentry really a dir? | |
166 if (!subEntryIsDir && subEntryName.length()+1==entryName.length() && entryName.endsWith("/")) | |
167 subEntryIsDir=true; | |
168 | |
169 //if there is a particular subEntry that we are looking for, only | |
170 //extract it. | |
171 if (subEntryIsDir) | |
172 { | |
173 //if it is a subdirectory we are looking for, then we | |
174 //are looking to extract its contents into the target | |
175 //directory. Remove the name of the subdirectory so | |
176 //that we don't wind up creating it too. | |
177 entryName = entryName.substring(subEntryName.length()); | |
178 if (!entryName.equals("")) | |
179 { | |
180 //the entry is | |
181 shouldExtract = true; | |
182 } | |
183 else | |
184 shouldExtract = false; | |
185 } | |
186 else | |
187 shouldExtract = true; | |
188 } | |
189 else if ((subEntryName != null) && (!entryName.startsWith(subEntryName))) | |
190 { | |
191 //there is a particular entry we are looking for, and this one | |
192 //isn't it | |
193 shouldExtract = false; | |
194 } | |
195 else | |
196 { | |
197 //we are extracting everything | |
198 shouldExtract = true; | |
199 } | |
200 | |
201 | |
202 if (!shouldExtract) | |
203 { | |
204 if (LOG.isDebugEnabled()) | |
205 LOG.debug("Skipping entry: "+entryName); | |
206 continue; | |
207 } | |
208 | |
209 String dotCheck = entryName.replace('\\', '/'); | |
210 dotCheck = URIUtil.canonicalPath(dotCheck); | |
211 if (dotCheck == null) | |
212 { | |
213 if (LOG.isDebugEnabled()) | |
214 LOG.debug("Invalid entry: "+entryName); | |
215 continue; | |
216 } | |
217 | |
218 File file=new File(directory,entryName); | |
219 | |
220 if (entry.isDirectory()) | |
221 { | |
222 // Make directory | |
223 if (!file.exists()) | |
224 file.mkdirs(); | |
225 } | |
226 else | |
227 { | |
228 // make directory (some jars don't list dirs) | |
229 File dir = new File(file.getParent()); | |
230 if (!dir.exists()) | |
231 dir.mkdirs(); | |
232 | |
233 // Make file | |
234 FileOutputStream fout = null; | |
235 try | |
236 { | |
237 fout = new FileOutputStream(file); | |
238 IO.copy(jin,fout); | |
239 } | |
240 finally | |
241 { | |
242 IO.close(fout); | |
243 } | |
244 | |
245 // touch the file. | |
246 if (entry.getTime()>=0) | |
247 file.setLastModified(entry.getTime()); | |
248 } | |
249 } | |
250 | |
251 if ((subEntryName == null) || (subEntryName != null && subEntryName.equalsIgnoreCase("META-INF/MANIFEST.MF"))) | |
252 { | |
253 Manifest manifest = jin.getManifest(); | |
254 if (manifest != null) | |
255 { | |
256 File metaInf = new File (directory, "META-INF"); | |
257 metaInf.mkdir(); | |
258 File f = new File(metaInf, "MANIFEST.MF"); | |
259 FileOutputStream fout = new FileOutputStream(f); | |
260 manifest.write(fout); | |
261 fout.close(); | |
262 } | |
263 } | |
264 IO.close(jin); | |
265 } | |
266 | |
267 public static Resource newJarResource(Resource resource) throws IOException | |
268 { | |
269 if (resource instanceof JarResource) | |
270 return resource; | |
271 return Resource.newResource("jar:" + resource + "!/"); | |
272 } | |
273 } |