1
2
3
4
5
6
7
8 package it.imolinfo.jbi4corba.webservice.generator.bcm;
9
10 import it.imolinfo.jbi4corba.Logger;
11 import it.imolinfo.jbi4corba.LoggerFactory;
12 import it.imolinfo.jbi4corba.exception.ClassGenerationException;
13 import it.imolinfo.jbi4corba.webservice.generator.AnyType;
14 import it.imolinfo.jbi4corba.webservice.generator.InterfaceType;
15 import it.imolinfo.jbi4corba.webservice.generator.MethodSignature;
16 import it.imolinfo.jbi4corba.webservice.generator.Param;
17 import it.imolinfo.jbi4corba.webservice.generator.TypeUtils;
18 import it.imolinfo.jbi4corba.webservice.generator.UnionType;
19 import it.imolinfo.jbi4corba.webservice.generator.UnionTypeUtils;
20 import it.imolinfo.jbi4corba.webservice.generator.Util;
21
22 import java.util.ArrayList;
23 import java.util.HashSet;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.Set;
27
28 import org.objectweb.asm.AnnotationVisitor;
29 import org.objectweb.asm.ClassAdapter;
30 import org.objectweb.asm.ClassVisitor;
31 import org.objectweb.asm.ClassWriter;
32 import org.objectweb.asm.MethodVisitor;
33 import org.objectweb.asm.Type;
34
35
36
37
38
39
40
41 public class WebServiceAnnotationAdapter extends ClassAdapter {
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70 public static final String JSR181_WEB_SERVICE = "Ljavax/jws/WebService;";
71 private static final String W3CEPR = Type.getDescriptor(javax.xml.ws.wsaddressing.W3CEndpointReference.class);
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88 public static final String JSR181_WEB_METHOD = "Ljavax/jws/WebMethod;";
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125 public static final String JSR181_WEB_PARAM = "Ljavax/jws/WebParam;";
126 public static final String JSR181_WEB_PARAM_MODE = "Ljavax/jws/WebParam$Mode;";
127 public static final String JSR181_WEB_PARAM_MODE_INOUT = "INOUT";
128 public static final String JSR181_WEB_RESULT = "Ljavax/jws/WebResult;";
129 public static final String JAVAX_XML_WS_HOLDER_TYPE = "Ljavax/xml/ws/Holder;";
130 public static final String JAVAX_XML_WS_HOLDER_TYPE_CANONICAL_NAME = "javax.xml.ws.Holder";
131 public static final String JAVAX_XML_WS_HOLDER_TYPE_NO_SEMICOLON = "Ljavax/xml/ws/Holder";
132 public static final String JSR181_SOAP_BINDING = "Ljavax/jws/soap/SOAPBinding;";
133 public static final String JAXB_XML_SEE_ALSO_ANNOTATOIN = "Ljavax/xml/bind/annotation/XmlSeeAlso;";
134 public static final String JSR181_SOAP_BINDING_USE = "Ljavax/jws/soap/SOAPBinding$Use;";
135 public static final String JSR181_SOAP_BINDING_STYLE = "Ljavax/jws/soap/SOAPBinding$ParameterStyle;";
136 public static final String JSR181_LITERAL = "LITERAL";
137 public static final String JSR181_WRAPPED = "WRAPPED";
138 public static final String JSR181_BARE = "BARE";
139 private Map<String, UnionType> allUnionTypes;
140 private Map<String, InterfaceType> allInterfaceTypes;
141 private String workingDirClasses;
142
143 public Set<String> exceptionsThrown = new HashSet<String>();
144
145
146
147 public static final String JSR181_ONEWAY = "Ljavax/jws/Oneway;";
148 protected static Set<String> noAnnotatedMethods = new HashSet<String>();
149
150
151 static {
152 noAnnotatedMethods.add("<init>");
153 noAnnotatedMethods.add("hashCode");
154 noAnnotatedMethods.add("getClass");
155 noAnnotatedMethods.add("wait");
156 noAnnotatedMethods.add("equals");
157 noAnnotatedMethods.add("notify");
158 noAnnotatedMethods.add("notifyAll");
159 noAnnotatedMethods.add("toString");
160 }
161
162
163
164 private static final Logger LOG = LoggerFactory.getLogger(WebServiceAnnotationAdapter.class);
165
166 protected ClassWriter classWriter = null;
167
168 protected List<MethodSignature> methodSignatureList = null;
169 boolean areClassAnnotationsPresent = false;
170
171 protected String nameSpace = null;
172
173 protected String portTypeName = null;
174
175 protected Set<Class> allTypes = null;
176
177
178
179
180
181
182
183
184
185
186 public WebServiceAnnotationAdapter(ClassVisitor cv, ClassWriter cw,
187 List<MethodSignature> aMethodSignatureList, String ns, String ptn, String workingDir, Map<String, UnionType> unionTypes, Map<String, InterfaceType> intfTypes, Set<Class> allTypesIDL) {
188
189 super(cv);
190
191 classWriter = cw;
192 methodSignatureList = aMethodSignatureList;
193 nameSpace = ns;
194 portTypeName = ptn;
195 allUnionTypes = unionTypes;
196 allInterfaceTypes = intfTypes;
197 workingDirClasses = workingDir;
198 allTypes = allTypesIDL;
199 }
200
201
202
203
204
205
206
207
208
209
210 @Override
211 public void visit(int version, int access, String name, String signature,
212 String superName, String[] interfaces) {
213
214 LOG.debug("CRB000605_WebServiceAnnotationAdapter_visit", new Object[]{version, access, name, signature, superName, interfaces});
215
216 super.visit(version, access, name, signature, superName, interfaces);
217
218 addAnnotation(name);
219
220 }
221
222 @Override
223 public void visitEnd() {
224
225 cv.visitEnd();
226 }
227
228
229
230
231
232 private void addAnnotation(String name) {
233 if (!areClassAnnotationsPresent) {
234
235
236 AnnotationVisitor av = cv.visitAnnotation(JSR181_WEB_SERVICE, true);
237
238
239 if (portTypeName != null) {
240 LOG.debug("Adding port type name:" + portTypeName);
241 av.visit("name", portTypeName);
242 } else {
243 String javaSimpleName = name.substring(name.lastIndexOf("/") + 1);
244 av.visit("name", javaSimpleName);
245 }
246 if (nameSpace != null) {
247 av.visit("targetNamespace", nameSpace);
248 LOG.debug("Adding targetNamespace:" + nameSpace);
249 }
250 if (av != null) {
251 av.visitEnd();
252 }
253
254
255 AnnotationVisitor av2 = cv.visitAnnotation(JSR181_SOAP_BINDING, true);
256 av2.visitEnum("use", JSR181_SOAP_BINDING_USE, JSR181_LITERAL);
257 av2.visitEnum("parameterStyle",
258 JSR181_SOAP_BINDING_STYLE, JSR181_WRAPPED);
259
260
261 if (av2 != null) {
262 av2.visitEnd();
263 }
264
265
266 AnnotationVisitor av3 = cv.visitAnnotation(JAXB_XML_SEE_ALSO_ANNOTATOIN, true);
267 AnnotationVisitor xmlElems = av3.visitArray("value");
268
269 for (Class typeClass : allTypes) {
270 String className = typeClass.getName();
271 UnionType union = UnionTypeUtils.isUnionType(className, false, allUnionTypes);
272 if (union != null) {
273 try {
274 typeClass = Util.classLoad(workingDirClasses, union.getTypeName() + "Wrapper");
275 } catch (ClassGenerationException e) {
276
277 LOG.debug("WebServiceAnnotationAdapter.addAnnotation: Class not found for union: " + union.getTypeName());
278 }
279 }
280
281 if (!Util.isThrowableSubClass(typeClass) && !typeClass.isInterface()) {
282
283 xmlElems.visit("value", Type.getType(typeClass));
284
285
286
287
288
289
290
291
292
293
294
295
296 }
297 }
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316 if (xmlElems != null) {
317 xmlElems.visitEnd();
318 }
319 if (av3 != null) {
320 av3.visitEnd();
321 }
322
323 areClassAnnotationsPresent = true;
324 }
325 }
326
327
328
329
330
331
332
333
334
335
336 @Override
337 public MethodVisitor visitMethod(int access, String name, String desc,
338 String signature, String[] exceptions) {
339
340 LOG.debug("WebServiceAnnotationAdapter.visitMethod. access=" + access + "; name=" + name + "; desc=" + desc + "; signature=" + signature + "; exceptions=" + exceptions);
341
342 if (exceptions != null) {
343 for (int i = 0; i < exceptions.length; i++) {
344 LOG.debug("Exception found: " + exceptions[i]);
345 exceptionsThrown.add(exceptions[i]);
346 }
347 }
348
349 if (noAnnotatedMethods.contains(name)) {
350 LOG.debug("NO WebService Annotations [methodName=" + name + "]");
351 return super.visitMethod(access, name, desc, signature, exceptions);
352 }
353
354 LOG.debug("WebService Annotations for [methodName=" + name + "]");
355
356
357 MethodSignature methodSignature = findFirstMethodSignature(name);
358
359
360 /
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386 protected void addMethodSignatureAnnotation(MethodVisitor methodVisitor,
387 MethodSignature methodSignature, String description, String signature) {
388
389 addAnnotationOperationName(methodVisitor, methodSignature.getMethodName());
390
391
392 if (methodSignature.isOneway()) {
393 LOG.debug("The method " + methodSignature.getMethodName() + " is marked 'oneway'.");
394 AnnotationVisitor avOneway = methodVisitor.visitAnnotation(JSR181_ONEWAY, true);
395 avOneway.visitEnd();
396 }
397
398 addAnnotationReturnName(methodVisitor, methodSignature.getReturnName());
399
400 addParameterAnnotation(methodVisitor, methodSignature);
401
402 }
403
404
405
406
407
408
409
410
411
412
413
414 protected void addParameterAnnotation(MethodVisitor methodVisitor,
415 MethodSignature sig) {
416
417
418 if (methodVisitor == null) {
419 LOG.debug("The method visitor is null. add no annotation");
420 return;
421 }
422
423
424 if (sig == null) {
425 LOG.debug("The method's signature is null. add no annotation");
426 return;
427 }
428
429
430 if (sig.getParameters() == null || sig.getParameters().size() == 0) {
431
432 LOG.debug("The list of parameter name is null or empty." + "add no annotation");
433 return;
434 }
435
436
437 LOG.debug("Adding parameter for the method: " + sig);
438 for (int pos = 0; pos < sig.getParameters().size(); pos++) {
439
440 String param = sig.getParameters().get(pos).getName();
441 String paramType = sig.getParameters().get(pos).getTypeName();
442
443 LOG.debug("Adding parameter name: " + param + " of type: " + paramType);
444
445 AnnotationVisitor av = methodVisitor.visitParameterAnnotation(pos, JSR181_WEB_PARAM, true);
446 av.visit("name", param);
447
448
449
450
451
452 if (sig.getParameters().get(pos).isHolder()) {
453 av.visitEnum("mode", JSR181_WEB_PARAM_MODE, JSR181_WEB_PARAM_MODE_INOUT);
454 }
455
456 av.visitEnd();
457
458 LOG.debug("WebParam annotation for [parameterName=" + param + "; parameterPosition=" + pos + "]");
459 }
460
461
462 }
463
464
465
466
467
468
469
470
471
472
473
474 protected void addAnnotationReturnName(MethodVisitor methodVisitor,
475 String returnName) {
476
477
478 if (methodVisitor == null) {
479 LOG.debug("The method visitor is null. add no annotation");
480 return;
481 }
482
483
484 if (returnName == null || "".equals(returnName)) {
485 LOG.debug("The return name is null or empty. add no annotation");
486 return;
487 }
488
489
490 AnnotationVisitor av = methodVisitor.visitAnnotation(JSR181_WEB_RESULT, true);
491
492 av.visit("name", returnName);
493 av.visitEnd();
494
495 }
496
497
498
499
500
501
502
503
504
505
506
507 protected void addAnnotationOperationName(MethodVisitor methodVisitor,
508 String operationName) {
509
510
511 if (methodVisitor == null) {
512 LOG.debug("The method visitor is null. add no annotation");
513 return;
514 }
515
516
517 if (operationName == null || "".equals(operationName)) {
518 LOG.debug("The operation name is null or empty. add no annotation");
519 return;
520 }
521
522
523 AnnotationVisitor av = methodVisitor.visitAnnotation(JSR181_WEB_METHOD, true);
524
525 av.visit("operationName", operationName);
526
527 av.visitEnd();
528 }
529
530
531
532
533
534
535
536
537
538
539
540 protected MethodSignature findFirstMethodSignature(String methodName) {
541 if (methodSignatureList == null) {
542 LOG.debug("Method's signature not found:" + "The list of the MethodSignature is null.");
543 return null;
544 }
545
546 if (methodName == null) {
547 LOG.debug("Method's signature not found:" + "The method name is null.");
548 return null;
549 }
550
551 for (MethodSignature sig : methodSignatureList) {
552 if (methodName.equals(sig.getMethodName())) {
553 LOG.debug("MethodSignature FOUND. MethodName=" + methodName + "; MethodSignature=" + sig);
554 return sig;
555 }
556 }
557
558 LOG.debug("Method's signature not found for the method " + methodName);
559 return null;
560 }
561
562 public Set<String> getExceptionsThrown() {
563 return exceptionsThrown;
564 }
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589 protected SignatureDescription changeHolderParameters(MethodSignature sig, String methodDescription, String methodSignature) {
590
591 StringBuffer newMethodDescription = new StringBuffer("(");
592 StringBuffer newMethodSignature = new StringBuffer("(");
593 InternalMethodDescriptionParser parser = new InternalMethodDescriptionParser(methodDescription);
594 List<String> internalParams = parser.parse();
595
596 if (internalParams.size() != 0) {
597
598 List<String> newParams = new ArrayList<String>();
599
600
601
602 for (int i = 0; i < sig.getParameters().size(); i++) {
603
604 Param param = (Param) sig.getParameters().get(i);
605 if (param.isHolder()) {
606
607 Class paramClass = param.getHolderValueType();
608 String paramTypeDescriptor = Type.getDescriptor(paramClass);
609 String holderValueTypeStr = TypeUtils.getTypeNameWithoutBrackets(paramClass);
610 UnionType union = allUnionTypes.get(holderValueTypeStr);
611 InterfaceType intf = allInterfaceTypes.get(holderValueTypeStr);
612
613 String arrayStr = TypeUtils.getArrayDimmentionAsPrefix(paramClass);
614 boolean isAny = TypeUtils.getTypeNameWithoutBrackets(paramClass).equals(AnyType.CORBA_ANY_TYPE);
615
616 if (isAny) {
617 paramTypeDescriptor = arrayStr + "Ljava/lang/Object;";
618 }
619
620 if (intf != null) {
621 paramTypeDescriptor = W3CEPR;
622 }
623
624 if (union != null) {
625 String wrapperType = null;
626 try {
627 wrapperType = UnionTypeUtils.createUnionClassWrapper(union, allUnionTypes, workingDirClasses);
628 paramTypeDescriptor = arrayStr + "L" + wrapperType + ";";
629 } catch (ClassGenerationException e) {
630 LOG.error("Error generating wrapper class for uniontype:" + holderValueTypeStr);
631 }
632 }
633
634 LOG.debug("The parameter:" + param.getName() + "/" + param.getTypeName() + " is an Holder of type:" + paramTypeDescriptor);
635
636
637 newParams.add(JAVAX_XML_WS_HOLDER_TYPE);
638 String newHolderParamName = JAVAX_XML_WS_HOLDER_TYPE_NO_SEMICOLON + "<" + paramTypeDescriptor + ">;";
639
640
641 param.setTypeName(JAVAX_XML_WS_HOLDER_TYPE_CANONICAL_NAME + "<" + param.getHolderValueType().getCanonicalName() + ">");
642
643
644 newMethodSignature.append(newHolderParamName);
645
646 } else {
647
648 newParams.add(internalParams.get(i));
649 newMethodSignature.append(internalParams.get(i));
650 }
651 newMethodDescription.append(newParams.get(i));
652 }
653
654 newMethodDescription.append(")").append(parser.getMethodDescriptionTail());
655 newMethodSignature.append(")").append(parser.getMethodDescriptionTail());
656
657
658 methodDescription = newMethodDescription.toString();
659 methodSignature = newMethodSignature.toString();
660 }
661
662 return new SignatureDescription(methodDescription, methodSignature);
663 }
664
665
666
667
668
669
670 public class SignatureDescription {
671
672
673 private String description;
674
675
676 private String signature;
677
678 public SignatureDescription(String desc, String sig) {
679 description = desc;
680 signature = sig;
681 }
682
683 public String getDescription() {
684 return description;
685 }
686
687 public String getSignature() {
688 return signature;
689 }
690 }
691 }