Ejemplo n.º 1
0
  /**
   * Converts the specified result to an XQuery value.
   *
   * @param obj result object
   * @param qc query context
   * @param sc static context
   * @return value
   * @throws QueryException query exception
   */
  public static Value toValue(final Object obj, final QueryContext qc, final StaticContext sc)
      throws QueryException {

    if (obj == null) return Empty.SEQ;
    if (obj instanceof Value) return (Value) obj;
    if (obj instanceof Iter) return ((Iter) obj).value();
    // find XQuery mapping for specified type
    final Type type = type(obj);
    if (type != null) return type.cast(obj, qc, sc, null);

    // primitive arrays
    if (obj instanceof byte[]) return BytSeq.get((byte[]) obj);
    if (obj instanceof long[]) return IntSeq.get((long[]) obj, AtomType.ITR);
    if (obj instanceof char[]) return Str.get(new String((char[]) obj));
    if (obj instanceof boolean[]) return BlnSeq.get((boolean[]) obj);
    if (obj instanceof double[]) return DblSeq.get((double[]) obj);
    if (obj instanceof float[]) return FltSeq.get((float[]) obj);

    // no array: return Java type
    if (!obj.getClass().isArray()) return new Jav(obj, qc);

    // empty array
    final int s = Array.getLength(obj);
    if (s == 0) return Empty.SEQ;
    // string array
    if (obj instanceof String[]) {
      final String[] r = (String[]) obj;
      final byte[][] b = new byte[r.length][];
      for (int v = 0; v < s; v++) b[v] = token(r[v]);
      return StrSeq.get(b);
    }
    // character array
    if (obj instanceof char[][]) {
      final char[][] r = (char[][]) obj;
      final byte[][] b = new byte[r.length][];
      for (int v = 0; v < s; v++) b[v] = token(new String(r[v]));
      return StrSeq.get(b);
    }
    // short array
    if (obj instanceof short[]) {
      final short[] r = (short[]) obj;
      final long[] b = new long[r.length];
      for (int v = 0; v < s; v++) b[v] = r[v];
      return IntSeq.get(b, AtomType.SHR);
    }
    // integer array
    if (obj instanceof int[]) {
      final int[] r = (int[]) obj;
      final long[] b = new long[r.length];
      for (int v = 0; v < s; v++) b[v] = r[v];
      return IntSeq.get(b, AtomType.INT);
    }
    // any other array (also nested ones)
    final Object[] objs = (Object[]) obj;
    final ValueBuilder vb = new ValueBuilder(objs.length);
    for (final Object o : objs) vb.add(toValue(o, qc, sc));
    return vb.value();
  }
Ejemplo n.º 2
0
  @Override
  public Expr compile(final QueryContext ctx) throws QueryException {
    for (int e = 0; e < expr.length; e++) expr[e] = expr[e].compile(ctx);

    // compute number of results
    size = 0;
    for (final Expr e : expr) {
      final long c = e.size();
      if (c == -1) {
        size = c;
        break;
      }
      size += c;
    }

    // evaluate sequence type
    type = SeqType.EMP;
    Value[] val = new Value[expr.length];
    for (int v = 0; v < expr.length; v++) {
      final Expr e = expr[v];
      // check if all expressions are values
      if (val != null) {
        if (e.isValue()) val[v] = (Value) e;
        else val = null;
      }
      // skip expression that will not add any results
      if (e.isEmpty()) continue;
      // evaluate sequence type
      final SeqType et = e.type();
      type =
          type == SeqType.EMP
              ? et
              : SeqType.get(
                  et.type == type.type ? et.type : AtomType.ITEM,
                  et.mayBeZero() && type.mayBeZero() ? Occ.ZERO_MORE : Occ.ONE_MORE);
    }

    // return cached integer sequence, cached values or self reference
    Expr e = this;
    final int s = (int) size;
    if (val != null && size <= Integer.MAX_VALUE) {
      if (type.type == AtomType.STR) e = StrSeq.get(val, s);
      else if (type.type == AtomType.BLN) e = BlnSeq.get(val, s);
      else if (type.type == AtomType.FLT) e = FltSeq.get(val, s);
      else if (type.type == AtomType.DBL) e = DblSeq.get(val, s);
      else if (type.type == AtomType.DEC) e = DecSeq.get(val, s);
      else if (type.type == AtomType.BYT) e = BytSeq.get(val, s);
      else if (type.type.instanceOf(AtomType.ITR)) e = IntSeq.get(val, s, type.type);
      else {
        final ValueBuilder vb = new ValueBuilder(s);
        for (final Value v : val) vb.add(v);
        e = vb.value();
      }
    }
    return optPre(e, ctx);
  }