Package org.sonatype.plexus.rest.resource

Source Code of org.sonatype.plexus.rest.resource.RestletResource$FakeFileItem

/*
* Sonatype Nexus (TM) Open Source Version
* Copyright (c) 2007-2014 Sonatype, Inc.
* All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
*
* This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
* which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
*
* Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
* of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
* Eclipse Foundation. All other trademarks are the property of their respective owners.
*/
package org.sonatype.plexus.rest.resource;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;

import org.sonatype.plexus.rest.PlexusRestletApplicationBridge;
import org.sonatype.plexus.rest.representation.InputStreamRepresentation;
import org.sonatype.plexus.rest.representation.XStreamRepresentation;
import org.sonatype.sisu.goodies.common.Loggers;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.XStreamException;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.FileItemHeaders;
import org.apache.commons.fileupload.FileUploadException;
import org.restlet.Context;
import org.restlet.data.CharacterSet;
import org.restlet.data.MediaType;
import org.restlet.data.Method;
import org.restlet.data.Request;
import org.restlet.data.Response;
import org.restlet.data.Status;
import org.restlet.ext.fileupload.RestletFileUpload;
import org.restlet.resource.Representation;
import org.restlet.resource.Resource;
import org.restlet.resource.ResourceException;
import org.restlet.resource.StringRepresentation;
import org.restlet.resource.Variant;
import org.slf4j.Logger;

/**
* The delegating resource.
*
* @author Jason van Zyl
* @author cstamas
*/
public class RestletResource
    extends Resource
{
  protected final Logger logger = Loggers.getLogger(getClass());

  private PlexusResource delegate;

  public RestletResource(Context context, Request request, Response response, PlexusResource delegate) {
    super(context, request, response);

    this.delegate = delegate;

    // set variants
    getVariants().clear();
    getVariants().addAll(delegate.getVariants());

    // mimic the constructor
    setAvailable(delegate.isAvailable());
    setReadable(delegate.isReadable());
    setModifiable(delegate.isModifiable());
    setNegotiateContent(delegate.isNegotiateContent());
  }

  /**
   * For file uploads we are using commons-fileupload integration with restlet.org. We are storing one
   * FileItemFactory
   * instance in context. This method simply encapsulates gettting it from Resource context.
   */
  protected FileItemFactory getFileItemFactory() {
    return (FileItemFactory) getContext().getAttributes().get(PlexusRestletApplicationBridge.FILEITEM_FACTORY);
  }

  protected XStreamRepresentation createRepresentation(Variant variant)
      throws ResourceException
  {
    XStreamRepresentation representation = null;

    try {
      // check is this variant a supported one, to avoid calling getText() on potentially huge representations
      if (MediaType.APPLICATION_JSON.equals(variant.getMediaType(), true)
          || MediaType.APPLICATION_XML.equals(variant.getMediaType(), true)
          || MediaType.TEXT_HTML.equals(variant.getMediaType(), true)) {
        String text = (variant instanceof Representation) ? ((Representation) variant).getText() : "";

        XStream xstream;
        if (MediaType.APPLICATION_JSON.equals(variant.getMediaType(), true)
            || MediaType.TEXT_HTML.equals(variant.getMediaType(), true)) {
          xstream = (XStream) getContext().getAttributes().get(PlexusRestletApplicationBridge.JSON_XSTREAM);
        }
        else if (MediaType.APPLICATION_XML.equals(variant.getMediaType(), true)) {
          xstream = (XStream) getContext().getAttributes().get(PlexusRestletApplicationBridge.XML_XSTREAM);
        }
        else {
          return null;
        }

        if (text != null) {
          CharacterSet charset = variant.getCharacterSet();
          if (charset == null) {
            charset = CharacterSet.ISO_8859_1;
          }
          if (!CharacterSet.UTF_8.equals(charset)) {
            // must fix text encoding NXCM-2494
            text = new String(new String(text.getBytes(), "UTF-8").getBytes(charset.getName()));
          }
        }

        representation = new XStreamRepresentation(xstream, text, variant.getMediaType());
        return representation;
      }
      else {
        return null;
      }
    }
    catch (IOException e) {
      throw new ResourceException(Status.SERVER_ERROR_INTERNAL, "Cannot get the representation!", e);
    }
  }

  protected Representation serialize(Variant variant, Object payload)
      throws ResourceException
  {
    if (payload == null) {
      return null;
    }

    XStreamRepresentation result = createRepresentation(variant);

    if (result == null) {
      throw new ResourceException(Status.CLIENT_ERROR_NOT_ACCEPTABLE, "The requested mediaType='"
          + variant.getMediaType() + "' is unsupported!");
    }

    result.setPayload(payload);

    return result;
  }

  protected Object deserialize(Object root)
      throws ResourceException
  {

    Object result = null;

    if (root != null) {

      if (String.class.isAssignableFrom(root.getClass())) {
        try {
          result = getRequest().getEntity().getText();
        }
        catch (IOException e) {
          throw new ResourceException(Status.SERVER_ERROR_INTERNAL, "Cannot get the representation!", e);
        }
      }

      XStreamRepresentation representation = createRepresentation(getRequest().getEntity());

      if (representation != null) {
        try {
          result = representation.getPayload(root);
        }
        catch (XStreamException e) {
          logger
              .warn("Invalid XML, unable to parse using XStream {}", (delegate == null ? "" : delegate.getClass()), e);

          throw new ResourceException(Status.CLIENT_ERROR_BAD_REQUEST,
              "Invalid XML, unable to parse using XStream", e);
        }
      }
    }
    return result;
  }

  protected Representation doRepresent(Object payload, Variant variant)
      throws ResourceException
  {
    if (Representation.class.isAssignableFrom(payload.getClass())) {
      // representation
      return (Representation) payload;
    }
    else if (InputStream.class.isAssignableFrom(payload.getClass())) {
      // inputStream
      return new InputStreamRepresentation(variant.getMediaType(), (InputStream) payload);
    }
    else if (String.class.isAssignableFrom(payload.getClass())) {
      // inputStream
      return new StringRepresentation((String) payload, variant.getMediaType());
    }
    else {
      // object, make it a representation
      return serialize(variant, payload);
    }
  }

  private Representation doRepresent(Object payload, Variant variant, Response response)
      throws ResourceException
  {
    final Representation representation = doRepresent(payload, variant);
    if (representation != null && representation instanceof RestletResponseCustomizer) {
      ((RestletResponseCustomizer) representation).customize(response);
    }
    return representation;
  }

  // == mkcol

  public boolean allowMkcol() {
    return false;
  }

  // == mkcol

  @Override
  public Representation represent(Variant variant)
      throws ResourceException
  {
    Object result;
    try {
      result = delegate.get(getContext(), getRequest(), getResponse(), variant);
    }
    catch (PlexusResourceException e) {
      // set the status
      getResponse().setStatus(e.getStatus());
      // try to get the responseObject
      result = e.getResultObject();
    }

    return (result != null) ? doRepresent(result, variant, getResponse()) : null;
  }

  @Override
  public void acceptRepresentation(Representation representation)
      throws ResourceException
  {
    if (delegate.acceptsUpload()) {
      upload(representation);
    }
    else {
      Object payloadInstance = delegate.getPayloadInstance(Method.POST);
      if (payloadInstance == null) {
        payloadInstance = delegate.getPayloadInstance();
      }
      Object payload = deserialize(payloadInstance);

      Object result = null;

      try {
        result = delegate.post(getContext(), getRequest(), getResponse(), payload);

        // This is a post, so set the status correctly
        // but only if the status was not changed to be something else, like a 202
        if (getResponse().getStatus() == Status.SUCCESS_OK) {
          getResponse().setStatus(Status.SUCCESS_CREATED);
        }
      }
      catch (PlexusResourceException e) {
        // set the status
        getResponse().setStatus(e.getStatus());
        // try to get the responseObject
        result = e.getResultObject();
      }

      if (result != null) {
        getResponse().setEntity(doRepresent(result, representation, getResponse()));
      }
    }
  }

  @Override
  public void storeRepresentation(Representation representation)
      throws ResourceException
  {
    if (delegate.acceptsUpload()) {
      upload(representation);
    }
    else {
      Object payloadInstance = delegate.getPayloadInstance(Method.PUT);
      if (payloadInstance == null) {
        payloadInstance = delegate.getPayloadInstance();
      }
      Object payload = deserialize(payloadInstance);

      Object result = null;
      try {
        result = delegate.put(getContext(), getRequest(), getResponse(), payload);

      }
      catch (PlexusResourceException e) {
        // set the status
        getResponse().setStatus(e.getStatus());
        // try to get the responseObject
        result = e.getResultObject();
      }

      if (result != null) {
        getResponse().setEntity(doRepresent(result, representation, getResponse()));
      }
    }
  }

  @Override
  public void removeRepresentations()
      throws ResourceException
  {
    delegate.delete(getContext(), getRequest(), getResponse());

    // if we have an Entity set, then return a 200 (default)
    // if not return a 204
    if (getResponse().getStatus() == Status.SUCCESS_OK && !getResponse().isEntityAvailable()) {
      getResponse().setStatus(Status.SUCCESS_NO_CONTENT);
    }
  }

  @Override
  public void handleOptions() {
    super.handleOptions();
      try {
        delegate.options(getContext(), getRequest(), getResponse());
      } catch (ResourceException re) {
          getResponse().setStatus(re.getStatus(), re);
      }
  }

  public void upload(Representation representation)
      throws ResourceException
  {
    Object result = null;

    List<FileItem> files = null;

    try {
      RestletFileUpload uploadRequest = new RestletFileUpload(getFileItemFactory());

      files = uploadRequest.parseRepresentation(representation);

      result = delegate.upload(getContext(), getRequest(), getResponse(), files);
    }
    catch (FileUploadException e) {
      // try to take simply the body as stream
      String name = getRequest().getResourceRef().getPath();

      if (name.contains("/")) {
        name = name.substring(name.lastIndexOf("/") + 1, name.length());
      }

      FileItem file = new FakeFileItem(name, representation);

      files = new ArrayList<FileItem>();

      files.add(file);

      result = delegate.upload(getContext(), getRequest(), getResponse(), files);
    }

    // only if the status was not changed to be something else, like a 202
    if (getResponse().getStatus() == Status.SUCCESS_OK) {
      getResponse().setStatus(Status.SUCCESS_CREATED);
    }

    if (result != null) {
      // TODO: representation cannot be returned as multipart! (representation above is possibly multipart)
      getResponse().setEntity(doRepresent(result, getPreferredVariant(), getResponse()));
    }
  }

  // ==

  private class FakeFileItem
      implements FileItem
  {
    private static final long serialVersionUID = 414885488690939983L;

    private final String name;

    private final Representation representation;

    public FakeFileItem(String name, Representation representation) {
      this.name = name;

      this.representation = representation;
    }

    @Override
    public String getContentType() {
      return representation.getMediaType().getName();
    }

    @Override
    public String getName() {
      return name;
    }

    @Override
    public String getFieldName() {
      return getName();
    }

    @Override
    public InputStream getInputStream()
        throws IOException
    {
      return representation.getStream();
    }

    // == ignored methods

    @Override
    public void delete() {
      // TODO Auto-generated method stub
    }

    @Override
    public byte[] get() {
      // TODO Auto-generated method stub
      return null;
    }

    @Override
    public OutputStream getOutputStream()
        throws IOException
    {
      // TODO Auto-generated method stub
      return null;
    }

    @Override
    public long getSize() {
      return 0;
    }

    @Override
    public String getString() {
      return null;
    }

    @Override
    public String getString(String encoding)
        throws UnsupportedEncodingException
    {
      return null;
    }

    @Override
    public boolean isFormField() {
      return false;
    }

    @Override
    public boolean isInMemory() {
      return false;
    }

    @Override
    public void setFieldName(String name) {
    }

    @Override
    public void setFormField(boolean state) {
    }

    @Override
    public void write(File file)
        throws Exception
    {
    }

    @Override
    public FileItemHeaders getHeaders() {
      return null;
    }

    @Override
    public void setHeaders(final FileItemHeaders headers) {

    }
  }

}
TOP

Related Classes of org.sonatype.plexus.rest.resource.RestletResource$FakeFileItem

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.