KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > beehive > wsm > model > jsr181 > Jsr181TypeMetadataImpl


1 package org.apache.beehive.wsm.model.jsr181;
2
3 /*
4  * Copyright 2004 The Apache Software Foundation
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  * $Header:$Factory
19  */

20
21 import org.apache.beehive.wsm.model.*;
22 import org.apache.beehive.wsm.model.java.JavaMethodInfo;
23 import org.apache.beehive.wsm.model.java.JavaTypeInfo;
24 import org.w3c.dom.Element JavaDoc;
25 import org.w3c.dom.Node JavaDoc;
26 import org.w3c.dom.NodeList JavaDoc;
27
28 import javax.jws.HandlerChain;
29 import javax.jws.WebMethod;
30 import javax.jws.WebService;
31 import javax.jws.soap.SOAPBinding;
32 import javax.jws.soap.SOAPMessageHandler;
33 import javax.jws.soap.SOAPMessageHandlers;
34 import javax.xml.parsers.DocumentBuilderFactory JavaDoc;
35 import java.io.File JavaDoc;
36 import java.lang.annotation.Annotation JavaDoc;
37 import java.net.MalformedURLException JavaDoc;
38 import java.net.URL JavaDoc;
39 import java.util.*;
40
41 /**
42  *
43  */

44 public class Jsr181TypeMetadataImpl implements BeehiveWsTypeMetadata, java.io.Serializable JavaDoc {
45
46     private static final long serialVersionUID = 1L;
47
48     private String JavaDoc wsName;
49     private String JavaDoc wsServiceName;
50     private String JavaDoc wsWsdlLocation;
51     private String JavaDoc wsTargetNamespace;
52     private String JavaDoc wsEndpointInterface;
53     private Map<String JavaDoc, BeehiveWsMethodMetadata> methodMap =
54             new HashMap<String JavaDoc, BeehiveWsMethodMetadata>();
55     private Set<BeehiveWsMethodMetadata> noDuplicateMethods;
56     private BeehiveWsSOAPBindingInfo soapBinding;
57     private String JavaDoc hcFileName;
58     private String JavaDoc hcName;
59     private List JavaDoc<BeehiveWsSOAPMessageHandlerInfo> soapHandlers =
60             new ArrayList<BeehiveWsSOAPMessageHandlerInfo>();
61     private String JavaDoc siValue;
62     private String JavaDoc className;
63     private File JavaDoc baseLocation;
64
65     /**
66      * Default constructor.
67      */

68     public Jsr181TypeMetadataImpl() {
69         // empty
70
}
71
72     /**
73      * This constructor creates an object that encapsulates all type-level
74      * annotations and their fields. Moreover, it enforces all rules specified
75      * in JSR-181.
76      * @param jt An object that provides Java-specific context services for
77      * type-level annotations.
78      */

79     public Jsr181TypeMetadataImpl(JavaTypeInfo jt) {
80
81         super();
82
83         if (null == jt) {
84             jt.logError("illegal java type info: <null>");
85             return;
86         }
87
88         // check required @WebService annotation
89
WebService webService = jt.getAnnotation(WebService.class);
90         if (null == webService) {
91             jt.logError("no @WebService annotation found");
92         }
93
94         // get webMethods
95
Collection<BeehiveWsMethodMetadata> webMethods =
96             new ArrayList<BeehiveWsMethodMetadata>();
97         // SIB: try adding only annotated methods
98
if (! jt.isInterface()) {
99             for (JavaMethodInfo jm : jt.getMethods()) {
100                 if (null != jm.getAnnotation(WebMethod.class)) {
101                     BeehiveWsMethodMetadata wsmm = new Jsr181MethodMetadataImpl(jm);
102                     if (null == wsmm) {
103                         jt.logError("illegal web method: " + jm.getMethodName());
104                     }
105                     webMethods.add(wsmm);
106                 }
107             }
108         }
109         // SEI or SIB with no @WebMethod annotations: add all methods
110
if (webMethods.isEmpty()) {
111             for (JavaMethodInfo jm : jt.getMethods()) {
112                 BeehiveWsMethodMetadata wsmm = new Jsr181MethodMetadataImpl(jm);
113                 webMethods.add(wsmm);
114             }
115         }
116         
117         // check required parameters: annotations, webMethods
118
Collection<Annotation JavaDoc> annotations = jt.getAnnotations();
119         if ((null == annotations) || (null == webMethods)) {
120             jt.logError("no annotations or web methods found");
121         }
122
123         // check required parameter: className
124
className = jt.getName();
125         if ((null == className) || (0 == className.length())) {
126             jt.logError("web service class is null");
127         }
128         baseLocation = jt.getLocation();
129
130         // enforce JSR-181 rules
131
if (jt.isFinal() || ! jt.isPublic()) {
132             jt.logError("@WebService class must be public but not final");
133         }
134         if (jt.hasFinalize()) {
135             jt.logError("web service class must not declare method: finalize()");
136         }
137         if (jt.isInterface()) {
138             if (null != webService.endpointInterface() && 0 < webService.endpointInterface().trim().length()) {
139                 jt.logError("@WebService.endpointInterface not allowed on interfaces");
140             }
141             if (null != webService.serviceName() && 0 < webService.serviceName().trim().length()) {
142                 jt.logError("@WebService.serviceName not allowed on interfaces");
143             }
144         }
145         else {
146             if (jt.isAbstract()) {
147                 jt.logError("service implementation bean must not be abstract");
148             }
149             if (! jt.hasDefaultConstructor()) {
150                 jt.logError("service implementation bean must have default constructor");
151             }
152         }
153         if (null != jt.getAnnotation(SOAPMessageHandlers.class) && null != jt.getAnnotation(HandlerChain.class)) {
154             jt.logError("Illegal combination of @SOAPMessageHandlers and @HandlerChain");
155         }
156         String JavaDoc wsdlLocation = webService.wsdlLocation();
157         if (null != wsdlLocation && 0 < wsdlLocation.trim().length()) {
158             try {
159                 findResource(wsdlLocation.trim(), baseLocation).openStream();
160             }
161             catch (Throwable JavaDoc t) {
162                 jt.logError("wsdlLocation does not exist: " + wsdlLocation);
163             }
164         }
165         
166         // initilize instance
167
initFromAnnotation(webService);
168
169         // set optional annotations
170
for (Annotation JavaDoc a : annotations) {
171
172             // @HandlerChain
173
if (a.annotationType() == javax.jws.HandlerChain.class) {
174                 initFromAnnotation((javax.jws.HandlerChain) a);
175             }
176
177             // @SOAPBinding
178
else if (a.annotationType() == javax.jws.soap.SOAPBinding.class) {
179                 initFromAnnotation((javax.jws.soap.SOAPBinding) a);
180             }
181
182             // @SOAPMessageHandlers
183
else if (a.annotationType() == javax.jws.soap.SOAPMessageHandlers.class) {
184                 initFromAnnotation((javax.jws.soap.SOAPMessageHandlers) a);
185             }
186
187             // @WebService
188
else if (a.annotationType() == javax.jws.WebService.class) {
189                 // ignore -- already done (see above)
190
// todo: why can't we do this here?
191
}
192             
193             // unsupported annotation
194
else {
195                 jt.logError("found unsupported annotation: " + a.annotationType().getName());
196             }
197         }
198         
199         // set Jsr181MethodMetadata and back fill JSR-181 default values
200
for (BeehiveWsMethodMetadata wsmm : webMethods) {
201             // JSR-181 defaults: fill in default for tergetNamespace from @WebService
202
String JavaDoc wrTargetNamespace = wsmm.getWrTargetNamespace();
203             if ((null == wrTargetNamespace) || (0 == wrTargetNamespace.length())) {
204                 wsmm.setWrTargetNamespace(getWsTargetNamespace());
205             }
206
207             // JSR-181 defaults: fill in default for tergetNamespace from @WebService
208
for (BeehiveWsParameterMetadata wspm : wsmm.getParams()) {
209                 String JavaDoc wpTargetNamespace = wspm.getWpTargetNamespace();
210                 if ((null == wpTargetNamespace) || (0 == wpTargetNamespace.length())) {
211                     wspm.setWpTargetNamespace(getWsTargetNamespace());
212                 }
213             }
214
215             // add WebMethod to TYPE metadata
216
try {
217                 addMethod(wsmm);
218             }
219             catch (ValidationException e) {
220                 jt.logError("cannot add web method to metadata: " + wsmm.getJavaMethodName());
221             }
222         }
223     }
224
225     protected void initFromAnnotation(WebService annotation) {
226
227         if (null == annotation) {
228             return;
229         }
230         
231         // initialize fields with values from annotations
232
wsEndpointInterface = annotation.endpointInterface().trim();
233         
234         setWsName(annotation.name());
235         setWsTargetNamespace(annotation.targetNamespace());
236         setWsWsdlLocation(annotation.wsdlLocation());
237         setWsServiceName(annotation.serviceName());
238         setWsEndpointInterface(annotation.endpointInterface());
239
240         // set default values
241

242         // name
243
String JavaDoc name = className;
244         if (-1 < name.indexOf('.')) {
245             int index = name.lastIndexOf('.');
246             name = name.substring(index + 1);
247         }
248         if (0 == getWsName().length()) {
249             setWsName(name);
250         }
251
252         // serviceName
253
String JavaDoc serviceName = className;
254         if (-1 < serviceName.indexOf('.')) {
255             int index = serviceName.lastIndexOf('.');
256             serviceName = serviceName.substring(index + 1);
257         }
258         if (0 == getWsServiceName().length()) {
259             setWsServiceName(serviceName + "Service");
260         }
261
262         // targetNamespace
263
if (0 == getWsTargetNamespace().length()) {
264             setWsTargetNamespace(getTargetNamespace(className));
265         }
266     }
267
268     private void initFromAnnotation(SOAPBinding annotation) {
269
270         if (null == annotation) {
271             return;
272         }
273         
274         // set soap binding from annotation
275
setSoapBinding(new SOAPBindingInfo(annotation));
276
277         // validate soap binding
278
BeehiveWsSOAPBindingInfo sbi = getSoapBinding();
279         if (null == sbi) {
280             throw new IllegalArgumentException JavaDoc("illegal SOAPBinding annotation on WebService class:\n\t" + sbi);
281         }
282
283         // no defaults to handle
284
}
285
286     private void initFromAnnotation(HandlerChain annotation) {
287
288         if (null == annotation) {
289             return;
290         }
291         
292         if (! getSoapHandlers().isEmpty()) {
293             throw new IllegalArgumentException JavaDoc("@SOAPMessageHandlers and @HandlerChain are mutually exclusive");
294         }
295         
296         String JavaDoc hcPath = annotation.file();
297         String JavaDoc hcName = annotation.name();
298
299         setHcName(hcName);
300         setHcFileName(hcPath);
301
302         try {
303             configureHandlerChain(hcPath, hcName);
304         }
305         catch (Throwable JavaDoc t) {
306             throw new RuntimeException JavaDoc(t.getMessage());
307         }
308     }
309
310     private void initFromAnnotation(SOAPMessageHandlers annotation) {
311         
312         if (null == annotation) {
313             return;
314         }
315         
316         if (null != getHcFileName()) {
317             throw new IllegalArgumentException JavaDoc("@SOAPMessageHandlers and @HandlerChain are mutually exclusive");
318         }
319                 
320         for (SOAPMessageHandler soapMessageHandler : annotation.value()) {
321             BeehiveWsSOAPMessageHandlerInfo smhi = new SOAPMessageHandlerInfo(soapMessageHandler);
322             // todo: validate smhi.getClassName()
323
addSOAPHandler(smhi);
324         }
325     }
326
327
328     private void configureHandlerChain(String JavaDoc handlerChainConfigPath, String JavaDoc handlerChainName)
329         throws Exception JavaDoc
330     {
331         // get URL for handler-chain config
332
URL JavaDoc handlerChainConfigURL = findResource(handlerChainConfigPath, baseLocation);
333         if (null == handlerChainConfigURL) {
334             throw new Exception JavaDoc("@HandlerChain: cannot resolve relative URL: " + handlerChainConfigPath + "(base directory: " + baseLocation + ")");
335         }
336         
337         // parse handler-chain config and add handler-chain to object model
338
initHandlersFromChainConfig(handlerChainConfigURL, handlerChainName);
339     }
340
341     /**
342      * Finds a resource given a resource path. Tries absolute path (http://...
343      * or file:/...) first, then relative to basePath. This method does not use
344      * class loaders since it needs to work with source files as well as with
345      * (binary) class files.
346      * @param resourcePath the path of the resource, either absolute or relative
347      * (to basePath).
348      * @param basePath only required when resourcePath is relative.
349      * @return URL of resource.
350      */

351     private URL JavaDoc findResource(String JavaDoc resourcePath, File JavaDoc basePath) {
352
353         URL JavaDoc resourceURL = null;
354
355         // validate path
356
if (null == resourcePath || 0 == resourcePath.length()) {
357             return null;
358         }
359         
360         // handle absolute URL
361
if (resourcePath.startsWith("http://") || resourcePath.startsWith("file:/")) {
362             try {
363                 resourceURL = new URL JavaDoc(resourcePath);
364                 return resourceURL;
365             }
366             catch (MalformedURLException JavaDoc e) {
367                 return null;
368             }
369         }
370         
371         // handle relative URL (we cannot use class loaders here)
372
if ((null == basePath) || (! basePath.exists())) {
373             return null;
374         }
375         if (resourcePath.startsWith("/")) {
376             String JavaDoc base = basePath.toString();
377             String JavaDoc temp = className;
378             int lastIdx = className.lastIndexOf('.');
379             if (0 >= lastIdx) {
380                 return null;
381             }
382             temp = temp.substring(0, lastIdx).replace('.', File.separatorChar);
383             if (! base.endsWith(temp)) {
384                 return null;
385             }
386             temp = base.substring(0, base.length() - temp.length());
387             try {
388                 resourceURL = new File JavaDoc(temp, resourcePath).toURL();
389             }
390             catch (MalformedURLException JavaDoc e) {
391                 return null;
392             }
393         }
394         else {
395             try {
396                 resourceURL = new File JavaDoc(basePath, resourcePath).toURL();
397             }
398             catch (MalformedURLException JavaDoc e) {
399                 return null;
400             }
401         }
402
403         return resourceURL;
404     }
405     
406     /**
407      * Made public so specific implementations can configure handlers relevant
408      * to their own environment. Calls to this are ignored if SOAPHandlers are
409      * already configured.
410      * e.g. in case the config file is located next to the .jws source file in
411      * the context root of an axis webapp rather than in the classpath
412      */

413     public void initHandlersFromChainConfig(URL JavaDoc chainConfigURL, String JavaDoc chainName)
414         throws Exception JavaDoc
415     {
416         // check input parameters
417
if (! getSoapHandlers().isEmpty()) {
418             throw new Exception JavaDoc("@HandlerChain: annotation doesn't allow for @SOAPMessageHandlers");
419         }
420         if (null == chainConfigURL || null == chainName) {
421             throw new Exception JavaDoc("@HandlerChain: URL for handler-chain config required");
422         }
423         
424         // create and configure factory
425
DocumentBuilderFactory JavaDoc factory = DocumentBuilderFactory.newInstance();
426         factory.setNamespaceAware(true);
427         factory.setIgnoringComments(true);
428         
429         // todo: this is broken; validate the document!!!
430

431         NodeList JavaDoc handlerChainNodes = factory.newDocumentBuilder().parse(chainConfigURL.openStream()).getElementsByTagName("handler-chain");
432         for (int j = 0; j < handlerChainNodes.getLength(); j++) {
433             Node JavaDoc handlerChainNode = handlerChainNodes.item(j);
434             if (handlerChainNode.getNodeType() == Node.ELEMENT_NODE) {
435                 Element JavaDoc chainElement = (Element JavaDoc) handlerChainNode;
436                 NodeList JavaDoc chainNames = chainElement.getElementsByTagName("handler-chain-name");
437                 
438                 // should only be one chain name so just grab the first one
439
// todo: this is broken; validate!!!
440
if (chainNames.getLength() > 0 && chainName.equals(chainNames.item(0).getFirstChild().getNodeValue())) {
441                     NodeList JavaDoc handlers = chainElement.getElementsByTagName("handler");
442                     for (int k = 0; k < handlers.getLength(); k++) {
443                         processHandlerNode(handlers.item(k));
444                     }
445                 }
446             }
447         }
448     }
449
450     /**
451      * @param handlerNode
452      * todo: hack: use "endsWith()" to ignore namespace
453      */

454     private void processHandlerNode(Node JavaDoc handlerNode)
455         throws Exception JavaDoc
456     {
457         if (handlerNode.hasChildNodes()) {
458             String JavaDoc handlerName = null;
459             String JavaDoc handlerClassName = null;
460             Map<String JavaDoc, String JavaDoc> initParams = new HashMap<String JavaDoc, String JavaDoc>();
461             Collection<String JavaDoc> roles = new ArrayList<String JavaDoc>();
462             Collection<String JavaDoc> headers = new ArrayList<String JavaDoc>();
463             Node JavaDoc currentChild = handlerNode.getFirstChild();
464             while (currentChild != null) {
465                 String JavaDoc nodeName = currentChild.getNodeName();
466                 if (nodeName.endsWith("handler-name")) {
467                     handlerName = currentChild.getFirstChild().getNodeValue();
468                 }
469                 else if (nodeName.endsWith("handler-class")) {
470                     handlerClassName = currentChild.getFirstChild().getNodeValue();
471                 }
472                 else if (nodeName.endsWith("soap-role")) {
473                     roles.add(currentChild.getFirstChild().getNodeValue());
474                 }
475                 else if (nodeName.endsWith("soap-header")) {
476                     headers.add(currentChild.getFirstChild().getNodeValue());
477                 }
478                 else if (nodeName.endsWith("init-param")) {
479                     nodeName = currentChild.getFirstChild().getNodeName();
480                     if (nodeName.endsWith("param-name")) {
481                         initParams.put(
482                             currentChild.getFirstChild().getNodeValue(),
483                             currentChild.getLastChild().getNodeValue());
484                     }
485                     else if (nodeName.endsWith("param-value")) {
486                         initParams.put(
487                             currentChild.getLastChild().getNodeValue(),
488                             currentChild.getFirstChild().getNodeValue()
489                         );
490                     }
491                 }
492                 currentChild = currentChild.getNextSibling();
493             }
494
495             addSOAPHandler(new SOAPMessageHandlerInfo(
496                     handlerClassName,
497                     handlerName,
498                     initParams,
499                     roles,
500                     headers));
501         }
502     }
503     
504     /**
505      *
506      */

507     public void validate() {
508         // empty
509
}
510
511     /**
512      * @return Returns the hcFileName.
513      */

514     public String JavaDoc getHcFileName() {
515         return hcFileName;
516     }
517
518     /**
519      * @param hcFileName The hcFileName to set.
520      */

521     public void setHcFileName(String JavaDoc hcFileName) {
522         this.hcFileName = hcFileName;
523     }
524
525     /**
526      * @return Returns the hcName.
527      */

528     public String JavaDoc getHcName() {
529         return hcName;
530     }
531
532     /**
533      * @param hcName The hcName to set.
534      */

535     public void setHcName(String JavaDoc hcName) {
536         this.hcName = hcName;
537     }
538
539
540     /**
541      * @return Returns the siRunAs.
542      */

543     public String JavaDoc getSiValue() {
544         return siValue;
545     }
546
547     /**
548      * @param siValue The siRunAs to set.
549      */

550     public void setSiValue(String JavaDoc siValue) {
551         this.siValue = siValue;
552     }
553
554     /**
555      * @return Returns the soapBinding.
556      */

557     public BeehiveWsSOAPBindingInfo getSoapBinding() {
558         if (soapBinding == null) {
559             soapBinding = new SOAPBindingInfo();
560         }
561         return soapBinding;
562     }
563
564     /**
565      * @param soapBinding The soapBinding to set.
566      */

567     public void setSoapBinding(BeehiveWsSOAPBindingInfo soapBinding) {
568         this.soapBinding = soapBinding;
569     }
570
571     /**
572      * @return Returns the wsName.
573      */

574     public String JavaDoc getWsName() {
575         return wsName;
576     }
577
578     /**
579      * @param wsName The wsName to set.
580      */

581     public void setWsName(String JavaDoc wsName) {
582         this.wsName = wsName;
583     }
584
585     /**
586      * @return Returns the wsServiceName.
587      */

588     public String JavaDoc getWsServiceName() {
589         return wsServiceName;
590     }
591
592     /**
593      * @param wsServiceName The wsServiceName to set.
594      */

595     public void setWsServiceName(String JavaDoc wsServiceName) {
596         this.wsServiceName = wsServiceName;
597     }
598
599     /**
600      * @return Returns the wsTargetNamespace.
601      */

602     public String JavaDoc getWsTargetNamespace() {
603         return wsTargetNamespace;
604     }
605
606     /**
607      * @param wsTargetNamespace The wsTargetNamespace to set.
608      */

609     public void setWsTargetNamespace(String JavaDoc wsTargetNamespace) {
610         this.wsTargetNamespace = wsTargetNamespace;
611     }
612
613     
614     public String JavaDoc[] getTargetNamespaceParts() {
615         // strip the "http://" from the targetnamespace
616
String JavaDoc namespace=getWsTargetNamespace().substring(7, getWsTargetNamespace().length());
617          String JavaDoc[] beforeTranspose = namespace.split("[\\./]");
618         String JavaDoc[] res = new String JavaDoc[beforeTranspose.length];
619         for(int i=0; i<res.length; i++)
620             res[i] = beforeTranspose[res.length - i - 1];
621         return res;
622     }
623     
624     /**
625      * @return Returns the wsEndpointInterface.
626      */

627     public String JavaDoc getWsEndpointInterface() {
628         return wsEndpointInterface;
629     }
630
631     /**
632      * @param wsEndpointInterface The wsEndpointInterface to set.
633      */

634     public void setWsEndpointInterface(String JavaDoc wsEndpointInterface) {
635         this.wsEndpointInterface = wsEndpointInterface;
636     }
637
638     /**
639      * @return Returns the wsWsdlLocation.
640      */

641     public String JavaDoc getWsWsdlLocation() {
642         return wsWsdlLocation;
643     }
644
645     /**
646      * @param wsWsdlLocation The wsWsdlLocation to set.
647      */

648     public void setWsWsdlLocation(String JavaDoc wsWsdlLocation) {
649         this.wsWsdlLocation = wsWsdlLocation;
650     }
651
652     /**
653      * @return Returns the methods.
654      */

655     public Collection<BeehiveWsMethodMetadata> getMethods() {
656         if (noDuplicateMethods == null) {
657             noDuplicateMethods = Collections
658                 .unmodifiableSet(new HashSet<BeehiveWsMethodMetadata>
659                                  (methodMap.values()));
660         }
661         return noDuplicateMethods;
662     }
663
664     public BeehiveWsMethodMetadata getMethod(String JavaDoc methodName,
665                                           Class JavaDoc... paramTypes) {
666         String JavaDoc sig = createCompleteMethodSignature(methodName, paramTypes);
667         
668         BeehiveWsMethodMetadata meta = methodMap.get(sig);
669         if (meta == null) {
670             /*
671              * NOTE jcolwell@bea.com 2004-Nov-29 --
672              * this fallback may be a bad thing but it is nice to have if the
673              * WSDLProcessor cannot map the Java types properly when used on the
674              * client side.
675              */

676             meta = methodMap.get(methodName + '('+ paramTypes.length + ')');
677         }
678         return meta;
679     }
680
681     public void addMethod(BeehiveWsMethodMetadata method)
682         throws ValidationException {
683
684         // NOTE jcolwell@bea.com 2004-Nov-29 -- clear the Set that prevents
685
// duplicates being returned from getMethods().
686
noDuplicateMethods = null;
687         List JavaDoc<? extends BeehiveWsParameterMetadata> params = method.getParams();
688         Class JavaDoc[] paramTypes = new Class JavaDoc[params.size()];
689         int j = 0;
690         for (BeehiveWsParameterMetadata param : params) {
691             Class JavaDoc javaType = param.getJavaType();
692             if (null == javaType) {
693                 throw new ValidationException("<null> is not a valid parameter class");
694             }
695             paramTypes[j++] = javaType;
696         }
697         String JavaDoc opName = method.getWmOperationName();
698         String JavaDoc sig = createCompleteMethodSignature(opName, paramTypes);
699         
700         if (methodMap.containsKey(sig)) {
701             throw new ValidationException(sig + " is already present in this Web Service and duplicate methods are not permitted");
702         }
703         else if (SOAPBinding.Style.DOCUMENT.equals(getSoapBinding().getStyle()) && methodMap.containsKey(opName)) {
704             throw new ValidationException("document-style does not allow duplicate methods: " + opName);
705         }
706         else {
707             methodMap.put(sig, method);
708             methodMap.put(opName + '(' + paramTypes.length + ')', method);
709         }
710     }
711
712     public List JavaDoc<? extends BeehiveWsSOAPMessageHandlerInfo> getSoapHandlers() {
713         return Collections.unmodifiableList(soapHandlers);
714     }
715
716     public void addSOAPHandler(BeehiveWsSOAPMessageHandlerInfo soapHandler) {
717         soapHandlers.add(soapHandler);
718     }
719
720     public String JavaDoc getClassName() {
721         return className;
722     }
723
724     public void setClassName(String JavaDoc className) {
725         this.className = className;
726     }
727
728     private String JavaDoc getTargetNamespace(String JavaDoc fqClassName) {
729         if ((null == fqClassName) || (0 == fqClassName.length())) {
730             return fqClassName;
731         }
732         String JavaDoc[] tokens = fqClassName.split("\\.");
733         String JavaDoc targetNamespace = tokens[0];
734         for (int i = 1; i <= tokens.length - 2; i++) {
735             targetNamespace = tokens[i] + "." + targetNamespace;
736         }
737         return "http://" + targetNamespace;
738     }
739
740     // todo: this needs to go, as it should really be in Jsr181MethodMetadataImpl!!!
741
private String JavaDoc createCompleteMethodSignature(String JavaDoc name,
742                                                  Class JavaDoc... paramTypes) {
743
744         StringBuilder JavaDoc sb = new StringBuilder JavaDoc(name);
745         sb.append('(');
746         boolean firstParam = true;
747         if (paramTypes != null) {
748             for (Class JavaDoc type : paramTypes) {
749                 if (firstParam) {
750                     firstParam = false;
751                 }
752                 else {
753                     sb.append(',');
754                 }
755                 sb.append(type.getName());
756             }
757         }
758         sb.append(')');
759         return sb.toString();
760     }
761
762     /**
763      * @param jt SIB type info.
764      * @throws Exception
765      */

766     public void merge(JavaTypeInfo jt) throws Exception JavaDoc {
767         
768         // check if this has endpointInterface --> error
769
String JavaDoc myEndpointInterface = getWsEndpointInterface();
770         if (null != myEndpointInterface && 0 < myEndpointInterface.length())
771             throw new ValidationException("service endpoint interface can't reference another service endpoint interface: " + myEndpointInterface);
772         
773         // check if objectModel doesn't reference this endpointInterface --> error
774
BeehiveWsTypeMetadata sibObjectModel = new Jsr181TypeMetadataImpl(jt);
775         String JavaDoc omEndpointInterface = sibObjectModel.getWsEndpointInterface();
776         if (null == omEndpointInterface || 0 >= omEndpointInterface.length() || ! omEndpointInterface.equals(getClassName()))
777             throw new Exception JavaDoc("Internal error: object model for " + sibObjectModel.getClassName() + " does not reference endpoint interface "+ omEndpointInterface);
778
779         // check if objectModel.wsWsdlLocation != null --> error
780
if (null != sibObjectModel.getWsWsdlLocation() && 0 < sibObjectModel.getWsWsdlLocation().length()) {
781             throw new Exception JavaDoc("implementation bean must not reference a service endpoint interface and a WSDL location at the same time");
782         }
783         
784         setWsServiceName(sibObjectModel.getWsServiceName());
785         setWsEndpointInterface(sibObjectModel.getWsEndpointInterface());
786         
787         setClassName(sibObjectModel.getClassName());
788         
789         // check if jt implements the contract
790
validateContract(jt);
791     }
792
793     /**
794      * Checks if "jt" implements "this".
795      * @param jt SIB type info.
796      * @throws ValidationException
797      */

798     protected void validateContract(JavaTypeInfo jt) throws ValidationException {
799         
800         // get all implemented methods
801
Collection<BeehiveWsMethodMetadata> implementedMethods = new HashSet<BeehiveWsMethodMetadata>();
802         for (JavaMethodInfo jm : jt.getMethods()) {
803             try {
804                 implementedMethods.add(new Jsr181MethodMetadataImpl(jm));
805             }
806             catch (Throwable JavaDoc t) {
807                 throw new ValidationException("invalid method declaration found: " + jt.getName() + ": " + jm.getMethodName());
808             }
809         }
810         
811         // check if we implement all required methods
812
for (BeehiveWsMethodMetadata declaredMethod : getMethods()) {
813             boolean implementationFound = false;
814             for (BeehiveWsMethodMetadata implementedMethod : implementedMethods) {
815                 if (implementedMethod.equals(declaredMethod)) {
816                     implementationFound = true;
817                     break;
818                 }
819             }
820             if (! implementationFound) {
821                 throw new ValidationException("method not implemented by " + jt.getName() + ": " + declaredMethod);
822             }
823         }
824     }
825 }
826
Popular Tags