IIOPProfileImpl.java revision 672:2bb058ce572e
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.iiop;
27
28import java.util.List ;
29import java.util.Iterator ;
30
31import org.omg.CORBA.SystemException ;
32
33import org.omg.CORBA_2_3.portable.OutputStream ;
34import org.omg.CORBA_2_3.portable.InputStream ;
35
36import org.omg.IOP.TAG_ALTERNATE_IIOP_ADDRESS ;
37import org.omg.IOP.TAG_INTERNET_IOP;
38import org.omg.IOP.TAG_JAVA_CODEBASE;
39
40import com.sun.corba.se.spi.protocol.RequestDispatcherRegistry ;
41
42import com.sun.corba.se.spi.oa.ObjectAdapter ;
43import com.sun.corba.se.spi.oa.ObjectAdapterFactory ;
44
45import com.sun.corba.se.spi.ior.ObjectId ;
46import com.sun.corba.se.spi.ior.ObjectAdapterId ;
47import com.sun.corba.se.spi.ior.TaggedProfile ;
48import com.sun.corba.se.spi.ior.TaggedProfileTemplate ;
49import com.sun.corba.se.spi.ior.ObjectKey ;
50import com.sun.corba.se.spi.ior.ObjectKeyTemplate ;
51import com.sun.corba.se.spi.ior.TaggedComponent ;
52import com.sun.corba.se.spi.ior.IdentifiableBase ;
53import com.sun.corba.se.spi.ior.IORFactories ;
54import com.sun.corba.se.spi.ior.ObjectKeyFactory ;
55
56import com.sun.corba.se.spi.ior.iiop.IIOPAddress ;
57import com.sun.corba.se.spi.ior.iiop.IIOPProfile ;
58import com.sun.corba.se.spi.ior.iiop.IIOPProfileTemplate ;
59import com.sun.corba.se.spi.ior.iiop.IIOPFactories ;
60import com.sun.corba.se.spi.ior.iiop.GIOPVersion ;
61import com.sun.corba.se.spi.ior.iiop.JavaCodebaseComponent ;
62
63import com.sun.corba.se.spi.orb.ORB ;
64import com.sun.corba.se.spi.orb.ORBVersion ;
65
66import com.sun.corba.se.spi.logging.CORBALogDomains ;
67
68import com.sun.corba.se.impl.ior.EncapsulationUtility ;
69
70import com.sun.corba.se.impl.encoding.EncapsInputStream ;
71import com.sun.corba.se.impl.encoding.EncapsOutputStream ;
72
73import sun.corba.EncapsInputStreamFactory;
74
75import com.sun.corba.se.impl.util.JDKBridge;
76
77import com.sun.corba.se.impl.logging.IORSystemException;
78
79public class IIOPProfileImpl extends IdentifiableBase implements IIOPProfile
80{
81    private ORB orb ;
82    private IORSystemException wrapper ;
83    private ObjectId oid;
84    private IIOPProfileTemplate proftemp;
85    private ObjectKeyTemplate oktemp ;
86
87    // Cached lookups
88    protected String codebase = null ;
89    protected boolean cachedCodebase = false;
90
91    private boolean checkedIsLocal = false ;
92    private boolean cachedIsLocal = false ;
93
94    // initialize-on-demand holder
95    private static class LocalCodeBaseSingletonHolder {
96        public static JavaCodebaseComponent comp ;
97
98        static {
99            String localCodebase = JDKBridge.getLocalCodebase() ;
100            if (localCodebase == null)
101                comp = null ;
102            else
103                comp = IIOPFactories.makeJavaCodebaseComponent(
104                    localCodebase ) ;
105        }
106    }
107
108    private GIOPVersion giopVersion = null;
109
110    public boolean equals( Object obj )
111    {
112        if (!(obj instanceof IIOPProfileImpl))
113            return false ;
114
115        IIOPProfileImpl other = (IIOPProfileImpl)obj ;
116
117        return oid.equals( other.oid ) && proftemp.equals( other.proftemp ) &&
118            oktemp.equals( other.oktemp ) ;
119    }
120
121    public int hashCode()
122    {
123        return oid.hashCode() ^ proftemp.hashCode() ^ oktemp.hashCode() ;
124    }
125
126    public ObjectId getObjectId()
127    {
128        return oid ;
129    }
130
131    public TaggedProfileTemplate getTaggedProfileTemplate()
132    {
133        return proftemp ;
134    }
135
136    public ObjectKeyTemplate getObjectKeyTemplate()
137    {
138        return oktemp ;
139    }
140
141    private IIOPProfileImpl( ORB orb )
142    {
143        this.orb = orb ;
144        wrapper = IORSystemException.get( orb,
145            CORBALogDomains.OA_IOR ) ;
146    }
147
148    public IIOPProfileImpl( ORB orb, ObjectKeyTemplate oktemp, ObjectId oid,
149        IIOPProfileTemplate proftemp )
150    {
151        this( orb ) ;
152        this.oktemp = oktemp ;
153        this.oid = oid ;
154        this.proftemp = proftemp ;
155    }
156
157    public IIOPProfileImpl( InputStream is )
158    {
159        this( (ORB)(is.orb()) ) ;
160        init( is ) ;
161    }
162
163    public IIOPProfileImpl( ORB orb, org.omg.IOP.TaggedProfile profile)
164    {
165        this( orb ) ;
166
167        if (profile == null || profile.tag != TAG_INTERNET_IOP.value ||
168            profile.profile_data == null) {
169            throw wrapper.invalidTaggedProfile() ;
170        }
171
172        EncapsInputStream istr = EncapsInputStreamFactory.newEncapsInputStream((ORB)orb, profile.profile_data,
173                profile.profile_data.length);
174        istr.consumeEndian();
175        init( istr ) ;
176    }
177
178    private void init( InputStream istr )
179    {
180        // First, read all of the IIOP IOR data
181        GIOPVersion version = new GIOPVersion() ;
182        version.read( istr ) ;
183        IIOPAddress primary = new IIOPAddressImpl( istr ) ;
184        byte[] key = EncapsulationUtility.readOctets( istr ) ;
185
186        ObjectKey okey = orb.getObjectKeyFactory().create( key ) ;
187        oktemp = okey.getTemplate() ;
188        oid = okey.getId() ;
189
190        proftemp = IIOPFactories.makeIIOPProfileTemplate( orb,
191            version, primary ) ;
192
193        // Handle any tagged components (if applicable)
194        if (version.getMinor() > 0)
195            EncapsulationUtility.readIdentifiableSequence( proftemp,
196                orb.getTaggedComponentFactoryFinder(), istr ) ;
197
198        // If there is no codebase in this IOR and there IS a
199        // java.rmi.server.codebase property set, we need to
200        // update the IOR with the local codebase.  Note that
201        // there is only one instance of the local codebase, but it
202        // can be safely shared in multiple IORs since it is immutable.
203        if (uncachedGetCodeBase() == null) {
204            JavaCodebaseComponent jcc = LocalCodeBaseSingletonHolder.comp ;
205
206            if (jcc != null) {
207                if (version.getMinor() > 0)
208                    proftemp.add( jcc ) ;
209
210                codebase = jcc.getURLs() ;
211            }
212
213            // Whether codebase is null or not, we have it,
214            // and so getCodebase ned never call uncachedGetCodebase.
215            cachedCodebase = true;
216        }
217    }
218
219    public void writeContents(OutputStream os)
220    {
221        proftemp.write( oktemp, oid, os ) ;
222    }
223
224    public int getId()
225    {
226        return proftemp.getId() ;
227    }
228
229    public boolean isEquivalent( TaggedProfile prof )
230    {
231        if (!(prof instanceof IIOPProfile))
232            return false ;
233
234        IIOPProfile other = (IIOPProfile)prof ;
235
236        return oid.equals( other.getObjectId() ) &&
237               proftemp.isEquivalent( other.getTaggedProfileTemplate() ) &&
238               oktemp.equals( other.getObjectKeyTemplate() ) ;
239    }
240
241    public ObjectKey getObjectKey()
242    {
243        ObjectKey result = IORFactories.makeObjectKey( oktemp, oid ) ;
244        return result ;
245    }
246
247    public org.omg.IOP.TaggedProfile getIOPProfile()
248    {
249        EncapsOutputStream os =
250            sun.corba.OutputStreamFactory.newEncapsOutputStream(orb);
251        os.write_long( getId() ) ;
252        write( os ) ;
253        InputStream is = (InputStream)(os.create_input_stream()) ;
254        return org.omg.IOP.TaggedProfileHelper.read( is ) ;
255    }
256
257    private String uncachedGetCodeBase() {
258        Iterator iter = proftemp.iteratorById( TAG_JAVA_CODEBASE.value ) ;
259
260        if (iter.hasNext()) {
261            JavaCodebaseComponent jcbc = (JavaCodebaseComponent)(iter.next()) ;
262            return jcbc.getURLs() ;
263        }
264
265        return null ;
266    }
267
268    public synchronized String getCodebase() {
269        if (!cachedCodebase) {
270            cachedCodebase = true ;
271            codebase = uncachedGetCodeBase() ;
272        }
273
274        return codebase ;
275    }
276
277    /**
278     * @return the ORBVersion associated with the object key in the IOR.
279     */
280    public ORBVersion getORBVersion() {
281        return oktemp.getORBVersion();
282    }
283
284    public synchronized boolean isLocal()
285    {
286        if (!checkedIsLocal) {
287            checkedIsLocal = true ;
288            String host = proftemp.getPrimaryAddress().getHost() ;
289
290            cachedIsLocal = orb.isLocalHost(host) &&
291                orb.isLocalServerId(oktemp.getSubcontractId(),
292                                           oktemp.getServerId()) &&
293                orb.getLegacyServerSocketManager()
294                    .legacyIsLocalServerPort(
295                        proftemp.getPrimaryAddress().getPort());
296        }
297
298        return cachedIsLocal ;
299    }
300
301    /** Return the servant for this IOR, if it is local AND if the OA that
302     * implements this objref supports direct access to servants outside of an
303     * invocation.
304     * XXX revisit: do we want this at all?  If we do, it might move to the
305     * ObjectKeyTemplate instead.
306     */
307    public java.lang.Object getServant()
308    {
309        if (!isLocal())
310            return null ;
311
312        RequestDispatcherRegistry scr = orb.getRequestDispatcherRegistry() ;
313        ObjectAdapterFactory oaf = scr.getObjectAdapterFactory(
314            oktemp.getSubcontractId() ) ;
315
316        ObjectAdapterId oaid = oktemp.getObjectAdapterId() ;
317        ObjectAdapter oa = null ;
318
319        try {
320            oa = oaf.find( oaid ) ;
321        } catch (SystemException exc) {
322            // Could not find the OA, so just return null.
323            // This usually happens when POAs are being deleted,
324            // and the POA always return null for getLocalServant anyway.
325            wrapper.getLocalServantFailure( exc, oaid.toString() ) ;
326            return null ;
327        }
328
329        byte[] boid = oid.getId() ;
330        java.lang.Object servant = oa.getLocalServant( boid ) ;
331        return servant ;
332    }
333
334    /**
335     * Return GIOPVersion for this IOR.
336     * Requests created against this IOR will be of the
337     * return Version.
338     */
339    public synchronized GIOPVersion getGIOPVersion()
340    {
341        return proftemp.getGIOPVersion() ;
342    }
343
344    public void makeImmutable()
345    {
346        proftemp.makeImmutable() ;
347    }
348}
349