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.deployer;
47  
48  import javax.servlet.ServletContext;
49  
50  import org.apache.axis.AxisEngine;
51  import org.apache.axis.WSDDEngineConfiguration;
52  import org.apache.axis.client.Service;
53  import org.apache.axis.deployment.wsdd.WSDDDeployment;
54  import org.seasar.framework.container.ComponentDef;
55  import org.seasar.framework.container.MetaDef;
56  import org.seasar.framework.container.S2Container;
57  import org.seasar.framework.message.MessageFormatter;
58  import org.seasar.remoting.axis.DeployFailedException;
59  import org.seasar.remoting.axis.S2AxisConstants;
60  import org.seasar.remoting.common.deployer.Deployer;
61  
62  /***
63   * diconファイル中に記述されたコンポーネントをAxisにデプロイします。
64   * 
65   * @author koichik
66   */
67  public class AxisDeployer implements Deployer {
68      //instance fields
69      protected S2Container container;
70      protected ServletContext servletContext;
71  
72      protected ItemDeployer serviceDeployer = new ServiceDeployer(this);
73      protected ItemDeployer handlerDeployer = new HandlerDeployer(this);
74      protected ItemDeployer wsddDeployer = new WSDDDeployer(this);
75  
76      /***
77       * S2コンテナを設定します。
78       * 
79       * @param container
80       *            S2コンテナ
81       */
82      public void setContainer(final S2Container container) {
83          this.container = container;
84      }
85  
86      /***
87       * サーブレットコンテキストを設定します。
88       * 
89       * @param servletContext
90       *            サーブレットコンテキスト
91       */
92      public void setServletContext(final ServletContext servletContext) {
93          this.servletContext = servletContext;
94      }
95  
96      /***
97       * コンテナに登録されているサービスやハンドラをデプロイします。
98       */
99      public void deploy() {
100         forEach(container.getRoot());
101     }
102 
103     /***
104      * コンテナの階層をたどって全てのコンテナとコンポーネント定義を走査します。 <br>
105      * 走査する順序は次の通りです。
106      * <ol>
107      * <li>コンテナ自身</li>
108      * <li>子のコンポーネント定義</li>
109      * <li>子のコンテナを再起的に</li>
110      * </ol>
111      * 
112      * @param container
113      *            起点となるコンテナ
114      */
115     protected void forEach(final S2Container container) {
116         process(container);
117 
118         final int componentDefSize = container.getComponentDefSize();
119         for (int i = 0; i < componentDefSize; ++i) {
120             process(container.getComponentDef(i));
121         }
122 
123         final int childContainerSize = container.getChildSize();
124         for (int i = 0; i < childContainerSize; ++i) {
125             forEach(container.getChild(i));
126         }
127     }
128 
129     /***
130      * S2コンテナにS2Axisのメタデータ <code>&lt;meta name="s2axis:deploy"&gt;</code>
131      * が指定されていれば、そのWSDDをAxisにデプロイします。
132      * 
133      * @param container
134      *            S2コンテナ
135      */
136     protected void process(final S2Container container) {
137         final MetaDef[] metaDefs = container.getMetaDefs(S2AxisConstants.META_S2AXIS_DEPLOY);
138         for (int i = 0; metaDefs != null && i < metaDefs.length; ++i) {
139             wsddDeployer.deploy(null, metaDefs[i]);
140         }
141     }
142 
143     /***
144      * コンポーネント定義にS2Axisのメタデータ <code>&lt;meta name="s2axis:service"&gt;</code>
145      * または <code>&lt;meta name="s2axis:handler"&gt;</code>
146      * が指定されていれば、そのコンポーネントをサービスまたはハンドラとしてAxisにデプロイします。
147      * 
148      * @param componentDef
149      *            コンポーネント定義
150      */
151     protected void process(final ComponentDef componentDef) {
152         final MetaDef serviceMetaDef = componentDef.getMetaDef(S2AxisConstants.META_S2AXIS_SERVICE);
153         if (serviceMetaDef != null) {
154             serviceDeployer.deploy(componentDef, serviceMetaDef);
155         }
156 
157         final MetaDef handlerMetaDef = componentDef.getMetaDef(S2AxisConstants.META_S2AXIS_HANDLER);
158         if (handlerMetaDef != null) {
159             handlerDeployer.deploy(componentDef, handlerMetaDef);
160         }
161     }
162 
163     /***
164      * WSDDデプロイメントを返します。
165      * 
166      * @param container
167      *            コンテナ
168      * @return WSDDデプロイメント
169      */
170     protected WSDDDeployment getDeployment(final S2Container container) {
171         return ((WSDDEngineConfiguration) getEngine(container).getConfig()).getDeployment();
172     }
173 
174     /***
175      * Axisエンジンを返します。 <br>
176      * Axisエンジンは、コンテナに名前 <code>s2-axis:engine</code> を持つ
177      * <code>&lt;meta&gt;</code> 要素が指定されていれば、その内容文字列から次のように決定されます。
178      * <dl>
179      * <dt>未定義の場合</dt>
180      * <dd><code>"default"</code> が指定されたものとしてエンジンを決定します。</dd>
181      * <dt><code>"default"</code></dt>
182      * <dd>コンテナに <code>javax.servlet.ServletContext</code> が設定されていれば
183      * <code>"default-server"</code> 、そうでなければ <code>"default-client"</code>
184      * が指定されたものとしてエンジンを決定します。</dd>
185      * <dt><code>"default-client"</code></dt>
186      * <dd>コンテナから <code>javax.xml.rpc.Service</code>
187      * を実装したコンポーネントを取得し、そのエンジンを使用します。</dd>
188      * <dt><code>"default-server"</code></dt>
189      * <dd><code>javax.servlet.ServletContext</code> に設定されているエンジンを使用します。
190      * </dd>
191      * <dt>その他</dt>
192      * <dd>内容文字列を名前として持つコンポーネントをエンジンとして使用します。</dd>
193      * </dl>
194      * 
195      * @param container
196      *            コンテナ
197      * @return Axisエンジン
198      */
199     protected AxisEngine getEngine(final S2Container container) {
200         String engineName = S2AxisConstants.ENGINE_DEFAULT;
201 
202         final MetaDef metadata = container.getMetaDef(S2AxisConstants.META_S2AXIS_ENGINE);
203         if (metadata != null) {
204             engineName = (String) metadata.getValue();
205         }
206 
207         if (S2AxisConstants.ENGINE_DEFAULT.equals(engineName)) {
208             if (servletContext == null) {
209                 engineName = S2AxisConstants.ENGINE_DEFAULT_CLIENT;
210             }
211             else {
212                 engineName = S2AxisConstants.ENGINE_DEFAULT_SERVER;
213             }
214         }
215 
216         AxisEngine engine = null;
217         if (S2AxisConstants.ENGINE_DEFAULT_CLIENT.equals(engineName)) {
218             final Service service = (Service) container.getComponent(javax.xml.rpc.Service.class);
219             engine = service.getEngine();
220         }
221         else if (S2AxisConstants.ENGINE_DEFAULT_SERVER.equals(engineName)) {
222             engine = (AxisEngine) servletContext.getAttribute(S2AxisConstants.ATTR_AXIS_ENGINE);
223         }
224         else {
225             engine = (AxisEngine) container.getComponent(engineName);
226         }
227 
228         if (engine == null) {
229             throw new DeployFailedException(MessageFormatter.getSimpleMessage("EAXS0007", null));
230         }
231         return engine;
232     }
233 }