Source for gnu.CORBA.DynAn.gnuDynValue

   1: /* gnuDynValue.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.DynAn;
  40: 
  41: import gnu.CORBA.Minor;
  42: import gnu.CORBA.Unexpected;
  43: 
  44: import org.omg.CORBA.Any;
  45: import org.omg.CORBA.BAD_PARAM;
  46: import org.omg.CORBA.MARSHAL;
  47: import org.omg.CORBA.ORB;
  48: import org.omg.CORBA.TCKind;
  49: import org.omg.CORBA.TypeCode;
  50: import org.omg.CORBA.VM_TRUNCATABLE;
  51: import org.omg.CORBA.portable.OutputStream;
  52: import org.omg.CORBA.portable.ValueFactory;
  53: import org.omg.DynamicAny.DynAny;
  54: import org.omg.DynamicAny.DynAnyPackage.InvalidValue;
  55: import org.omg.DynamicAny.DynAnyPackage.TypeMismatch;
  56: import org.omg.DynamicAny.DynStruct;
  57: import org.omg.DynamicAny.DynValue;
  58: import org.omg.DynamicAny.DynValueCommon;
  59: import org.omg.DynamicAny.DynValueOperations;
  60: import org.omg.DynamicAny.NameDynAnyPair;
  61: import org.omg.DynamicAny.NameValuePair;
  62: 
  63: import java.io.Serializable;
  64: 
  65: /**
  66:  * Implementation of DynValue.
  67:  *
  68:  * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org)
  69:  */
  70: public class gnuDynValue extends RecordAny implements DynValue,
  71:   Serializable
  72: {
  73:   /**
  74:    * Use serialVersionUID for interoperability.
  75:    */
  76:   private static final long serialVersionUID = 1;
  77: 
  78:   /**
  79:    * If true, the value of this ValueType is set to null.
  80:    */
  81:   boolean isNull;
  82: 
  83:   /**
  84:    * Create an instance.
  85:    */
  86:   public gnuDynValue(TypeCode oType, TypeCode aType,
  87:     gnuDynAnyFactory aFactory, ORB anOrb
  88:   )
  89:   {
  90:     super(oType, aType, aFactory, anOrb);
  91: 
  92:     // Initialise fields. The array of fields also includes all inherited
  93:     // fields.
  94:     try
  95:       {
  96:         array = new DynAny[ final_type.member_count() ];
  97:         fNames = new String[ array.length ];
  98:         for (int i = 0; i < array.length; i++)
  99:           {
 100:             array [ i ] =
 101:               factory.create_dyn_any_from_type_code(final_type.member_type(i));
 102:             fNames [ i ] = final_type.member_name(i);
 103:           }
 104: 
 105:         // Search of inherited members.
 106:         if (final_type.type_modifier() == VM_TRUNCATABLE.value)
 107:           {
 108:             TypeCode parent = final_type.concrete_base_type();
 109:             DynAny ancestor = factory.create_dyn_any_from_type_code(parent);
 110: 
 111:             if (ancestor instanceof DynValue)
 112:               {
 113:                 // Add members of ancestor in front of the curren members.
 114:                 DynValue anc = (DynValue) ancestor;
 115:                 anc.set_to_value();
 116: 
 117:                 NameDynAnyPair[] aar = anc.get_members_as_dyn_any();
 118:                 inheritFields(aar);
 119:               }
 120:             else if (ancestor instanceof DynStruct)
 121:               {
 122:                 // Add members of ancestor in front of the curren members.
 123:                 DynStruct anc = (DynStruct) ancestor;
 124:                 NameDynAnyPair[] aar = anc.get_members_as_dyn_any();
 125:                 inheritFields(aar);
 126:               }
 127:             else
 128:               throw new BAD_PARAM("The parent of " + final_type.id() + ", " +
 129:                 parent.id() + ", is not structure nor value."
 130:               );
 131:           }
 132:       }
 133:     catch (Exception e)
 134:       {
 135:         throw new Unexpected(e);
 136:       }
 137: 
 138:     set_to_null();
 139:   }
 140: 
 141:   /**
 142:    * Inherit the provided fields.
 143:    */
 144:   private void inheritFields(NameDynAnyPair[] aar)
 145:   {
 146:     DynAny[] nArray = new DynAny[ array.length + aar.length ];
 147:     String[] nNames = new String[ array.length + aar.length ];
 148:     int p = 0;
 149:     for (int i = 0; i < aar.length; i++)
 150:       {
 151:         nArray [ p ] = aar [ i ].value;
 152:         nNames [ p ] = aar [ i ].id;
 153:         p++;
 154:       }
 155: 
 156:     for (int i = 0; i < array.length; i++)
 157:       {
 158:         nArray [ p ] = array [ i ];
 159:         nNames [ p ] = fNames [ i ];
 160:         p++;
 161:       }
 162: 
 163:     array = nArray;
 164:     fNames = nNames;
 165:   }
 166: 
 167:   /** @inheritDoc */
 168:   public TCKind current_member_kind() throws TypeMismatch, InvalidValue
 169:   {
 170:     if (isNull)
 171:       throw new TypeMismatch(ISNULL);
 172:     else
 173:       return super.current_member_kind();
 174:   }
 175: 
 176:   /** @inheritDoc */
 177:   public String current_member_name() throws TypeMismatch, InvalidValue
 178:   {
 179:     if (isNull)
 180:       throw new TypeMismatch(ISNULL);
 181:     else
 182:       return super.current_member_name();
 183:   }
 184: 
 185:   /** @inheritDoc */
 186:   public NameDynAnyPair[] get_members_as_dyn_any() throws InvalidValue
 187:   {
 188:     if (isNull)
 189:       throw new InvalidValue(ISNULL);
 190:     return super.gnu_get_members_as_dyn_any();
 191:   }
 192: 
 193:   /** @inheritDoc */
 194:   public NameValuePair[] get_members() throws InvalidValue
 195:   {
 196:     if (isNull)
 197:       throw new InvalidValue(ISNULL);
 198:     else
 199:       return super.gnu_get_members();
 200:   }
 201: 
 202:   /** @inheritDoc */
 203:   public void set_members_as_dyn_any(NameDynAnyPair[] value)
 204:     throws TypeMismatch, InvalidValue
 205:   {
 206:     super.set_members_as_dyn_any(value);
 207:     isNull = false;
 208:   }
 209: 
 210:   /** @inheritDoc */
 211:   public void set_members(NameValuePair[] value)
 212:     throws TypeMismatch, InvalidValue
 213:   {
 214:     super.set_members(value);
 215:     isNull = false;
 216:   }
 217: 
 218:   /** @inheritDoc */
 219:   public boolean is_null()
 220:   {
 221:     return isNull;
 222:   }
 223: 
 224:   /** @inheritDoc */
 225:   public void set_to_null()
 226:   {
 227:     isNull = true;
 228:     valueChanged();
 229:   }
 230: 
 231:   /** @inheritDoc */
 232:   public void set_to_value()
 233:   {
 234:     isNull = false;
 235:     valueChanged();
 236:   }
 237: 
 238:   /**
 239:    * Create a new instance.
 240:    */
 241:   protected RecordAny newInstance(TypeCode oType, TypeCode aType,
 242:     gnuDynAnyFactory aFactory, ORB anOrb
 243:   )
 244:   {
 245:     gnuDynValue v = new gnuDynValue(oType, aType, aFactory, anOrb);
 246:     if (isNull)
 247:       v.set_to_null();
 248:     else
 249:       v.set_to_value();
 250:     return v;
 251:   }
 252: 
 253:   /**
 254:    * Compare for equality, minding null values.
 255:    */
 256:   public boolean equal(DynAny other)
 257:   {
 258:     if (other instanceof DynValueOperations)
 259:       {
 260:         DynValueCommon o = (DynValueCommon) other;
 261:         if (isNull)
 262:           return o.is_null() && o.type().equal(official_type);
 263:         else
 264:           return !o.is_null() && super.equal(other);
 265:       }
 266:     else
 267:       return false;
 268:   }
 269: 
 270:   /**
 271:    * Get the focused component, throwing exception if the current value is null.
 272:    */
 273:   protected DynAny focused() throws InvalidValue, TypeMismatch
 274:   {
 275:     if (isNull)
 276:       throw new TypeMismatch(ISNULL);
 277:     else
 278:       return super.focused();
 279:   }
 280: 
 281:   /**
 282:    * Convert into Any.
 283:    */
 284:   public Any to_any()
 285:   {
 286:     if (isNull)
 287:       {
 288:         Any a0 = createAny();
 289:         a0.type(orb.get_primitive_tc(TCKind.tk_null));
 290:         return a0;
 291:       }
 292:     else
 293:       {
 294:         try
 295:           {
 296:             ValueFactory factory =
 297:               ((org.omg.CORBA_2_3.ORB) orb).lookup_value_factory(official_type.id());
 298:             if (factory == null)
 299:               {
 300:                 MARSHAL m = new MARSHAL("Factory for " + official_type.id() +
 301:                 " not registered.");
 302:                 m.minor = Minor.Factory;
 303:                 throw m;
 304:               }
 305: 
 306:             OutputStream out = orb.create_output_stream();
 307: 
 308:             for (int i = 0; i < array.length; i++)
 309:               array [ i ].to_any().write_value(out);
 310: 
 311:             org.omg.CORBA_2_3.portable.InputStream in =
 312:               (org.omg.CORBA_2_3.portable.InputStream) out.create_input_stream();
 313:             Serializable v = factory.read_value(in);
 314: 
 315:             Any g = createAny();
 316:             g.type(official_type);
 317:             g.insert_Value(v, official_type);
 318: 
 319:             return g;
 320:           }
 321:         catch (Exception e)
 322:           {
 323:             throw new Unexpected(e);
 324:           }
 325:       }
 326:   }
 327: 
 328:   /** @inheritDoc */
 329:   public void assign(DynAny from) throws TypeMismatch
 330:   {
 331:     checkType(official_type, from.type());
 332: 
 333:     if (from instanceof DynValue)
 334:       {
 335:         DynValue other = (DynValue) from;
 336:         if (other.is_null())
 337:           set_to_null();
 338:         else
 339:           {
 340:             set_to_value();
 341:             try
 342:               {
 343:                 DynValueOperations src = (DynValueOperations) from;
 344:                 set_members_as_dyn_any(src.get_members_as_dyn_any());
 345:               }
 346:             catch (InvalidValue e)
 347:               {
 348:                 TypeMismatch t = new TypeMismatch("Invalid value");
 349:                 t.initCause(e);
 350:                 throw t;
 351:               }
 352:           }
 353:       }
 354:     else
 355:       throw new TypeMismatch("Not a DynValue");
 356:   }
 357: 
 358:   /**
 359:    * Get the number of components.
 360:    */
 361:   public int component_count()
 362:   {
 363:     return isNull ? 0 : super.component_count();
 364:   }
 365: 
 366:   /** {@inheritDoc} */
 367:   public Serializable get_val() throws TypeMismatch, InvalidValue
 368:   {
 369:     return to_any().extract_Value();
 370:   }
 371: 
 372:   /** {@inheritDoc} */
 373:   public void insert_val(Serializable a_x) throws InvalidValue, TypeMismatch
 374:   {
 375:     Any a = to_any();
 376:     a.insert_Value(a_x);
 377:     from_any(a);
 378:     valueChanged();
 379:   }
 380: }