Source for gnu.CORBA.Poa.AOM

   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:   }