ActiveObjectMap.java revision 608:7e06bf1dcb09
1/* 2 * Copyright (c) 1997, 2003, 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 26package com.sun.corba.se.impl.oa.poa; 27 28import java.util.Set ; 29import java.util.HashSet ; 30import java.util.Map ; 31import java.util.HashMap ; 32import java.util.Iterator ; 33import java.util.Vector ; 34 35import org.omg.PortableServer.Servant ; 36import org.omg.PortableServer.POAPackage.WrongPolicy ; 37import org.omg.CORBA.INTERNAL ; 38 39/** The ActiveObjectMap maintains associations between servants and 40 * their keys. There are two variants, to support whether or not 41 * multiple IDs per servant are allowed. This class suppots bidirectional 42 * traversal of the key-servant association. Access to an instance of this 43 * class is serialized by the POA mutex. 44 */ 45public abstract class ActiveObjectMap 46{ 47 public static class Key { 48 public byte[] id; 49 50 Key(byte[] id) { 51 this.id = id; 52 } 53 54 public String toString() { 55 StringBuffer buffer = new StringBuffer(); 56 for(int i = 0; i < id.length; i++) { 57 buffer.append(Integer.toString((int) id[i], 16)); 58 if (i != id.length-1) 59 buffer.append(":"); 60 } 61 return buffer.toString(); 62 } 63 64 public boolean equals(java.lang.Object key) { 65 if (!(key instanceof Key)) 66 return false; 67 Key k = (Key) key; 68 if (k.id.length != this.id.length) 69 return false; 70 for(int i = 0; i < this.id.length; i++) 71 if (this.id[i] != k.id[i]) 72 return false; 73 return true; 74 } 75 76 // Use the same hash function as for String 77 public int hashCode() { 78 int h = 0; 79 for (int i = 0; i < id.length; i++) 80 h = 31*h + id[i]; 81 return h; 82 } 83 } 84 85 protected POAImpl poa ; 86 87 protected ActiveObjectMap( POAImpl poa ) 88 { 89 this.poa = poa ; 90 } 91 92 public static ActiveObjectMap create( POAImpl poa, boolean multipleIDsAllowed ) 93 { 94 if (multipleIDsAllowed) 95 return new MultipleObjectMap( poa ) ; 96 else 97 return new SingleObjectMap(poa ) ; 98 } 99 100 private Map keyToEntry = new HashMap() ; // Map< Key, AOMEntry > 101 private Map entryToServant = new HashMap() ; // Map< AOMEntry, Servant > 102 private Map servantToEntry = new HashMap() ; // Map< Servant, AOMEntry > 103 104 public final boolean contains(Servant value) 105 { 106 return servantToEntry.containsKey( value ) ; 107 } 108 109 public final boolean containsKey(Key key) 110 { 111 return keyToEntry.containsKey(key); 112 } 113 114 /** get Returbs the entry assigned to the key, or creates a new 115 * entry in state INVALID if none is present. 116 */ 117 public final AOMEntry get(Key key) 118 { 119 AOMEntry result = (AOMEntry)keyToEntry.get(key); 120 if (result == null) { 121 result = new AOMEntry( poa ) ; 122 putEntry( key, result ) ; 123 } 124 125 return result ; 126 } 127 128 public final Servant getServant( AOMEntry entry ) 129 { 130 return (Servant)entryToServant.get( entry ) ; 131 } 132 133 public abstract Key getKey(AOMEntry value) throws WrongPolicy ; 134 135 public Key getKey(Servant value) throws WrongPolicy 136 { 137 AOMEntry entry = (AOMEntry)servantToEntry.get( value ) ; 138 return getKey( entry ) ; 139 } 140 141 protected void putEntry( Key key, AOMEntry value ) 142 { 143 keyToEntry.put( key, value ) ; 144 } 145 146 public final void putServant( Servant servant, AOMEntry value ) 147 { 148 entryToServant.put( value, servant ) ; 149 servantToEntry.put( servant, value ) ; 150 } 151 152 protected abstract void removeEntry( AOMEntry entry, Key key ) ; 153 154 public final void remove( Key key ) 155 { 156 AOMEntry entry = (AOMEntry)keyToEntry.remove( key ) ; 157 Servant servant = (Servant)entryToServant.remove( entry ) ; 158 if (servant != null) 159 servantToEntry.remove( servant ) ; 160 161 removeEntry( entry, key ) ; 162 } 163 164 public abstract boolean hasMultipleIDs(AOMEntry value) ; 165 166 protected void clear() 167 { 168 keyToEntry.clear(); 169 } 170 171 public final Set keySet() 172 { 173 return keyToEntry.keySet() ; 174 } 175} 176 177class SingleObjectMap extends ActiveObjectMap 178{ 179 private Map entryToKey = new HashMap() ; // Map< AOMEntry, Key > 180 181 public SingleObjectMap( POAImpl poa ) 182 { 183 super( poa ) ; 184 } 185 186 public Key getKey(AOMEntry value) throws WrongPolicy 187 { 188 return (Key)entryToKey.get( value ) ; 189 } 190 191 protected void putEntry(Key key, AOMEntry value) 192 { 193 super.putEntry( key, value); 194 195 entryToKey.put( value, key ) ; 196 } 197 198 public boolean hasMultipleIDs(AOMEntry value) 199 { 200 return false; 201 } 202 203 // This case does not need the key. 204 protected void removeEntry(AOMEntry entry, Key key) 205 { 206 entryToKey.remove( entry ) ; 207 } 208 209 public void clear() 210 { 211 super.clear() ; 212 entryToKey.clear() ; 213 } 214} 215 216class MultipleObjectMap extends ActiveObjectMap 217{ 218 private Map entryToKeys = new HashMap() ; // Map< AOMEntry, Set< Key > > 219 220 public MultipleObjectMap( POAImpl poa ) 221 { 222 super( poa ) ; 223 } 224 225 public Key getKey(AOMEntry value) throws WrongPolicy 226 { 227 throw new WrongPolicy() ; 228 } 229 230 protected void putEntry(Key key, AOMEntry value) 231 { 232 super.putEntry( key, value); 233 234 Set set = (Set)entryToKeys.get( value ) ; 235 if (set == null) { 236 set = new HashSet() ; 237 entryToKeys.put( value, set ) ; 238 } 239 set.add( key ) ; 240 } 241 242 public boolean hasMultipleIDs(AOMEntry value) 243 { 244 Set set = (Set)entryToKeys.get( value ) ; 245 if (set == null) 246 return false ; 247 return set.size() > 1 ; 248 } 249 250 protected void removeEntry(AOMEntry entry, Key key) 251 { 252 Set keys = (Set)entryToKeys.get( entry ) ; 253 if (keys != null) { 254 keys.remove( key ) ; 255 if (keys.isEmpty()) 256 entryToKeys.remove( entry ) ; 257 } 258 } 259 260 public void clear() 261 { 262 super.clear() ; 263 entryToKeys.clear() ; 264 } 265} 266