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> が指定されたものとしてAxisエンジンを決定します。</dd>
    181      * <dt><code>"default"</code></dt>
    182      * <dd>コンテナにサーブレットコンテキストが設定されていれば <code>"default-server"</code> 、そうでなければ
    183      * <code>"default-client"</code> が指定されたものとしてAxisエンジンを決定します。</dd>
    184      * <dt><code>"default-client"</code></dt>
    185      * <dd>コンテナから <code>javax.xml.rpc.Service</code>
    186      * を実装したコンポーネントを取得し、そのエンジンを使用します。</dd>
    187      * <dt><code>"default-server"</code></dt>
    188      * <dd>サーブレットコンテキストに設定されているAxisエンジンを使用します。 <br>
    189      * 最初に {@link S2AxisConstants#AXIS_SERVLET}と
    190      * {@link S2AxisConstants#ATTR_AXIS_ENGINE}を連結した文字列をキーとして
    191      * サーブレットコンテキストからAxisエンジンを取得します。 <br>
    192      * 見つからなかった場合は{S2AxisConstants#ATTR_AXIS_ENGINE}を
    193      * キーとしてサーブレットコンテキストから取得したAxisエンジンを取得します。 <br>
    194      * </dd>
    195      * <dt><code>"servlet:"</code> で始まる文字列</dt>
    196      * <dd><code>"servlet:"</code> の後ろの文字列をキーとしてサーブレットコンテキストから
    197      * 取得したAxisエンジンを使用します。
    198      * <dd>
    199      * <dt><code>"s2:"</code> で始まる文字列</dt>
    200      * <dd><code>"s2:"</code> の後ろの文字列をキーとしてS2コンテナから
    201      * 取得したコンポーネントをAxisエンジンを使用します。</dd>
    202      * <dt>その他</dt>
    203      * <dd>キーとしてS2コンテナから取得したコンポーネントをAxisエンジンとして使用します。</dd>
    204      * </dl>
    205      *
    206      * @param container
    207      *            コンテナ
    208      * @return Axisエンジン
    209      */
    210     protected AxisEngine getEngine(final S2Container container) {
    211         String engineName = S2AxisConstants.ENGINE_DEFAULT;
    212
    213         final MetaDef metadata = container.getMetaDef(S2AxisConstants.META_S2AXIS_ENGINE);
    214         if (metadata != null) {
    215             engineName = (String) metadata.getValue();
    216         }
    217
    218         if (S2AxisConstants.ENGINE_DEFAULT.equals(engineName)) {
    219             if (servletContext == null) {
    220                 engineName = S2AxisConstants.ENGINE_DEFAULT_CLIENT;
    221             }
    222             else {
    223                 engineName = S2AxisConstants.ENGINE_DEFAULT_SERVER;
    224             }
    225         }
    226
    227         AxisEngine engine = null;
    228         if (S2AxisConstants.ENGINE_DEFAULT_CLIENT.equals(engineName)) {
    229             final Service service = (Service) container.getComponent(javax.xml.rpc.Service.class);
    230             engine = service.getEngine();
    231         }
    232         else if (S2AxisConstants.ENGINE_DEFAULT_SERVER.equals(engineName)) {
    233             engine = (AxisEngine) servletContext.getAttribute(S2AxisConstants.AXIS_SERVLET
    234                     + S2AxisConstants.ATTR_AXIS_ENGINE);
    235             if (engine == null) {
    236                 engine = (AxisEngine) servletContext.getAttribute(S2AxisConstants.ATTR_AXIS_ENGINE);
    237             }
    238         }
    239         else if (engineName.startsWith(S2AxisConstants.ENGINE_FROM_SERVLET)) {
    240             final String servletName = engineName.substring(S2AxisConstants.ENGINE_FROM_SERVLET
    241                     .length());
    242             engine = (AxisEngine) servletContext.getAttribute(servletName
    243                     + S2AxisConstants.ATTR_AXIS_ENGINE);
    244         }
    245         else if (engineName.startsWith(S2AxisConstants.ENGINE_FROM_S2CONTAINER)) {
    246             final String componentName = engineName
    247                     .substring(S2AxisConstants.ENGINE_FROM_S2CONTAINER.length());
    248             engine = (AxisEngine) container.getComponent(componentName);
    249         }
    250         else {
    251             engine = (AxisEngine) container.getComponent(engineName);
    252         }
    253
    254         if (engine == null) {
    255             throw new DeployFailedException(MessageFormatter.getSimpleMessage("EAXS0007", null));
    256         }
    257         return engine;
    258     }
    259 }