📄 messagecontext.java
字号:
/* * Copyright 2001-2004 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.axis ;import org.apache.axis.attachments.Attachments;import org.apache.axis.client.AxisClient;import org.apache.axis.components.logger.LogFactory;import org.apache.axis.description.OperationDesc;import org.apache.axis.description.ServiceDesc;import org.apache.axis.encoding.TypeMapping;import org.apache.axis.encoding.TypeMappingRegistry;import org.apache.axis.constants.Style;import org.apache.axis.constants.Use;import org.apache.axis.handlers.soap.SOAPService;import org.apache.axis.schema.SchemaVersion;import org.apache.axis.session.Session;import org.apache.axis.soap.SOAPConstants;import org.apache.axis.utils.JavaUtils;import org.apache.axis.utils.LockableHashtable;import org.apache.axis.utils.Messages;import org.apache.commons.logging.Log;import javax.xml.namespace.QName;import javax.xml.rpc.Call;import javax.xml.rpc.handler.soap.SOAPMessageContext;import java.io.File;import java.util.ArrayList;import java.util.Hashtable;// fixme: fields are declared throughout this class, some at the top, and some// near to where they are used. We should move all field declarations into a// single block - it makes it easier to see what is decalred in this class and// what is inherited. It also makes it easier to find them./** * A MessageContext is the Axis implementation of the javax * SOAPMessageContext class, and is core to message processing * in handlers and other parts of the system. * * This class also contains constants for accessing some * well-known properties. Using a hierarchical namespace is * strongly suggested in order to lower the chance for * conflicts. * * (These constants should be viewed as an explicit list of well * known and widely used context keys, there's nothing wrong * with directly using the key strings. This is the reason for * the hierarchical constant namespace. * * Actually I think we might just list the keys in the docs and * provide no such constants since they create yet another * namespace, but we'd have no compile-time checks then. * * Whaddya think? - todo by Jacek) * * * @author Doug Davis (dug@us.ibm.com) * @author Jacek Kopecky (jacek@idoox.com) */public class MessageContext implements SOAPMessageContext { /** The <code>Log</code> used for logging all messages. */ protected static Log log = LogFactory.getLog(MessageContext.class.getName()); /** * The request message. If we're on the client, this is the outgoing * message heading to the server. If we're on the server, this is the * incoming message we've received from the client. */ private Message requestMessage; /** * The response message. If we're on the server, this is the outgoing * message heading back to the client. If we're on the client, this is the * incoming message we've received from the server. */ private Message responseMessage; /** * That unique key/name that the next router/dispatch handler should use * to determine what to do next. */ private String targetService; /** * The name of the Transport which this message was received on (or is * headed to, for the client). */ private String transportName; /** * The default <code>ClassLoader</code> that this service should use. */ private ClassLoader classLoader; /** * The AxisEngine which this context is involved with. */ private AxisEngine axisEngine; /** * A Session associated with this request. */ private Session session; /** * Should we track session state, or not? * default is not. * Could potentially refactor this so that * maintainSession iff session != null... */ private boolean maintainSession = false; // fixme: ambiguity here due to lac of docs - havePassedPivot vs // request/response, vs sending/processing & recieving/responding // I may have just missed the key bit of text /** * Are we doing request stuff, or response stuff? True if processing * response (I think). */ private boolean havePassedPivot = false; /** * Maximum amount of time to wait on a request, in milliseconds. */ private int timeout = Constants.DEFAULT_MESSAGE_TIMEOUT; /** * An indication of whether we require "high fidelity" recording of * deserialized messages for this interaction. Defaults to true for * now, and can be set to false, usually at service-dispatch time. */ private boolean highFidelity = true; /** * Storage for an arbitrary bag of properties associated with this * MessageContext. */ private LockableHashtable bag = new LockableHashtable(); /* * These variables are logically part of the bag, but are separated * because they are used often and the Hashtable is more expensive. * * fixme: this may be fixed by moving to a plain Map impl like HashMap. * Alternatively, we could hide all this magic behind a custom Map impl - * is synchronization on the map needed? these properties aren't * synchronized so I'm guessing not. */ private String username = null; private String password = null; private String encodingStyle = Use.ENCODED.getEncoding(); private boolean useSOAPAction = false; private String SOAPActionURI = null; /** * SOAP Actor roles. */ private String[] roles; /** Our SOAP namespaces and such. */ private SOAPConstants soapConstants = Constants.DEFAULT_SOAP_VERSION; /** Schema version information - defaults to 2001. */ private SchemaVersion schemaVersion = SchemaVersion.SCHEMA_2001; /** Our current operation. */ private OperationDesc currentOperation = null; /** * The current operation. * * @return the current operation; may be <code>null</code> */ public OperationDesc getOperation() { return currentOperation; } /** * Set the current operation. * * @param operation the <code>Operation</code> this context is executing */ public void setOperation(OperationDesc operation) { currentOperation = operation; } /** * Returns a list of operation descriptors that could may * possibly match a body containing an element of the given QName. * For non-DOCUMENT, the list of operation descriptors that match * the name is returned. For DOCUMENT, all the operations that have * qname as a parameter are returned * * @param qname of the first element in the body * @return list of operation descriptions * @throws AxisFault if the operation names could not be looked up */ public OperationDesc [] getPossibleOperationsByQName(QName qname) throws AxisFault { if (currentOperation != null) { return new OperationDesc [] { currentOperation }; } OperationDesc [] possibleOperations = null; if (serviceHandler == null) { try { if (log.isDebugEnabled()) { log.debug(Messages.getMessage("dispatching00", qname.getNamespaceURI())); } // Try looking this QName up in our mapping table... setService(axisEngine.getConfig(). getServiceByNamespaceURI(qname.getNamespaceURI())); } catch (ConfigurationException e) { // Didn't find one... } } if (serviceHandler != null) { ServiceDesc desc = serviceHandler.getInitializedServiceDesc(this); if (desc != null) { if (desc.getStyle() != Style.DOCUMENT) { possibleOperations = desc.getOperationsByQName(qname); } else { // DOCUMENT Style // Get all of the operations that have qname as // a possible parameter QName ArrayList allOperations = desc.getOperations(); ArrayList foundOperations = new ArrayList(); for (int i=0; i < allOperations.size(); i++ ) { OperationDesc tryOp = (OperationDesc) allOperations.get(i); if (tryOp.getParamByQName(qname) != null) { foundOperations.add(tryOp); } } if (foundOperations.size() > 0) { possibleOperations = (OperationDesc[]) JavaUtils.convert(foundOperations, OperationDesc[].class); } } } } return possibleOperations; } /** * get the first possible operation that could match a * body containing an element of the given QName. Sets the currentOperation * field in the process; if that field is already set then its value * is returned instead * @param qname name of the message body * @return an operation or null * @throws AxisFault */ public OperationDesc getOperationByQName(QName qname) throws AxisFault { if (currentOperation == null) { OperationDesc [] possibleOperations = getPossibleOperationsByQName(qname); if (possibleOperations != null && possibleOperations.length > 0) { currentOperation = possibleOperations[0]; } } return currentOperation; } /** * Get the active message context. * * @return the current active message context */ public static MessageContext getCurrentContext() { return AxisEngine.getCurrentMessageContext(); } /** * Temporary directory to store attachments. */ protected static String systemTempDir= null; /** * set the temp dir * TODO: move this piece of code out of this class and into a utilities * class. */ static { try { //get the temp dir from the engine systemTempDir=AxisProperties.getProperty(AxisEngine.ENV_ATTACHMENT_DIR); } catch(Throwable t) { systemTempDir= null; } if(systemTempDir== null) { try { //or create and delete a file in the temp dir to make //sure we have write access to it. File tf= File.createTempFile("Axis", ".tmp"); File dir= tf.getParentFile(); if (tf.exists()) { tf.delete(); } if (dir != null) { systemTempDir= dir.getCanonicalPath(); } } catch(Throwable t) { log.debug("Unable to find a temp dir with write access"); systemTempDir= null; } } } /** * Create a message context. * @param engine the controlling axis engine. Null is actually accepted here, * though passing a null engine in is strongly discouraged as many of the methods * assume that it is in fact defined. */ public MessageContext(AxisEngine engine) { this.axisEngine = engine; if(null != engine){ java.util.Hashtable opts= engine.getOptions(); String attachmentsdir= null; if(null!=opts) { attachmentsdir= (String) opts.get(AxisEngine.PROP_ATTACHMENT_DIR); } if(null == attachmentsdir) { attachmentsdir= systemTempDir; } if(attachmentsdir != null){ setProperty(ATTACHMENTS_DIR, attachmentsdir); } // If SOAP 1.2 has been specified as the default for the engine, // switch the constants over. String defaultSOAPVersion = (String)engine.getOption( AxisEngine.PROP_SOAP_VERSION); if (defaultSOAPVersion != null && "1.2".equals(defaultSOAPVersion)) { setSOAPConstants(SOAPConstants.SOAP12_CONSTANTS); } String singleSOAPVersion = (String)engine.getOption( AxisEngine.PROP_SOAP_ALLOWED_VERSION); if (singleSOAPVersion != null) { if ("1.2".equals(singleSOAPVersion)) { setProperty(Constants.MC_SINGLE_SOAP_VERSION, SOAPConstants.SOAP12_CONSTANTS); } else if ("1.1".equals(singleSOAPVersion)) { setProperty(Constants.MC_SINGLE_SOAP_VERSION, SOAPConstants.SOAP11_CONSTANTS); } } } } /** * during finalization, the dispose() method is called. * @see #dispose() */ protected void finalize() { dispose(); } /** * Mappings of QNames to serializers/deserializers (and therfore * to Java types). */ private TypeMappingRegistry mappingRegistry = null; /** * Replace the engine's type mapping registry with a local one. This will * have no effect on any type mappings obtained before this call. * * @param reg the new <code>TypeMappingRegistry</code> */ public void setTypeMappingRegistry(TypeMappingRegistry reg) { mappingRegistry = reg; } /** * Get the currently in-scope type mapping registry. * * By default, will return a reference to the AxisEngine's TMR until * someone sets our local one (usually as a result of setting the * serviceHandler). * * @return the type mapping registry to use for this request. */ public TypeMappingRegistry getTypeMappingRegistry() { if (mappingRegistry == null) { return axisEngine.getTypeMappingRegistry(); } return mappingRegistry; } /** * Return the type mapping currently in scope for our encoding style. * * @return the type mapping */ public TypeMapping getTypeMapping() { return (TypeMapping)getTypeMappingRegistry(). getTypeMapping(encodingStyle); } /** * The name of the transport for this context. * * @return the transport name */ public String getTransportName() { return transportName; } // fixme: the transport names should be a type-safe e-num, or the range // of legal values should be specified in the documentation and validated // in the method (raising IllegalArgumentException) /** * Set the transport name for this context. * * @param transportName the name of the transport */ public void setTransportName(String transportName) { this.transportName = transportName; } /** * Get the <code>SOAPConstants</code> used by this message context.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -