1 /*
   2  * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.sun.corba.se.impl.ior;
  27 
  28 import java.io.IOException ;
  29 
  30 import org.omg.CORBA.MARSHAL ;
  31 import org.omg.CORBA.OctetSeqHolder ;
  32 import org.omg.CORBA_2_3.portable.InputStream ;
  33 
  34 import com.sun.corba.se.spi.ior.ObjectId ;
  35 import com.sun.corba.se.spi.ior.ObjectKey ;
  36 import com.sun.corba.se.spi.ior.ObjectKeyFactory ;
  37 import com.sun.corba.se.spi.ior.ObjectKeyTemplate ;
  38 
  39 import com.sun.corba.se.spi.orb.ORB ;
  40 import com.sun.corba.se.spi.logging.CORBALogDomains ;
  41 
  42 import com.sun.corba.se.impl.orbutil.ORBConstants ;
  43 
  44 import com.sun.corba.se.impl.ior.JIDLObjectKeyTemplate ;
  45 import com.sun.corba.se.impl.ior.POAObjectKeyTemplate ;
  46 import com.sun.corba.se.impl.ior.WireObjectKeyTemplate ;
  47 import com.sun.corba.se.impl.ior.ObjectIdImpl ;
  48 import com.sun.corba.se.impl.ior.ObjectKeyImpl ;
  49 import com.sun.corba.se.impl.logging.IORSystemException ;
  50 
  51 import com.sun.corba.se.impl.encoding.EncapsInputStream ;
  52 import sun.corba.EncapsInputStreamFactory;
  53 
  54 
  55 /** Based on the magic and scid, return the appropriate
  56 * ObjectKeyTemplate.  Expects to be called with a valid
  57 * magic.  If scid is not valid, null should be returned.
  58 */
  59 interface Handler {
  60     ObjectKeyTemplate handle( int magic, int scid,
  61         InputStream is, OctetSeqHolder osh ) ;
  62 }
  63 
  64 /** Singleton used to manufacture ObjectKey and ObjectKeyTemplate
  65  * instances.
  66  * @author Ken Cavanaugh
  67  */
  68 public class ObjectKeyFactoryImpl implements ObjectKeyFactory
  69 {
  70     public static final int MAGIC_BASE                  = 0xAFABCAFE ;
  71 
  72     // Magic used in our object keys for JDK 1.2, 1.3, RMI-IIOP OP,
  73     // J2EE 1.0-1.2.1.
  74     public static final int JAVAMAGIC_OLD               = MAGIC_BASE ;
  75 
  76     // Magic used only in JDK 1.3.1.  No format changes in object keys.
  77     public static final int JAVAMAGIC_NEW               = MAGIC_BASE + 1 ;
  78 
  79     // New magic used in our object keys for JDK 1.4, J2EE 1.3 and later.
  80     // Format changes: all object keys have version string; POA key format
  81     // is changed.
  82     public static final int JAVAMAGIC_NEWER             = MAGIC_BASE + 2 ;
  83 
  84     public static final int MAX_MAGIC                   = JAVAMAGIC_NEWER ;
  85 
  86     // Beginning in JDK 1.3.1_01, we introduced changes which required
  87     // the ability to distinguish between JDK 1.3.1 FCS and the patch
  88     // versions.  See OldJIDLObjectKeyTemplate.
  89     public static final byte JDK1_3_1_01_PATCH_LEVEL = 1;
  90 
  91     private final ORB orb ;
  92     private IORSystemException wrapper ;
  93 
  94     public ObjectKeyFactoryImpl( ORB orb )
  95     {
  96         this.orb = orb ;
  97         wrapper = IORSystemException.get( orb,
  98             CORBALogDomains.OA_IOR ) ;
  99     }
 100 
 101     // XXX The handlers still need to be made pluggable.
 102     //
 103     // I think this can be done as follows:
 104     // 1. Move the Handler interface into the SPI as ObjectKeyHandler.
 105     // 2. Add two methods to ObjectAdapterFactory:
 106     //      ObjectKeyHandler getHandlerForObjectKey( ) ;
 107     //      ObjectKeyHandler getHandlerForObjectKeyTemplate( ) ;
 108     // 3. Move the implementation of the fullKey handler and the
 109     //    oktempOnly handler into TOAFactory and POAFactory.
 110     // 4. Move the ObjectKey impl classes into the impl/oa packages.
 111     // 5. Create an internal interface
 112     //      interface HandlerFinder {
 113     //          ObjectKeyHandler get( int scid ) ;
 114     //      }
 115     //    and modify create(InputStream,Handler,OctetSeqHolder)
 116     //    to take a HandlerFinder instead of a Handler.
 117     // 6. Modify create( byte[] ) and createTemplate( InputStream )
 118     //    to create an instance of HandlerFinder: something like:
 119     //      new HandlerFinder() {
 120     //          ObjectKeyHandler get( int scid )
 121     //          {
 122     //              return orb.getRequestDispatcherRegistry().
 123     //                  getObjectAdapterFactory( scid ).getHandlerForObjectKey() ;
 124     //          }
 125     //      and similarly for getHandlerForObjectKeyTemplate.
 126 
 127     /** This handler reads the full object key, both the oktemp
 128     * and the ID.
 129     */
 130     private Handler fullKey = new Handler() {
 131         public ObjectKeyTemplate handle( int magic, int scid,
 132             InputStream is, OctetSeqHolder osh ) {
 133                 ObjectKeyTemplate oktemp = null ;
 134 
 135                 if ((scid >= ORBConstants.FIRST_POA_SCID) &&
 136                     (scid <= ORBConstants.MAX_POA_SCID)) {
 137                     if (magic >= JAVAMAGIC_NEWER)
 138                         oktemp = new POAObjectKeyTemplate( orb, magic, scid, is, osh ) ;
 139                     else
 140                         oktemp = new OldPOAObjectKeyTemplate( orb, magic, scid, is, osh ) ;
 141                 } else if ((scid >= 0) && (scid < ORBConstants.FIRST_POA_SCID)) {
 142                     if (magic >= JAVAMAGIC_NEWER)
 143                         oktemp = new JIDLObjectKeyTemplate( orb, magic, scid, is, osh ) ;
 144                     else
 145                         oktemp = new OldJIDLObjectKeyTemplate( orb, magic, scid, is, osh );
 146                 }
 147 
 148                 return oktemp ;
 149             }
 150         } ;
 151 
 152     /** This handler reads only the oktemp.
 153     */
 154     private Handler oktempOnly = new Handler() {
 155         public ObjectKeyTemplate handle( int magic, int scid,
 156             InputStream is, OctetSeqHolder osh ) {
 157                 ObjectKeyTemplate oktemp = null ;
 158 
 159                 if ((scid >= ORBConstants.FIRST_POA_SCID) &&
 160                     (scid <= ORBConstants.MAX_POA_SCID)) {
 161                     if (magic >= JAVAMAGIC_NEWER)
 162                         oktemp = new POAObjectKeyTemplate( orb, magic, scid, is ) ;
 163                     else
 164                         oktemp = new OldPOAObjectKeyTemplate( orb, magic, scid, is ) ;
 165                 } else if ((scid >= 0) && (scid < ORBConstants.FIRST_POA_SCID)) {
 166                     if (magic >= JAVAMAGIC_NEWER)
 167                         oktemp = new JIDLObjectKeyTemplate( orb, magic, scid, is ) ;
 168                     else
 169                         oktemp = new OldJIDLObjectKeyTemplate( orb, magic, scid, is ) ;
 170                 }
 171 
 172                 return oktemp ;
 173             }
 174         } ;
 175 
 176     /** Returns true iff magic is in the range of valid magic numbers
 177     * for our ORB.
 178     */
 179     private boolean validMagic( int magic )
 180     {
 181         return (magic >= MAGIC_BASE) && (magic <= MAX_MAGIC) ;
 182     }
 183 
 184     /** Creates an ObjectKeyTemplate from the InputStream.  Most of the
 185     * decoding is done inside the handler.
 186     */
 187     private ObjectKeyTemplate create( InputStream is, Handler handler,
 188         OctetSeqHolder osh )
 189     {
 190         ObjectKeyTemplate oktemp = null ;
 191 
 192         try {
 193             is.mark(0) ;
 194             int magic = is.read_long() ;
 195 
 196             if (validMagic( magic )) {
 197                 int scid = is.read_long() ;
 198                 oktemp = handler.handle( magic, scid, is, osh ) ;
 199             }
 200         } catch (MARSHAL mexc) {
 201             // XXX log this error
 202             // ignore this: error handled below because oktemp == null
 203         }
 204 
 205         if (oktemp == null)
 206             // If we did not successfully construct a oktemp, reset the
 207             // stream so that WireObjectKeyTemplate can correctly construct the
 208             // object key.
 209             try {
 210                 is.reset() ;
 211             } catch (IOException exc) {
 212                 // XXX log this error
 213                 // ignore this
 214             }
 215 
 216         return oktemp ;
 217     }
 218 
 219     public ObjectKey create( byte[] key )
 220     {
 221         OctetSeqHolder osh = new OctetSeqHolder() ;
 222         EncapsInputStream is = EncapsInputStreamFactory.newEncapsInputStream( orb, key, key.length );
 223 
 224         ObjectKeyTemplate oktemp = create( is, fullKey, osh ) ;
 225         if (oktemp == null)
 226             oktemp = new WireObjectKeyTemplate( is, osh ) ;
 227 
 228         ObjectId oid = new ObjectIdImpl( osh.value ) ;
 229         return new ObjectKeyImpl( oktemp, oid ) ;
 230     }
 231 
 232     public ObjectKeyTemplate createTemplate( InputStream is )
 233     {
 234         ObjectKeyTemplate oktemp = create( is, oktempOnly, null ) ;
 235         if (oktemp == null)
 236             oktemp = new WireObjectKeyTemplate( orb ) ;
 237 
 238         return oktemp ;
 239     }
 240 }