/**
* 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.client;
import java.util.HashMap;
import org.json.simple.JSONObject;
import com.fujitsu.dc.client.http.DcResponse;
import com.fujitsu.dc.client.http.IRestAdapter;
import com.fujitsu.dc.client.http.RestAdapter;
import com.fujitsu.dc.client.http.RestAdapterFactory;
import com.fujitsu.dc.client.utils.Utils;
///**
// * OData関連の各機能を生成/削除するためのクラスの抽象クラス.
// */
/**
* It creates a new object of ODataManager. This is the abstract class for generating / deleting the OData related
* functions and serves as middle layer in API calls for CRUD operations.
*/
public class ODataManager implements IODataManager {
// /** アクセス主体. */
/** Reference to Accessor. */
Accessor accessor;
// /** DAVコレクション. */
/** Reference to DcCollection. */
DcCollection collection;
// /** EntitySet名. */
/** EntitySet Name. */
String entitySetName;
/** EntityID. */
String keyPredicate;
/** NavigationProperty. */
String naviProperty;
// /**
// * コンストラクタ.
// * @param as アクセス主体
// */
/**
* This is the parameterized constructor with one argument initializing the accessor.
* @param as Accessor
*/
public ODataManager(Accessor as) {
this.accessor = as.clone();
}
// /**
// * コンストラクタ.
// * @param as アクセス主体
// * @param col DAVコレクション
// */
/**
* This is the parameterized constructor with two arguments calling its own constructor and initializing collection.
* @param as Accessor
* @param col DcCollection
*/
public ODataManager(Accessor as, DcCollection col) {
this(as);
this.collection = col;
}
// /**
// * コンストラクタ.
// * @param as アクセス主体
// * @param col DAVコレクション
// * @param name EntitySet名
// */
/**
* This is the parameterized constructor with three arguments calling its own constructor and initializing other
* class variables.
* @param as Accessor
* @param col DcCollection
* @param name EntitySetName
*/
public ODataManager(Accessor as, DcCollection col, String name) {
this(as);
this.collection = col;
this.entitySetName = name;
}
// /**
// * IDをEntitySet指定する.
// * @param key keyPredicate
// * @return EntitySetオブジェクト
// */
/**
* This method sets key for EntityID.
* @param key keyPredicate
* @return EntitySet object
*/
public ODataManager key(String key) {
this.keyPredicate = key;
return this;
}
// /**
// * navigationPropertyをEntitySet指定する.
// * @param navProp NavigationProperty
// * @return EntitySetオブジェクト
// */
/**
* This method specifies the EntitySet navigationProperty.
* @param navProp NavigationProperty
* @return EntitySet object
*/
public ODataManager nav(String navProp) {
this.naviProperty = navProp;
return this;
}
// /**
// * ベースURL取得.
// * @return ベースURL
// */
/**
* This method returns the Base URL for making a connection.
* @return BaseURL value
*/
public String getBaseUrl() {
return this.accessor.getContext().getBaseUrl();
}
// /**
// * ODataデータを作成.
// * @param body POSTするリクエストボディ
// * @return 対象となるODataContextを抽象クラスとして返却
// * @throws DaoException DAO例外
// */
/**
* This method performs create operation using request body.
* @param body POST Request Body
* @return JSONObject as response
* @throws DaoException Exception thrown
*/
JSONObject internalCreate(HashMap<String, Object> body) throws DaoException {
String url = this.getUrl();
IRestAdapter rest = RestAdapterFactory.create(accessor);
DcResponse res = rest.post(url, JSONObject.toJSONString(body), RestAdapter.CONTENT_TYPE_JSON);
JSONObject json = (JSONObject) ((JSONObject) res.bodyAsJson().get("d")).get("results");
return json;
}
// /**
// * ODataデータを作成.
// * @param body POSTするリクエストボディ
// * @param headers POSTするリクエストヘッダー
// * @return 対象となるODataContextを抽象クラスとして返却
// * @throws DaoException DAO例外
// */
/**
* This method performs create operation using request body and headers.
* @param body POST Request Body
* @param headers POST Request Headers
* @return JSONObject as response
* @throws DaoException Exception thrown
*/
JSONObject internalCreate(HashMap<String, Object> body, HashMap<String, String> headers) throws DaoException {
String url = this.getUrl();
IRestAdapter rest = RestAdapterFactory.create(accessor);
DcResponse res = rest.post(url, headers, JSONObject.toJSONString(body), RestAdapter.CONTENT_TYPE_JSON);
JSONObject json = (JSONObject) ((JSONObject) res.bodyAsJson().get("d")).get("results");
return json;
}
// /**
// * ODataデータを取得.
// * @param id 対象となるID値
// * @return 1件取得した結果のオブジェクト
// * @throws DaoException DAO例外
// */
/**
* This method performs retrieve operation. It internally calls internalRetrieveMultikey.
* @param id ID value
* @return Object of the result(JSONObject)
* @throws DaoException Exception thrown
*/
JSONObject internalRetrieve(String id) throws DaoException {
return this.internalRetrieveMultikey("'" + Utils.escapeURI(id) + "'");
}
// /**
// * ODataデータを取得(複合キー).
// * @param id 対象となる複合キー<br>
// * urlエンコードが必要
// * @return 1件取得した結果のオブジェクト
// * @throws DaoException DAO例外
// */
/**
* This method performs retrieve operation.
* @param id composite key url encoding the target
* @return JSONObject as response
* @throws DaoException Exception thrown
*/
JSONObject internalRetrieveMultikey(String id) throws DaoException {
DcResponse res = internalRetrieveMultikeyAsDcResponse(id);
JSONObject json = (JSONObject) ((JSONObject) res.bodyAsJson().get("d")).get("results");
return json;
}
// /**
// * ODataデータを取得.
// * @param id 対象となるID値
// * @return 1件取得した結果のDcResponseオブジェクト
// * @throws DaoException DAO例外
// */
/**
* This method is used to retrieve the OData data for the specified ID. It internally calls
* internalRetrieveMultikeyAsDcResponse.
* @param id ID value
* @return Object of the result
* @throws DaoException Exception thrown
*/
DcResponse internalRetrieveAsDcResponse(String id) throws DaoException {
return this.internalRetrieveMultikeyAsDcResponse("'" + Utils.escapeURI(id) + "'");
}
// /**
// * ODataデータを取得(複合キー).
// * @param id 対象となる複合キー<br>
// * urlエンコードが必要
// * @return 1件取得した結果のDcResponseオブジェクト
// * @throws DaoException DAO例外
// */
/**
* This method is used to retrieve the OData data for the specified ID.
* @param id composite key url encoding the target
* @return Object of the result
* @throws DaoException Exception thrown
*/
DcResponse internalRetrieveMultikeyAsDcResponse(String id) throws DaoException {
String url = this.getUrl() + "(" + id + ")";
IRestAdapter rest = RestAdapterFactory.create(accessor);
return rest.get(url, RestAdapter.CONTENT_TYPE_JSON);
}
// /**
// * ODataデータを更新.
// * @param id 対象となるID値
// * @param body PUTするリクエストボディ
// * @param etag ETag値
// * @throws DaoException DAO例外
// */
/**
* This method performs update operation using Request Body and Etag value. It internally calls
* internalUpdateMultiKey.
* @param id ID value
* @param body PUT Request Body
* @param etag ETag value
* @throws DaoException Exception thrown
*/
void internalUpdate(String id, HashMap<String, Object> body, String etag) throws DaoException {
this.internalUpdateMultiKey("'" + Utils.escapeURI(id) + "'", body, etag);
}
// /**
// * ODataデータを更新.
// * @param id 対象となるID値
// * @param body PUTするリクエストボディ
// * @param etag ETag値
// * @param headers PUTするリクエストヘッダー
// * @throws DaoException DAO例外
// */
/**
* This method performs update operation using Request Body, Header and Etag value.
* @param id ID value
* @param body PUT Request Body
* @param etag ETag value
* @param headers PUT Request Headers
* @throws DaoException DAO例外
*/
void internalUpdate(String id, JSONObject body, String etag, HashMap<String, String> headers) throws DaoException {
String url = this.getUrl() + "('" + id + "')";
IRestAdapter rest = RestAdapterFactory.create(accessor);
rest.put(url, body.toJSONString(), etag, headers, RestAdapter.CONTENT_TYPE_JSON);
}
// /**
// * ODataデータを更新(複合キー).
// * @param multiKey 対象となる複合キー<br>
// * urlエンコードが必要
// * @param body PUTするリクエストボディ
// * @param etag ETag値
// * @throws DaoException DAO例外
// */
/**
* This method performs update operation using Request Body and Etag value.
* @param multiKeymultiKey composite key url encoding the target
* @param body PUT Request Body
* @param etag ETag Value
* @throws DaoException Exception thrown
*/
void internalUpdateMultiKey(String multiKey, HashMap<String, Object> body, String etag) throws DaoException {
String url = this.getUrl() + "(" + multiKey + ")";
IRestAdapter rest = RestAdapterFactory.create(accessor);
rest.put(url, JSONObject.toJSONString(body), etag, RestAdapter.CONTENT_TYPE_JSON);
}
// /**
// * ODataデータを削除.
// * @param id 削除するODataデータのID値
// * @param etag ETag値
// * @throws DaoException DAO例外
// */
/**
* This method performs delete operation. It internally calls internalDelMultiKey.
* @param id ID value
* @param etag ETag Value
* @throws DaoException Exception thrown
*/
void internalDel(String id, String etag) throws DaoException {
this.internalDelMultiKey("'" + Utils.escapeURI(id) + "'", etag);
}
// /**
// * ODataデータを削除(複合キー).
// * @param id 削除するODataデータの複合キー<br>
// * urlエンコードが必要
// * @param etag ETag値
// * @throws DaoException DAO例外
// */
/**
* This method performs delete operation.
* @param id id composite key url encoding the target
* @param etag ETag Value
* @throws DaoException Exception thrown
*/
void internalDelMultiKey(String id, String etag) throws DaoException {
String url = this.getUrl() + "(" + id + ")";
IRestAdapter rest = RestAdapterFactory.create(accessor);
rest.del(url, etag);
}
// /**
// * ODataデータを登録.
// * @param json 登録するJSONオブジェクト
// * @return 登録結果のレスポンス
// * @throws DaoException DAO例外
// */
/**
* This method registers the OData data and returns in JSON form.
* @param json JSON object
* @return Response of the registration result
* @throws DaoException Exception thrown
*/
@SuppressWarnings("unchecked")
public HashMap<String, Object> createAsJson(HashMap<String, Object> json) throws DaoException {
return this.internalCreate(json);
}
// /**
// * ODataデータを取得.
// * @param id 取得するID値
// * @return 取得したJSONオブジェクト
// * @throws DaoException DAO例外
// */
/**
* This method retrieves data in JSON form.
* @param id ID value
* @return JSON object
* @throws DaoException Exception thrown
*/
@SuppressWarnings("unchecked")
public HashMap<String, Object> retrieveAsJson(String id) throws DaoException {
return (HashMap<String, Object>) this.internalRetrieve(id);
}
// /**
// * ODataデータを更新.
// * @param id 対象となるID値
// * @param body PUTするリクエストボディ
// * @param etag ETag値
// * @throws DaoException DAO例外
// */
/**
* This method performs update operation.
* @param id ID value
* @param body PUT Request Body
* @param etag ETagvalue
* @throws DaoException Exception thrown
*/
public void update(String id, HashMap<String, Object> body, String etag) throws DaoException {
this.internalUpdate(id, body, etag);
}
// /**
// * ODataデータを削除.
// * @param id 削除するODataデータのID値
// * @param etag ETag値
// * @throws DaoException DAO例外
// */
/**
* This method performs delete operation with etag specified.
* @param id ID value
* @param etag ETag value
* @throws DaoException Exception thrown
*/
public void del(String id, String etag) throws DaoException {
this.internalDel(id, etag);
}
// /**
// * ODataデータを削除.
// * @param id 削除するODataデータのID値
// * @throws DaoException DAO例外
// */
/**
* This method performs delete operation without etag specified.
* @param id ID value
* @throws DaoException Exception thrown
*/
public void del(String id) throws DaoException {
this.internalDel(id, "*");
}
/**
* This method appends query string to execute Query for Search.
* @param query Query object
* @return JSON response
* @throws DaoException Exception thrown
*/
@SuppressWarnings("unchecked")
@Override
public HashMap<String, Object> doSearch(Query query) throws DaoException {
StringBuilder sb = new StringBuilder(this.getUrl());
String qry = query.makeQueryString();
if (qry != null && !"".equals(qry)) {
sb.append("?" + qry);
}
IRestAdapter rest = RestAdapterFactory.create(accessor);
DcResponse res = rest.get(sb.toString(), RestAdapter.CONTENT_TYPE_JSON);
return (HashMap<String, Object>) ((JSONObject) res.bodyAsJson());
}
// /**
// * クエリを生成.
// * @return 生成したQueryオブジェクト
// */
/**
* This method executes Query.
* @return Query object generated
*/
public Query query() {
return new Query(this);
}
// /**
// * ODataデータの生存確認.
// * @param id 対象となるODataデータのID
// * @return true:生存、false:不在
// */
/**
* This method checks whether the specified Odata exists.
* @param id ID value
* @return true:Survival false:Absence
*/
public Boolean exists(String id) {
String url = this.getUrl() + "('" + id + "')";
IRestAdapter rest = RestAdapterFactory.create(accessor);
try {
rest.head(url);
return true;
} catch (DaoException e) {
return false;
}
}
/**
* This method generates the URL for executing API calls.
* @return URL value
*/
@Override
public String getUrl() {
StringBuilder sb = new StringBuilder();
// $Batchモードの場合は、相対パス
/** In the case of $ Batch mode, the relative path . */
if (!accessor.isBatchMode()) {
sb.append(this.collection.getPath());
sb.append("/");
}
sb.append(this.entitySetName);
// key()によりKeyPredicateが指定されていたら
/** KeyPredicate if it has been specified by the key. */
if (null != this.keyPredicate && !"".equals(this.keyPredicate)) {
sb.append(String.format("('%s')", this.keyPredicate));
// nav()によりnaviPropertyが指定されていたら
/** naviProperty if it was given by nav. */
if (null != this.naviProperty && !"".equals(this.naviProperty)) {
sb.append(String.format("/_%s", this.naviProperty));
}
}
return sb.toString();
}
}