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