1. /*
  2. * @(#)CachedCodeBase.java 1.6 04/06/21
  3. *
  4. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package com.sun.corba.se.impl.encoding;
  8. import java.util.Hashtable;
  9. import com.sun.org.omg.CORBA.ValueDefPackage.FullValueDescription;
  10. import com.sun.org.omg.SendingContext.CodeBase;
  11. import com.sun.org.omg.SendingContext.CodeBaseHelper;
  12. import com.sun.org.omg.SendingContext._CodeBaseImplBase;
  13. import com.sun.org.omg.SendingContext._CodeBaseStub;
  14. import com.sun.corba.se.spi.transport.CorbaConnection;
  15. /**
  16. * Provides the reading side with a per connection cache of
  17. * info obtained via calls to the remote CodeBase.
  18. *
  19. * Previously, most of this was in IIOPConnection.
  20. *
  21. * Features:
  22. * Delays cache creation unless used
  23. * Postpones remote calls until necessary
  24. * Handles creating obj ref from IOR
  25. * Maintains caches for the following maps:
  26. * CodeBase IOR to obj ref (global)
  27. * RepId to implementation URL(s)
  28. * RepId to remote FVD
  29. * RepId to superclass type list
  30. *
  31. * Needs cache management.
  32. */
  33. // REVISIT: revert to package protected after framework merge.
  34. public class CachedCodeBase extends _CodeBaseImplBase
  35. {
  36. private Hashtable implementations, fvds, bases;
  37. private CodeBase delegate;
  38. private CorbaConnection conn;
  39. private static Hashtable iorToCodeBaseObjMap = new Hashtable();
  40. public CachedCodeBase(CorbaConnection connection) {
  41. conn = connection;
  42. }
  43. public com.sun.org.omg.CORBA.Repository get_ir () {
  44. return null;
  45. }
  46. public String implementation (String repId) {
  47. String urlResult = null;
  48. if (implementations == null)
  49. implementations = new Hashtable();
  50. else
  51. urlResult = (String)implementations.get(repId);
  52. if (urlResult == null && connectedCodeBase()) {
  53. urlResult = delegate.implementation(repId);
  54. if (urlResult != null)
  55. implementations.put(repId, urlResult);
  56. }
  57. return urlResult;
  58. }
  59. public String[] implementations (String[] repIds) {
  60. String[] urlResults = new String[repIds.length];
  61. for (int i = 0; i < urlResults.length; i++)
  62. urlResults[i] = implementation(repIds[i]);
  63. return urlResults;
  64. }
  65. public FullValueDescription meta (String repId) {
  66. FullValueDescription result = null;
  67. if (fvds == null)
  68. fvds = new Hashtable();
  69. else
  70. result = (FullValueDescription)fvds.get(repId);
  71. if (result == null && connectedCodeBase()) {
  72. result = delegate.meta(repId);
  73. if (result != null)
  74. fvds.put(repId, result);
  75. }
  76. return result;
  77. }
  78. public FullValueDescription[] metas (String[] repIds) {
  79. FullValueDescription[] results
  80. = new FullValueDescription[repIds.length];
  81. for (int i = 0; i < results.length; i++)
  82. results[i] = meta(repIds[i]);
  83. return results;
  84. }
  85. public String[] bases (String repId) {
  86. String[] results = null;
  87. if (bases == null)
  88. bases = new Hashtable();
  89. else
  90. results = (String[])bases.get(repId);
  91. if (results == null && connectedCodeBase()) {
  92. results = delegate.bases(repId);
  93. if (results != null)
  94. bases.put(repId, results);
  95. }
  96. return results;
  97. }
  98. // Ensures that we've used the connection's IOR to create
  99. // a valid CodeBase delegate. If this returns false, then
  100. // it is not valid to access the delegate.
  101. private boolean connectedCodeBase() {
  102. if (delegate != null)
  103. return true;
  104. // The delegate was null, so see if the connection's
  105. // IOR was set. If so, then we just need to connect
  106. // it. Otherwise, there is no hope of checking the
  107. // remote code base. That could be bug if the
  108. // service context processing didn't occur, or it
  109. // could be that we're talking to a foreign ORB which
  110. // doesn't include this optional service context.
  111. if (conn.getCodeBaseIOR() == null) {
  112. // REVISIT. Use Merlin logging service to report that
  113. // codebase functionality was requested but unavailable.
  114. if (conn.getBroker().transportDebugFlag)
  115. conn.dprint("CodeBase unavailable on connection: " + conn);
  116. return false;
  117. }
  118. synchronized(this) {
  119. // Recheck the condition to make sure another
  120. // thread didn't already do this while we waited
  121. if (delegate != null)
  122. return true;
  123. // Do we have a reference initialized by another connection?
  124. delegate = (CodeBase)CachedCodeBase.iorToCodeBaseObjMap.get(conn.getCodeBaseIOR());
  125. if (delegate != null)
  126. return true;
  127. // Connect the delegate and update the cache
  128. delegate = CodeBaseHelper.narrow(getObjectFromIOR());
  129. // Save it for the benefit of other connections
  130. CachedCodeBase.iorToCodeBaseObjMap.put(conn.getCodeBaseIOR(),
  131. delegate);
  132. }
  133. // It's now safe to use the delegate
  134. return true;
  135. }
  136. private final org.omg.CORBA.Object getObjectFromIOR() {
  137. return CDRInputStream_1_0.internalIORToObject(
  138. conn.getCodeBaseIOR(), null /*stubFactory*/, conn.getBroker());
  139. }
  140. }
  141. // End of file.