1 | |
|
2 | |
|
3 | |
|
4 | |
|
5 | |
|
6 | |
|
7 | |
|
8 | |
|
9 | |
|
10 | |
|
11 | |
package org.mule.tools.schemadocs; |
12 | |
|
13 | |
import org.mule.util.IOUtils; |
14 | |
|
15 | |
import java.io.File; |
16 | |
import java.io.FileOutputStream; |
17 | |
import java.io.FilenameFilter; |
18 | |
import java.io.IOException; |
19 | |
import java.io.InputStream; |
20 | |
import java.io.OutputStream; |
21 | |
import java.io.OutputStreamWriter; |
22 | |
import java.net.JarURLConnection; |
23 | |
import java.net.MalformedURLException; |
24 | |
import java.net.URL; |
25 | |
import java.util.Arrays; |
26 | |
import java.util.Enumeration; |
27 | |
import java.util.Iterator; |
28 | |
import java.util.LinkedList; |
29 | |
import java.util.List; |
30 | |
import java.util.jar.JarEntry; |
31 | |
|
32 | |
import javax.xml.parsers.ParserConfigurationException; |
33 | |
import javax.xml.transform.Source; |
34 | |
import javax.xml.transform.Templates; |
35 | |
import javax.xml.transform.Transformer; |
36 | |
import javax.xml.transform.TransformerException; |
37 | |
import javax.xml.transform.TransformerFactory; |
38 | |
import javax.xml.transform.stream.StreamResult; |
39 | |
import javax.xml.transform.stream.StreamSource; |
40 | |
|
41 | |
import org.apache.commons.logging.Log; |
42 | |
import org.apache.commons.logging.LogFactory; |
43 | |
import org.springframework.core.io.Resource; |
44 | |
import org.springframework.core.io.support.PathMatchingResourcePatternResolver; |
45 | |
|
46 | |
|
47 | |
public class SchemaDocsMain |
48 | |
{ |
49 | |
|
50 | |
public static final String BACKUP = ".bak"; |
51 | |
public static final String XSD = ".xsd"; |
52 | |
public static final String MULE = "mule"; |
53 | |
public static final String TAG = "tag"; |
54 | |
public static final String XSL_FILE = "rename-tag.xsl"; |
55 | 2 | public static final List TARGET_PATH = Arrays.asList(new String[]{"tools", "schemadocs", "target"}); |
56 | 2 | public static final String[] BLOCKED = new String[]{"wssecurity"}; |
57 | |
|
58 | 0 | protected final Log logger = LogFactory.getLog(getClass()); |
59 | |
|
60 | |
public static void main(String[] args) |
61 | |
throws IOException, TransformerException, ParserConfigurationException |
62 | |
{ |
63 | 0 | if (null == args || args.length != 3) |
64 | |
{ |
65 | 0 | throw new IllegalArgumentException("Needs 3 arguments: prefix, postfix and destination"); |
66 | |
} |
67 | 0 | new SchemaDocsMain(args[0], args[1], args[2]); |
68 | 0 | } |
69 | |
|
70 | |
public SchemaDocsMain(String prefix, String postfix, String normalizedPath) |
71 | |
throws IOException, TransformerException, ParserConfigurationException |
72 | 0 | { |
73 | 0 | logger.info("Generating " + normalizedPath); |
74 | 0 | logger.debug("prefix: " + prefix); |
75 | 0 | logger.debug("postfix: " + postfix); |
76 | 0 | File normalized = inTargetDir(normalizedPath); |
77 | 0 | backup(normalized); |
78 | 0 | InputStream xslSource = IOUtils.getResourceAsStream(XSL_FILE, getClass()); |
79 | 0 | if (null == xslSource) |
80 | |
{ |
81 | 0 | throw new IllegalStateException("Cannot open " + XSL_FILE); |
82 | |
} |
83 | 0 | create(normalized, false); |
84 | 0 | OutputStream out = new FileOutputStream(normalized); |
85 | 0 | logger.debug("out: " + out); |
86 | 0 | OutputStreamWriter outWriter = new OutputStreamWriter(out); |
87 | 0 | IOUtils.copy(IOUtils.getResourceAsStream(prefix, getClass()), outWriter); |
88 | 0 | outWriter.flush(); |
89 | 0 | processSchema(xslSource, out); |
90 | 0 | out.flush(); |
91 | 0 | IOUtils.copy(IOUtils.getResourceAsStream(postfix, getClass()), outWriter); |
92 | 0 | outWriter.close(); |
93 | 0 | } |
94 | |
|
95 | |
protected void create(File file, boolean dir) throws IOException |
96 | |
{ |
97 | 0 | if (!file.getParentFile().exists()) |
98 | |
{ |
99 | 0 | create(file.getParentFile(), true); |
100 | |
} |
101 | 0 | logger.debug("creating " + file); |
102 | 0 | if (dir) |
103 | |
{ |
104 | 0 | file.mkdir(); |
105 | |
} |
106 | |
else |
107 | |
{ |
108 | 0 | file.createNewFile(); |
109 | |
} |
110 | 0 | } |
111 | |
|
112 | |
|
113 | |
protected File inTargetDir(String path) |
114 | |
{ |
115 | 0 | if (path.startsWith(File.separator)) |
116 | |
{ |
117 | 0 | return new File(path); |
118 | |
} |
119 | |
else |
120 | |
{ |
121 | 0 | File dir = new File("."); |
122 | 0 | Iterator dirs = TARGET_PATH.iterator(); |
123 | 0 | boolean foundPath = false; |
124 | 0 | while (dirs.hasNext()) |
125 | |
{ |
126 | 0 | File next = new File(dir, (String) dirs.next()); |
127 | 0 | if (next.exists()) |
128 | |
{ |
129 | 0 | foundPath = true; |
130 | 0 | dir = next; |
131 | |
} |
132 | 0 | else if (foundPath) |
133 | |
{ |
134 | |
|
135 | |
|
136 | |
|
137 | 0 | throw new IllegalArgumentException("Could not find " + next + " while placing in target directory"); |
138 | |
} |
139 | 0 | } |
140 | 0 | File target = new File(dir, path); |
141 | 0 | logger.info("Target: " + target); |
142 | 0 | return target; |
143 | |
} |
144 | |
} |
145 | |
|
146 | |
protected void processSchema(InputStream xslSource, OutputStream out) |
147 | |
throws TransformerException, IOException, ParserConfigurationException |
148 | |
{ |
149 | 0 | TransformerFactory factory = TransformerFactory.newInstance(); |
150 | 0 | Templates template = factory.newTemplates(new StreamSource(xslSource)); |
151 | 0 | Transformer xformer = template.newTransformer(); |
152 | 0 | Iterator urls = listSchema2().iterator(); |
153 | 0 | while (urls.hasNext()) |
154 | |
{ |
155 | 0 | URL url = (URL) urls.next(); |
156 | 0 | String tag = tagFromFileName(url.getFile()); |
157 | 0 | logger.info(tag + " : " + url); |
158 | 0 | xformer.setParameter(TAG, tag); |
159 | 0 | Source source = new StreamSource(url.openStream()); |
160 | 0 | xformer.transform(source, new StreamResult(out)); |
161 | |
|
162 | 0 | out.flush(); |
163 | 0 | } |
164 | 0 | } |
165 | |
|
166 | |
|
167 | |
protected static String tagFromFileName(String name) |
168 | |
{ |
169 | 4 | String dropExtension = toLeftOf(name, ".", name); |
170 | 4 | String dropSlash = toRightOf(dropExtension, "/", dropExtension, true); |
171 | 4 | String dropBackslash = toRightOf(dropSlash, "\\", dropSlash, true); |
172 | 4 | return toRightOf(dropBackslash, "-", "mule", false); |
173 | |
} |
174 | |
|
175 | |
protected static String toRightOf(String text, String delim, String deflt, boolean far) |
176 | |
{ |
177 | 12 | int index = far ? text.lastIndexOf(delim) : text.indexOf(delim); |
178 | 12 | if (index > -1) |
179 | |
{ |
180 | 8 | return text.substring(index+1); |
181 | |
} |
182 | |
else |
183 | |
{ |
184 | 4 | return deflt; |
185 | |
} |
186 | |
} |
187 | |
|
188 | |
protected static String toLeftOf(String text, String delim, String deflt) |
189 | |
{ |
190 | 4 | int index = text.lastIndexOf(delim); |
191 | 4 | if (index > -1) |
192 | |
{ |
193 | 4 | return text.substring(0, index); |
194 | |
} |
195 | |
else |
196 | |
{ |
197 | 0 | return deflt; |
198 | |
} |
199 | |
} |
200 | |
|
201 | |
|
202 | |
protected List listSchema1() throws IOException |
203 | |
{ |
204 | 0 | PathMatchingResourcePatternResolver resolver = |
205 | |
new PathMatchingResourcePatternResolver(getClass().getClassLoader()); |
206 | 0 | Resource[] resources = resolver.getResources("**/META-INF/*.xsd"); |
207 | 0 | List list = new LinkedList(); |
208 | 0 | for (int i = 0; i < resources.length; ++i) |
209 | |
{ |
210 | 0 | list.add(resources[i].getURL()); |
211 | |
} |
212 | 0 | return list; |
213 | |
} |
214 | |
|
215 | |
|
216 | |
|
217 | |
protected List listSchema2() throws IOException |
218 | |
{ |
219 | 0 | ClassLoader loader = getClass().getClassLoader(); |
220 | 0 | List files = new LinkedList(); |
221 | 0 | Enumeration resources = loader.getResources("META-INF"); |
222 | 0 | FilenameFilter filter = |
223 | |
new FilenameFilter() { |
224 | 0 | public boolean accept(File dir, String name) |
225 | |
{ |
226 | 0 | if (name.startsWith(MULE) && name.endsWith(XSD)) |
227 | |
{ |
228 | 0 | for (int i = 0; i < BLOCKED.length; ++i) |
229 | |
{ |
230 | 0 | if (name.indexOf(BLOCKED[i]) > -1) |
231 | |
{ |
232 | 0 | return false; |
233 | |
} |
234 | |
} |
235 | 0 | return true; |
236 | |
} |
237 | |
else |
238 | |
{ |
239 | 0 | return false; |
240 | |
} |
241 | |
} |
242 | |
}; |
243 | 0 | while (resources.hasMoreElements()) |
244 | |
{ |
245 | 0 | URL url = (URL) resources.nextElement(); |
246 | 0 | logger.debug("url: " + url); |
247 | 0 | if (url.toString().startsWith("jar:")) |
248 | |
{ |
249 | 0 | readFromJar(url, files); |
250 | |
} |
251 | 0 | else if ("file".equals(url.getProtocol())) |
252 | |
{ |
253 | 0 | readFromDirectory(new File(url.getFile()), files, filter); |
254 | |
} |
255 | 0 | } |
256 | 0 | return files; |
257 | |
} |
258 | |
|
259 | |
|
260 | |
protected void readFromDirectory(File dir, List files, FilenameFilter filter) throws MalformedURLException |
261 | |
{ |
262 | 0 | String[] names = dir.list(filter); |
263 | 0 | for (int i = 0; i < names.length; ++i) |
264 | |
{ |
265 | 0 | String name = names[i]; |
266 | 0 | logger.debug("file: " + name); |
267 | 0 | files.add(new File(dir, name).toURL()); |
268 | |
} |
269 | 0 | } |
270 | |
|
271 | |
|
272 | |
protected void readFromJar(URL jarUrl, List resources) throws IOException |
273 | |
{ |
274 | 0 | JarURLConnection jarConnection = (JarURLConnection) jarUrl.openConnection(); |
275 | 0 | Enumeration entries = jarConnection.getJarFile().entries(); |
276 | 0 | while (entries.hasMoreElements()) |
277 | |
{ |
278 | 0 | JarEntry entry = (JarEntry) entries.nextElement(); |
279 | 0 | String name = new File(entry.getName()).getName(); |
280 | 0 | if (name.startsWith(MULE) && name.endsWith(XSD)) |
281 | |
{ |
282 | 0 | logger.debug("entry: " + entry); |
283 | 0 | resources.add(new URL(jarUrl, entry.getName())); |
284 | |
} |
285 | 0 | } |
286 | 0 | } |
287 | |
|
288 | |
protected void backup(File file) throws IOException |
289 | |
{ |
290 | 0 | if (file.exists()) |
291 | |
{ |
292 | 0 | File backup = new File(file.getAbsoluteFile().getParent(), file.getName() + BACKUP); |
293 | 0 | if (backup.exists()) |
294 | |
{ |
295 | 0 | logger.debug("deleting " + backup.getCanonicalPath()); |
296 | 0 | backup.delete(); |
297 | |
} |
298 | 0 | logger.debug("renaming " + file.getCanonicalPath() + " to " + backup.getCanonicalPath()); |
299 | 0 | file.renameTo(backup); |
300 | |
} |
301 | 0 | } |
302 | |
|
303 | |
} |