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