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 10 public class CastAs extends Convert 11 { 12 public static final CastAs castAs = new CastAs(); 13 14 public Object apply2 (Object arg1, Object arg2) 15 { 16 Type type = (Type) arg1; 17 if (type instanceof XDataType) 18 return ((XDataType) type).cast(arg2); 19 if (type instanceof OccurrenceType) 20 { 21 OccurrenceType occ = (OccurrenceType) type; 22 Type base = occ.getBase(); 23 if (base instanceof XDataType) 24 { 25 int min = occ.minOccurs(); 26 int max = occ.maxOccurs(); 27 if (arg2 instanceof Values) 28 { 29 if (arg2 == Values.empty && min == 0) 30 return arg2; 31 Values vals = (Values) arg2; 32 int pos = vals.startPos(); 33 int n = 0; 34 Values result = new Values(); 35 for (;;) 36 { 37 pos = vals.nextPos(pos); 38 if (pos == 0) 39 { 40 if (n >= min && (max < 0 || n <= max)) 41 return result.canonicalize(); 42 break; 43 } 44 Object value = vals.getPosPrevious(pos); 45 value = ((XDataType) base).cast(value); 46 result.writeObject(value); 47 n++; 48 } 49 } 50 else 51 { 52 if (min <= 1 && max != 0) 53 return ((XDataType) base).cast(arg2); 54 } 55 throw new ClassCastException ("cannot cast "+arg2 56 +" to "+arg1); 57 } 58 } 59 return super.apply2(arg1, arg2); 60 } 61 62 static final ClassType typeXDataType = 63 ClassType.make("gnu.kawa.xml.XDataType"); 64 static final Method castMethod = typeXDataType.getDeclaredMethod("cast", 1); 65 66 public Expression inline (ApplyExp exp, ExpWalker walker) 67 { 68 exp = Invoke.inlineClassName(exp, 0, (InlineCalls) walker); 69 Expression[] args = exp.getArgs(); 70 if (args.length != 2 || ! (args[0] instanceof QuoteExp)) 71 return exp; 72 Object type = ((QuoteExp) args[0]).getValue(); 73 if (type instanceof XDataType) 74 { 75 XDataType xtype = (XDataType) type; 76 return new ApplyExp(castMethod, args); 77 } 78 return exp; 79 } 80 81 public void compile (ApplyExp exp, Compilation comp, Target target) 82 { 83 ApplyExp.compile(exp, comp, target); 84 } 85 } 86 | Popular Tags |