/** * 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.Reader; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.DELETE; import javax.ws.rs.GET; import javax.ws.rs.HeaderParam; import javax.ws.rs.HttpMethod; 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.Response; import org.apache.http.HttpStatus; import org.apache.wink.webdav.WebDAVMethod; 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.BoxPrivilege; import com.fujitsu.dc.core.model.DavCmp; import com.fujitsu.dc.core.model.DavMoveResource; import com.fujitsu.dc.core.model.DavRsCmp; /** * プレーンなWebDAVコレクションに対応するJAX-RS Resource クラス. */ public final class DavCollectionResource { DavRsCmp davRsCmp; /** * constructor. * @param parent 親 * @param davCmp 部品 */ public DavCollectionResource(final DavRsCmp parent, final DavCmp davCmp) { this.davRsCmp = new DavRsCmp(parent, davCmp); } /** * GETメソッドを処理してこのリソースを取得します. * @return JAX-RS Response Object */ @GET public Response get() { // アクセス制御 this.davRsCmp.checkAccessContext(this.davRsCmp.getAccessContext(), BoxPrivilege.READ); StringBuilder sb = new StringBuilder(); sb.append("URL : " + this.davRsCmp.getUrl() + "\n"); return Response.status(HttpStatus.SC_OK).entity(sb.toString()).build(); } /** * @param requestBodyXml Request Body * @return JAX-RS Response */ @WebDAVMethod.PROPPATCH public Response proppatch(final Reader requestBodyXml) { // アクセス制御 this.davRsCmp.checkAccessContext( this.davRsCmp.getAccessContext(), BoxPrivilege.WRITE_PROPERTIES); return this.davRsCmp.doProppatch(requestBodyXml); } /** * DELETEメソッドを処理してこのリソースを削除します. * @param recursiveHeader recursive header * @return JAX-RS応答オブジェクト */ @DELETE public Response delete(@HeaderParam(DcCoreUtils.HttpHeaders.X_DC_RECURSIVE) final String recursiveHeader) { boolean recursive = false; // X-Dc-Recursive Header if (recursiveHeader != null) { try { recursive = Boolean.valueOf(recursiveHeader); } catch (Exception e) { throw DcCoreException.Misc.PRECONDITION_FAILED.params(DcCoreUtils.HttpHeaders.X_DC_RECURSIVE); } } // アクセス制御(親の権限をチェックする) // DavCollectionResourceは必ず親(最上位はBox)を持つため、this.davRsCmp.getParent()の結果がnullになることはない this.davRsCmp.getParent().checkAccessContext(this.davRsCmp.getAccessContext(), BoxPrivilege.WRITE); if (!this.davRsCmp.getDavCmp().isEmpty()) { return Response.status(HttpStatus.SC_CONFLICT).entity("delete children first").build(); } return this.davRsCmp.getDavCmp().delete(null, recursive).build(); } /** * @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); } /** * 現在のリソースの一つ下位パスを担当する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); } /** * 405 (Method Not Allowed) - MKCOL can only be executed on a deleted/non-existent resource. * @return JAX-RS Response */ @WebDAVMethod.MKCOL public Response mkcol() { // アクセス制御 this.davRsCmp.checkAccessContext(this.davRsCmp.getAccessContext(), BoxPrivilege.WRITE); throw DcCoreException.Dav.METHOD_NOT_ALLOWED; } /** * 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); } /** * OPTIONSメソッド. * @return JAX-RS Response */ @OPTIONS public Response options() { // アクセス制御 this.davRsCmp.checkAccessContext(this.davRsCmp.getAccessContext(), BoxPrivilege.READ); return DcCoreUtils.responseBuilderForOptions( HttpMethod.GET, HttpMethod.PUT, HttpMethod.DELETE, com.fujitsu.dc.common.utils.DcCoreUtils.HttpMethod.MKCOL, com.fujitsu.dc.common.utils.DcCoreUtils.HttpMethod.MOVE, com.fujitsu.dc.common.utils.DcCoreUtils.HttpMethod.PROPFIND, com.fujitsu.dc.common.utils.DcCoreUtils.HttpMethod.PROPPATCH, com.fujitsu.dc.common.utils.DcCoreUtils.HttpMethod.ACL ).build(); } /** * MOVEメソッドの処理. * @param headers ヘッダ情報 * @return JAX-RS応答オブジェクト */ @WebDAVMethod.MOVE public Response move( @Context HttpHeaders headers) { // 移動元に対するアクセス制御(親の権限をチェックする) // DavCollectionResourceは必ず親(最上位はBox)を持つため、this.davRsCmp.getParent()の結果がnullになることはない this.davRsCmp.getParent().checkAccessContext(this.davRsCmp.getAccessContext(), BoxPrivilege.WRITE); return new DavMoveResource(this.davRsCmp.getParent(), this.davRsCmp.getDavCmp(), headers).doMove(); } }