* @param in The stream to read the object contents from
* @throws IOException
* @throws ClassNotFoundException
*/
public void readExternal(ObjectInput inObject) throws IOException, ClassNotFoundException {
SafeObjectInputStream in = SafeObjectInputStream.install(inObject);
// set the flag to indicate that the message context is being
// reconstituted and will need to have certain object references
// to be reconciled with the current engine setup
needsToBeReconciled = true;
// trace point
if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
log.trace(myClassName + ":readExternal(): BEGIN bytes available in stream [" +
in.available() + "] ");
}
//---------------------------------------------------------
// object level identifiers
//---------------------------------------------------------
// serialization version ID
long suid = in.readLong();
// revision ID
int revID = in.readInt();
// make sure the object data is in a version we can handle
if (suid != serialVersionUID) {
throw new ClassNotFoundException(ExternalizeConstants.UNSUPPORTED_SUID);
}
// make sure the object data is in a revision level we can handle
if (revID != REVISION_2) {
throw new ClassNotFoundException(ExternalizeConstants.UNSUPPORTED_REVID);
}
//---------------------------------------------------------
// various simple fields
//---------------------------------------------------------
// the type of execution flow for the message context
FLOW = in.readInt();
// various flags
processingFault = in.readBoolean();
paused = in.readBoolean();
outputWritten = in.readBoolean();
newThreadRequired = in.readBoolean();
isSOAP11 = in.readBoolean();
doingREST = in.readBoolean();
doingMTOM = in.readBoolean();
doingSwA = in.readBoolean();
responseWritten = in.readBoolean();
serverSide = in.readBoolean();
long time = in.readLong();
setLastTouchedTime(time);
logCorrelationID = (String) in.readObject();
// trace point
if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
logCorrelationIDString = "[MessageContext: logID=" + getLogCorrelationID() + "]";
log.trace(myClassName + ":readExternal(): reading the input stream for " +
getLogIDString());
}
//---------------------------------------------------------
// Message
// Read the message and attachments
//---------------------------------------------------------
envelope = MessageExternalizeUtils.readExternal(in, this, getLogIDString());
//---------------------------------------------------------
// ArrayList executionChain
// handler and phase related data
//---------------------------------------------------------
// Restore the metadata about each member of the list
// and the order of the list.
// This metadata will be used to match up with phases
// and handlers on the engine.
//
// Non-null list:
// UTF - description string
// boolean - active flag
// int - current handler index
// int - current phase index
// int - expected number of entries in the list
// not including the last entry marker
// objects - MetaDataEntry object per list entry
// last entry will be empty MetaDataEntry
// with MetaDataEntry.LAST_ENTRY marker
// int - adjusted number of entries in the list
// includes the last empty entry
//
// Empty list:
// UTF - description string
// boolean - empty flag
//---------------------------------------------------------
// the local chain is not enabled until the
// list has been reconstituted
executionChain = null;
currentHandlerIndex = -1;
currentPhaseIndex = 0;
metaExecutionChain = null;
String marker = in.readUTF();
if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
log.trace(getLogIDString() +
": readExternal(): About to read executionChain, marker is: " + marker);
}
boolean gotChain = in.readBoolean();
if (gotChain == ExternalizeConstants.ACTIVE_OBJECT) {
metaHandlerIndex = in.readInt();
metaPhaseIndex = in.readInt();
int expectedNumberEntries = in.readInt();
if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
log.trace(getLogIDString() +
":readExternal(): execution chain: expected number of entries [" +
expectedNumberEntries + "]");
}
// setup the list
metaExecutionChain = new ArrayList<MetaDataEntry>();
// process the objects
boolean keepGoing = true;
int count = 0;
while (keepGoing) {
// stop when we get to the end-of-list marker
// get the object
Object tmpObj = in.readObject();
count++;
MetaDataEntry mdObj = (MetaDataEntry) tmpObj;
// get the class name, then add it to the list
String tmpClassNameStr;
String tmpQNameAsStr;
if (mdObj != null) {
tmpClassNameStr = mdObj.getClassName();
if (tmpClassNameStr.equalsIgnoreCase(MetaDataEntry.END_OF_LIST)) {
// this is the last entry
keepGoing = false;
} else {
// add the entry to the meta data list
metaExecutionChain.add(mdObj);
tmpQNameAsStr = mdObj.getQNameAsString();
if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
String tmpHasList = mdObj.isListEmpty() ? "no children" : "has children";
if (log.isTraceEnabled()) {
log.trace(getLogIDString() +
":readExternal(): meta data class [" + tmpClassNameStr +
"] qname [" + tmpQNameAsStr + "] index [" + count + "] [" +
tmpHasList + "]");
}
}
}
} else {
// some error occurred
keepGoing = false;
}
} // end while keep going
int adjustedNumberEntries = in.readInt();
if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
log.trace(getLogIDString() +
":readExternal(): adjusted number of entries ExecutionChain [" +
adjustedNumberEntries + "] ");
}
}
if ((metaExecutionChain == null) || (metaExecutionChain.isEmpty())) {
if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
log.trace(getLogIDString() +
":readExternal(): meta data for Execution Chain is NULL");
}
}
//---------------------------------------------------------
// LinkedList executedPhases
//
// Note that in previous versions of Axis2, this was
// represented by two lists: "inboundExecutedPhases", "outboundExecutedPhases",
// however since the message context itself represents a flow
// direction, one of these lists was always null. This was changed
// around 2007-06-08 revision r545615. For backward compatability
// with streams saved in previous versions of Axis2, we need
// to be able to process both the old style and new style.
//---------------------------------------------------------
// Restore the metadata about each member of the list
// and the order of the list.
// This metadata will be used to match up with phases
// and handlers on the engine.
//
// Non-null list:
// UTF - description string
// boolean - active flag
// int - expected number of entries in the list
// not including the last entry marker
// objects - MetaDataEntry object per list entry
// last entry will be empty MetaDataEntry
// with MetaDataEntry.LAST_ENTRY marker
// int - adjusted number of entries in the list
// includes the last empty entry
//
// Empty list:
// UTF - description string
// boolean - empty flag
//---------------------------------------------------------
// the local chain is not enabled until the
// list has been reconstituted
executedPhases = null;
metaExecuted = null;
marker = in.readUTF();
if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
log.trace(getLogIDString() +
": readExternal(): About to read executedPhases, marker is: " + marker);
}
// Previous versions of Axis2 saved two phases in the stream, although one should
// always have been null. The two phases and their associated markers are, in this order:
// "inboundExecutedPhases", "outboundExecutedPhases".
boolean gotInExecList = in.readBoolean();
boolean oldStyleExecutedPhases = false;
if (marker.equals("inboundExecutedPhases")) {
oldStyleExecutedPhases = true;
}
if (oldStyleExecutedPhases && (gotInExecList == ExternalizeConstants.EMPTY_OBJECT)) {
// There are an inboundExecutedPhases and an outboundExecutedPhases and this one
// is empty, so skip over it and read the next one
marker = in.readUTF();
if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
log.trace(getLogIDString() +
": readExternal(): Skipping over oldStyle empty inboundExecutedPhases");
log.trace(getLogIDString() +
": readExternal(): About to read executedPhases, marker is: " + marker);
}
gotInExecList = in.readBoolean();
}
/*
* At this point, the stream should point to either "executedPhases" if this is the
* new style of serialization. If it is the oldStyle, it should point to whichever
* of "inbound" or "outbound" executed phases contains an active object, since only one
* should
*/
if (gotInExecList == ExternalizeConstants.ACTIVE_OBJECT) {
int expectedNumberInExecList = in.readInt();
if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
log.trace(getLogIDString() +
":readExternal(): executed phases: expected number of entries [" +
expectedNumberInExecList + "]");
}
// setup the list
metaExecuted = new LinkedList<MetaDataEntry>();
// process the objects
boolean keepGoing = true;
int count = 0;
while (keepGoing) {
// stop when we get to the end-of-list marker
// get the object
Object tmpObj = in.readObject();
count++;
MetaDataEntry mdObj = (MetaDataEntry) tmpObj;
// get the class name, then add it to the list
String tmpClassNameStr;
String tmpQNameAsStr;
String tmpHasList = "no list";
if (mdObj != null) {
tmpClassNameStr = mdObj.getClassName();
if (tmpClassNameStr.equalsIgnoreCase(MetaDataEntry.END_OF_LIST)) {
// this is the last entry
keepGoing = false;
} else {
// add the entry to the meta data list
metaExecuted.add(mdObj);
tmpQNameAsStr = mdObj.getQNameAsString();
if (!mdObj.isListEmpty()) {
tmpHasList = "has list";
}
if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
log.trace(getLogIDString() +
":readExternal(): meta data class [" + tmpClassNameStr +
"] qname [" + tmpQNameAsStr + "] index [" + count + "] [" +
tmpHasList + "]");
}
}
} else {
// some error occurred
keepGoing = false;
}
} // end while keep going
int adjustedNumberInExecList = in.readInt();
if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
log.trace(getLogIDString() +
":readExternal(): adjusted number of entries executedPhases [" +
adjustedNumberInExecList + "] ");
}
}
if ((metaExecuted == null) || (metaExecuted.isEmpty())) {
if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
log.trace(getLogIDString() +
":readExternal(): meta data for executedPhases list is NULL");
}
}
marker = in.readUTF(); // Read marker
if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
log.trace(getLogIDString() +
": readExternal(): After reading executedPhases, marker is: " + marker);
}
// If this is an oldStyle that contained both an inbound and outbound executed phases,
// and the outbound phases wasn't read above, then we need to skip over it
if (marker.equals("outboundExecutedPhases")) {
Boolean gotOutExecList = in.readBoolean();
if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
log.trace(getLogIDString() +
": readExternal(): Skipping over outboundExecutedPhases, marker is: " + marker +
", is list an active object: " + gotOutExecList);
}
if (gotOutExecList != ExternalizeConstants.EMPTY_OBJECT) {
throw new IOException("Both inboundExecutedPhases and outboundExecutedPhases had active objects");
}
marker = in.readUTF();
if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
log.trace(getLogIDString() +
": readExternal(): After skipping ooutboundExecutePhases, marker is: " + marker);
}
}
//---------------------------------------------------------
// options
//---------------------------------------------------------
options = (Options) in.readObject();
if (options != null) {
if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
log.trace(getLogIDString() + ":readExternal(): restored Options [" +
options.getLogCorrelationIDString() + "]");
}
}
//---------------------------------------------------------
// operation
//---------------------------------------------------------
// axisOperation is not usable until the meta data has been reconciled
axisOperation = null;
marker = in.readUTF(); // Read Marker
if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
log.trace(getLogIDString() +
": readExternal(): About to read axisOperation, marker is: " + marker);
}
metaAxisOperation = (MetaDataEntry) in.readObject();
// operation context is not usable until it has been activated
// NOTE: expect this to be the parent
marker = in.readUTF(); // Read marker
if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
log.trace(getLogIDString() +
": readExternal(): About to read operationContext, marker is: " + marker);
}
operationContext = (OperationContext) in.readObject();
if (operationContext != null) {
if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
log.trace(getLogIDString() + ":readExternal(): restored OperationContext [" +
operationContext.getLogCorrelationIDString() + "]");
}
}
//---------------------------------------------------------
// service
//---------------------------------------------------------
// axisService is not usable until the meta data has been reconciled
axisService = null;
marker = in.readUTF(); // Read marker
if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
log.trace(getLogIDString() +
": readExternal(): About to read axisService, marker is: " + marker);
}
metaAxisService = (MetaDataEntry) in.readObject();
//-------------------------
// serviceContextID string
//-------------------------
serviceContextID = (String) in.readObject();
//-------------------------
// serviceContext
//-------------------------
marker = in.readUTF(); // Read marker
if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
log.trace(getLogIDString() +
": readExternal(): About to read serviceContext, marker is: " + marker);
}
boolean servCtxActive = in.readBoolean();
if (servCtxActive == ExternalizeConstants.EMPTY_OBJECT) {
// empty object
serviceContext = null;
} else {
// active object
boolean isParent = in.readBoolean();
// there's an object to read in if it is not the parent of the operation context
if (!isParent) {
serviceContext = (ServiceContext) in.readObject();
} else {
// the service context is the parent of the operation context
// so get it from the operation context during activate
serviceContext = null;
}
}
//---------------------------------------------------------
// serviceGroup
//---------------------------------------------------------
// axisServiceGroup is not usable until the meta data has been reconciled
axisServiceGroup = null;
marker = in.readUTF(); // Read marker
if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
log.trace(getLogIDString() +
": readExternal(): About to read AxisServiceGroup, marker is: " + marker);
}
metaAxisServiceGroup = (MetaDataEntry) in.readObject();
//-----------------------------
// serviceGroupContextId string
//-----------------------------
serviceGroupContextId = (String) in.readObject();
//-----------------------------
// serviceGroupContext
//-----------------------------
marker = in.readUTF();
if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
log.trace(getLogIDString() +
": readExternal(): About to read ServiceGroupContext, marker is: " + marker);
}
boolean servGrpCtxActive = in.readBoolean();
if (servGrpCtxActive == ExternalizeConstants.EMPTY_OBJECT) {
// empty object
serviceGroupContext = null;
} else {
// active object
boolean isParentSGC = in.readBoolean();
// there's an object to read in if it is not the parent of the service group context
if (!isParentSGC) {
serviceGroupContext = (ServiceGroupContext) in.readObject();
} else {
// the service group context is the parent of the service context
// so get it from the service context during activate
serviceGroupContext = null;
}
}
//---------------------------------------------------------
// axis message
//---------------------------------------------------------
// axisMessage is not usable until the meta data has been reconciled
axisMessage = null;
marker = in.readUTF(); // Read marker
if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
log.trace(getLogIDString() +
": readExternal(): About to read AxisMessage, marker is: " + marker);
}
metaAxisMessage = (MetaDataEntry) in.readObject();
reconcileAxisMessage = (metaAxisMessage != null);
//---------------------------------------------------------
// configuration context
//---------------------------------------------------------
// TODO: check to see if there is any runtime data important to this
// message context in the configuration context
// if so, then need to restore the saved runtime data and reconcile
// it with the configuration context on the system when
// this message context object is restored
//---------------------------------------------------------
// session context
//---------------------------------------------------------
sessionContext = (SessionContext) in.readObject();
//---------------------------------------------------------
// transport
//---------------------------------------------------------
//------------------------------
// incomingTransportName string
//------------------------------
incomingTransportName = (String) in.readObject();
// TransportInDescription transportIn
// is not usable until the meta data has been reconciled
transportIn = null;
metaTransportIn = (MetaDataEntry) in.readObject();
// TransportOutDescription transportOut
// is not usable until the meta data has been reconciled
transportOut = null;
metaTransportOut = (MetaDataEntry) in.readObject();
//---------------------------------------------------------
// properties
//---------------------------------------------------------
// read local properties
marker = in.readUTF(); // Read marker
if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
log.trace(getLogIDString() +
": readExternal(): About to read properties, marker is: " + marker);
}
properties = in.readMap(new HashMapUpdateLockable());
//---------------------------------------------------------
// special data
//---------------------------------------------------------
marker = in.readUTF(); // Read marker
if (LoggingControl.debugLoggingAllowed && log.isTraceEnabled()) {
log.trace(getLogIDString() +
": readExternal(): About to read SpecialData, marker is: " + marker);
}
boolean gotSelfManagedData = in.readBoolean();
if (gotSelfManagedData == ExternalizeConstants.ACTIVE_OBJECT) {
selfManagedDataHandlerCount = in.readInt();
if (selfManagedDataListHolder == null) {
selfManagedDataListHolder = new ArrayList<SelfManagedDataHolder>();
} else {
selfManagedDataListHolder.clear();
}
for (int i = 0; i < selfManagedDataHandlerCount; i++) {
selfManagedDataListHolder.add((SelfManagedDataHolder) in.readObject());
}
}
//---------------------------------------------------------
// done