/** * 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.impl.es.doc; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.odata4j.edm.EdmDataServices; import com.fujitsu.dc.core.model.ctl.EntityType; import com.fujitsu.dc.core.model.ctl.Property; import com.fujitsu.dc.core.model.impl.es.odata.PropertyAlias; import com.fujitsu.dc.core.odata.OEntityWrapper; /** * プロパティのDocHandler. */ public class PropertyDocHandler extends OEntityDocHandler implements EntitySetDocHandler { Map<String, PropertyAlias> propertyAliasMap; Map<String, String> entityTypeMap; String linkTypeName = Property.P_ENTITYTYPE_NAME.getName(); /** * コンストラクタ. */ public PropertyDocHandler() { this.propertyAliasMap = null; } /** * OEntityWrapperから IDのないDocHandlerをつくるConstructor. * @param type ESのtype名 * @param oEntityWrapper OEntityWrapper * @param metadata スキーマ情報 */ public PropertyDocHandler(String type, OEntityWrapper oEntityWrapper, EdmDataServices metadata) { this.propertyAliasMap = null; initInstance(type, oEntityWrapper, metadata); this.staticFields.put(Property.P_IS_DECLARED.getName(), true); } /** * コンストラクタ. * @param cellId セルID * @param boxId ボックスID * @param nodeId ノードID * @param entityTypeId 紐付くエンティティタイプのID * @param source 静的プロパティフィールド */ public PropertyDocHandler(String cellId, String boxId, String nodeId, String entityTypeId, Map<String, Object> source) { this.propertyAliasMap = null; this.type = Property.EDM_TYPE_NAME; this.version = 0L; // Cell, Box, Nodeの紐付 this.setCellId(cellId); this.setBoxId(boxId); this.setNodeId(nodeId); // published, updated long crrTime = System.currentTimeMillis(); this.setPublished(crrTime); this.setUpdated(crrTime); this.staticFields = source; this.dynamicFields = new HashMap<String, Object>(); this.hiddenFields = new HashMap<String, Object>(); Map<String, Object> linksMap = new HashMap<String, Object>(); linksMap.put(EntityType.EDM_TYPE_NAME, entityTypeId); this.manyToOnelinkId = linksMap; } /** * EntityType名を返却する. * @return EntityType名 */ public String getEntityTypeName() { String entityTypeId = (String) this.manyToOnelinkId.get(EntityType.EDM_TYPE_NAME); return this.entityTypeMap.get(linkTypeName + entityTypeId); } /** * 登録済のエイリアス一覧を返却する. * @return propertyMap 登録済のエイリアス一覧 */ public Map<String, String> getEntityTypeMap() { return this.entityTypeMap; } /** * 登録済のエイリアス一覧を設定する. * @param map セットする propertyMap */ public void setEntityTypeMap(Map<String, String> map) { this.entityTypeMap = map; } /** * 登録済のエイリアス一覧を返却する. * @return propertyMap 登録済のエイリアス一覧 */ public Map<String, PropertyAlias> getPropertyAliasMap() { return this.propertyAliasMap; } /** * 登録済のエイリアス一覧を設定する. * @param map セットする propertyAliasMap */ public void setPropertyAliasMap(Map<String, PropertyAlias> map) { this.propertyAliasMap = map; } /** * ES/MySQL登録用データを取得する. * @return 登録用データ */ @Override public Map<String, Object> getSource() { String dataType = (String) this.staticFields.get("Type"); String entityTypeId = (String) this.manyToOnelinkId.get(EntityType.EDM_TYPE_NAME); String entityTypeName = this.entityTypeMap.get(linkTypeName + entityTypeId); String alias = getNextAlias(entityTypeName, dataType); String propertyName = (String) this.staticFields.get("Name"); String key = "Name='" + propertyName + "'," + linkTypeName + "='" + entityTypeName + "'"; PropertyAlias propertyAlias = new PropertyAlias(linkTypeName, propertyName, entityTypeName, alias); Map<String, Object> ret = setSource(key, propertyAlias); return ret; } /** * ES/MySQL登録用データをMapオブジェクトに設定する. * @param propertyAlias プロパティのAlias情報 * @param key キー * @return 作成したMapオブジェクト */ protected Map<String, Object> setSource(String key, PropertyAlias propertyAlias) { this.propertyAliasMap.put(key, propertyAlias); this.hiddenFields.put("Alias", propertyAlias.getAlias()); Map<String, Object> ret = new HashMap<String, Object>(); ret.put(KEY_STATIC_FIELDS, this.staticFields); ret.put(KEY_HIDDEN_FIELDS, this.hiddenFields); ret.put(KEY_PUBLISHED, this.published); ret.put(KEY_UPDATED, this.updated); ret.put(KEY_CELL_ID, this.cellId); ret.put(KEY_BOX_ID, this.boxId); ret.put(KEY_NODE_ID, this.nodeId); ret.put(KEY_LINK, this.manyToOnelinkId); return ret; } /** * PropertyのNameを取得する. * @return PropertyのName */ public String getName() { return (String) this.staticFields.get("Name"); } /** * 登録済みプロパティの最大値+1のプロパティAliasを取得する. * @param entityTypeName EntityType名 * @param dataType プロパティのデータ型名 * @return 採番したプロパティ名のAlias */ protected String getNextAlias(String entityTypeName, String dataType) { // データ種別からエイリアスのプレフィックスを決定する String aliasPrefix = "P"; if (!dataType.startsWith("Edm.")) { aliasPrefix = "C"; } // プロパティとエイリアスの対応MapをEntityType名で絞り込んでエイリアスのListを作る List<Integer> aliasList = new ArrayList<Integer>(); for (Map.Entry<String, PropertyAlias> entry : this.propertyAliasMap.entrySet()) { if (entry.getKey().endsWith(this.linkTypeName + "='" + entityTypeName + "'")) { String value = entry.getValue().getAlias(); if (value == null) { // 暫定的なnullチェック continue; } if (!value.startsWith(aliasPrefix)) { // プレフィックス(P/C)が異なるエイリアスは除外 continue; } // 数値部分のみ切り出し int num = getAliasNumber(value); aliasList.add(Integer.valueOf(num)); } } int nextNum = aliasList.size() + 1; // プロパティ番号の採番 // 単純型と複合型の通番は個別に採番する。 if (aliasList.contains(Integer.valueOf(nextNum))) { // 既に使われているので空きを探す for (int i = 0; i < aliasList.size(); i++) { if (!aliasList.contains(Integer.valueOf(i + 1))) { nextNum = i + 1; break; } } } String newAlias = String.format("%s%03d", aliasPrefix, nextNum); return newAlias; } /** * Alias文字列からインデックスを取得する. * @param alias Alias文字列 * @return インデックス */ protected int getAliasNumber(String alias) { if (alias.startsWith("C")) { String[] splitedAlias = alias.split(":"); return Integer.parseInt(splitedAlias[0].substring(1)); } return Integer.parseInt(alias.substring(1)); } }