View Javadoc

1   /*
2    *
3    * The Seasar Software License, Version 1.1
4    *
5    * Copyright (c) 2003-2004 The Seasar Project. All rights reserved.
6    *
7    * Redistribution and use in source and binary forms, with or
8    * without modification, are permitted provided that the following
9    * conditions are met:
10   *
11   * 1. Redistributions of source code must retain the above
12   *    copyright notice, this list of conditions and the following
13   *    disclaimer.
14   *
15   * 2. Redistributions in binary form must reproduce the above
16   *    copyright notice, this list of conditions and the following
17   *    disclaimer in the documentation and/or other materials provided
18   *    with the distribution.
19   *
20   * 3. The end-user documentation included with the redistribution,
21   *    if any, must include the following acknowledgement:
22   *    "This product includes software developed by the
23   *    Seasar Project (http://www.seasar.org/)."
24   *    Alternately, this acknowledgement may appear in the software
25   *    itself, if and wherever such third-party acknowledgements
26   *    normally appear.
27   *
28   * 4. Neither the name "The Seasar Project" nor the names of its
29   *    contributors may be used to endorse or promote products derived
30   *    from this software without specific prior written permission of
31   *    the Seasar Project.
32   *
33   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR
34   * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
35   * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
36   * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE SEASAR PROJECT
37   * OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
38   * INCIDENTAL,SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
39   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
40   * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
41   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
42   * WHETHER IN CONTRACT, STRICT LIABILITY,OR TORT (INCLUDING
43   * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
44   * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
45   */
46  package org.seasar.remoting.axis.deployment;
47  
48  import java.util.HashMap;
49  import java.util.Iterator;
50  import java.util.Map;
51  
52  import javax.xml.namespace.QName;
53  
54  import org.apache.axis.Constants;
55  import org.apache.axis.deployment.wsdd.WSDDConstants;
56  import org.apache.axis.deployment.wsdd.WSDDException;
57  import org.apache.axis.deployment.wsdd.WSDDService;
58  import org.apache.axis.deployment.wsdd.WSDDTypeMapping;
59  import org.apache.axis.description.JavaServiceDesc;
60  import org.apache.axis.encoding.TypeMappingRegistry;
61  import org.apache.axis.providers.java.JavaProvider;
62  import org.apache.axis.wsdl.fromJava.Namespaces;
63  import org.apache.axis.wsdl.fromJava.Types;
64  import org.seasar.framework.container.ComponentDef;
65  import org.seasar.framework.message.MessageFormatter;
66  import org.seasar.framework.util.StringUtil;
67  import org.seasar.remoting.axis.S2AxisConstants;
68  import org.seasar.remoting.axis.ServiceDef;
69  import org.seasar.remoting.axis.TypeMappingDef;
70  import org.seasar.remoting.axis.encoding.AutoRegisterTypeMappingImpl;
71  import org.w3c.dom.Element;
72  
73  /***
74   * S2によりインスタンス管理されるサービスのWSDDによる表現です。
75   * 
76   * @author koichik
77   */
78  public class WSDDS2Service extends WSDDService {
79      //static fields
80      protected static final Map providerMapping = new HashMap();
81      static {
82          providerMapping.put(PROVIDER_RPC, S2AxisConstants.PROVIDER_S2RPC);
83          providerMapping.put(PROVIDER_RPC, S2AxisConstants.PROVIDER_S2RPC);
84      }
85  
86      //instance fields
87      protected ComponentDef componentDef;
88  
89      /***
90       * コンポーネント定義からインスタンスを構築します。
91       * 
92       * @param componentDef
93       *            コンポーネント定義
94       * @throws WSDDException
95       *             インスタンスの構築に失敗した場合にスローされます。
96       */
97      public WSDDS2Service(final ComponentDef componentDef) throws WSDDException {
98          this(componentDef, new ServiceDef());
99      }
100 
101     /***
102      * コンポーネント定義とサービス定義からインスタンスを構築します。
103      * 
104      * @param componentDef
105      *            コンポーネント定義
106      * @param serviceDef
107      *            サービス定義
108      * @throws WSDDException
109      *             インスタンスの構築に失敗した場合にスローされます。
110      */
111     public WSDDS2Service(final ComponentDef componentDef, final ServiceDef serviceDef)
112             throws WSDDException {
113         this.componentDef = componentDef;
114 
115         final String name = getName();
116         setQName(new QName(name));
117 
118         final JavaServiceDesc serviceDesc = (JavaServiceDesc) getServiceDesc();
119         serviceDesc.setName(name);
120 
121         Class serviceType = serviceDef.getServiceType();
122         if (serviceType == null) {
123             serviceType = componentDef.getComponentClass();
124         }
125         if (serviceType == null) {
126             throw new WSDDException(MessageFormatter.getSimpleMessage("EAXS0006",
127                     new Object[] { name }));
128         }
129         setParameter(JavaProvider.OPTION_CLASSNAME, serviceType.getName());
130 
131         setProviderQName(new QName(WSDDConstants.URI_WSDD_JAVA, getS2Provider(serviceDef
132                 .getProvider())));
133 
134         final String allowedMethods = serviceDef.getAllowedMethods();
135         if (!StringUtil.isEmpty(allowedMethods)) {
136             setParameter(JavaProvider.OPTION_ALLOWEDMETHODS, allowedMethods);
137         }
138 
139         final Iterator typeMappingDefs = serviceDef.getTypeMappings();
140         while (typeMappingDefs.hasNext()) {
141             final TypeMappingDef typeMappingDef = (TypeMappingDef) typeMappingDefs.next();
142             addTypeMapping(createWSDDTypeMapping(typeMappingDef));
143         }
144 
145         initTMR();
146         validateDescriptors();
147 
148         final TypeMappingRegistry tmr = serviceDesc.getTypeMappingRegistry();
149         final AutoRegisterTypeMappingImpl autoTM = new AutoRegisterTypeMappingImpl(null);
150         tmr.register(getUse().getEncoding(), autoTM);
151         serviceDesc.setTypeMapping(autoTM);
152     }
153 
154     /***
155      * コンポーネント定義とWSDDファイル(XML)のDOMツリーからインスタンスを構築します。 <br>
156      * WSDD中の <code>&lt;service&gt;</code> 要素の <code>provider</code>
157      * 属性で指定されたプロバイダを対応するS2Axisのプロバイダに変更します。
158      * 
159      * @param componentDef
160      *            コンポーネント定義
161      * @param serviceElement
162      *            WSDDファイル(XML)のDOMツリー
163      * @throws WSDDException
164      *             インスタンスの構築に失敗した場合にスローされます。
165      */
166     public WSDDS2Service(final ComponentDef componentDef, final Element serviceElement)
167             throws WSDDException {
168         super(serviceElement);
169         this.componentDef = componentDef;
170         final String provider = getProviderQName().getLocalPart();
171         setProviderQName(new QName(WSDDConstants.URI_WSDD_JAVA, getS2Provider(provider)));
172     }
173 
174     /***
175      * コンポーネント定義を返します。
176      * 
177      * @return コンポーネント定義
178      */
179     public ComponentDef getComponentDef() {
180         return componentDef;
181     }
182 
183     /***
184      * サービス名を返します。 <br>
185      * サービス名は、コンポーネント定義に名前空間が指定されていれば"名前空間/コンポーネント名"、そうでなければ"コンポーネント名"になります。
186      * 
187      * @return サービス名
188      */
189     protected String getName() {
190         final String namespace = componentDef.getContainer().getNamespace();
191         final String componentName = componentDef.getComponentName();
192         if (StringUtil.isEmpty(namespace)) {
193             return componentName;
194         }
195         return namespace + "/" + componentName;
196     }
197 
198     /***
199      * サービスの型を返します。 <br>
200      * サービスの型は、サービス定義に型が指定されていればその型、そうでなければコンポーネントの型になります。
201      * 
202      * @param serviceDef
203      *            サービス定義
204      * @return サービスの型
205      */
206     protected Class getServiceClass(final ServiceDef serviceDef) {
207         Class serviceType = null;
208         serviceType = serviceDef.getServiceType();
209         if (serviceType == null) {
210             serviceType = componentDef.getComponentClass();
211         }
212         if (serviceType == null) {
213             componentDef.getComponent().getClass();
214         }
215         return serviceType;
216     }
217 
218     /***
219      * Axisのプロバイダ名に対応するS2Axis用のプロバイダ名を返します。
220      * 
221      * @param provider
222      *            Axis標準のプロバイダ名
223      * @return S2Axis用のプロバイダ名
224      * @throws WSDDException
225      *             Axisのプロバイダ名対応するS2Axisのプロバイダがない場合にスローされます
226      */
227     protected String getS2Provider(final String provider) throws WSDDException {
228         final String s2Provider = (String) providerMapping.get(provider);
229         if (s2Provider == null) {
230             throw new WSDDException(provider);
231         }
232         return s2Provider;
233     }
234 
235     /***
236      * WSDDタイプマッピングを作成して返します。
237      * 
238      * @param typeMappingDef
239      *            タイプマッピング定義
240      * @return WSDDタイプマッピング
241      */
242     protected WSDDTypeMapping createWSDDTypeMapping(final TypeMappingDef typeMappingDef) {
243         final WSDDTypeMapping wsddTypeMapping = new WSDDTypeMapping();
244 
245         final Class type = typeMappingDef.getType();
246         wsddTypeMapping.setLanguageSpecificType(typeMappingDef.getType());
247 
248         wsddTypeMapping.setQName(createQNameOfType(type, typeMappingDef.getNamespaceURI(),
249                 typeMappingDef.getLocalPart(), typeMappingDef.getNamespacePrefix()));
250 
251         if (typeMappingDef.getSerializer() != null) {
252             wsddTypeMapping.setSerializer(typeMappingDef.getSerializer());
253         }
254         if (typeMappingDef.getDeserializer() != null) {
255             wsddTypeMapping.setDeserializer(typeMappingDef.getDeserializer());
256         }
257 
258         if (typeMappingDef.getEncodingStyle() == null) {
259             wsddTypeMapping.setEncodingStyle(Constants.URI_DEFAULT_SOAP_ENC);
260         }
261         else {
262             wsddTypeMapping.setEncodingStyle(typeMappingDef.getEncodingStyle());
263         }
264 
265         return wsddTypeMapping;
266     }
267 
268     /***
269      * XML型のQNameを作成して返します。
270      * 
271      * @param type
272      *            Java型
273      * @param namespaceURI
274      *            XML型の名前空間URI。省略するとJava型のパッケージ名から導出されます
275      * @param localPart
276      *            XML型のローカル名。省略するとJava型のクラス名が使われます
277      * @param namespacePrefix
278      *            XML型の名前空間接頭辞。省略するとデフォルト名前空間になります
279      * @return XML型のQName
280      */
281     protected QName createQNameOfType(final Class type, String namespaceURI, String localPart,
282             final String namespacePrefix) {
283         if (StringUtil.isEmpty(namespaceURI)) {
284             namespaceURI = Namespaces.makeNamespace(type.getName());
285         }
286 
287         if (StringUtil.isEmpty(localPart)) {
288             localPart = Types.getLocalNameFromFullName(type.getName());
289         }
290 
291         return new QName(namespaceURI, localPart, namespacePrefix);
292     }
293 }