Save This Page
Home » axis2-1.5-src » org.apache » axis2 » description » [javadoc | source]
    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one
    3    * or more contributor license agreements. See the NOTICE file
    4    * distributed with this work for additional information
    5    * regarding copyright ownership. The ASF licenses this file
    6    * to you under the Apache License, Version 2.0 (the
    7    * "License"); you may not use this file except in compliance
    8    * with the License. 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,
   13    * software distributed under the License is distributed on an
   14    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
   15    * KIND, either express or implied. See the License for the
   16    * specific language governing permissions and limitations
   17    * under the License.
   18    */
   19   
   20   package org.apache.axis2.description;
   21   
   22   import org.apache.axiom.om.OMAbstractFactory;
   23   import org.apache.axiom.om.OMElement;
   24   import org.apache.axiom.om.OMFactory;
   25   import org.apache.axiom.om.OMNode;
   26   import org.apache.axiom.om.OMText;
   27   import org.apache.axis2.AxisFault;
   28   import org.apache.axis2.engine.AxisConfiguration;
   29   import org.apache.axis2.i18n.Messages;
   30   import org.apache.axis2.modules.Module;
   31   import org.apache.axis2.util.JavaUtils;
   32   import org.apache.axis2.util.Utils;
   33   import org.apache.axis2.wsdl.WSDLConstants;
   34   import org.apache.axis2.wsdl.WSDLUtil;
   35   import org.apache.commons.logging.Log;
   36   import org.apache.commons.logging.LogFactory;
   37   import org.apache.neethi.Assertion;
   38   import org.apache.neethi.Policy;
   39   
   40   import javax.xml.stream.XMLStreamException;
   41   import java.io.StringWriter;
   42   import java.util.ArrayList;
   43   import java.util.Collection;
   44   import java.util.Iterator;
   45   import java.util.List;
   46   import java.util.Map;
   47   import java.util.concurrent.ConcurrentHashMap;
   48   
   49   public abstract class AxisDescription implements ParameterInclude, DescriptionConstants {
   50   
   51       protected AxisDescription parent = null;
   52   
   53       private ParameterInclude parameterInclude;
   54   
   55       private PolicyInclude policyInclude = null;
   56   
   57       private PolicySubject policySubject = null;
   58   
   59       private Map<Object, AxisDescription> children;
   60   
   61       protected Map<String, AxisModule> engagedModules;
   62   
   63       /** List of ParameterObservers who want to be notified of changes */
   64       protected List<ParameterObserver> parameterObservers = null;
   65   
   66       private OMFactory omFactory = OMAbstractFactory.getOMFactory();
   67   
   68       // Holds the documentation details for each element
   69       private OMNode documentation;
   70   
   71       // creating a logger instance
   72       private static Log log = LogFactory.getLog(AxisDescription.class);
   73   
   74       public AxisDescription() {
   75           parameterInclude = new ParameterIncludeImpl();
   76           children = new ConcurrentHashMap<Object, AxisDescription>();
   77           policySubject = new PolicySubject();
   78       }
   79   
   80       public void addParameterObserver(ParameterObserver observer) {
   81           if (parameterObservers == null)
   82               parameterObservers = new ArrayList<ParameterObserver>();
   83           parameterObservers.add(observer);
   84       }
   85   
   86       public void removeParameterObserver(ParameterObserver observer) {
   87           if (parameterObservers != null) {
   88               parameterObservers.remove(observer);
   89           }
   90       }
   91   
   92       public void addParameter(Parameter param) throws AxisFault {
   93           if (param == null) {
   94               return;
   95           }
   96   
   97           if (isParameterLocked(param.getName())) {
   98               throw new AxisFault(Messages.getMessage("paramterlockedbyparent",
   99                                                       param.getName()));
  100           }
  101   
  102           parameterInclude.addParameter(param);
  103   
  104           // Tell anyone who wants to know
  105           if (parameterObservers != null) {
  106               for (Object parameterObserver : parameterObservers) {
  107                   ParameterObserver observer = (ParameterObserver)parameterObserver;
  108                   observer.parameterChanged(param.getName(), param.getValue());
  109               }
  110           }
  111       }
  112   
  113       public void addParameter(String name, Object value) throws AxisFault {
  114           addParameter(new Parameter(name, value));
  115       }
  116   
  117       public void removeParameter(Parameter param) throws AxisFault {
  118           parameterInclude.removeParameter(param);
  119       }
  120   
  121       public void deserializeParameters(OMElement parameterElement)
  122               throws AxisFault {
  123   
  124           parameterInclude.deserializeParameters(parameterElement);
  125   
  126       }
  127   
  128       /**
  129        * If the parameter is found in the current description then the Parameter will be writable else
  130        * it will be read only
  131        *
  132        * @param name name of Parameter to retrieve
  133        * @return the Parameter, if found anywhere in the stack, or null if not
  134        */
  135       public Parameter getParameter(String name) {
  136           Parameter parameter = parameterInclude.getParameter(name);
  137           if (parameter != null) {
  138               parameter.setEditable(true);
  139               return parameter;
  140           }
  141           if (parent != null) {
  142               parameter = parent.getParameter(name);
  143               if (parameter != null) {
  144                   parameter.setEditable(false);
  145               }
  146               return parameter;
  147           }
  148           return null;
  149       }
  150   
  151       public Object getParameterValue(String name) {
  152           Parameter param = getParameter(name);
  153           if (param == null) {
  154               return null;
  155           }
  156           return param.getValue();
  157       }
  158   
  159       public boolean isParameterTrue(String name) {
  160           Parameter param = getParameter(name);
  161           return param != null && JavaUtils.isTrue(param.getValue());
  162       }
  163   
  164       public ArrayList<Parameter> getParameters() {
  165           return parameterInclude.getParameters();
  166       }
  167   
  168       public boolean isParameterLocked(String parameterName) {
  169   
  170           if (this.parent != null && this.parent.isParameterLocked(parameterName)) {
  171               return true;
  172           }
  173   
  174           Parameter parameter = getParameter(parameterName);
  175           return parameter != null && parameter.isLocked();
  176       }
  177   
  178       public String getDocumentation() {
  179           if (documentation != null) {
  180               if (documentation.getType() == OMNode.TEXT_NODE) {
  181                   return ((OMText)documentation).getText();
  182               } else {
  183                   StringWriter writer = new StringWriter();
  184                   documentation.build();
  185                   try {
  186                       documentation.serialize(writer);
  187                   } catch (XMLStreamException e) {
  188                       log.error(e);
  189                   }
  190                   writer.flush();
  191                   return writer.toString();
  192               }
  193           }
  194           return null;
  195       }
  196   
  197       public OMNode getDocumentationNode() {
  198           return documentation;
  199       }
  200   
  201       public void setDocumentation(OMNode documentation) {
  202           this.documentation = documentation;
  203       }
  204   
  205       public void setDocumentation(String documentation) {
  206           if (!"".equals(documentation)) {
  207               this.documentation = omFactory.createOMText(documentation);
  208           }
  209       }
  210   
  211       public void setParent(AxisDescription parent) {
  212           this.parent = parent;
  213       }
  214   
  215       public AxisDescription getParent() {
  216           return parent;
  217       }
  218   
  219       /**
  220        * @param policyInclude PolicyInclude value
  221        * @see org.apache.axis2.description.AxisDescription#setPolicyInclude(PolicyInclude)
  222        * @deprecated As of release 1.4, if you want to access the policy cache of a particular
  223        *             AxisDescription object use {@link #getPolicySubject()} instead.
  224        */
  225       public void setPolicyInclude(PolicyInclude policyInclude) {
  226           this.policyInclude = policyInclude;
  227       }
  228   
  229   
  230       /**
  231        * @return the active PolicyInclue
  232        * @see org.apache.axis2.description.AxisDescription#getPolicySubject()
  233        * @deprecated As of release 1.4, replaced by {@link #getPolicySubject()}
  234        */
  235       public PolicyInclude getPolicyInclude() {
  236           if (policyInclude == null) {
  237               policyInclude = new PolicyInclude(this);
  238           }
  239           return policyInclude;
  240       }
  241   
  242   
  243       // NOTE - These are NOT typesafe!
  244       public void addChild(AxisDescription child) {
  245           if (child.getKey() == null) {
  246               // FIXME: Several classes that extend AxisDescription pass null in their getKey method.
  247   //            throw new IllegalArgumentException("Please specify a key in the child");
  248           } else {
  249               children.put(child.getKey(), child);
  250           }
  251       }
  252   
  253   
  254       public void addChild(Object key, AxisDescription child) {
  255           children.put(key, child);
  256       }
  257   
  258       public Iterator<? extends AxisDescription> getChildren() {
  259           return children.values().iterator();
  260       }
  261   
  262       public AxisDescription getChild(Object key) {
  263           if (key == null) {
  264               // FIXME: Why are folks sending in null?
  265               return null;
  266           }
  267           return (AxisDescription)children.get(key);
  268       }
  269   
  270       public void removeChild(Object key) {
  271           children.remove(key);
  272       }
  273   
  274       /**
  275        * This method sets the policy as the default of this AxisDescription instance. Further more
  276        * this method does the followings. <p/> (1) Engage whatever modules necessary to execute new
  277        * the effective policy of this AxisDescription instance. (2) Disengage whatever modules that
  278        * are not necessary to execute the new effective policy of this AxisDescription instance. (3)
  279        * Check whether each module can execute the new effective policy of this AxisDescription
  280        * instance. (4) If not throw an AxisFault to notify the user. (5) Else notify each module about
  281        * the new effective policy.
  282        *
  283        * @param policy the new policy of this AxisDescription instance. The effective policy is the
  284        *               merge of this argument with effective policy of parent of this
  285        *               AxisDescription.
  286        * @throws AxisFault if any module is unable to execute the effective policy of this
  287        *                   AxisDescription instance successfully or no module to execute some portion
  288        *                   (one or more PrimtiveAssertions ) of that effective policy.
  289        */
  290       public void applyPolicy(Policy policy) throws AxisFault {
  291           // sets AxisDescription policy
  292           getPolicySubject().clear();
  293           getPolicySubject().attachPolicy(policy);
  294   
  295           /*
  296              * now we try to engage appropriate modules based on the merged policy
  297              * of axis description object and the corresponding axis binding
  298              * description object.
  299              */
  300           applyPolicy();
  301       }
  302   
  303       /**
  304        * Applies the policies on the Description Hierarchy recursively.
  305        *
  306        * @throws AxisFault an error occurred applying the policy
  307        */
  308       public void applyPolicy() throws AxisFault {
  309           AxisConfiguration configuration = getAxisConfiguration();
  310           if (configuration == null) {
  311               return;
  312           }
  313   
  314           Policy applicablePolicy = getApplicablePolicy(this);
  315           if (applicablePolicy != null) {
  316               engageModulesForPolicy(applicablePolicy, configuration);
  317           }
  318   
  319           for (Iterator<? extends AxisDescription> children = getChildren(); children.hasNext();) {
  320               AxisDescription child = children.next();
  321               child.applyPolicy();
  322           }
  323       }
  324   
  325       private boolean canSupportAssertion(Assertion assertion, List<AxisModule> moduleList) {
  326   
  327           Module module;
  328   
  329           for (AxisModule axisModule : moduleList) {
  330               // FIXME is this step really needed ??
  331               // Shouldn't axisMoudle.getModule always return not-null value ??
  332               module = axisModule.getModule();
  333   
  334               if (!(module == null || module.canSupportAssertion(assertion))) {
  335                   log.debug(axisModule.getName() + " says it can't support " + assertion.getName());
  336                   return false;
  337               }
  338           }
  339   
  340           return true;
  341       }
  342   
  343       private void engageModulesForPolicy(Policy policy, AxisConfiguration axisConfiguration)
  344               throws AxisFault {
  345           /*
  346              * for the moment we consider policies with only one alternative. If the
  347              * policy contains multiple alternatives only the first alternative will
  348              * be considered.
  349              */
  350           Iterator iterator = policy.getAlternatives();
  351           if (!iterator.hasNext()) {
  352               throw new AxisFault("Policy doesn't contain any policy alternatives");
  353           }
  354   
  355           List assertionList = (List)iterator.next();
  356   
  357           Assertion assertion;
  358           String namespaceURI;
  359   
  360           List moduleList;
  361   
  362           List namespaceList = new ArrayList();
  363           List modulesToEngage = new ArrayList();
  364   
  365           for (Object anAssertionList : assertionList) {
  366               assertion = (Assertion)anAssertionList;
  367               namespaceURI = assertion.getName().getNamespaceURI();
  368   
  369               moduleList = axisConfiguration.getModulesForPolicyNamesapce(namespaceURI);
  370   
  371               if (moduleList == null) {
  372                   log.debug("can't find any module to process " + assertion.getName() +
  373                             " type assertions");
  374                   continue;
  375               }
  376   
  377               if (!canSupportAssertion(assertion, moduleList)) {
  378                   throw new AxisFault("atleast one module can't support " + assertion.getName());
  379               }
  380   
  381               if (!namespaceList.contains(namespaceURI)) {
  382                   namespaceList.add(namespaceURI);
  383                   modulesToEngage.addAll(moduleList);
  384               }
  385           }
  386           engageModulesToAxisDescription(modulesToEngage, this);
  387       }
  388   
  389       private void engageModulesToAxisDescription(List<AxisModule> moduleList, AxisDescription description)
  390               throws AxisFault {
  391   
  392           AxisModule axisModule;
  393           Module module;
  394   
  395           for (Object aModuleList : moduleList) {
  396               axisModule = (AxisModule)aModuleList;
  397               // FIXME is this step really needed ??
  398               // Shouldn't axisMoudle.getModule always return not-null value ??
  399               module = axisModule.getModule();
  400   
  401               if (!(module == null || description.isEngaged(axisModule.getName()))) {
  402                   // engages the module to AxisDescription
  403                   description.engageModule(axisModule);
  404                   // notifies the module about the engagement
  405                   axisModule.getModule().engageNotify(description);
  406               }
  407           }
  408       }
  409   
  410       public AxisConfiguration getAxisConfiguration() {
  411   
  412           if (this instanceof AxisConfiguration) {
  413               return (AxisConfiguration)this;
  414           }
  415   
  416           if (this.parent != null) {
  417               return this.parent.getAxisConfiguration();
  418           }
  419   
  420           return null;
  421       }
  422   
  423       public abstract Object getKey();
  424   
  425   
  426       /**
  427        * Engage a Module at this level
  428        *
  429        * @param axisModule the Module to engage
  430        * @throws AxisFault if there's a problem engaging
  431        */
  432       public void engageModule(AxisModule axisModule) throws AxisFault {
  433           engageModule(axisModule, this);
  434       }
  435   
  436       /**
  437        * Engage a Module at this level, keeping track of which level the engage was originally called
  438        * from.  This is meant for internal use only.
  439        *
  440        * @param axisModule module to engage
  441        * @param source     the AxisDescription which originally called engageModule()
  442        * @throws AxisFault if there's a problem engaging
  443        */
  444       public void engageModule(AxisModule axisModule, AxisDescription source) throws AxisFault {
  445           if (engagedModules == null) engagedModules = new ConcurrentHashMap<String, AxisModule>();
  446           String moduleName = axisModule.getName();
  447           for (Object o : engagedModules.values()) {
  448               AxisModule tempAxisModule = ((AxisModule)o);
  449               String tempModuleName = tempAxisModule.getName();
  450   
  451               if (moduleName.equals(tempModuleName)) {
  452                   String existing = tempAxisModule.getVersion();
  453                   if (!Utils.checkVersion(axisModule.getVersion(), existing)) {
  454                       throw new AxisFault(Messages.getMessage("mismatchedModuleVersions",
  455                                                               getClass().getName(),
  456                                                               moduleName,
  457                                                               existing));
  458                   }
  459               }
  460   
  461           }
  462   
  463           // Let the Module know it's being engaged.  If it's not happy about it, it can throw.
  464           Module module = axisModule.getModule();
  465           if (module != null) {
  466               module.engageNotify(this);
  467           }
  468   
  469           // If we have anything specific to do, let that happen
  470           onEngage(axisModule, source);
  471   
  472           engagedModules.put(Utils.getModuleName(axisModule.getName(), axisModule.getVersion()),
  473                              axisModule);
  474       }
  475   
  476       protected void onEngage(AxisModule module, AxisDescription engager)
  477               throws AxisFault {
  478           // Default version does nothing, feel free to override
  479       }
  480   
  481       static Collection<AxisModule> NULL_MODULES = new ArrayList<AxisModule>(0);
  482   
  483       public Collection<AxisModule> getEngagedModules() {
  484           return engagedModules == null ? NULL_MODULES : engagedModules.values();
  485       }
  486   
  487       /**
  488        * Check if a given module is engaged at this level.
  489        *
  490        * @param moduleName module to investigate.
  491        * @return true if engaged, false if not. TODO: Handle versions? isEngaged("addressing") should
  492        *         be true even for versioned modulename...
  493        */
  494       public boolean isEngaged(String moduleName) {
  495           return engagedModules != null
  496                  && engagedModules.keySet().contains(moduleName);
  497       }
  498   
  499       public boolean isEngaged(AxisModule axisModule) {
  500           String id = Utils.getModuleName(axisModule.getName(), axisModule
  501                   .getVersion());
  502           return engagedModules != null && engagedModules.keySet().contains(id);
  503       }
  504   
  505       public void disengageModule(AxisModule module) throws AxisFault {
  506           if (module == null || engagedModules == null)
  507               return;
  508           // String id = Utils.getModuleName(module.getName(),
  509           // module.getVersion());
  510           if (isEngaged(module)) {
  511               onDisengage(module);
  512               engagedModules.remove(Utils.getModuleName(module.getName(), module
  513                       .getVersion()));
  514           }
  515       }
  516   
  517       protected void onDisengage(AxisModule module) throws AxisFault {
  518           // Base version does nothing
  519       }
  520   
  521       private Policy getApplicablePolicy(AxisDescription axisDescription) {
  522           if (axisDescription instanceof AxisMessage) {
  523               AxisMessage axisMessage = (AxisMessage)axisDescription;
  524               AxisOperation axisOperation = axisMessage.getAxisOperation();
  525               if (axisOperation != null) {
  526                   AxisService axisService = axisOperation.getAxisService();
  527                   if (axisService != null) {
  528                       if (axisService.getEndpointName() != null) {
  529                           AxisEndpoint axisEndpoint =
  530                                   axisService.getEndpoint(axisService.getEndpointName());
  531                           if (axisEndpoint != null) {
  532                               AxisBinding axisBinding = axisEndpoint.getBinding();
  533                               AxisBindingOperation axisBindingOperation =
  534                                       (AxisBindingOperation)axisBinding
  535                                               .getChild(axisOperation.getName());
  536                               String direction = axisMessage.getDirection();
  537                               AxisBindingMessage axisBindingMessage;
  538                               if (WSDLConstants.WSDL_MESSAGE_DIRECTION_IN.equals(direction)
  539                                   && WSDLUtil
  540                                       .isInputPresentForMEP(axisOperation
  541                                               .getMessageExchangePattern())) {
  542                                   axisBindingMessage = (AxisBindingMessage)axisBindingOperation
  543                                           .getChild(WSDLConstants.MESSAGE_LABEL_IN_VALUE);
  544                                   return axisBindingMessage.getEffectivePolicy();
  545   
  546                               } else if (WSDLConstants.WSDL_MESSAGE_DIRECTION_OUT
  547                                       .equals(direction)
  548                                          && WSDLUtil
  549                                       .isOutputPresentForMEP(axisOperation
  550                                               .getMessageExchangePattern())) {
  551                                   axisBindingMessage = (AxisBindingMessage)axisBindingOperation
  552                                           .getChild(WSDLConstants.MESSAGE_LABEL_OUT_VALUE);
  553                                   return axisBindingMessage.getEffectivePolicy();
  554                               }
  555                           }
  556   
  557                       }
  558                   }
  559               }
  560               return ((AxisMessage)axisDescription).getEffectivePolicy();
  561           }
  562           return null;
  563       }
  564   
  565       public PolicySubject getPolicySubject() {
  566           return policySubject;
  567       }
  568   
  569   }

Save This Page
Home » axis2-1.5-src » org.apache » axis2 » description » [javadoc | source]