1 package org.appfuse;
2
3 import org.codehaus.plexus.util.StringUtils;
4 import org.codehaus.plexus.util.SelectorUtils;
5
6 import java.io.File;
7 import java.io.FileOutputStream;
8 import java.io.IOException;
9 import java.io.InputStream;
10 import java.util.Enumeration;
11 import java.util.jar.JarOutputStream;
12 import java.util.regex.Matcher;
13 import java.util.regex.Pattern;
14 import java.util.zip.ZipEntry;
15 import java.util.zip.ZipFile;
16
17
18
19
20 public class WarPathUtils
21 {
22 public static final Pattern WEBINF_CLASSES_PATTERN;
23
24 static
25 {
26 WEBINF_CLASSES_PATTERN = Pattern.compile("^[/\\\\]?web-inf[/\\\\]classes[/\\\\]?(.*)$", Pattern.CASE_INSENSITIVE);
27 }
28
29
30
31
32
33
34
35
36
37
38
39 public static void unpackWarClassesIfNewer(File warFile, File classesJarFile, String includes, String excludes) throws IOException
40 {
41 boolean process = false;
42 if (!classesJarFile.exists() || warFile.lastModified() > classesJarFile.lastModified())
43 {
44 process = true;
45 }
46
47 if (process)
48 {
49 ZipFile zipFile = new ZipFile(warFile);
50 JarOutputStream classesJarOutputStream = new JarOutputStream(new FileOutputStream(classesJarFile));
51 try
52 {
53 unpackWebInfClasses(zipFile, classesJarOutputStream, includes, excludes);
54 }
55 finally
56 {
57 closeZipFile(zipFile);
58 closeOutputStream(classesJarOutputStream);
59 }
60 }
61 }
62
63 private static void closeOutputStream(JarOutputStream classesJarOutputStream)
64 {
65 if (classesJarOutputStream != null)
66 {
67 try
68 {
69 classesJarOutputStream.close();
70 }
71 catch (IOException e)
72 {
73
74 }
75 }
76 }
77
78 private static void closeZipFile(ZipFile zipFile)
79 {
80 if (zipFile != null)
81 {
82 try
83 {
84 zipFile.close();
85 }
86 catch (IOException e)
87 {
88
89 }
90 }
91 }
92
93
94
95
96
97
98
99
100
101
102 public static void unpackWebInfClasses(ZipFile zipFile, JarOutputStream classesJarOutputStream, String includes, String excludes) throws IOException
103 {
104 Enumeration zipEntries = zipFile.entries();
105
106 String[] includePatterns;
107
108 if (StringUtils.isNotEmpty(includes))
109 {
110 includePatterns = StringUtils.split(includes, ",");
111 }
112 else
113 {
114 includePatterns = new String[]{"**"};
115 }
116
117 String[] excludesPattern;
118
119 if (StringUtils.isNotEmpty(excludes))
120 {
121 excludesPattern = StringUtils.split(excludes, ",");
122 }
123 else
124 {
125 excludesPattern = new String[0];
126 }
127
128 while (zipEntries.hasMoreElements())
129 {
130 ZipEntry zipEntry = (ZipEntry) zipEntries.nextElement();
131 Matcher matcher = WEBINF_CLASSES_PATTERN.matcher(zipEntry.getName());
132 if (matcher.matches() && matcher.group(1).length() > 0)
133 {
134 String classesEntry = matcher.group(1);
135
136 if (matches(classesEntry, includePatterns))
137 {
138 if (!matches(classesEntry, excludesPattern))
139 {
140 ZipEntry jarEntry = new ZipEntry(classesEntry);
141
142 jarEntry.setComment(zipEntry.getComment());
143 jarEntry.setExtra(zipEntry.getExtra());
144 jarEntry.setMethod(zipEntry.getMethod());
145 jarEntry.setTime(zipEntry.getTime());
146 jarEntry.setSize(zipEntry.getSize());
147 jarEntry.setCompressedSize(zipEntry.getCompressedSize());
148 jarEntry.setCrc(zipEntry.getCrc());
149 classesJarOutputStream.putNextEntry(jarEntry);
150 byte[] readBuffer = new byte[1024];
151 int readLength;
152 InputStream inputStream = zipFile.getInputStream(zipEntry);
153 while ((readLength = inputStream.read(readBuffer)) >= 0)
154 {
155 classesJarOutputStream.write(readBuffer, 0, readLength);
156 }
157 }
158 }
159 }
160 }
161 }
162
163 private static boolean matches(String entry, String[] patterns)
164 {
165 entry = replaceFileSeparator(entry);
166 for (int i = 0; i < patterns.length; i++)
167 {
168 String pattern = replaceFileSeparator(patterns[i].trim());
169 if (SelectorUtils.matchPath(pattern, entry))
170 {
171 return true;
172 }
173
174 }
175 return false;
176 }
177
178 private static String replaceFileSeparator(String path)
179 {
180 path = path.replace('/', File.separatorChar);
181 path = path.replace('\\', File.separatorChar);
182 return path;
183 }
184
185 }