com.msopentech.odatajclient.engine.data.AbstractODataReader.java Source code

Java tutorial

Introduction

Here is the source code for com.msopentech.odatajclient.engine.data.AbstractODataReader.java

Source

/**
 * Copyright  Microsoft Open Technologies, Inc.
 *
 * All Rights Reserved
 *
 * Licensed 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
 *
 * THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS
 * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
 * ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A
 * PARTICULAR PURPOSE, MERCHANTABILITY OR NON-INFRINGEMENT.
 *
 * See the Apache License, Version 2.0 for the specific language
 * governing permissions and limitations under the License.
 */
package com.msopentech.odatajclient.engine.data;

import java.io.InputStream;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import com.msopentech.odatajclient.engine.client.ODataClient;
import com.msopentech.odatajclient.engine.data.metadata.AbstractEdmMetadata;
import com.msopentech.odatajclient.engine.data.metadata.edm.EdmSimpleType;
import com.msopentech.odatajclient.engine.data.xml.XMLServiceDocument;
import com.msopentech.odatajclient.engine.format.ODataFormat;
import com.msopentech.odatajclient.engine.format.ODataPubFormat;
import com.msopentech.odatajclient.engine.format.ODataValueFormat;
import com.msopentech.odatajclient.engine.utils.ODataConstants;

public abstract class AbstractODataReader implements ODataReader {

    private static final long serialVersionUID = -1988865870981207079L;

    /**
     * Logger.
     */
    protected static final Logger LOG = LoggerFactory.getLogger(AbstractODataReader.class);

    protected final ODataClient client;

    protected AbstractODataReader(final ODataClient client) {
        this.client = client;
    }

    @Override
    public ODataEntitySet readEntitySet(final InputStream input, final ODataPubFormat format) {
        return client.getBinder().getODataEntitySet(
                client.getDeserializer().toFeed(input, client.getResourceFactory().feedClassForFormat(format)));
    }

    @Override
    public ODataEntity readEntity(final InputStream input, final ODataPubFormat format) {
        return client.getBinder().getODataEntity(
                client.getDeserializer().toEntry(input, client.getResourceFactory().entryClassForFormat(format)));
    }

    @Override
    public ODataProperty readProperty(final InputStream input, final ODataFormat format) {
        final Element property = client.getDeserializer().toPropertyDOM(input, format);

        // The ODataProperty object is used either for actual entity properties and for invoke result (when return type
        // is neither an entity nor a collection of entities).
        // Such formats are mostly the same except for collections: an entity property looks like
        //     <aproperty m:type="Collection(AType)">
        //       <element>....</element>
        //     </aproperty>
        //
        // while an invoke result with returnType="Collection(AnotherType)" looks like
        //     <functionImportName>
        //       <element m:type="AnotherType">...</element>
        //     <functionImportName>
        //
        // The code below is meant for "normalizing" the latter into
        //     <functionImportName m:type="Collection(AnotherType)">
        //       <element m:type="AnotherType">...</element>
        //     <functionImportName>
        final String type = property.getAttribute(ODataConstants.ATTR_M_TYPE);
        final NodeList elements = property.getElementsByTagName(ODataConstants.ELEM_ELEMENT);
        if (StringUtils.isBlank(type) && elements != null && elements.getLength() > 0) {
            final Node elementType = elements.item(0).getAttributes().getNamedItem(ODataConstants.ATTR_M_TYPE);
            if (elementType != null) {
                property.setAttribute(ODataConstants.ATTR_M_TYPE,
                        "Collection(" + elementType.getTextContent() + ")");
            }
        }

        return client.getBinder().getProperty(property);
    }

    @Override
    public ODataLinkCollection readLinks(final InputStream input, final ODataFormat format) {
        return client.getBinder().getLinkCollection(client.getDeserializer().toLinkCollection(input, format));
    }

    @Override
    public XMLServiceDocument readServiceDocument(final InputStream input, final ODataFormat format) {
        return client.getBinder()
                .getODataServiceDocument(client.getDeserializer().toServiceDocument(input, format));
    }

    @Override
    public ODataError readError(final InputStream inputStream, final boolean isXML) {
        return client.getDeserializer().toODataError(inputStream, isXML);
    }

    @Override
    @SuppressWarnings("unchecked")
    public <T> T read(final InputStream src, final String format, final Class<T> reference) {
        Object res;

        try {
            if (ODataEntitySetIterator.class.isAssignableFrom(reference)) {
                res = new ODataEntitySetIterator(client, src, ODataPubFormat.fromString(format));
            } else if (ODataEntitySet.class.isAssignableFrom(reference)) {
                res = readEntitySet(src, ODataPubFormat.fromString(format));
            } else if (ODataEntity.class.isAssignableFrom(reference)) {
                res = readEntity(src, ODataPubFormat.fromString(format));
            } else if (ODataProperty.class.isAssignableFrom(reference)) {
                res = readProperty(src, ODataFormat.fromString(format));
            } else if (ODataLinkCollection.class.isAssignableFrom(reference)) {
                res = readLinks(src, ODataFormat.fromString(format));
            } else if (ODataValue.class.isAssignableFrom(reference)) {
                res = client.getPrimitiveValueBuilder()
                        .setType(ODataValueFormat.fromString(format) == ODataValueFormat.TEXT ? EdmSimpleType.String
                                : EdmSimpleType.Stream)
                        .setText(IOUtils.toString(src)).build();
            } else if (AbstractEdmMetadata.class.isAssignableFrom(reference)) {
                res = readMetadata(src);
            } else if (XMLServiceDocument.class.isAssignableFrom(reference)) {
                res = readServiceDocument(src, ODataFormat.fromString(format));
            } else if (ODataError.class.isAssignableFrom(reference)) {
                res = readError(src, !format.toString().contains("json"));
            } else {
                throw new IllegalArgumentException("Invalid reference type " + reference);
            }
        } catch (Exception e) {
            LOG.warn("Cast error", e);
            res = null;
        } finally {
            if (!ODataEntitySetIterator.class.isAssignableFrom(reference)) {
                IOUtils.closeQuietly(src);
            }
        }

        return (T) res;
    }
}