/** * 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); } } }