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 }