Package org.apache.axis2.description

Source Code of org.apache.axis2.description.AxisDescription

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

package org.apache.axis2.description;

import edu.emory.mathcs.backport.java.util.concurrent.ConcurrentHashMap;
import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.OMNode;
import org.apache.axiom.om.OMText;
import org.apache.axis2.AxisFault;
import org.apache.axis2.engine.AxisConfiguration;
import org.apache.axis2.i18n.Messages;
import org.apache.axis2.modules.Module;
import org.apache.axis2.util.JavaUtils;
import org.apache.axis2.util.Utils;
import org.apache.axis2.wsdl.WSDLConstants;
import org.apache.axis2.wsdl.WSDLUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.neethi.Assertion;
import org.apache.neethi.Policy;

import javax.xml.stream.XMLStreamException;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

public abstract class AxisDescription implements ParameterInclude,
    DescriptionConstants {

  protected AxisDescription parent = null;

  private ParameterInclude parameterInclude;

  private PolicyInclude policyInclude = null;


  private PolicySubject policySubject = null;

  private Map children;

  protected Map engagedModules;

  /** List of ParameterObservers who want to be notified of changes */
  protected List parameterObservers = null;

  private OMFactory omFactory = OMAbstractFactory.getOMFactory();

  // Holds the documentation details for each element
  private OMNode documentation;

  // creating a logger instance
  private static Log log = LogFactory.getLog(AxisDescription.class);

    public AxisDescription() {
        parameterInclude = new ParameterIncludeImpl();
        children = new ConcurrentHashMap();
        policySubject = new PolicySubject();
    }

  public void addParameterObserver(ParameterObserver observer) {
    if (parameterObservers == null)
      parameterObservers = new ArrayList();
    parameterObservers.add(observer);
  }

  public void removeParameterObserver(ParameterObserver observer) {
    if (parameterObservers != null) {
      parameterObservers.remove(observer);
    }
  }

  public void addParameter(Parameter param) throws AxisFault {
    if (param == null) {
      return;
    }

    if (isParameterLocked(param.getName())) {
      throw new AxisFault(Messages.getMessage("paramterlockedbyparent",
          param.getName()));
    }

    parameterInclude.addParameter(param);

    // Tell anyone who wants to know
    if (parameterObservers != null) {
      for (Iterator i = parameterObservers.iterator(); i.hasNext();) {
        ParameterObserver observer = (ParameterObserver) i.next();
        observer.parameterChanged(param.getName(), param.getValue());
      }
    }
  }

  public void addParameter(String name, Object value) throws AxisFault {
    addParameter(new Parameter(name, value));
  }

  public void removeParameter(Parameter param) throws AxisFault {
    parameterInclude.removeParameter(param);
  }

  public void deserializeParameters(OMElement parameterElement)
      throws AxisFault {

    parameterInclude.deserializeParameters(parameterElement);

  }

  /**
   * If the parameter found in the current decription then the paremeter will
   * be writable else it will be read only
   *
   * @param name
   * @return
   */
  public Parameter getParameter(String name) {
    Parameter parameter = parameterInclude.getParameter(name);
    if (parameter != null) {
      parameter.setEditable(true);
      return parameter;
    }
    if (parent != null) {
      parameter = parent.getParameter(name);
      if (parameter != null) {
        parameter.setEditable(false);
      }
      return parameter;
    }
    return null;
  }

  public Object getParameterValue(String name) {
    Parameter param = getParameter(name);
    if (param == null) {
      return null;
    }
    return param.getValue();
  }

  public boolean isParameterTrue(String name) {
    Parameter param = getParameter(name);
    return param != null && JavaUtils.isTrue(param.getValue());
  }

  public ArrayList getParameters() {
    return parameterInclude.getParameters();
  }

  public boolean isParameterLocked(String parameterName) {

    if (this.parent != null && this.parent.isParameterLocked(parameterName)) {
      return true;
    }

    Parameter parameter = getParameter(parameterName);
    return parameter != null && parameter.isLocked();
  }

  public String getDocumentation() {
    if (documentation != null) {
      if (documentation.getType() == OMNode.TEXT_NODE) {
        return ((OMText) documentation).getText();
      } else {
        StringWriter writer = new StringWriter();
        documentation.build();
        try {
          documentation.serialize(writer);
        } catch (XMLStreamException e) {
          log.error(e);
        }
        writer.flush();
        return writer.toString();
      }
    }
    return null;
  }

  public OMNode getDocumentationNode() {
    return documentation;
  }

  public void setDocumentation(OMNode documentation) {
    this.documentation = documentation;
  }

  public void setDocumentation(String documentation) {
    if (!"".equals(documentation)) {
      this.documentation = omFactory.createOMText(documentation);
    }
  }

  public void setParent(AxisDescription parent) {
    this.parent = parent;
  }

  public AxisDescription getParent() {
    return parent;
  }

  /**
   * @see org.apache.axis2.description.AxisDescription#setPolicyInclude(PolicyInclude)
   * @deprecated As of release 1.4, if you want to access the policy cache of
   *             a particular AxisDescription object use
   *             {@line #getPolicySubject()} instead.
   *
   * @param policyInclude
   */
  public void setPolicyInclude(PolicyInclude policyInclude) {
    this.policyInclude = policyInclude;
  }


  /**
   * @see org.apache.axis2.description.AxisDescription#getPolicySubject()
   * @deprecated As of release 1.4, replaced by {@link #getPolicySubject()}
   */
  public PolicyInclude getPolicyInclude() {
    if (policyInclude == null) {
      policyInclude = new PolicyInclude(this);
    }
    return policyInclude;
  }


    // NOTE - These are NOT typesafe!
    public void addChild(AxisDescription child) {
        if (child.getKey() == null) {
        // FIXME: Several classes that extend AxisDescription pass null in their getKey method.   
//            throw new IllegalArgumentException("Please specify a key in the child");
        } else {
            children.put(child.getKey(), child);
        }
    }



  public void addChild(Object key, AxisDescription child) {
    children.put(key, child);
  }

  public Iterator getChildren() {
    return children.values().iterator();
  }

    public AxisDescription getChild(Object key) {
        if(key == null) {
            // FIXME: Why are folks sending in null?
            return null;
        }
        return (AxisDescription) children.get(key);
    }

  public void removeChild(Object key) {
    children.remove(key);
  }

  /**
   * This method sets the policy as the default of this AxisDescription
   * instance. Further more this method does the followings. <p/> (1) Engage
   * whatever modules necessary to execute new the effective policy of this
   * AxisDescription instance. (2) Disengage whatever modules that are not
   * necessary to execute the new effective policy of this AxisDescription
   * instance. (3) Check whether each module can execute the new effective
   * policy of this AxisDescription instance. (4) If not throw an AxisFault to
   * notify the user. (5) Else notify each module about the new effective
   * policy.
   *
   * @param policy
   *            the new policy of this AxisDescription instance. The effective
   *            policy is the merge of this argument with effective policy of
   *            parent of this AxisDescription.
   * @throws AxisFault
   *             if any module is unable to execute the effective policy of
   *             this AxisDescription instance successfully or no module to
   *             execute some portion (one or more PrimtiveAssertions ) of
   *             that effective policy.
   */
  public void applyPolicy(Policy policy) throws AxisFault {
    // sets AxisDescription policy
    getPolicySubject().clear();
    getPolicySubject().attachPolicy(policy);

    /*
     * now we try to engage appropriate modules based on the merged policy
     * of axis description object and the corresponding axis binding
     * description object.
     */
    applyPolicy();
  }

  /**
   * Applies the policies on the Description Hierarchy recursively.
   *
   * @throws AxisFault
   *             an error occurred applying the policy
   */
  public void applyPolicy() throws AxisFault {
    AxisConfiguration configuration = getAxisConfiguration();
    if (configuration == null) {
      return;
    }

    Policy applicablePolicy = getApplicablePolicy(this);
    if (applicablePolicy != null) {
      engageModulesForPolicy(this, applicablePolicy, configuration);
    }

    for (Iterator children = getChildren(); children.hasNext();) {
      AxisDescription child = (AxisDescription) children.next();
      child.applyPolicy();
    }
  }

  private boolean canSupportAssertion(Assertion assertion, List moduleList) {

    AxisModule axisModule;
    Module module;

    for (Iterator iterator = moduleList.iterator(); iterator.hasNext();) {
      axisModule = (AxisModule) iterator.next();
      // FIXME is this step really needed ??
      // Shouldn't axisMoudle.getModule always return not-null value ??
      module = axisModule.getModule();

      if (!(module == null || module.canSupportAssertion(assertion))) {
        log.debug(axisModule.getName() + " says it can't support "
            + assertion.getName());
        return false;
      }
    }

    return true;
  }
 
  private void engageModulesForPolicy(AxisDescription axisDescription,
      Policy policy, AxisConfiguration axisConfiguration)
      throws AxisFault {
    /*
     * for the moment we consider policies with only one alternative. If the
     * policy contains multiple alternatives only the first alternative will
     * be considered.
     */
    Iterator iterator = policy.getAlternatives();
    if (!iterator.hasNext()) {
      throw new AxisFault(
          "Policy doesn't contain any policy alternatives");
    }

    List assertionList = (List) iterator.next();

    Assertion assertion;
    String namespaceURI;

    List moduleList;

    List namespaceList = new ArrayList();
    List modulesToEngage = new ArrayList();

    for (Iterator assertions = assertionList.iterator(); assertions
        .hasNext();) {
      assertion = (Assertion) assertions.next();
      namespaceURI = assertion.getName().getNamespaceURI();

      moduleList = axisConfiguration
          .getModulesForPolicyNamesapce(namespaceURI);

      if (moduleList == null) {
        log.debug("can't find any module to process "
            + assertion.getName() + " type assertions");
        continue;
      }

      if (!canSupportAssertion(assertion, moduleList)) {
        throw new AxisFault("atleast one module can't support "
            + assertion.getName());
      }

      if (!namespaceList.contains(namespaceURI)) {
        namespaceList.add(namespaceURI);
        modulesToEngage.addAll(moduleList);
      }
    }
    engageModulesToAxisDescription(modulesToEngage, this);
  }

  private void engageModulesToAxisDescription(List moduleList,
      AxisDescription description) throws AxisFault {

    AxisModule axisModule;
    Module module;

    for (Iterator iterator = moduleList.iterator(); iterator.hasNext();) {
      axisModule = (AxisModule) iterator.next();
      // FIXME is this step really needed ??
      // Shouldn't axisMoudle.getModule always return not-null value ??
      module = axisModule.getModule();

      if (!(module == null || description.isEngaged(axisModule.getName()))) {
        // engages the module to AxisDescription
        description.engageModule(axisModule);
        // notifies the module about the engagement
        axisModule.getModule().engageNotify(description);
      }
    }
  }

  public AxisConfiguration getAxisConfiguration() {

    if (this instanceof AxisConfiguration) {
      return (AxisConfiguration) this;
    }

    if (this.parent != null) {
      return this.parent.getAxisConfiguration();
    }

    return null;
  }

  public abstract Object getKey();


  /**
   * Engage a Module at this level
   *
   * @param axisModule
   *            the Module to engage
   * @throws AxisFault
   *             if there's a problem engaging
   */
  public void engageModule(AxisModule axisModule) throws AxisFault {
    engageModule(axisModule, this);
  }
 
    /**
     * Engage a Module at this level, keeping track of which level the engage was originally
     * called from.  This is meant for internal use only.
     *
     * @param axisModule module to engage
     * @param source the AxisDescription which originally called engageModule()
     * @throws AxisFault if there's a problem engaging
     */
    public void engageModule(AxisModule axisModule, AxisDescription source) throws AxisFault {
        if (engagedModules == null) engagedModules = new ConcurrentHashMap();
        String moduleName = axisModule.getName();
        for (Iterator iterator = engagedModules.values().iterator(); iterator.hasNext();) {
            AxisModule tempAxisModule = ((AxisModule) iterator.next());
            String tempModuleName = tempAxisModule.getName();

            if (moduleName.equals(tempModuleName)) {
                String existing = tempAxisModule.getVersion();
                if (!Utils.checkVersion(axisModule.getVersion(), existing)) {
                    throw new AxisFault(Messages.getMessage("mismatchedModuleVersions",
                            getClass().getName(),
                            moduleName,
                            existing));
                }
            }
           
        }

        // Let the Module know it's being engaged.  If it's not happy about it, it can throw.
        Module module = axisModule.getModule();
        if (module != null) {
            module.engageNotify(this);
        }

        // If we have anything specific to do, let that happen
        onEngage(axisModule, source);

        engagedModules.put(Utils.getModuleName(axisModule.getName(), axisModule.getVersion()),
                           axisModule);
    }
   
  protected void onEngage(AxisModule module, AxisDescription engager)
      throws AxisFault {
    // Default version does nothing, feel free to override
  }

  static Collection NULL_MODULES = new ArrayList(0);

  public Collection getEngagedModules() {
    return engagedModules == null ? NULL_MODULES : engagedModules.values();
  }

  /**
   * Check if a given module is engaged at this level.
   *
   * @param moduleName
   *            module to investigate.
   * @return true if engaged, false if not. TODO: Handle versions?
   *         isEngaged("addressing") should be true even for versioned
   *         modulename...
   */
  public boolean isEngaged(String moduleName) {
    return engagedModules != null
        && engagedModules.keySet().contains(moduleName);
  }

  public boolean isEngaged(AxisModule axisModule) {
    String id = Utils.getModuleName(axisModule.getName(), axisModule
        .getVersion());
    return engagedModules != null && engagedModules.keySet().contains(id);
  }

  public void disengageModule(AxisModule module) throws AxisFault {
    if (module == null || engagedModules == null)
      return;
    // String id = Utils.getModuleName(module.getName(),
    // module.getVersion());
    if (isEngaged(module)) {
      onDisengage(module);
      engagedModules.remove(Utils.getModuleName(module.getName(), module
          .getVersion()));
    }
  }

  protected void onDisengage(AxisModule module) throws AxisFault {
    // Base version does nothing
  }

  private Policy getApplicablePolicy(AxisDescription axisDescription) {
    if (axisDescription instanceof AxisMessage) {
      AxisMessage axisMessage = (AxisMessage) axisDescription;
      AxisOperation axisOperation = axisMessage.getAxisOperation();
      if (axisOperation != null) {
        AxisService axisService = (AxisService) axisOperation
            .getAxisService();
        if (axisService != null) {
          if (axisService.getEndpointName() != null) {
            AxisEndpoint axisEndpoint = axisService
                .getEndpoint(axisService.getEndpointName());
            if (axisEndpoint != null) {
              AxisBinding axisBinding = axisEndpoint.getBinding();
              AxisBindingOperation axisBindingOperation = (AxisBindingOperation) axisBinding
                  .getChild(axisOperation.getName());
              String direction = axisMessage.getDirection();
              AxisBindingMessage axisBindingMessage = null;
              if (WSDLConstants.WSDL_MESSAGE_DIRECTION_IN
                  .equals(direction)
                  && WSDLUtil
                      .isInputPresentForMEP(axisOperation
                          .getMessageExchangePattern())) {
                axisBindingMessage = (AxisBindingMessage) axisBindingOperation
                    .getChild(WSDLConstants.MESSAGE_LABEL_IN_VALUE);
                return axisBindingMessage.getEffectivePolicy();
               
              } else if (WSDLConstants.WSDL_MESSAGE_DIRECTION_OUT
                  .equals(direction)
                  && WSDLUtil
                      .isOutputPresentForMEP(axisOperation
                          .getMessageExchangePattern())) {
                axisBindingMessage = (AxisBindingMessage) axisBindingOperation
                    .getChild(WSDLConstants.MESSAGE_LABEL_OUT_VALUE);
                return axisBindingMessage.getEffectivePolicy();
              }
            }

          }
        }
      }
      return ((AxisMessage) axisDescription).getEffectivePolicy();
    }
    return null;
  }

  public PolicySubject getPolicySubject() {
    return policySubject;
  }

}
TOP

Related Classes of org.apache.axis2.description.AxisDescription

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.