Source for gnu.CORBA.DynAn.gnuDynSequence

   1: /* gnuDynSequence.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: 
  43: import org.omg.CORBA.Any;
  44: import org.omg.CORBA.BAD_PARAM;
  45: import org.omg.CORBA.ORB;
  46: import org.omg.CORBA.TypeCode;
  47: import org.omg.CORBA.TypeCodePackage.BadKind;
  48: import org.omg.DynamicAny.DynAny;
  49: import org.omg.DynamicAny.DynAnyFactoryPackage.InconsistentTypeCode;
  50: import org.omg.DynamicAny.DynAnyPackage.InvalidValue;
  51: import org.omg.DynamicAny.DynAnyPackage.TypeMismatch;
  52: import org.omg.DynamicAny.DynSequence;
  53: 
  54: import java.io.Serializable;
  55: 
  56: import java.lang.reflect.*;
  57: 
  58: public class gnuDynSequence
  59:   extends gnuDynArray
  60:   implements DynSequence, Serializable
  61: {
  62:   /**
  63:    * Use serialVersionUID for interoperability.
  64:    */
  65:   private static final long serialVersionUID = 1;
  66: 
  67:   /**
  68:    * The bound of the sequence, as defined in typecode.
  69:    */
  70:   final int bound;
  71: 
  72:   /**
  73:    * Create a new gnuDynSequence with the given typecode.
  74:    *
  75:    * @throws BAD_PARAM if the passed typecode is probably not a sequence
  76:    * typecode.
  77:    */
  78:   public gnuDynSequence(TypeCode oType, TypeCode aType,
  79:                         gnuDynAnyFactory aFactory, ORB anOrb
  80:                        )
  81:                  throws BAD_PARAM
  82:   {
  83:     super(oType, aType, aFactory, anOrb, false);
  84:     array = new DynAny[ 0 ];
  85:     try
  86:       {
  87:         bound = final_type.length();
  88:       }
  89:     catch (BadKind ex)
  90:       {
  91:         throw new Unexpected(ex);
  92:       }
  93:   }
  94: 
  95:   /**
  96:    * Get the length of the sequence.
  97:    */
  98:   public int get_length()
  99:   {
 100:     return array.length;
 101:   }
 102: 
 103:   /**
 104:    * Resize the sequence, preserving components.
 105:    */
 106:   public void set_length(int length)
 107:                   throws InvalidValue
 108:   {
 109:     checkBound(length);
 110:     if (length == array.length)
 111:       return; // Nothing to do.
 112:     else if (length < array.length)
 113:       {
 114:         // Truncate.
 115:         DynAny[] d = new DynAny[ length ];
 116:         for (int i = 0; i < d.length; i++)
 117:           d [ i ] = array [ i ];
 118:         array = d;
 119:       }
 120:     else
 121:       {
 122:         // Expand.
 123:         DynAny[] d = new DynAny[ length ];
 124:         for (int i = 0; i < array.length; i++)
 125:           d [ i ] = array [ i ];
 126: 
 127:         for (int i = array.length; i < d.length; i++)
 128:           {
 129:             try
 130:               {
 131:                 d [ i ] =
 132:                   factory.create_dyn_any_from_type_code(official_components);
 133:               }
 134:             catch (InconsistentTypeCode e)
 135:               {
 136:                 throw new Unexpected(e);
 137:               }
 138:           }
 139:         array = d;
 140:       }
 141:     valueChanged();
 142:   }
 143: 
 144:   /**
 145:    * Copy one DynAny into another.
 146:    */
 147:   public void assign(DynAny from)
 148:               throws TypeMismatch
 149:   {
 150:     checkType(official_type, from.type());
 151:     if (from instanceof DynSequence)
 152:       {
 153:         DynSequence dyn = (DynSequence) from;
 154:         array = dyn.get_elements_as_dyn_any();
 155:       }
 156:     else
 157:       throw new TypeMismatch();
 158:   }
 159: 
 160:   /*
 161:    * Set the contenst of the sequence, resizing if required.
 162:    */
 163:   public void set_elements_as_dyn_any(DynAny[] value)
 164:                                throws InvalidValue, TypeMismatch
 165:   {
 166:     checkBound(value.length);
 167:     if (array.length != value.length)
 168:       set_length(value.length);
 169: 
 170:     for (int i = 0; i < value.length; i++)
 171:       {
 172:         checkType(official_components, value [ i ].type());
 173:         array [ i ].assign(value [ i ]);
 174:       }
 175:     valueChanged();
 176:   }
 177: 
 178:   /**
 179:    * Set the elements from array of Any's.
 180:    */
 181:   public void set_elements(Any[] value)
 182:                     throws InvalidValue, TypeMismatch
 183:   {
 184:     checkBound(value.length);
 185: 
 186:     DynAny[] prev = array;
 187: 
 188:     array = new DynAny[ value.length ];
 189:     try
 190:       {
 191:         super.set_elements(value);
 192: 
 193:         // valueChanged() is called in super.set_elements(value).
 194:       }
 195: 
 196:     // On the problem, value does not change.
 197:     catch (TypeMismatch ex)
 198:       {
 199:         array = prev;
 200:         throw ex;
 201:       }
 202:     catch (InvalidValue ex)
 203:       {
 204:         array = prev;
 205:         throw ex;
 206:       }
 207:     catch (RuntimeException rex)
 208:       {
 209:         array = prev;
 210:         throw rex;
 211:       }
 212:   }
 213: 
 214:   /**
 215:    * Create a copy.
 216:    */
 217:   public DynAny copy()
 218:   {
 219:     DynAny[] c = new DynAny[ array.length ];
 220:     for (int i = 0; i < c.length; i++)
 221:       {
 222:         c [ i ] = array [ i ].copy();
 223:       }
 224: 
 225:     gnuDynSequence d =
 226:       new gnuDynSequence(official_type, final_type, factory, orb);
 227:     d.array = c;
 228:     return d;
 229:   }
 230: 
 231:   /**
 232:    * Check the bound.
 233:    *
 234:    * @param x the value to check.
 235:    */
 236:   void checkBound(int x)
 237:            throws InvalidValue
 238:   {
 239:     if (bound != 0)
 240:       if (x < 0 || x > bound)
 241:         throw new InvalidValue(x + " out of bounds, valid [0.." + bound + "]");
 242:   }
 243: 
 244:   /**
 245:    * Check if array size is valid. Called from from_any.
 246:    */
 247:   protected void checkArrayValid(Object members)
 248:                           throws TypeMismatch, InvalidValue
 249:   {
 250:     checkBound(Array.getLength(members));
 251:     if (get_length() != Array.getLength(members))
 252:       set_length(Array.getLength(members));
 253:   }
 254: }