1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.codehaus.mojo.jaxws;
18
19 import java.io.BufferedReader;
20 import java.io.BufferedWriter;
21 import java.io.File;
22 import java.io.FileInputStream;
23 import java.io.FileWriter;
24 import java.io.InputStreamReader;
25 import java.lang.annotation.Annotation;
26 import java.net.URL;
27 import java.net.URLClassLoader;
28 import java.util.ArrayList;
29 import java.util.LinkedList;
30 import java.util.List;
31 import java.util.Set;
32
33 import org.apache.maven.artifact.Artifact;
34 import org.apache.maven.plugin.MojoExecutionException;
35 import org.apache.maven.plugin.MojoFailureException;
36
37 import com.sun.tools.ws.WsGen;
38
39
40
41
42
43
44
45
46
47
48
49 abstract class AbstractWsGenMojo extends AbstractJaxwsMojo {
50
51
52
53
54
55
56 private boolean genWsdl;
57
58
59
60
61
62
63
64
65 private File resourceDestDir;
66
67
68
69
70
71
72
73 private String sei;
74
75
76
77
78
79
80
81
82 private List classpathElements;
83
84
85
86
87
88
89
90
91 private List compileSourceRoots;
92
93
94
95
96
97
98
99
100 private File classDirectory;
101
102
103
104
105
106
107
108
109
110 private String protocol;
111
112
113
114
115
116 private String hostURL;
117
118
119
120
121
122 private String contextURL;
123
124
125
126
127
128
129 private String serviceURL;
130
131
132
133
134
135
136
137 private File sourceDestDir;
138
139
140 private URLClassLoader classLoader = null;
141
142 public void execute()
143 throws MojoExecutionException, MojoFailureException {
144 init();
145
146
147 ClassLoader parent = this.getClass().getClassLoader();
148 String orginalSystemClasspath = this.initClassLoader(parent);
149
150 try {
151 List<String> classesToProcess = new LinkedList<String>();
152 if (sei.equals("*")) {
153
154 ArrayList<URL> urls = new ArrayList<URL>();
155 URL url = classDirectory.toURL();
156 urls.add(url);
157
158 for (Object cp : classpathElements) {
159 url = new File((String) cp).toURL();
160 urls.add(url);
161 }
162 classLoader = new URLClassLoader(urls.toArray(new URL[0]));
163
164
165 addClassFiles(classesToProcess, classDirectory);
166 } else {
167 classesToProcess.add(sei);
168 }
169
170
171 if (hostURL != null && contextURL != null) {
172 if (!hostURL.endsWith("/")) {
173 hostURL = hostURL + "/";
174 }
175 if (!contextURL.endsWith("/")) {
176 contextURL = contextURL + "/";
177 }
178 }
179
180 for (String classToProcess : classesToProcess) {
181 sei = classToProcess;
182 ArrayList<String> args = getWsGenArgs();
183
184 if (WsGen.doMain(args.toArray(new String[args.size()])) != 0)
185 throw new MojoExecutionException("Error executing: wsgen " + args);
186
187
188 if (genWsdl && hostURL != null && contextURL != null && serviceURL != null) {
189
190 String[] nameAndServiceName = getNameAndServiceName(classToProcess);
191 String name = nameAndServiceName[0];
192 String serviceName = nameAndServiceName[1];
193
194 String actualServiceURL = serviceURL.replaceAll("\\*", name);
195 replaceURLinWSDL(serviceName, hostURL + contextURL + actualServiceURL);
196 }
197 }
198 } catch (MojoExecutionException e) {
199 throw e;
200 } catch (Throwable e) {
201 throw new MojoExecutionException("Failed to execute wsgen",e);
202 } finally {
203
204 Thread.currentThread().setContextClassLoader(parent);
205 System.setProperty("java.class.path", orginalSystemClasspath);
206 }
207 }
208
209 private void init() throws MojoExecutionException, MojoFailureException {
210 if (!getDestDir().exists())
211 getDestDir().mkdirs();
212 }
213
214
215
216
217
218
219 private ArrayList<String> getWsGenArgs()
220 throws MojoExecutionException {
221 ArrayList<String> args = new ArrayList<String>();
222
223 if (verbose) {
224 args.add("-verbose");
225 }
226
227 if (keep || this.sourceDestDir!=null) {
228 args.add("-keep");
229 }
230
231 if (this.sourceDestDir != null) {
232 args.add("-s");
233 args.add(this.sourceDestDir.getAbsolutePath());
234 this.sourceDestDir.mkdirs();
235 }
236
237 args.add("-d");
238 args.add(getDestDir().getAbsolutePath());
239
240 args.add("-cp");
241 StringBuilder buf = new StringBuilder();
242 buf.append(getDestDir().getAbsolutePath());
243 for (Artifact a : (Set<Artifact>)project.getArtifacts()) {
244 buf.append(File.pathSeparatorChar);
245 buf.append(a.getFile().getAbsolutePath());
246 }
247 args.add(buf.toString());
248
249 if (this.genWsdl) {
250 if (this.protocol != null) {
251 args.add("-wsdl:" + this.protocol);
252 } else {
253 args.add("-wsdl");
254 }
255
256 args.add("-r");
257 args.add(this.resourceDestDir.getAbsolutePath());
258 this.resourceDestDir.mkdirs();
259
260 }
261
262 args.add(sei);
263
264 getLog().debug("jaxws:wsgen args: " + args);
265
266 return args;
267 }
268
269
270
271
272
273
274 @SuppressWarnings("unchecked")
275 private void addClassFiles(List<String> list, File folder) {
276 for (File file : folder.listFiles()) {
277 if (file.isDirectory()) {
278 addClassFiles(list, file);
279 } else {
280 if (!file.getName().endsWith(".class")) {
281 continue;
282 }
283
284
285 String path = file.toString().substring(
286 classDirectory.toString().length() + 1);
287
288
289 boolean found = false;
290 for (Object srcDir : compileSourceRoots) {
291 String dirReplaced = ((String) srcDir)
292 + File.separatorChar + path;
293 dirReplaced = dirReplaced.substring(0,
294 dirReplaced.length() - "class".length());
295 if (new File(dirReplaced + "java").exists()) {
296 found = true;
297 }
298 }
299 if (!found) {
300 continue;
301 }
302
303 String className = path.replace(File.separatorChar, '.');
304 className = className.substring(0,
305 className.length() - ".class".length());
306
307 try {
308 Class c = classLoader.loadClass(className);
309
310
311 if (c.isInterface()) {
312 continue;
313 }
314
315 Annotation[] annots = c.getAnnotations();
316
317 for (Annotation annotation : annots) {
318 if (annotation.annotationType().getName()
319 .equals("javax.jws.WebService")) {
320
321 list.add(className);
322 break;
323 }
324 }
325 } catch (Exception e) {
326
327 }
328 }
329 }
330 }
331
332
333
334
335
336
337
338 private void replaceURLinWSDL(String serviceName, String url)
339 throws MojoExecutionException {
340
341 File file = new File(resourceDestDir, serviceName + ".wsdl");
342
343 if (file.exists()) {
344 String line;
345 StringBuilder sb = new StringBuilder();
346 try {
347
348 FileInputStream fis = new FileInputStream(file);
349 BufferedReader reader = new BufferedReader(
350 new InputStreamReader(fis));
351 while ((line = reader.readLine()) != null) {
352 line = line.replaceAll("REPLACE_WITH_ACTUAL_URL", url);
353 sb.append(line + "\n");
354 }
355 reader.close();
356
357
358 BufferedWriter out = new BufferedWriter(new FileWriter(file));
359 out.write(sb.toString());
360 out.close();
361 } catch (Throwable e) {
362 throw new MojoExecutionException(
363 "Could not modify WSDL file for service " + serviceName);
364 }
365 } else {
366 getLog().warn("Could not find generated WSDL for service '" + serviceName + "'");
367 }
368 }
369
370
371
372
373
374
375 @SuppressWarnings("unchecked")
376 private String[] getNameAndServiceName(String classToProcess)
377 throws MojoExecutionException {
378
379 String name = null;
380 String serviceName = null;
381 try {
382 Class c = classLoader.loadClass(classToProcess);
383
384 Annotation[] annots = c.getAnnotations();
385
386 for (Annotation annotation : annots) {
387 if (annotation.annotationType().getName()
388 .equals("javax.jws.WebService")) {
389
390 name = (String) annotation
391 .annotationType().getMethod("name")
392 .invoke(annotation);
393
394 serviceName = (String) annotation
395 .annotationType().getMethod("serviceName")
396 .invoke(annotation);
397
398 break;
399 }
400 }
401
402 if (name == null) {
403
404 name = c.getSimpleName();
405 }
406 if (serviceName == null) {
407
408 serviceName = c.getSimpleName() + "Service";
409 }
410 } catch (Exception e) {
411 throw new MojoExecutionException(
412 "Could not get serviceName from " + classToProcess);
413 }
414 if (serviceName == null) {
415 throw new MojoExecutionException(
416 "Could not get serviceName from " + classToProcess);
417 }
418
419 return new String[] {name, serviceName};
420 }
421 }