1 /*
   2  * Copyright (c) 2002, 2006, 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.transport;
  27 
  28 import java.util.ArrayList;
  29 import java.util.Iterator;
  30 import java.util.List;
  31 
  32 import com.sun.corba.se.pept.transport.ContactInfo;
  33 
  34 import com.sun.corba.se.spi.ior.IOR ;
  35 import com.sun.corba.se.spi.ior.iiop.IIOPProfile ;
  36 import com.sun.corba.se.spi.ior.iiop.IIOPProfileTemplate ;
  37 import com.sun.corba.se.spi.oa.ObjectAdapterFactory;
  38 import com.sun.corba.se.spi.orb.ORB;
  39 import com.sun.corba.se.spi.protocol.LocalClientRequestDispatcher;
  40 import com.sun.corba.se.spi.protocol.LocalClientRequestDispatcherFactory;
  41 import com.sun.corba.se.spi.transport.CorbaContactInfoList ;
  42 import com.sun.corba.se.spi.transport.SocketInfo;
  43 
  44 import com.sun.corba.se.impl.orbutil.ORBConstants;
  45 import com.sun.corba.se.impl.protocol.NotLocalLocalCRDImpl;
  46 
  47 /**
  48  * @author Harold Carr
  49  */
  50 public class CorbaContactInfoListImpl
  51     implements
  52         CorbaContactInfoList
  53 {
  54     protected ORB orb;
  55     protected LocalClientRequestDispatcher LocalClientRequestDispatcher;
  56     protected IOR targetIOR;
  57     protected IOR effectiveTargetIOR;
  58     protected List effectiveTargetIORContactInfoList;
  59     protected ContactInfo primaryContactInfo;
  60 
  61     // XREVISIT - is this used?
  62     public CorbaContactInfoListImpl(ORB orb)
  63     {
  64         this.orb = orb;
  65     }
  66 
  67     public CorbaContactInfoListImpl(ORB orb, IOR targetIOR)
  68     {
  69         this(orb);
  70         setTargetIOR(targetIOR);
  71     }
  72 
  73     ////////////////////////////////////////////////////
  74     //
  75     // pept.transport.ContactInfoList
  76     //
  77 
  78     public synchronized Iterator iterator()
  79     {
  80         createContactInfoList();
  81         return new CorbaContactInfoListIteratorImpl(
  82             orb, this, primaryContactInfo,
  83             effectiveTargetIORContactInfoList);
  84     }
  85 
  86     ////////////////////////////////////////////////////
  87     //
  88     // spi.transport.CorbaContactInfoList
  89     //
  90 
  91     public synchronized void setTargetIOR(IOR targetIOR)
  92     {
  93         this.targetIOR = targetIOR;
  94         setEffectiveTargetIOR(targetIOR);
  95     }
  96 
  97     public synchronized IOR getTargetIOR()
  98     {
  99         return targetIOR;
 100     }
 101 
 102     public synchronized void setEffectiveTargetIOR(IOR effectiveTargetIOR)
 103     {
 104         this.effectiveTargetIOR = effectiveTargetIOR;
 105         effectiveTargetIORContactInfoList = null;
 106         if (primaryContactInfo != null &&
 107             orb.getORBData().getIIOPPrimaryToContactInfo() != null)
 108         {
 109             orb.getORBData().getIIOPPrimaryToContactInfo()
 110                 .reset(primaryContactInfo);
 111         }
 112         primaryContactInfo = null;
 113         setLocalSubcontract();
 114     }
 115 
 116     public synchronized IOR getEffectiveTargetIOR()
 117     {
 118         return effectiveTargetIOR;
 119     }
 120 
 121     public synchronized LocalClientRequestDispatcher getLocalClientRequestDispatcher()
 122     {
 123         return LocalClientRequestDispatcher;
 124     }
 125 
 126     ////////////////////////////////////////////////////
 127     //
 128     // org.omg.CORBA.portable.Delegate
 129     //
 130 
 131     // REVISIT - hashCode(org.omg.CORBA.Object self)
 132 
 133     ////////////////////////////////////////////////////
 134     //
 135     // java.lang.Object
 136     //
 137 
 138     public synchronized int hashCode()
 139     {
 140         return targetIOR.hashCode();
 141     }
 142 
 143     ////////////////////////////////////////////////////
 144     //
 145     // Implementation
 146     //
 147 
 148     protected void createContactInfoList()
 149     {
 150         if (effectiveTargetIORContactInfoList != null) {
 151             return;
 152         }
 153 
 154         effectiveTargetIORContactInfoList = new ArrayList();
 155 
 156         IIOPProfile iiopProfile = effectiveTargetIOR.getProfile();
 157         String hostname =
 158             ((IIOPProfileTemplate)iiopProfile.getTaggedProfileTemplate())
 159                 .getPrimaryAddress().getHost().toLowerCase();
 160         int    port     =
 161             ((IIOPProfileTemplate)iiopProfile.getTaggedProfileTemplate())
 162                 .getPrimaryAddress().getPort();
 163         // For use by "sticky manager" if one is registered.
 164         primaryContactInfo =
 165             createContactInfo(SocketInfo.IIOP_CLEAR_TEXT, hostname, port);
 166 
 167         if (iiopProfile.isLocal()) {
 168             // NOTE: IMPORTANT:
 169             // Only do local.  The APP Server interceptors check
 170             // effectiveTarget.isLocal - which is determined via
 171             // the IOR - so if we added other addresses then
 172             // transactions and interceptors would not execute.
 173             ContactInfo contactInfo = new SharedCDRContactInfoImpl(
 174                 orb, this, effectiveTargetIOR,
 175                 orb.getORBData().getGIOPAddressDisposition());
 176             effectiveTargetIORContactInfoList.add(contactInfo);
 177         } else {
 178             addRemoteContactInfos(effectiveTargetIOR,
 179                                   effectiveTargetIORContactInfoList);
 180         }
 181     }
 182 
 183     protected void addRemoteContactInfos(
 184         IOR  effectiveTargetIOR,
 185         List effectiveTargetIORContactInfoList)
 186     {
 187         ContactInfo contactInfo;
 188         List socketInfos = orb.getORBData()
 189             .getIORToSocketInfo().getSocketInfo(effectiveTargetIOR);
 190         Iterator iterator = socketInfos.iterator();
 191         while (iterator.hasNext()) {
 192             SocketInfo socketInfo = (SocketInfo) iterator.next();
 193             String type = socketInfo.getType();
 194             String host = socketInfo.getHost().toLowerCase();
 195             int    port = socketInfo.getPort();
 196             contactInfo = createContactInfo(type, host, port);
 197             effectiveTargetIORContactInfoList.add(contactInfo);
 198         }
 199     }
 200 
 201     protected ContactInfo createContactInfo(String type,
 202                                             String hostname, int port)
 203     {
 204         return new SocketOrChannelContactInfoImpl(
 205             orb, this,
 206             // XREVISIT - See Base Line 62
 207             effectiveTargetIOR,
 208             orb.getORBData().getGIOPAddressDisposition(),
 209             type, hostname, port);
 210     }
 211 
 212     /**
 213      * setLocalSubcontract sets cached information that is set whenever
 214      * the effectiveTargetIOR changes.
 215      *
 216      * Note: this must be maintained accurately whether or not the ORB
 217      * allows local optimization, because ServantManagers in the POA
 218      * ALWAYS use local optimization ONLY (they do not have a remote case).
 219      */
 220     protected void setLocalSubcontract()
 221     {
 222         if (!effectiveTargetIOR.getProfile().isLocal()) {
 223             LocalClientRequestDispatcher = new NotLocalLocalCRDImpl();
 224             return;
 225         }
 226 
 227         // XXX Note that this always uses the first IIOP profile to get the
 228         // scid.  What about multi-profile IORs?  This should perhaps be
 229         // tied to the current ContactInfo in some way, together with an
 230         // implementation of ClientDelegate that generally prefers co-located
 231         // ContactInfo.  This may in fact mean that we should do this at
 232         // the ContactInfo level, rather than the IOR/profile level.
 233         int scid = effectiveTargetIOR.getProfile().getObjectKeyTemplate().
 234             getSubcontractId() ;
 235         LocalClientRequestDispatcherFactory lcsf = orb.getRequestDispatcherRegistry().getLocalClientRequestDispatcherFactory( scid ) ;
 236         LocalClientRequestDispatcher = lcsf.create( scid, effectiveTargetIOR ) ;
 237     }
 238 }
 239 
 240 // End of file.