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