Source for gnu.CORBA.DynAn.RecordAny

   1: /* RecordAny.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.Unexpected;
  42: import gnu.CORBA.HolderLocator;
  43: 
  44: import org.omg.CORBA.Any;
  45: import org.omg.CORBA.ORB;
  46: import org.omg.CORBA.TCKind;
  47: import org.omg.CORBA.TypeCode;
  48: import org.omg.CORBA.TypeCodePackage.BadKind;
  49: import org.omg.CORBA.TypeCodePackage.Bounds;
  50: import org.omg.CORBA.portable.Streamable;
  51: import org.omg.DynamicAny.DynAny;
  52: import org.omg.DynamicAny.DynAnyPackage.InvalidValue;
  53: import org.omg.DynamicAny.DynAnyPackage.TypeMismatch;
  54: import org.omg.DynamicAny.DynStruct;
  55: import org.omg.DynamicAny.DynValueCommonOperations;
  56: import org.omg.DynamicAny.NameDynAnyPair;
  57: import org.omg.DynamicAny.NameValuePair;
  58: 
  59: import java.io.Serializable;
  60: 
  61: import java.lang.reflect.Field;
  62: 
  63: /**
  64:  * A shared base for both dynamic structure an dynamic value final_type.
  65:  *
  66:  * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org)
  67:  */
  68: public abstract class RecordAny
  69:   extends DivideableAny
  70:   implements DynAny, Serializable
  71: {
  72:   /**
  73:    * Use serialVersionUID for interoperability.
  74:    */
  75:   private static final long serialVersionUID = 1;
  76:   String[] fNames;
  77: 
  78:   /**
  79:    * Creates the structure with the given typecode.
  80:    *
  81:    * @param fields The DynAny's, representing the fields of the structure.
  82:    */
  83:   public RecordAny(TypeCode oType, TypeCode aType,
  84:                         gnuDynAnyFactory aFactory, ORB anOrb
  85:                        )
  86:   {
  87:     super(oType, aType, aFactory, anOrb);
  88:   }
  89: 
  90:   /** @inheritDoc */
  91:   public TCKind current_member_kind()
  92:                              throws TypeMismatch, InvalidValue
  93:   {
  94:     if (array.length == 0)
  95:       throw new TypeMismatch(EMPTY);
  96:     try
  97:       {
  98:         return final_type.member_type(pos).kind();
  99:       }
 100:     catch (BadKind e)
 101:       {
 102:         TypeMismatch t = new TypeMismatch();
 103:         t.initCause(e);
 104:         throw t;
 105:       }
 106:     catch (Bounds e)
 107:       {
 108:         InvalidValue t = new InvalidValue();
 109:         t.initCause(e);
 110:         throw t;
 111:       }
 112:   }
 113: 
 114:   /** @inheritDoc */
 115:   public String current_member_name()
 116:                              throws TypeMismatch, InvalidValue
 117:   {
 118:     if (array.length == 0)
 119:       throw new TypeMismatch(EMPTY);
 120:     try
 121:       {
 122:         return final_type.member_name(pos);
 123:       }
 124:     catch (BadKind e)
 125:       {
 126:         TypeMismatch t = new TypeMismatch();
 127:         t.initCause(e);
 128:         throw t;
 129:       }
 130:     catch (Bounds e)
 131:       {
 132:         InvalidValue t = new InvalidValue();
 133:         t.initCause(e);
 134:         throw t;
 135:       }
 136:   }
 137: 
 138:   /**
 139:    * Get content of the structure. This method must be defined on a different
 140:    * name because get_members_as_dyn_any() throws exception only in some of the
 141:    * supported interfaces.
 142:    */
 143:   public NameDynAnyPair[] gnu_get_members_as_dyn_any()
 144:   {
 145:     NameDynAnyPair[] r = new NameDynAnyPair[ array.length ];
 146:     for (int i = 0; i < r.length; i++)
 147:       {
 148:         try
 149:           {
 150:             r [ i ] = new NameDynAnyPair(fNames [ i ], array [ i ]);
 151:           }
 152:         catch (Exception ex)
 153:           {
 154:             throw new Unexpected(ex);
 155:           }
 156:       }
 157:     return r;
 158:   }
 159: 
 160:   /**
 161:    * Get content of the structure. This method must be defined on a different
 162:    * name because get_members_as_dyn_any() throws exception only in some of the
 163:    * supported interfaces.
 164:    */
 165:   public NameValuePair[] gnu_get_members()
 166:   {
 167:     NameValuePair[] r = new NameValuePair[ array.length ];
 168:     for (int i = 0; i < r.length; i++)
 169:       {
 170:         try
 171:           {
 172:             r [ i ] = new NameValuePair(fNames [ i ], array [ i ].to_any());
 173:           }
 174:         catch (Exception ex)
 175:           {
 176:             throw new Unexpected(ex);
 177:           }
 178:       }
 179:     return r;
 180:   }
 181: 
 182:   /**
 183:    * Set members from the provided array.
 184:    */
 185:   public void set_members_as_dyn_any(NameDynAnyPair[] value)
 186:                               throws TypeMismatch, InvalidValue
 187:   {
 188:     if (value.length != array.length)
 189:       throw new InvalidValue(sizeMismatch(array.length, value.length));
 190: 
 191:     for (int i = 0; i < value.length; i++)
 192:       {
 193:         DynAny dynAny = value [ i ].value;
 194:         checkType(dynAny.type(), i);
 195:         checkName(value [ i ].id, i);
 196: 
 197:         array [ i ] = dynAny;
 198:       }
 199:     pos = 0;
 200:   }
 201: 
 202:   /**
 203:    * Check the name at the given position ("" matches everything).
 204:    */
 205:   private void checkName(String xName, int i)
 206:                   throws TypeMismatch
 207:   {
 208:     if (xName.length() > 0 && fNames [ i ].length() > 0)
 209:       if (!xName.equals(fNames [ i ]))
 210:         throw new TypeMismatch("Field name mismatch " + xName + " expected " +
 211:                                fNames [ i ]
 212:                               );
 213:   }
 214: 
 215:   /**
 216:    * Check the type at the given position.
 217:    */
 218:   private void checkType(TypeCode t, int i)
 219:                   throws TypeMismatch
 220:   {
 221:     if (!array [ i ].type().equal(t))
 222:       throw new TypeMismatch(typeMismatch(array [ i ].type(), t) + " field " +
 223:                              i
 224:                             );
 225:   }
 226: 
 227:   /**
 228:    * Set members from the provided array.
 229:    */
 230:   public void set_members(NameValuePair[] value)
 231:                    throws TypeMismatch, InvalidValue
 232:   {
 233:     if (value.length != array.length)
 234:       throw new InvalidValue(sizeMismatch(array.length, value.length));
 235: 
 236:     for (int i = 0; i < value.length; i++)
 237:       {
 238:         Any any = value [ i ].value;
 239:         checkType(any.type(), i);
 240:         checkName(value [ i ].id, i);
 241: 
 242:         array [ i ].from_any(any);
 243:       }
 244:     pos = 0;
 245:   }
 246: 
 247:   /** @inheritDoc */
 248:   public void assign(DynAny from)
 249:               throws TypeMismatch
 250:   {
 251:     checkType(official_type, from.type());
 252:     if (from instanceof DynStruct)
 253:       {
 254:         try
 255:           {
 256:             set_members_as_dyn_any(((DynStruct) from).get_members_as_dyn_any());
 257:           }
 258:         catch (InvalidValue e)
 259:           {
 260:             TypeMismatch t = new TypeMismatch("Invalid value");
 261:             t.initCause(e);
 262:             throw t;
 263:           }
 264:       }
 265:     else
 266:       throw new TypeMismatch("Not a DynStruct");
 267:   }
 268: 
 269:   /**
 270:    * Create a copy.
 271:    */
 272:   public DynAny copy()
 273:   {
 274:     DynAny[] c = new DynAny[ array.length ];
 275:     for (int i = 0; i < c.length; i++)
 276:       {
 277:         c [ i ] = array [ i ].copy();
 278:       }
 279: 
 280:     RecordAny d = newInstance(official_type, final_type, factory, orb);
 281:     d.array = c;
 282:     return d;
 283:   }
 284: 
 285:   /**
 286:    * Create a new instance when copying.
 287:    */
 288:   protected abstract RecordAny newInstance(TypeCode oType, TypeCode aType,
 289:                                                 gnuDynAnyFactory aFactory,
 290:                                                 ORB anOrb
 291:                                                );
 292: 
 293:   /**
 294:    * Done via reflection.
 295:    */
 296:   public Any to_any()
 297:   {
 298:     try
 299:       {
 300:         Streamable sHolder = HolderLocator.createHolder(official_type);
 301: 
 302:         Class sHolderClass = sHolder.getClass();
 303:         Field sHolderValue = sHolderClass.getField("value");
 304:         Class sClass = sHolderValue.getType();
 305: 
 306:         Object structure = sClass.newInstance();
 307:         Object member;
 308:         Any am;
 309:         Field vread;
 310:         Field vwrite;
 311:         Streamable memberHolder;
 312: 
 313:         for (int i = 0; i < array.length; i++)
 314:           {
 315:             am = array [ i ].to_any();
 316:             memberHolder = am.extract_Streamable();
 317:             vwrite = structure.getClass().getField(final_type.member_name(i));
 318:             vread = memberHolder.getClass().getField("value");
 319:             member = vread.get(memberHolder);
 320:             vwrite.set(structure, member);
 321:           }
 322: 
 323:         Any g = createAny();
 324:         sHolderValue.set(sHolder, structure);
 325:         g.insert_Streamable(sHolder);
 326:         g.type(official_type);
 327:         return g;
 328:       }
 329:     catch (Exception e)
 330:       {
 331:         throw new Unexpected(e);
 332:       }
 333:   }
 334: 
 335:   /**
 336:    * Done via reflection.
 337:    */
 338:   public void from_any(Any an_any)
 339:                 throws TypeMismatch, InvalidValue
 340:   {
 341:     checkType(official_type, an_any.type());
 342:     try
 343:       {
 344:         Streamable s = an_any.extract_Streamable();
 345:         if (s == null)
 346:           {
 347:             if (this instanceof DynValueCommonOperations)
 348:               {
 349:                 ((DynValueCommonOperations) this).set_to_null();
 350:                 return;
 351:               }
 352:             else
 353:               throw new InvalidValue(ISNULL);
 354:           }
 355: 
 356:         Object structure = s.getClass().getField("value").get(s);
 357:         if (structure == null && (this instanceof DynValueCommonOperations))
 358:           {
 359:             ((DynValueCommonOperations) this).set_to_null();
 360:             return;
 361:           }
 362: 
 363:         Any member;
 364:         Streamable holder;
 365:         Object field;
 366:         TypeCode fType;
 367:         Field fField;
 368: 
 369:         for (int i = 0; i < array.length; i++)
 370:           {
 371:             fField = structure.getClass().getField(fNames [ i ]);
 372:             field = fField.get(structure);
 373:             fType = array [ i ].type();
 374:             holder = HolderLocator.createHolder(fType);
 375: 
 376:             member = createAny();
 377:             holder.getClass().getField("value").set(holder, field);
 378:             member.insert_Streamable(holder);
 379:             member.type(fType);
 380: 
 381:             array [ i ].from_any(member);
 382:           }
 383: 
 384:         if (this instanceof DynValueCommonOperations)
 385:           ((DynValueCommonOperations) this).set_to_value();
 386:       }
 387:     catch (InvalidValue v)
 388:       {
 389:         throw v;
 390:       }
 391:     catch (NoSuchFieldException ex)
 392:       {
 393:         TypeMismatch v =
 394:           new TypeMismatch("holder value does not match typecode");
 395:         v.initCause(ex);
 396:         throw v;
 397:       }
 398:     catch (Exception ex)
 399:       {
 400:         TypeMismatch t = new TypeMismatch();
 401:         t.initCause(ex);
 402:         throw t;
 403:       }
 404:   }
 405: }