| /* |
| * Copyright 2004,2006 The Apache Software Foundation. |
| * |
| * Licensed 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 org.apache.axis2.AxisFault; |
| import org.apache.axis2.client.OperationClient; |
| import org.apache.axis2.client.Options; |
| import org.apache.axis2.context.ConfigurationContext; |
| import org.apache.axis2.context.MessageContext; |
| import org.apache.axis2.context.OperationContext; |
| import org.apache.axis2.context.ServiceContext; |
| import org.apache.axis2.engine.AxisConfiguration; |
| import org.apache.axis2.engine.AxisError; |
| import org.apache.axis2.engine.MessageReceiver; |
| import org.apache.axis2.i18n.Messages; |
| import org.apache.axis2.modules.Module; |
| import org.apache.axis2.phaseresolver.PhaseResolver; |
| import org.apache.axis2.wsdl.WSDLConstants; |
| import org.apache.commons.logging.Log; |
| import org.apache.commons.logging.LogFactory; |
| |
| import javax.xml.namespace.QName; |
| import java.util.*; |
| |
| public abstract class AxisOperation extends AxisDescription |
| implements WSDLConstants { |
| public static final String STYLE_RPC = "rpc"; |
| public static final String STYLE_MSG = "msg"; |
| public static final String STYLE_DOC = "doc"; |
| private static final Log log = LogFactory.getLog(AxisOperation.class); |
| private int mep = WSDL20_2004Constants.MEP_CONSTANT_INVALID; |
| |
| public static final String SOAP_ACTION = "soapaction"; |
| |
| |
| // to store engaged modules |
| private ArrayList engagedModules = new ArrayList(); |
| |
| // to hide control operation , operation which added by RM like module |
| private boolean controlOperation = false; |
| private String style = STYLE_DOC; |
| |
| // to store mepURL |
| private String mepURI; |
| private MessageReceiver messageReceiver; |
| private HashMap moduleConfigmap; |
| |
| // To store deploy-time module refs |
| private ArrayList modulerefs; |
| |
| private ArrayList faultMessages; |
| |
| private QName name; |
| |
| private ArrayList wsamappingList; |
| private String outputAction; |
| private HashMap faultActions = new HashMap(); |
| |
| private String soapAction; |
| |
| public AxisOperation() { |
| mepURI = WSDL20_2004Constants.MEP_URI_IN_OUT; |
| modulerefs = new ArrayList(); |
| moduleConfigmap = new HashMap(); |
| faultMessages = new ArrayList(); |
| } |
| |
| public AxisOperation(QName name) { |
| this(); |
| this.setName(name); |
| } |
| |
| public abstract void addMessage(AxisMessage message, String label); |
| |
| /** |
| * Adds a message context into an operation context. Depending on MEPs, this |
| * method has to be overridden. |
| * Depending on the MEP operation description know how to fill the message context map |
| * in operationContext. |
| * As an example, if the MEP is IN-OUT then depending on messagable operation description |
| * should know how to keep them in correct locations. |
| * |
| * @param msgContext <code>MessageContext</code> |
| * @param opContext <code>OperationContext</code> |
| * @throws AxisFault <code>AxisFault</code> |
| */ |
| public abstract void addMessageContext(MessageContext msgContext, OperationContext opContext) |
| throws AxisFault; |
| |
| public abstract void addFaultMessageContext(MessageContext msgContext, OperationContext opContext) |
| throws AxisFault; |
| |
| public void addModule(QName moduleName) { |
| modulerefs.add(moduleName); |
| } |
| |
| /** |
| * Adds module configuration, if there is moduleConfig tag in operation. |
| * |
| * @param moduleConfiguration |
| */ |
| public void addModuleConfig(ModuleConfiguration moduleConfiguration) { |
| moduleConfigmap.put(moduleConfiguration.getModuleName(), moduleConfiguration); |
| } |
| |
| /** |
| * Engages a module. It is required to use this method. |
| * |
| * @param moduleref |
| * @throws AxisFault |
| */ |
| public final void engageModule(AxisModule moduleref, AxisConfiguration axisConfig) |
| throws AxisFault { |
| ArrayList moduleOperations = engageModuleToOperation(moduleref, axisConfig); |
| AxisService service = (AxisService) getParent(); |
| if (service != null) { |
| for (int i = 0; i < moduleOperations.size(); i++) { |
| AxisOperation axisOperation = (AxisOperation) moduleOperations.get(i); |
| service.addOperation(axisOperation); |
| } |
| } |
| } |
| |
| private ArrayList engageModuleToOperation(AxisModule moduleref, AxisConfiguration axisConfig) throws AxisFault { |
| if (moduleref == null) { |
| return null; |
| } |
| Iterator module_itr = engagedModules.iterator(); |
| boolean isEngagable; |
| QName moduleName = moduleref.getName(); |
| while (module_itr.hasNext()) { |
| AxisModule module = (AxisModule) module_itr.next(); |
| QName modu = module.getName(); |
| isEngagable = org.apache.axis2.util.Utils.checkVersion(moduleName, modu); |
| if (!isEngagable) { |
| return new ArrayList(); |
| } |
| } |
| PhaseResolver phaseResolver = new PhaseResolver(axisConfig); |
| phaseResolver.engageModuleToOperation(this, moduleref); |
| Module module = moduleref.getModule(); |
| if (module != null) { |
| module.engageNotify(this); |
| } |
| engagedModules.add(moduleref); |
| return addModuleOperations(moduleref, axisConfig, (AxisService) getParent()); |
| } |
| |
| public void disengageModule(AxisModule module) { |
| if (module != null) { |
| if (getParent() != null) { |
| AxisService service = (AxisService) getParent(); |
| AxisConfiguration axiConfiguration = service.getAxisConfiguration(); |
| PhaseResolver phaseResolver = new PhaseResolver(axiConfiguration); |
| if (service.isEngaged(module.getName())) { |
| phaseResolver.disengageModuleFromOperationChain(module, this); |
| } else if (axiConfiguration != null && |
| axiConfiguration.isEngaged(module.getName())) { |
| phaseResolver.disengageModuleFromOperationChain(module, this); |
| } else { |
| if (axiConfiguration != null) { |
| phaseResolver.disengageModuleFromGlobalChains(module); |
| } |
| phaseResolver.disengageModuleFromOperationChain(module, this); |
| //removing operations added at the time of module engagemnt |
| HashMap moduleOperations = module.getOperations(); |
| if (moduleOperations != null) { |
| Iterator moduleOperations_itr = moduleOperations.values().iterator(); |
| while (moduleOperations_itr.hasNext()) { |
| AxisOperation operation = (AxisOperation) moduleOperations_itr.next(); |
| service.removeOperation(operation.getName()); |
| } |
| } |
| } |
| } |
| engagedModules.remove(module); |
| log.debug("removed module from engaged modules list " |
| + module.getName().getLocalPart()); |
| } |
| } |
| |
| /** |
| * To remove module from engage module list |
| * |
| * @param module |
| */ |
| public void removeFromEngagedModuleList(AxisModule module) { |
| engagedModules.remove(module); |
| log.debug("removed module from engaged modules list " + module.getName().getLocalPart()); |
| } |
| |
| |
| /** |
| * Adds an operation to a service if a module is required to do so. |
| * |
| * @param module |
| */ |
| public ArrayList addModuleOperations(AxisModule module, AxisConfiguration axisConfig, |
| AxisService service) |
| throws AxisFault { |
| HashMap map = module.getOperations(); |
| Collection col = map.values(); |
| PhaseResolver phaseResolver = new PhaseResolver(axisConfig); |
| //this array list is return , to avoid concurrent modifications , in the deployment engine |
| ArrayList ops = new ArrayList(); |
| for (Iterator iterator = col.iterator(); iterator.hasNext();) { |
| AxisOperation axisOperation = copyOperation((AxisOperation) iterator.next()); |
| axisOperation.setParent(service); |
| ArrayList wsamappings = axisOperation.getWsamappingList(); |
| if (service.getOperation(axisOperation.getName()) == null) { |
| // this operation is a control operation. |
| axisOperation.setControlOperation(true); |
| Module moduleclazz = module.getModule(); |
| if (moduleclazz != null) { |
| moduleclazz.engageNotify(axisOperation); |
| } |
| phaseResolver.engageModuleToOperation(axisOperation, module); |
| ops.add(axisOperation); |
| if (wsamappings != null) { |
| for (int j = 0; j < wsamappings.size(); j++) { |
| String mapping = (String) wsamappings.get(j); |
| |
| service.mapActionToOperation(mapping, axisOperation); |
| } |
| } |
| } |
| } |
| return ops; |
| } |
| |
| /** |
| * Gets a copy from module operation. |
| * |
| * @param axisOperation |
| * @return Returns AxisOperation. |
| * @throws AxisFault |
| */ |
| private AxisOperation copyOperation(AxisOperation axisOperation) throws AxisFault { |
| AxisOperation operation = |
| AxisOperationFactory.getOperationDescription(axisOperation.getMessageExchangePattern()); |
| |
| operation.setMessageReceiver(axisOperation.getMessageReceiver()); |
| operation.setName(axisOperation.getName()); |
| |
| Iterator parameters = axisOperation.getParameters().iterator(); |
| |
| while (parameters.hasNext()) { |
| Parameter parameter = (Parameter) parameters.next(); |
| |
| operation.addParameter(parameter); |
| } |
| |
| operation.setWsamappingList(axisOperation.getWsamappingList()); |
| operation.setOutputAction(axisOperation.getOutputAction()); |
| String[] faultActionNames = axisOperation.getFaultActionNames(); |
| for (int i = 0; i < faultActionNames.length; i++) { |
| operation.addFaultAction(faultActionNames[i], axisOperation.getFaultAction(faultActionNames[i])); |
| } |
| operation.setRemainingPhasesInFlow(axisOperation.getRemainingPhasesInFlow()); |
| operation.setPhasesInFaultFlow(axisOperation.getPhasesInFaultFlow()); |
| operation.setPhasesOutFaultFlow(axisOperation.getPhasesOutFaultFlow()); |
| operation.setPhasesOutFlow(axisOperation.getPhasesOutFlow()); |
| |
| return operation; |
| } |
| |
| |
| /** |
| * Returns as existing OperationContext related to this message if one exists. |
| * |
| * @param msgContext |
| * @return Returns OperationContext. |
| * @throws AxisFault |
| */ |
| public OperationContext findForExistingOperationContext(MessageContext msgContext) |
| throws AxisFault { |
| OperationContext operationContext; |
| |
| if ((operationContext = msgContext.getOperationContext()) != null) { |
| return operationContext; |
| } |
| |
| // If this message is not related to another one, or it is but not one emitted |
| // from the same operation, don't further look for an operation context or fault. |
| if (null != msgContext.getRelatesTo()) { |
| // So this message may be part of an ongoing MEP |
| ConfigurationContext configContext = msgContext.getConfigurationContext(); |
| |
| operationContext = |
| configContext.getOperationContext(msgContext.getRelatesTo().getValue()); |
| |
| if (null == operationContext && log.isDebugEnabled()) { |
| log.debug("Cannot correlate inbound message RelatesTo value [" + msgContext.getRelatesTo() + "] to in-progree MEP"); |
| } |
| } |
| |
| return operationContext; |
| } |
| |
| /** |
| * Finds a MEPContext for an incoming message. An incoming message can be |
| * of two states. |
| * <p/> |
| * 1)This is a new incoming message of a given MEP. 2)This message is a |
| * part of an MEP which has already begun. |
| * <p/> |
| * The method is special cased for the two MEPs |
| * <p/> |
| * #IN_ONLY #IN_OUT |
| * <p/> |
| * for two reasons. First reason is the wide usage and the second being that |
| * the need for the MEPContext to be saved for further incoming messages. |
| * <p/> |
| * In the event that MEP of this operation is different from the two MEPs |
| * defaulted above the decision of creating a new or this message relates |
| * to a MEP which already in business is decided by looking at the WSA |
| * Relates TO of the incoming message. |
| * |
| * @param msgContext |
| */ |
| public OperationContext findOperationContext(MessageContext msgContext, |
| ServiceContext serviceContext) |
| throws AxisFault { |
| OperationContext operationContext; |
| |
| if (null == msgContext.getRelatesTo()) { |
| |
| // Its a new incoming message so get the factory to create a new |
| // one |
| operationContext = new OperationContext(this, serviceContext); |
| } else { |
| |
| // So this message is part of an ongoing MEP |
| ConfigurationContext configContext = msgContext.getConfigurationContext(); |
| |
| operationContext = |
| configContext.getOperationContext(msgContext.getRelatesTo().getValue()); |
| |
| if (null == operationContext) { |
| throw new AxisFault(Messages.getMessage("cannotCorrelateMsg", |
| this.name.toString(), msgContext.getRelatesTo().getValue())); |
| } |
| } |
| return operationContext; |
| } |
| |
| public void registerOperationContext(MessageContext msgContext, |
| OperationContext operationContext) |
| throws AxisFault { |
| msgContext.setAxisOperation(this); |
| msgContext.getConfigurationContext().registerOperationContext(msgContext.getMessageID(), |
| operationContext); |
| operationContext.addMessageContext(msgContext); |
| msgContext.setOperationContext(operationContext); |
| if (operationContext.isComplete()) { |
| operationContext.cleanup(); |
| } |
| } |
| |
| public void registerMessageContext(MessageContext msgContext, |
| OperationContext operationContext) throws AxisFault { |
| msgContext.setAxisOperation(this); |
| operationContext.addMessageContext(msgContext); |
| msgContext.setOperationContext(operationContext); |
| if (operationContext.isComplete()) { |
| operationContext.cleanup(); |
| } |
| } |
| |
| /** |
| * Maps the String URI of the Message exchange pattern to a integer. |
| * Further, in the first lookup, it will cache the looked |
| * up value so that the subsequent method calls are extremely efficient. |
| */ |
| public int getAxisSpecifMEPConstant() { |
| if (this.mep != WSDL20_2004Constants.MEP_CONSTANT_INVALID) { |
| return this.mep; |
| } |
| |
| int temp = WSDL20_2004Constants.MEP_CONSTANT_INVALID; |
| |
| if (WSDL20_2004Constants.MEP_URI_IN_OUT.equals(mepURI) || WSDL20_2006Constants.MEP_URI_IN_OUT.equals(mepURI)) { |
| temp = WSDL20_2004Constants.MEP_CONSTANT_IN_OUT; |
| } else if (WSDL20_2004Constants.MEP_URI_IN_ONLY.equals(mepURI) || WSDL20_2006Constants.MEP_URI_IN_ONLY.equals(mepURI)) { |
| temp = WSDL20_2004Constants.MEP_CONSTANT_IN_ONLY; |
| } else if (WSDL20_2004Constants.MEP_URI_IN_OPTIONAL_OUT.equals(mepURI) || WSDL20_2006Constants.MEP_URI_IN_OPTIONAL_OUT.equals(mepURI)) { |
| temp = WSDL20_2004Constants.MEP_CONSTANT_IN_OPTIONAL_OUT; |
| } else if (WSDL20_2004Constants.MEP_URI_OUT_IN.equals(mepURI) || WSDL20_2006Constants.MEP_URI_OUT_IN.equals(mepURI)) { |
| temp = WSDL20_2004Constants.MEP_CONSTANT_OUT_IN; |
| } else if (WSDL20_2004Constants.MEP_URI_OUT_ONLY.equals(mepURI) || WSDL20_2006Constants.MEP_URI_OUT_ONLY.equals(mepURI)) { |
| temp = WSDL20_2004Constants.MEP_CONSTANT_OUT_ONLY; |
| } else if (WSDL20_2004Constants.MEP_URI_OUT_OPTIONAL_IN.equals(mepURI) || WSDL20_2006Constants.MEP_URI_OUT_OPTIONAL_IN.equals(mepURI)) { |
| temp = WSDL20_2004Constants.MEP_CONSTANT_OUT_OPTIONAL_IN; |
| } else if (WSDL20_2004Constants.MEP_URI_ROBUST_IN_ONLY.equals(mepURI) || WSDL20_2006Constants.MEP_URI_ROBUST_IN_ONLY.equals(mepURI)) { |
| temp = WSDL20_2004Constants.MEP_CONSTANT_ROBUST_IN_ONLY; |
| } else if (WSDL20_2004Constants.MEP_URI_ROBUST_OUT_ONLY.equals(mepURI) || WSDL20_2006Constants.MEP_URI_ROBUST_OUT_ONLY.equals(mepURI)) { |
| temp = WSDL20_2004Constants.MEP_CONSTANT_ROBUST_OUT_ONLY; |
| } |
| |
| if (temp == WSDL20_2004Constants.MEP_CONSTANT_INVALID) { |
| throw new AxisError(Messages.getMessage("mepmappingerror")); |
| } |
| |
| this.mep = temp; |
| |
| return this.mep; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.apache.axis2.description.AxisService#getEngadgedModules() |
| */ |
| |
| /** |
| * Method getEngagedModules. |
| */ |
| public Collection getEngagedModules() { |
| return engagedModules; |
| } |
| |
| public abstract AxisMessage getMessage(String label); |
| |
| public String getMessageExchangePattern() { |
| return mepURI; |
| } |
| |
| public MessageReceiver getMessageReceiver() { |
| return messageReceiver; |
| } |
| |
| public ModuleConfiguration getModuleConfig(QName moduleName) { |
| return (ModuleConfiguration) moduleConfigmap.get(moduleName); |
| } |
| |
| public ArrayList getModuleRefs() { |
| return modulerefs; |
| } |
| |
| public QName getName() { |
| return name; |
| } |
| |
| public abstract ArrayList getPhasesInFaultFlow(); |
| |
| public abstract ArrayList getPhasesOutFaultFlow(); |
| |
| public abstract ArrayList getPhasesOutFlow(); |
| |
| public abstract ArrayList getRemainingPhasesInFlow(); |
| |
| public String getStyle() { |
| return style; |
| } |
| |
| public ArrayList getWsamappingList() { |
| return wsamappingList; |
| } |
| |
| public boolean isControlOperation() { |
| return controlOperation; |
| } |
| |
| // to check whether a given parameter is locked |
| public boolean isParameterLocked(String parameterName) { |
| |
| // checking the locked value of parent |
| boolean locked = false; |
| |
| if (getParent() != null) { |
| locked = getParent().isParameterLocked(parameterName); |
| } |
| |
| if (locked) { |
| return true; |
| } else { |
| Parameter parameter = getParameter(parameterName); |
| |
| return (parameter != null) && parameter.isLocked(); |
| } |
| } |
| |
| public void setControlOperation(boolean controlOperation) { |
| this.controlOperation = controlOperation; |
| } |
| |
| public void setMessageExchangePattern(String mepURI) { |
| this.mepURI = mepURI; |
| } |
| |
| public void setMessageReceiver(MessageReceiver messageReceiver) { |
| this.messageReceiver = messageReceiver; |
| } |
| |
| public void setName(QName name) { |
| this.name = name; |
| } |
| |
| public abstract void setPhasesInFaultFlow(ArrayList list); |
| |
| public abstract void setPhasesOutFaultFlow(ArrayList list); |
| |
| public abstract void setPhasesOutFlow(ArrayList list); |
| |
| public abstract void setRemainingPhasesInFlow(ArrayList list); |
| |
| public void setStyle(String style) { |
| if (!"".equals(style)) { |
| this.style = style; |
| } |
| } |
| |
| public void setWsamappingList(ArrayList wsamappingList) { |
| this.wsamappingList = wsamappingList; |
| } |
| |
| /** |
| * |
| */ |
| public OperationClient createClient(ServiceContext sc, Options options) { |
| throw new UnsupportedOperationException(Messages.getMessage("mepnotyetimplemented", mepURI)); |
| } |
| |
| public Object getKey() { |
| return this.name; |
| } |
| |
| public ArrayList getFaultMessages() { |
| return faultMessages; |
| } |
| |
| public void setFaultMessages(AxisMessage faultMessage) { |
| faultMessages.add(faultMessage); |
| } |
| |
| public String getSoapAction() { |
| return soapAction; |
| } |
| |
| public void setSoapAction(String soapAction) { |
| this.soapAction = soapAction; |
| } |
| |
| public String getInputAction() { |
| String result = this.soapAction; |
| if (result == null || "".equals(result)) { |
| if (wsamappingList != null && !wsamappingList.isEmpty()) { |
| result = wsamappingList.get(0).toString(); |
| } |
| } |
| return result; |
| } |
| |
| public String getOutputAction() { |
| return outputAction; |
| } |
| |
| public void setOutputAction(String act) { |
| outputAction = act; |
| } |
| |
| public void addFaultAction(String faultName, String action) { |
| faultActions.put(faultName, action); |
| } |
| |
| public void removeFaultAction(String faultName) { |
| faultActions.remove(faultName); |
| } |
| |
| public String getFaultAction(String faultName) { |
| return (String) faultActions.get(faultName); |
| } |
| |
| public String[] getFaultActionNames() { |
| Set keys = faultActions.keySet(); |
| String[] faultActionNames = new String[keys.size()]; |
| faultActionNames = (String[]) keys.toArray(faultActionNames); |
| return faultActionNames; |
| } |
| |
| public String getFaultAction() { |
| String result = null; |
| Iterator iter = faultActions.values().iterator(); |
| if (iter.hasNext()) { |
| result = (String) iter.next(); |
| } |
| return result; |
| } |
| |
| public boolean isEngaged(QName moduleName) { |
| Iterator engagedModuleItr = engagedModules.iterator(); |
| while (engagedModuleItr.hasNext()) { |
| AxisModule axisModule = (AxisModule) engagedModuleItr.next(); |
| if (axisModule.getName().getLocalPart().equals(moduleName.getLocalPart())) { |
| return true; |
| } |
| } |
| return false; |
| } |
| } |