001/* 002 * Copyright (c) 2009 The openGion Project. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 013 * either express or implied. See the License for the specific language 014 * governing permissions and limitations under the License. 015 */ 016package org.opengion.hayabusa.db; 017 018import org.opengion.hayabusa.common.HybsSystemException; // 6.4.5.0 (2016/04/08) 019 020import java.util.Arrays; 021import java.util.Comparator; 022import java.util.Map; 023import java.util.HashMap; 024import java.util.concurrent.ConcurrentMap; // 6.4.3.3 (2016/03/04) 025import java.util.concurrent.ConcurrentHashMap; // 6.4.3.1 (2016/02/12) refactoring 026import java.io.Serializable; 027 028/** 029 * ユーザー単位の編集設定情報を管理するためのクラスです。 030 * 031 * 画面ID+編集名をキーとして編集設定オブジェクトの 032 * 追加、削除、参照を行います。 033 * 034 * @og.rev 5.3.6.0 (2011/06/01) 新規追加 035 * 036 * @version 5.0 037 * @author Hiroki Nakamura 038 * @since JDK6.0, 039 */ 040public class DBEditConfigManager { 041 042 // 編集設定情報の管理オブジェクト(画面ID+編集名単位で管理) 043 /** 6.4.3.1 (2016/02/12) PMD refactoring. HashMap → ConcurrentHashMap に置き換え。 */ 044 private final ConcurrentMap<String,Map<String,DBEditConfig>> editConfigMap = new ConcurrentHashMap<>(); 045 046 private static final String NAME_KEY = "EDIT_NAME_" ; // 6.4.5.0 (2016/04/08) 047 private static final int NAME_LEN = NAME_KEY.length(); // 6.4.5.0 (2016/04/08) 048 049 // EDIT_SELECTED_ + 画面ID で、設定される 選択中編集名を記録します。 050 private final ConcurrentMap<String,String> editSelMap = new ConcurrentHashMap<>(); 051 052 private static final String SLCT_KEY = "EDIT_SELECTED_" ; // 6.4.5.0 (2016/04/08) 053 private static final int SLCT_LEN = SLCT_KEY.length(); // 6.4.5.0 (2016/04/08) 054 055 /** 056 * デフォルトコンストラクター 057 * 058 * 互換性を考慮し、デフォルトコンストラクターは残しておきます。 059 * 060 * @og.rev 6.0.2.2 (2014/10/03) 新規追加 061 */ 062 public DBEditConfigManager() { super(); } // これも、自動的に呼ばれるが、空のメソッドを作成すると警告されるので、明示的にしておきます。 063 064 /** 065 * 引数付コンストラクター 066 * 067 * UserInfo の Map<String,String> attribute から、EDIT_NAME_ で始まるキーワードを 068 * 取り出して、DBEditConfig オブジェクトを作成します。 069 * attribute には、"EDIT_NAME_(画面ID)_(編集名)" というキー情報があるので、 070 * 画面IDと編集名を分離し、DBEditConfig の各キーと再び合成して、attribute から、 071 * 設定値を取り出します。 072 * ただし、画面IDや、編集名 にも、アンダーバーが含まれている可能性がある為、 073 * EDIT_NAME_(画面ID)_(編集名) の値である、編集名 を使用して、分離します。 074 * そのキーと値の配列を元に作成された DBEditConfig オブジェクトを、内部Map に画面IDを 075 * キーに設定します。 076 * 077 * 元々、UserInfo#makeEditConfigMap() で処理していた内容を、こちらに移植しました。 078 * 079 * @og.rev 6.0.2.2 (2014/10/03) 新規追加。DBEditConfig から、移動 080 * @og.rev 6.3.9.1 (2015/11/27) getEditKeys(String,String) は、DBEditConfigManager ⇒ DBEditConfig へ移動。 081 * @og.rev 6.4.5.0 (2016/04/08) UserInfo のEditConfig関連機能を、DBEditConfigManagerに移植します。 082 * 083 * @param attribute UserInfo の 属性Map 084 */ 085 public DBEditConfigManager( final Map<String,String> attribute ) { 086 final String[] keys = attribute.keySet().toArray( new String[attribute.size()] ); 087 088 for( final String key : keys ) { 089 if( key == null ) { continue; } 090 091 // 6.4.5.0 (2016/04/08) UserInfo のEditConfig関連機能を、DBEditConfigManagerに移植します。 092 if( key.startsWith( SLCT_KEY ) ) { 093 final String editName = attribute.get( key ); 094 if( editName == null || editName.isEmpty() ) { 095 attribute.remove( key ); // editName の存在しない EDIT_SELECTED_ キーは削除します。 096 continue; 097 } 098 099 final String guikey = key.substring( SLCT_LEN ); // "EDIT_SELECTED_" の後ろが画面ID 100 if( guikey != null && guikey.length() > 0 ) { 101 editSelMap.put( guikey , editName ); 102 } 103 } 104 105 if( key.startsWith( NAME_KEY ) ) { 106 final String editName = attribute.get( key ); 107 if( editName == null || editName.isEmpty() ) { 108 attribute.remove( key ); // editName の存在しない EDIT_NAME_ キーは削除します。 109 continue; 110 } 111 112 // "EDIT_NAME_" より後ろで、editName の頭までが、画面ID 113 // (ただし、後ろにアンダーバーが付いているので、さらに、1文字削除対象を増やす。) 114 final int last = key.lastIndexOf(editName)-1 ; 115 if( last < 0 ) { // 一致しない場合は、キーが違うから。 116 attribute.remove( key ); // editName の一致しない EDIT_NAME_ キーは削除します。 117 continue; 118 } 119 120 final String guikey = key.substring( NAME_LEN,last ); 121 if( guikey != null && guikey.length() > 0 ) { 122 final String[] editKeys = DBEditConfig.getEditKeys( guikey, editName ); 123 String[] editVals = new String[editKeys.length]; 124 for( int i=0; i<editKeys.length; i++ ) { 125 editVals[i] = attribute.get( editKeys[i] ); 126 } 127 // Map#computeIfAbsent : 戻り値は、既存の、または計算された値。追加有り、置換なし、削除なし 128 editConfigMap.computeIfAbsent( guikey , k -> new HashMap<>() ).put( editName , new DBEditConfig( editVals ) ); 129 } 130 } 131 } 132 } 133 134 /** 135 * 編集設定オブジェクトを追加します。 136 * 137 * ここでの追加はあくまでメモリ上での登録になります。 138 * 登録した内容を永続的に登録する場合は、別途DBへの登録が必要になります。 139 * 140 * @og.rev 6.4.3.1 (2016/02/12) PMD refactoring. HashMap → ConcurrentHashMap に置き換え。 141 * 142 * @param guikey 画面ID 143 * @param editName 編集名 144 * @param config 編集設定オブジェクト 145 */ 146 public void addEditConfig( final String guikey, final String editName, final DBEditConfig config ) { 147 // 6.4.3.1 (2016/02/12) ConcurrentMap 系は、key,val ともに not null 制限です。 148 if( guikey != null && editName != null && config != null ) { 149 150 // Map#computeIfAbsent : 戻り値は、既存の、または計算された値。追加有り、置換なし、削除なし 151 final Map<String,DBEditConfig> confMap = editConfigMap.computeIfAbsent( guikey , k -> new HashMap<>() ); 152 final DBEditConfig oldConf = confMap.get( editName ); 153 154 // 個別設定と共通設定は、同じキーでは登録できません。 155 if( oldConf != null && oldConf.isCommon() != config.isCommon() ) { 156 final String errMsg = "個別設定と共通設定は、同じキーでは登録できません。"; 157 throw new HybsSystemException( errMsg ); 158 } 159 confMap.put( editName , config ); 160 } 161 } 162 163 /** 164 * 編集設定オブジェクトを削除します。 165 * 166 * ここでの追加はあくまでメモリ上での削除になります。 167 * 登録した内容を永続的に削除する場合は、別途DBへの登録が必要になります。 168 * 169 * @og.rev 6.4.3.2 (2016/02/19) ConcurrentHashMap の同期処理を使用。 170 * @og.rev 6.4.5.0 (2016/04/08) UserInfo のEditConfig関連機能を、DBEditConfigManagerに移植します。 171 * 172 * @param guikey 画面ID 173 * @param editName 編集名 174 * 175 * @return 編集設定オブジェクト 176 */ 177 public DBEditConfig deleteEditConfig( final String guikey, final String editName ) { 178 // 6.4.3.2 (2016/02/19) ConcurrentHashMap は、key,val ともに、NOT NULL制限があります。 179 if( guikey == null || guikey.isEmpty() || 180 editName == null || editName.isEmpty() ) { return null; } 181 182 final Map<String,DBEditConfig> ecMap = editConfigMap.get( guikey ); 183 184 return ecMap == null ? null : ecMap.remove( editName ); 185 } 186 187 /** 188 * 編集設定オブジェクトを取得します。 189 * 190 * @og.rev 6.4.3.2 (2016/02/19) ConcurrentHashMap の同期処理を使用。 191 * @og.rev 6.4.5.0 (2016/04/08) UserInfo のEditConfig関連機能を、DBEditConfigManagerに移植します。 192 * 193 * @param guikey 画面ID 194 * @param editName 編集名 195 * 196 * @return 編集設定オブジェクト 197 */ 198 public DBEditConfig getEditConfig( final String guikey, final String editName ) { 199 // 6.4.3.2 (2016/02/19) ConcurrentHashMap は、key,val ともに、NOT NULL制限があります。 200 if( guikey == null || guikey.isEmpty() || 201 editName == null || editName.isEmpty() ) { return null; } 202 203 final Map<String,DBEditConfig> ecMap = editConfigMap.get( guikey ); 204 205 return ecMap == null ? null : ecMap.get( editName ); 206 } 207 208 /** 209 * 画面IDをキーに編集設定の一覧(配列)を返します。 210 * 返される配列は、編集名順にソートされた状態で返されます。 211 * 212 * @og.rev 6.1.0.0 (2014/12/26) refactoring: null ではなく長さが0の配列を返す。 213 * 214 * @param guikey 画面ID 215 * 216 * @return 編集設定一覧(配列) 217 * @og.rtnNotNull 218 */ 219 public DBEditConfig[] getEditConfigs( final String guikey ) { 220 if( guikey == null || guikey.isEmpty() ) { return new DBEditConfig[0] ; } // 6.1.0.0 (2014/12/26) 221 222 final Map<String,DBEditConfig> map = editConfigMap.get( guikey ); 223 if( map == null ) { return new DBEditConfig[0]; } // 6.1.0.0 (2014/12/26) 224 225 final DBEditConfig[] configs = map.values().toArray( new DBEditConfig[map.size()] ); // 6.0.2.5 (2014/10/31) refactoring 226 // 6.0.2.5 (2014/10/31) findBugs対応:名前付き static 内部クラスにリファクタリングできるかもしれません。 227 Arrays.sort( configs , new EditConfigComparator() ); 228 229 return configs; 230 } 231 232 /** 233 * 指定の画面IDに対して選択済みの編集名を返します。 234 * 235 * @og.rev 5.3.6.0 (2011/06/01) 新規追加 236 * @og.rev 6.0.2.2 (2014/10/03) EDIT_NAME_SELECTED_ を、EDIT_SELECTED_ に変更 237 * @og.rev 6.4.5.0 (2016/04/08) UserInfo のEditConfig関連機能を、DBEditConfigManagerに移植します。 238 * 239 * @param guikey 画面ID 240 * 241 * @return 選択済み編集名 242 */ 243 public String getSelectedEdit( final String guikey ) { 244 return editSelMap.get( SLCT_KEY + guikey ); 245 } 246 247 /** 248 * DBEditConfig 比較用の Comparator 実装です。 249 * 名前なしclass から、名前あり staticクラスに格上げです。 250 * 251 * @og.rev 6.0.2.5 (2014/10/31) findBugs対応:新規追加 252 */ 253 private static final class EditConfigComparator implements Comparator<DBEditConfig>, Serializable { 254 private static final long serialVersionUID = 602520141024L ; 255 256 /** 257 * DBEditConfig 比較メソッド 258 * インタフェース Comparable の 実装です。 259 * 260 * @og.rev 6.0.2.5 (2014/10/31) findBugs対応:新規追加 261 * 262 * @param c1 比較対象の最初のオブジェクト 263 * @param c2 比較対象の 2 番目のオブジェクト 264 * @return 最初の引数が 2 番目の引数より小さい場合は負の整数、両方が等しい場合は 0、最初の引数が 2 番目の引数より大きい場合は正の整数 265 */ 266 @Override // Comparator 267 public int compare( final DBEditConfig c1, final DBEditConfig c2 ) { 268 return c1 == null ? -1 : c1.getEditName().compareTo( c2.getEditName() ) ; 269 } 270 } 271}