com.fujitsu.dc.core.rs.box.BoxResource.java Source code

Java tutorial

Introduction

Here is the source code for com.fujitsu.dc.core.rs.box.BoxResource.java

Source

/**
 * personium.io
 * Copyright 2014 FUJITSU LIMITED
 *
 * 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
 *
 * 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 com.fujitsu.dc.core.rs.box;

import java.io.InputStream;
import java.io.Reader;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.TimeZone;

import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.GET;
import javax.ws.rs.HeaderParam;
import javax.ws.rs.OPTIONS;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.Request;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;

import org.apache.http.HttpStatus;
import org.apache.wink.webdav.WebDAVMethod;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.fujitsu.dc.common.utils.DcCoreUtils;
import com.fujitsu.dc.core.DcCoreException;
import com.fujitsu.dc.core.annotations.ACL;
import com.fujitsu.dc.core.auth.AccessContext;
import com.fujitsu.dc.core.auth.BoxPrivilege;
import com.fujitsu.dc.core.bar.BarFileInstaller;
import com.fujitsu.dc.core.eventbus.DcEventBus;
import com.fujitsu.dc.core.eventbus.JSONEvent;
import com.fujitsu.dc.core.model.Box;
import com.fujitsu.dc.core.model.BoxCmp;
import com.fujitsu.dc.core.model.BoxRsCmp;
import com.fujitsu.dc.core.model.Cell;
import com.fujitsu.dc.core.model.DavCmp;
import com.fujitsu.dc.core.model.DavRsCmp;
import com.fujitsu.dc.core.model.ModelFactory;
import com.fujitsu.dc.core.model.ctl.Event;
import com.fujitsu.dc.core.model.ctl.Event.LEVEL;
import com.fujitsu.dc.core.model.progress.Progress;
import com.fujitsu.dc.core.model.progress.ProgressInfo;
import com.fujitsu.dc.core.model.progress.ProgressManager;
import com.fujitsu.dc.core.rs.cell.CellCtlResource;
import com.fujitsu.dc.core.rs.cell.EventResource;
import com.fujitsu.dc.core.rs.odata.ODataEntityResource;

/**
 * Box?JAX-RS.
 */
public final class BoxResource {
    static Logger log = LoggerFactory.getLogger(BoxResource.class);
    String boxName;

    Cell cell;
    Box box;
    AccessContext accessContext;
    DavRsCmp davRsCmp;
    DavCmp davCmp;
    DavRsCmp cellRsCmp; // for box Install

    /**
     * .
     * @param cell CELL Object
     * @param boxName Box Name
     * @param cellRsCmp cellRsCmp
     * @param accessContext AccessContext
     * @param request HTTP
     * @param jaxRsRequest JAX-RSHTTP
     */
    public BoxResource(final Cell cell, final String boxName, final AccessContext accessContext,
            final DavRsCmp cellRsCmp, final HttpServletRequest request, Request jaxRsRequest) {
        // ????????????boxName?????
        this.cell = cell;
        this.boxName = boxName;
        // this.path= path;
        this.accessContext = accessContext;

        // Box??
        // ??Box????????????????Box???????
        // ????box??Box????????????????????????
        // ?HTTP? MKCOL ?????
        // ?PathInfo? Box?? ????
        // Collection??MKCOL???????box??????
        this.box = this.cell.getBoxForName(boxName);
        // box??Cell??????
        this.cellRsCmp = cellRsCmp;
        if (this.box != null) {
            // ??Box???????BoxCmp??
            this.davCmp = ModelFactory.boxCmp(this.box);
            this.davRsCmp = new BoxRsCmp(davCmp, this.cell, this.accessContext, this.box);
        } else {
            String reqPathInfo = request.getPathInfo();
            if (!reqPathInfo.endsWith("/")) {
                reqPathInfo += "/";
            }
            String pathForBox = boxName;
            if (!pathForBox.endsWith("/")) {
                pathForBox += "/";
            }
            if (!("MKCOL".equals(jaxRsRequest.getMethod()) && reqPathInfo.endsWith(pathForBox))) {
                throw DcCoreException.Dav.BOX_NOT_FOUND.params(this.cell.getUrl() + boxName);
            }
        }

    }

    /*
     * ???URL???. ??Box?URL???
     * @see com.fujitsu.dc.core.rs.box.AbstractDavResource#getPathList()
     */

    /**
     * ??????Jax-RS?.
     * @param nextPath ????
     * @param request 
     * @return ??Jax-RS
     */
    @Path("{nextPath}")
    public Object nextPath(@PathParam("nextPath") final String nextPath, @Context HttpServletRequest request) {
        return this.davRsCmp.nextPath(nextPath, request);
    }

    /**
     * @return DavRsCmp
     */
    public DavRsCmp getDavRsCmp() {
        return this.davRsCmp;
    }

    /**
     * Box??????.
     * @return Box???
     */
    public String getName() {
        return this.boxName;
    }

    /**
     * @return Box 
     */
    public Box getBox() {
        return this.box;
    }

    /**
     * @return BoxCmp .
     */
    public BoxCmp getCmp() {
        return (BoxCmp) this.davCmp;
    }

    /**
     * @return AccessContext 
     */
    public AccessContext getAccessContext() {
        return accessContext;
    }

    /**
     * GET ?? .
     * @return JAX-RS Response
     */
    @GET
    public Response get() {

        // 
        this.davRsCmp.checkAccessContext(this.davRsCmp.getAccessContext(), BoxPrivilege.READ);

        // ?box???????
        // ???null?????????box????????
        // ???????????
        String key = "box-" + this.box.getId();
        Progress progress = ProgressManager.getProgress(key);
        if (progress == null) {
            JSONObject response = createNotRequestedResponse();
            return Response.ok().entity(response.toJSONString()).build();
        }

        String jsonString = progress.getValue();
        JSONObject jsonObj = null;
        try {
            jsonObj = (JSONObject) (new JSONParser()).parse(jsonString);
        } catch (ParseException e) {
            throw DcCoreException.Server.DATA_STORE_UNKNOWN_ERROR.reason(e);
        }

        // ????????box????????
        JSONObject barInfo = (JSONObject) jsonObj.get("barInfo");
        if (barInfo == null) {
            log.info("cache(" + key + "): process" + (String) jsonObj.get("process"));
            JSONObject response = createNotRequestedResponse();
            return Response.ok().entity(response.toJSONString()).build();
        }

        // box???????????
        JSONObject response = createResponse(barInfo);
        return Response.ok().entity(response.toJSONString()).build();
    }

    /**
     * box????????????????????.
     * @return ?JSON
     */
    @SuppressWarnings("unchecked")
    private JSONObject createNotRequestedResponse() {
        JSONObject response = new JSONObject();
        response.put("status", ProgressInfo.STATUS.COMPLETED.value());
        response.put("schema", this.getBox().getSchema());

        SimpleDateFormat sdfIso8601ExtendedFormatUtc = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
        sdfIso8601ExtendedFormatUtc.setTimeZone(TimeZone.getTimeZone("UTC"));
        String installedAt = sdfIso8601ExtendedFormatUtc.format(new Date(this.getBox().getPublished()));
        response.put("installed_at", installedAt);
        return response;
    }

    /**
     * box????????????????????.
     * @return ?JSON
     */
    @SuppressWarnings("unchecked")
    private JSONObject createResponse(JSONObject values) {
        JSONObject response = new JSONObject();
        response.putAll(values);
        response.remove("cell_id");
        response.remove("box_id");
        response.put("schema", this.getBox().getSchema());
        ProgressInfo.STATUS status = ProgressInfo.STATUS.valueOf((String) values.get("status"));
        if (status == ProgressInfo.STATUS.COMPLETED) {
            response.remove("progress");
            String startedAt = (String) response.remove("started_at");
            response.put("installed_at", startedAt);
        }
        response.put("status", status.value());
        return response;
    }

    /**
     * PROPFIND??.
     * @param requestBodyXml Request Body
     * @param depth Depth Header
     * @param contentLength Content-Length Header
     * @param transferEncoding Transfer-Encoding Header
     * @return JAX-RS Response
     */
    @WebDAVMethod.PROPFIND
    public Response propfind(final Reader requestBodyXml,
            @HeaderParam(DcCoreUtils.HttpHeaders.DEPTH) final String depth,
            @HeaderParam(HttpHeaders.CONTENT_LENGTH) final Long contentLength,
            @HeaderParam("Transfer-Encoding") final String transferEncoding) {

        return this.davRsCmp.doPropfind(requestBodyXml, depth, contentLength, transferEncoding,
                BoxPrivilege.READ_PROPERTIES, BoxPrivilege.READ_ACL);
    }

    /**
     * PROPPATCH??.
     * @param requestBodyXml Request Body
     * @return JAX-RS Response
     */
    @WebDAVMethod.PROPPATCH
    public Response proppatch(final Reader requestBodyXml) {
        // 
        this.davRsCmp.checkAccessContext(this.getAccessContext(), BoxPrivilege.WRITE_PROPERTIES);
        return this.davRsCmp.doProppatch(requestBodyXml);
    }

    /**
     * OPTIONS.
     * @return JAX-RS Response
     */
    @OPTIONS
    public Response options() {
        return this.davRsCmp.options();
    }

    /**
     * ACL??. ACL??.
     * @param reader XML
     * @return JAX-RS Response
     */
    @ACL
    public Response acl(final Reader reader) {
        // 
        this.davRsCmp.checkAccessContext(this.davRsCmp.getAccessContext(), BoxPrivilege.WRITE_ACL);
        return this.davRsCmp.doAcl(reader);
    }

    /**
     * MKCOL??. box?.
     * @param uriInfo UriInfo
     * @param dcCredHeader dcCredHeader
     * @param contentType Content-Type?
     * @param contentLength Content-Length?
     * @param requestKey ??RequestKey?
     * @param inStream Http?InputStream
     * @return JAX-RS Response
     */
    @WebDAVMethod.MKCOL
    public Response mkcol(@Context final UriInfo uriInfo,
            @HeaderParam(DcCoreUtils.HttpHeaders.X_DC_CREDENTIAL) final String dcCredHeader,
            @HeaderParam(HttpHeaders.CONTENT_TYPE) final String contentType,
            @HeaderParam(HttpHeaders.CONTENT_LENGTH) final String contentLength,
            @HeaderParam(DcCoreUtils.HttpHeaders.X_DC_REQUESTKEY) String requestKey, final InputStream inStream) {

        DcEventBus eventBus = new DcEventBus(this.cell);
        Event event = null;
        Response res = null;
        try {
            // 
            JSONEvent reqBody = new JSONEvent();
            reqBody.setAction(WebDAVMethod.MKCOL.toString());
            reqBody.setLevel(LEVEL.INFO);
            reqBody.setObject(this.cell.getUrl() + boxName);
            reqBody.setResult("");
            // X-Dc-RequestKey???????
            requestKey = EventResource.validateXDcRequestKey(requestKey);
            // TODO findBugs
            log.debug(requestKey);

            event = EventResource.createEvent(reqBody, requestKey, this.accessContext);
            // eventBus.outputEventLog(event);

            if (Box.DEFAULT_BOX_NAME.equals(this.boxName)) {
                throw DcCoreException.Misc.METHOD_NOT_ALLOWED;
            }

            // Box?????CellCtlResource?ODataEntityResource(ODataProducer)??
            // ???? "X-Dc-Credential" ??????null?
            CellCtlResource cellctl = new CellCtlResource(this.accessContext, null, this.cellRsCmp);
            String keyName = "'" + this.boxName + "'";
            ODataEntityResource odataEntity = new ODataEntityResource(cellctl, Box.EDM_TYPE_NAME, keyName);

            Map<String, String> headers = new HashMap<String, String>();
            headers.put(HttpHeaders.CONTENT_TYPE, contentType);
            headers.put(HttpHeaders.CONTENT_LENGTH, contentLength);

            // X-Dc-RequestKey???????
            BarFileInstaller installer = new BarFileInstaller(this.cell, this.boxName, odataEntity, uriInfo);

            res = installer.barFileInstall(headers, inStream, event.getRequestKey());
            event.setResult(Integer.toString(res.getStatus()));
        } catch (RuntimeException e) {
            // TODO ????
            if (e instanceof DcCoreException) {
                event.setResult(Integer.toString(((DcCoreException) e).getStatus()));
                if (((DcCoreException) e).getStatus() > HttpStatus.SC_INTERNAL_SERVER_ERROR) {
                    event.setLevel(LEVEL.WARN);
                } else {
                    event.setLevel(LEVEL.ERROR);
                }
            } else {
                event.setResult(Integer.toString(HttpStatus.SC_INTERNAL_SERVER_ERROR));
                event.setLevel(LEVEL.ERROR);
            }
            throw e;
        } finally {
            // 
            eventBus.outputEventLog(event);
        }
        return res;
    }
}