package org.odata4j.format.xml; import java.io.Reader; import org.odata4j.core.OCollection; import org.odata4j.core.OCollections; import org.odata4j.core.OComplexObject; import org.odata4j.core.OSimpleObject; import org.odata4j.core.OSimpleObjects; import org.odata4j.edm.EdmCollectionType; import org.odata4j.edm.EdmComplexType; import org.odata4j.edm.EdmDataServices; import org.odata4j.edm.EdmSimpleType; import org.odata4j.edm.EdmType; import org.odata4j.format.FormatParser; import org.odata4j.format.Settings; import org.odata4j.stax2.Attribute2; import org.odata4j.stax2.QName2; import org.odata4j.stax2.StartElement2; import org.odata4j.stax2.XMLEvent2; import org.odata4j.stax2.XMLEventReader2; import org.odata4j.stax2.util.StaxUtil; /** * * Copyright 2013 Halliburton * @author <a href="mailto:peng.chen@halliburton.com">Kevin Chen</a> * */ public class AtomCollectionFormatParser implements FormatParser<OCollection<?>> { private final Settings settings; /** * constructor. * @param setting the parseType should be the itemType of the collection */ public AtomCollectionFormatParser (Settings setting) { EdmType itemType = ((EdmCollectionType)setting.parseType).getItemType(); this.settings = new Settings(setting.version, setting.metadata, setting.entitySetName, setting.entityKey, setting.fcMapping, setting.isResponse, itemType, setting.parseFunction); } /** * Constructor. * @param itemType the collection's item type. * @param md the metadat. * @param isResponse is this a response. not used for now. */ public AtomCollectionFormatParser(EdmType itemType, EdmDataServices md, boolean isResponse) { this.settings = new Settings(null, md, null, null, null, isResponse, itemType); } @SuppressWarnings({ "rawtypes", "unchecked" }) @Override public OCollection<?> parse(Reader reader) { XMLEventReader2 xmlReader = StaxUtil.newXMLEventReader(reader); xmlReader.nextEvent(); // start document XMLEvent2 startElementEvent = xmlReader.nextEvent(); // start element return AtomCollectionFormatParser.parse(xmlReader, startElementEvent.asStartElement(), this.settings.metadata, this.settings.parseType); } public static OCollection parse(XMLEventReader2 reader, StartElement2 startElement, EdmDataServices metadata, EdmType itemType) { QName2 seName = startElement.getName(); Attribute2 seTypeAttribute = startElement.getAttributeByName(XmlFormatParser.M_TYPE); Attribute2 seNullAttribute = startElement.getAttributeByName(XmlFormatParser.M_NULL); boolean seIsNull = seNullAttribute != null && "true".equals(seNullAttribute.getValue()); if (seIsNull) { return null; } OCollection.Builder rt = OCollections.newBuilder(itemType); while (reader.hasNext()) { XMLEvent2 event = reader.nextEvent(); // end of the element, return if (event.isEndElement() && event.asEndElement().getName().equals(seName)) { return rt.build(); } if (event.isStartElement() && event.asStartElement().getName().getNamespaceUri().equals(XmlFormatParser.NS_DATASERVICES)) { // String name = event.asStartElement().getName().getLocalPart(); // Attribute2 typeAttribute = event.asStartElement().getAttributeByName(XmlFormatParser.M_TYPE); Attribute2 nullAttribute = event.asStartElement().getAttributeByName(XmlFormatParser.M_NULL); boolean isNull = nullAttribute != null && "true".equals(nullAttribute.getValue()); // for simple types if (itemType.isSimple()) { OSimpleObject<?> simple = OSimpleObjects.parse((EdmSimpleType) itemType, isNull? null: reader.getElementText()); rt.add(simple); } else if (itemType instanceof EdmComplexType){ OComplexObject complex = AtomComplexFormatParser.parse(reader, event.asStartElement(), metadata, (EdmComplexType) itemType); rt.add(complex); } else if (itemType instanceof EdmCollectionType) { OCollection col = AtomCollectionFormatParser.parse(reader, startElement, metadata, ((EdmCollectionType)itemType).getItemType()); rt.add(col); } } } throw new RuntimeException("cannot find the matching end element"); } }