OSDN Git Service

Normalise whitespace in GNU Classpath.
[pf3gnuchains/gcc-fork.git] / libjava / classpath / gnu / CORBA / gnuAny.java
1 /* gnuAny.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;
40
41 import gnu.CORBA.CDR.Vio;
42 import gnu.CORBA.CDR.BufferredCdrInput;
43 import gnu.CORBA.CDR.BufferedCdrOutput;
44 import gnu.CORBA.typecodes.PrimitiveTypeCode;
45 import gnu.CORBA.typecodes.StringTypeCode;
46
47 import org.omg.CORBA.Any;
48 import org.omg.CORBA.AnyHolder;
49 import org.omg.CORBA.BAD_OPERATION;
50 import org.omg.CORBA.BooleanHolder;
51 import org.omg.CORBA.CharHolder;
52 import org.omg.CORBA.DoubleHolder;
53 import org.omg.CORBA.FixedHolder;
54 import org.omg.CORBA.FloatHolder;
55 import org.omg.CORBA.IntHolder;
56 import org.omg.CORBA.LongHolder;
57 import org.omg.CORBA.MARSHAL;
58 import org.omg.CORBA.ORB;
59 import org.omg.CORBA.ObjectHolder;
60 import org.omg.CORBA.Principal;
61 import org.omg.CORBA.PrincipalHolder;
62 import org.omg.CORBA.ShortHolder;
63 import org.omg.CORBA.StringHolder;
64 import org.omg.CORBA.TCKind;
65 import org.omg.CORBA.TypeCode;
66 import org.omg.CORBA.TypeCodeHolder;
67 import org.omg.CORBA.ValueBaseHolder;
68 import org.omg.CORBA.portable.Streamable;
69
70 import java.io.Serializable;
71 import java.lang.reflect.Field;
72 import java.math.BigDecimal;
73 import java.util.Arrays;
74 import java.util.zip.Adler32;
75
76 /**
77  * The implementation of {@link Any}.
78  *
79  * For performance reasonse, the inserted values are not cloned.
80  * If the value object allows modifications (like {@link Streamable}),
81  * these subsequent alterations are reflected by the instance of
82  * this gnuAny, and the gnuAny alterations are reflected by the
83  * returned value. If it is required to have the uncoupled value,
84  * it must be requested from the copy of the current instance.
85  * The {@link gnuAny} can be simply cloned by the provided
86  * {@link Clone()} method.
87  *
88  * @author Audrius Meskauskas (AudriusA@Bioinformatics.org)
89  */
90 public class gnuAny
91   extends Any
92 {
93   /**
94    * Use serialVersionUID for interoperability.
95    */
96   private static final long serialVersionUID = 1;
97
98   /**
99    * The value, returned by {@link #type()} if the value has been
100    * not intialized.
101    */
102   protected static final TypeCode nullType =
103     new PrimitiveTypeCode(TCKind.tk_null);
104
105   /**
106    * The Streamable, representing the value, held by this gnuAny.
107    */
108   protected Streamable has;
109
110   /**
111    * The complete typecode of the Streamable, if explicitly set.
112    */
113   protected TypeCode typecode;
114
115   /**
116    * The typecode kind of the Streamable, if explicitly set.
117    */
118   protected int xKind = -1;
119
120   /**
121    * The associated ORB.
122    */
123   private ORB orb;
124
125   /**
126    * Set the associated orb.
127    */
128   public void setOrb(ORB an_orb)
129   {
130     orb = an_orb;
131   }
132
133   /**
134    * Creates a deep copy of this gnuAny, writing to and subsequently
135    * reading from from the byte buffer.
136    *
137    * @return the uncoupled gnuAny with all fields set to identical
138    * values.
139    */
140   public gnuAny Clone()
141   {
142     BufferedCdrOutput out = new BufferedCdrOutput();
143     out.setOrb(orb);
144     out.write_any(this);
145
146     BufferredCdrInput in = new BufferredCdrInput(out.buffer.toByteArray());
147     in.setOrb(orb);
148     return (gnuAny) in.read_any();
149   }
150
151   /**
152    * Create the buffered CDR input stream, containing the
153    * value, stored inside of this {@link Any}.
154    */
155   public org.omg.CORBA.portable.InputStream create_input_stream()
156   {
157     if (has instanceof GeneralHolder)
158       {
159         GeneralHolder u = (GeneralHolder) has;
160         return u.getInputStream();
161       }
162     else
163       {
164         BufferedCdrOutput out = new BufferedCdrOutput();
165         out.setOrb(orb);
166         write_value(out);
167
168         BufferredCdrInput in = new BufferredCdrInput(out.buffer.toByteArray());
169         in.setOrb(orb);
170         return in;
171       }
172   }
173
174   /**
175    * Create the buffered CDR output stream (empty).
176    */
177   public org.omg.CORBA.portable.OutputStream create_output_stream()
178   {
179     BufferedCdrOutput stream = new BufferedCdrOutput();
180     stream.setOrb(orb);
181     return stream;
182   }
183
184   /**
185    * Compare two Any's for equality.
186    * @param other the other Any to compare.
187    */
188   public boolean equal(Any other)
189   {
190     if (other == this)
191       return true;
192     if (type().kind() != other.type().kind())
193       return false;
194
195     if (has != null && other instanceof gnuAny)
196       if (has.equals(((gnuAny) other).has))
197         return true;
198
199     BufferedCdrOutput a = new BufferedCdrOutput();
200     a.setOrb(orb);
201     write_value(a);
202
203     BufferedCdrOutput b = new BufferedCdrOutput();
204     b.setOrb(orb);
205     other.write_value(b);
206
207     byte[] ba = a.buffer.toByteArray();
208     byte[] bb = b.buffer.toByteArray();
209
210     return Arrays.equals(ba, bb);
211   }
212
213   /**
214    * Get the content - dependent hashcode.
215    */
216   public int hashCode()
217   {
218     if (has == null)
219       return type().kind().value();
220     else
221       {
222         Adler32 adler = new Adler32();
223
224         BufferedCdrOutput a = new BufferedCdrOutput();
225         a.setOrb(orb);
226         write_value(a);
227
228         adler.update(a.buffer.toByteArray());
229         adler.update(type().kind().value());
230
231         return (int) adler.getValue() & Integer.MAX_VALUE;
232       }
233   }
234
235   /**
236    * Delegates functionality to {@link #equal(Any)}.
237    */
238   public boolean equals(java.lang.Object other)
239   {
240     if (other == this)
241       return true;
242     if (!(other instanceof Any))
243       return false;
244
245     return equal((Any) other);
246   }
247
248   /**
249    * Extract the previously stored object.
250    */
251   public org.omg.CORBA.Object extract_Object()
252   {
253     try
254       {
255         return ((ObjectHolder) has).value;
256       }
257     catch (ClassCastException ex)
258       {
259         BAD_OPERATION bad = new BAD_OPERATION();
260         bad.initCause(ex);
261         bad.minor = Minor.Any;
262         throw bad;
263       }
264   }
265
266   /**
267    * Extract the previously inserted CORBA <code>Principal</code>/
268    * @return the previously inserted value.
269    *
270    * @throws org.omg.CORBA.BAD_OPERATION if the holder contains something
271    * else than Principal.
272    *
273    * @deprecated by CORBA 2.2.
274    */
275   public Principal extract_Principal()
276   {
277     check(TCKind._tk_Principal);
278     return ((PrincipalHolder) has).value;
279   }
280
281   /**
282    * Return the value, encapsulated in a suitable holder.
283    * This implementation returns the direct reference,
284    * so the alterations on the returned streamable are
285    * directly reflected to the content of this {@link Any}.
286    */
287   public Streamable extract_Streamable()
288   {
289     return has;
290   }
291
292   public TypeCode extract_TypeCode()
293                             throws BAD_OPERATION
294   {
295     check(TCKind._tk_TypeCode);
296     return ((TypeCodeHolder) has).value;
297   }
298
299   /**
300    * Extract the stored value type.
301    *
302    * @return the previously stored value type.
303    *
304    * @throws BAD_OPERATION if the Any contains something different.
305    *
306    * @see org.omg.CORBA.portable.ValueBase
307    */
308   public Serializable extract_Value()
309                              throws BAD_OPERATION
310   {
311     try
312       {
313         if (has instanceof ValueBaseHolder)
314           return ((ValueBaseHolder) has).value;
315         else
316           {
317             // Normally, ValueBase holder must be an instance of the
318             // ValueBaseHolder. However some IDL compilers probably
319             // have a bug, do not deriving this way. The the only
320             // way to access the wrapped value is via reflection.
321             Field f = has.getClass().getField("value");
322             return (Serializable) f.get(has);
323           }
324       }
325     catch (Exception ex)
326       {
327         BAD_OPERATION bad = new BAD_OPERATION("Value type expected");
328         bad.minor = Minor.Any;
329         bad.initCause(ex);
330         throw bad;
331       }
332   }
333
334   /** {@inheritDoc} */
335   public Any extract_any()
336                   throws BAD_OPERATION
337   {
338     check(TCKind._tk_any);
339     return ((AnyHolder) has).value;
340   }
341
342   /** {@inheritDoc} */
343   public boolean extract_boolean()
344                           throws BAD_OPERATION
345   {
346     check(TCKind._tk_boolean);
347     return ((BooleanHolder) has).value;
348   }
349
350   /** {@inheritDoc} */
351   public char extract_char()
352                     throws BAD_OPERATION
353   {
354     check(TCKind._tk_char);
355     return ((CharHolder) has).value;
356   }
357
358   /** {@inheritDoc} */
359   public double extract_double()
360                         throws BAD_OPERATION
361   {
362     check(TCKind._tk_double);
363     return ((DoubleHolder) has).value;
364   }
365
366   /**
367    * Extract the previously inserted CORBA <code>fixed</code>/
368    * @return the previously inserted value.
369    *
370    * @throws org.omg.CORBA.BAD_OPERATION if the holder contains something
371    * else than BigDecimal.
372    */
373   public BigDecimal extract_fixed()
374                            throws org.omg.CORBA.BAD_OPERATION
375   {
376     check(TCKind._tk_fixed);
377     return ((FixedHolder) has).value;
378   }
379
380   /** {@inheritDoc} */
381   public float extract_float()
382                       throws BAD_OPERATION
383   {
384     check(TCKind._tk_float);
385     return ((FloatHolder) has).value;
386   }
387
388   /** {@inheritDoc} */
389   public int extract_long()
390                    throws BAD_OPERATION
391   {
392     // CORBA long = java int.
393     check(TCKind._tk_long);
394     return ((IntHolder) has).value;
395   }
396
397   /** {@inheritDoc} */
398   public long extract_longlong()
399                         throws BAD_OPERATION
400   {
401     check(TCKind._tk_longlong);
402     return ((LongHolder) has).value;
403   }
404
405   /** {@inheritDoc} */
406   public byte extract_octet()
407                      throws BAD_OPERATION
408   {
409     // ShortHolder holds also octets.
410     check(TCKind._tk_octet);
411     return (byte) ((OctetHolder) has).value;
412   }
413
414   /** {@inheritDoc} */
415   public short extract_short()
416                       throws BAD_OPERATION
417   {
418     check(TCKind._tk_short);
419     return ((ShortHolder) has).value;
420   }
421
422   /** {@inheritDoc} */
423   public String extract_string()
424                         throws BAD_OPERATION
425   {
426     check(TCKind._tk_string);
427     return ((StringHolder) has).value;
428   }
429
430   /** {@inheritDoc} */
431   public int extract_ulong()
432                     throws BAD_OPERATION
433   {
434     // IntHolder also holds ulongs.
435     check(TCKind._tk_ulong);
436     return ((IntHolder) has).value;
437   }
438
439   /** {@inheritDoc} */
440   public long extract_ulonglong()
441                          throws BAD_OPERATION
442   {
443     // LongHolder also holds ulonglong
444     check(TCKind._tk_ulonglong);
445     return ((LongHolder) has).value;
446   }
447
448   /** {@inheritDoc} */
449   public short extract_ushort()
450                        throws BAD_OPERATION
451   {
452     // ShortHolder also holds ushorts.
453     check(TCKind._tk_ushort);
454     return ((ShortHolder) has).value;
455   }
456
457   /** {@inheritDoc} */
458   public char extract_wchar()
459                      throws BAD_OPERATION
460   {
461     check(TCKind._tk_wchar);
462     return ((WCharHolder) has).value;
463   }
464
465   /** {@inheritDoc} */
466   public String extract_wstring()
467                          throws BAD_OPERATION
468   {
469     // StringHolder also holds wstrings.
470     check(TCKind._tk_wstring);
471     return ((WStringHolder) has).value;
472   }
473
474   /**
475    * Inserts the CORBA object and sets the typecode to the given type.
476    */
477   public void insert_Object(org.omg.CORBA.Object x, TypeCode typecode)
478   {
479     has = new ObjectHolder(x);
480     type(typecode);
481   }
482
483   /**
484    * Inserts the CORBA object.
485    */
486   public void insert_Object(org.omg.CORBA.Object x)
487   {
488     has = new ObjectHolder(x);
489   }
490
491   /**
492    * Insert the CORBA Principal.
493    * This implementation uses direct assignment, so the later
494    * alterations of that BigDecimal are reflected on the
495    * content of this {@link Any}.
496    *
497    * @deprecated by CORBA 2.2.
498    */
499   public void insert_Principal(Principal x)
500   {
501     resetTypes();
502     if (has instanceof PrincipalHolder)
503       ((PrincipalHolder) has).value = x;
504     else
505       has = new PrincipalHolder(x);
506   }
507
508   /**
509    * Sets the value to the value, encapsulated in this holder.
510    * This implementation uses direct assignment, so the later
511    * alterations of that streamable are reflected on the
512    * content of this {@link Any}.
513    */
514   public void insert_Streamable(Streamable x)
515   {
516     resetTypes();
517     has = x;
518   }
519
520   /**
521    * Insert the typecode into this Any
522    * @param typecode the typecode to insert.
523    */
524   public void insert_TypeCode(TypeCode typecode)
525   {
526     resetTypes();
527     if (has instanceof TypeCodeHolder)
528       ((TypeCodeHolder) has).value = typecode;
529     else
530       has = new TypeCodeHolder(typecode);
531   }
532
533   /** {@inheritDoc} */
534   public void insert_Value(Serializable x, TypeCode c_typecode)
535   {
536     if (typecode != null && typecode.kind() == TCKind.tk_value_box)
537       {
538         has = new gnuValueHolder(x, typecode);
539       }
540     else
541       {
542         type(typecode);
543         insert_Value(x);
544       }
545   }
546
547   /** {@inheritDoc} */
548   public void insert_Value(Serializable x)
549   {
550     if (typecode != null && typecode.kind() == TCKind.tk_value_box)
551       {
552         has = new gnuValueHolder(x, typecode);
553       }
554     else
555       {
556         if (has instanceof ValueBaseHolder)
557           ((ValueBaseHolder) has).value = x;
558         else
559           has = new ValueBaseHolder(x);
560       }
561   }
562
563   /**
564   * Insert another {@link Any} into this {@link Any}.
565   * This implementation uses direct assignment, so the later
566   * alterations of that {@link Any} are reflected on the
567   * content of this {@link Any}.
568   */
569   public void insert_any(Any an_any)
570   {
571     resetTypes();
572     if (has instanceof AnyHolder)
573       ((AnyHolder) has).value = an_any;
574     else
575       has = new AnyHolder(an_any);
576   }
577
578   /** {@inheritDoc} */
579   public void insert_boolean(boolean x)
580   {
581     resetTypes();
582     if (has instanceof BooleanHolder)
583       ((BooleanHolder) has).value = x;
584     else
585       has = new BooleanHolder(x);
586   }
587
588   /** {@inheritDoc} */
589   public void insert_char(char x)
590   {
591     resetTypes();
592     if (has instanceof CharHolder)
593       ((CharHolder) has).value = x;
594     else
595       has = new CharHolder(x);
596   }
597
598   /** {@inheritDoc} */
599   public void insert_double(double x)
600   {
601     resetTypes();
602     if (has instanceof DoubleHolder)
603       ((DoubleHolder) has).value = x;
604     else
605       has = new DoubleHolder(x);
606   }
607
608   /**
609    * Inserts the CORBA <code>fixed</code>, setting the typecode
610    * explicitly.
611    * This implementation uses direct assignment, so the later
612    * alterations of that BigDecimal are reflected on the
613    * content of this {@link Any}.
614    */
615   public void insert_fixed(BigDecimal x, TypeCode x_typecode)
616   {
617     resetTypes();
618     insert_fixed(x);
619     typecode = x_typecode;
620   }
621
622   /**
623    * Inserts the CORBA <code>fixed</code>, setting the typecode
624    * by example of the currently passed value.
625    * This implementation uses direct assignment, so the later
626    * alterations of that BigDecimal are reflected on the
627    * content of this {@link Any}, including the typecode.
628    */
629   public void insert_fixed(BigDecimal x)
630   {
631     resetTypes();
632     if (has instanceof FixedHolder)
633       ((FixedHolder) has).value = x;
634     else
635       has = new FixedHolder(x);
636   }
637
638   /** {@inheritDoc} */
639   public void insert_float(float x)
640   {
641     resetTypes();
642     if (has instanceof FloatHolder)
643       ((FloatHolder) has).value = x;
644     else
645       has = new FloatHolder(x);
646   }
647
648   /** {@inheritDoc} */
649   public void insert_long(int x)
650   {
651     resetTypes();
652     if (has instanceof IntHolder)
653       ((IntHolder) has).value = x;
654     else
655       has = new IntHolder(x);
656   }
657
658   /** {@inheritDoc} */
659   public void insert_longlong(long x)
660   {
661     resetTypes();
662     if (has instanceof LongHolder)
663       ((LongHolder) has).value = x;
664     else
665       has = new LongHolder(x);
666   }
667
668   /** {@inheritDoc} */
669   public void insert_octet(byte x)
670   {
671     resetTypes();
672     if (has instanceof OctetHolder)
673       ((OctetHolder) has).value = x;
674     else
675       has = new OctetHolder(x);
676   }
677
678   /** {@inheritDoc} */
679   public void insert_short(short x)
680   {
681     resetTypes();
682     if (has instanceof ShortHolder)
683       ((ShortHolder) has).value = x;
684     else
685       has = new ShortHolder(x);
686   }
687
688   /** {@inheritDoc} */
689   public void insert_string(String x)
690   {
691     resetTypes();
692     if (has instanceof StringHolder)
693       ((StringHolder) has).value = x;
694     else
695       has = new StringHolder(x);
696
697     typecode = new StringTypeCode(TCKind.tk_string);
698   }
699
700   /** {@inheritDoc} */
701   public void insert_ulong(int x)
702   {
703     resetTypes();
704     if (has instanceof IntHolder)
705       ((IntHolder) has).value = x;
706     else
707       has = new IntHolder(x);
708     xKind = TCKind._tk_ulong;
709   }
710
711   /** {@inheritDoc} */
712   public void insert_ulonglong(long x)
713   {
714     resetTypes();
715     if (has instanceof LongHolder)
716       ((LongHolder) has).value = x;
717     else
718       has = new LongHolder(x);
719     xKind = TCKind._tk_ulonglong;
720   }
721
722   /** {@inheritDoc} */
723   public void insert_ushort(short x)
724   {
725     resetTypes();
726     if (has instanceof ShortHolder)
727       ((ShortHolder) has).value = x;
728     else
729       has = new ShortHolder(x);
730     xKind = TCKind._tk_ushort;
731   }
732
733   /** {@inheritDoc} */
734   public void insert_wchar(char x)
735   {
736     resetTypes();
737     if (has instanceof WCharHolder)
738       ((WCharHolder) has).value = x;
739     else
740       has = new WCharHolder(x);
741   }
742
743   /** {@inheritDoc} */
744   public void insert_wstring(String x)
745   {
746     resetTypes();
747     if (has instanceof WStringHolder)
748       ((WStringHolder) has).value = x;
749     else
750       has = new WStringHolder(x);
751   }
752
753   /**
754    * Return the associated orb.
755    */
756   public ORB orb()
757   {
758     return orb;
759   }
760
761   /**
762    * Read the value of the given type from the given stream.
763    *
764    * @param input a stream to read from.
765    * @param a_type a typecode of the value to read.
766    */
767   public void read_value(org.omg.CORBA.portable.InputStream input,
768                          TypeCode a_type
769                         )
770                   throws MARSHAL
771   {
772     try
773       {
774         int kind = a_type.kind().value();
775
776         // Fixed needs special handling.
777         if (kind == TCKind._tk_fixed)
778           {
779             BigDecimal dec = BigDecimalHelper.read(input, a_type.fixed_scale());
780             has = new FixedHolder(dec);
781           }
782         else
783           {
784             has = HolderLocator.createHolder(a_type);
785             if (has == null)
786               {
787                 // Use the Universal Holder that reads till the end of stream.
788                 // This works with the extract/insert pair of the typical
789                 // Helper.
790                 BufferedCdrOutput buffer = new BufferedCdrOutput();
791                 buffer.setOrb(orb);
792                 has = new GeneralHolder(buffer);
793               }
794           }
795         type(a_type);
796
797         if (!(has instanceof GeneralHolder) &&
798             (kind == TCKind._tk_value_box))
799           {
800             // The streamable only contains operations for
801             // reading the value, not the value header.
802             Field vField = has.getClass().getField("value");
803
804             Object content = Vio.read(input, a_type.id());
805             vField.set(has, content);
806           }
807         else
808           has._read(input);
809       }
810     catch (Exception ex)
811       {
812         MARSHAL m = new MARSHAL();
813         m.minor = Minor.Any;
814         m.initCause(ex);
815         throw m;
816       }
817   }
818
819   /** {@inheritDoc} */
820   public TypeCode type()
821   {
822     if (typecode != null)
823       return typecode;
824     else if (xKind >= 0)
825       {
826         typecode = new PrimitiveTypeCode(TCKind.from_int(xKind));
827         return typecode;
828       }
829     else
830       return has != null ? has._type() : nullType;
831   }
832
833   /**
834    * Explicitly set the typecode of the value to the given type.
835    *
836    * @param valueTypeCode the typecode of the value.
837    */
838   public void type(TypeCode valueTypeCode)
839   {
840     xKind = valueTypeCode.kind().value();
841     typecode = valueTypeCode;
842   }
843
844   /** {@inheritDoc} */
845   public void write_value(org.omg.CORBA.portable.OutputStream output)
846   {
847     if (has != null)
848       has._write(output);
849     else
850     // These kinds support null.
851     if (xKind == TCKind._tk_null || xKind == TCKind._tk_objref ||
852         xKind == TCKind._tk_value || xKind == TCKind._tk_value_box
853        )
854       output.write_long(0);
855   }
856
857   /**
858    * Check if the current value if the value of the given kind.
859    *
860    * @param kind a kind to check.
861    * @throws BAD_OPERATION if the value is not set of is different kind.
862    */
863   protected void check(int kind)
864     throws BAD_OPERATION
865   {
866     if (has == null)
867       {
868         BAD_OPERATION bad = new BAD_OPERATION("value not set");
869         bad.minor = Minor.Any;
870         throw bad;
871       }
872
873     if (xKind >= 0)
874       {
875         if (xKind != kind)
876           if (!(xKind == TCKind._tk_alias && has._type().kind().value() == kind))
877             {
878               BAD_OPERATION bad = new BAD_OPERATION("Extracting "
879                 + TypeKindNamer.nameIt(kind) + " when stored "
880                 + TypeKindNamer.nameIt(xKind));
881               bad.minor = Minor.Any;
882               throw bad;
883             }
884       }
885     else
886       {
887         if (type().kind().value() != kind)
888           if (!(type().kind().value() == TCKind._tk_alias && has._type().kind().value() == kind))
889             {
890               BAD_OPERATION bad = new BAD_OPERATION("Extracting "
891                 + TypeKindNamer.nameIt(kind) + " stored "
892                 + TypeKindNamer.nameIt(type()));
893               bad.minor = Minor.Any;
894               throw bad;
895             }
896       }
897   }
898
899   /**
900    * Clear the additional type information before reusing this instance.
901    */
902   private final void resetTypes()
903   {
904     typecode = null;
905     xKind = -1;
906   }
907 }