blob: 4ce8a9cb7c898ee59192415bd329cc74b6d57364 [file] [log] [blame]
/*******************************************************************************
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
******************************************************************************/
package org.apache.olingo.odata2.core.ep.consumer;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import org.apache.olingo.odata2.api.edm.Edm;
import org.apache.olingo.odata2.api.ep.EntityProviderException;
import org.apache.olingo.odata2.api.servicedocument.Accept;
import org.apache.olingo.odata2.api.servicedocument.Categories;
import org.apache.olingo.odata2.api.servicedocument.Category;
import org.apache.olingo.odata2.api.servicedocument.Collection;
import org.apache.olingo.odata2.api.servicedocument.ExtensionAttribute;
import org.apache.olingo.odata2.api.servicedocument.ExtensionElement;
import org.apache.olingo.odata2.api.servicedocument.Fixed;
import org.apache.olingo.odata2.api.servicedocument.Workspace;
import org.apache.olingo.odata2.core.commons.XmlHelper;
import org.apache.olingo.odata2.core.ep.util.FormatXml;
import org.apache.olingo.odata2.core.servicedocument.AcceptImpl;
import org.apache.olingo.odata2.core.servicedocument.AtomInfoImpl;
import org.apache.olingo.odata2.core.servicedocument.CategoriesImpl;
import org.apache.olingo.odata2.core.servicedocument.CategoryImpl;
import org.apache.olingo.odata2.core.servicedocument.CollectionImpl;
import org.apache.olingo.odata2.core.servicedocument.CommonAttributesImpl;
import org.apache.olingo.odata2.core.servicedocument.ExtensionAttributeImpl;
import org.apache.olingo.odata2.core.servicedocument.ExtensionElementImpl;
import org.apache.olingo.odata2.core.servicedocument.ServiceDocumentImpl;
import org.apache.olingo.odata2.core.servicedocument.TitleImpl;
import org.apache.olingo.odata2.core.servicedocument.WorkspaceImpl;
public class AtomServiceDocumentConsumer {
private String currentHandledStartTagName;
private static final String DEFAULT_PREFIX = "";
public ServiceDocumentImpl readServiceDokument(final XMLStreamReader reader) throws EntityProviderException {
AtomInfoImpl atomInfo = new AtomInfoImpl();
ServiceDocumentImpl serviceDocument = new ServiceDocumentImpl();
List<Workspace> workspaces = new ArrayList<Workspace>();
List<ExtensionElement> extElements = new ArrayList<ExtensionElement>();
CommonAttributesImpl attributes = new CommonAttributesImpl();
try {
while (reader.hasNext()
&& !(reader.isEndElement() && Edm.NAMESPACE_APP_2007.equals(reader.getNamespaceURI()) && FormatXml.APP_SERVICE
.equals(reader.getLocalName()))) {
reader.next();
if (reader.isStartElement()) {
currentHandledStartTagName = reader.getLocalName();
if (FormatXml.APP_SERVICE.equals(currentHandledStartTagName)) {
attributes = parseCommonAttribute(reader);
} else if (FormatXml.APP_WORKSPACE.equals(currentHandledStartTagName)) {
workspaces.add(parseWorkspace(reader));
} else {
ExtensionElementImpl extElement = parseExtensionElement(reader);
if (extElement != null) {
extElements.add(extElement);
}
}
}
}
if (workspaces.isEmpty()) {
throw new EntityProviderException(EntityProviderException.INVALID_STATE
.addContent("Service element must contain at least one workspace element"));
}
reader.close();
atomInfo.setWorkspaces(workspaces).setCommonAttributes(attributes).setExtesionElements(extElements);
serviceDocument.setAtomInfo(atomInfo);
serviceDocument.setEntitySetsInfo(atomInfo.getEntitySetsInfo());
return serviceDocument;
} catch (XMLStreamException e) {
throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
.getSimpleName()), e);
}
}
private CommonAttributesImpl parseCommonAttribute(final XMLStreamReader reader) {
CommonAttributesImpl attribute = new CommonAttributesImpl();
List<ExtensionAttribute> extAttributes = new ArrayList<ExtensionAttribute>();
attribute.setBase(reader.getAttributeValue(null, FormatXml.XML_BASE));
attribute.setLang(reader.getAttributeValue(null, FormatXml.XML_LANG));
for (int i = 0; i < reader.getAttributeCount(); i++) {
if (!(FormatXml.XML_BASE.equals(reader.getAttributeLocalName(i))
&& Edm.PREFIX_XML.equals(reader.getAttributePrefix(i))
|| (FormatXml.XML_LANG.equals(reader.getAttributeLocalName(i)) && Edm.PREFIX_XML.equals(reader
.getAttributePrefix(i)))
|| ("local".equals(reader.getAttributeNamespace(i)) || DEFAULT_PREFIX.equals(reader.getAttributePrefix(i)))))
{
extAttributes.add(new ExtensionAttributeImpl()
.setName(reader.getAttributeLocalName(i))
.setNamespace(reader.getAttributeNamespace(i))
.setPrefix(reader.getAttributePrefix(i))
.setText(reader.getAttributeValue(i)));
}
}
return attribute.setAttributes(extAttributes);
}
private WorkspaceImpl parseWorkspace(final XMLStreamReader reader)
throws XMLStreamException, EntityProviderException {
reader.require(XMLStreamConstants.START_ELEMENT, Edm.NAMESPACE_APP_2007, FormatXml.APP_WORKSPACE);
TitleImpl title = null;
List<Collection> collections = new ArrayList<Collection>();
List<ExtensionElement> extElements = new ArrayList<ExtensionElement>();
CommonAttributesImpl attributes = parseCommonAttribute(reader);
while (reader.hasNext()
&& !(reader.isEndElement() && Edm.NAMESPACE_APP_2007.equals(reader.getNamespaceURI()) && FormatXml.APP_WORKSPACE
.equals(reader.getLocalName()))) {
reader.next();
if (reader.isStartElement()) {
currentHandledStartTagName = reader.getLocalName();
if (FormatXml.APP_COLLECTION.equals(currentHandledStartTagName)) {
collections.add(parseCollection(reader));
} else if (FormatXml.ATOM_TITLE.equals(currentHandledStartTagName)) {
title = parseTitle(reader);
} else {
extElements.add(parseExtensionSansTitleElement(reader));
}
}
}
if (title == null) {
throw new EntityProviderException(EntityProviderException.INVALID_STATE
.addContent("Missing element title for workspace"));
}
return new WorkspaceImpl().setTitle(title).setCollections(collections).setAttributes(attributes)
.setExtesionElements(extElements);
}
private CollectionImpl parseCollection(final XMLStreamReader reader) throws XMLStreamException,
EntityProviderException {
reader.require(XMLStreamConstants.START_ELEMENT, Edm.NAMESPACE_APP_2007, FormatXml.APP_COLLECTION);
TitleImpl title = null;
String resourceIdentifier = reader.getAttributeValue(null, FormatXml.ATOM_HREF);
CommonAttributesImpl attributes = parseCommonAttribute(reader);
List<ExtensionElement> extElements = new ArrayList<ExtensionElement>();
List<Accept> acceptList = new ArrayList<Accept>();
List<Categories> categories = new ArrayList<Categories>();
if (resourceIdentifier == null) {
throw new EntityProviderException(EntityProviderException.MISSING_ATTRIBUTE.addContent("href"));
}
while (reader.hasNext()
&& !(reader.isEndElement() && Edm.NAMESPACE_APP_2007.equals(reader.getNamespaceURI())
&& FormatXml.APP_COLLECTION.equals(reader.getLocalName()))) {
reader.next();
if (reader.isStartElement()) {
currentHandledStartTagName = reader.getLocalName();
if (FormatXml.ATOM_TITLE.equals(currentHandledStartTagName)) {
title = parseTitle(reader);
} else if (FormatXml.APP_ACCEPT.equals(currentHandledStartTagName)) {
acceptList.add(parseAccept(reader));
} else if (FormatXml.APP_CATEGORIES.equals(currentHandledStartTagName)) {
categories.add(parseCategories(reader));
} else {
extElements.add(parseExtensionSansTitleElement(reader));
}
}
}
return new CollectionImpl().setHref(resourceIdentifier).setTitle(title).setCommonAttributes(attributes)
.setExtesionElements(extElements).setAcceptElements(acceptList).setCategories(categories);
}
private TitleImpl parseTitle(final XMLStreamReader reader) throws XMLStreamException {
reader.require(XMLStreamConstants.START_ELEMENT, Edm.NAMESPACE_ATOM_2005, FormatXml.ATOM_TITLE);
String text = reader.getElementText();
reader.require(XMLStreamConstants.END_ELEMENT, Edm.NAMESPACE_ATOM_2005, FormatXml.ATOM_TITLE);
return new TitleImpl().setText(text);
}
private AcceptImpl parseAccept(final XMLStreamReader reader) throws XMLStreamException {
reader.require(XMLStreamConstants.START_ELEMENT, Edm.NAMESPACE_APP_2007, FormatXml.APP_ACCEPT);
CommonAttributesImpl commonAttributes = parseCommonAttribute(reader);
String text = reader.getElementText();
reader.require(XMLStreamConstants.END_ELEMENT, Edm.NAMESPACE_APP_2007, FormatXml.APP_ACCEPT);
return new AcceptImpl().setCommonAttributes(commonAttributes).setText(text);
}
private CategoriesImpl parseCategories(final XMLStreamReader reader) throws XMLStreamException,
EntityProviderException {
reader.require(XMLStreamConstants.START_ELEMENT, Edm.NAMESPACE_APP_2007, FormatXml.APP_CATEGORIES);
CategoriesImpl categories = new CategoriesImpl();
String href = reader.getAttributeValue(null, FormatXml.ATOM_HREF);
String fixed = reader.getAttributeValue(null, FormatXml.APP_CATEGORIES_FIXED);
categories.setScheme(reader.getAttributeValue(null, FormatXml.APP_CATEGORIES_SCHEME));
categories.setHref(href);
if (href == null) {
for (int i = 0; i < Fixed.values().length; i++) {
if (Fixed.values()[i].name().equalsIgnoreCase(fixed)) {
categories.setFixed(Fixed.values()[i]);
}
}
if (categories.getFixed() == null) {
categories.setFixed(Fixed.NO);
}
List<Category> categoriesList = new ArrayList<Category>();
while (reader.hasNext()
&& !(reader.isEndElement() && Edm.NAMESPACE_APP_2007.equals(reader.getNamespaceURI())
&& FormatXml.APP_CATEGORIES.equals(reader.getLocalName()))) {
reader.next();
if (reader.isStartElement()) {
currentHandledStartTagName = reader.getLocalName();
if (FormatXml.ATOM_CATEGORY.equals(currentHandledStartTagName)) {
categoriesList.add(parseCategory(reader));
}
}
}
categories.setCategoryList(categoriesList);
}
if ((href != null && fixed != null && categories.getScheme() != null) ||
(href == null && fixed == null && categories.getScheme() == null)) {
throw new EntityProviderException(EntityProviderException.MISSING_ATTRIBUTE
.addContent("for the element categories"));
}
return categories;
}
private CategoryImpl parseCategory(final XMLStreamReader reader) throws XMLStreamException {
reader.require(XMLStreamConstants.START_ELEMENT, Edm.NAMESPACE_ATOM_2005, FormatXml.ATOM_CATEGORY);
CategoryImpl category = new CategoryImpl();
category.setScheme(reader.getAttributeValue(null, FormatXml.ATOM_CATEGORY_SCHEME));
category.setTerm(reader.getAttributeValue(null, FormatXml.ATOM_CATEGORY_TERM));
category.setLabel(reader.getAttributeValue(null, FormatXml.ATOM_CATEGORY_LABEL));
CommonAttributesImpl attributes = parseCommonAttribute(reader);
return category.setCommonAttributes(attributes);
}
private ExtensionElementImpl parseExtensionSansTitleElement(final XMLStreamReader reader) throws XMLStreamException,
EntityProviderException {
ExtensionElementImpl extElement = new ExtensionElementImpl();
if (!(Edm.NAMESPACE_APP_2007.equals(reader.getNamespaceURI())
|| (FormatXml.ATOM_TITLE.equals(reader.getLocalName())
&& Edm.NAMESPACE_ATOM_2005.equals(reader.getNamespaceURI())))) {
extElement = parseElement(reader);
}
return extElement;
}
private ExtensionElementImpl parseExtensionElement(final XMLStreamReader reader) throws XMLStreamException,
EntityProviderException {
ExtensionElementImpl extElement = null;
if (!Edm.NAMESPACE_APP_2007.equals(reader.getNamespaceURI())) {
extElement = parseElement(reader);
}
return extElement;
}
private ExtensionElementImpl parseElement(final XMLStreamReader reader) throws XMLStreamException,
EntityProviderException {
List<ExtensionElement> extensionElements = new ArrayList<ExtensionElement>();
ExtensionElementImpl extElement =
new ExtensionElementImpl().setName(reader.getLocalName()).setNamespace(reader.getNamespaceURI()).setPrefix(
reader.getPrefix());
extElement.setAttributes(parseAttribute(reader));
while (reader.hasNext()
&& !(reader.isEndElement() && extElement.getName() != null && extElement.getName()
.equals(reader.getLocalName()))) {
reader.next();
if (reader.isStartElement()) {
extensionElements.add(parseExtensionElement(reader));
} else if (reader.isCharacters()) {
String extElementText = "";
do {
extElementText = extElementText + reader.getText();
reader.next();
} while (reader.isCharacters());
extElement.setText(extElementText);
}
}
extElement.setElements(extensionElements);
if (extElement.getText() == null && extElement.getAttributes().isEmpty() && extElement.getElements().isEmpty()) {
throw new EntityProviderException(EntityProviderException.INVALID_STATE.addContent("Invalid extension element"));
}
return extElement;
}
private List<ExtensionAttribute> parseAttribute(final XMLStreamReader reader) {
List<ExtensionAttribute> extAttributes = new ArrayList<ExtensionAttribute>();
for (int i = 0; i < reader.getAttributeCount(); i++) {
{
extAttributes.add(new ExtensionAttributeImpl()
.setName(reader.getAttributeLocalName(i))
.setNamespace(reader.getAttributeNamespace(i))
.setPrefix(reader.getAttributePrefix(i))
.setText(reader.getAttributeValue(i)));
}
}
return extAttributes;
}
public ServiceDocumentImpl parseXml(final InputStream in) throws EntityProviderException {
return readServiceDokument(XmlHelper.createStreamReader(in));
}
}