/**
* 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.io.InputStream;
import org.apache.http.HttpHeaders;
import org.apache.http.HttpStatus;
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.UrlUtils;
import com.fujitsu.dc.client.utils.Utils;
///**
// * Cell へアクセスするためのクラス.
// */
/**
* It creates a new object of Cell. This class represents Cell object to perform cell related operations.
*/
public class Cell extends AbstractODataContext {
// /** キャメル方で表現したクラス名. */
/** Class name in camel case. */
private static final String CLASSNAME = "cell";
// /** Cell名. */
/** Cell Name. */
private String name;
/** Location. */
private String location;
// CHECKSTYLE:OFF
// /** CellレベルACLへアクセスするためのクラス. */
/** Class to access to the Cell level ACL. */
public AclManager acl;
// /** メンバーへアクセスするためのクラスインスタンス。cell().accountでアクセス. */
/** Class instance to access the member AccountManager. */
public AccountManager account;
// /** BoxのCRUDを行うマネージャクラス. */
/** Manager class to perform CRUD of Box. */
public BoxManager box;
// /** BoxのCRUDを行うマネージャクラス. */
/** Manager class to perform CRUD of Box. */
public BoxManager boxManager;
// /** Relation へアクセスするためのクラス. */
/** Manager class to perform CRUD of Relation. */
public RelationManager relation;
// /** Role へアクセスするためのクラス. */
/** Manager class to perform CRUD of Role. */
public RoleManager role;
// /** ExtRole へアクセスするためのクラス. */
/** Manager class to perform CRUD of ExternalRole. */
public ExtRoleManager extRole;
// /** ExtCell へアクセスするためのクラス. */
/** Manager class to perform CRUD of ExternalCell. */
public ExtCellManager extCell;
// /** cellレベルEventへアクセスするためのクラス. */
/** Manager class to perform CRUD of Event. */
public EventManager event;
// /** cellレベルEvent(current)へアクセスするためのクラス. */
/** Class variable to access the (current) cell level Event. */
public LogManager currentLog;
// /** cellレベルEvent(archive)へアクセスするためのクラス. */
/** Class variable to access the (archive) cell level Event. */
public LogManager archiveLog;
// CHECKSTYLE:ON
// /**
// * コンストラクタ.
// */
/**
* This is the default constructor calling its parent constructor.
*/
public Cell() {
super();
}
// /**
// * コンストラクタ.
// * @param as アクセス主体
// * @throws DaoException DAO例外
// */
/**
* This is the parameterized constructor with one parameter and calling its another constructor.
* @param as Accessor
* @throws DaoException Exception thrown
*/
public Cell(Accessor as) throws DaoException {
this(as, as.getCellName());
}
// /**
// * コンストラクタ.
// * @param as アクセス主体
// * @param key 対象Cell
// * @throws DaoException DAO例外
// */
/**
* This is the parameterized constructor with two parameters using accessor and cell name and calling initialize
* method.
* @param as Accessor
* @param key Cell Name
* @throws DaoException Exception thrown
*/
public Cell(Accessor as, String key) throws DaoException {
super(as);
this.name = key;
this.initialize(as, null);
}
// /**
// * コンストラクタ.
// * @param as アクセス主体
// * @param body 生成するCellのJson
// * @throws DaoException DAO例外
// */
/**
* This is the parameterized constructor with two parameters and calling initialize method.
* @param as Accessor
* @param body JSON Body
* @throws DaoException Exception thrown
*/
public Cell(Accessor as, JSONObject body) throws DaoException {
this.initialize(as, body);
}
// /**
// * オブジェクトを初期化.
// * @param as アクセス主体
// * @param json サーバーから返却されたJSONオブジェクト
// */
/**
* This method is used to initialize various class variables.
* @param as Accessor
* @param json JSON object
*/
public void initialize(Accessor as, JSONObject json) {
super.initialize(as);
if (json != null) {
this.rawData = json;
this.name = (String) json.get("Name");
this.location = (String) ((JSONObject) json.get("__metadata")).get("uri");
}
this.accessor.setCurrentCell(this);
this.relation = new RelationManager(this.accessor);
this.role = new RoleManager(this.accessor);
this.acl = new AclManager(this.accessor, this.name);
this.account = new AccountManager(this.accessor);
this.box = new BoxManager(this.accessor);
this.boxManager = new BoxManager(this.accessor);
this.extRole = new ExtRoleManager(this.accessor);
this.extCell = new ExtCellManager(this.accessor);
this.event = new EventManager(this.accessor);
this.currentLog = new CurrentLogManager(this.accessor);
this.archiveLog = new ArchiveLogManager(this.accessor);
}
// /**
// * Cell名を取得.
// * @return Cell名
// */
/**
* This method returns the Cell Name.
* @return Cell Name value
*/
public String getName() {
return name;
}
// /**
// * Cell名を設定.
// * @param value Cell名
// */
/**
* This method sets the Cell Name.
* @param value CellName
*/
public void setName(String value) {
this.name = value;
}
// /**
// * CellのURLを取得する.
// * @return 取得した CellのURL
// */
/**
* This method creates and returns the URL for performing Cell related operations.
* @return CellURL value
*/
public String getUrl() {
String url = this.name;
if (!UrlUtils.isUrl(this.name)) {
url = UrlUtils.append(accessor.getBaseUrl(), Utils.escapeURI(this.name) + "/");
} else if (!this.name.endsWith("/")) {
url = url + "/";
}
return url;
}
// /**
// * アクセストークンを取得.
// * @return アクセストークン
// * @throws DaoException DAO例外
// */
/**
* This method returns the access token.
* @return Access Token
* @throws DaoException Exception thrown
*/
public String getAccessToken() throws DaoException {
if (this.accessor.getAccessToken() != null) {
return this.accessor.getAccessToken();
} else {
throw DaoException.create("Unauthorized", HttpStatus.SC_UNAUTHORIZED);
}
}
// /**
// * アクセストークンの有効期限を取得.
// * @return アクセストークンの有効期限
// */
/**
* This method returns the expiration date of the access token.
* @return Expiration date of the access token
*/
public Number getExpiresIn() {
return this.accessor.getExpiresIn();
}
// /**
// * アクセストークンのタイプを取得.
// * @return アクセストークンのタイプ
// */
/**
* This method returns the token type.
* @return Token Type
*/
public String getTokenType() {
return this.accessor.getTokenType();
}
// /**
// * リフレッシュトークンを取得.
// * @return リフレッシュトークン
// * @throws DaoException DAO例外
// */
/**
* This method returns the refresh token.
* @return Refresh Token value
* @throws DaoException Exception thrown
*/
public String getRefreshToken() throws DaoException {
if (this.accessor.getRefreshToken() != null) {
return this.accessor.getRefreshToken();
} else {
throw DaoException.create("Unauthorized", HttpStatus.SC_UNAUTHORIZED);
}
}
// /**
// * リフレッシュの有効期限を取得.
// * @return リフレッシュトークンの有効期限
// */
/**
* This method gets the expiration date of the refresh token.
* @return Expiration date of the refresh token
*/
public Number getRefreshExpiresIn() {
return this.accessor.getRefreshExpiresIn();
}
/**
* Thismethod returns the location.
* @return the location
*/
public String getLocation() {
return location;
}
// /**
// * CellのownerRepresentativeAccountsを設定.
// * @param user アカウント名
// * @throws DaoException DAO例外
// */
/**
* This method sets the ownerRepresentativeAccounts of Cell.
* @param user Account Name
* @throws DaoException Exception thrown
*/
public void setOwnerRepresentativeAccounts(String user) throws DaoException {
String value;
value = "<dc:account>" + user + "</dc:account>";
RestAdapter rest = (RestAdapter) RestAdapterFactory.create(this.accessor);
rest.proppatch(this.getUrl(), "dc:ownerRepresentativeAccounts", value);
}
// /**
// * CellのownerRepresentativeAccountsを設定(複数アカウント登録).
// * @param accountName アカウント名の配列
// * @throws DaoException DAO例外
// */
/**
* This method sets the ownerRepresentativeAccounts of Cell(multiple sign up for an account).
* @param accountName Account Name
* @throws DaoException Exception thrown
*/
public void setOwnerRepresentativeAccounts(String[] accountName) throws DaoException {
StringBuilder sb = new StringBuilder();
for (Object an : accountName) {
sb.append("<dc:account>");
sb.append(an);
sb.append("</dc:account>");
}
RestAdapter rest = (RestAdapter) RestAdapterFactory.create(this.accessor);
rest.proppatch(this.getUrl(), "dc:ownerRepresentativeAccounts", sb.toString());
}
// /**
// * Boxへアクセスするためのクラスを生成して返します。 Accessorがスキーマ認証済みである場合はその認証されたスキーマに対応するBoxを、
// * そうでない場合は、このセルのDcContextに指定されたスキーマのBoxを返します. 該当するBoxが存在しないときは、例外をスローします。 例外:
// * <ul>
// * <li>スキーマ認証済みで対応するBoxが存在しない場合。</li>
// * <li>スキーマ認証なしでDcContextにスキーマが定義されていない場合。</li>
// * <li>スキーマ認証なしでDcContextに定義されたスキーマに対応するBoxが見つからない場合。</li>
// * </ul>
// * @return 生成したBoxインスタンス
// * @throws DaoException DAO例外
// */
/**
* It creates and returns the class to access the Box. The Box corresponding to the schema that has been
* authenticated if Accessor is a schema authenticated, Otherwise, it returns a Box of schema that is specified in
* the DcContext of this cell. When there is no corresponding Box, it throws an exception. Exception:
* <ul>
* <li>If the Box the corresponding schema authenticated does not exist.</li>
* <li>If the schema is not defined in the DcContext without authentication schema.</li>
* <li>If the Box that corresponds to the schema defined in the DcContext without authentication schema can not be
* found.</li>
* </ul>
* @return Box object
* @throws DaoException Exception thrown
*/
// CHECKSTYLE:ON
public Box box() throws DaoException {
/** obtain schemaUrl */
DcContext context = this.accessor.getContext();
String schemaUrlFromAuthzHeader = this.accessor.getSchema();
String schemaUrlFromContext = context.getBoxSchema();
/**
* If the URL of this Cell equals to the one set in the DcContext, return the box configured in the DcContext
* without the following URL discovery process.
*/
String cellUrl = this.getUrl();
if (cellUrl != null && cellUrl.equals(context.getCellUrl())) {
return box(context.getBoxName(), context.getBoxSchema());
}
/** Discover the Box Url from Authorization Header or from Box Schema Url */
String schemaUrl = null;
String url = null;
if (schemaUrlFromAuthzHeader != null) {
url = UrlUtils.append(this.getUrl(), "__box");
schemaUrl = schemaUrlFromAuthzHeader;
} else if (schemaUrlFromContext != null) {
url = UrlUtils.append(this.getUrl(), "__box?schema=" + Utils.escapeURI(schemaUrlFromContext));
schemaUrl = schemaUrlFromContext;
} else {
throw new DaoException("Cannot specify the box.");
}
Accessor tmpAccessor = this.accessor.clone();
IRestAdapter rest = RestAdapterFactory.create(tmpAccessor);
DcResponse resp = rest.get(url, RestAdapter.CONTENT_TYPE_JSON);
String locationHeader = resp.getHeader(HttpHeaders.LOCATION);
/** Extract the box name from box URL */
String[] params = locationHeader.split("/");
String boxName = null;
if (locationHeader.endsWith("/")) {
boxName = params[params.length - 2];
} else {
boxName = params[params.length - 1];
}
return box(boxName, schemaUrl);
}
// /**
// * Boxへアクセスするためのクラスを生成.
// * @param param Box名、schema名
// * @return 生成したBoxインスタンス
// * @throws DaoException DAO例外
// */
/**
* It creates and returns the class to access the Box for the specified Box name.
* @param param Box Name
* @return Box object
* @throws DaoException Exception thrown
*/
public Box box(String param) throws DaoException {
String boxName = param;
if (boxName.startsWith("http://") || boxName.startsWith("https://")) {
// SchemaからBox名を引く
/** Fetch Box name from Box schema. */
String url = UrlUtils.append(this.getUrl(), "__box?schema=" + Utils.escapeURI(param));
Accessor tmpAccessor = this.accessor.clone();
IRestAdapter rest = RestAdapterFactory.create(tmpAccessor);
DcResponse resp = rest.get(url, RestAdapter.CONTENT_TYPE_JSON);
String locationHeader = resp.getHeader(HttpHeaders.LOCATION);
String[] params = locationHeader.split("/");
if (locationHeader.endsWith("/")) {
boxName = params[params.length - 2];
} else {
boxName = params[params.length - 1];
}
}
this.accessor.setBoxName(boxName);
String url = UrlUtils.append(this.accessor.getCurrentCell().getUrl(), accessor.getBoxName());
return new Box(this.accessor, boxName, "", url);
}
// /**
// * Boxへアクセスするためのクラスを生成.
// * @param boxName Box Name
// * @param schemaValue スキーマ名
// * @return 生成したBoxインスタンス
// * @throws DaoException DAO例外
// */
/**
* It creates and returns the class to access the Box for the specified Box name and Box schema.
* @param boxName Box Name
* @param schemaValue BoxSchema
* @return Box object
* @throws DaoException Exception thrown
*/
public Box box(String boxName, String schemaValue) throws DaoException {
this.accessor.setBoxName(boxName);
String url = UrlUtils.append(this.accessor.getCurrentCell().getUrl(), accessor.getBoxName());
return new Box(this.accessor, boxName, schemaValue, url);
}
// /**
// * BaseUrl を取得.
// * @return baseUrl 基底URL文字列
// */
/**
* This method returns the BaseURl in string form.
* @return baseUrl BaseURL.
*/
public String getBaseUrlString() {
return accessor.getBaseUrl();
}
// /**
// * ODataのキーを取得する.
// * @return ODataのキー情報
// */
/**
* This method formats and returns the key for Box.
* @return OData Key
*/
public String getKey() {
return String.format("('%s')", this.name);
}
// /**
// * クラス名をキャメル型で取得する.
// * @return ODataのキー情報
// */
/**
* This method returns the classname in camel case.
* @return ClassName
*/
public String getClassName() {
return CLASSNAME;
}
/**
* This method is used for installing a box using a bar file.
* @param boxName desired name of the box to be installed.
* @param barFile input stream of actual bar file
* @return Box response
* @throws DaoException thrown when installation is rejected for some reason.
*/
public Box installBox(String boxName, InputStream barFile) throws DaoException {
RestAdapter rest = (RestAdapter) RestAdapterFactory.create(this.accessor);
rest.mkcol(boxName, barFile, IRestAdapter.CONTENT_TYPE_ZIP);
/** if an error response is returned in HTTP, DaoException will be thrown. */
return this.box(boxName, null);
}
/**
* This method is used for installing a box using a bar file URL.
* @param boxName desired name of the box to be installed.
* @param barFileUrl URL of the bar file publicly available.
* @return Box response
* @throws DaoException thrown when installation is rejected for some reason.
*/
public Box installBox(String boxName, String barFileUrl) throws DaoException {
DcResponse res = RestAdapterFactory.create(this.accessor).get(barFileUrl, "application/octet-stream");
InputStream barFile = res.bodyAsStream();
return this.installBox(boxName, barFile);
}
}