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