CastAs.java 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. package gnu.xquery.util;
  2. import gnu.kawa.functions.Convert;
  3. import gnu.bytecode.*;
  4. import gnu.expr.*;
  5. import gnu.kawa.xml.*;
  6. import gnu.kawa.reflect.Invoke;
  7. import gnu.kawa.reflect.OccurrenceType;
  8. import gnu.mapping.Values;
  9. import gnu.mapping.Procedure;
  10. import java.util.ArrayList;
  11. import java.util.List;
  12. public class CastAs extends Convert
  13. {
  14. public static final CastAs castAs = new CastAs();
  15. public CastAs ()
  16. {
  17. super("cast-as", false);
  18. setProperty(Procedure.validateApplyKey,
  19. "gnu.xquery.util.CompileMisc:validateApplyCastAs");
  20. }
  21. public Object apply2 (Object arg1, Object arg2)
  22. {
  23. Type type = (Type) arg1;
  24. if (type instanceof XDataType)
  25. return ((XDataType) type).cast(arg2);
  26. if (type instanceof OccurrenceType)
  27. {
  28. OccurrenceType occ = (OccurrenceType) type;
  29. Type base = occ.getBase();
  30. if (base instanceof XDataType)
  31. {
  32. int min = occ.minOccurs();
  33. int max = occ.maxOccurs();
  34. if (arg2 instanceof Values)
  35. {
  36. if (arg2 == Values.empty && min == 0)
  37. return arg2;
  38. Values vals = (Values) arg2;
  39. int pos = vals.startPos();
  40. int n = 0;
  41. List lst = new ArrayList();
  42. while ((pos = vals.nextPos(pos)) != 0)
  43. {
  44. Object value = vals.getPosPrevious(pos);
  45. value = ((XDataType) base).cast(value);
  46. lst.add(value);
  47. n++;
  48. }
  49. if (n >= min && (max < 0 || n <= max))
  50. return Values.make(lst);
  51. }
  52. else
  53. {
  54. if (min <= 1 && max != 0)
  55. return ((XDataType) base).cast(arg2);
  56. }
  57. throw new ClassCastException("cannot cast "+arg2
  58. +" to "+arg1);
  59. }
  60. }
  61. return super.apply2(arg1, arg2);
  62. }
  63. public void compile (ApplyExp exp, Compilation comp, Target target)
  64. {
  65. // To override Convert.compile.
  66. ApplyExp.compile(exp, comp, target);
  67. }
  68. }