ObjectKeyFactoryImpl.java revision 608:7e06bf1dcb09
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
26package com.sun.corba.se.impl.ior;
27
28import java.io.IOException ;
29
30import org.omg.CORBA.MARSHAL ;
31import org.omg.CORBA.OctetSeqHolder ;
32import org.omg.CORBA_2_3.portable.InputStream ;
33
34import com.sun.corba.se.spi.ior.ObjectId ;
35import com.sun.corba.se.spi.ior.ObjectKey ;
36import com.sun.corba.se.spi.ior.ObjectKeyFactory ;
37import com.sun.corba.se.spi.ior.ObjectKeyTemplate ;
38
39import com.sun.corba.se.spi.orb.ORB ;
40import com.sun.corba.se.spi.logging.CORBALogDomains ;
41
42import com.sun.corba.se.impl.orbutil.ORBConstants ;
43
44import com.sun.corba.se.impl.ior.JIDLObjectKeyTemplate ;
45import com.sun.corba.se.impl.ior.POAObjectKeyTemplate ;
46import com.sun.corba.se.impl.ior.WireObjectKeyTemplate ;
47import com.sun.corba.se.impl.ior.ObjectIdImpl ;
48import com.sun.corba.se.impl.ior.ObjectKeyImpl ;
49import com.sun.corba.se.impl.logging.IORSystemException ;
50
51import com.sun.corba.se.impl.encoding.EncapsInputStream ;
52import 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*/
59interface 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 */
68public 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}
241