1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.maven.plugin;
20
21 import java.io.File;
22 import java.io.FileOutputStream;
23 import java.io.IOException;
24 import java.io.InputStream;
25 import java.net.URL;
26 import java.util.Arrays;
27 import java.util.Collections;
28 import java.util.List;
29 import java.util.jar.JarEntry;
30 import java.util.jar.JarInputStream;
31 import java.util.jar.Manifest;
32
33 import org.codehaus.plexus.util.SelectorUtils;
34 import org.eclipse.jetty.util.IO;
35 import org.eclipse.jetty.util.URIUtil;
36 import org.eclipse.jetty.util.log.Log;
37 import org.eclipse.jetty.util.log.Logger;
38 import org.eclipse.jetty.util.resource.JarResource;
39
40
41
42
43
44
45
46
47
48 public class SelectiveJarResource extends JarResource
49 {
50 private static final Logger LOG = Log.getLogger(SelectiveJarResource.class);
51 public static final List<String> DEFAULT_INCLUDES = Arrays.asList(new String[]{"**"});
52 public static final List<String> DEFAULT_EXCLUDES = Collections.emptyList();
53
54
55 List<String> _includes = null;
56 List<String> _excludes = null;
57 boolean _caseSensitive = false;
58
59
60
61
62
63 public SelectiveJarResource(URL url)
64 {
65 super(url);
66 }
67
68
69
70
71
72 public SelectiveJarResource(URL url, boolean useCaches)
73 {
74 super(url, useCaches);
75 }
76
77
78 public void setCaseSensitive (boolean caseSensitive)
79 {
80 _caseSensitive = caseSensitive;
81 }
82
83 public void setIncludes (List<String> patterns)
84 {
85 _includes = patterns;
86 }
87
88
89 public void setExcludes (List<String> patterns)
90 {
91 _excludes = patterns;
92 }
93
94
95 protected boolean isIncluded (String name)
96 {
97 for (String include:_includes)
98 {
99 if (SelectorUtils.matchPath(include, name, _caseSensitive))
100 {
101 return true;
102 }
103 }
104 return false;
105 }
106
107 protected boolean isExcluded (String name)
108 {
109 for (String exclude:_excludes)
110 {
111 if (SelectorUtils.matchPath (exclude, name, _caseSensitive))
112 {
113 return true;
114 }
115 }
116 return false;
117 }
118
119
120
121
122
123
124
125 @Override
126 public void copyTo(File directory) throws IOException
127 {
128 if (_includes == null)
129 _includes = DEFAULT_INCLUDES;
130 if (_excludes == null)
131 _excludes = DEFAULT_EXCLUDES;
132
133
134
135
136 if (!exists())
137 return;
138
139 String urlString = this.getURL().toExternalForm().trim();
140 int endOfJarUrl = urlString.indexOf("!/");
141 int startOfJarUrl = (endOfJarUrl >= 0?4:0);
142
143 if (endOfJarUrl < 0)
144 throw new IOException("Not a valid jar url: "+urlString);
145
146 URL jarFileURL = new URL(urlString.substring(startOfJarUrl, endOfJarUrl));
147
148 InputStream is = jarFileURL.openConnection().getInputStream();
149 JarInputStream jin = new JarInputStream(is);
150 JarEntry entry;
151
152 while((entry=jin.getNextJarEntry())!=null)
153 {
154 String entryName = entry.getName();
155
156 LOG.debug("Looking at "+entryName);
157 String dotCheck = entryName.replace('\\', '/');
158 dotCheck = URIUtil.canonicalPath(dotCheck);
159 if (dotCheck == null)
160 {
161 LOG.info("Invalid entry: "+entryName);
162 continue;
163 }
164
165 File file=new File(directory,entryName);
166
167 if (entry.isDirectory())
168 {
169 if (isIncluded(entryName))
170 {
171 if (!isExcluded(entryName))
172 {
173
174 if (!file.exists())
175 file.mkdirs();
176 }
177 else
178 LOG.debug("{} dir is excluded", entryName);
179 }
180 else
181 LOG.debug("{} dir is NOT included", entryName);
182 }
183 else
184 {
185
186 if (isIncluded(entryName))
187 {
188 if (!isExcluded(entryName))
189 {
190
191 File dir = new File(file.getParent());
192 if (!dir.exists())
193 dir.mkdirs();
194
195
196 FileOutputStream fout = null;
197 try
198 {
199 fout = new FileOutputStream(file);
200 IO.copy(jin,fout);
201 }
202 finally
203 {
204 IO.close(fout);
205 }
206
207
208 if (entry.getTime()>=0)
209 file.setLastModified(entry.getTime());
210 }
211 else
212 LOG.debug("{} file is excluded", entryName);
213 }
214 else
215 LOG.debug("{} file is NOT included", entryName);
216 }
217 }
218
219 Manifest manifest = jin.getManifest();
220 if (manifest != null)
221 {
222 if (isIncluded("META-INF") && !isExcluded("META-INF"))
223 {
224 File metaInf = new File (directory, "META-INF");
225 metaInf.mkdir();
226 File f = new File(metaInf, "MANIFEST.MF");
227 FileOutputStream fout = new FileOutputStream(f);
228 manifest.write(fout);
229 fout.close();
230 }
231 }
232 IO.close(jin);
233 }
234
235 }