Source for gnu.CORBA.DynAn.gnuDynFixed

   1: /* gnuDynFixed.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 org.omg.CORBA.Any;
  42: import org.omg.CORBA.BAD_OPERATION;
  43: import org.omg.CORBA.BAD_PARAM;
  44: import org.omg.CORBA.ORB;
  45: import org.omg.CORBA.TypeCode;
  46: import org.omg.DynamicAny.DynAny;
  47: import org.omg.DynamicAny.DynAnyPackage.InvalidValue;
  48: import org.omg.DynamicAny.DynAnyPackage.TypeMismatch;
  49: import org.omg.DynamicAny.DynFixed;
  50: import org.omg.DynamicAny.DynFixedOperations;
  51: 
  52: import java.math.BigDecimal;
  53: 
  54: /**
  55:  * Implements DynAny, holding CORBA <code>fixed</code>. This class is derived
  56:  * from gnuDynEnm to avoid repetetive inclusion of unused DynAny methods.
  57:  *
  58:  * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org)
  59:  */
  60: public class gnuDynFixed extends UndivideableAny implements DynFixed
  61: {
  62:   /**
  63:    * Use serialVersionUID for interoperability.
  64:    */
  65:   private static final long serialVersionUID = 1;
  66: 
  67:   /**
  68:    * The default value, assigned in the new instance.
  69:    */
  70:   static final BigDecimal ZERO = new BigDecimal("0.0");
  71: 
  72:   /**
  73:    * The content of the dyn fixed, wrapped in this DynAny.
  74:    */
  75:   BigDecimal value;
  76: 
  77:   /**
  78:    * The number of digits after the decimal point.
  79:    */
  80:   final int scale;
  81: 
  82:   /**
  83:    * The number of digits.
  84:    */
  85:   final int digits;
  86: 
  87:   /**
  88:    * Create a new instance of the dyn fixed.
  89:    */
  90:   public gnuDynFixed(TypeCode oType, TypeCode aType,
  91:     gnuDynAnyFactory aFactory, ORB anOrb
  92:   )
  93:   {
  94:     super(oType, aType, aFactory, anOrb);
  95:     try
  96:       {
  97:         digits = final_type.fixed_digits();
  98:         scale = final_type.fixed_scale();
  99:       }
 100:     catch (Exception e)
 101:       {
 102:         throw new BAD_PARAM("Not a fixed");
 103:       }
 104:     value = ZERO;
 105:   }
 106: 
 107:   /**
 108:    * Clone the current instance.
 109:    */
 110:   public gnuDynFixed(gnuDynFixed from)
 111:   {
 112:     super(from.official_type, from.final_type, from.factory, from.orb);
 113:     digits = from.digits;
 114:     scale = from.scale;
 115:     value = from.value;
 116:   }
 117: 
 118:   /**
 119:    * Get the value of the wrapped dyn fixed, as string.
 120:    */
 121:   public String get_value()
 122:   {
 123:     return value.toString();
 124:   }
 125: 
 126:   /**
 127:    * Set the value.
 128:    */
 129:   public boolean set_value(String fixed_value)
 130:     throws TypeMismatch, InvalidValue
 131:   {
 132:     // Count the digits till decimal point.
 133:     int digs = 0;
 134:     char c;
 135:     boolean leading0 = true;
 136:     Digs:
 137:     for (int i = 0; i < fixed_value.length(); i++)
 138:       {
 139:         c = fixed_value.charAt(i);
 140:         if (Character.isDigit(c))
 141:           {
 142:             if (!(c == '0' && leading0))
 143:               digs++;
 144:             if (c != '0')
 145:               leading0 = false;
 146:           }
 147:         else if (c == '.')
 148:           break Digs;
 149:       }
 150:     if (digs > (digits - scale))
 151:       throw new InvalidValue("Too many digits: " + digs + " for " + digits +
 152:         "." + scale
 153:       );
 154: 
 155:     try
 156:       {
 157:         value = new BigDecimal(fixed_value);
 158:       }
 159:     catch (NumberFormatException ex)
 160:       {
 161:         if (fixed_value.trim().length() == 0)
 162:           throw new InvalidValue("Empty string passed");
 163: 
 164:         TypeMismatch inva =
 165:           new TypeMismatch("Not a number: '" + fixed_value + "'");
 166:         inva.initCause(ex);
 167:         throw inva;
 168:       }
 169: 
 170:     valueChanged();
 171:     return value.scale() <= scale;
 172:   }
 173: 
 174:   /**
 175:    * Assign the value from another BigDecimal.
 176:    */
 177:   public void assign(DynAny from) throws TypeMismatch
 178:   {
 179:     checkType(official_type, from.type());
 180: 
 181:     if (from instanceof gnuDynFixed)
 182:       {
 183:         gnuDynFixed other = (gnuDynFixed) from;
 184:         value = other.value;
 185:       }
 186:     else if (from instanceof DynFixedOperations)
 187:       {
 188:         value = new BigDecimal(((DynFixedOperations) from).get_value());
 189:       }
 190:     else
 191:       throw new TypeMismatch("Not a DynFixed");
 192:     valueChanged();
 193:   }
 194: 
 195:   /**
 196:    * Create a copy.
 197:    */
 198:   public DynAny copy()
 199:   {
 200:     return new gnuDynFixed(this);
 201:   }
 202: 
 203:   /**
 204:    * Compare for equality.
 205:    */
 206:   public boolean equal(DynAny other)
 207:   {
 208:     if (other instanceof gnuDynFixed)
 209:       {
 210:         // Normally, this code would be executed.
 211:         return value.equals(((gnuDynFixed) other).value);
 212:       }
 213:     if (other instanceof DynFixedOperations)
 214:       {
 215:         // This may be involved when mixing implementations.
 216:         return ((DynFixedOperations) other).get_value().equals(get_value());
 217:       }
 218:     else
 219:       return false;
 220:   }
 221: 
 222:   /**
 223:    * Set the value from Any (must hold <code>fixed</code> with the matching
 224:    * typecode.).
 225:    */
 226:   public void from_any(Any an_any) throws TypeMismatch, InvalidValue
 227:   {
 228:     try
 229:       {
 230:         checkType(official_type, an_any.type());
 231: 
 232:         value = an_any.extract_fixed();
 233:         valueChanged();
 234:       }
 235:     catch (BAD_OPERATION e)
 236:       {
 237:         InvalidValue t = new InvalidValue();
 238:         t.initCause(e);
 239:         throw t;
 240:       }
 241:   }
 242: 
 243:   /**
 244:    * Create and return Any, holding this DynFixed value.
 245:    */
 246:   public Any to_any()
 247:   {
 248:     Any g = createAny();
 249:     g.insert_fixed(value, official_type);
 250:     return g;
 251:   }
 252: }