/**
* 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.cell;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;
import javax.ws.rs.core.UriInfo;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import org.odata4j.core.OCollection;
import org.odata4j.core.OCollections;
import org.odata4j.core.OComplexObjects;
import org.odata4j.core.ODataConstants;
import org.odata4j.core.ODataVersion;
import org.odata4j.core.OEntity;
import org.odata4j.core.OEntityKey;
import org.odata4j.core.OObject;
import org.odata4j.core.OProperties;
import org.odata4j.core.OProperty;
import org.odata4j.edm.EdmCollectionType;
import org.odata4j.edm.EdmComplexType;
import org.odata4j.edm.EdmEntitySet;
import org.odata4j.producer.EntitiesResponse;
import org.odata4j.producer.EntityResponse;
import org.odata4j.producer.InlineCount;
import org.odata4j.producer.QueryInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.fujitsu.dc.common.auth.token.Role;
import com.fujitsu.dc.common.auth.token.TransCellAccessToken;
import com.fujitsu.dc.common.utils.DcCoreUtils;
import com.fujitsu.dc.core.DcCoreException;
import com.fujitsu.dc.core.auth.OAuth2Helper;
import com.fujitsu.dc.core.model.ctl.Common;
import com.fujitsu.dc.core.model.ctl.CtlSchema;
import com.fujitsu.dc.core.model.ctl.ExtCell;
import com.fujitsu.dc.core.model.ctl.ReceivedMessage;
import com.fujitsu.dc.core.model.ctl.ReceivedMessagePort;
import com.fujitsu.dc.core.model.ctl.Relation;
import com.fujitsu.dc.core.model.ctl.SentMessage;
import com.fujitsu.dc.core.model.ctl.SentMessagePort;
import com.fujitsu.dc.core.model.impl.es.odata.CellCtlODataProducer;
import com.fujitsu.dc.core.odata.DcODataProducer;
import com.fujitsu.dc.core.odata.OEntityWrapper;
import com.fujitsu.dc.core.rs.odata.AbstractODataResource;
import com.fujitsu.dc.core.rs.odata.ODataResource;
import com.fujitsu.dc.core.utils.HttpClientFactory;
import com.fujitsu.dc.core.utils.ODataUtils;
import com.fujitsu.dc.core.utils.ResourceUtils;
/**
* __messageのOData操作クラス.
*/
public final class MessageODataResource extends AbstractODataResource {
static Logger log = LoggerFactory.getLogger(MessageODataResource.class);
private MessageResource odataResource;
private Map<String, String> propMap = new HashMap<String, String>();
private String version;
/** 最大送信許可数. */
private static final int MAX_SENT_NUM = 1000;
/**
* constructor.
* @param odataResource ODataリソース
* @param producer ODataプロデューサ
* @param entityTypeName エンティティタイプ名
*/
public MessageODataResource(MessageResource odataResource, DcODataProducer producer, String entityTypeName) {
this.odataResource = odataResource;
setOdataProducer(producer);
setEntitySetName(entityTypeName);
}
/**
* personium Version情報のセット.
* @param version セットする version
*/
public void setVersion(String version) {
this.version = version;
}
/**
* 受信/送信メッセージEntityを作成する.
* @param uriInfo URL情報
* @param reader リクエストボディ
* @return response情報
*/
protected Response createMessage(UriInfo uriInfo,
Reader reader) {
// response用URLに__ctlを追加する
UriInfo resUriInfo = DcCoreUtils.createUriInfo(uriInfo, 2, "__ctl");
// Entityの作成を Producerに依頼
OEntityWrapper oew = getOEntityWrapper(reader, odataResource, CtlSchema.getEdmDataServicesForMessage().build());
EntityResponse res = getOdataProducer().createEntity(getEntitySetName(), oew);
// レスポンスボディを生成する
OEntity ent = res.getEntity();
MediaType outputFormat = MediaType.APPLICATION_JSON_TYPE;
List<MediaType> contentTypes = new ArrayList<MediaType>();
contentTypes.add(MediaType.APPLICATION_JSON_TYPE);
String key = AbstractODataResource.replaceDummyKeyToNull(ent.getEntityKey().toKeyString());
String responseStr = renderEntityResponse(resUriInfo, res, "json", contentTypes);
// 制御コードのエスケープ処理
responseStr = escapeResponsebody(responseStr);
ResponseBuilder rb = getPostResponseBuilder(ent, outputFormat, responseStr, resUriInfo, key);
return rb.build();
}
/**
* 受信メッセージステータスを変更する.
* @param reader リクエストボディ
* @param key メッセージId
* @return response情報
*/
protected Response changeMessageStatus(Reader reader, String key) {
JSONObject body;
try {
body = ResourceUtils.parseBodyAsJSON(reader);
} catch (IOException e1) {
throw DcCoreException.OData.JSON_PARSE_ERROR.reason(e1);
} catch (ParseException e1) {
throw DcCoreException.OData.JSON_PARSE_ERROR.reason(e1);
}
String status = (String) body.get(ReceivedMessage.MESSAGE_COMMAND);
// ステータスのチェック
if (!ReceivedMessage.STATUS_UNREAD.equals(status)
&& !ReceivedMessage.STATUS_READ.equals(status)
&& !ReceivedMessage.STATUS_APPROVED.equals(status)
&& !ReceivedMessage.STATUS_REJECTED.equals(status)) {
throw DcCoreException.OData.REQUEST_FIELD_FORMAT_ERROR.params(ReceivedMessage.MESSAGE_COMMAND);
}
// EdmEntitySetの取得
EdmEntitySet edmEntitySet = getOdataProducer().getMetadata()
.getEdmEntitySet(ReceivedMessagePort.EDM_TYPE_NAME);
// OEntityKeyの作成
OEntityKey oEntityKey;
try {
oEntityKey = OEntityKey.parse("('" + key + "')");
} catch (IllegalArgumentException e) {
throw DcCoreException.OData.ENTITY_KEY_PARSE_ERROR.reason(e);
}
// ステータス更新、及び関係登録/削除をProducerに依頼
String etag = ((CellCtlODataProducer) getOdataProducer()).changeStatusAndUpdateRelation(
edmEntitySet, oEntityKey, status);
return Response.noContent()
.header(HttpHeaders.ETAG, ODataResource.renderEtagHeader(etag))
.header(ODataConstants.Headers.DATA_SERVICE_VERSION, ODataVersion.V2.asString)
.build();
}
/**
* プロパティ操作.
* @param props プロパティ一覧
* @param id メッセージのID
*/
@Override
protected void editProperty(List<OProperty<?>> props, String id) {
if (ReceivedMessage.EDM_TYPE_NAME.equals(this.getEntitySetName())) {
for (int i = 0; i < props.size(); i++) {
if (ReceivedMessagePort.P_SCHEMA.getName().equals(props.get(i).getName())) {
// メッセージ受信でSchemaはデータとして保持しないため、削除する
props.remove(i);
} else if (ReceivedMessagePort.P_BOX_NAME.getName().equals(props.get(i).getName())) {
// メッセージ受信で_Box.Nameはデータとして保持しないるため置き換える
props.set(i, OProperties.string(ReceivedMessagePort.P_BOX_NAME.getName(), (String) null));
}
}
} else if (SentMessage.EDM_TYPE_NAME.equals(this.getEntitySetName())) {
EdmCollectionType collectionType = new EdmCollectionType(SentMessage.P_RESULT.getCollectionKind(),
SentMessage.P_RESULT.getType());
// 受信APIの呼び出し、呼出し結果を送信メッセージのResultsにセット
OCollection.Builder<OObject> builder = requestReceivedMessage(collectionType, id);
// ComplexTypeの配列要素をプロパティに追加する
props.add(OProperties.collection(SentMessage.P_RESULT.getName(), collectionType, builder.build()));
for (int i = 0; i < props.size(); i++) {
if (SentMessagePort.P_BOX_BOUND.getName().equals(props.get(i).getName())) {
// メッセージ送信でBoxBoundはデータとして保持しないため、削除する
props.remove(i);
} else if (SentMessagePort.P_BOX_NAME.getName().equals(props.get(i).getName())) {
// メッセージ受信で_Box.Nameはデータとして保持しているため置き換える
props.set(i, OProperties.string(SentMessagePort.P_BOX_NAME.getName(), (String) null));
} else if (SentMessagePort.P_RESULT.getName().equals(props.get(i).getName())) {
// メッセージ受信でResultはデータとして保持しているため置き換える
props.set(i, OProperties.collection(SentMessage.P_RESULT.getName(),
collectionType, builder.build()));
}
}
}
}
/**
* メッセージ受信APIを呼出す.
* @param collectionType EdmCollectionType
* @param idKey 送信メッセージのIDキー
* @return メッセージ受信の結果
*/
private OCollection.Builder<OObject> requestReceivedMessage(
final EdmCollectionType collectionType,
String idKey) {
OCollection.Builder<OObject> builder = OCollections.<OObject>newBuilder(collectionType.getItemType());
// ComplexTypeの型情報を取得する
EdmComplexType ct = SentMessage.COMPLEXTYPE_BUILDER.build();
String fromCellUrl = this.odataResource.getAccessContext().getCell().getUrl();
// 宛先リスト作成
List<String> toList = createRequestUrl();
// リクエストの件数分繰り返し
for (String toCellUrl : toList) {
List<OProperty<?>> result = null;
toCellUrl = formatCellUrl(toCellUrl);
// 受信API呼出しのトークン作成
TransCellAccessToken token = new TransCellAccessToken(
fromCellUrl, fromCellUrl, toCellUrl, new ArrayList<Role>(), "");
// ('ID')からIDを抜き出す
Pattern formatPattern = Pattern.compile("\\('(.+)'\\)");
Matcher formatMatcher = formatPattern.matcher(idKey);
formatMatcher.matches();
String id = formatMatcher.group(1);
// 受信API呼出しのリクエストボディ作成
JSONObject requestBody = createRequestJsonBody(fromCellUrl, toCellUrl, toList, id);
// 受信API呼出し
result = requestHttpReceivedMessage(token, toCellUrl, requestBody);
// 呼出し結果を配列に追加する
builder.add(OComplexObjects.create(ct, result));
}
return builder;
}
/**
* 宛先リスト作成.
* @return 送信先のCellURLのリスト
*/
private List<String> createRequestUrl() {
List<String> toList = new ArrayList<String>();
String requestToStr = null;
String requestToRelationStr = null;
requestToStr = this.propMap.get(SentMessage.P_TO.getName());
requestToRelationStr = this.propMap.get(SentMessage.P_TO_RELATION.getName());
// リクエストボディのTo項目からCellURLを取得
if (requestToStr != null) {
String[] uriList = requestToStr.split(",");
for (String uri : uriList) {
toList.add(uri);
}
}
// リクエストボディのToRelation項目からCellURLを取得する
if (requestToRelationStr != null) {
List<String> extCellUrlList = getExtCellListFromToRelation(requestToRelationStr);
toList.addAll(extCellUrlList);
}
List<String> formatToList = new ArrayList<String>();
// 宛先リストの整形
for (String to : toList) {
// 末尾に"/"を追加
if (!to.endsWith("/")) {
to += "/";
}
// ToとToRelationで重複している送信先を省く
if (!formatToList.contains(to)) {
formatToList.add(to);
}
}
checkMaxDestinationsSize(formatToList.size());
return formatToList;
}
/**
* ToRelationで指定されたRelationにも付くExtCellのURL一覧を取得する.
* @param toRelation ToRelationのプロパティ値
* @return extCellUrlList ExtCellのURL一覧
*/
protected List<String> getExtCellListFromToRelation(String toRelation) {
List<String> extCellUrlList = new ArrayList<String>();
String keyString = AbstractODataResource.replaceNullToDummyKeyWithParenthesis(
"'" + toRelation + "'");
OEntityKey oEntityKey = OEntityKey.parse(keyString);
EntitiesResponse response = null;
try {
QueryInfo query = new QueryInfo(InlineCount.ALLPAGES, MAX_SENT_NUM,
null, null, null, null, null, null, null);
response = (EntitiesResponse) getOdataProducer().getNavProperty(
Relation.EDM_TYPE_NAME,
oEntityKey,
"_" + ExtCell.EDM_TYPE_NAME,
query);
} catch (DcCoreException e) {
if (DcCoreException.OData.NO_SUCH_ENTITY.getCode().equals(e.getCode())) {
// ToRelationで指定されたRelationが存在しない場合は400エラーを返却
throw DcCoreException.SentMessage.TO_RELATION_NOT_FOUND_ERROR.params(toRelation);
} else {
throw e;
}
}
// ToRelationから取得したExtCellのURLを追加する
List<OEntity> extCellEntities = response.getEntities();
checkMaxDestinationsSize(response.getInlineCount());
for (OEntity extCell : extCellEntities) {
extCellUrlList.add(extCell.getProperty(ExtCell.P_URL.getName()).getValue().toString());
}
if (extCellUrlList.isEmpty()) {
// ToRelationで指定されたRelationに紐付くExtCellが存在しない場合は400エラーを返却
throw DcCoreException.SentMessage.RELATED_EXTCELL_NOT_FOUND_ERROR.params(toRelation);
}
return extCellUrlList;
}
/**
* 送信先URLが最大送信許可数を超えているかチェック.
* @param destinationsSize 送信先URLの件数
*/
public void checkMaxDestinationsSize(int destinationsSize) {
if (destinationsSize > MAX_SENT_NUM) {
throw DcCoreException.SentMessage.OVER_MAX_SENT_NUM;
}
}
/**
* メッセージ受信API呼出しのリクエストボディ作成.
* @param fromCellUrl 送信元CellURL
* @param targetCellUrl 送信先CellURL
* @param toList 宛先リスト
* @param id 受信メッセージのID
* @return リクエストボディ
*/
@SuppressWarnings("unchecked")
private JSONObject createRequestJsonBody(String fromCellUrl, String targetCellUrl, List<String> toList, String id) {
JSONObject requestBody = new JSONObject();
String type = this.propMap.get(SentMessage.P_TYPE.getName());
// Statusの設定
String status = null;
if (ReceivedMessage.TYPE_MESSAGE.equals(type)) {
status = ReceivedMessage.STATUS_UNREAD;
} else {
status = ReceivedMessage.STATUS_NONE;
}
// MulticastToの設定
String multicastTo = null;
StringBuilder sbMulticastTo = null;
for (String to : toList) {
String formatTo = formatCellUrl(to);
if (!formatTo.equals(targetCellUrl)) {
if (sbMulticastTo == null) {
sbMulticastTo = new StringBuilder();
} else {
sbMulticastTo.append(",");
}
sbMulticastTo.append(formatTo);
}
}
if (sbMulticastTo != null) {
multicastTo = sbMulticastTo.toString();
}
requestBody.put(ReceivedMessage.P_ID.getName(), id);
requestBody.put(ReceivedMessage.P_IN_REPLY_TO.getName(), this.propMap.get(SentMessage.P_IN_REPLY_TO.getName()));
requestBody.put(ReceivedMessage.P_FROM.getName(), fromCellUrl);
requestBody.put(ReceivedMessage.P_MULTICAST_TO.getName(), multicastTo);
requestBody.put(ReceivedMessage.P_TYPE.getName(), type);
requestBody.put(ReceivedMessage.P_TITLE.getName(), this.propMap.get(SentMessage.P_TITLE.getName()));
requestBody.put(ReceivedMessage.P_BODY.getName(), this.propMap.get(SentMessage.P_BODY.getName()));
requestBody.put(ReceivedMessage.P_PRIORITY.getName(),
Integer.valueOf(this.propMap.get(SentMessage.P_PRIORITY.getName())));
requestBody.put(ReceivedMessage.P_STATUS.getName(), status);
requestBody.put(ReceivedMessage.P_REQUEST_RELATION.getName(),
this.propMap.get(SentMessage.P_REQUEST_RELATION.getName()));
requestBody.put(ReceivedMessage.P_REQUEST_RELATION_TARGET.getName(),
this.propMap.get(SentMessage.P_REQUEST_RELATION_TARGET.getName()));
return requestBody;
}
/**
* CellURLの書式を整形する.
* @param cellUrl cellのUrl
* @return 整形後の値
*/
private String formatCellUrl(String cellUrl) {
String formatCellUrl = cellUrl;
if (!cellUrl.endsWith("/")) {
formatCellUrl += "/";
}
return formatCellUrl;
}
/**
* メッセージ受信API呼出し.
* @param token トークン
* @param requestCellUrl リクエスト先CellURL
* @param jsonBody リクエストボディ
* @return リクエスト結果
*/
private List<OProperty<?>> requestHttpReceivedMessage(
TransCellAccessToken token,
String requestCellUrl,
JSONObject jsonBody) {
String requestUrl = requestCellUrl + "__message/port";
// リクエストヘッダを取得し、以下内容を追加
HttpClient client = HttpClientFactory.create(HttpClientFactory.TYPE_INSECURE);
HttpPost req = new HttpPost(requestUrl);
// リクエストボディ
StringEntity body = null;
try {
body = new StringEntity(jsonBody.toJSONString(), "UTF-8");
} catch (UnsupportedEncodingException e) {
throw DcCoreException.SentMessage.SM_BODY_PARSE_ERROR.reason(e);
}
req.setEntity(body);
req.addHeader(DcCoreUtils.HttpHeaders.X_DC_VERSION, this.version);
req.addHeader(HttpHeaders.AUTHORIZATION, OAuth2Helper.Scheme.BEARER_CREDENTIALS_PREFIX + token.toTokenString());
req.addHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON);
req.addHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON);
// リクエストを投げる
HttpResponse objResponse = null;
try {
objResponse = client.execute(req);
} catch (Exception ioe) {
throw DcCoreException.SentMessage.SM_CONNECTION_ERROR.reason(ioe);
}
// リクエスト結果の作成
String statusCode = Integer.toString(objResponse.getStatusLine().getStatusCode());
List<OProperty<?>> properties = new ArrayList<OProperty<?>>();
properties.add(OProperties.string(SentMessage.P_RESULT_TO.getName(), requestCellUrl));
properties.add(OProperties.string(SentMessage.P_RESULT_CODE.getName(), statusCode));
if (Integer.toString(HttpStatus.SC_CREATED).equals(statusCode)) {
properties.add(OProperties.string(SentMessage.P_RESULT_REASON.getName(), "Created."));
} else {
properties.add(OProperties.string(SentMessage.P_RESULT_REASON.getName(), getErrorMessage(objResponse)));
}
return properties;
}
/**
* HttpResponseからメッセージ取得.
* @param objResponse HttpResponse
* @return メッセージ
*/
private String getErrorMessage(HttpResponse objResponse) {
JSONObject resBody = bodyAsJson(objResponse);
String message = "";
try {
if (resBody != null) {
message = (String) ((JSONObject) resBody.get("message")).get("value");
}
} catch (Exception e) {
log.info(e.getMessage());
}
return message;
}
/**
* HttpResponseからJSON型のボディ取得.
* @param objResponse HttpResponse
* @return ボディ
*/
private JSONObject bodyAsJson(HttpResponse objResponse) {
JSONObject body = null;
InputStream is = null;
InputStreamReader isr = null;
BufferedReader reader = null;
String bodyString = null;
try {
objResponse.getHeaders("Content-Encoding");
is = objResponse.getEntity().getContent();
isr = new InputStreamReader(is, "UTF-8");
reader = new BufferedReader(isr);
StringBuffer sb = new StringBuffer();
int chr;
while ((chr = is.read()) != -1) {
sb.append((char) chr);
}
bodyString = sb.toString();
} catch (IllegalStateException e) {
log.info(e.getMessage());
} catch (IOException e) {
log.info(e.getMessage());
} finally {
try {
if (reader != null) {
reader.close();
}
if (isr != null) {
isr.close();
}
if (is != null) {
is.close();
}
} catch (IOException e) {
log.info(e.getMessage());
}
}
try {
if (bodyString != null) {
body = (JSONObject) new JSONParser().parse(bodyString);
}
} catch (ParseException e) {
log.info(e.getMessage());
}
return body;
}
/**
* 個別バリデート処理.
* @param props OProperty一覧
*/
@Override
public void validate(List<OProperty<?>> props) {
// メッセージ受信のときのチェック
if (ReceivedMessage.EDM_TYPE_NAME.equals(this.getEntitySetName())) {
MessageODataResource.validateUriCsv(ReceivedMessage.P_MULTICAST_TO.getName(),
propMap.get(ReceivedMessage.P_MULTICAST_TO.getName()));
MessageODataResource.validateBody(propMap.get(ReceivedMessage.P_BODY.getName()),
Common.MAX_MESSAGE_BODY_LENGTH);
MessageODataResource.validateStatus(propMap.get(ReceivedMessage.P_TYPE.getName()),
propMap.get(ReceivedMessage.P_STATUS.getName()));
MessageODataResource.validateReqRelation(propMap.get(ReceivedMessage.P_TYPE.getName()),
propMap.get(ReceivedMessage.P_REQUEST_RELATION.getName()),
propMap.get(ReceivedMessage.P_REQUEST_RELATION_TARGET.getName()));
}
// メッセージ送信のときのチェック
if (SentMessage.EDM_TYPE_NAME.equals(this.getEntitySetName())) {
MessageODataResource.validateUriCsv(SentMessage.P_TO.getName(), propMap.get(SentMessage.P_TO.getName()));
MessageODataResource.validateBody(propMap.get(SentMessage.P_BODY.getName()),
Common.MAX_MESSAGE_BODY_LENGTH);
MessageODataResource.validateToAndToRelation(
propMap.get(SentMessage.P_TO.getName()),
propMap.get(SentMessage.P_TO_RELATION.getName()));
MessageODataResource.validateToValue(
propMap.get(SentMessage.P_TO.getName()),
this.odataResource.getAccessContext().getBaseUri());
MessageODataResource.validateReqRelation(propMap.get(SentMessage.P_TYPE.getName()),
propMap.get(SentMessage.P_REQUEST_RELATION.getName()),
propMap.get(SentMessage.P_REQUEST_RELATION_TARGET.getName()));
}
}
/**
* プロパティの一覧取得.
* @param props プロパティ一覧
* @param
*/
@Override
public void collectProperties(List<OProperty<?>> props) {
for (OProperty<?> property : props) {
if (property.getValue() == null) {
propMap.put(property.getName(), null);
} else {
propMap.put(property.getName(), property.getValue().toString());
}
}
}
/**
* MulticastToのバリデート.
* @param propKey プロパティキー
* @param propValue プロパティ値
*/
public static void validateUriCsv(String propKey, String propValue) {
if (propValue == null) {
return;
}
if (propValue.contains(",")) {
// CSV形式で複数指定されていた場合
String[] uriList = propValue.split(",");
for (String uri : uriList) {
if (uri.length() != 0) {
if (!ODataUtils.isValidUri(uri)) {
throw DcCoreException.OData.REQUEST_FIELD_FORMAT_ERROR.params(propKey);
}
} else {
throw DcCoreException.OData.REQUEST_FIELD_FORMAT_ERROR.params(propKey);
}
}
} else {
// CSV形式で複数指定されていた場合
if (!ODataUtils.isValidUri(propValue)) {
throw DcCoreException.OData.REQUEST_FIELD_FORMAT_ERROR.params(propValue);
}
}
}
/**
* Toで指定されたリクエスト先がbaseUrlのホストと一致するかのチェック.
* @param toValue toで指定された値
* @param baseUrl baseUrl
*/
public static void validateToValue(String toValue, String baseUrl) {
if (toValue == null) {
return;
}
// リクエストURLのドメインチェック
String checkBaseUrl = null;
String[] uriList = toValue.split(",");
for (String uriStr : uriList) {
try {
URI uri = new URI(uriStr);
checkBaseUrl = uri.getScheme() + "://" + uri.getHost();
int port = uri.getPort();
if (port != -1) {
checkBaseUrl += ":" + Integer.toString(port);
}
checkBaseUrl += "/";
} catch (URISyntaxException e) {
log.info(e.getMessage());
throw DcCoreException.OData.REQUEST_FIELD_FORMAT_ERROR.params(SentMessage.P_TO.getName());
}
if (checkBaseUrl == null || !checkBaseUrl.equals(baseUrl)) {
throw DcCoreException.OData.REQUEST_FIELD_FORMAT_ERROR.params(SentMessage.P_TO.getName());
}
}
}
/**
* Bodyのバリデート.
* @param value チェック対象値
* @param maxLength 最大長
*/
public static void validateBody(String value, int maxLength) {
if (value.getBytes().length > maxLength) {
throw DcCoreException.OData.REQUEST_FIELD_FORMAT_ERROR.params(ReceivedMessage.P_BODY.getName());
}
}
/**
* Statusのバリデート.
* @param type タイプ
* @param status ステータス
*/
public static void validateStatus(String type, String status) {
// Typeがmessageの場合unread:未読
// Typeがreq.relation.build/req.relation.breakの場合 none:未決
if (!(ReceivedMessage.TYPE_MESSAGE.equals(type) && ReceivedMessage.STATUS_UNREAD.equals(status))
&& !((ReceivedMessage.TYPE_REQ_RELATION_BUILD.equals(type)
|| ReceivedMessage.TYPE_REQ_RELATION_BREAK.equals(type))
&& ReceivedMessage.STATUS_NONE.equals(status))) {
throw DcCoreException.OData.REQUEST_FIELD_FORMAT_ERROR.params(ReceivedMessage.P_STATUS.getName());
}
}
/**
* RequestRelationのバリデート.
* @param type タイプ
* @param requestRelation 関係登録依頼リレーションクラスURL
* @param requestRelationTarget 関係登録依頼CellURL
*/
public static void validateReqRelation(String type, String requestRelation, String requestRelationTarget) {
if ((ReceivedMessage.TYPE_REQ_RELATION_BUILD.equals(type)
|| ReceivedMessage.TYPE_REQ_RELATION_BREAK.equals(type))
&& (requestRelation == null || requestRelationTarget == null)) {
String detail = ReceivedMessage.P_REQUEST_RELATION.getName()
+ "," + ReceivedMessage.P_REQUEST_RELATION_TARGET.getName();
throw DcCoreException.OData.REQUEST_FIELD_FORMAT_ERROR.params(detail);
}
}
/**
* To-ToRelationのバリデート.
* @param to 送信先セルURL
* @param toRelation 送信対象の関係名
*/
public static void validateToAndToRelation(String to, String toRelation) {
if (to == null && toRelation == null) {
String detail = SentMessage.P_TO.getName() + "," + SentMessage.P_TO_RELATION.getName();
throw DcCoreException.OData.REQUEST_FIELD_FORMAT_ERROR.params(detail);
}
}
}