/*
 * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */
package com.sun.corba.se.impl.encoding;

import java.util.Hashtable;
import com.sun.org.omg.CORBA.ValueDefPackage.FullValueDescription;
import com.sun.org.omg.SendingContext.CodeBase;
import com.sun.org.omg.SendingContext.CodeBaseHelper;
import com.sun.org.omg.SendingContext._CodeBaseImplBase;
import com.sun.org.omg.SendingContext._CodeBaseStub;
import com.sun.corba.se.spi.transport.CorbaConnection;
import com.sun.corba.se.spi.ior.IOR;
import com.sun.corba.se.spi.orb.ORB;
Provides the reading side with a per connection cache of info obtained via calls to the remote CodeBase. Previously, most of this was in IIOPConnection. Features: Delays cache creation unless used Postpones remote calls until necessary Handles creating obj ref from IOR Maintains caches for the following maps: CodeBase IOR to obj ref (global) RepId to implementation URL(s) RepId to remote FVD RepId to superclass type list Needs cache management.
/** * Provides the reading side with a per connection cache of * info obtained via calls to the remote CodeBase. * * Previously, most of this was in IIOPConnection. * * Features: * Delays cache creation unless used * Postpones remote calls until necessary * Handles creating obj ref from IOR * Maintains caches for the following maps: * CodeBase IOR to obj ref (global) * RepId to implementation URL(s) * RepId to remote FVD * RepId to superclass type list * * Needs cache management. */
public class CachedCodeBase extends _CodeBaseImplBase { private Hashtable implementations, fvds, bases; private volatile CodeBase delegate; private CorbaConnection conn; private static Object iorMapLock = new Object(); private static Hashtable<IOR,CodeBase> iorMap = new Hashtable<>(); public static synchronized void cleanCache( ORB orb ) { synchronized (iorMapLock) { for (IOR ior : iorMap.keySet()) { if (ior.getORB() == orb) { iorMap.remove(ior); } } } } public CachedCodeBase(CorbaConnection connection) { conn = connection; } public com.sun.org.omg.CORBA.Repository get_ir () { return null; } public synchronized String implementation (String repId) { String urlResult = null; if (implementations == null) implementations = new Hashtable(); else urlResult = (String)implementations.get(repId); if (urlResult == null && connectedCodeBase()) { urlResult = delegate.implementation(repId); if (urlResult != null) implementations.put(repId, urlResult); } return urlResult; } public synchronized String[] implementations (String[] repIds) { String[] urlResults = new String[repIds.length]; for (int i = 0; i < urlResults.length; i++) urlResults[i] = implementation(repIds[i]); return urlResults; } public synchronized FullValueDescription meta (String repId) { FullValueDescription result = null; if (fvds == null) fvds = new Hashtable(); else result = (FullValueDescription)fvds.get(repId); if (result == null && connectedCodeBase()) { result = delegate.meta(repId); if (result != null) fvds.put(repId, result); } return result; } public synchronized FullValueDescription[] metas (String[] repIds) { FullValueDescription[] results = new FullValueDescription[repIds.length]; for (int i = 0; i < results.length; i++) results[i] = meta(repIds[i]); return results; } public synchronized String[] bases (String repId) { String[] results = null; if (bases == null) bases = new Hashtable(); else results = (String[])bases.get(repId); if (results == null && connectedCodeBase()) { results = delegate.bases(repId); if (results != null) bases.put(repId, results); } return results; } // Ensures that we've used the connection's IOR to create // a valid CodeBase delegate. If this returns false, then // it is not valid to access the delegate. private synchronized boolean connectedCodeBase() { if (delegate != null) return true; // The delegate was null, so see if the connection's // IOR was set. If so, then we just need to connect // it. Otherwise, there is no hope of checking the // remote code base. That could be bug if the // service context processing didn't occur, or it // could be that we're talking to a foreign ORB which // doesn't include this optional service context. if (conn.getCodeBaseIOR() == null) { // REVISIT. Use Merlin logging service to report that // codebase functionality was requested but unavailable. if (conn.getBroker().transportDebugFlag) conn.dprint("CodeBase unavailable on connection: " + conn); return false; } synchronized(iorMapLock) { // Recheck the condition to make sure another // thread didn't already do this while we waited if (delegate != null) return true; // Do we have a reference initialized by another connection? delegate = CachedCodeBase.iorMap.get(conn.getCodeBaseIOR()); if (delegate != null) return true; // Connect the delegate and update the cache delegate = CodeBaseHelper.narrow(getObjectFromIOR()); // Save it for the benefit of other connections CachedCodeBase.iorMap.put(conn.getCodeBaseIOR(), delegate); } // It's now safe to use the delegate return true; } private final org.omg.CORBA.Object getObjectFromIOR() { return CDRInputStream_1_0.internalIORToObject( conn.getCodeBaseIOR(), null /*stubFactory*/, conn.getBroker()); } } // End of file.