FileDocCategorySizeDatePackage
ServiceContexts.javaAPI DocJava SE 5 API11739Fri Aug 26 14:54:40 BST 2005com.sun.corba.se.spi.servicecontext

ServiceContexts

public class ServiceContexts extends Object

Fields Summary
private static final int
JAVAIDL_ALIGN_SERVICE_ID
Hopefully unused scid: This should be changed to a proper VMCID aligned value. REVISIT!
private com.sun.corba.se.spi.orb.ORB
orb
private Map
scMap
Map of all ServiceContext objects in this container. Keys are java.lang.Integers for service context IDs. Values are either instances of ServiceContext or the unmarshaled byte arrays (unmarshaled on first use). This provides a mild optimization if we don't happen to use a given service context, but it's main advantage is that it allows us to change the order in which we unmarshal them. We need to do the UnknownExceptionInfo service context after the SendingContextRunTime service context so that we can get the CodeBase if necessary.
private boolean
addAlignmentOnWrite
If true, write out a special alignment service context to force the correct alignment on re-marshalling.
private com.sun.org.omg.SendingContext.CodeBase
codeBase
private com.sun.corba.se.spi.ior.iiop.GIOPVersion
giopVersion
private com.sun.corba.se.impl.logging.ORBUtilSystemException
wrapper
Constructors Summary
public ServiceContexts(com.sun.corba.se.spi.orb.ORB orb)

	this.orb = orb ;
	wrapper = ORBUtilSystemException.get( orb, 
	    CORBALogDomains.RPC_PROTOCOL ) ;

	addAlignmentOnWrite = false ;

        scMap = new HashMap();

        // Use the GIOP version of the ORB.  Should
        // be specified in ServiceContext.  
        // See REVISIT below concerning giopVersion.
        giopVersion = orb.getORBData().getGIOPVersion();
	codeBase = null ;
    
public ServiceContexts(org.omg.CORBA_2_3.portable.InputStream s)
Read the Service contexts from the input stream.

	this( (ORB)(s.orb()) ) ;

        // We need to store this so that we can have access
        // to the CodeBase for unmarshaling possible
        // RMI-IIOP valuetype data within an encapsulation.
        // (Known case: UnknownExceptionInfo)
        codeBase = ((CDRInputStream)s).getCodeBase();

        createMapFromInputStream(s);

	// Fix for bug 4904723
	giopVersion = ((CDRInputStream)s).getGIOPVersion();
    
Methods Summary
public voidaddAlignmentPadding()

	// Make service context 12 bytes longer by adding 
	// JAVAIDL_ALIGN_SERVICE_ID service context at end.
	// The exact length
	// must be >8 (minimum service context size) and 
	// =4 mod 8, so 12 is the minimum.
	addAlignmentOnWrite = true ;
    
private voidcreateMapFromInputStream(org.omg.CORBA_2_3.portable.InputStream is)
Given the input stream, this fills our service context map. See the definition of scMap for details. Creates a HashMap. Note that we don't actually unmarshal the bytes of the service contexts here. That is done when they are actually requested via get(int).

        orb = (ORB)(is.orb()) ;
        if (orb.serviceContextDebugFlag)
            dprint( "Constructing ServiceContexts from input stream" ) ;

        int numValid = is.read_long() ;

        if (orb.serviceContextDebugFlag)
            dprint("Number of service contexts = " + numValid);

        for (int ctr = 0; ctr < numValid; ctr++) {
            int scId = is.read_long();

            if (orb.serviceContextDebugFlag)
                dprint("Reading service context id " + scId);

            byte[] data = OctetSeqHelper.read(is);

            if (orb.serviceContextDebugFlag)
                dprint("Service context" + scId + " length: " + data.length);

            scMap.put(new Integer(scId), data);
        }
    
public voiddelete(int scId)

        this.delete(new Integer(scId));
    
public voiddelete(java.lang.Integer id)

        scMap.remove(id)  ;
    
private voiddprint(java.lang.String msg)

	ORBUtility.dprint( this, msg ) ;
    
public com.sun.corba.se.spi.servicecontext.ServiceContextget(int scId)

        return this.get(new Integer(scId));
    
public com.sun.corba.se.spi.servicecontext.ServiceContextget(java.lang.Integer id)

        Object result = scMap.get(id);
	if (result == null)
	    return null ;

        // Lazy unmarshaling on first use.
        if (result instanceof byte[]) {

            ServiceContext sc = unmarshal(id, (byte[])result);

            scMap.put(id, sc);

            return sc;
        } else {
            return (ServiceContext)result;
        }
    
private static booleanisDebugging(org.omg.CORBA_2_3.portable.OutputStream os)

	ORB orb = (ORB)(os.orb()) ;
	if (orb==null)
	    return false ;
	return orb.serviceContextDebugFlag ;
    
private static booleanisDebugging(org.omg.CORBA_2_3.portable.InputStream is)

	ORB orb = (ORB)(is.orb()) ;
	if (orb==null) 
	    return false ;
	return orb.serviceContextDebugFlag ;
    
public voidput(com.sun.corba.se.spi.servicecontext.ServiceContext sc)
Add a service context to the stream, if there is not already a service context in this object with the same id as sc.

        Integer id = new Integer(sc.getId());
        scMap.put(id, sc);
    
private com.sun.corba.se.spi.servicecontext.ServiceContextunmarshal(java.lang.Integer scId, byte[] data)
Find the ServiceContextData for a given scId and unmarshal the bytes.


        ServiceContextRegistry scr = orb.getServiceContextRegistry();

        ServiceContextData scd = scr.findServiceContextData(scId.intValue());
        ServiceContext sc = null;

        if (scd == null) {
            if (orb.serviceContextDebugFlag) {
                dprint("Could not find ServiceContextData for "
                       + scId
                       + " using UnknownServiceContext");
            }

            sc = new UnknownServiceContext(scId.intValue(), data);

        } else {

            if (orb.serviceContextDebugFlag) {
                dprint("Found " + scd);
            }

            // REVISIT.  GIOP version should be specified as
            // part of a service context's definition, so should
            // be accessible from ServiceContextData via
            // its ServiceContext implementation class.
            //
            // Since we don't have that, yet, I'm using the GIOP
            // version of the input stream, presuming that someone
            // can't send a service context of a later GIOP
            // version than its stream version.
            //
            // Note:  As of Jan 2001, no standard OMG or Sun service contexts
            // ship wchar data or are defined as using anything but GIOP 1.0 CDR.
            EncapsInputStream eis 
                = new EncapsInputStream(orb,
                                        data,
                                        data.length,
                                        giopVersion,
                                        codeBase);
            eis.consumeEndian();

	    // Now the input stream passed to a ServiceContext
	    // constructor is already the encapsulation input
	    // stream with the endianness read off, so the
	    // service context should just unmarshal its own
	    // data.
	    sc = scd.makeServiceContext(eis, giopVersion);
	    if (sc == null)
		throw wrapper.svcctxUnmarshalError( 
		    CompletionStatus.COMPLETED_MAYBE);
        }

        return sc;
    
public voidwrite(org.omg.CORBA_2_3.portable.OutputStream os, com.sun.corba.se.spi.ior.iiop.GIOPVersion gv)
Write the service contexts to the output stream. If they haven't been unmarshaled, we don't have to unmarshal them.


                             
         
    
	if (isDebugging(os)) {
	    dprint( "Writing service contexts to output stream" ) ;
	    Utility.printStackTrace() ;
  	}

	int numsc = scMap.size();

	if (addAlignmentOnWrite) {
	    if (isDebugging(os))
		dprint( "Adding alignment padding" ) ;

	    numsc++ ;
	}

	if (isDebugging(os))
	    dprint( "Service context has " + numsc + " components"  ) ;

	os.write_long( numsc ) ;

        writeServiceContextsInOrder(os, gv);

	if (addAlignmentOnWrite) {
	    if (isDebugging(os))
		dprint( "Writing alignment padding" ) ;

	    os.write_long( JAVAIDL_ALIGN_SERVICE_ID ) ;
	    os.write_long( 4 ) ;
	    os.write_octet( (byte)0 ) ;
	    os.write_octet( (byte)0 ) ;
	    os.write_octet( (byte)0 ) ;
	    os.write_octet( (byte)0 ) ;
	}

	if (isDebugging(os))
	    dprint( "Service context writing complete" ) ;
    
private voidwriteMapEntry(org.omg.CORBA_2_3.portable.OutputStream os, java.lang.Integer id, java.lang.Object scObj, com.sun.corba.se.spi.ior.iiop.GIOPVersion gv)
Write the given entry from the scMap to the OutputStream. See note on giopVersion. The service context should know the GIOP version it is meant for.


        // If it's still in byte[] form, we don't need to
        // unmarshal it here, just copy the bytes into
        // the new stream.

        if (scObj instanceof byte[]) {
            if (isDebugging(os))
                dprint( "Writing service context bytes for id " + id);

            OctetSeqHelper.write(os, (byte[])scObj);

        } else {

            // We actually unmarshaled it into a ServiceContext
            // at some point.
            ServiceContext sc = (ServiceContext)scObj;

            if (isDebugging(os))
                dprint( "Writing service context " + sc ) ;

            sc.write(os, gv);
        }
    
public static voidwriteNullServiceContext(org.omg.CORBA_2_3.portable.OutputStream os)

	if (isDebugging(os))
	    ORBUtility.dprint( "ServiceContexts", "Writing null service context" ) ;
	os.write_long( 0 ) ;
    
private voidwriteServiceContextsInOrder(org.omg.CORBA_2_3.portable.OutputStream os, com.sun.corba.se.spi.ior.iiop.GIOPVersion gv)
Write the service contexts in scMap in a desired order. Right now, the only special case we have is UnknownExceptionInfo, so I'm merely writing it last if present.


        // Temporarily remove this rather than check it per iteration
        Integer ueInfoId
            = new Integer(UEInfoServiceContext.SERVICE_CONTEXT_ID);

        Object unknownExceptionInfo = scMap.remove(ueInfoId);

	Iterator iter = scMap.keySet().iterator();

	while (iter.hasNext()) {
            Integer id = (Integer)iter.next();

            writeMapEntry(os, id, scMap.get(id), gv);
        }

        // Write the UnknownExceptionInfo service context last
        // (so it will be after the CodeBase) and restore it in
        // the map.
        if (unknownExceptionInfo != null) {
            writeMapEntry(os, ueInfoId, unknownExceptionInfo, gv);

            scMap.put(ueInfoId, unknownExceptionInfo);
        }