Frames | No Frames |
1: /* AOM.java -- 2: Copyright (C) 2005 Free Software Foundation, Inc. 3: 4: This file is part of GNU Classpath. 5: 6: GNU Classpath is free software; you can redistribute it and/or modify 7: it under the terms of the GNU General Public License as published by 8: the Free Software Foundation; either version 2, or (at your option) 9: any later version. 10: 11: GNU Classpath is distributed in the hope that it will be useful, but 12: WITHOUT ANY WARRANTY; without even the implied warranty of 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14: General Public License for more details. 15: 16: You should have received a copy of the GNU General Public License 17: along with GNU Classpath; see the file COPYING. If not, write to the 18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19: 02110-1301 USA. 20: 21: Linking this library statically or dynamically with other modules is 22: making a combined work based on this library. Thus, the terms and 23: conditions of the GNU General Public License cover the whole 24: combination. 25: 26: As a special exception, the copyright holders of this library give you 27: permission to link this library with independent modules to produce an 28: executable, regardless of the license terms of these independent 29: modules, and to copy and distribute the resulting executable under 30: terms of your choice, provided that you also meet, for each linked 31: independent module, the terms and conditions of the license of that 32: module. An independent module is a module which is not derived from 33: or based on this library. If you modify this library, you may extend 34: this exception to your version of the library, but you are not 35: obligated to do so. If you do not wish to do so, delete this 36: exception statement from your version. */ 37: 38: 39: package gnu.CORBA.Poa; 40: 41: import gnu.CORBA.ByteArrayComparator; 42: 43: import org.omg.CORBA.portable.Delegate; 44: import org.omg.CORBA.portable.ObjectImpl; 45: import org.omg.PortableServer.Servant; 46: 47: import java.util.Iterator; 48: import java.util.Map; 49: import java.util.Set; 50: import java.util.TreeMap; 51: 52: /** 53: * Implements the conception of the Active Object Map. 54: * If the POA supports the RETAIN policy, it maintains an Active 55: * Object Map, that associates Object Ids with active servants. 56: * Each association constitutes an active object. We use a single map 57: * for all POAs on the given orb. 58: * 59: * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) 60: */ 61: public class AOM 62: { 63: /** 64: * The reference data about the object, placed on the AOM. 65: */ 66: public class Obj 67: { 68: /** 69: * Create an initialised instance. 70: */ 71: Obj(gnuServantObject _object, byte[] _key, Servant _servant, gnuPOA _poa) 72: { 73: object = _object; 74: key = _key; 75: servant = _servant; 76: poa = _poa; 77: } 78: 79: /** 80: * The object. 81: */ 82: public final gnuServantObject object; 83: 84: /** 85: * The servant, serving the given object. 86: */ 87: public Servant servant; 88: 89: /** 90: * The local servant that once served this object. 91: * This field is used by {@link ForwardedServant} when it discovers that 92: * the forwarding chaing returns back to the original location. 93: * It should not be used anywhere else. 94: */ 95: Servant primary_servant; 96: 97: /** 98: * The POA, where the object is connected. 99: */ 100: public final gnuPOA poa; 101: 102: /** 103: * The object key. 104: */ 105: public final byte[] key; 106: 107: /** 108: * If true, this entry is deactivated. 109: */ 110: public boolean deactivated; 111: 112: /** 113: * Set the servant value, preserving any non null 114: * value as the primary servant. 115: */ 116: public void setServant(Servant s) 117: { 118: if (primary_servant == null) 119: primary_servant = s; 120: servant = s; 121: } 122: 123: /** 124: * Get the servant. 125: */ 126: public Servant getServant() 127: { 128: return servant; 129: } 130: 131: /** 132: * Get the deactivation state. 133: */ 134: public boolean isDeactiveted() 135: { 136: return deactivated; 137: } 138: 139: /** 140: * Set the deactivation state. 141: */ 142: public void setDeactivated(boolean state) 143: { 144: deactivated = state; 145: } 146: } 147: 148: /** 149: * The free number to give for the next instance. 150: * This field is incremented each time the 151: * new collection of the connected objects is created. 152: * Each collection has its own unique instance number. 153: */ 154: private static long free_id; 155: 156: /** 157: * The map of the all connected objects, maps the object key to the 158: * object. 159: */ 160: Map objects = new TreeMap(new ByteArrayComparator()); 161: 162: /** 163: * Get the record of the stored object. If the object is mapped several times 164: * under the different keys, one of the mappings is used. 165: * 166: * @param stored_object the stored object 167: * 168: * @return the record about the stored object, null if this object is not 169: * stored here. 170: */ 171: public Obj findObject(org.omg.CORBA.Object stored_object) 172: { 173: if (stored_object == null) 174: return null; 175: 176: Map.Entry item; 177: Iterator iter; 178: Obj ref; 179: 180: if (stored_object instanceof ObjectImpl) 181: { 182: // If the delegate is available, search by delegate. 183: Delegate d = ((ObjectImpl) stored_object)._get_delegate(); 184: Delegate d2; 185: 186: if (d != null) 187: { 188: iter = objects.entrySet().iterator(); 189: while (iter.hasNext()) 190: { 191: item = (Map.Entry) iter.next(); 192: ref = (Obj) item.getValue(); 193: d2 = ref.object._get_delegate(); 194: 195: if (d == d2 || (d2 != null && d2.equals(d))) 196: return ref; 197: } 198: } 199: } 200: 201: // For other objects (or if not possible to get the delegate), 202: // search by .equals 203: iter = objects.entrySet().iterator(); 204: while (iter.hasNext()) 205: { 206: item = (Map.Entry) iter.next(); 207: ref = (Obj) item.getValue(); 208: if (stored_object.equals(ref.object)) 209: return ref; 210: } 211: return null; 212: } 213: 214: /** 215: * Find the reference info for the given servant. If the servant is mapped to 216: * several objects, this returns the first found occurence. 217: * 218: * @param servant a servant to find. 219: * 220: * @return the servant/object/POA binding or null if no such found. 221: */ 222: public Obj findServant(Servant servant) 223: { 224: if (servant == null) 225: return null; 226: 227: Map.Entry item; 228: Iterator iter = objects.entrySet().iterator(); 229: Obj ref; 230: 231: while (iter.hasNext()) 232: { 233: item = (Map.Entry) iter.next(); 234: ref = (Obj) item.getValue(); 235: if (servant.equals(ref.servant)) 236: return ref; 237: } 238: return null; 239: } 240: 241: /** 242: * Find the reference info for the given servant. 243: * If the servant is mapped to several objects, this 244: * returns the first found occurence. 245: * 246: * @param servant a servant to find. 247: * @param speficies if to search for the inactive (true) or active 248: * (false) servant. A servant with unmatching activity is ignored 249: * by this method. 250: * 251: * @return the servant/object/POA binding or null if no such found. 252: */ 253: public Obj findServant(Servant servant, boolean inactive) 254: { 255: if (servant == null) 256: return null; 257: 258: Map.Entry item; 259: Iterator iter = objects.entrySet().iterator(); 260: Obj ref; 261: 262: while (iter.hasNext()) 263: { 264: item = (Map.Entry) iter.next(); 265: ref = (Obj) item.getValue(); 266: if (ref.deactivated == inactive) 267: if (ref.servant != null) 268: if (servant.equals(ref.servant)) 269: return ref; 270: } 271: return null; 272: } 273: 274: /** 275: * Add the new object to the repository. The object key is 276: * generated automatically. 277: * 278: * @param object the object to add. 279: * @param servant a servant, serving the given object. 280: * @param poa the poa, where the object is connected. 281: * 282: * @return the newly created object record. 283: */ 284: public Obj add(gnuServantObject object, Servant servant, gnuPOA poa) 285: { 286: return add(generateObjectKey(object), object, servant, poa); 287: } 288: 289: /** 290: * Add the new object to the repository. 291: * 292: * @param key the object key. 293: * @param object the object to add. 294: * @param servant a servant, serving the given object. 295: * @param poa the POA, where the object is connected. 296: */ 297: public Obj add(byte[] key, gnuServantObject object, Servant servant, 298: gnuPOA poa 299: ) 300: { 301: Obj rec = new Obj(object, key, servant, poa); 302: objects.put(key, rec); 303: return rec; 304: } 305: 306: /** 307: * Add the new object to the repository. 308: * 309: * @param delegate the delegate, providing data about the servant, key, POA 310: * and object. 311: * @param port the port that this object would take. 312: */ 313: public Obj add(ServantDelegateImpl delegate) 314: { 315: Obj rec = 316: new Obj(delegate.object, delegate.servant_id, delegate.servant, 317: delegate.poa 318: ); 319: objects.put(delegate.servant_id, rec); 320: return rec; 321: } 322: 323: /** 324: * Put back the definition structure that has probably been removed earlier. 325: */ 326: public void put(Obj obj) 327: { 328: objects.put(obj.key, obj); 329: } 330: 331: /** 332: * Get the stored object. 333: * 334: * @param key the key (in the byte array form). 335: * 336: * @return the matching object, null if none is matching. 337: */ 338: public Obj get(byte[] key) 339: { 340: return (Obj) objects.get(key); 341: } 342: 343: /** 344: * Get the map key set. 345: */ 346: public Set keySet() 347: { 348: return objects.keySet(); 349: } 350: 351: /** 352: * Remove the given object, indiciating it by the key. 353: * 354: * @param object the object to remove. 355: */ 356: public void remove(byte[] key) 357: { 358: objects.remove(key); 359: } 360: 361: /** 362: * Generate the object key, unique in the currently 363: * running java virtual machine. The passed object 364: * parameter is currently not in use. 365: * 366: * @return the generated key. 367: */ 368: protected byte[] generateObjectKey(org.omg.CORBA.Object object) 369: { 370: byte[] key; 371: 372: // The repetetive keys cannot be generated, but theoretically 373: // the same keys can be passed when calling add(byte[]...). 374: // Hence we check if the key is not already in the map and, 375: // if it is, use the subsequent value. 376: do 377: { 378: key = getFreeId(); 379: } 380: while (objects.containsKey(key)); 381: return key; 382: } 383: 384: /** 385: * Get the next free 8 byte id, surely unique between calls of this 386: * method for the currently running virtual machine. 387: */ 388: public static synchronized byte[] getFreeId() 389: { 390: byte[] r = new byte[ 8 ]; 391: 392: // Start from the faster-changing. 393: r [ 0 ] = ((byte) (0xff & free_id)); 394: r [ 1 ] = ((byte) (0xff & (free_id >> 8))); 395: r [ 2 ] = ((byte) (0xff & (free_id >> 16))); 396: r [ 3 ] = ((byte) (0xff & (free_id >> 24))); 397: r [ 4 ] = ((byte) (0xff & (free_id >> 32))); 398: r [ 5 ] = ((byte) (0xff & (free_id >> 40))); 399: r [ 6 ] = ((byte) (0xff & (free_id >> 48))); 400: r [ 7 ] = ((byte) (0xff & (free_id >> 56))); 401: 402: free_id++; 403: 404: return r; 405: } 406: }