blob: 78a5d9df8f5355496718d835de33397f48e31575 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2012-2014 SAP SE.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* SAP SE - initial API and implementation and/or initial documentation
*
*******************************************************************************/
package org.eclipse.ogee.client.parser;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.logging.Logger;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.eclipse.ogee.client.exceptions.MarshalerException;
import org.eclipse.ogee.client.exceptions.ParserException;
import org.eclipse.ogee.client.model.atom.AppService;
import org.eclipse.ogee.client.model.atom.AtomEntry;
import org.eclipse.ogee.client.model.atom.AtomFeed;
import org.eclipse.ogee.client.model.atom.ODataPropertyImpl;
import org.eclipse.ogee.client.model.edmx.Edmx;
import org.eclipse.ogee.client.model.generic.ODataCollection;
import org.eclipse.ogee.client.model.generic.ODataEntry;
import org.eclipse.ogee.client.model.generic.ODataProperty;
import org.eclipse.ogee.client.model.generic.ServiceDocument;
import org.eclipse.ogee.client.nls.messages.Messages;
import org.eclipse.ogee.client.parser.impl.AppServiceTagFactory;
import org.eclipse.ogee.client.parser.impl.AtomFeedAndEntryTagFactory;
import org.eclipse.ogee.client.parser.impl.Marshaller;
import org.eclipse.ogee.client.parser.impl.ODataSaxHandler;
import org.eclipse.ogee.client.parser.impl.TagFactory;
import org.eclipse.ogee.client.parser.impl.TypeConverter;
import org.eclipse.ogee.client.util.Util;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
/**
* Atom specific implementation of IODataParser
*
*/
public class ODataAtomParser implements IODataParser {
private static final String CHARACTER_ENCODING = "utf-8"; //$NON-NLS-1$
private final static Logger LOGGER = Logger.getLogger(ODataAtomParser.class
.getName());
private TypeConverter typeConverter = TypeConverter.ATOM;
/**
* Construcs a new Atom parser.
*/
public ODataAtomParser() {
super();
}
/**
* Converts OData entry XML in ATOM format to an AtomEntry object
*
* @param xml
* ATOM format
* @return AtomEntry
* @throws ParserException
*/
private AtomEntry fromXmlToAtomEntry(String xml) throws ParserException {
if (xml != null) {
xml = xml.trim();
}
if (xml == null || xml.isEmpty()) {
String message = Messages.getString("ODataAtomParser.1"); //$NON-NLS-1$
LOGGER.warning(message);
throw new ParserException(message);
}
InputStream inputStream = null;
try {
inputStream = new ByteArrayInputStream(
xml.getBytes(CHARACTER_ENCODING));
AtomEntry atomEntry = fromXmlToAtomEntry(inputStream);
return atomEntry;
} catch (UnsupportedEncodingException e) {
throw logAndCreateParserException(inputStream, e);
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
LOGGER.severe(e.getMessage());
}
}
}
}
/**
* Converts input stream in OData ATOM format to AtomEntry object
*
* @param inputStream
* stream in OData ATOM format
* @return AtomEntry
* @throws ParserException
*/
private AtomEntry fromXmlToAtomEntry(InputStream inputStream)
throws ParserException {
if (inputStream == null) {
String message = Messages.getString("ODataAtomParser.2"); //$NON-NLS-1$
LOGGER.warning(message);
throw new ParserException(message);
}
AtomEntry atomEntry = (AtomEntry) parseObject(inputStream,
new AtomFeedAndEntryTagFactory());
return atomEntry;
}
/**
* Converts OData Collection XML in OData ATOM format to AtomFeed object
*
* @param xml
* OData ATOM format
* @return AtomFeed
* @throws ParserException
*/
private AtomFeed fromXmlToAtomFeed(String xml) throws ParserException {
if (xml != null) {
xml = xml.trim();
}
if (xml == null || xml.isEmpty()) {
String message = Messages.getString("ODataAtomParser.3"); //$NON-NLS-1$
LOGGER.warning(message);
throw new ParserException(message);
}
InputStream inputStream = null;
try {
inputStream = new ByteArrayInputStream(
xml.getBytes(CHARACTER_ENCODING));
AtomFeed atomFeed = fromXmlToAtomFeed(inputStream);
return atomFeed;
} catch (IOException e) {
throw logAndCreateParserException(inputStream, e);
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
LOGGER.severe(e.getMessage());
}
}
}
}
/**
* Converts input stream in OData ATOM format to AtomFeed object
*
* @param inputStream
* stream in OData ATOM format
* @return AtomFeed
* @throws ParserException
*/
private AtomFeed fromXmlToAtomFeed(InputStream inputStream)
throws ParserException {
if (inputStream == null) {
String message = Messages.getString("ODataAtomParser.4"); //$NON-NLS-1$
LOGGER.warning(message);
throw new ParserException(message);
}
AtomFeed atomFeed = (AtomFeed) parseObject(inputStream,
new AtomFeedAndEntryTagFactory());
return atomFeed;
}
/**
* Converts Service Document XML in OData ATOM format to AppService object
*
* @param xml
* OData ATOM format
* @return AppService
* @throws ParserException
*/
private AppService fromXmlToAppService(String xml) throws ParserException {
if (xml != null) {
xml = xml.trim();
}
if (xml == null || xml.length() == 0) {
String message = Messages.getString("ODataAtomParser.5"); //$NON-NLS-1$
LOGGER.warning(message);
throw new ParserException(message);
}
if (!xml.contains("<app:service") && !xml.contains("<service")) //$NON-NLS-1$ //$NON-NLS-2$
{
String message = Messages.getString("ODataAtomParser.8"); //$NON-NLS-1$
LOGGER.warning(message);
throw new ParserException(message);
}
InputStream inputStream = null;
try {
inputStream = new ByteArrayInputStream(
xml.getBytes(CHARACTER_ENCODING));
AppService appService = fromXmlToAppService(inputStream);
return appService;
} catch (IOException e) {
throw logAndCreateParserException(inputStream, e);
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
LOGGER.severe(e.getMessage());
}
}
}
}
/**
* Converts input stream in OData ATOM format to AppService object
*
* @param inputStream
* stream in SAP Data Protocol format
* @return AppService
* @throws ParserException
*/
private AppService fromXmlToAppService(InputStream inputStream)
throws ParserException {
if (inputStream == null) {
String message = Messages.getString("ODataAtomParser.9"); //$NON-NLS-1$
LOGGER.warning(message);
throw new ParserException(message);
}
AppService appService = (AppService) parseObject(inputStream,
new AppServiceTagFactory());
return appService;
}
/**
* Parses an object given the inputstream and tag factory parameters.
*
* @param inputStream
* - input stream.
* @param tagFactory
* - tag factory.
* @return - a parsed object.
* @throws ParserException
*/
public Object parseObject(InputStream inputStream, TagFactory tagFactory)
throws ParserException {
try {
ODataSaxHandler handler = new ODataSaxHandler(tagFactory);
SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setValidating(true);
factory.setFeature(
"http://xml.org/sax/features/namespace-prefixes", true);
factory.setFeature("http://xml.org/sax/features/namespaces", true);
factory.setFeature("http://xml.org/sax/features/validation", true);
factory.setFeature(
"http://apache.org/xml/features/validation/schema", true);
factory.setFeature(
"http://apache.org/xml/features/validation/schema-full-checking",
true);
factory.setFeature(
"http://xml.org/sax/features/external-general-entities", false); //$NON-NLS-1$
factory.setFeature(
"http://xml.org/sax/features/external-parameter-entities", false); //$NON-NLS-1$
factory.setFeature(
"http://apache.org/xml/features/disallow-doctype-decl", true); //$NON-NLS-1$
SAXParser parser = factory.newSAXParser();
XMLReader reader = parser.getXMLReader();
try {
reader.setFeature(
"http://xml.org/sax/features/namespaces", true); //$NON-NLS-1$
} catch (SAXException e) {
LOGGER.severe(Messages.getString("ODataAtomParser.14")); //$NON-NLS-1$
}
parser.parse(inputStream, handler);
return handler.getRoot();
} catch (ParserConfigurationException e) {
throw logAndCreateParserException(inputStream, e);
} catch (SAXException e) {
throw logAndCreateParserException(inputStream, e);
} catch (IOException e) {
throw logAndCreateParserException(inputStream, e);
} finally {
try {
inputStream.close();
} catch (IOException e) {
LOGGER.severe(e.getMessage());
}
}
}
private static ParserException logAndCreateParserException(String xml,
Exception e) {
LOGGER.severe(Messages.getString("ODataAtomParser.17") + xml); //$NON-NLS-1$
LOGGER.severe(e.getMessage());
return new ParserException(e.getMessage());
}
private static ParserException logAndCreateParserException(
InputStream inputStream, Exception e) {
try {
String xml = Util.convertStreamToString(inputStream);
return logAndCreateParserException(xml, e);
} catch (IOException ioe) {
LOGGER.severe(ioe.getMessage());
return new ParserException(e);
}
}
/**
* Converts XML in OData ATOM format to ODataPropertyImpl object
*
* @param xml
* OData ATOM format
* @return ODataPropertyImpl
* @throws ParserException
*/
private ODataPropertyImpl fromXmlToDataValue(String xml)
throws ParserException {
if (xml != null) {
xml = xml.trim();
}
if (xml == null || xml.length() == 0) {
String message = Messages.getString("ODataAtomParser.18"); //$NON-NLS-1$
LOGGER.warning(message);
throw new ParserException(message);
}
InputStream inputStream = null;
try {
inputStream = new ByteArrayInputStream(
xml.getBytes(CHARACTER_ENCODING));
ODataPropertyImpl dataValue = fromXmlToDataValue(inputStream);
return dataValue;
} catch (IOException e) {
LOGGER.severe(e.getMessage());
throw new ParserException(e);
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
LOGGER.severe(e.getMessage());
}
}
}
}
/**
* Converts input stream in OData ATOM format to ODataPropertyImpl object
*
* @param inputStream
* stream in OData ATOM format
* @return ODataPropertyImpl
* @throws ParserException
*/
private ODataPropertyImpl fromXmlToDataValue(InputStream inputStream)
throws ParserException {
if (inputStream == null) {
String message = Messages.getString("ODataAtomParser.19"); //$NON-NLS-1$
LOGGER.warning(message);
throw new ParserException(message);
}
ODataPropertyImpl dataValue = (ODataPropertyImpl) parseObject(
inputStream, new AtomFeedAndEntryTagFactory());
return dataValue;
}
/**
* Converts AtomFeed object to XML in OData ATOM format
*
* @param atomFeed
* AtomFeed
* @return String
* @throws MarshalerException
*/
private String toXml(AtomFeed atomFeed)
throws org.eclipse.ogee.client.exceptions.MarshalerException {
String xml = Marshaller.getInstance().marshal(atomFeed);
return xml;
}
/**
* Formats the given entry to string representation.
*
* @param entry
* - the OData entry to format.
* @return - A string representation of the given entry.
* @throws MarshalerException
*/
public String format(ODataEntry entry) throws MarshalerException {
return toXml((AtomEntry) entry);
}
/**
* Formats the given OData collection to string representation.
*
* @param collection
* - the OData collection to format.
* @return - A string representation of the given collection.
* @throws MarshalerException
*/
public String format(ODataCollection collection) throws MarshalerException {
return toXml((AtomFeed) collection);
}
/**
* Converts AtomEntry object to XML in OData ATOM format
*
* @param atomEntry
* @return String
* @throws MarshalerException
*/
private String toXml(AtomEntry atomEntry) throws MarshalerException {
String xml = Marshaller.getInstance().marshal(atomEntry);
return xml;
}
/**
* Parses the given xml to a service document object.
*
* @param xml
* - the xml to parse.
* @return - A Service Document object.
* @throws ParserException
*/
public ServiceDocument parseServiceDocument(String xml)
throws ParserException {
return fromXmlToAppService(xml);
}
/**
* Parses the given xml to an OData collection object.
*
* @param xml
* - the xml to parse.
* @return - An OData collection object.
* @throws ParserException
*/
public ODataCollection parseODataCollection(String xml)
throws ParserException {
return fromXmlToAtomFeed(xml);
}
/**
* Parses the given xml to an OData entry object.
*
* @param xml
* - the xml to parse.
* @return - An OData entry object.
* @throws ParserException
*/
public ODataEntry parseODataEntry(String xml) throws ParserException {
return fromXmlToAtomEntry(xml);
}
/**
* Parses the given xml to an OData property object.
*
* @param xml
* - the xml to parse.
* @return - An OData property object.
* @throws ParserException
*/
public ODataProperty parseODataProperty(String xml) throws ParserException {
return fromXmlToDataValue(xml);
}
@Override
public TypeConverter getTypeConverter() {
return typeConverter;
}
@Override
public Representation getRepresentation() {
return Representation.ATOM;
}
@Override
public String format(Edmx edmx) throws MarshalerException {
return Marshaller.getInstance().format(edmx);
}
}