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.PortableServer.Servant; 44: 45: import java.util.Iterator; 46: import java.util.Map; 47: import java.util.Set; 48: import java.util.TreeMap; 49: 50: /** 51: * Implements the conception of the Active Object Map. 52: * If the POA supports the RETAIN policy, it maintains an Active 53: * Object Map, that associates Object Ids with active servants. 54: * Each association constitutes an active object. We use a single map 55: * for all POAs on the given orb. 56: * 57: * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) 58: */ 59: public class AOM 60: { 61: /** 62: * The reference data about the object, placed on the AOM. 63: */ 64: public class Obj 65: { 66: /** 67: * Create an initialised instance. 68: */ 69: Obj(org.omg.CORBA.Object _object, byte[] _key, Servant _servant, gnuPOA _poa) 70: { 71: object = _object; 72: key = _key; 73: servant = _servant; 74: poa = _poa; 75: } 76: 77: /** 78: * The object. 79: */ 80: public final org.omg.CORBA.Object object; 81: 82: /** 83: * The servant, serving the given object. 84: */ 85: public Servant servant; 86: 87: /** 88: * The local servant that once served this object. 89: * This field is used by {@link ForwardedServant} when it discovers that 90: * the forwarding chaing returns back to the original location. 91: * It should not be used anywhere else. 92: */ 93: Servant primary_servant; 94: 95: /** 96: * The POA, where the object is connected. 97: */ 98: public final gnuPOA poa; 99: 100: /** 101: * The object key. 102: */ 103: public final byte[] key; 104: 105: /** 106: * If true, this entry is deactivated. 107: */ 108: public boolean deactivated; 109: 110: /** 111: * Set the servant value, preserving any non null 112: * value as the primary servant. 113: */ 114: public void setServant(Servant s) 115: { 116: if (primary_servant == null) 117: primary_servant = s; 118: servant = s; 119: } 120: 121: /** 122: * Get the servant. 123: */ 124: public Servant getServant() 125: { 126: return servant; 127: } 128: 129: /** 130: * Get the deactivation state. 131: */ 132: public boolean isDeactiveted() 133: { 134: return deactivated; 135: } 136: 137: /** 138: * Set the deactivation state. 139: */ 140: public void setDeactivated(boolean state) 141: { 142: deactivated = state; 143: } 144: } 145: 146: /** 147: * The free number to give for the next instance. 148: * This field is incremented each time the 149: * new collection of the connected objects is created. 150: * Each collection has its own unique instance number. 151: */ 152: private static long free_id; 153: 154: /** 155: * The map of the all connected objects, maps the object key to the 156: * object. 157: */ 158: Map objects = new TreeMap(new ByteArrayComparator()); 159: 160: /** 161: * Get the record of the stored object. If the object is mapped 162: * several times under the different keys, one of the mappings 163: * is used. 164: * 165: * @param object the stored object 166: * 167: * @return the record about the stored object, null if 168: * this object is not stored here. 169: */ 170: public Obj findObject(org.omg.CORBA.Object stored_object) 171: { 172: if (stored_object == null) 173: return null; 174: 175: Map.Entry item; 176: Iterator iter = objects.entrySet().iterator(); 177: Obj ref; 178: 179: while (iter.hasNext()) 180: { 181: item = (Map.Entry) iter.next(); 182: ref = (Obj) item.getValue(); 183: if (stored_object.equals(ref.object)) 184: return ref; 185: } 186: return null; 187: } 188: 189: /** 190: * Find the reference info for the given servant. 191: * If the servant is mapped to several objects, this 192: * returns the first found occurence. 193: * 194: * @param servant a servant to find. 195: * 196: * @return the servant/object/POA binding or null if no such found. 197: */ 198: public Obj findServant(Servant servant) 199: { 200: if (servant == null) 201: return null; 202: 203: Map.Entry item; 204: Iterator iter = objects.entrySet().iterator(); 205: Obj ref; 206: 207: while (iter.hasNext()) 208: { 209: item = (Map.Entry) iter.next(); 210: ref = (Obj) item.getValue(); 211: if (servant.equals(ref.servant)) 212: return ref; 213: } 214: return null; 215: } 216: 217: /** 218: * Find the reference info for the given servant. 219: * If the servant is mapped to several objects, this 220: * returns the first found occurence. 221: * 222: * @param servant a servant to find. 223: * @param speficies if to search for the inactive (true) or active 224: * (false) servant. A servant with unmatching activity is ignored 225: * by this method. 226: * 227: * @return the servant/object/POA binding or null if no such found. 228: */ 229: public Obj findServant(Servant servant, boolean inactive) 230: { 231: if (servant == null) 232: return null; 233: 234: Map.Entry item; 235: Iterator iter = objects.entrySet().iterator(); 236: Obj ref; 237: 238: while (iter.hasNext()) 239: { 240: item = (Map.Entry) iter.next(); 241: ref = (Obj) item.getValue(); 242: if (ref.deactivated == inactive) 243: if (ref.servant != null) 244: if (servant.equals(ref.servant)) 245: return ref; 246: } 247: return null; 248: } 249: 250: /** 251: * Add the new object to the repository. The object key is 252: * generated automatically. 253: * 254: * @param object the object to add. 255: * @param servant a servant, serving the given object. 256: * @param poa the poa, where the object is connected. 257: * 258: * @return the newly created object record. 259: */ 260: public Obj add(org.omg.CORBA.Object object, Servant servant, gnuPOA poa) 261: { 262: return add(generateObjectKey(object), object, servant, poa); 263: } 264: 265: /** 266: * Add the new object to the repository. 267: * 268: * @param key the object key. 269: * @param object the object to add. 270: * @param servant a servant, serving the given object. 271: * @param poa the POA, where the object is connected. 272: */ 273: public Obj add(byte[] key, org.omg.CORBA.Object object, Servant servant, 274: gnuPOA poa 275: ) 276: { 277: Obj rec = new Obj(object, key, servant, poa); 278: objects.put(key, rec); 279: return rec; 280: } 281: 282: /** 283: * Add the new object to the repository. 284: * 285: * @param delegate the delegate, providing data about the servant, key, POA 286: * and object. 287: * @param port the port that this object would take. 288: */ 289: public Obj add(ServantDelegateImpl delegate) 290: { 291: Obj rec = 292: new Obj(delegate.object, delegate.servant_id, delegate.servant, 293: delegate.poa 294: ); 295: objects.put(delegate.servant_id, rec); 296: return rec; 297: } 298: 299: /** 300: * Put back the definition structure that has probably been removed earlier. 301: */ 302: public void put(Obj obj) 303: { 304: objects.put(obj.key, obj); 305: } 306: 307: /** 308: * Get the stored object. 309: * 310: * @param key the key (in the byte array form). 311: * 312: * @return the matching object, null if none is matching. 313: */ 314: public Obj get(byte[] key) 315: { 316: return (Obj) objects.get(key); 317: } 318: 319: /** 320: * Get the map key set. 321: */ 322: public Set keySet() 323: { 324: return objects.keySet(); 325: } 326: 327: /** 328: * Remove the given object, indiciating it by the key. 329: * 330: * @param object the object to remove. 331: */ 332: public void remove(byte[] key) 333: { 334: objects.remove(key); 335: } 336: 337: /** 338: * Generate the object key, unique in the currently 339: * running java virtual machine. The passed object 340: * parameter is currently not in use. 341: * 342: * @return the generated key. 343: */ 344: protected byte[] generateObjectKey(org.omg.CORBA.Object object) 345: { 346: byte[] key; 347: 348: // The repetetive keys cannot be generated, but theoretically 349: // the same keys can be passed when calling add(byte[]...). 350: // Hence we check if the key is not already in the map and, 351: // if it is, use the subsequent value. 352: do 353: { 354: key = getFreeId(); 355: } 356: while (objects.containsKey(key)); 357: return key; 358: } 359: 360: /** 361: * Get the next free 8 byte id, surely unique between calls of this 362: * method for the currently running virtual machine. 363: */ 364: public static synchronized byte[] getFreeId() 365: { 366: byte[] r = new byte[ 8 ]; 367: 368: // Start from the faster-changing. 369: r [ 0 ] = ((byte) (0xff & free_id)); 370: r [ 1 ] = ((byte) (0xff & (free_id >> 8))); 371: r [ 2 ] = ((byte) (0xff & (free_id >> 16))); 372: r [ 3 ] = ((byte) (0xff & (free_id >> 24))); 373: r [ 4 ] = ((byte) (0xff & (free_id >> 32))); 374: r [ 5 ] = ((byte) (0xff & (free_id >> 40))); 375: r [ 6 ] = ((byte) (0xff & (free_id >> 48))); 376: r [ 7 ] = ((byte) (0xff & (free_id >> 56))); 377: 378: free_id++; 379: 380: return r; 381: }