/** * 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.model; import java.net.URI; import java.net.URISyntaxException; import java.util.List; import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.ResponseBuilder; import com.fujitsu.dc.core.DcCoreConfig; import com.fujitsu.dc.core.DcCoreException; /** * JaxRS Resource オブジェクトから処理の委譲を受けてDavのMoveに関する処理を行うクラス. */ public class DavMoveResource extends DavRsCmp { private String depth = null; private String overwrite = null; private String destination = null; private String ifMatch = null; /** * コンストラクタ. * @param parent 親リソース * @param davCmp バックエンド実装に依存する処理を受け持つ部品 * @param headers リクエストヘッダ情報 */ public DavMoveResource(DavRsCmp parent, DavCmp davCmp, HttpHeaders headers) { super(parent, davCmp); // リクエストヘッダから、移動に必要な情報を取得する depth = getFirstHeader(headers, org.apache.http.HttpHeaders.DEPTH, DavCommon.DEPTH_INFINITY); overwrite = getFirstHeader(headers, org.apache.http.HttpHeaders.OVERWRITE, DavCommon.OVERWRITE_FALSE); destination = getFirstHeader(headers, org.apache.http.HttpHeaders.DESTINATION); ifMatch = getFirstHeader(headers, HttpHeaders.IF_MATCH, "*"); } /** * MOVEメソッドの処理. * @return JAX-RS応答オブジェクト */ public Response doMove() { // リクエストヘッダのバリデート validateHeaders(); // 移動先のBox情報を取得する BoxRsCmp boxRsCmp = getBoxRsCmp(); // 移動先の情報を生成 DavDestination davDestination; try { davDestination = new DavDestination(destination, this.getAccessContext().getBaseUri(), boxRsCmp); } catch (URISyntaxException e) { // URI 形式でない throw DcCoreException.Dav.INVALID_REQUEST_HEADER.params(org.apache.http.HttpHeaders.DESTINATION, destination); } // データの更新・削除 ResponseBuilder response = this.davCmp.move(this.ifMatch, this.overwrite, davDestination); return response.build(); } private BoxRsCmp getBoxRsCmp() { // 最上位にあるBoxのリソース情報を取得する DavRsCmp davRsCmp = this; for (int i = 0; i <= DcCoreConfig.getMaxCollectionDepth(); i++) { DavRsCmp parent = davRsCmp.getParent(); if (null == parent) { break; } davRsCmp = parent; } // 最上位までたどった結果をBoxとして扱う BoxRsCmp boxRsCmp = (BoxRsCmp) davRsCmp; return boxRsCmp; } /** * Moveメソッドに関するヘッダのバリデートを行う. <br /> * バリデートに失敗した場合は、例外をスローする. * @param headers ヘッダ情報 */ void validateHeaders() { // Depth ヘッダ if (!DavCommon.DEPTH_INFINITY.equalsIgnoreCase(depth)) { throw DcCoreException.Dav.INVALID_DEPTH_HEADER.params(depth); } // Overwrite ヘッダ if (!DavCommon.OVERWRITE_FALSE.equalsIgnoreCase(overwrite) && !DavCommon.OVERWRITE_TRUE.equalsIgnoreCase(overwrite)) { throw DcCoreException.Dav.INVALID_REQUEST_HEADER.params(org.apache.http.HttpHeaders.OVERWRITE, overwrite); } // Destination ヘッダ if (destination == null || destination.length() <= 0) { throw DcCoreException.Dav.REQUIRED_REQUEST_HEADER_NOT_EXIST .params(org.apache.http.HttpHeaders.DESTINATION); } if (this.getUrl().equals(destination)) { // 移動元と移動先が等しい場合はエラーとする throw DcCoreException.Dav.DESTINATION_EQUALS_SOURCE_URL.params(destination); } DavPath destinationPath = getDestination(); if (!this.getAccessContext().getBaseUri().equals(destinationPath.getBaseUri())) { // スキーマ、ホストが移動元、移動先で異なる場合はエラーとする throw DcCoreException.Dav.INVALID_REQUEST_HEADER.params( org.apache.http.HttpHeaders.DESTINATION, destination); } if (!this.getCell().getName().equals(destinationPath.getCellName()) || !this.getBox().getName().equals(destinationPath.getBoxName())) { // Cell、Box が移動元、移動先で異なる場合はエラーとする throw DcCoreException.Dav.INVALID_REQUEST_HEADER.params( org.apache.http.HttpHeaders.DESTINATION, destination); } } /** * 移動先のオブジェクのパス情報を作成して返却する. * @return DavPath 移動先のリソースパスを管理するオブジェクト */ private DavPath getDestination() { URI destUri; try { destUri = new URI(destination); } catch (URISyntaxException e) { // URI 形式でない throw DcCoreException.Dav.INVALID_REQUEST_HEADER.params(org.apache.http.HttpHeaders.DESTINATION, destination); } return new DavPath(destUri, this.getAccessContext().getBaseUri()); } /** * ヘッダ情報から指定されたキーのヘッダを取得する. <br /> * 存在しない場合はnullを返却する. * @param headers ヘッダ情報 * @param key 取得するヘッダのキー * @return 指定されたキーのヘッダ */ private String getFirstHeader(HttpHeaders headers, String key) { return this.getFirstHeader(headers, key, null); } /** * ヘッダ情報から指定されたキーのヘッダを取得する. <br /> * 存在しない場合はnullを返却する. * @param headers ヘッダ情報 * @param key 取得するヘッダのキー * @param defaultValue ヘッダが存在しない場合のデフォルト値 * @return 指定されたキーのヘッダ */ private String getFirstHeader(HttpHeaders headers, String key, String defaultValue) { List<String> header = headers.getRequestHeader(key); if (header != null && header.size() > 0) { return header.get(0); } return defaultValue; } }