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.iiop;
  27 
  28 import java.util.List ;
  29 import java.util.Iterator ;
  30 
  31 import org.omg.CORBA.SystemException ;
  32 
  33 import org.omg.CORBA_2_3.portable.OutputStream ;
  34 import org.omg.CORBA_2_3.portable.InputStream ;
  35 
  36 import org.omg.IOP.TAG_ALTERNATE_IIOP_ADDRESS ;
  37 import org.omg.IOP.TAG_INTERNET_IOP;
  38 import org.omg.IOP.TAG_JAVA_CODEBASE;
  39 
  40 import com.sun.corba.se.spi.protocol.RequestDispatcherRegistry ;
  41 
  42 import com.sun.corba.se.spi.oa.ObjectAdapter ;
  43 import com.sun.corba.se.spi.oa.ObjectAdapterFactory ;
  44 
  45 import com.sun.corba.se.spi.ior.ObjectId ;
  46 import com.sun.corba.se.spi.ior.ObjectAdapterId ;
  47 import com.sun.corba.se.spi.ior.TaggedProfile ;
  48 import com.sun.corba.se.spi.ior.TaggedProfileTemplate ;
  49 import com.sun.corba.se.spi.ior.ObjectKey ;
  50 import com.sun.corba.se.spi.ior.ObjectKeyTemplate ;
  51 import com.sun.corba.se.spi.ior.TaggedComponent ;
  52 import com.sun.corba.se.spi.ior.IdentifiableBase ;
  53 import com.sun.corba.se.spi.ior.IORFactories ;
  54 import com.sun.corba.se.spi.ior.ObjectKeyFactory ;
  55 
  56 import com.sun.corba.se.spi.ior.iiop.IIOPAddress ;
  57 import com.sun.corba.se.spi.ior.iiop.IIOPProfile ;
  58 import com.sun.corba.se.spi.ior.iiop.IIOPProfileTemplate ;
  59 import com.sun.corba.se.spi.ior.iiop.IIOPFactories ;
  60 import com.sun.corba.se.spi.ior.iiop.GIOPVersion ;
  61 import com.sun.corba.se.spi.ior.iiop.JavaCodebaseComponent ;
  62 
  63 import com.sun.corba.se.spi.orb.ORB ;
  64 import com.sun.corba.se.spi.orb.ORBVersion ;
  65 
  66 import com.sun.corba.se.spi.logging.CORBALogDomains ;
  67 
  68 import com.sun.corba.se.impl.ior.EncapsulationUtility ;
  69 
  70 import com.sun.corba.se.impl.encoding.EncapsInputStream ;
  71 import com.sun.corba.se.impl.encoding.EncapsOutputStream ;
  72 
  73 import sun.corba.EncapsInputStreamFactory;
  74 
  75 import com.sun.corba.se.impl.util.JDKBridge;
  76 
  77 import com.sun.corba.se.impl.logging.IORSystemException;
  78 
  79 /**
  80  * @author
  81  */
  82 public 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 }