Ejemplo n.º 1
0
  protected List<Object> readArray(XMLStreamReader parser) throws XMLStreamException {
    if (XMLStreamConstants.START_ELEMENT != parser.getEventType()) {
      throw new RuntimeException("must be start element, not: " + parser.getEventType());
    }
    if (!"arr".equals(parser.getLocalName().toLowerCase(Locale.ENGLISH))) {
      throw new RuntimeException("must be 'arr', not: " + parser.getLocalName());
    }

    StringBuilder builder = new StringBuilder();
    KnownType type = null;

    List<Object> vals = new ArrayList<Object>();

    int depth = 0;
    while (true) {
      switch (parser.next()) {
        case XMLStreamConstants.START_ELEMENT:
          depth++;
          KnownType t = KnownType.get(parser.getLocalName());
          if (t == null) {
            throw new RuntimeException("this must be known type! not: " + parser.getLocalName());
          }
          if (type == null) {
            type = t;
          }
          /**
           * * actually, there is no rule that arrays need the same type else if( type != t && !(t
           * == KnownType.NULL || type == KnownType.NULL)) { throw new RuntimeException( "arrays
           * must have the same type! ("+type+"!="+t+") "+parser.getLocalName() ); } *
           */
          type = t;

          builder.setLength(0); // reset the text

          if (!type.isLeaf) {
            switch (type) {
              case LST:
                vals.add(readNamedList(parser));
                depth--;
                continue;
              case ARR:
                vals.add(readArray(parser));
                depth--;
                continue;
              case RESULT:
                vals.add(readDocuments(parser));
                depth--;
                continue;
              case DOC:
                vals.add(readDocument(parser));
                depth--;
                continue;
            }
            throw new XMLStreamException("branch element not handled!", parser.getLocation());
          }
          break;

        case XMLStreamConstants.END_ELEMENT:
          if (--depth < 0) {
            return vals; // the last element is itself
          }
          // System.out.println( "ARR:"+type+"::"+builder );
          Object val = type.read(builder.toString().trim());
          if (val == null && type != KnownType.NULL) {
            throw new XMLStreamException("error reading value:" + type, parser.getLocation());
          }
          vals.add(val);
          break;

        case XMLStreamConstants
            .SPACE: // TODO?  should this be trimmed? make sure it only gets one/two space?
        case XMLStreamConstants.CDATA:
        case XMLStreamConstants.CHARACTERS:
          builder.append(parser.getText());
          break;
      }
    }
  }
Ejemplo n.º 2
0
  protected SolrDocument readDocument(XMLStreamReader parser) throws XMLStreamException {
    if (XMLStreamConstants.START_ELEMENT != parser.getEventType()) {
      throw new RuntimeException("must be start element, not: " + parser.getEventType());
    }
    if (!"doc".equals(parser.getLocalName().toLowerCase(Locale.ENGLISH))) {
      throw new RuntimeException("must be 'lst', not: " + parser.getLocalName());
    }

    SolrDocument doc = new SolrDocument();
    StringBuilder builder = new StringBuilder();
    KnownType type = null;
    String name = null;

    // just eat up the events...
    int depth = 0;
    while (true) {
      switch (parser.next()) {
        case XMLStreamConstants.START_ELEMENT:
          depth++;
          builder.setLength(0); // reset the text
          type = KnownType.get(parser.getLocalName());
          if (type == null) {
            throw new RuntimeException("this must be known type! not: " + parser.getLocalName());
          }

          name = null;
          int cnt = parser.getAttributeCount();
          for (int i = 0; i < cnt; i++) {
            if ("name".equals(parser.getAttributeLocalName(i))) {
              name = parser.getAttributeValue(i);
              break;
            }
          }

          if (name == null) {
            throw new XMLStreamException(
                "requires 'name' attribute: " + parser.getLocalName(), parser.getLocation());
          }

          // Handle multi-valued fields
          if (type == KnownType.ARR) {
            for (Object val : readArray(parser)) {
              doc.addField(name, val);
            }
            depth--; // the array reading clears out the 'endElement'
          } else if (!type.isLeaf) {
            throw new XMLStreamException("must be value or array", parser.getLocation());
          }
          break;

        case XMLStreamConstants.END_ELEMENT:
          if (--depth < 0) {
            return doc;
          }
          // System.out.println( "FIELD:"+type+"::"+name+"::"+builder );
          Object val = type.read(builder.toString().trim());
          if (val == null) {
            throw new XMLStreamException("error reading value:" + type, parser.getLocation());
          }
          doc.addField(name, val);
          break;

        case XMLStreamConstants
            .SPACE: // TODO?  should this be trimmed? make sure it only gets one/two space?
        case XMLStreamConstants.CDATA:
        case XMLStreamConstants.CHARACTERS:
          builder.append(parser.getText());
          break;
      }
    }
  }
Ejemplo n.º 3
0
  protected NamedList<Object> readNamedList(XMLStreamReader parser) throws XMLStreamException {
    if (XMLStreamConstants.START_ELEMENT != parser.getEventType()) {
      throw new RuntimeException("must be start element, not: " + parser.getEventType());
    }

    StringBuilder builder = new StringBuilder();
    NamedList<Object> nl = new SimpleOrderedMap<Object>();
    KnownType type = null;
    String name = null;

    // just eat up the events...
    int depth = 0;
    while (true) {
      switch (parser.next()) {
        case XMLStreamConstants.START_ELEMENT:
          depth++;
          builder.setLength(0); // reset the text
          type = KnownType.get(parser.getLocalName());
          if (type == null) {
            throw new RuntimeException("this must be known type! not: " + parser.getLocalName());
          }

          name = null;
          int cnt = parser.getAttributeCount();
          for (int i = 0; i < cnt; i++) {
            if ("name".equals(parser.getAttributeLocalName(i))) {
              name = parser.getAttributeValue(i);
              break;
            }
          }

          /**
           * The name in a NamedList can actually be null if( name == null ) { throw new
           * XMLStreamException( "requires 'name' attribute: "+parser.getLocalName(),
           * parser.getLocation() ); }
           */
          if (!type.isLeaf) {
            switch (type) {
              case LST:
                nl.add(name, readNamedList(parser));
                depth--;
                continue;
              case ARR:
                nl.add(name, readArray(parser));
                depth--;
                continue;
              case RESULT:
                nl.add(name, readDocuments(parser));
                depth--;
                continue;
              case DOC:
                nl.add(name, readDocument(parser));
                depth--;
                continue;
            }
            throw new XMLStreamException("branch element not handled!", parser.getLocation());
          }
          break;

        case XMLStreamConstants.END_ELEMENT:
          if (--depth < 0) {
            return nl;
          }
          // System.out.println( "NL:ELEM:"+type+"::"+name+"::"+builder );
          nl.add(name, type.read(builder.toString().trim()));
          break;

        case XMLStreamConstants
            .SPACE: // TODO?  should this be trimmed? make sure it only gets one/two space?
        case XMLStreamConstants.CDATA:
        case XMLStreamConstants.CHARACTERS:
          builder.append(parser.getText());
          break;
      }
    }
  }