/*
* Copyright (c) 2000, 2003, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package org.jboss.com.sun.corba.se.impl.ior;
import java.io.IOException;
import org.jboss.com.sun.corba.se.impl.encoding.EncapsInputStream;
import org.jboss.com.sun.corba.se.impl.orbutil.ORBConstants;
import org.jboss.com.sun.corba.se.spi.ior.ObjectId;
import org.jboss.com.sun.corba.se.spi.ior.ObjectKey;
import org.jboss.com.sun.corba.se.spi.ior.ObjectKeyFactory;
import org.jboss.com.sun.corba.se.spi.ior.ObjectKeyTemplate;
import org.jboss.com.sun.corba.se.spi.orb.ORB;
import org.omg.CORBA.MARSHAL;
import org.omg.CORBA.OctetSeqHolder;
import org.omg.CORBA_2_3.portable.InputStream;
/**
* Based on the magic and scid, return the appropriate ObjectKeyTemplate. Expects to be called with a valid magic. If
* scid is not valid, null should be returned.
*/
interface Handler
{
ObjectKeyTemplate handle(int magic, int scid, InputStream is, OctetSeqHolder osh);
}
/**
* Singleton used to manufacture ObjectKey and ObjectKeyTemplate instances.
*
* @author Ken Cavanaugh
*/
public class ObjectKeyFactoryImpl implements ObjectKeyFactory
{
public static final int MAGIC_BASE = 0xAFABCAFE;
// Magic used in our object keys for JDK 1.2, 1.3, RMI-IIOP OP,
// J2EE 1.0-1.2.1.
public static final int JAVAMAGIC_OLD = MAGIC_BASE;
// Magic used only in JDK 1.3.1. No format changes in object keys.
public static final int JAVAMAGIC_NEW = MAGIC_BASE + 1;
// New magic used in our object keys for JDK 1.4, J2EE 1.3 and later.
// Format changes: all object keys have version string; POA key format is changed.
public static final int JAVAMAGIC_NEWER = MAGIC_BASE + 2;
public static final int MAX_MAGIC = JAVAMAGIC_NEWER;
// Beginning in JDK 1.3.1_01, we introduced changes which required the ability to distinguish between JDK 1.3.1 FCS
// and the patch versions. See OldJIDLObjectKeyTemplate.
public static final byte JDK1_3_1_01_PATCH_LEVEL = 1;
private final ORB orb;
public ObjectKeyFactoryImpl(ORB orb)
{
this.orb = orb;
}
// XXX The handlers still need to be made pluggable.
//
// I think this can be done as follows:
// 1. Move the Handler interface into the SPI as ObjectKeyHandler.
// 2. Add two methods to ObjectAdapterFactory:
// ObjectKeyHandler getHandlerForObjectKey( ) ;
// ObjectKeyHandler getHandlerForObjectKeyTemplate( ) ;
// 3. Move the implementation of the fullKey handler and the
// oktempOnly handler into TOAFactory and POAFactory.
// 4. Move the ObjectKey impl classes into the impl/oa packages.
// 5. Create an internal interface
// interface HandlerFinder {
// ObjectKeyHandler get( int scid ) ;
// }
// and modify create(InputStream,Handler,OctetSeqHolder)
// to take a HandlerFinder instead of a Handler.
// 6. Modify create( byte[] ) and createTemplate( InputStream )
// to create an instance of HandlerFinder: something like:
// new HandlerFinder() {
// ObjectKeyHandler get( int scid )
// {
// return orb.getRequestDispatcherRegistry().
// getObjectAdapterFactory( scid ).getHandlerForObjectKey() ;
// }
// and similarly for getHandlerForObjectKeyTemplate.
/**
* This handler reads the full object key, both the oktemp and the ID.
*/
private Handler fullKey = new Handler()
{
public ObjectKeyTemplate handle(int magic, int scid, InputStream is, OctetSeqHolder osh)
{
ObjectKeyTemplate oktemp = null;
if ((scid >= ORBConstants.FIRST_POA_SCID) && (scid <= ORBConstants.MAX_POA_SCID))
{
if (magic >= JAVAMAGIC_NEWER)
oktemp = new POAObjectKeyTemplate(orb, magic, scid, is, osh);
else
oktemp = new OldPOAObjectKeyTemplate(orb, magic, scid, is, osh);
}
else if ((scid >= 0) && (scid < ORBConstants.FIRST_POA_SCID))
{
if (magic >= JAVAMAGIC_NEWER)
oktemp = new JIDLObjectKeyTemplate(orb, magic, scid, is, osh);
else
oktemp = new OldJIDLObjectKeyTemplate(orb, magic, scid, is, osh);
}
return oktemp;
}
};
/**
* This handler reads only the oktemp.
*/
private Handler oktempOnly = new Handler()
{
public ObjectKeyTemplate handle(int magic, int scid, InputStream is, OctetSeqHolder osh)
{
ObjectKeyTemplate oktemp = null;
if ((scid >= ORBConstants.FIRST_POA_SCID) && (scid <= ORBConstants.MAX_POA_SCID))
{
if (magic >= JAVAMAGIC_NEWER)
oktemp = new POAObjectKeyTemplate(orb, magic, scid, is);
else
oktemp = new OldPOAObjectKeyTemplate(orb, magic, scid, is);
}
else if ((scid >= 0) && (scid < ORBConstants.FIRST_POA_SCID))
{
if (magic >= JAVAMAGIC_NEWER)
oktemp = new JIDLObjectKeyTemplate(orb, magic, scid, is);
else
oktemp = new OldJIDLObjectKeyTemplate(orb, magic, scid, is);
}
return oktemp;
}
};
/**
* Returns true iff magic is in the range of valid magic numbers for our ORB.
*/
private boolean validMagic(int magic)
{
return (magic >= MAGIC_BASE) && (magic <= MAX_MAGIC);
}
/**
* Creates an ObjectKeyTemplate from the InputStream. Most of the decoding is done inside the handler.
*/
private ObjectKeyTemplate create(InputStream is, Handler handler, OctetSeqHolder osh)
{
ObjectKeyTemplate oktemp = null;
try
{
is.mark(0);
int magic = is.read_long();
if (validMagic(magic))
{
int scid = is.read_long();
oktemp = handler.handle(magic, scid, is, osh);
}
}
catch (MARSHAL mexc)
{
// XXX log this error
// ignore this: error handled below because oktemp == null
}
if (oktemp == null)
// If we did not successfully construct a oktemp, reset the stream so that WireObjectKeyTemplate can
// correctly construct the object key.
try
{
is.reset();
}
catch (IOException exc)
{
// XXX log this error
// ignore this
}
return oktemp;
}
public ObjectKey create(byte[] key)
{
OctetSeqHolder osh = new OctetSeqHolder();
EncapsInputStream is = new EncapsInputStream(orb, key, key.length);
ObjectKeyTemplate oktemp = create(is, fullKey, osh);
if (oktemp == null)
oktemp = new WireObjectKeyTemplate(is, osh);
ObjectId oid = new ObjectIdImpl(osh.value);
return new ObjectKeyImpl(oktemp, oid);
}
public ObjectKeyTemplate createTemplate(InputStream is)
{
ObjectKeyTemplate oktemp = create(is, oktempOnly, null);
if (oktemp == null)
oktemp = new WireObjectKeyTemplate(orb);
return oktemp;
}
}