1. /*
  2. * @(#)ActiveObjectMap.java 1.18 03/12/19
  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.oa.poa;
  8. import java.util.Set ;
  9. import java.util.HashSet ;
  10. import java.util.Map ;
  11. import java.util.HashMap ;
  12. import java.util.Iterator ;
  13. import java.util.Vector ;
  14. import org.omg.PortableServer.Servant ;
  15. import org.omg.PortableServer.POAPackage.WrongPolicy ;
  16. import org.omg.CORBA.INTERNAL ;
  17. /** The ActiveObjectMap maintains associations between servants and
  18. * their keys. There are two variants, to support whether or not
  19. * multiple IDs per servant are allowed. This class suppots bidirectional
  20. * traversal of the key-servant association. Access to an instance of this
  21. * class is serialized by the POA mutex.
  22. */
  23. public abstract class ActiveObjectMap
  24. {
  25. public static class Key {
  26. public byte[] id;
  27. Key(byte[] id) {
  28. this.id = id;
  29. }
  30. public String toString() {
  31. StringBuffer buffer = new StringBuffer();
  32. for(int i = 0; i < id.length; i++) {
  33. buffer.append(Integer.toString((int) id[i], 16));
  34. if (i != id.length-1)
  35. buffer.append(":");
  36. }
  37. return buffer.toString();
  38. }
  39. public boolean equals(java.lang.Object key) {
  40. if (!(key instanceof Key))
  41. return false;
  42. Key k = (Key) key;
  43. if (k.id.length != this.id.length)
  44. return false;
  45. for(int i = 0; i < this.id.length; i++)
  46. if (this.id[i] != k.id[i])
  47. return false;
  48. return true;
  49. }
  50. // Use the same hash function as for String
  51. public int hashCode() {
  52. int h = 0;
  53. for (int i = 0; i < id.length; i++)
  54. h = 31*h + id[i];
  55. return h;
  56. }
  57. }
  58. protected POAImpl poa ;
  59. protected ActiveObjectMap( POAImpl poa )
  60. {
  61. this.poa = poa ;
  62. }
  63. public static ActiveObjectMap create( POAImpl poa, boolean multipleIDsAllowed )
  64. {
  65. if (multipleIDsAllowed)
  66. return new MultipleObjectMap( poa ) ;
  67. else
  68. return new SingleObjectMap(poa ) ;
  69. }
  70. private Map keyToEntry = new HashMap() ; // Map< Key, AOMEntry >
  71. private Map entryToServant = new HashMap() ; // Map< AOMEntry, Servant >
  72. private Map servantToEntry = new HashMap() ; // Map< Servant, AOMEntry >
  73. public final boolean contains(Servant value)
  74. {
  75. return servantToEntry.containsKey( value ) ;
  76. }
  77. public final boolean containsKey(Key key)
  78. {
  79. return keyToEntry.containsKey(key);
  80. }
  81. /** get Returbs the entry assigned to the key, or creates a new
  82. * entry in state INVALID if none is present.
  83. */
  84. public final AOMEntry get(Key key)
  85. {
  86. AOMEntry result = (AOMEntry)keyToEntry.get(key);
  87. if (result == null) {
  88. result = new AOMEntry( poa ) ;
  89. putEntry( key, result ) ;
  90. }
  91. return result ;
  92. }
  93. public final Servant getServant( AOMEntry entry )
  94. {
  95. return (Servant)entryToServant.get( entry ) ;
  96. }
  97. public abstract Key getKey(AOMEntry value) throws WrongPolicy ;
  98. public Key getKey(Servant value) throws WrongPolicy
  99. {
  100. AOMEntry entry = (AOMEntry)servantToEntry.get( value ) ;
  101. return getKey( entry ) ;
  102. }
  103. protected void putEntry( Key key, AOMEntry value )
  104. {
  105. keyToEntry.put( key, value ) ;
  106. }
  107. public final void putServant( Servant servant, AOMEntry value )
  108. {
  109. entryToServant.put( value, servant ) ;
  110. servantToEntry.put( servant, value ) ;
  111. }
  112. protected abstract void removeEntry( AOMEntry entry, Key key ) ;
  113. public final void remove( Key key )
  114. {
  115. AOMEntry entry = (AOMEntry)keyToEntry.remove( key ) ;
  116. Servant servant = (Servant)entryToServant.remove( entry ) ;
  117. if (servant != null)
  118. servantToEntry.remove( servant ) ;
  119. removeEntry( entry, key ) ;
  120. }
  121. public abstract boolean hasMultipleIDs(AOMEntry value) ;
  122. protected void clear()
  123. {
  124. keyToEntry.clear();
  125. }
  126. public final Set keySet()
  127. {
  128. return keyToEntry.keySet() ;
  129. }
  130. }
  131. class SingleObjectMap extends ActiveObjectMap
  132. {
  133. private Map entryToKey = new HashMap() ; // Map< AOMEntry, Key >
  134. public SingleObjectMap( POAImpl poa )
  135. {
  136. super( poa ) ;
  137. }
  138. public Key getKey(AOMEntry value) throws WrongPolicy
  139. {
  140. return (Key)entryToKey.get( value ) ;
  141. }
  142. protected void putEntry(Key key, AOMEntry value)
  143. {
  144. super.putEntry( key, value);
  145. entryToKey.put( value, key ) ;
  146. }
  147. public boolean hasMultipleIDs(AOMEntry value)
  148. {
  149. return false;
  150. }
  151. // This case does not need the key.
  152. protected void removeEntry(AOMEntry entry, Key key)
  153. {
  154. entryToKey.remove( entry ) ;
  155. }
  156. public void clear()
  157. {
  158. super.clear() ;
  159. entryToKey.clear() ;
  160. }
  161. }
  162. class MultipleObjectMap extends ActiveObjectMap
  163. {
  164. private Map entryToKeys = new HashMap() ; // Map< AOMEntry, Set< Key > >
  165. public MultipleObjectMap( POAImpl poa )
  166. {
  167. super( poa ) ;
  168. }
  169. public Key getKey(AOMEntry value) throws WrongPolicy
  170. {
  171. throw new WrongPolicy() ;
  172. }
  173. protected void putEntry(Key key, AOMEntry value)
  174. {
  175. super.putEntry( key, value);
  176. Set set = (Set)entryToKeys.get( value ) ;
  177. if (set == null) {
  178. set = new HashSet() ;
  179. entryToKeys.put( value, set ) ;
  180. }
  181. set.add( key ) ;
  182. }
  183. public boolean hasMultipleIDs(AOMEntry value)
  184. {
  185. Set set = (Set)entryToKeys.get( value ) ;
  186. if (set == null)
  187. return false ;
  188. return set.size() > 1 ;
  189. }
  190. protected void removeEntry(AOMEntry entry, Key key)
  191. {
  192. Set keys = (Set)entryToKeys.get( entry ) ;
  193. if (keys != null) {
  194. keys.remove( key ) ;
  195. if (keys.isEmpty())
  196. entryToKeys.remove( entry ) ;
  197. }
  198. }
  199. public void clear()
  200. {
  201. super.clear() ;
  202. entryToKeys.clear() ;
  203. }
  204. }