org.apache.olingo.fit.V3Services.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.olingo.fit.V3Services.java

Source

/*
 * 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.fit;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.cxf.interceptor.InInterceptors;
import org.apache.cxf.jaxrs.ext.multipart.Attachment;
import org.apache.olingo.commons.api.data.EntitySet;
import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
import org.apache.olingo.fit.metadata.Metadata;
import org.apache.olingo.fit.methods.MERGE;
import org.apache.olingo.fit.methods.PATCH;
import org.apache.olingo.fit.rest.XHTTPMethodInterceptor;
import org.apache.olingo.fit.utils.AbstractUtilities;
import org.apache.olingo.fit.utils.Accept;
import org.apache.olingo.fit.utils.Commons;
import org.apache.olingo.fit.utils.ConstantKey;
import org.apache.olingo.fit.utils.Constants;
import org.apache.olingo.fit.utils.FSManager;
import org.apache.olingo.fit.utils.LinkInfo;
import org.springframework.stereotype.Service;

import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMultipart;
import javax.ws.rs.BadRequestException;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.HeaderParam;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

@Service
@Path("/V30/Static.svc")
@InInterceptors(classes = XHTTPMethodInterceptor.class)
public class V3Services extends AbstractServices {

    public V3Services() throws IOException {
        super(ODataServiceVersion.V30, Commons.getMetadata(ODataServiceVersion.V30));
    }

    protected V3Services(final Metadata metadata) throws IOException {
        super(ODataServiceVersion.V30, metadata);
    }

    @GET
    @Path("/InStreamErrorGetCustomer")
    public Response instreamErrorGetCustomer(
            @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
            @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format) {

        final Accept acceptType;
        if (StringUtils.isNotBlank(format)) {
            acceptType = Accept.valueOf(format.toUpperCase());
        } else {
            acceptType = Accept.parse(accept, version);
        }

        try {
            final InputStream error = FSManager.instance(version).readFile("InStreamErrorGetCustomer", acceptType);

            return Response.ok(error)
                    .header(Constants.get(version, ConstantKey.ODATA_SERVICE_VERSION), version + ";")
                    .header("Content-Type", acceptType.toString(version)).build();
        } catch (Exception e) {
            if (acceptType == Accept.XML || acceptType == Accept.TEXT) {
                throw new UnsupportedMediaTypeException("Unsupported media type");
            }

            return xml.createFaultResponse(accept, e);
        }
    }

    /**
     * Provide sample large metadata.
     *
     * @return metadata.
     */
    @GET
    @Path("/large/$metadata")
    @Produces(MediaType.APPLICATION_XML)
    public Response getLargeMetadata() {
        return getMetadata("large" + StringUtils.capitalize(Constants.get(version, ConstantKey.METADATA)));
    }

    @Override
    protected void setInlineCount(final EntitySet feed, final String count) {
        if ("allpages".equals(count)) {
            feed.setCount(feed.getEntities().size());
        }
    }

    @Override
    public InputStream exploreMultipart(final List<Attachment> attachments, final String boundary,
            final boolean contineOnError) throws IOException {

        final ByteArrayOutputStream bos = new ByteArrayOutputStream();

        Response res = null;
        boolean goon = true;
        for (int i = 0; i < attachments.size() && goon; i++) {
            try {
                final Attachment obj = attachments.get(i);
                bos.write(("--" + boundary).getBytes());
                bos.write(Constants.CRLF);

                final Object content = obj.getDataHandler().getContent();
                if (content instanceof MimeMultipart) {
                    final Map<String, String> references = new HashMap<String, String>();

                    final String cboundary = "changeset_" + UUID.randomUUID().toString();
                    bos.write(("Content-Type: multipart/mixed;boundary=" + cboundary).getBytes());
                    bos.write(Constants.CRLF);
                    bos.write(Constants.CRLF);

                    final ByteArrayOutputStream chbos = new ByteArrayOutputStream();
                    String lastContebtID = null;
                    try {
                        for (int j = 0; j < ((MimeMultipart) content).getCount(); j++) {
                            final MimeBodyPart part = (MimeBodyPart) ((MimeMultipart) content).getBodyPart(j);
                            lastContebtID = part.getContentID();
                            addChangesetItemIntro(chbos, lastContebtID, cboundary);

                            res = bodyPartRequest(new MimeBodyPart(part.getInputStream()), references);
                            if (res == null || res.getStatus() >= 400) {
                                throw new Exception("Failure processing changeset");
                            }

                            addSingleBatchResponse(res, lastContebtID, chbos);
                            references.put("$" + lastContebtID, res.getHeaderString("Location"));
                        }

                        bos.write(chbos.toByteArray());
                        IOUtils.closeQuietly(chbos);

                        bos.write(("--" + cboundary + "--").getBytes());
                        bos.write(Constants.CRLF);
                    } catch (Exception e) {
                        LOG.warn("While processing changeset", e);
                        IOUtils.closeQuietly(chbos);

                        addChangesetItemIntro(bos, lastContebtID, cboundary);

                        if (res == null || res.getStatus() < 400) {
                            addErrorBatchResponse(e, "1", bos);
                        } else {
                            addSingleBatchResponse(res, lastContebtID, bos);
                        }

                        goon = contineOnError;
                    }
                } else {
                    addItemIntro(bos);

                    res = bodyPartRequest(new MimeBodyPart(obj.getDataHandler().getInputStream()));

                    if (res.getStatus() >= 400) {
                        goon = contineOnError;
                        throw new Exception("Failure processing changeset");
                    }

                    addSingleBatchResponse(res, bos);
                }
            } catch (Exception e) {
                if (res == null || res.getStatus() < 400) {
                    addErrorBatchResponse(e, bos);
                } else {
                    addSingleBatchResponse(res, bos);
                }
            }
        }

        bos.write(("--" + boundary + "--").getBytes());

        return new ByteArrayInputStream(bos.toByteArray());
    }

    @GET
    @Path("/Car/{type:[a-zA-Z].*}")
    public Response filterCar(@Context final UriInfo uriInfo,
            @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
            @QueryParam("$top") @DefaultValue(StringUtils.EMPTY) final String top,
            @QueryParam("$skip") @DefaultValue(StringUtils.EMPTY) final String skip,
            @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format,
            @QueryParam("$inlinecount") @DefaultValue(StringUtils.EMPTY) final String count,
            @QueryParam("$filter") @DefaultValue(StringUtils.EMPTY) final String filter,
            @QueryParam("$orderby") @DefaultValue(StringUtils.EMPTY) final String orderby,
            @QueryParam("$skiptoken") @DefaultValue(StringUtils.EMPTY) final String skiptoken) {

        return super.getEntitySet(uriInfo, accept, "Car", top, skip, format, count, filter, orderby, skiptoken);
    }

    @GET
    @Path("/Login({entityId})")
    public Response getLogin(@Context final UriInfo uriInfo,
            @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
            @PathParam("entityId") final String entityId,
            @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format,
            @QueryParam("$expand") @DefaultValue(StringUtils.EMPTY) final String expand,
            @QueryParam("$select") @DefaultValue(StringUtils.EMPTY) final String select) {

        return super.getEntityInternal(uriInfo.getRequestUri().toASCIIString(), accept, "Login",
                StringUtils.remove(entityId, "'"), format, expand, select);
    }

    @POST
    @Path("/Login")
    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON })
    @Consumes({ MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON, MediaType.APPLICATION_OCTET_STREAM })
    public Response postLogin(@Context final UriInfo uriInfo,
            @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
            @HeaderParam("Content-Type") @DefaultValue(StringUtils.EMPTY) final String contentType,
            @HeaderParam("Prefer") @DefaultValue(StringUtils.EMPTY) final String prefer, final String entity) {

        if ("{\"odata.type\":\"Microsoft.Test.OData.Services.AstoriaDefaultService.Login\"}".equals(entity)) {
            return xml.createFaultResponse(accept, new BadRequestException());
        }

        return super.postNewEntity(uriInfo, accept, contentType, prefer, "Login", entity);
    }

    @DELETE
    @Path("/Login({entityId})")
    public Response removeLogin(@PathParam("entityId") final String entityId) {

        return super.removeEntity("Login", StringUtils.remove(entityId, "'"));
    }

    /**
     * Retrieve links sample.
     *
     * @param accept Accept header.
     * @param entitySetName Entity set name.
     * @param entityId entity id.
     * @param linkName link name.
     * @param format format query option.
     * @return links.
     */
    @GET
    @Path("/{entitySetName}({entityId})/$links/{linkName}")
    public Response getLinks(@HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
            @PathParam("entitySetName") final String entitySetName, @PathParam("entityId") final String entityId,
            @PathParam("linkName") final String linkName,
            @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format) {
        try {
            final Accept acceptType;
            if (StringUtils.isNotBlank(format)) {
                acceptType = Accept.valueOf(format.toUpperCase());
            } else {
                acceptType = Accept.parse(accept, version);
            }

            if (acceptType == Accept.ATOM) {
                throw new UnsupportedMediaTypeException("Unsupported media type");
            }

            final LinkInfo links = xml.readLinks(entitySetName, entityId, linkName, acceptType);

            return xml.createResponse(links.getLinks(), links.getEtag(), acceptType);
        } catch (Exception e) {
            return xml.createFaultResponse(accept, e);
        }
    }

    @POST
    @Path("/{entitySetName}({entityId})/$links/{linkName}")
    public Response postLink(@HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
            @HeaderParam("Content-Type") @DefaultValue(StringUtils.EMPTY) final String contentType,
            @PathParam("entitySetName") final String entitySetName, @PathParam("entityId") final String entityId,
            @PathParam("linkName") final String linkName, final String link,
            @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format) {
        try {
            final Accept acceptType;
            if (StringUtils.isNotBlank(format)) {
                acceptType = Accept.valueOf(format.toUpperCase());
            } else {
                acceptType = Accept.parse(accept, version);
            }

            if (acceptType == Accept.ATOM) {
                throw new UnsupportedMediaTypeException("Unsupported media type");
            }

            final Accept content;
            if (StringUtils.isNotBlank(contentType)) {
                content = Accept.parse(contentType, version);
            } else {
                content = acceptType;
            }

            final AbstractUtilities utils = getUtilities(acceptType);

            final List<String> links;
            if (content == Accept.XML || content == Accept.TEXT || content == Accept.ATOM) {
                links = xml.extractLinkURIs(IOUtils.toInputStream(link, Constants.ENCODING)).getValue();
            } else {
                links = json.extractLinkURIs(IOUtils.toInputStream(link, Constants.ENCODING)).getValue();
            }

            utils.putLinksInMemory(Commons.getEntityBasePath(entitySetName, entityId), entitySetName, entityId,
                    linkName, links);

            return xml.createResponse(null, null, null, Response.Status.NO_CONTENT);
        } catch (Exception e) {
            return xml.createFaultResponse(accept, e);
        }
    }

    @MERGE
    @Path("/{entitySetName}({entityId})/$links/{linkName}")
    public Response mergeLink(@HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
            @HeaderParam("Content-Type") @DefaultValue(StringUtils.EMPTY) final String contentType,
            @PathParam("entitySetName") final String entitySetName, @PathParam("entityId") final String entityId,
            @PathParam("linkName") final String linkName, final String link,
            @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format) {
        return putLink(accept, contentType, entitySetName, entityId, linkName, link, format);
    }

    @PATCH
    @Path("/{entitySetName}({entityId})/$links/{linkName}")
    public Response patchLink(@HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
            @HeaderParam("Content-Type") @DefaultValue(StringUtils.EMPTY) final String contentType,
            @PathParam("entitySetName") final String entitySetName, @PathParam("entityId") final String entityId,
            @PathParam("linkName") final String linkName, final String link,
            @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format) {
        return putLink(accept, contentType, entitySetName, entityId, linkName, link, format);
    }

    @PUT
    @Path("/{entitySetName}({entityId})/$links/{linkName}")
    public Response putLink(@HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
            @HeaderParam("Content-Type") @DefaultValue(StringUtils.EMPTY) final String contentType,
            @PathParam("entitySetName") final String entitySetName, @PathParam("entityId") final String entityId,
            @PathParam("linkName") final String linkName, final String link,
            @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format) {
        try {
            final Accept acceptType;
            if (StringUtils.isNotBlank(format)) {
                acceptType = Accept.valueOf(format.toUpperCase());
            } else {
                acceptType = Accept.parse(accept, version);
            }

            if (acceptType == Accept.ATOM) {
                throw new UnsupportedMediaTypeException("Unsupported media type");
            }

            final Accept content;
            if (StringUtils.isNotBlank(contentType)) {
                content = Accept.parse(contentType, version);
            } else {
                content = acceptType;
            }

            final AbstractUtilities utils = getUtilities(acceptType);

            final List<String> links;
            if (content == Accept.XML || content == Accept.TEXT || content == Accept.ATOM) {
                links = xml.extractLinkURIs(IOUtils.toInputStream(link, Constants.ENCODING)).getValue();
            } else {
                links = json.extractLinkURIs(IOUtils.toInputStream(link, Constants.ENCODING)).getValue();
            }

            utils.putLinksInMemory(Commons.getEntityBasePath(entitySetName, entityId), entitySetName, linkName,
                    links);

            return xml.createResponse(null, null, null, Response.Status.NO_CONTENT);
        } catch (Exception e) {
            return xml.createFaultResponse(accept, e);
        }
    }

    @DELETE
    @Path("/{entitySetName}({entityId})/$links/{linkName}({linkId})")
    public Response deleteLink(@HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
            @HeaderParam("Content-Type") @DefaultValue(StringUtils.EMPTY) final String contentType,
            @PathParam("entitySetName") final String entitySetName, @PathParam("entityId") final String entityId,
            @PathParam("linkName") final String linkName, @PathParam("linkId") final String linkId,
            @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format) {
        try {
            final Accept acceptType;
            if (StringUtils.isNotBlank(format)) {
                acceptType = Accept.valueOf(format.toUpperCase());
            } else {
                acceptType = Accept.parse(accept, version);
            }

            if (acceptType == Accept.ATOM) {
                throw new UnsupportedMediaTypeException("Unsupported media type");
            }

            final AbstractUtilities utils = getUtilities(acceptType);

            final Map.Entry<String, List<String>> currents = json.extractLinkURIs(
                    utils.readLinks(entitySetName, entityId, linkName, Accept.JSON_FULLMETA).getLinks());

            final Map.Entry<String, List<String>> toBeRemoved = json.extractLinkURIs(
                    utils.readLinks(entitySetName, entityId, linkName + "(" + linkId + ")", Accept.JSON_FULLMETA)
                            .getLinks());

            final List<String> remains = currents.getValue();
            remains.removeAll(toBeRemoved.getValue());

            utils.putLinksInMemory(Commons.getEntityBasePath(entitySetName, entityId), entitySetName, linkName,
                    remains);

            return xml.createResponse(null, null, null, Response.Status.NO_CONTENT);
        } catch (Exception e) {
            return xml.createFaultResponse(accept, e);
        }
    }
}