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