1 /* 2 * Copyright (c) 2001, 2012, 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 package com.sun.corba.se.impl.encoding; 26 27 import java.util.Hashtable; 28 import com.sun.org.omg.CORBA.ValueDefPackage.FullValueDescription; 29 import com.sun.org.omg.SendingContext.CodeBase; 30 import com.sun.org.omg.SendingContext.CodeBaseHelper; 31 import com.sun.org.omg.SendingContext._CodeBaseImplBase; 32 import com.sun.org.omg.SendingContext._CodeBaseStub; 33 import com.sun.corba.se.spi.transport.CorbaConnection; 34 import com.sun.corba.se.spi.ior.IOR; 35 import com.sun.corba.se.spi.orb.ORB; 36 /** 37 * Provides the reading side with a per connection cache of 38 * info obtained via calls to the remote CodeBase. 39 * 40 * Previously, most of this was in IIOPConnection. 41 * 42 * Features: 43 * Delays cache creation unless used 44 * Postpones remote calls until necessary 45 * Handles creating obj ref from IOR 46 * Maintains caches for the following maps: 47 * CodeBase IOR to obj ref (global) 48 * RepId to implementation URL(s) 49 * RepId to remote FVD 50 * RepId to superclass type list 51 * 52 * Needs cache management. 53 */ 54 public class CachedCodeBase extends _CodeBaseImplBase 55 { 56 private Hashtable implementations, fvds, bases; 57 private volatile CodeBase delegate; 58 private CorbaConnection conn; 59 60 private static Object iorMapLock = new Object(); 61 private static Hashtable<IOR,CodeBase> iorMap = new Hashtable<>(); 62 63 public static synchronized void cleanCache( ORB orb ) { 64 synchronized (iorMapLock) { 65 for (IOR ior : iorMap.keySet()) { 66 if (ior.getORB() == orb) { 67 iorMap.remove(ior); 68 } 69 } 70 } 71 } 72 73 public CachedCodeBase(CorbaConnection connection) { 74 conn = connection; 75 } 76 77 public com.sun.org.omg.CORBA.Repository get_ir () { 78 return null; 79 } 80 81 public synchronized String implementation (String repId) { 82 String urlResult = null; 83 84 if (implementations == null) 85 implementations = new Hashtable(); 86 else 87 urlResult = (String)implementations.get(repId); 88 89 if (urlResult == null && connectedCodeBase()) { 90 urlResult = delegate.implementation(repId); 91 92 if (urlResult != null) 93 implementations.put(repId, urlResult); 94 } 95 96 return urlResult; 97 } 98 99 public synchronized String[] implementations (String[] repIds) { 100 String[] urlResults = new String[repIds.length]; 101 102 for (int i = 0; i < urlResults.length; i++) 103 urlResults[i] = implementation(repIds[i]); 104 105 return urlResults; 106 } 107 108 public synchronized FullValueDescription meta (String repId) { 109 FullValueDescription result = null; 110 111 if (fvds == null) 112 fvds = new Hashtable(); 113 else 114 result = (FullValueDescription)fvds.get(repId); 115 116 if (result == null && connectedCodeBase()) { 117 result = delegate.meta(repId); 118 119 if (result != null) 120 fvds.put(repId, result); 121 } 122 123 return result; 124 } 125 126 public synchronized FullValueDescription[] metas (String[] repIds) { 127 FullValueDescription[] results 128 = new FullValueDescription[repIds.length]; 129 130 for (int i = 0; i < results.length; i++) 131 results[i] = meta(repIds[i]); 132 133 return results; 134 } 135 136 public synchronized String[] bases (String repId) { 137 138 String[] results = null; 139 140 if (bases == null) 141 bases = new Hashtable(); 142 else 143 results = (String[])bases.get(repId); 144 145 if (results == null && connectedCodeBase()) { 146 results = delegate.bases(repId); 147 148 if (results != null) 149 bases.put(repId, results); 150 } 151 152 return results; 153 } 154 155 // Ensures that we've used the connection's IOR to create 156 // a valid CodeBase delegate. If this returns false, then 157 // it is not valid to access the delegate. 158 private synchronized boolean connectedCodeBase() { 159 if (delegate != null) 160 return true; 161 162 // The delegate was null, so see if the connection's 163 // IOR was set. If so, then we just need to connect 164 // it. Otherwise, there is no hope of checking the 165 // remote code base. That could be bug if the 166 // service context processing didn't occur, or it 167 // could be that we're talking to a foreign ORB which 168 // doesn't include this optional service context. 169 if (conn.getCodeBaseIOR() == null) { 170 // REVISIT. Use Merlin logging service to report that 171 // codebase functionality was requested but unavailable. 172 if (conn.getBroker().transportDebugFlag) 173 conn.dprint("CodeBase unavailable on connection: " + conn); 174 175 return false; 176 } 177 178 synchronized(iorMapLock) { 179 180 // Recheck the condition to make sure another 181 // thread didn't already do this while we waited 182 if (delegate != null) 183 return true; 184 185 // Do we have a reference initialized by another connection? 186 delegate = CachedCodeBase.iorMap.get(conn.getCodeBaseIOR()); 187 188 if (delegate != null) 189 return true; 190 191 // Connect the delegate and update the cache 192 delegate = CodeBaseHelper.narrow(getObjectFromIOR()); 193 194 // Save it for the benefit of other connections 195 CachedCodeBase.iorMap.put(conn.getCodeBaseIOR(), delegate); 196 } 197 198 // It's now safe to use the delegate 199 return true; 200 } 201 202 private final org.omg.CORBA.Object getObjectFromIOR() { 203 return CDRInputStream_1_0.internalIORToObject( 204 conn.getCodeBaseIOR(), null /*stubFactory*/, conn.getBroker()); 205 } 206 } 207 208 // End of file.