Save This Page
Home » axis2-1.5-src » org.apache » axis2 » context » [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.context;
   21   
   22   import org.apache.axiom.attachments.Attachments;
   23   import org.apache.axiom.om.OMOutputFormat;
   24   import org.apache.axiom.om.util.DetachableInputStream;
   25   import org.apache.axiom.om.util.UUIDGenerator;
   26   import org.apache.axiom.soap.SOAP11Constants;
   27   import org.apache.axiom.soap.SOAP12Constants;
   28   import org.apache.axiom.soap.SOAPEnvelope;
   29   import org.apache.axis2.AxisFault;
   30   import org.apache.axis2.Constants;
   31   import org.apache.axis2.Constants.Configuration;
   32   import org.apache.axis2.addressing.EndpointReference;
   33   import org.apache.axis2.addressing.RelatesTo;
   34   import org.apache.axis2.client.Options;
   35   import org.apache.axis2.context.externalize.ActivateUtils;
   36   import org.apache.axis2.context.externalize.ExternalizeConstants;
   37   import org.apache.axis2.context.externalize.MessageExternalizeUtils;
   38   import org.apache.axis2.context.externalize.SafeObjectInputStream;
   39   import org.apache.axis2.context.externalize.SafeObjectOutputStream;
   40   import org.apache.axis2.context.externalize.SafeSerializable;
   41   import org.apache.axis2.description.AxisBinding;
   42   import org.apache.axis2.description.AxisBindingMessage;
   43   import org.apache.axis2.description.AxisBindingOperation;
   44   import org.apache.axis2.description.AxisEndpoint;
   45   import org.apache.axis2.description.AxisMessage;
   46   import org.apache.axis2.description.AxisModule;
   47   import org.apache.axis2.description.AxisOperation;
   48   import org.apache.axis2.description.AxisService;
   49   import org.apache.axis2.description.AxisServiceGroup;
   50   import org.apache.axis2.description.HandlerDescription;
   51   import org.apache.axis2.description.ModuleConfiguration;
   52   import org.apache.axis2.description.Parameter;
   53   import org.apache.axis2.description.TransportInDescription;
   54   import org.apache.axis2.description.TransportOutDescription;
   55   import org.apache.axis2.engine.AxisConfiguration;
   56   import org.apache.axis2.engine.AxisError;
   57   import org.apache.axis2.engine.Handler;
   58   import org.apache.axis2.engine.Phase;
   59   import org.apache.axis2.util.JavaUtils;
   60   import org.apache.axis2.util.LoggingControl;
   61   import org.apache.axis2.util.MetaDataEntry;
   62   import org.apache.axis2.util.SelfManagedDataHolder;
   63   import org.apache.axis2.wsdl.WSDLConstants;
   64   import org.apache.axis2.wsdl.WSDLUtil;
   65   import org.apache.commons.logging.Log;
   66   import org.apache.commons.logging.LogFactory;
   67   import org.apache.neethi.Policy;
   68   
   69   import javax.activation.DataHandler;
   70   import javax.xml.namespace.QName;
   71   import java.io.ByteArrayInputStream;
   72   import java.io.ByteArrayOutputStream;
   73   import java.io.Externalizable;
   74   import java.io.IOException;
   75   import java.io.ObjectInput;
   76   import java.io.ObjectOutput;
   77   import java.util.ArrayList;
   78   import java.util.Collections;
   79   import java.util.HashMap;
   80   import java.util.Iterator;
   81   import java.util.LinkedHashMap;
   82   import java.util.LinkedList;
   83   import java.util.List;
   84   import java.util.Map;
   85   
   86   /**
   87    * <p>Axis2 states are held in two information models, called description hierarchy
   88    *  and context hierarchy. Description hierarchy hold deployment configuration 
   89    *  and it's values does not change unless deployment configuration change 
   90    *  occurs where Context hierarchy hold run time information. Both hierarchies 
   91    *  consists four levels, Global, Service Group, Operation and Message. Please 
   92    *  look at "Information Model" section  of "Axis2 Architecture Guide" for more 
   93    *  information.</p>
   94    *  <p>MessageContext hold run time information about one Message invocation. It 
   95    *  hold reference to OperationContext, ServiceGroupContext, and Configuration 
   96    *  Context tied with current message. For an example if you need accesses to other 
   97    *  messages of the current invocation, you can get to them via OperationContext. 
   98    *  Addition to class attributes define in Message context, message context stores 
   99    *  the information as name value pairs. Those name value pairs,and class attributes 
  100    *  tweak the execution behavior of message context and some of them can be find in 
  101    *  org.apache.axis2.Constants class. (TODO we should provide list of supported 
  102    *  options). You may set them at any level of context hierarchy and they will 
  103    *  affect invocations related to their child elements. </p>
  104    */
  105   public class MessageContext extends AbstractContext 
  106       implements Externalizable, SafeSerializable {
  107   
  108       /*
  109        * setup for logging
  110        */
  111       private static final Log log = LogFactory.getLog(MessageContext.class);
  112   
  113       /**
  114        * @serial An ID which can be used to correlate operations on a single
  115        * message in the log files, irrespective of thread switches, persistence,
  116        * etc.
  117        */
  118       private String logCorrelationID = null;
  119   
  120       /**
  121        * This string will be used to hold a form of the logCorrelationID that
  122        * is more suitable for output than its generic form.
  123        */
  124       private transient String logCorrelationIDString = null;
  125   
  126       private static final String myClassName = "MessageContext";
  127   
  128       /**
  129        * @serial The serialization version ID tracks the version of the class.
  130        * If a class definition changes, then the serialization/externalization
  131        * of the class is affected. If a change to the class is made which is
  132        * not compatible with the serialization/externalization of the class,
  133        * then the serialization version ID should be updated.
  134        * Refer to the "serialVer" utility to compute a serialization
  135        * version ID.
  136        */
  137       private static final long serialVersionUID = -7753637088257391858L;
  138   
  139       /**
  140        * @serial Tracks the revision level of a class to identify changes to the
  141        * class definition that are compatible to serialization/externalization.
  142        * If a class definition changes, then the serialization/externalization
  143        * of the class is affected.
  144        * Refer to the writeExternal() and readExternal() methods.
  145        */
  146       // supported revision levels, add a new level to manage compatible changes
  147       private static final int REVISION_2 = 2;
  148       // current revision level of this object
  149       private static final int revisionID = REVISION_2;
  150   
  151   
  152       /**
  153        * A place to store the current MessageContext
  154        */
  155       public static ThreadLocal<MessageContext> currentMessageContext = new ThreadLocal<MessageContext>();
  156   
  157       public static MessageContext getCurrentMessageContext() {
  158           return (MessageContext) currentMessageContext.get();
  159       }
  160   
  161       public static void setCurrentMessageContext(MessageContext ctx) {
  162           currentMessageContext.set(ctx);
  163       }
  164   
  165   
  166       /**
  167        * @serial Options on the message
  168        */
  169       protected Options options;
  170   
  171       public final static int IN_FLOW = 1;
  172       public final static int IN_FAULT_FLOW = 3;
  173   
  174       public final static int OUT_FLOW = 2;
  175       public final static int OUT_FAULT_FLOW = 4;
  176   
  177       public static final String REMOTE_ADDR = "REMOTE_ADDR";
  178       public static final String TRANSPORT_ADDR = "TRANSPORT_ADDR";
  179       public static final String TRANSPORT_HEADERS = "TRANSPORT_HEADERS";
  180   
  181   
  182       /**
  183        * message attachments
  184        * NOTE: Serialization of message attachments is handled as part of the
  185        * overall message serialization.  If this needs to change, then
  186        * investigate having the Attachment class implement the
  187        * java.io.Externalizable interface.
  188        */
  189       public transient Attachments attachments;
  190   
  191       /**
  192        * Field TRANSPORT_OUT
  193        */
  194       public static final String TRANSPORT_OUT = "TRANSPORT_OUT";
  195   
  196       /**
  197        * Field TRANSPORT_IN
  198        */
  199       public static final String TRANSPORT_IN = "TRANSPORT_IN";
  200   
  201       /**
  202        * Field CHARACTER_SET_ENCODING
  203        */
  204       public static final String CHARACTER_SET_ENCODING = "CHARACTER_SET_ENCODING";
  205   
  206       /**
  207        * Field UTF_8. This is the 'utf-8' value for CHARACTER_SET_ENCODING
  208        * property.
  209        */
  210       public static final String UTF_8 = "UTF-8";
  211   
  212       /**
  213        * Field UTF_16. This is the 'utf-16' value for CHARACTER_SET_ENCODING
  214        * property.
  215        */
  216       public static final String UTF_16 = "utf-16";
  217   
  218       /**
  219        * Field TRANSPORT_SUCCEED
  220        */
  221       public static final String TRANSPORT_SUCCEED = "TRANSPORT_SUCCEED";
  222   
  223       /**
  224        * Field DEFAULT_CHAR_SET_ENCODING. This is the default value for
  225        * CHARACTER_SET_ENCODING property.
  226        */
  227       public static final String DEFAULT_CHAR_SET_ENCODING = UTF_8;
  228   
  229       /**
  230        * @serial The direction flow in use to figure out which path the message is in
  231        * (send or receive)
  232        */
  233       public int FLOW = IN_FLOW;
  234   
  235       /**
  236        * To invoke fireAndforget method we have to hand over transport sending logic to a thread
  237        * other wise user has to wait till it get transport response (in the case of HTTP its HTTP
  238        * 202)
  239        */
  240       public static final String TRANSPORT_NON_BLOCKING = "transportNonBlocking";
  241   
  242       /**
  243        * This property allows someone (e.g. RM) to disable an async callback from
  244        * being invoked if a fault occurs during message transmission.  If this is
  245        * not set, it can be assumed that the fault will be delivered via
  246        * Callback.onError(...).
  247        */
  248       public static final String DISABLE_ASYNC_CALLBACK_ON_TRANSPORT_ERROR =
  249               "disableTransmissionErrorCallback";
  250   
  251       /**
  252        * @serial processingFault
  253        */
  254       private boolean processingFault;
  255   
  256       /**
  257        * @serial paused
  258        */
  259       private boolean paused;
  260   
  261       /**
  262        * @serial outputWritten
  263        */
  264       public boolean outputWritten;
  265   
  266       /**
  267        * @serial newThreadRequired
  268        */
  269       private boolean newThreadRequired;
  270   
  271       /**
  272        * @serial isSOAP11
  273        */
  274       private boolean isSOAP11 = true;
  275   
  276       /**
  277        * @serial The chain of Handlers/Phases for processing this message
  278        */
  279       private ArrayList<Handler> executionChain;
  280   
  281       /**
  282        * @serial The chain of executed Handlers/Phases from processing
  283        */
  284       private LinkedList<Handler> executedPhases;
  285   
  286       /**
  287        * @serial Flag to indicate if we are doing REST
  288        */
  289       private boolean doingREST;
  290   
  291       /**
  292        * @serial Flag to indicate if we are doing MTOM
  293        */
  294       private boolean doingMTOM;
  295   
  296       /**
  297        * @serial Flag to indicate if we are doing SWA
  298        */
  299       private boolean doingSwA;
  300   
  301       /**
  302        * AxisMessage associated with this message context
  303        */
  304       private transient AxisMessage axisMessage;
  305   
  306       /**
  307        * AxisOperation associated with this message context
  308        */
  309       private transient AxisOperation axisOperation;
  310   
  311       /**
  312        * AxisService
  313        */
  314       private transient AxisService axisService;
  315   
  316       /**
  317        * AxisServiceGroup
  318        * <p/>
  319        * Note the service group can be set independently of the service
  320        * so the service might not match up with this serviceGroup
  321        */
  322       private transient AxisServiceGroup axisServiceGroup;
  323   
  324       /**
  325        * ConfigurationContext
  326        */
  327       private transient ConfigurationContext configurationContext;
  328   
  329       /**
  330        * @serial Index into the executuion chain of the currently executing handler
  331        */
  332       private int currentHandlerIndex;
  333   
  334       /**
  335        * @serial Index into the current Phase of the currently executing handler (if any)
  336        */
  337       private int currentPhaseIndex;
  338   
  339       /**
  340        * If we're processing this MC due to flowComplete() being called in the case
  341        * of an Exception, this will hold the Exception which caused the problem.
  342        */
  343       private Exception failureReason;
  344   
  345       /**
  346        * @serial SOAP envelope
  347        */
  348       private SOAPEnvelope envelope;
  349   
  350       /**
  351        * @serial OperationContext
  352        */
  353       private OperationContext operationContext;
  354   
  355       /**
  356        * @serial responseWritten
  357        */
  358       private boolean responseWritten;
  359   
  360       /**
  361        * @serial serverSide
  362        */
  363       private boolean serverSide;
  364   
  365       /**
  366        * @serial ServiceContext
  367        */
  368       private ServiceContext serviceContext;
  369   
  370       /**
  371        * @serial service context ID
  372        */
  373       private String serviceContextID;
  374   
  375       /**
  376        * @serial service group context
  377        */
  378       private ServiceGroupContext serviceGroupContext;
  379   
  380       /**
  381        * @serial Holds a key to retrieve the correct ServiceGroupContext.
  382        */
  383       private String serviceGroupContextId;
  384   
  385       /**
  386        * @serial sessionContext
  387        */
  388       private SessionContext sessionContext;
  389   
  390   
  391       /**
  392        * transport out description
  393        */
  394       private transient TransportOutDescription transportOut;
  395   
  396       /**
  397        * transport in description
  398        */
  399       private transient TransportInDescription transportIn;
  400   
  401   
  402       /**
  403        * @serial incoming transport name
  404        */
  405       //The value will be set by the transport receiver and there will be validation for the transport
  406       //at the dispatch phase (its post condition)
  407       private String incomingTransportName;
  408   
  409   
  410       /*
  411        * SelfManagedData will hold message-specific data set by handlers
  412        * Note that this list is not explicitly saved by the MessageContext, but
  413        * rather through the SelfManagedDataManager interface implemented by handlers
  414        */
  415       private transient LinkedHashMap<String, Object> selfManagedDataMap = null;
  416   
  417       //-------------------------------------------------------------------------
  418       // MetaData for data to be restored in activate() after readExternal()
  419       //-------------------------------------------------------------------------
  420   
  421       /**
  422        * Indicates whether the message context has been reconstituted
  423        * and needs to have its object references reconciled
  424        */
  425       private transient boolean needsToBeReconciled = false;
  426   
  427       /**
  428        * selfManagedDataHandlerCount is a count of the number of handlers
  429        * that actually saved data during serialization
  430        */
  431       private transient int selfManagedDataHandlerCount = 0;
  432   
  433       /**
  434        * SelfManagedData cannot be restored until the configurationContext
  435        * is available, so we have to hold the data from readExternal until
  436        * activate is called.
  437        */
  438       private transient ArrayList<SelfManagedDataHolder> selfManagedDataListHolder = null;
  439   
  440       /**
  441        * The ordered list of metadata for handlers/phases
  442        * used during re-constitution of the message context
  443        */
  444       private transient ArrayList<MetaDataEntry> metaExecutionChain = null;
  445   
  446       /**
  447        * The ordered list of metadata for executed phases
  448        * used during re-constitution of the message context
  449        */
  450       private transient LinkedList<MetaDataEntry> metaExecuted = null;
  451   
  452       /**
  453        * Index into the executuion chain of the currently executing handler
  454        */
  455       private transient int metaHandlerIndex = 0;
  456   
  457       /**
  458        * Index into the current Phase of the currently executing handler (if any)
  459        */
  460       private transient int metaPhaseIndex = 0;
  461   
  462       /**
  463        * The AxisOperation metadata will be used during
  464        * activate to match up with an existing object
  465        */
  466       private transient MetaDataEntry metaAxisOperation = null;
  467   
  468       /**
  469        * The AxisService metadata will be used during
  470        * activate to match up with an existing object
  471        */
  472       private transient MetaDataEntry metaAxisService = null;
  473   
  474       /**
  475        * The AxisServiceGroup metadata will be used during
  476        * activate to match up with an existing object
  477        */
  478       private transient MetaDataEntry metaAxisServiceGroup = null;
  479   
  480       /**
  481        * The TransportOutDescription metadata will be used during
  482        * activate to match up with an existing object
  483        */
  484       private transient MetaDataEntry metaTransportOut = null;
  485   
  486       /**
  487        * The TransportInDescription metadata will be used during
  488        * activate to match up with an existing object
  489        */
  490       private transient MetaDataEntry metaTransportIn = null;
  491   
  492       /**
  493        * The AxisMessage metadata will be used during
  494        * activate to match up with an existing object
  495        */
  496       private transient MetaDataEntry metaAxisMessage = null;
  497   
  498       /**
  499        * Indicates whether this message context has an
  500        * AxisMessage object associated with it that needs to
  501        * be reconciled
  502        */
  503       private transient boolean reconcileAxisMessage = false;
  504   
  505       /**
  506        * Indicates whether the executed phase list
  507        * was reset before the restored list has been reconciled
  508        */
  509       private transient boolean executedPhasesReset = false;
  510   
  511       //----------------------------------------------------------------
  512       // end MetaData section
  513       //----------------------------------------------------------------
  514   
  515   
  516       /**
  517        * Constructor
  518        */
  519       public MessageContext() {
  520           super(null);
  521           options = new Options();
  522       }
  523   
  524       /**
  525        * Constructor has package access
  526        *
  527        * @param configContext the associated ConfigurationContext
  528        */
  529       MessageContext(ConfigurationContext configContext) {
  530           this();
  531           setConfigurationContext(configContext);
  532       }
  533   
  534       public String toString() {
  535           return getLogIDString();
  536       }
  537   
  538       /**
  539        * Get a "raw" version of the logCorrelationID.  The logCorrelationID
  540        * is guaranteed to be unique and may be persisted along with the rest
  541        * of the message context.
  542        *
  543        * @return A string that can be output to a log file as an identifier
  544        *         for this MessageContext.  It is suitable for matching related log
  545        *         entries.
  546        */
  547       public String getLogCorrelationID() {
  548           if (logCorrelationID == null) {
  549               logCorrelationID = UUIDGenerator.getUUID();
  550           }
  551           return logCorrelationID;
  552       }
  553   
  554       /**
  555        * Get a formatted version of the logCorrelationID.
  556        *
  557        * @return A string that can be output to a log file as an identifier
  558        *         for this MessageContext.  It is suitable for matching related log
  559        *         entries.
  560        */
  561       public String getLogIDString() {
  562           if (logCorrelationIDString == null) {
  563               logCorrelationIDString = "[MessageContext: logID=" + getLogCorrelationID() + "]";
  564           }
  565           return logCorrelationIDString;
  566       }
  567   
  568   
  569       /**
  570        * Pause the execution of the current handler chain
  571        */
  572       public void pause() {
  573           paused = true;
  574       }
  575   
  576       public AxisOperation getAxisOperation() {
  577           if (LoggingControl.debugLoggingAllowed) {
  578               checkActivateWarning("getAxisOperation");
  579           }
  580           return axisOperation;
  581       }
  582   
  583       public AxisService getAxisService() {
  584           if (LoggingControl.debugLoggingAllowed) {
  585               checkActivateWarning("getAxisService");
  586           }
  587           return axisService;
  588       }
  589   
  590       /*
  591        * <P>
  592        * Note the service group can be set independently of the service
  593        * so the service might not match up with this serviceGroup
  594       */
  595       public AxisServiceGroup getAxisServiceGroup() {
  596           if (LoggingControl.debugLoggingAllowed) {
  597               checkActivateWarning("getAxisServiceGroup");
  598           }
  599           return axisServiceGroup;
  600       }
  601   
  602       public ConfigurationContext getConfigurationContext() {
  603           if (LoggingControl.debugLoggingAllowed) {
  604               checkActivateWarning("getConfigurationContext");
  605           }
  606           return configurationContext;
  607       }
  608   
  609       public int getCurrentHandlerIndex() {
  610           return currentHandlerIndex;
  611       }
  612   
  613       public int getCurrentPhaseIndex() {
  614           return currentPhaseIndex;
  615       }
  616   
  617       /**
  618        * @return Returns SOAPEnvelope.
  619        */
  620       public SOAPEnvelope getEnvelope() {
  621           return envelope;
  622       }
  623   
  624       public ArrayList<Handler> getExecutionChain() {
  625           if (LoggingControl.debugLoggingAllowed) {
  626               checkActivateWarning("getExecutionChain");
  627           }
  628           return executionChain;
  629       }
  630   
  631       /**
  632        * Add a Phase to the collection of executed phases for the path.
  633        * Phases will be inserted in a LIFO data structure.
  634        *
  635        * @param phase The phase to add to the list.
  636        */
  637       public void addExecutedPhase(Handler phase) {
  638           if (executedPhases == null) {
  639               executedPhases = new LinkedList<Handler>();
  640           }
  641           executedPhases.addFirst(phase);
  642       }
  643   
  644       /**
  645        * Remove the first Phase in the collection of executed phases
  646        */
  647       public void removeFirstExecutedPhase() {
  648           if (executedPhases != null) {
  649               executedPhases.removeFirst();
  650           }
  651       }
  652   
  653       /**
  654        * Get an iterator over the executed phase list.
  655        *
  656        * @return An Iterator over the LIFO data structure.
  657        */
  658       public Iterator<Handler> getExecutedPhases() {
  659           if (LoggingControl.debugLoggingAllowed) {
  660               checkActivateWarning("getExecutedPhases");
  661           }
  662           if (executedPhases == null) {
  663               executedPhases = new LinkedList<Handler>();
  664           }
  665           return executedPhases.iterator();
  666       }
  667   
  668       /**
  669        * Reset the list of executed phases.
  670        * This is needed because the OutInAxisOperation currently invokes
  671        * receive() even when a fault occurs, and we will have already executed
  672        * the flowComplete on those before receiveFault() is called.
  673        */
  674       public void resetExecutedPhases() {
  675           executedPhasesReset = true;
  676           executedPhases = new LinkedList<Handler>();
  677       }
  678   
  679       /**
  680        * @return Returns EndpointReference.
  681        */
  682       public EndpointReference getFaultTo() {
  683           return options.getFaultTo();
  684       }
  685   
  686       /**
  687        * @return Returns EndpointReference.
  688        */
  689       public EndpointReference getFrom() {
  690           return options.getFrom();
  691       }
  692   
  693       /**
  694        * @return Returns message id.
  695        */
  696       public String getMessageID() {
  697           return options.getMessageId();
  698       }
  699   
  700       /**
  701        * Retrieves both module specific configuration parameters as well as other
  702        * parameters. The order of search is as follows:
  703        * <ol>
  704        * <li> Search in module configurations inside corresponding operation
  705        * description if its there </li>
  706        * <li> Search in corresponding operation if its there </li>
  707        * <li> Search in module configurations inside corresponding service
  708        * description if its there </li>
  709        * <li> Next search in Corresponding Service description if its there </li>
  710        * <li> Next search in module configurations inside axisConfiguration </li>
  711        * <li> Search in AxisConfiguration for parameters </li>
  712        * <li> Next get the corresponding module and search for the parameters
  713        * </li>
  714        * <li> Search in HandlerDescription for the parameter </li>
  715        * </ol>
  716        * <p/> and the way of specifying module configuration is as follows
  717        * <moduleConfig name="addressing"> <parameter name="addressingPara"
  718        * >N/A</parameter> </moduleConfig>
  719        *
  720        * @param key        :
  721        *                   Parameter Name
  722        * @param moduleName :
  723        *                   Name of the module
  724        * @param handler    <code>HandlerDescription</code>
  725        * @return Parameter <code>Parameter</code>
  726        */
  727       public Parameter getModuleParameter(String key, String moduleName,
  728                                           HandlerDescription handler) {
  729           Parameter param;
  730           ModuleConfiguration moduleConfig;
  731   
  732           AxisOperation opDesc = getAxisOperation();
  733   
  734           if (opDesc != null) {
  735   
  736               moduleConfig = opDesc.getModuleConfig(moduleName);
  737   
  738               if (moduleConfig != null) {
  739                   param = moduleConfig.getParameter(key);
  740   
  741                   if (param != null) {
  742                       return param;
  743                   } else {
  744                       param = opDesc.getParameter(key);
  745   
  746                       if (param != null) {
  747                           return param;
  748                       }
  749                   }
  750               }
  751           }
  752   
  753           AxisService axisService = getAxisService();
  754   
  755           if (axisService != null) {
  756   
  757               moduleConfig = axisService.getModuleConfig(moduleName);
  758   
  759               if (moduleConfig != null) {
  760                   param = moduleConfig.getParameter(key);
  761   
  762                   if (param != null) {
  763                       return param;
  764                   } else {
  765                       param = axisService.getParameter(key);
  766   
  767                       if (param != null) {
  768                           return param;
  769                       }
  770                   }
  771               }
  772           }
  773   
  774           AxisServiceGroup axisServiceDesc = getAxisServiceGroup();
  775   
  776           if (axisServiceDesc != null) {
  777   
  778               moduleConfig = axisServiceDesc.getModuleConfig(moduleName);
  779   
  780               if (moduleConfig != null) {
  781                   param = moduleConfig.getParameter(key);
  782   
  783                   if (param != null) {
  784                       return param;
  785                   } else {
  786                       param = axisServiceDesc.getParameter(key);
  787   
  788                       if (param != null) {
  789                           return param;
  790                       }
  791                   }
  792               }
  793           }
  794   
  795           AxisConfiguration baseConfig = configurationContext.getAxisConfiguration();
  796   
  797           moduleConfig = baseConfig.getModuleConfig(moduleName);
  798   
  799           if (moduleConfig != null) {
  800               param = moduleConfig.getParameter(key);
  801   
  802               if (param != null) {
  803                   return param;
  804               } else {
  805                   param = baseConfig.getParameter(key);
  806   
  807                   if (param != null) {
  808                       return param;
  809                   }
  810               }
  811           }
  812   
  813           AxisModule module = baseConfig.getModule(moduleName);
  814   
  815           if (module != null) {
  816               param = module.getParameter(key);
  817   
  818               if (param != null) {
  819                   return param;
  820               }
  821           }
  822   
  823           param = handler.getParameter(key);
  824   
  825           return param;
  826       }
  827   
  828       public OperationContext getOperationContext() {
  829           if (LoggingControl.debugLoggingAllowed) {
  830               checkActivateWarning("getOperationContext");
  831           }
  832           return operationContext;
  833       }
  834   
  835       /**
  836        * Retrieves configuration descriptor parameters at any level. The order of
  837        * search is as follows:
  838        * <ol>
  839        * <li> Search in message description if it exists </li>
  840        * <li> If parameter is not found or if axisMessage is null, search in
  841        * AxisOperation </li>
  842        * <li> If parameter is not found or if operationContext is null, search in
  843        * AxisService </li>
  844        * <li> If parameter is not found or if axisService is null, search in
  845        * AxisConfiguration </li>
  846        * </ol>
  847        *
  848        * @param key name of desired parameter
  849        * @return Parameter <code>Parameter</code>
  850        */
  851       public Parameter getParameter(String key) {
  852           
  853           if( axisMessage != null ) {
  854               return axisMessage.getParameter(key);
  855           }
  856           
  857           if (axisOperation != null) {
  858               return axisOperation.getParameter(key);
  859           }
  860   
  861           if (axisService != null) {
  862               return axisService.getParameter(key);
  863           }
  864   
  865           if (axisServiceGroup != null) {
  866               return axisServiceGroup.getParameter(key);
  867           }
  868   
  869           if (configurationContext != null) {
  870               AxisConfiguration baseConfig = configurationContext
  871                       .getAxisConfiguration();
  872               return baseConfig.getParameter(key);
  873           }
  874           return null;
  875       }
  876   
  877       /**
  878        * Retrieves a property value. The order of search is as follows: search in
  879        * my own map and then look at my options. Does not search up the hierarchy.
  880        *
  881        * @param name name of the property to search for
  882        * @return the value of the property, or null if the property is not found
  883        */
  884       public Object getLocalProperty(String name) {
  885           return getLocalProperty(name, true);
  886       }
  887       public Object getLocalProperty(String name, boolean searchOptions) {
  888           if (LoggingControl.debugLoggingAllowed) {
  889               checkActivateWarning("getProperty");
  890           }
  891   
  892           // search in my own options
  893           Object obj = super.getLocalProperty(name);
  894           if (obj != null) {
  895               return obj;
  896           }
  897   
  898           if (searchOptions) {
  899               obj = options.getProperty(name);
  900               if (obj != null) {
  901                   return obj;
  902               }
  903           }
  904   
  905           // tough
  906           return null;
  907       }
  908       
  909       /**
  910        * Retrieves a property value. The order of search is as follows: search in
  911        * my own map and then look in my context hierarchy, and then in options. 
  912        * Since its possible
  913        * that the entire hierarchy is not present, I will start at whatever level
  914        * has been set.
  915        *
  916        * @param name name of the property to search for
  917        * @return the value of the property, or null if the property is not found
  918        */
  919       public Object getProperty(String name) {
  920           if (LoggingControl.debugLoggingAllowed) {
  921               checkActivateWarning("getProperty");
  922           }
  923   
  924           // search in my own options
  925           Object obj = super.getProperty(name);
  926           if (obj != null) {
  927               return obj;
  928           }
  929   
  930           obj = options.getProperty(name);
  931           if (obj != null) {
  932               return obj;
  933           }
  934   
  935           // My own context hierarchy may not all be present. So look for whatever
  936           // nearest level is present and ask that to find the property.
  937           //
  938           // If the context is already an ancestor, it was checked during
  939           // the super.getProperty call.  In such cases, the second check 
  940           // is not performed.
  941           if (operationContext != null) {
  942               if (!isAncestor(operationContext)) {
  943                   obj = operationContext.getProperty(name);
  944               }
  945           } else if (serviceContext != null) {
  946               if (!isAncestor(serviceContext)) {
  947                   obj = serviceContext.getProperty(name);
  948               }
  949           } else if (serviceGroupContext != null) {
  950               if (!isAncestor(serviceGroupContext)) {
  951                   obj =  serviceGroupContext.getProperty(name);
  952               }
  953           } else if (configurationContext != null) {
  954               if (!isAncestor(configurationContext)) {
  955                   obj = configurationContext.getProperty(name);
  956               }
  957           }
  958   
  959           return obj;
  960       }
  961   
  962       /**
  963        * Check if a given property is true.  Will return false if the property
  964        * does not exist or is not an explicit "true" value.
  965        *
  966        * @param name name of the property to check
  967        * @return true if the property exists and is Boolean.TRUE, "true", 1, etc.
  968        */
  969       public boolean isPropertyTrue(String name) {
  970           return isPropertyTrue(name, false);
  971       }
  972   
  973       /**
  974        * Check if a given property is true.  Will return the passed default if the property
  975        * does not exist.
  976        *
  977        * @param name name of the property to check
  978        * @param defaultVal the default value if the property doesn't exist
  979        * @return true if the property exists and is Boolean.TRUE, "true", 1, etc.
  980        */
  981       public boolean isPropertyTrue(String name, boolean defaultVal) {
  982           return JavaUtils.isTrueExplicitly(getProperty(name), defaultVal);
  983       }
  984       
  985       /**
  986        * Retrieves all property values. The order of search is as follows: search in
  987        * my own options and then look in my context hierarchy. Since its possible
  988        * that the entire hierarchy is not present, it will start at whatever level
  989        * has been set and start there.
  990        * The returned map is unmodifiable, so any changes to the properties have
  991        * to be done by calling {@link #setProperty(String,Object)}. In addition,
  992        * any changes to the properties are not reflected on this map.
  993        *
  994        * @return An unmodifiable map containing the combination of all available
  995        *         properties or an empty map.
  996        */
  997       public Map<String, Object> getProperties() {
  998           final Map<String, Object> resultMap = new HashMap<String, Object>();
  999   
 1000           // My own context hierarchy may not all be present. So look for whatever
 1001           // nearest level is present and add the properties
 1002           // We have to access the contexts in reverse order, in order to allow
 1003           // a nearer context to overwrite values from a more distant context
 1004           if (configurationContext != null) {
 1005               resultMap.putAll(configurationContext.getProperties());
 1006           }
 1007           if (serviceGroupContext != null) {
 1008               resultMap.putAll(serviceGroupContext.getProperties());
 1009           }
 1010           if (serviceContext != null) {
 1011               resultMap.putAll(serviceContext.getProperties());
 1012           }
 1013           if (operationContext != null) {
 1014               resultMap.putAll(operationContext.getProperties());
 1015           }
 1016           // and now add options
 1017           resultMap.putAll(options.getProperties());
 1018           return Collections.unmodifiableMap(resultMap);
 1019       }
 1020   
 1021       /**
 1022        * @return Returns RelatesTo array.
 1023        */
 1024       public RelatesTo[] getRelationships() {
 1025           return options.getRelationships();
 1026       }
 1027   
 1028       /**
 1029        * Get any RelatesTos of a particular type associated with this MessageContext
 1030        * TODO: Shouldn't this return a List?
 1031        *
 1032        * @param type the relationship type
 1033        * @return Returns RelatesTo.
 1034        */
 1035       public RelatesTo getRelatesTo(String type) {
 1036           return options.getRelatesTo(type);
 1037       }
 1038   
 1039       /**
 1040        * @return Returns RelatesTo.
 1041        */
 1042       public RelatesTo getRelatesTo() {
 1043           return options.getRelatesTo();
 1044       }
 1045   
 1046       /**
 1047        * @return Returns EndpointReference.
 1048        */
 1049       public EndpointReference getReplyTo() {
 1050           return options.getReplyTo();
 1051       }
 1052   
 1053       /**
 1054        * @return Returns ServiceContext.
 1055        */
 1056       public ServiceContext getServiceContext() {
 1057           if (LoggingControl.debugLoggingAllowed) {
 1058               checkActivateWarning("getServiceContext");
 1059           }
 1060           return serviceContext;
 1061       }
 1062   
 1063       /**
 1064        * @return Returns the serviceContextID.
 1065        */
 1066       public String getServiceContextID() {
 1067           return serviceContextID;
 1068       }
 1069   
 1070       public ServiceGroupContext getServiceGroupContext() {
 1071           if (LoggingControl.debugLoggingAllowed) {
 1072               checkActivateWarning("getServiceGroupContext");
 1073           }
 1074           return serviceGroupContext;
 1075       }
 1076   
 1077       public String getServiceGroupContextId() {
 1078           return serviceGroupContextId;
 1079       }
 1080   
 1081       /**
 1082        * @return Returns SessionContext.
 1083        */
 1084       public SessionContext getSessionContext() {
 1085           return sessionContext;
 1086       }
 1087   
 1088       public void setSessionContext(SessionContext sessionContext) {
 1089           this.sessionContext = sessionContext;
 1090       }
 1091   
 1092   
 1093       /**
 1094        * @return Returns soap action.
 1095        */
 1096       public String getSoapAction() {
 1097           return options.getAction();
 1098       }
 1099   
 1100       /**
 1101        * @return Returns EndpointReference.
 1102        */
 1103       public EndpointReference getTo() {
 1104           return options.getTo();
 1105       }
 1106   
 1107       /**
 1108        * @return Returns TransportInDescription.
 1109        */
 1110       public TransportInDescription getTransportIn() {
 1111           if (LoggingControl.debugLoggingAllowed) {
 1112               checkActivateWarning("getTransportIn");
 1113           }
 1114           return transportIn;
 1115       }
 1116   
 1117       /**
 1118        * @return Returns TransportOutDescription.
 1119        */
 1120       public TransportOutDescription getTransportOut() {
 1121           if (LoggingControl.debugLoggingAllowed) {
 1122               checkActivateWarning("getTransportOut");
 1123           }
 1124           return transportOut;
 1125       }
 1126   
 1127       public String getWSAAction() {
 1128           return options.getAction();
 1129       }
 1130   
 1131       /**
 1132        * @return Returns boolean.
 1133        */
 1134       public boolean isDoingMTOM() {
 1135           return doingMTOM;
 1136       }
 1137   
 1138       /**
 1139        * @return Returns boolean.
 1140        */
 1141       public boolean isDoingREST() {
 1142           return doingREST;
 1143       }
 1144   
 1145       /**
 1146        * @return Returns boolean.
 1147        */
 1148       public boolean isDoingSwA() {
 1149           return doingSwA;
 1150       }
 1151   
 1152       /**
 1153        * @return Returns boolean.
 1154        */
 1155       public boolean isNewThreadRequired() {
 1156           return newThreadRequired;
 1157       }
 1158   
 1159       /**
 1160        * @return Returns boolean.
 1161        */
 1162       public boolean isOutputWritten() {
 1163           return outputWritten;
 1164       }
 1165   
 1166       /**
 1167        * @return Returns boolean.
 1168        */
 1169       public boolean isPaused() {
 1170           return paused;
 1171       }
 1172   
 1173       public void setPaused(boolean paused) {
 1174           this.paused = paused;
 1175       }
 1176   
 1177       /**
 1178        * @return Returns boolean.
 1179        */
 1180       public boolean isProcessingFault() {
 1181           return processingFault;
 1182       }
 1183   
 1184       /**
 1185        * @return Returns boolean.
 1186        */
 1187       public boolean isResponseWritten() {
 1188           return responseWritten;
 1189       }
 1190   
 1191       public boolean isSOAP11() {
 1192           return isSOAP11;
 1193       }
 1194   
 1195       /**
 1196        * @return inbound content length of 0
 1197        */
 1198       public long getInboundContentLength() throws IOException {
 1199           // If there is an attachment map, the Attachments keep track
 1200           // of the inbound content length.
 1201           if (attachments != null) {
 1202   //            return attachments.getContentLength();
 1203           } 
 1204           
 1205           // Otherwise the length is accumulated by the DetachableInputStream.
 1206           DetachableInputStream dis = 
 1207               (DetachableInputStream) getProperty(Constants.DETACHABLE_INPUT_STREAM);
 1208           if (dis != null) {
 1209               return dis.length();
 1210           }
 1211           return 0;
 1212       }
 1213       /**
 1214        * @return Returns boolean.
 1215        */
 1216       public boolean isServerSide() {
 1217           return serverSide;
 1218       }
 1219   
 1220       public AxisMessage getAxisMessage() {
 1221           if (reconcileAxisMessage) {
 1222               if (LoggingControl.debugLoggingAllowed && log.isWarnEnabled()) {
 1223                   log.warn(this.getLogIDString() +
 1224                       ":getAxisMessage(): ****WARNING**** MessageContext.activate(configurationContext) needs to be invoked.");
 1225               }
 1226           }
 1227   
 1228           return axisMessage;
 1229       }
 1230   
 1231       public void setAxisMessage(AxisMessage axisMessage) {
 1232           this.axisMessage = axisMessage;
 1233       }
 1234   
 1235       public void setAxisOperation(AxisOperation axisOperation) {
 1236           this.axisOperation = axisOperation;
 1237       }
 1238   
 1239       public void setAxisService(AxisService axisService) {
 1240           this.axisService = axisService;
 1241           if (this.axisService != null) {
 1242               this.axisServiceGroup = axisService.getAxisServiceGroup();
 1243           } else {
 1244               this.axisServiceGroup = null;
 1245           }
 1246       }
 1247   
 1248       /*
 1249        * note setAxisServiceGroup() does not verify that the service is associated with the service group!
 1250        */
 1251       public void setAxisServiceGroup(AxisServiceGroup axisServiceGroup) {
 1252           // need to set the axis service group object to null when necessary
 1253           // for example, when extracting the message context object from
 1254           // the object graph
 1255           this.axisServiceGroup = axisServiceGroup;
 1256       }
 1257   
 1258       /**
 1259        * @param context
 1260        */
 1261       public void setConfigurationContext(ConfigurationContext context) {
 1262           configurationContext = context;
 1263       }
 1264   
 1265       public void setCurrentHandlerIndex(int currentHandlerIndex) {
 1266           this.currentHandlerIndex = currentHandlerIndex;
 1267       }
 1268   
 1269       public void setCurrentPhaseIndex(int currentPhaseIndex) {
 1270           this.currentPhaseIndex = currentPhaseIndex;
 1271       }
 1272   
 1273       /**
 1274        * @param b
 1275        */
 1276       public void setDoingMTOM(boolean b) {
 1277           doingMTOM = b;
 1278       }
 1279   
 1280       /**
 1281        * @param b
 1282        */
 1283       public void setDoingREST(boolean b) {
 1284           doingREST = b;
 1285       }
 1286   
 1287       /**
 1288        * @param b
 1289        */
 1290       public void setDoingSwA(boolean b) {
 1291           doingSwA = b;
 1292       }
 1293   
 1294       /**
 1295        * @param envelope
 1296        */
 1297       public void setEnvelope(SOAPEnvelope envelope) throws AxisFault {
 1298           this.envelope = envelope;
 1299   
 1300           if (this.envelope != null) {
 1301               String soapNamespaceURI = envelope.getNamespace().getNamespaceURI();
 1302   
 1303               if (SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI
 1304                       .equals(soapNamespaceURI)) {
 1305                   isSOAP11 = false;
 1306               } else if (SOAP11Constants.SOAP_ENVELOPE_NAMESPACE_URI
 1307                       .equals(soapNamespaceURI)) {
 1308                   isSOAP11 = true;
 1309               } else {
 1310                   throw new AxisFault(
 1311                           "Unknown SOAP Version. Current Axis handles only SOAP 1.1 and SOAP 1.2 messages");
 1312               }
 1313               // Inform the listeners of an attach envelope event
 1314               if (getAxisService() != null) {
 1315                   getAxisService().attachEnvelopeEvent(this);
 1316               }
 1317           }
 1318       }
 1319   
 1320       /**
 1321        * Set the execution chain of Handler in this MessageContext. Doing this
 1322        * causes the current handler/phase indexes to reset to 0, since we have new
 1323        * Handlers to execute (this usually only happens at initialization and when
 1324        * a fault occurs).
 1325        *
 1326        * @param executionChain
 1327        */
 1328       public void setExecutionChain(ArrayList<Handler> executionChain) {
 1329           this.executionChain = executionChain;
 1330           currentHandlerIndex = -1;
 1331           currentPhaseIndex = 0;
 1332       }
 1333   
 1334       /**
 1335        * @param reference
 1336        */
 1337       public void setFaultTo(EndpointReference reference) {
 1338           options.setFaultTo(reference);
 1339       }
 1340   
 1341       /**
 1342        * @param reference
 1343        */
 1344       public void setFrom(EndpointReference reference) {
 1345           options.setFrom(reference);
 1346       }
 1347   
 1348       /**
 1349        * @param messageId
 1350        */
 1351       public void setMessageID(String messageId) {
 1352           options.setMessageId(messageId);
 1353       }
 1354   
 1355       /**
 1356        * @param b
 1357        */
 1358       public void setNewThreadRequired(boolean b) {
 1359           newThreadRequired = b;
 1360       }
 1361   
 1362       /**
 1363        * @param context The OperationContext
 1364        */
 1365       public void setOperationContext(OperationContext context) {
 1366           // allow setting the fields to null
 1367           // useful when extracting the messge context from the object graph
 1368           operationContext = context;
 1369   
 1370           this.setParent(operationContext);
 1371   
 1372           if (operationContext != null) {
 1373               if (serviceContext == null) {
 1374                   setServiceContext(operationContext.getServiceContext());
 1375               } else {
 1376                   if (operationContext.getParent() != serviceContext) {
 1377                       throw new AxisError("ServiceContext in OperationContext does not match !");
 1378                   }
 1379               }
 1380   
 1381               this.setAxisOperation(operationContext.getAxisOperation());
 1382           }
 1383       }
 1384   
 1385       /**
 1386        * @param b
 1387        */
 1388       public void setOutputWritten(boolean b) {
 1389           outputWritten = b;
 1390       }
 1391   
 1392       /**
 1393        * @param b
 1394        */
 1395       public void setProcessingFault(boolean b) {
 1396           processingFault = b;
 1397       }
 1398   
 1399       /**
 1400        * Add a RelatesTo
 1401        *
 1402        * @param reference RelatesTo describing how we relate to another message
 1403        */
 1404       public void addRelatesTo(RelatesTo reference) {
 1405           options.addRelatesTo(reference);
 1406       }
 1407   
 1408       /**
 1409        * Set ReplyTo destination
 1410        *
 1411        * @param reference the ReplyTo EPR
 1412        */
 1413       public void setReplyTo(EndpointReference reference) {
 1414           options.setReplyTo(reference);
 1415       }
 1416   
 1417       /**
 1418        * @param b
 1419        */
 1420       public void setResponseWritten(boolean b) {
 1421           responseWritten = b;
 1422       }
 1423   
 1424       /**
 1425        * @param b
 1426        */
 1427       public void setServerSide(boolean b) {
 1428           serverSide = b;
 1429       }
 1430   
 1431       /**
 1432        * @param context
 1433        */
 1434       public void setServiceContext(ServiceContext context) {
 1435   
 1436           // allow the service context to be set to null
 1437           // this allows the message context object to be extraced from
 1438           // the object graph
 1439   
 1440           serviceContext = context;
 1441   
 1442           if (serviceContext != null) {
 1443               if ((operationContext != null)
 1444                       && (operationContext.getParent() != context)) {
 1445                   throw new AxisError("ServiceContext and OperationContext.parent do not match!");
 1446               }
 1447               // setting configcontext using configuration context in service context
 1448               if (configurationContext == null) {
 1449                   // setting configcontext
 1450                   configurationContext = context.getConfigurationContext();
 1451               }
 1452               if (serviceGroupContext == null) {
 1453                   // setting service group context
 1454                   serviceGroupContext = context.getServiceGroupContext();
 1455               }
 1456               AxisService axisService = context.getAxisService();
 1457               this.setAxisService(axisService);
 1458               
 1459               // Inform the listeners of an attach event
 1460               if (axisService != null) {
 1461                   axisService.attachServiceContextEvent(serviceContext, this);
 1462               }
 1463           }
 1464       }
 1465   
 1466       /**
 1467        * Sets the service context id.
 1468        *
 1469        * @param serviceContextID
 1470        */
 1471       public void setServiceContextID(String serviceContextID) {
 1472           this.serviceContextID = serviceContextID;
 1473       }
 1474   
 1475       public void setServiceGroupContext(ServiceGroupContext serviceGroupContext) {
 1476           // allow the service group context to be set to null
 1477           // this allows the message context object to be extraced from
 1478           // the object graph
 1479   
 1480           this.serviceGroupContext = serviceGroupContext;
 1481   
 1482           if (this.serviceGroupContext != null) {
 1483               this.axisServiceGroup = serviceGroupContext.getDescription();
 1484           }
 1485       }
 1486   
 1487       public void setServiceGroupContextId(String serviceGroupContextId) {
 1488           this.serviceGroupContextId = serviceGroupContextId;
 1489       }
 1490   
 1491       /**
 1492        * @param soapAction
 1493        */
 1494       public void setSoapAction(String soapAction) {
 1495           options.setAction(soapAction);
 1496       }
 1497   
 1498       /**
 1499        * @param to
 1500        */
 1501       public void setTo(EndpointReference to) {
 1502           options.setTo(to);
 1503       }
 1504   
 1505       /**
 1506        * @param in
 1507        */
 1508       public void setTransportIn(TransportInDescription in) {
 1509           this.transportIn = in;
 1510       }
 1511   
 1512       /**
 1513        * @param out
 1514        */
 1515       public void setTransportOut(TransportOutDescription out) {
 1516           transportOut = out;
 1517       }
 1518   
 1519       /**
 1520        * setWSAAction
 1521        */
 1522       public void setWSAAction(String actionURI) {
 1523           options.setAction(actionURI);
 1524       }
 1525   
 1526       public void setWSAMessageId(String messageID) {
 1527           options.setMessageId(messageID);
 1528       }
 1529   
 1530       // to get the flow inwhich the execution chain below
 1531       public int getFLOW() {
 1532           return FLOW;
 1533       }
 1534   
 1535       public void setFLOW(int FLOW) {
 1536           this.FLOW = FLOW;
 1537       }
 1538   
 1539       public Options getOptions() {
 1540           if (LoggingControl.debugLoggingAllowed) {
 1541               checkActivateWarning("getOptions");
 1542           }
 1543           return options;
 1544       }
 1545   
 1546       /**
 1547        * Set the options for myself. I make the given options my own options'
 1548        * parent so that that becomes the default. That allows the user to override
 1549        * specific options on a given message context and not affect the overall
 1550        * options.
 1551        *
 1552        * @param options the options to set
 1553        */
 1554       public void setOptions(Options options) {
 1555           this.options.setParent(options);
 1556       }
 1557   
 1558       public String getIncomingTransportName() {
 1559           return incomingTransportName;
 1560       }
 1561   
 1562       public void setIncomingTransportName(String incomingTransportName) {
 1563           this.incomingTransportName = incomingTransportName;
 1564       }
 1565   
 1566       public void setRelationships(RelatesTo[] list) {
 1567           options.setRelationships(list);
 1568       }
 1569   
 1570   
 1571       public Policy getEffectivePolicy() {
 1572           if (LoggingControl.debugLoggingAllowed) {
 1573               checkActivateWarning("getEffectivePolicy");
 1574           }
 1575           
 1576           AxisBindingMessage bindingMessage = 
 1577           	(AxisBindingMessage) getProperty(Constants.AXIS_BINDING_MESSAGE);
 1578           
 1579           // If AxisBindingMessage is not set, try to find the binding message from the AxisService
 1580           if (bindingMessage == null) {
 1581           	bindingMessage = findBindingMessage();
 1582           }
 1583           
 1584           if (bindingMessage != null) {
 1585               return bindingMessage.getEffectivePolicy();
 1586           // If we can't find the AxisBindingMessage, then try the AxisMessage   
 1587           } else if (axisMessage != null) {
 1588           		return axisMessage.getEffectivePolicy();        		
 1589           } else {
 1590           		return null;
 1591           }
 1592       }
 1593    
 1594       private AxisBindingMessage findBindingMessage() {
 1595       	if (axisService != null && axisOperation != null ) {
 1596   			if (axisService.getEndpointName() != null) {
 1597   				AxisEndpoint axisEndpoint = axisService
 1598   						.getEndpoint(axisService.getEndpointName());
 1599   				if (axisEndpoint != null) {
 1600   					AxisBinding axisBinding = axisEndpoint.getBinding();
 1601                       AxisBindingOperation axisBindingOperation = (AxisBindingOperation) axisBinding
 1602   							.getChild(axisOperation.getName());
 1603   
 1604                       //If Binding Operation is not found, just return null
 1605                       if (axisBindingOperation == null) {
 1606                          return null;
 1607                       }
 1608   
 1609                       String direction = axisMessage.getDirection();
 1610   					AxisBindingMessage axisBindingMessage = null;
 1611   					if (WSDLConstants.WSDL_MESSAGE_DIRECTION_IN
 1612   							.equals(direction)
 1613   							&& WSDLUtil
 1614   									.isInputPresentForMEP(axisOperation
 1615   											.getMessageExchangePattern())) {
 1616   						axisBindingMessage = (AxisBindingMessage) axisBindingOperation
 1617   								.getChild(WSDLConstants.MESSAGE_LABEL_IN_VALUE);
 1618   						return axisBindingMessage;
 1619   						
 1620   					} else if (WSDLConstants.WSDL_MESSAGE_DIRECTION_OUT
 1621   							.equals(direction)
 1622   							&& WSDLUtil
 1623   									.isOutputPresentForMEP(axisOperation
 1624   											.getMessageExchangePattern())) {
 1625   						axisBindingMessage = (AxisBindingMessage) axisBindingOperation
 1626   								.getChild(WSDLConstants.MESSAGE_LABEL_OUT_VALUE);
 1627   						return axisBindingMessage;
 1628   					}
 1629   				}
 1630   
 1631   			}
 1632   		}
 1633       	return null;
 1634       }
 1635   
 1636   
 1637       public boolean isEngaged(String moduleName) {
 1638           if (LoggingControl.debugLoggingAllowed) {
 1639               checkActivateWarning("isEngaged");
 1640           }
 1641           boolean enegage;
 1642           if (configurationContext != null) {
 1643               AxisConfiguration axisConfig = configurationContext.getAxisConfiguration();
 1644               AxisModule module = axisConfig.getModule(moduleName);
 1645               if (module == null) {
 1646                   return false;
 1647               }
 1648               enegage = axisConfig.isEngaged(module);
 1649               if (enegage) {
 1650                   return true;
 1651               }
 1652               if (axisServiceGroup != null) {
 1653                   enegage = axisServiceGroup.isEngaged(module);
 1654                   if (enegage) {
 1655                       return true;
 1656                   }
 1657               }
 1658               if (axisService != null) {
 1659                   enegage = axisService.isEngaged(module);
 1660                   if (enegage) {
 1661                       return true;
 1662                   }
 1663               }
 1664               if (axisOperation != null) {
 1665                   enegage = axisOperation.isEngaged(module);
 1666                   if (enegage) {
 1667                       return true;
 1668                   }
 1669               }
 1670           }
 1671           return false;
 1672       }
 1673   
 1674       /**
 1675        * Gets the first child of the envelope, check if it is a soap:Body, which means there is no header.
 1676        * We do this basically to make sure we don't parse and build the om tree of the whole envelope
 1677        * looking for the soap header. If this method returns true, there still is no guarantee that there is
 1678        * a soap:Header present, use getHeader() and also check for null on getHeader() to be absolutely sure.
 1679        *
 1680        * @return boolean
 1681        * @deprecated The bonus you used to get from this is now built in to SOAPEnvelope.getHeader()
 1682        */
 1683       public boolean isHeaderPresent() {
 1684           // If there's no envelope there can't be a header.
 1685           if (this.envelope == null) {
 1686               return false;
 1687           }
 1688           return (this.envelope.getHeader() != null);
 1689       }
 1690   
 1691       /**
 1692        * Setting of the attachments map should be performed at the receipt of a
 1693        * message only. This method is only meant to be used by the Axis2
 1694        * internals.
 1695        *
 1696        * @param attachments
 1697        */
 1698       public void setAttachmentMap(Attachments attachments) {
 1699           this.attachments = attachments;
 1700       }
 1701   
 1702       /**
 1703        * You can directly access the attachment map of the message context from
 1704        * here. Returned attachment map can be empty.
 1705        *
 1706        * @return attachment
 1707        */
 1708       public Attachments getAttachmentMap() {
 1709           if (attachments == null) {
 1710               attachments = new Attachments();
 1711           }
 1712           return attachments;
 1713       }
 1714   
 1715       /**
 1716        * Adds an attachment to the attachment Map of this message context. This
 1717        * attachment gets serialised as a MIME attachment when sending the message
 1718        * if SOAP with Attachments is enabled.
 1719        *
 1720        * @param contentID   :
 1721        *                    will be the content ID of the MIME part (without the "cid:" prefix)
 1722        * @param dataHandler
 1723        */
 1724       public void addAttachment(String contentID, DataHandler dataHandler) {
 1725           if (attachments == null) {
 1726               attachments = new Attachments();
 1727           }
 1728           attachments.addDataHandler(contentID, dataHandler);
 1729       }
 1730   
 1731       /**
 1732        * Adds an attachment to the attachment Map of this message context. This
 1733        * attachment gets serialised as a MIME attachment when sending the message
 1734        * if SOAP with Attachments is enabled. Content ID of the MIME part will be
 1735        * auto generated by Axis2.
 1736        *
 1737        * @param dataHandler
 1738        * @return the auto generated content ID of the MIME attachment
 1739        */
 1740       public String addAttachment(DataHandler dataHandler) {
 1741           String contentID = UUIDGenerator.getUUID();
 1742           addAttachment(contentID, dataHandler);
 1743           return contentID;
 1744       }
 1745   
 1746       /**
 1747        * Access the DataHandler of the attachment contained in the map corresponding to the given
 1748        * content ID. Returns "NULL" if a attachment cannot be found by the given content ID.
 1749        *
 1750        * @param contentID :
 1751        *                  Content ID of the MIME attachment (without the "cid:" prefix)
 1752        * @return Data handler of the attachment
 1753        */
 1754       public DataHandler getAttachment(String contentID) {
 1755           if (attachments == null) {
 1756               attachments = new Attachments();
 1757           }
 1758           return attachments.getDataHandler(contentID);
 1759       }
 1760   
 1761       /**
 1762        * Removes the attachment with the given content ID from the Attachments Map
 1763        * Do nothing if a attachment cannot be found by the given content ID.
 1764        *
 1765        * @param contentID of the attachment (without the "cid:" prefix)
 1766        */
 1767       public void removeAttachment(String contentID) {
 1768           if (attachments != null) {
 1769               attachments.removeDataHandler(contentID);
 1770           }
 1771       }
 1772   
 1773       /*
 1774        * ===============================================================
 1775        * SelfManagedData Section
 1776        * ===============================================================
 1777        */
 1778   
 1779       /*
 1780       * character to delimit strings
 1781       */
 1782       private String selfManagedDataDelimiter = "*";
 1783   
 1784   
 1785       /**
 1786        * Set up a unique key in the form of
 1787        * <OL>
 1788        * <LI>the class name for the class that owns the key
 1789        * <LI>delimitor
 1790        * <LI>the key as a string
 1791        * <LI>delimitor
 1792        * <LI>the key's hash code as a string
 1793        * </OL>
 1794        *
 1795        * @param clazz The class that owns the supplied key
 1796        * @param key   The key
 1797        * @return A string key
 1798        */
 1799       private String generateSelfManagedDataKey(Class clazz, Object key) {
 1800           return clazz.getName() + selfManagedDataDelimiter + key.toString() +
 1801                   selfManagedDataDelimiter + Integer.toString(key.hashCode());
 1802       }
 1803   
 1804       /**
 1805        * Add a key-value pair of self managed data to the set associated with
 1806        * this message context.
 1807        * <p/>
 1808        * This is primarily intended to allow handlers to manage their own
 1809        * message-specific data when the message context is saved/restored.
 1810        *
 1811        * @param clazz The class of the caller that owns the key-value pair
 1812        * @param key   The key for this data object
 1813        * @param value The data object
 1814        */
 1815       public void setSelfManagedData(Class clazz, Object key, Object value) {
 1816           if (selfManagedDataMap == null) {
 1817               selfManagedDataMap = new LinkedHashMap<String, Object>();
 1818           }
 1819   
 1820           // make sure we have a unique key and a delimiter so we can
 1821           // get the classname and hashcode for serialization/deserialization
 1822           selfManagedDataMap.put(generateSelfManagedDataKey(clazz, key), value);
 1823       }
 1824   
 1825       /**
 1826        * Retrieve a value of self managed data previously saved with the specified key.
 1827        *
 1828        * @param clazz The class of the caller that owns the key-value pair
 1829        * @param key   The key for the data
 1830        * @return The data object associated with the key, or NULL if not found
 1831        */
 1832       public Object getSelfManagedData(Class clazz, Object key) {
 1833           if (selfManagedDataMap != null) {
 1834               return selfManagedDataMap.get(generateSelfManagedDataKey(clazz, key));
 1835           }
 1836           return null;
 1837       }
 1838   
 1839       /**
 1840        * Check to see if the key for the self managed data is available
 1841        *
 1842        * @param clazz The class of the caller that owns the key-value pair
 1843        * @param key   The key to look for
 1844        * @return TRUE if the key exists, FALSE otherwise
 1845        */
 1846       public boolean containsSelfManagedDataKey(Class clazz, Object key) {
 1847           if (selfManagedDataMap == null) {
 1848               return false;
 1849           }
 1850           return selfManagedDataMap.containsKey(generateSelfManagedDataKey(clazz, key));
 1851       }
 1852   
 1853       /**
 1854        * Removes the mapping of the specified key if the specified key
 1855        * has been set for self managed data
 1856        *
 1857        * @param clazz The class of the caller that owns the key-value pair
 1858        * @param key   The key of the object to be removed
 1859        */
 1860       public void removeSelfManagedData(Class clazz, Object key) {
 1861           if (selfManagedDataMap != null) {
 1862               selfManagedDataMap.remove(generateSelfManagedDataKey(clazz, key));
 1863           }
 1864       }
 1865   
 1866       /**
 1867        * Flatten the phase list into a list of just unique handler instances
 1868        *
 1869        * @param list the list of handlers
 1870        * @param map  users should pass null as this is just a holder for the recursion
 1871        * @return a list of unigue object instances
 1872        */
 1873       private ArrayList<Handler> flattenPhaseListToHandlers(ArrayList<Handler> list, LinkedHashMap<String, Handler> map) {
 1874   
 1875           if (map == null) {
 1876               map = new LinkedHashMap<String, Handler>();
 1877           }
 1878   
 1879           Iterator<Handler> it = list.iterator();
 1880           while (it.hasNext()) {
 1881               Handler handler = (Handler) it.next();
 1882   
 1883               String key = null;
 1884               if (handler != null) {
 1885                   key = handler.getClass().getName() + "@" + handler.hashCode();
 1886               }
 1887   
 1888               if (handler instanceof Phase) {
 1889                   // add its handlers to the list
 1890                   flattenHandlerList(((Phase) handler).getHandlers(), map);
 1891               } else {
 1892                   // if the same object is already in the list,
 1893                   // then it won't be in the list multiple times
 1894                   map.put(key, handler);
 1895               }
 1896           }
 1897   
 1898           if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
 1899               Iterator<String> it2 = map.keySet().iterator();
 1900               while (it2.hasNext()) {
 1901                   Object key = it2.next();
 1902                   Handler value = (Handler) map.get(key);
 1903                   String name = value.getName();
 1904                   log.trace(getLogIDString() + ":flattenPhaseListToHandlers():  key [" + key +
 1905                           "]    handler name [" + name + "]");
 1906               }
 1907           }
 1908   
 1909   
 1910           return new ArrayList<Handler>(map.values());
 1911       }
 1912   
 1913   
 1914       /**
 1915        * Flatten the handler list into just unique handler instances
 1916        * including phase instances.
 1917        *
 1918        * @param list the list of handlers/phases
 1919        * @param map  users should pass null as this is just a holder for the recursion
 1920        * @return a list of unigue object instances
 1921        */
 1922       private ArrayList<Handler> flattenHandlerList(List<Handler> list, LinkedHashMap<String, Handler> map) {
 1923   
 1924           if (map == null) {
 1925               map = new LinkedHashMap<String, Handler>();
 1926           }
 1927   
 1928           Iterator<Handler> it = list.iterator();
 1929           while (it.hasNext()) {
 1930               Handler handler = (Handler) it.next();
 1931   
 1932               String key = null;
 1933               if (handler != null) {
 1934                   key = handler.getClass().getName() + "@" + handler.hashCode();
 1935               }
 1936   
 1937               if (handler instanceof Phase) {
 1938                   // put the phase in the list
 1939                   map.put(key, handler);
 1940   
 1941                   // add its handlers to the list
 1942                   flattenHandlerList(((Phase) handler).getHandlers(), map);
 1943               } else {
 1944                   // if the same object is already in the list,
 1945                   // then it won't be in the list multiple times
 1946                   map.put(key, handler);
 1947               }
 1948           }
 1949   
 1950           return new ArrayList<Handler>(map.values());
 1951       }
 1952   
 1953   
 1954       /**
 1955        * Calls the serializeSelfManagedData() method of each handler that
 1956        * implements the <bold>SelfManagedDataManager</bold> interface.
 1957        * Handlers for this message context are identified via the
 1958        * executionChain list.
 1959        *
 1960        * @param out The output stream
 1961        */
 1962       private void serializeSelfManagedData(ObjectOutput out) {
 1963           selfManagedDataHandlerCount = 0;
 1964   
 1965           try {
 1966               if ((selfManagedDataMap == null)
 1967                       || (executionChain == null)
 1968                       || (selfManagedDataMap.size() == 0)
 1969                       || (executionChain.size() == 0)) {
 1970                   out.writeBoolean(ExternalizeConstants.EMPTY_OBJECT);
 1971   
 1972                   if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
 1973                       log.trace(getLogIDString() + ":serializeSelfManagedData(): No data : END");
 1974                   }
 1975   
 1976                   return;
 1977               }
 1978   
 1979               // let's create a temporary list with the handlers
 1980               ArrayList<Handler> flatExecChain = flattenPhaseListToHandlers(executionChain, null);
 1981   
 1982               //ArrayList selfManagedDataHolderList = serializeSelfManagedDataHelper(flatExecChain.iterator(), new ArrayList());
 1983               ArrayList<SelfManagedDataHolder> selfManagedDataHolderList = serializeSelfManagedDataHelper(flatExecChain);
 1984   
 1985               if (selfManagedDataHolderList.size() == 0) {
 1986                   out.writeBoolean(ExternalizeConstants.EMPTY_OBJECT);
 1987   
 1988                   if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
 1989                       log.trace(getLogIDString() + ":serializeSelfManagedData(): No data : END");
 1990                   }
 1991   
 1992                   return;
 1993               }
 1994   
 1995               out.writeBoolean(ExternalizeConstants.ACTIVE_OBJECT);
 1996   
 1997               // SelfManagedData can be binary so won't be able to treat it as a
 1998               // string - need to treat it as a byte []
 1999   
 2000               // how many handlers actually
 2001               // returned serialized SelfManagedData
 2002               out.writeInt(selfManagedDataHolderList.size());
 2003   
 2004               for (int i = 0; i < selfManagedDataHolderList.size(); i++) {
 2005                   out.writeObject(selfManagedDataHolderList.get(i));
 2006               }
 2007   
 2008           }
 2009           catch (IOException e) {
 2010               if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
 2011                   log.trace("MessageContext:serializeSelfManagedData(): Exception [" +
 2012                       e.getClass().getName() + "]  description [" + e.getMessage() + "]", e);
 2013               }
 2014           }
 2015   
 2016       }
 2017   
 2018   
 2019       /**
 2020        * This is the helper method to do the recursion for serializeSelfManagedData()
 2021        *
 2022        * @param handlers
 2023        * @return ArrayList
 2024        */
 2025       private ArrayList<SelfManagedDataHolder> serializeSelfManagedDataHelper(ArrayList<Handler> handlers) {
 2026           ArrayList<SelfManagedDataHolder> selfManagedDataHolderList = new ArrayList<SelfManagedDataHolder>();
 2027           Iterator<Handler> it = handlers.iterator();
 2028   
 2029           try {
 2030               while (it.hasNext()) {
 2031                   Handler handler = (Handler) it.next();
 2032   
 2033                   //if (handler instanceof Phase)
 2034                   //{
 2035                   //    selfManagedDataHolderList = serializeSelfManagedDataHelper(((Phase)handler).getHandlers().iterator(), selfManagedDataHolderList);
 2036                   //}
 2037                   //else if (SelfManagedDataManager.class.isAssignableFrom(handler.getClass()))
 2038                   if (SelfManagedDataManager.class.isAssignableFrom(handler.getClass())) {
 2039                       // only call the handler's serializeSelfManagedData if it implements SelfManagedDataManager
 2040   
 2041                       if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
 2042                           log.trace(
 2043                                   "MessageContext:serializeSelfManagedDataHelper(): calling handler  [" +
 2044                                           handler.getClass().getName() + "]  name [" +
 2045                                           handler.getName() + "]   serializeSelfManagedData method");
 2046                       }
 2047   
 2048                       ByteArrayOutputStream baos_fromHandler =
 2049                               ((SelfManagedDataManager) handler).serializeSelfManagedData(this);
 2050   
 2051                       if (baos_fromHandler != null) {
 2052                           baos_fromHandler.close();
 2053   
 2054                           try {
 2055                               SelfManagedDataHolder selfManagedDataHolder = new SelfManagedDataHolder(
 2056                                       handler.getClass().getName(), handler.getName(),
 2057                                       baos_fromHandler.toByteArray());
 2058                               selfManagedDataHolderList.add(selfManagedDataHolder);
 2059                               selfManagedDataHandlerCount++;
 2060                           }
 2061                           catch (Exception exc) {
 2062                               if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
 2063                                   log.trace("MessageContext:serializeSelfManagedData(): exception [" +
 2064                                       exc.getClass().getName() + "][" + exc.getMessage() +
 2065                                       "]  in setting up SelfManagedDataHolder object for [" +
 2066                                       handler.getClass().getName() + " / " + handler.getName() + "] ",
 2067                                         exc);
 2068                               }
 2069                           }
 2070                       }
 2071                   }
 2072               }
 2073   
 2074               return selfManagedDataHolderList;
 2075           }
 2076           catch (Exception ex) {
 2077               if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
 2078                   log.trace("MessageContext:serializeSelfManagedData(): exception [" +
 2079                       ex.getClass().getName() + "][" + ex.getMessage() + "]", ex);
 2080               }
 2081               return null;
 2082           }
 2083   
 2084       }
 2085   
 2086       /**
 2087        * During deserialization, the executionChain will be
 2088        * re-constituted before the SelfManagedData is restored.
 2089        * This means the handler instances are already available.
 2090        * This method lets us find the handler instance from the
 2091        * executionChain so we can call each one's
 2092        * deserializeSelfManagedData method.
 2093        *
 2094        * @param it            The iterator from the executionChain object
 2095        * @param classname     The class name
 2096        * @param qNameAsString The QName in string form
 2097        * @return SelfManagedDataManager handler
 2098        */
 2099       private SelfManagedDataManager deserialize_getHandlerFromExecutionChain(Iterator<Handler> it,
 2100                                                                               String classname,
 2101                                                                               String qNameAsString) {
 2102           SelfManagedDataManager handler_toreturn = null;
 2103   
 2104           try {
 2105               while ((it.hasNext()) && (handler_toreturn == null)) {
 2106                   Handler handler = (Handler) it.next();
 2107   
 2108                   if (handler instanceof Phase) {
 2109                       handler_toreturn = deserialize_getHandlerFromExecutionChain(
 2110                               ((Phase) handler).getHandlers().iterator(), classname, qNameAsString);
 2111                   } else if ((handler.getClass().getName().equals(classname))
 2112                           && (handler.getName().equals(qNameAsString))) {
 2113                       handler_toreturn = (SelfManagedDataManager) handler;
 2114                   }
 2115               }
 2116               return handler_toreturn;
 2117           }
 2118           catch (ClassCastException e) {
 2119               // Doesn't seem likely to happen, but just in case...
 2120               // A handler classname in the executionChain matched up with our parameter
 2121               // classname, but the existing class in the executionChain is a different
 2122               // implementation than the one we saved during serializeSelfManagedData.
 2123               // NOTE: the exception gets absorbed!
 2124   
 2125               if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
 2126                   log.trace(
 2127                       "MessageContext:deserialize_getHandlerFromExecutionChain(): ClassCastException thrown: " +
 2128                               e.getMessage(), e);
 2129               }
 2130               return null;
 2131           }
 2132       }
 2133   
 2134   
 2135       /*
 2136       * We don't need to create new instances of the handlers
 2137       * since the executionChain is rebuilt after readExternal().
 2138       * We just have to find them in the executionChain and
 2139       * call each handler's deserializeSelfManagedData method.
 2140       */
 2141       private void deserializeSelfManagedData() throws IOException {
 2142           try {
 2143               for (int i = 0;
 2144                    (selfManagedDataListHolder != null) && (i < selfManagedDataListHolder.size()); i++)
 2145               {
 2146                   SelfManagedDataHolder selfManagedDataHolder =
 2147                           (SelfManagedDataHolder) selfManagedDataListHolder.get(i);
 2148   
 2149                   String classname = selfManagedDataHolder.getClassname();
 2150                   String qNameAsString = selfManagedDataHolder.getId();
 2151   
 2152                   SelfManagedDataManager handler = deserialize_getHandlerFromExecutionChain(
 2153                           executionChain.iterator(), classname, qNameAsString);
 2154   
 2155                   if (handler == null) {
 2156                       if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
 2157                           log.trace(getLogIDString() + ":deserializeSelfManagedData():  [" +
 2158                                   classname +
 2159                                   "]  was not found in the executionChain associated with the message context.");
 2160                       }
 2161   
 2162                       throw new IOException("The class [" + classname +
 2163                               "] was not found in the executionChain associated with the message context.");
 2164                   }
 2165   
 2166                   ByteArrayInputStream handlerData =
 2167                           new ByteArrayInputStream(selfManagedDataHolder.getData());
 2168   
 2169                   // the handler implementing SelfManagedDataManager is responsible for repopulating
 2170                   // the SelfManagedData in the MessageContext (this)
 2171   
 2172                   if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
 2173                       log.trace(getLogIDString() +
 2174                               ":deserializeSelfManagedData(): calling handler [" + classname + "] [" +
 2175                               qNameAsString + "]  deserializeSelfManagedData method");
 2176                   }
 2177   
 2178                   handler.deserializeSelfManagedData(handlerData, this);
 2179                   handler.restoreTransientData(this);
 2180               }
 2181           }
 2182           catch (IOException ioe) {
 2183               if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
 2184                   log.trace(getLogIDString() + ":deserializeSelfManagedData(): IOException thrown: " +
 2185                           ioe.getMessage(), ioe);
 2186               }
 2187               throw ioe;
 2188           }
 2189   
 2190       }
 2191   
 2192       /* ===============================================================
 2193       * Externalizable support
 2194       * ===============================================================
 2195       */
 2196   
 2197   
 2198       /**
 2199        * Save the contents of this MessageContext instance.
 2200        * <p/>
 2201        * NOTE: Transient fields and static fields are not saved.
 2202        * Also, objects that represent "static" data are
 2203        * not saved, except for enough information to be
 2204        * able to find matching objects when the message
 2205        * context is re-constituted.
 2206        *
 2207        * @param out The stream to write the object contents to
 2208        * @throws IOException
 2209        */
 2210       public void writeExternal(ObjectOutput o) throws IOException {
 2211           SafeObjectOutputStream out = SafeObjectOutputStream.install(o);
 2212           String logCorrelationIDString = getLogIDString();
 2213   
 2214           if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
 2215               log.trace(logCorrelationIDString + ":writeExternal(): writing to output stream");
 2216           }
 2217   
 2218           //---------------------------------------------------------
 2219           // in order to handle future changes to the message
 2220           // context definition, be sure to maintain the
 2221           // object level identifiers
 2222           //---------------------------------------------------------
 2223           // serialization version ID
 2224           out.writeLong(serialVersionUID);
 2225   
 2226           // revision ID
 2227           out.writeInt(revisionID);
 2228   
 2229           //---------------------------------------------------------
 2230           // various simple fields
 2231           //---------------------------------------------------------
 2232   
 2233           // the type of execution flow for the message context
 2234           out.writeInt(FLOW);
 2235   
 2236           // various flags
 2237           out.writeBoolean(processingFault);
 2238           out.writeBoolean(paused);
 2239           out.writeBoolean(outputWritten);
 2240           out.writeBoolean(newThreadRequired);
 2241           out.writeBoolean(isSOAP11);
 2242           out.writeBoolean(doingREST);
 2243           out.writeBoolean(doingMTOM);
 2244           out.writeBoolean(doingSwA);
 2245           out.writeBoolean(responseWritten);
 2246           out.writeBoolean(serverSide);
 2247   
 2248           out.writeLong(getLastTouchedTime());
 2249           out.writeObject(getLogCorrelationID());
 2250   
 2251           //-----------------------------------------------------------------------
 2252           // Create and initialize the OMOutputFormat for Message Externalization
 2253           //-----------------------------------------------------------------------
 2254           
 2255           OMOutputFormat outputFormat= new OMOutputFormat();
 2256           outputFormat.setSOAP11(isSOAP11);
 2257           boolean persistOptimized = getPersistOptimized();
 2258           if (persistOptimized) {
 2259               outputFormat.setDoOptimize(true);
 2260           }
 2261           String charSetEnc = (String) getProperty(MessageContext.CHARACTER_SET_ENCODING);
 2262           if (charSetEnc == null) {
 2263               OperationContext opContext = getOperationContext();
 2264               if (opContext != null) {
 2265                   charSetEnc =
 2266                           (String) opContext.getProperty(MessageContext.CHARACTER_SET_ENCODING);
 2267               }
 2268           }
 2269           if (charSetEnc == null) {
 2270               charSetEnc = MessageContext.DEFAULT_CHAR_SET_ENCODING;
 2271           }
 2272           outputFormat.setCharSetEncoding(charSetEnc);
 2273   
 2274           // ----------------------------------------------------------
 2275           // Externalize the Message
 2276           // ----------------------------------------------------------
 2277           MessageExternalizeUtils.writeExternal(out, this, logCorrelationIDString, outputFormat);
 2278   
 2279           // ---------------------------------------------------------
 2280           // ArrayList executionChain
 2281           //     handler and phase related data
 2282           //---------------------------------------------------------
 2283           // The strategy is to save some metadata about each
 2284           // member of the list and the order of the list.
 2285           // Then when the message context is re-constituted,
 2286           // try to match up with phases and handlers on the
 2287           // engine.
 2288           //
 2289           // Non-null list:
 2290           //    UTF          - description string
 2291           //    boolean      - active flag
 2292           //    int          - current handler index
 2293           //    int          - current phase index
 2294           //    int          - expected number of entries in the list
 2295           //    objects      - MetaDataEntry object per list entry
 2296           //                        last entry will be empty MetaDataEntry
 2297           //                        with MetaDataEntry.LAST_ENTRY marker
 2298           //    int          - adjusted number of entries in the list
 2299           //                        includes the last empty entry
 2300           //
 2301           // Empty list:
 2302           //    UTF          - description string
 2303           //    boolean      - empty flag
 2304           //---------------------------------------------------------
 2305           out.writeUTF("executionChain");
 2306           if (executionChain != null && executionChain.size() > 0) {
 2307               // start writing data to the output stream
 2308               out.writeBoolean(ExternalizeConstants.ACTIVE_OBJECT);
 2309               out.writeInt(currentHandlerIndex);
 2310               out.writeInt(currentPhaseIndex);
 2311               out.writeInt(executionChain.size());
 2312   
 2313               // put the metadata on each member of the list into a buffer
 2314   
 2315               // match the current index with the actual saved list
 2316               int nextIndex = 0;
 2317   
 2318               Iterator<Handler> i = executionChain.iterator();
 2319   
 2320               while (i.hasNext()) {
 2321                   Object obj = i.next();
 2322                   String objClass = obj.getClass().getName();
 2323                   // start the meta data entry for this object
 2324                   MetaDataEntry mdEntry = new MetaDataEntry();
 2325                   mdEntry.setClassName(objClass);
 2326   
 2327                   // get the correct object-specific name
 2328                   String qnameAsString;
 2329   
 2330                   if (obj instanceof Phase) {
 2331                       Phase phaseObj = (Phase) obj;
 2332                       qnameAsString = phaseObj.getName();
 2333   
 2334                       // add the list of handlers to the meta data
 2335                       setupPhaseList(phaseObj, mdEntry);
 2336                   } else if (obj instanceof Handler) {
 2337                       Handler handlerObj = (Handler) obj;
 2338                       qnameAsString = handlerObj.getName();
 2339                   } else {
 2340                       // TODO: will there be any other kinds of objects in the execution Chain?
 2341                       qnameAsString = "NULL";
 2342                   }
 2343   
 2344                   mdEntry.setQName(qnameAsString);
 2345   
 2346                   // update the index for the entry in the chain
 2347   
 2348                   if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
 2349                       log.trace(logCorrelationIDString +
 2350                               ":writeExternal(): ***BEFORE OBJ WRITE*** executionChain entry class [" +
 2351                               objClass + "] qname [" + qnameAsString + "]");
 2352                   }
 2353   
 2354                   out.writeObject(mdEntry);
 2355   
 2356                   // update the index so that the index
 2357                   // now indicates the next entry that
 2358                   // will be attempted
 2359                   nextIndex++;
 2360   
 2361                   if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
 2362                       log.trace(logCorrelationIDString +
 2363                               ":writeExternal(): ***AFTER OBJ WRITE*** executionChain entry class [" +
 2364                               objClass + "] qname [" + qnameAsString + "]");
 2365                   }
 2366   
 2367               } // end while entries in execution chain
 2368   
 2369               // done with the entries in the execution chain
 2370               // add the end-of-list marker
 2371               MetaDataEntry lastEntry = new MetaDataEntry();
 2372               lastEntry.setClassName(MetaDataEntry.END_OF_LIST);
 2373   
 2374               out.writeObject(lastEntry);
 2375               nextIndex++;
 2376   
 2377               // nextIndex also gives us the number of entries
 2378               // that were actually saved as opposed to the
 2379               // number of entries in the executionChain
 2380               out.writeInt(nextIndex);
 2381   
 2382           } else {
 2383               // general case: handle "null" or "empty"
 2384               out.writeBoolean(ExternalizeConstants.EMPTY_OBJECT);
 2385   
 2386               if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
 2387                   log.trace(logCorrelationIDString + ":writeExternal(): executionChain is NULL");
 2388               }
 2389           }
 2390   
 2391           //---------------------------------------------------------
 2392           // LinkedList executedPhases
 2393           //---------------------------------------------------------
 2394           // The strategy is to save some metadata about each
 2395           // member of the list and the order of the list.
 2396           // Then when the message context is re-constituted,
 2397           // try to match up with phases and handlers on the
 2398           // engine.
 2399           //
 2400           // Non-null list:
 2401           //    UTF          - description string
 2402           //    boolean      - active flag
 2403           //    int          - expected number of entries in the list
 2404           //    objects      - MetaDataEntry object per list entry
 2405           //                        last entry will be empty MetaDataEntry
 2406           //                        with MetaDataEntry.LAST_ENTRY marker
 2407           //    int          - adjusted number of entries in the list
 2408           //                        includes the last empty entry
 2409           //
 2410           // Empty list:
 2411           //    UTF          - description string
 2412           //    boolean      - empty flag
 2413           //---------------------------------------------------------
 2414           out.writeUTF("executedPhases");
 2415           if (executedPhases != null && executedPhases.size() > 0) {
 2416           
 2417               // start writing data to the output stream
 2418               out.writeBoolean(ExternalizeConstants.ACTIVE_OBJECT);
 2419               out.writeInt(executedPhases.size());
 2420   
 2421               // put the metadata on each member of the list into a buffer
 2422   
 2423               int execNextIndex = 0;
 2424   
 2425               Iterator<Handler> iterator = executedPhases.iterator();
 2426   
 2427               while (iterator.hasNext()) {
 2428                   Object obj = iterator.next();
 2429                   String objClass = obj.getClass().getName();
 2430                   // start the meta data entry for this object
 2431                   MetaDataEntry mdEntry = new MetaDataEntry();
 2432                   mdEntry.setClassName(objClass);
 2433   
 2434                   // get the correct object-specific name
 2435                   String qnameAsString;
 2436   
 2437                   if (obj instanceof Phase) {
 2438                       Phase inPhaseObj = (Phase) obj;
 2439                       qnameAsString = inPhaseObj.getName();
 2440   
 2441                       // add the list of handlers to the meta data
 2442                       setupPhaseList(inPhaseObj, mdEntry);
 2443                   } else if (obj instanceof Handler) {
 2444                       Handler inHandlerObj = (Handler) obj;
 2445                       qnameAsString = inHandlerObj.getName();
 2446                   } else {
 2447                       // TODO: will there be any other kinds of objects in the list
 2448                       qnameAsString = "NULL";
 2449                   }
 2450   
 2451                   mdEntry.setQName(qnameAsString);
 2452   
 2453                   if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
 2454                       log.trace(logCorrelationIDString +
 2455                               ":writeExternal(): ***BEFORE Executed List OBJ WRITE*** executedPhases entry class [" +
 2456                               objClass + "] qname [" + qnameAsString + "]");
 2457                   }
 2458   
 2459                   out.writeObject(mdEntry);
 2460   
 2461                   // update the index so that the index
 2462                   // now indicates the next entry that
 2463                   // will be attempted
 2464                   execNextIndex++;
 2465   
 2466                   if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
 2467                       log.trace(logCorrelationIDString + ":writeExternal(): " +
 2468                               "***AFTER Executed List OBJ WRITE*** " +
 2469                               "executedPhases entry class [" + objClass + "] " +
 2470                               "qname [" + qnameAsString + "]");
 2471                   }
 2472               } // end while entries in execution chain
 2473   
 2474               // done with the entries in the execution chain
 2475               // add the end-of-list marker
 2476               MetaDataEntry lastEntry = new MetaDataEntry();
 2477               lastEntry.setClassName(MetaDataEntry.END_OF_LIST);
 2478   
 2479               out.writeObject(lastEntry);
 2480               execNextIndex++;
 2481   
 2482               // execNextIndex also gives us the number of entries
 2483               // that were actually saved as opposed to the
 2484               // number of entries in the executedPhases
 2485               out.writeInt(execNextIndex);
 2486   
 2487           } else {
 2488               // general case: handle "null" or "empty"
 2489               out.writeBoolean(ExternalizeConstants.EMPTY_OBJECT);
 2490   
 2491               if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
 2492                   log.trace(
 2493                           logCorrelationIDString + ":writeExternal(): executedPhases is NULL");
 2494               }
 2495           }
 2496   
 2497           //---------------------------------------------------------
 2498           // options
 2499           //---------------------------------------------------------
 2500           // before saving the Options, make sure there is a message ID
 2501           String tmpID = getMessageID();
 2502           if (tmpID == null) {
 2503               // get an id to use when restoring this object
 2504               tmpID = UUIDGenerator.getUUID();
 2505               setMessageID(tmpID);
 2506           }
 2507   
 2508           if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
 2509               log.trace(logCorrelationIDString + ":writeExternal():   message ID [" + tmpID + "]");
 2510           }
 2511   
 2512           out.writeUTF("options");
 2513           out.writeObject(options);
 2514           
 2515           //---------------------------------------------------------
 2516           // operation
 2517           //---------------------------------------------------------
 2518           // axis operation
 2519           //---------------------------------------------------------
 2520           out.writeUTF("axisOperation");
 2521           metaAxisOperation = null;
 2522           if (axisOperation != null) {
 2523               // TODO: may need to include the meta data for the axis service that is
 2524               //       the parent of the axis operation
 2525               // make sure the axis operation has a name associated with it
 2526               QName aoTmpQName = axisOperation.getName();
 2527   
 2528               if (aoTmpQName == null) {
 2529                   aoTmpQName = new QName(ExternalizeConstants.EMPTY_MARKER);
 2530                   axisOperation.setName(aoTmpQName);
 2531               }
 2532   
 2533               metaAxisOperation = new MetaDataEntry(axisOperation.getClass().getName(),
 2534                                                     axisOperation.getName().toString());
 2535           }
 2536           out.writeObject(metaAxisOperation);
 2537   
 2538           //---------------------------------------------------------
 2539           // operation context
 2540           //---------------------------------------------------------
 2541           // The OperationContext has pointers to MessageContext objects.
 2542           // In order to avoid having multiple copies of the object graph
 2543           // being saved at different points in the serialization,
 2544           // it is important to isolate this message context object.
 2545           out.writeUTF("operationContext");
 2546           if (operationContext != null) {
 2547               operationContext.isolateMessageContext(this);
 2548           }
 2549   
 2550           out.writeObject(operationContext);
 2551      
 2552   
 2553           //---------------------------------------------------------
 2554           // service
 2555           //---------------------------------------------------------
 2556           // axis service
 2557           //-------------------------
 2558           // this is expected to be the parent of the axis operation object
 2559           out.writeUTF("axisService");
 2560           metaAxisService = null;
 2561           if (axisService != null) {
 2562               metaAxisService = new MetaDataEntry(axisService.getClass().getName(), 
 2563                                                   axisService.getName());
 2564           }
 2565           out.writeObject(metaAxisService);
 2566   
 2567           //-------------------------
 2568           // serviceContextID string
 2569           //-------------------------
 2570           out.writeObject(serviceContextID);
 2571   
 2572           //-------------------------
 2573           // serviceContext
 2574           //-------------------------
 2575           // is this the same as the parent of the OperationContext?
 2576           boolean isParent = false;
 2577           out.writeUTF("serviceContext");
 2578   
 2579           if (operationContext != null) {
 2580               ServiceContext opctxParent = operationContext.getServiceContext();
 2581   
 2582               if (serviceContext != null) {
 2583                   if (serviceContext.equals(opctxParent)) {
 2584                       // the ServiceContext is the parent of the OperationContext
 2585                       isParent = true;
 2586                   }
 2587               }
 2588           }
 2589   
 2590           if (serviceContext == null) {
 2591               out.writeBoolean(ExternalizeConstants.EMPTY_OBJECT);
 2592           } else {
 2593               out.writeBoolean(ExternalizeConstants.ACTIVE_OBJECT);
 2594               out.writeBoolean(isParent);
 2595   
 2596               // only write out the object if it is not the parent
 2597               if (!isParent) {
 2598                   out.writeObject(serviceContext);
 2599               }
 2600           }
 2601   
 2602           //---------------------------------------------------------
 2603           // axisServiceGroup
 2604           //---------------------------------------------------------
 2605           out.writeUTF("axisServiceGroup");
 2606           metaAxisServiceGroup = null;
 2607           if (axisServiceGroup != null) {
 2608               metaAxisServiceGroup = new MetaDataEntry(axisServiceGroup.getClass().getName(),
 2609                                                        axisServiceGroup.getServiceGroupName());
 2610           }
 2611           out.writeObject(metaAxisServiceGroup);
 2612   
 2613           //-----------------------------
 2614           // serviceGroupContextId string
 2615           //-----------------------------
 2616           out.writeObject(serviceGroupContextId);
 2617   
 2618           //-------------------------
 2619           // serviceGroupContext
 2620           //-------------------------
 2621           // is this the same as the parent of the ServiceContext?
 2622           isParent = false;
 2623           out.writeUTF("serviceGroupContext");
 2624   
 2625           if (serviceContext != null) {
 2626               ServiceGroupContext srvgrpctxParent = (ServiceGroupContext) serviceContext.getParent();
 2627   
 2628               if (serviceGroupContext != null) {
 2629                   if (serviceGroupContext.equals(srvgrpctxParent)) {
 2630                       // the ServiceGroupContext is the parent of the ServiceContext
 2631                       isParent = true;
 2632                   }
 2633               }
 2634           }
 2635   
 2636           if (serviceGroupContext == null) {
 2637               out.writeBoolean(ExternalizeConstants.EMPTY_OBJECT);
 2638           } else {
 2639               out.writeBoolean(ExternalizeConstants.ACTIVE_OBJECT);
 2640               out.writeBoolean(isParent);
 2641   
 2642               // only write out the object if it is not the parent
 2643               if (!isParent) {
 2644                   out.writeObject(serviceGroupContext);
 2645               }
 2646           }
 2647   
 2648           //---------------------------------------------------------
 2649           // axis message
 2650           //---------------------------------------------------------
 2651           out.writeUTF("axisMessage");
 2652           metaAxisMessage = null;
 2653           if (axisMessage != null) {
 2654               // This AxisMessage is expected to belong to the AxisOperation
 2655               // that has already been recorded for this MessageContext.
 2656               // If an AxisMessage associated with this Messagecontext is
 2657               // associated with a different AxisOperation, then more
 2658               // meta information would need to be saved
 2659   
 2660               // make sure the axis message has a name associated with it
 2661               String amTmpName = axisMessage.getName();
 2662   
 2663               if (amTmpName == null) {
 2664                   amTmpName = ExternalizeConstants.EMPTY_MARKER;
 2665                   axisMessage.setName(amTmpName);
 2666               }
 2667   
 2668               // get the element name if there is one
 2669               QName amTmpElementQName = axisMessage.getElementQName();
 2670               String amTmpElemQNameString = null;
 2671   
 2672               if (amTmpElementQName != null) {
 2673                   amTmpElemQNameString = amTmpElementQName.toString();
 2674               }
 2675   
 2676               metaAxisMessage = new MetaDataEntry(axisMessage.getClass().getName(),
 2677                                                   axisMessage.getName(), amTmpElemQNameString);
 2678   
 2679           }
 2680           out.writeObject(metaAxisMessage);
 2681   
 2682           //---------------------------------------------------------
 2683           // configuration context
 2684           //---------------------------------------------------------
 2685   
 2686           // NOTE: Currently, there does not seem to be any
 2687           //       runtime data important to this message context
 2688           //       in the configuration context.
 2689           //       if so, then need to save that runtime data and reconcile
 2690           //       it with the configuration context on the system when
 2691           //       this message context object is restored
 2692   
 2693           //---------------------------------------------------------
 2694           // session context
 2695           //---------------------------------------------------------
 2696           out.writeObject(sessionContext);
 2697   
 2698           //---------------------------------------------------------
 2699           // transport
 2700           //---------------------------------------------------------
 2701   
 2702           //------------------------------
 2703           // incomingTransportName string
 2704           //------------------------------
 2705           out.writeObject(incomingTransportName);
 2706   
 2707           // TransportInDescription transportIn
 2708           metaTransportIn = null;
 2709           if (transportIn != null) {
 2710               metaTransportIn = new MetaDataEntry(null, transportIn.getName());
 2711           } 
 2712           out.writeObject(metaTransportIn);
 2713   
 2714           // TransportOutDescription transportOut
 2715           metaTransportOut = null;
 2716           if (transportOut != null) {
 2717               metaTransportOut = new MetaDataEntry(null, transportOut.getName());
 2718           }
 2719           out.writeObject(metaTransportOut);
 2720           
 2721   
 2722           //---------------------------------------------------------
 2723           // properties
 2724           //---------------------------------------------------------
 2725           // Write out the local properties on the MessageContext
 2726           // Don't write out the properties from other hierarchical layers.
 2727           // (i.e. don't use getProperties())
 2728           out.writeUTF("properties"); // write marker
 2729           out.writeMap(properties);
 2730   
 2731           //---------------------------------------------------------
 2732           // special data
 2733           //---------------------------------------------------------
 2734           out.writeUTF("selfManagedData");
 2735           serializeSelfManagedData(out);
 2736   
 2737           //---------------------------------------------------------
 2738           // done
 2739           //---------------------------------------------------------
 2740   
 2741           if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
 2742               log.trace(logCorrelationIDString +
 2743                       ":writeExternal(): completed writing to output stream for " +
 2744                       logCorrelationIDString);
 2745           }
 2746   
 2747       }
 2748       
 2749       /**
 2750        * @return true if the data should be persisted as optimized attachments
 2751        */
 2752       private boolean getPersistOptimized() {
 2753           boolean persistOptimized = false;
 2754           if (attachments != null && attachments.getContentIDList().size() > 1) {
 2755               persistOptimized = true;
 2756               if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled())
 2757                   log.trace(getLogIDString()
 2758                           + ":getPersistOptimized(): attachments present; persist optimized");
 2759           }
 2760           if (!persistOptimized) {
 2761               Object property = getProperty(Configuration.ENABLE_MTOM);
 2762               if (property != null && JavaUtils.isTrueExplicitly(property)) {
 2763                   persistOptimized = true;
 2764                   if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled())
 2765                       log.trace(getLogIDString()
 2766                               + ":getPersistOptimized(): ENBABLE_MTOM is set; persist optimized");
 2767               }
 2768           }
 2769           if (!persistOptimized) {
 2770               Object property = getProperty(Configuration.ENABLE_SWA);
 2771               if (property != null && JavaUtils.isTrueExplicitly(property)) {
 2772                   persistOptimized = true;
 2773                   if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled())
 2774                       log.trace(getLogIDString()
 2775                               + ":getPersistOptimized(): ENBABLE_SWA is set; persist optimized");
 2776               }
 2777           }
 2778           if (!persistOptimized && LoggingControl.debugLoggingAllowed && log.isTraceEnabled())
 2779               log.trace(getLogIDString()
 2780                       + ":getPersistOptimized(): No attachments or attachment settings; persist non-optimized");
 2781           return persistOptimized;
 2782       }
 2783   
 2784   
 2785       /**
 2786        * Restore the contents of the MessageContext that was
 2787        * previously saved.
 2788        * <p/>
 2789        * NOTE: The field data must read back in the same order and type
 2790        * as it was written.  Some data will need to be validated when
 2791        * resurrected.
 2792        *
 2793        * @param in The stream to read the object contents from
 2794        * @throws IOException
 2795        * @throws ClassNotFoundException
 2796        */
 2797       public void readExternal(ObjectInput inObject) throws IOException, ClassNotFoundException {        
 2798           SafeObjectInputStream in = SafeObjectInputStream.install(inObject);
 2799           // set the flag to indicate that the message context is being
 2800           // reconstituted and will need to have certain object references
 2801           // to be reconciled with the current engine setup
 2802           needsToBeReconciled = true;
 2803   
 2804           // trace point
 2805           if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
 2806               log.trace(myClassName + ":readExternal():  BEGIN  bytes available in stream [" +
 2807                       in.available() + "]  ");
 2808           }
 2809   
 2810           //---------------------------------------------------------
 2811           // object level identifiers
 2812           //---------------------------------------------------------
 2813   
 2814           // serialization version ID
 2815           long suid = in.readLong();
 2816   
 2817           // revision ID
 2818           int revID = in.readInt();
 2819   
 2820           // make sure the object data is in a version we can handle
 2821           if (suid != serialVersionUID) {
 2822               throw new ClassNotFoundException(ExternalizeConstants.UNSUPPORTED_SUID);
 2823           }
 2824   
 2825           // make sure the object data is in a revision level we can handle
 2826           if (revID != REVISION_2) {
 2827               throw new ClassNotFoundException(ExternalizeConstants.UNSUPPORTED_REVID);
 2828           }
 2829   
 2830           //---------------------------------------------------------
 2831           // various simple fields
 2832           //---------------------------------------------------------
 2833   
 2834           // the type of execution flow for the message context
 2835           FLOW = in.readInt();
 2836   
 2837           // various flags
 2838           processingFault = in.readBoolean();
 2839           paused = in.readBoolean();
 2840           outputWritten = in.readBoolean();
 2841           newThreadRequired = in.readBoolean();
 2842           isSOAP11 = in.readBoolean();
 2843           doingREST = in.readBoolean();
 2844           doingMTOM = in.readBoolean();
 2845           doingSwA = in.readBoolean();
 2846           responseWritten = in.readBoolean();
 2847           serverSide = in.readBoolean();
 2848   
 2849           long time = in.readLong();
 2850           setLastTouchedTime(time);
 2851           logCorrelationID = (String) in.readObject();
 2852   
 2853           // trace point
 2854           if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
 2855               logCorrelationIDString = "[MessageContext: logID=" + getLogCorrelationID() + "]";
 2856               log.trace(myClassName + ":readExternal():  reading the input stream for  " +
 2857                         getLogIDString());
 2858           }
 2859   
 2860           //---------------------------------------------------------
 2861           // Message
 2862           // Read the message and attachments
 2863           //---------------------------------------------------------
 2864           envelope = MessageExternalizeUtils.readExternal(in, this, getLogIDString());
 2865   
 2866           //---------------------------------------------------------
 2867           // ArrayList executionChain
 2868           //     handler and phase related data
 2869           //---------------------------------------------------------
 2870           // Restore the metadata about each member of the list
 2871           // and the order of the list.
 2872           // This metadata will be used to match up with phases
 2873           // and handlers on the engine.
 2874           //
 2875           // Non-null list:
 2876           //    UTF          - description string
 2877           //    boolean      - active flag
 2878           //    int          - current handler index
 2879           //    int          - current phase index
 2880           //    int          - expected number of entries in the list
 2881           //                        not including the last entry marker
 2882           //    objects      - MetaDataEntry object per list entry
 2883           //                        last entry will be empty MetaDataEntry
 2884           //                        with MetaDataEntry.LAST_ENTRY marker
 2885           //    int          - adjusted number of entries in the list
 2886           //                        includes the last empty entry
 2887           //
 2888           // Empty list:
 2889           //    UTF          - description string
 2890           //    boolean      - empty flag
 2891           //---------------------------------------------------------
 2892   
 2893           // the local chain is not enabled until the
 2894           // list has been reconstituted
 2895           executionChain = null;
 2896           currentHandlerIndex = -1;
 2897           currentPhaseIndex = 0;
 2898           metaExecutionChain = null;
 2899   
 2900           String marker = in.readUTF();
 2901           if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
 2902               log.trace(getLogIDString() + 
 2903                         ": readExternal(): About to read executionChain, marker is: " + marker);
 2904           }
 2905           boolean gotChain = in.readBoolean();
 2906   
 2907           if (gotChain == ExternalizeConstants.ACTIVE_OBJECT) {
 2908               metaHandlerIndex = in.readInt();
 2909               metaPhaseIndex = in.readInt();
 2910   
 2911               int expectedNumberEntries = in.readInt();
 2912   
 2913               if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
 2914                   log.trace(getLogIDString() +
 2915                           ":readExternal(): execution chain:  expected number of entries [" +
 2916                           expectedNumberEntries + "]");
 2917               }
 2918   
 2919               // setup the list
 2920               metaExecutionChain = new ArrayList<MetaDataEntry>();
 2921   
 2922               // process the objects
 2923               boolean keepGoing = true;
 2924               int count = 0;
 2925   
 2926               while (keepGoing) {
 2927                   // stop when we get to the end-of-list marker
 2928   
 2929                   // get the object
 2930                   Object tmpObj = in.readObject();
 2931   
 2932                   count++;
 2933   
 2934                   MetaDataEntry mdObj = (MetaDataEntry) tmpObj;
 2935   
 2936                   // get the class name, then add it to the list
 2937                   String tmpClassNameStr;
 2938                   String tmpQNameAsStr;
 2939   
 2940                   if (mdObj != null) {
 2941                       tmpClassNameStr = mdObj.getClassName();
 2942   
 2943                       if (tmpClassNameStr.equalsIgnoreCase(MetaDataEntry.END_OF_LIST)) {
 2944                           // this is the last entry
 2945                           keepGoing = false;
 2946                       } else {
 2947                           // add the entry to the meta data list
 2948                           metaExecutionChain.add(mdObj);
 2949   
 2950                           tmpQNameAsStr = mdObj.getQNameAsString();
 2951   
 2952                           if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
 2953                               String tmpHasList = mdObj.isListEmpty() ? "no children" : "has children";
 2954   
 2955                               if (log.isTraceEnabled()) {
 2956                                   log.trace(getLogIDString() +
 2957                                       ":readExternal(): meta data class [" + tmpClassNameStr +
 2958                                       "] qname [" + tmpQNameAsStr + "]  index [" + count + "]   [" +
 2959                                       tmpHasList + "]");
 2960                               }
 2961                           }
 2962                       }
 2963                   } else {
 2964                       // some error occurred
 2965                       keepGoing = false;
 2966                   }
 2967   
 2968               } // end while keep going
 2969   
 2970               int adjustedNumberEntries = in.readInt();
 2971   
 2972               if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
 2973                   log.trace(getLogIDString() +
 2974                           ":readExternal(): adjusted number of entries ExecutionChain [" +
 2975                           adjustedNumberEntries + "]    ");
 2976               }
 2977           }
 2978   
 2979           if ((metaExecutionChain == null) || (metaExecutionChain.isEmpty())) {
 2980               if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
 2981                   log.trace(getLogIDString() +
 2982                           ":readExternal(): meta data for Execution Chain is NULL");
 2983               }
 2984           }
 2985   
 2986           //---------------------------------------------------------
 2987           // LinkedList executedPhases
 2988           //
 2989           // Note that in previous versions of Axis2, this was
 2990           // represented by two lists: "inboundExecutedPhases", "outboundExecutedPhases",
 2991           // however since the message context itself represents a flow
 2992           // direction, one of these lists was always null.  This was changed
 2993           // around 2007-06-08 revision r545615.  For backward compatability
 2994           // with streams saved in previous versions of Axis2, we need
 2995           // to be able to process both the old style and new style.
 2996           //---------------------------------------------------------
 2997           // Restore the metadata about each member of the list
 2998           // and the order of the list.
 2999           // This metadata will be used to match up with phases
 3000           // and handlers on the engine.
 3001           //
 3002           // Non-null list:
 3003           //    UTF          - description string
 3004           //    boolean      - active flag
 3005           //    int          - expected number of entries in the list
 3006           //                        not including the last entry marker
 3007           //    objects      - MetaDataEntry object per list entry
 3008           //                        last entry will be empty MetaDataEntry
 3009           //                        with MetaDataEntry.LAST_ENTRY marker
 3010           //    int          - adjusted number of entries in the list
 3011           //                        includes the last empty entry
 3012           //
 3013           // Empty list:
 3014           //    UTF          - description string
 3015           //    boolean      - empty flag
 3016           //---------------------------------------------------------
 3017   
 3018           // the local chain is not enabled until the
 3019           // list has been reconstituted
 3020           executedPhases = null;
 3021           metaExecuted = null;
 3022   
 3023           marker = in.readUTF();
 3024           if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
 3025               log.trace(getLogIDString() + 
 3026                         ": readExternal(): About to read executedPhases, marker is: " + marker);
 3027           }
 3028           
 3029           // Previous versions of Axis2 saved two phases in the stream, although one should 
 3030           // always have been null.  The two phases and their associated markers are, in this order:
 3031           // "inboundExecutedPhases", "outboundExecutedPhases".
 3032           boolean gotInExecList = in.readBoolean();
 3033           boolean oldStyleExecutedPhases = false;
 3034           if (marker.equals("inboundExecutedPhases")) {
 3035               oldStyleExecutedPhases = true;
 3036           }
 3037           
 3038           if (oldStyleExecutedPhases && (gotInExecList == ExternalizeConstants.EMPTY_OBJECT)) {
 3039               // There are an inboundExecutedPhases and an outboundExecutedPhases and this one
 3040               // is empty, so skip over it and read the next one
 3041               marker = in.readUTF();
 3042               if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
 3043                   log.trace(getLogIDString() + 
 3044                             ": readExternal(): Skipping over oldStyle empty inboundExecutedPhases");
 3045                   log.trace(getLogIDString() + 
 3046                             ": readExternal(): About to read executedPhases, marker is: " + marker);
 3047               }
 3048               gotInExecList = in.readBoolean();
 3049           }
 3050           
 3051           /*
 3052            * At this point, the stream should point to either "executedPhases" if this is the 
 3053            * new style of serialization.  If it is the oldStyle, it should point to whichever 
 3054            * of "inbound" or "outbound" executed phases contains an active object, since only one
 3055            * should
 3056            */
 3057           if (gotInExecList == ExternalizeConstants.ACTIVE_OBJECT) {
 3058               int expectedNumberInExecList = in.readInt();
 3059   
 3060               if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
 3061                   log.trace(getLogIDString() +
 3062                           ":readExternal(): executed phases:  expected number of entries [" +
 3063                           expectedNumberInExecList + "]");
 3064               }
 3065   
 3066               // setup the list
 3067               metaExecuted = new LinkedList<MetaDataEntry>();
 3068   
 3069               // process the objects
 3070               boolean keepGoing = true;
 3071               int count = 0;
 3072   
 3073               while (keepGoing) {
 3074                   // stop when we get to the end-of-list marker
 3075   
 3076                   // get the object
 3077                   Object tmpObj = in.readObject();
 3078   
 3079                   count++;
 3080   
 3081                   MetaDataEntry mdObj = (MetaDataEntry) tmpObj;
 3082   
 3083                   // get the class name, then add it to the list
 3084                   String tmpClassNameStr;
 3085                   String tmpQNameAsStr;
 3086                   String tmpHasList = "no list";
 3087   
 3088                   if (mdObj != null) {
 3089                       tmpClassNameStr = mdObj.getClassName();
 3090   
 3091                       if (tmpClassNameStr.equalsIgnoreCase(MetaDataEntry.END_OF_LIST)) {
 3092                           // this is the last entry
 3093                           keepGoing = false;
 3094                       } else {
 3095                           // add the entry to the meta data list
 3096                           metaExecuted.add(mdObj);
 3097   
 3098                           tmpQNameAsStr = mdObj.getQNameAsString();
 3099   
 3100                           if (!mdObj.isListEmpty()) {
 3101                               tmpHasList = "has list";
 3102                           }
 3103   
 3104                           if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
 3105                               log.trace(getLogIDString() +
 3106                                       ":readExternal(): meta data class [" + tmpClassNameStr +
 3107                                       "] qname [" + tmpQNameAsStr + "]  index [" + count + "]   [" +
 3108                                       tmpHasList + "]");
 3109                           }
 3110                       }
 3111                   } else {
 3112                       // some error occurred
 3113                       keepGoing = false;
 3114                   }
 3115   
 3116               } // end while keep going
 3117   
 3118               int adjustedNumberInExecList = in.readInt();
 3119   
 3120               if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
 3121                   log.trace(getLogIDString() +
 3122                           ":readExternal(): adjusted number of entries executedPhases [" +
 3123                           adjustedNumberInExecList + "]    ");
 3124               }
 3125           }
 3126           
 3127           if ((metaExecuted == null) || (metaExecuted.isEmpty())) {
 3128               if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
 3129                   log.trace(getLogIDString() +
 3130                           ":readExternal(): meta data for executedPhases list is NULL");
 3131               }
 3132           }
 3133           
 3134           marker = in.readUTF(); // Read marker
 3135           if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
 3136               log.trace(getLogIDString() + 
 3137                         ": readExternal(): After reading executedPhases, marker is: " + marker);
 3138           }
 3139   
 3140           // If this is an oldStyle that contained both an inbound and outbound executed phases, 
 3141           // and the outbound phases wasn't read above, then we need to skip over it
 3142           if (marker.equals("outboundExecutedPhases")) {
 3143               Boolean gotOutExecList = in.readBoolean();
 3144               if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
 3145                   log.trace(getLogIDString() + 
 3146                             ": readExternal(): Skipping over outboundExecutedPhases, marker is: " + marker + 
 3147                             ", is list an active object: " + gotOutExecList);
 3148               }
 3149               if (gotOutExecList != ExternalizeConstants.EMPTY_OBJECT) {
 3150                   throw new IOException("Both inboundExecutedPhases and outboundExecutedPhases had active objects");
 3151               }
 3152               
 3153               marker = in.readUTF();
 3154               if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
 3155                   log.trace(getLogIDString() + 
 3156                             ": readExternal(): After skipping ooutboundExecutePhases, marker is: " + marker);
 3157               }
 3158           }
 3159   
 3160           //---------------------------------------------------------
 3161           // options
 3162           //---------------------------------------------------------
 3163           
 3164           options = (Options) in.readObject();
 3165   
 3166           if (options != null) {
 3167               if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
 3168                   log.trace(getLogIDString() + ":readExternal(): restored Options [" +
 3169                           options.getLogCorrelationIDString() + "]");
 3170               }
 3171           }
 3172   
 3173           //---------------------------------------------------------
 3174           // operation
 3175           //---------------------------------------------------------
 3176   
 3177           // axisOperation is not usable until the meta data has been reconciled
 3178           axisOperation = null;
 3179           marker = in.readUTF();  // Read Marker
 3180           if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
 3181               log.trace(getLogIDString() + 
 3182                         ": readExternal(): About to read axisOperation, marker is: " + marker);
 3183           }
 3184           metaAxisOperation = (MetaDataEntry) in.readObject();
 3185   
 3186           // operation context is not usable until it has been activated
 3187           // NOTE: expect this to be the parent
 3188           marker = in.readUTF();  // Read marker
 3189           if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
 3190               log.trace(getLogIDString() + 
 3191                         ": readExternal(): About to read operationContext, marker is: " + marker);
 3192           }
 3193           operationContext = (OperationContext) in.readObject();
 3194   
 3195           if (operationContext != null) {
 3196               if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
 3197                   log.trace(getLogIDString() + ":readExternal(): restored OperationContext [" +
 3198                           operationContext.getLogCorrelationIDString() + "]");
 3199               }
 3200           }
 3201   
 3202           //---------------------------------------------------------
 3203           // service
 3204           //---------------------------------------------------------
 3205   
 3206           // axisService is not usable until the meta data has been reconciled
 3207           axisService = null;
 3208           marker = in.readUTF(); // Read marker
 3209           if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
 3210               log.trace(getLogIDString() + 
 3211                         ": readExternal(): About to read axisService, marker is: " + marker);
 3212           }
 3213           metaAxisService = (MetaDataEntry) in.readObject();
 3214   
 3215           //-------------------------
 3216           // serviceContextID string
 3217           //-------------------------
 3218           serviceContextID = (String) in.readObject();
 3219           
 3220           //-------------------------
 3221           // serviceContext
 3222           //-------------------------
 3223           marker = in.readUTF(); // Read marker
 3224           if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
 3225               log.trace(getLogIDString() + 
 3226                         ": readExternal(): About to read serviceContext, marker is: " + marker);
 3227           }
 3228   
 3229           boolean servCtxActive = in.readBoolean();
 3230   
 3231           if (servCtxActive == ExternalizeConstants.EMPTY_OBJECT) {
 3232               // empty object
 3233   
 3234               serviceContext = null;
 3235           } else {
 3236               // active object
 3237   
 3238               boolean isParent = in.readBoolean();
 3239   
 3240               // there's an object to read in if it is not the parent of the operation context
 3241               if (!isParent) {
 3242                   serviceContext = (ServiceContext) in.readObject();
 3243               } else {
 3244                   // the service context is the parent of the operation context
 3245                   // so get it from the operation context during activate
 3246                   serviceContext = null;
 3247               }
 3248           }
 3249   
 3250           //---------------------------------------------------------
 3251           // serviceGroup
 3252           //---------------------------------------------------------
 3253   
 3254           // axisServiceGroup is not usable until the meta data has been reconciled
 3255           axisServiceGroup = null;
 3256           marker = in.readUTF(); // Read marker
 3257           if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
 3258               log.trace(getLogIDString() + 
 3259                         ": readExternal(): About to read AxisServiceGroup, marker is: " + marker);
 3260           }
 3261           metaAxisServiceGroup = (MetaDataEntry) in.readObject();
 3262   
 3263           //-----------------------------
 3264           // serviceGroupContextId string
 3265           //-----------------------------
 3266           serviceGroupContextId = (String) in.readObject();
 3267   
 3268           //-----------------------------
 3269           // serviceGroupContext
 3270           //-----------------------------
 3271           marker = in.readUTF();
 3272           if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
 3273               log.trace(getLogIDString() + 
 3274                         ": readExternal(): About to read ServiceGroupContext, marker is: " + marker);
 3275           }
 3276   
 3277           boolean servGrpCtxActive = in.readBoolean();
 3278   
 3279           if (servGrpCtxActive == ExternalizeConstants.EMPTY_OBJECT) {
 3280               // empty object
 3281   
 3282               serviceGroupContext = null;
 3283           } else {
 3284               // active object
 3285   
 3286               boolean isParentSGC = in.readBoolean();
 3287   
 3288               // there's an object to read in if it is not the parent of the service group context
 3289               if (!isParentSGC) {
 3290                   serviceGroupContext = (ServiceGroupContext) in.readObject();
 3291               } else {
 3292                   // the service group context is the parent of the service context
 3293                   // so get it from the service context during activate
 3294                   serviceGroupContext = null;
 3295               }
 3296           }
 3297   
 3298           //---------------------------------------------------------
 3299           // axis message
 3300           //---------------------------------------------------------
 3301   
 3302           // axisMessage is not usable until the meta data has been reconciled
 3303           axisMessage = null;
 3304           marker = in.readUTF();  // Read marker
 3305           if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
 3306               log.trace(getLogIDString() + 
 3307                         ": readExternal(): About to read AxisMessage, marker is: " + marker);
 3308           }
 3309           metaAxisMessage = (MetaDataEntry) in.readObject();
 3310           reconcileAxisMessage = (metaAxisMessage != null);
 3311   
 3312   
 3313           //---------------------------------------------------------
 3314           // configuration context
 3315           //---------------------------------------------------------
 3316   
 3317           // TODO: check to see if there is any runtime data important to this
 3318           //       message context in the configuration context
 3319           //       if so, then need to restore the saved runtime data and reconcile
 3320           //       it with the configuration context on the system when
 3321           //       this message context object is restored
 3322   
 3323           //---------------------------------------------------------
 3324           // session context
 3325           //---------------------------------------------------------
 3326           sessionContext = (SessionContext) in.readObject();
 3327   
 3328           //---------------------------------------------------------
 3329           // transport
 3330           //---------------------------------------------------------
 3331   
 3332           //------------------------------
 3333           // incomingTransportName string
 3334           //------------------------------
 3335           incomingTransportName = (String) in.readObject();
 3336   
 3337           // TransportInDescription transportIn
 3338           // is not usable until the meta data has been reconciled
 3339           transportIn = null;
 3340           metaTransportIn = (MetaDataEntry) in.readObject();
 3341   
 3342           // TransportOutDescription transportOut
 3343           // is not usable until the meta data has been reconciled
 3344           transportOut = null;
 3345           metaTransportOut = (MetaDataEntry) in.readObject();
 3346   
 3347           //---------------------------------------------------------
 3348           // properties
 3349           //---------------------------------------------------------
 3350           // read local properties
 3351           marker = in.readUTF(); // Read marker
 3352           if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
 3353               log.trace(getLogIDString() + 
 3354                         ": readExternal(): About to read properties, marker is: " + marker);
 3355           }
 3356           properties = in.readMap(new HashMapUpdateLockable());
 3357   
 3358   
 3359           //---------------------------------------------------------
 3360           // special data
 3361           //---------------------------------------------------------
 3362           marker = in.readUTF(); // Read marker
 3363           if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
 3364               log.trace(getLogIDString() + 
 3365                         ": readExternal(): About to read SpecialData, marker is: " + marker);
 3366           }
 3367   
 3368           boolean gotSelfManagedData = in.readBoolean();
 3369   
 3370           if (gotSelfManagedData == ExternalizeConstants.ACTIVE_OBJECT) {
 3371               selfManagedDataHandlerCount = in.readInt();
 3372   
 3373               if (selfManagedDataListHolder == null) {
 3374                   selfManagedDataListHolder = new ArrayList<SelfManagedDataHolder>();
 3375               } else {
 3376                   selfManagedDataListHolder.clear();
 3377               }
 3378   
 3379               for (int i = 0; i < selfManagedDataHandlerCount; i++) {
 3380                   selfManagedDataListHolder.add((SelfManagedDataHolder) in.readObject());
 3381               }
 3382           }
 3383   
 3384           //---------------------------------------------------------
 3385           // done
 3386           //---------------------------------------------------------
 3387   
 3388           // trace point
 3389           if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
 3390               log.trace(getLogIDString() +
 3391                       ":readExternal():  message context object created for  " +
 3392                       getLogIDString());
 3393           }
 3394       }
 3395   
 3396   
 3397       /**
 3398        * This method checks to see if additional work needs to be
 3399        * done in order to complete the object reconstitution.
 3400        * Some parts of the object restored from the readExternal()
 3401        * cannot be completed until we have a configurationContext
 3402        * from the active engine. The configurationContext is used
 3403        * to help this object to plug back into the engine's
 3404        * configuration and deployment objects.
 3405        *
 3406        * @param cc The configuration context object representing the active configuration
 3407        */
 3408       public void activate(ConfigurationContext cc) {
 3409           // see if there's any work to do
 3410           if (!needsToBeReconciled) {
 3411               // return quick
 3412               return;
 3413           }
 3414   
 3415           // use the supplied configuration context
 3416           setConfigurationContext(cc);
 3417   
 3418           // get the axis configuration
 3419           AxisConfiguration axisConfig = configurationContext.getAxisConfiguration();
 3420   
 3421           // We previously saved metaAxisService; restore it
 3422           if (metaAxisService != null) {
 3423               this.setAxisService(ActivateUtils.findService(axisConfig,
 3424                                                   metaAxisService.getClassName(),
 3425                                                   metaAxisService.getQNameAsString()));
 3426           }
 3427   
 3428           // We previously saved metaAxisServiceGroup; restore it
 3429           if (metaAxisServiceGroup != null) {
 3430               this.setAxisServiceGroup(
 3431                                        ActivateUtils.findServiceGroup(axisConfig,
 3432                                                   metaAxisServiceGroup.getClassName(),
 3433                                                   metaAxisServiceGroup.getQNameAsString()));
 3434           }
 3435   
 3436           // We previously saved metaAxisOperation; restore it
 3437           if (metaAxisOperation != null) {
 3438               AxisService serv = axisService;
 3439   
 3440               if (serv != null) {
 3441                   // TODO: check for the empty name
 3442                   this.setAxisOperation(ActivateUtils.findOperation(serv,
 3443                                                                     metaAxisOperation.getClassName(),
 3444                                                                     metaAxisOperation.getQName()));
 3445               } else {
 3446                   this.setAxisOperation(ActivateUtils.findOperation(axisConfig,
 3447                                                                     metaAxisOperation.getClassName(),
 3448                                                                     metaAxisOperation.getQName()));
 3449               }
 3450           }
 3451   
 3452           // We previously saved metaAxisMessage; restore it
 3453           if (metaAxisMessage != null) {
 3454               AxisOperation op = axisOperation;
 3455   
 3456               if (op != null) {
 3457                   // TODO: check for the empty name
 3458                   this.setAxisMessage(ActivateUtils.findMessage(op,
 3459                                                                 metaAxisMessage.getQNameAsString(),
 3460                                                                 metaAxisMessage.getExtraName()));
 3461               }
 3462           }
 3463   
 3464           //---------------------------------------------------------------------
 3465           // operation context
 3466           //---------------------------------------------------------------------
 3467           // this will do a full hierarchy, so do it first
 3468           // then we can re-use its objects
 3469   
 3470           if (operationContext != null) {
 3471               operationContext.activate(cc);
 3472   
 3473               // this will be set as the parent of the message context
 3474               // after the other context objects have been activated
 3475           }
 3476   
 3477           //---------------------------------------------------------------------
 3478           // service context
 3479           //---------------------------------------------------------------------
 3480   
 3481           if (serviceContext == null) {
 3482               // get the parent serviceContext of the operationContext
 3483               if (operationContext != null) {
 3484                   serviceContext = operationContext.getServiceContext();
 3485               }
 3486           }
 3487   
 3488           // if we have a service context, make sure it is usable
 3489           if (serviceContext != null) {
 3490               // for some reason, the service context might be set differently from
 3491               // the operation context parent
 3492               serviceContext.activate(cc);
 3493           }
 3494   
 3495           //---------------------------------------------------------------------
 3496           // service group context
 3497           //---------------------------------------------------------------------
 3498   
 3499           if (serviceGroupContext == null) {
 3500               // get the parent serviceGroupContext of the serviceContext
 3501               if (serviceContext != null) {
 3502                   serviceGroupContext = (ServiceGroupContext) serviceContext.getParent();
 3503               }
 3504           }
 3505   
 3506           // if we have a service group context, make sure it is usable
 3507           if (serviceGroupContext != null) {
 3508               // for some reason, the service group context might be set differently from
 3509               // the service context parent
 3510               serviceGroupContext.activate(cc);
 3511           }
 3512   
 3513           //---------------------------------------------------------------------
 3514           // other context-related reconciliation
 3515           //---------------------------------------------------------------------
 3516   
 3517           this.setParent(operationContext);
 3518   
 3519           //---------------------------------------------------------------------
 3520           // options
 3521           //---------------------------------------------------------------------
 3522           if (options != null) {
 3523               options.activate(cc);
 3524           }
 3525   
 3526           String tmpID = getMessageID();
 3527           String logCorrelationIDString = getLogIDString();
 3528   
 3529           if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
 3530               log.trace(logCorrelationIDString + ":activate():   message ID [" + tmpID + "] for " +
 3531                       logCorrelationIDString);
 3532           }
 3533   
 3534           //---------------------------------------------------------------------
 3535           // transports
 3536           //---------------------------------------------------------------------
 3537   
 3538           // We previously saved metaTransportIn; restore it
 3539           if (metaTransportIn != null) {
 3540               QName qin = metaTransportIn.getQName();
 3541               TransportInDescription tmpIn = null;
 3542               try {
 3543                   tmpIn = axisConfig.getTransportIn(qin.getLocalPart());
 3544               }
 3545               catch (Exception exin) {
 3546                   // if a fault is thrown, log it and continue
 3547                   log.trace(logCorrelationIDString +
 3548                           "activate():  exception caught when getting the TransportInDescription [" +
 3549                           qin.toString() + "]  from the AxisConfiguration [" +
 3550                           exin.getClass().getName() + " : " + exin.getMessage() + "]");
 3551               }
 3552   
 3553               if (tmpIn != null) {
 3554                   transportIn = tmpIn;
 3555               } else {
 3556                   transportIn = null;
 3557               }
 3558           } else {
 3559               transportIn = null;
 3560           }
 3561   
 3562           // We previously saved metaTransportOut; restore it
 3563           if (metaTransportOut != null) {
 3564               // TODO : Check if this should really be a QName?
 3565               QName qout = metaTransportOut.getQName();
 3566               TransportOutDescription tmpOut = null;
 3567               try {
 3568                   tmpOut = axisConfig.getTransportOut(qout.getLocalPart());
 3569               }
 3570               catch (Exception exout) {
 3571                   // if a fault is thrown, log it and continue
 3572                   if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
 3573                       log.trace(logCorrelationIDString +
 3574                           "activate():  exception caught when getting the TransportOutDescription [" +
 3575                           qout.toString() + "]  from the AxisConfiguration [" +
 3576                           exout.getClass().getName() + " : " + exout.getMessage() + "]");
 3577                   }
 3578               }
 3579   
 3580               if (tmpOut != null) {
 3581                   transportOut = tmpOut;
 3582               } else {
 3583                   transportOut = null;
 3584               }
 3585           } else {
 3586               transportOut = null;
 3587           }
 3588   
 3589           //-------------------------------------------------------
 3590           // reconcile the execution chain
 3591           //-------------------------------------------------------
 3592           if (metaExecutionChain != null) {
 3593               if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
 3594                   log.trace(
 3595                           logCorrelationIDString + ":activate(): reconciling the execution chain...");
 3596               }
 3597   
 3598               currentHandlerIndex = metaHandlerIndex;
 3599               currentPhaseIndex = metaPhaseIndex;
 3600   
 3601               executionChain = restoreHandlerList(metaExecutionChain);
 3602   
 3603               try {
 3604                   deserializeSelfManagedData();
 3605               }
 3606               catch (Exception ex) {
 3607                   // log the exception
 3608                   if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
 3609                       log.trace(logCorrelationIDString +
 3610                           ":activate(): *** WARNING *** deserializing the self managed data encountered Exception [" +
 3611                           ex.getClass().getName() + " : " + ex.getMessage() + "]", ex);
 3612                   }
 3613               }
 3614           }
 3615   
 3616           //-------------------------------------------------------
 3617           // reconcile the lists for the executed phases
 3618           //-------------------------------------------------------
 3619           if (metaExecuted != null) {
 3620               if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
 3621                   log.trace(logCorrelationIDString +
 3622                           ":activate(): reconciling the executed chain...");
 3623               }
 3624   
 3625               if (!(executedPhasesReset)) {
 3626                   executedPhases =
 3627                           restoreExecutedList(executedPhases, metaExecuted);
 3628               }
 3629           }
 3630   
 3631           if (executedPhases == null) {
 3632               executedPhases = new LinkedList<Handler>();
 3633           }
 3634   
 3635   
 3636           //-------------------------------------------------------
 3637           // finish up remaining links
 3638           //-------------------------------------------------------
 3639           if (operationContext != null) {
 3640               operationContext.restoreMessageContext(this);
 3641           }
 3642   
 3643           //-------------------------------------------------------
 3644           // done, reset the flag
 3645           //-------------------------------------------------------
 3646           needsToBeReconciled = false;
 3647   
 3648       }
 3649   
 3650   
 3651       /**
 3652        * This method checks to see if additional work needs to be
 3653        * done in order to complete the object reconstitution.
 3654        * Some parts of the object restored from the readExternal()
 3655        * cannot be completed until we have an object that gives us
 3656        * a view of the active object graph from the active engine.
 3657        * <p/>
 3658        * NOTE: when activating an object, you only need to call
 3659        * one of the activate methods (activate() or activateWithOperationContext())
 3660        * but not both.
 3661        *
 3662        * @param operationCtx The operation context object that is a member of the active object graph
 3663        */
 3664       public void activateWithOperationContext(OperationContext operationCtx) {
 3665           // see if there's any work to do
 3666           if (!(needsToBeReconciled)) {
 3667               // return quick
 3668               return;
 3669           }
 3670   
 3671           String logCorrelationIDString = getLogIDString();
 3672           // trace point
 3673           if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
 3674               log.trace(logCorrelationIDString + ":activateWithOperationContext():  BEGIN");
 3675           }
 3676   
 3677           if (operationCtx == null) {
 3678               // won't be able to finish
 3679               if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
 3680                   log.trace(logCorrelationIDString +
 3681                       ":activateWithOperationContext():  *** WARNING ***  No active OperationContext object is available.");
 3682               }
 3683               return;
 3684           }
 3685   
 3686           //---------------------------------------------------------------------
 3687           // locate the objects in the object graph
 3688           //---------------------------------------------------------------------
 3689           ConfigurationContext configCtx = operationCtx.getConfigurationContext();
 3690   
 3691           if (configCtx == null) {
 3692               // won't be able to finish
 3693               if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
 3694                   log.trace(logCorrelationIDString +
 3695                       ":activateWithOperationContext():  *** WARNING ***  No active ConfigurationContext object is available.");
 3696               }
 3697               return;
 3698           }
 3699   
 3700           AxisConfiguration axisCfg = configCtx.getAxisConfiguration();
 3701   
 3702           AxisOperation axisOp = operationCtx.getAxisOperation();
 3703           ServiceContext serviceCtx = operationCtx.getServiceContext();
 3704   
 3705           ServiceGroupContext serviceGroupCtx = null;
 3706           AxisService axisSrv = null;
 3707           AxisServiceGroup axisSG = null;
 3708   
 3709           if (serviceCtx != null) {
 3710               serviceGroupCtx = serviceCtx.getServiceGroupContext();
 3711               axisSrv = serviceCtx.getAxisService();
 3712           }
 3713   
 3714           if (serviceGroupCtx != null) {
 3715               axisSG = serviceGroupCtx.getDescription();
 3716           }
 3717   
 3718           //---------------------------------------------------------------------
 3719           // link to the objects in the object graph
 3720           //---------------------------------------------------------------------
 3721   
 3722           setConfigurationContext(configCtx);
 3723   
 3724           setAxisOperation(axisOp);
 3725           setAxisService(axisSrv);
 3726           setAxisServiceGroup(axisSG);
 3727   
 3728           setServiceGroupContext(serviceGroupCtx);
 3729           setServiceContext(serviceCtx);
 3730           setOperationContext(operationCtx);
 3731   
 3732           //---------------------------------------------------------------------
 3733           // reconcile the remaining objects
 3734           //---------------------------------------------------------------------
 3735   
 3736           // We previously saved metaAxisMessage; restore it
 3737           if (metaAxisMessage != null) {
 3738               if (axisOp != null) {
 3739                   // TODO: check for the empty name
 3740                   this.setAxisMessage(ActivateUtils.findMessage(axisOp,
 3741                                                    metaAxisMessage.getQNameAsString(),
 3742                                                    metaAxisMessage.getExtraName()));
 3743               }
 3744           }
 3745   
 3746           //---------------------------------------------------------------------
 3747           // options
 3748           //---------------------------------------------------------------------
 3749           if (options != null) {
 3750               options.activate(configCtx);
 3751           }
 3752   
 3753           String tmpID = getMessageID();
 3754   
 3755           if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
 3756               log.trace(logCorrelationIDString + ":activateWithOperationContext():   message ID [" +
 3757                       tmpID + "]");
 3758           }
 3759   
 3760           //---------------------------------------------------------------------
 3761           // transports
 3762           //---------------------------------------------------------------------
 3763   
 3764           // We previously saved metaTransportIn; restore it
 3765           if (metaTransportIn != null) {
 3766               QName qin = metaTransportIn.getQName();
 3767               TransportInDescription tmpIn = null;
 3768               try {
 3769                   tmpIn = axisCfg.getTransportIn(qin.getLocalPart());
 3770               }
 3771               catch (Exception exin) {
 3772                   // if a fault is thrown, log it and continue
 3773                   if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
 3774                       log.trace(logCorrelationIDString +
 3775                           "activateWithOperationContext():  exception caught when getting the TransportInDescription [" +
 3776                           qin.toString() + "]  from the AxisConfiguration [" +
 3777                           exin.getClass().getName() + " : " + exin.getMessage() + "]");
 3778                   }
 3779   
 3780               }
 3781   
 3782               if (tmpIn != null) {
 3783                   transportIn = tmpIn;
 3784               } else {
 3785                   transportIn = null;
 3786               }
 3787           } else {
 3788               transportIn = null;
 3789           }
 3790   
 3791           // We previously saved metaTransportOut; restore it
 3792           if (metaTransportOut != null) {
 3793               QName qout = metaTransportOut.getQName();
 3794               TransportOutDescription tmpOut = null;
 3795               try {
 3796                   tmpOut = axisCfg.getTransportOut(qout.getLocalPart());
 3797               }
 3798               catch (Exception exout) {
 3799                   // if a fault is thrown, log it and continue
 3800                   if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
 3801                       log.trace(logCorrelationIDString +
 3802                           "activateWithOperationContext():  exception caught when getting the TransportOutDescription [" +
 3803                           qout.toString() + "]  from the AxisConfiguration [" +
 3804                           exout.getClass().getName() + " : " + exout.getMessage() + "]");
 3805                   }
 3806               }
 3807   
 3808               if (tmpOut != null) {
 3809                   transportOut = tmpOut;
 3810               } else {
 3811                   transportOut = null;
 3812               }
 3813           } else {
 3814               transportOut = null;
 3815           }
 3816   
 3817           //-------------------------------------------------------
 3818           // reconcile the execution chain
 3819           //-------------------------------------------------------
 3820           if (metaExecutionChain != null) {
 3821               if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
 3822                   log.trace(logCorrelationIDString +
 3823                           ":activateWithOperationContext(): reconciling the execution chain...");
 3824               }
 3825   
 3826               currentHandlerIndex = metaHandlerIndex;
 3827               currentPhaseIndex = metaPhaseIndex;
 3828   
 3829               executionChain = restoreHandlerList(metaExecutionChain);
 3830   
 3831               try {
 3832                   deserializeSelfManagedData();
 3833               }
 3834               catch (Exception ex) {
 3835                   // log the exception
 3836                   if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
 3837                       log.trace(logCorrelationIDString +
 3838                           ":activateWithOperationContext(): *** WARNING *** deserializing the self managed data encountered Exception [" +
 3839                           ex.getClass().getName() + " : " + ex.getMessage() + "]", ex);
 3840                   }
 3841               }
 3842           }
 3843   
 3844           //-------------------------------------------------------
 3845           // reconcile the lists for the executed phases
 3846           //-------------------------------------------------------
 3847           if (metaExecuted != null) {
 3848               if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
 3849                   log.trace(logCorrelationIDString +
 3850                           ":activateWithOperationContext(): reconciling the executed chain...");
 3851               }
 3852   
 3853               if (!(executedPhasesReset)) {
 3854                   executedPhases =
 3855                           restoreExecutedList(executedPhases, metaExecuted);
 3856               }
 3857           }
 3858   
 3859           if (executedPhases == null) {
 3860               executedPhases = new LinkedList<Handler>();
 3861           }
 3862   
 3863           //-------------------------------------------------------
 3864           // done, reset the flag
 3865           //-------------------------------------------------------
 3866           needsToBeReconciled = false;
 3867   
 3868           if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
 3869               log.trace(logCorrelationIDString + ":activateWithOperationContext():  END");
 3870           }
 3871       }
 3872   
 3873   
 3874       /**
 3875        * @param metaDataEntries ArrayList of MetaDataEntry objects
 3876        * @return ArrayList of Handlers based on our list of handlers from the reconstituted deserialized list, and the existing handlers in the AxisConfiguration object.  May return null.
 3877        */
 3878       private ArrayList<Handler> restoreHandlerList(ArrayList<MetaDataEntry> metaDataEntries) {
 3879           AxisConfiguration axisConfig = configurationContext.getAxisConfiguration();
 3880   
 3881           List<Handler> existingHandlers = new ArrayList<Handler>();
 3882   
 3883           // TODO: I'm using clone for the ArrayList returned from axisConfig object.
 3884           //     Does it do a deep clone of the Handlers held there?  Does it matter?
 3885           switch (FLOW) {
 3886               case IN_FLOW:
 3887                   existingHandlers.addAll(axisConfig.getInFlowPhases());
 3888                   break;
 3889   
 3890               case OUT_FLOW:
 3891               	existingHandlers.addAll(axisConfig.getOutFlowPhases());
 3892                   break;
 3893   
 3894               case IN_FAULT_FLOW:
 3895               	existingHandlers.addAll(axisConfig.getInFaultFlowPhases());
 3896                   break;
 3897   
 3898               case OUT_FAULT_FLOW:
 3899               	existingHandlers.addAll(axisConfig.getOutFaultFlowPhases());
 3900                   break;
 3901           }
 3902   
 3903           existingHandlers = flattenHandlerList(existingHandlers, null);
 3904   
 3905           ArrayList<Handler> handlerListToReturn = new ArrayList<Handler>();
 3906   
 3907           for (int i = 0; i < metaDataEntries.size(); i++) {
 3908               Handler handler = (Handler) ActivateUtils
 3909                       .findHandler(existingHandlers, (MetaDataEntry) metaDataEntries.get(i));
 3910   
 3911               if (handler != null) {
 3912                   handlerListToReturn.add(handler);
 3913               }
 3914           }
 3915   
 3916           return handlerListToReturn;
 3917       }
 3918   
 3919   
 3920       /**
 3921        * Using meta data for phases/handlers, create a linked list of actual
 3922        * phase/handler objects.  The created list is composed of the objects
 3923        * from the base list at the top of the created list followed by the
 3924        * restored objects.
 3925        *
 3926        * @param base            Linked list of phase/handler objects
 3927        * @param metaDataEntries Linked list of MetaDataEntry objects
 3928        * @return LinkedList of objects or NULL if none available
 3929        */
 3930       private LinkedList<Handler> restoreExecutedList(LinkedList<Handler> base, LinkedList<MetaDataEntry> metaDataEntries) {
 3931           if (metaDataEntries == null) {
 3932               return base;
 3933           }
 3934   
 3935           // get a list of existing handler/phase objects for the restored objects
 3936   
 3937           ArrayList<MetaDataEntry> tmpMetaDataList = new ArrayList<MetaDataEntry>(metaDataEntries);
 3938   
 3939           ArrayList<Handler> existingList = restoreHandlerList(tmpMetaDataList);
 3940   
 3941           if ((existingList == null) || (existingList.isEmpty())) {
 3942               return base;
 3943           }
 3944   
 3945           // set up a list to return
 3946   
 3947           LinkedList<Handler> returnedList = new LinkedList<Handler>();
 3948   
 3949           if (base != null) {
 3950               returnedList.addAll(base);
 3951           }
 3952   
 3953           returnedList.addAll(existingList);
 3954   
 3955           return returnedList;
 3956       }
 3957   
 3958   
 3959       /**
 3960        * Process the list of handlers from the Phase object
 3961        * into the appropriate meta data.
 3962        *
 3963        * @param phase   The Phase object containing a list of handlers
 3964        * @param mdPhase The meta data object associated with the specified Phase object
 3965        */
 3966       private void setupPhaseList(Phase phase, MetaDataEntry mdPhase) {
 3967           // get the list from the phase object
 3968           List<Handler> handlers = phase.getHandlers();
 3969   
 3970           if (handlers.isEmpty()) {
 3971               // done, make sure there is no list in the given meta data
 3972               mdPhase.removeList();
 3973               return;
 3974           }
 3975   
 3976           // get the metadata on each member of the list
 3977   
 3978           int listSize = handlers.size();
 3979   
 3980           if (listSize > 0) {
 3981   
 3982               Iterator<Handler> i = handlers.iterator();
 3983   
 3984               while (i.hasNext()) {
 3985                   Object obj = i.next();
 3986                   String objClass = obj.getClass().getName();
 3987   
 3988                   // start the meta data entry for this object
 3989                   MetaDataEntry mdEntry = new MetaDataEntry();
 3990                   mdEntry.setClassName(objClass);
 3991   
 3992                   // get the correct object-specific name
 3993                   String qnameAsString;
 3994   
 3995                   if (obj instanceof Phase) {
 3996                       // nested condition, the phase object contains another phase!
 3997                       Phase phaseObj = (Phase) obj;
 3998                       qnameAsString = phaseObj.getName();
 3999   
 4000                       // add the list of handlers to the meta data
 4001                       setupPhaseList(phaseObj, mdEntry);
 4002                   } else if (obj instanceof Handler) {
 4003                       Handler handlerObj = (Handler) obj;
 4004                       qnameAsString = handlerObj.getName();
 4005                   } else {
 4006                       // TODO: will there be any other kinds of objects
 4007                       // in the list?
 4008                       qnameAsString = "NULL";
 4009                   }
 4010   
 4011                   mdEntry.setQName(qnameAsString);
 4012   
 4013                   // done with setting up the meta data for the list entry
 4014                   // so add it to the parent
 4015                   mdPhase.addToList(mdEntry);
 4016   
 4017                   if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
 4018                       log.trace(getLogIDString() + ":setupPhaseList(): list entry class [" +
 4019                               objClass + "] qname [" + qnameAsString + "]");
 4020                   }
 4021   
 4022               } // end while entries in list
 4023           } else {
 4024               // a list with no entries
 4025               // done, make sure there is no list in the given meta data
 4026               mdPhase.removeList();
 4027           }
 4028       }
 4029   
 4030   
 4031       /**
 4032        * Return a Read-Only copy of this message context
 4033        * that has been extracted from the object
 4034        * hierachy.  In other words, the message context
 4035        * copy does not have links to the object graph.
 4036        * <p/>
 4037        * NOTE: The copy shares certain objects with the original.
 4038        * The intent is to use the copy to read values but not
 4039        * modify them, especially since the copy is not part
 4040        * of the normal *Context and Axis* object graph.
 4041        *
 4042        * @return A copy of the message context that is not in the object graph
 4043        */
 4044       public MessageContext extractCopyMessageContext() {
 4045           MessageContext copy = new MessageContext();
 4046           String logCorrelationIDString = getLogIDString();
 4047           if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
 4048               log.trace(logCorrelationIDString + ":extractCopyMessageContext():  based on " +
 4049                       logCorrelationIDString + "   into copy " + copy.getLogIDString());
 4050           }
 4051   
 4052           //---------------------------------------------------------
 4053           // various simple fields
 4054           //---------------------------------------------------------
 4055   
 4056           copy.setFLOW(FLOW);
 4057   
 4058           copy.setProcessingFault(processingFault);
 4059           copy.setPaused(paused);
 4060           copy.setOutputWritten(outputWritten);
 4061           copy.setNewThreadRequired(newThreadRequired);
 4062           copy.setDoingREST(doingREST);
 4063           copy.setDoingMTOM(doingMTOM);
 4064           copy.setDoingSwA(doingSwA);
 4065           copy.setResponseWritten(responseWritten);
 4066           copy.setServerSide(serverSide);
 4067   
 4068           copy.setLastTouchedTime(getLastTouchedTime());
 4069   
 4070           //---------------------------------------------------------
 4071           // message
 4072           //---------------------------------------------------------
 4073           try {
 4074               copy.setEnvelope(envelope);
 4075           }
 4076           catch (Exception ex) {
 4077               if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
 4078                   log.trace(logCorrelationIDString +
 4079                       ":extractCopyMessageContext():  Exception caught when setting the copy with the envelope",
 4080                         ex);
 4081               }
 4082           }
 4083   
 4084           copy.setAttachmentMap(attachments);
 4085   
 4086           copy.setIsSOAP11Explicit(isSOAP11);
 4087   
 4088           //---------------------------------------------------------
 4089           // ArrayList executionChain
 4090           //     handler and phase related data
 4091           //---------------------------------------------------------
 4092           copy.setExecutionChain(executionChain);
 4093   
 4094           // the setting of the execution chain is actually a reset
 4095           // so copy the indices after putting in the execution chain
 4096           copy.setCurrentHandlerIndex(currentHandlerIndex);
 4097           copy.setCurrentPhaseIndex(currentPhaseIndex);
 4098   
 4099           //---------------------------------------------------------
 4100           // LinkedList executedPhases
 4101           //---------------------------------------------------------
 4102           copy.setExecutedPhasesExplicit(executedPhases);
 4103   
 4104           //---------------------------------------------------------
 4105           // options
 4106           //---------------------------------------------------------
 4107           copy.setOptionsExplicit(options);
 4108   
 4109           //---------------------------------------------------------
 4110           // axis operation
 4111           //---------------------------------------------------------
 4112           copy.setAxisOperation(null);
 4113   
 4114           //---------------------------------------------------------
 4115           // operation context
 4116           //---------------------------------------------------------
 4117           copy.setOperationContext(null);
 4118   
 4119           //---------------------------------------------------------
 4120           // axis service
 4121           //---------------------------------------------------------
 4122           copy.setAxisService(null);
 4123   
 4124           //-------------------------
 4125           // serviceContextID string
 4126           //-------------------------
 4127           copy.setServiceContextID(serviceContextID);
 4128   
 4129           //-------------------------
 4130           // serviceContext
 4131           //-------------------------
 4132           copy.setServiceContext(null);
 4133   
 4134           //---------------------------------------------------------
 4135           // serviceGroup
 4136           //---------------------------------------------------------
 4137           copy.setServiceGroupContext(null);
 4138   
 4139           //-----------------------------
 4140           // serviceGroupContextId string
 4141           //-----------------------------
 4142           copy.setServiceGroupContextId(serviceGroupContextId);
 4143   
 4144           //---------------------------------------------------------
 4145           // axis message
 4146           //---------------------------------------------------------
 4147           copy.setAxisMessage(axisMessage);
 4148   
 4149           //---------------------------------------------------------
 4150           // configuration context
 4151           //---------------------------------------------------------
 4152           copy.setConfigurationContext(configurationContext);
 4153   
 4154           //---------------------------------------------------------
 4155           // session context
 4156           //---------------------------------------------------------
 4157           copy.setSessionContext(sessionContext);
 4158   
 4159           //---------------------------------------------------------
 4160           // transport
 4161           //---------------------------------------------------------
 4162   
 4163           //------------------------------
 4164           // incomingTransportName string
 4165           //------------------------------
 4166           copy.setIncomingTransportName(incomingTransportName);
 4167   
 4168           copy.setTransportIn(transportIn);
 4169           copy.setTransportOut(transportOut);
 4170   
 4171           //---------------------------------------------------------
 4172           // properties
 4173           //---------------------------------------------------------
 4174           // Only set the local properties (i.e. don't use getProperties())
 4175           copy.setProperties(properties);
 4176   
 4177           //---------------------------------------------------------
 4178           // special data
 4179           //---------------------------------------------------------
 4180   
 4181           copy.setSelfManagedDataMapExplicit(selfManagedDataMap);
 4182   
 4183           //---------------------------------------------------------
 4184           // done
 4185           //---------------------------------------------------------
 4186   
 4187           return copy;
 4188       }
 4189   
 4190       //------------------------------------------------------------------------
 4191       // additional setter methods needed to copy the message context object
 4192       //------------------------------------------------------------------------
 4193   
 4194       public void setIsSOAP11Explicit(boolean t) {
 4195           isSOAP11 = t;
 4196       }
 4197   
 4198       public void setExecutedPhasesExplicit(LinkedList<Handler> inb) {
 4199           executedPhases = inb;
 4200       }
 4201   
 4202       public void setSelfManagedDataMapExplicit(LinkedHashMap<String, Object> map) {
 4203           selfManagedDataMap = map;
 4204       }
 4205   
 4206       public void setOptionsExplicit(Options op) {
 4207           this.options = op;
 4208       }
 4209   
 4210   
 4211       /**
 4212        * Trace a warning message, if needed, indicating that this
 4213        * object needs to be activated before accessing certain fields.
 4214        *
 4215        * @param methodname The method where the warning occurs
 4216        */
 4217       private void checkActivateWarning(String methodname) {
 4218           if (needsToBeReconciled) {
 4219               if (LoggingControl.debugLoggingAllowed && log.isWarnEnabled()) {
 4220                   log.warn(getLogIDString() + ":" + methodname + "(): ****WARNING**** " + myClassName +
 4221                       ".activate(configurationContext) needs to be invoked.");
 4222               }
 4223           }
 4224       }
 4225   
 4226       public ConfigurationContext getRootContext() {
 4227           return configurationContext;
 4228       }
 4229   
 4230       public boolean isFault() {
 4231           try {
 4232               return getEnvelope().hasFault();
 4233           } catch (Exception e) {
 4234               // TODO: What should we be doing here?  No envelope certainly seems bad....
 4235               return false;
 4236           }
 4237       }
 4238   
 4239   
 4240       /**
 4241        * Obtain the Exception which caused the processing chain to halt.
 4242        * @return null, or an Exception.
 4243        */
 4244       public Exception getFailureReason() {
 4245           return failureReason;
 4246       }
 4247   
 4248       /**
 4249        * Set the failure reason.  Only AxisEngine should ever do this.
 4250        *
 4251        * @param failureReason an Exception which caused processing to halt.
 4252        */
 4253       public void setFailureReason(Exception failureReason) {
 4254           this.failureReason = failureReason;
 4255       }
 4256   }

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