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     */
016    package org.opengion.hayabusa.taglib;
017    
018    import org.opengion.hayabusa.common.HybsSystem;
019    import org.opengion.hayabusa.common.HybsSystemException;
020    import org.opengion.hayabusa.db.DBColumn;
021    import org.opengion.hayabusa.db.DBTableModel;
022    import org.opengion.hayabusa.db.DBTableModelUtil;
023    
024    import org.opengion.fukurou.util.StringUtil;
025    import static org.opengion.fukurou.util.StringUtil.nval ;
026    
027    import java.util.Map;
028    import java.util.LinkedHashMap;
029    import java.util.Locale ;
030    
031    /**
032     * ?’つの DBTableModel の é›?�ˆ処ç�?‚’行うタグですã?
033     *
034     * マスタとスレーブã?それぞれの DBTableModel を取得し、ã?ージ、差åˆ??排他などの
035     * ãƒ??タ処ç�?‚’行いますã?結果をã?æŒ?®šã? tableId と scope に書きå?しますã?
036     * マスタãƒ??ブルは、masterTableId と masterScope より取り出しますã?スレーブテーブルはã€?
037     * slaveTableId と slaveScope より取り出しますã?
038     * 取り出されã�?DBTableModel は、ã?スタãƒ??ブルに対して、スレーブテーブルæƒ??を参照する形で行われã?
039     * 結果はマスタãƒ??ブルに上書きされる形で行われますã?
040     * æŒ?®šできるアクションは、å?体集å�?UNION_ALL)、和é›?�ˆ(UNION)、積集å�?INTERSECT)ã€?
041     * 差é›?�ˆ(MINUS)、差åˆ?›†å�?DIFFERENCE)、å?合æ?(UNION_CLM)ã€?列追åŠ?ADD_CLM)ã€?グルーãƒ?GROUP)ですã?
042     * 列合成と列追åŠ??グループ以外ã?処ç�?�§は、カラãƒ??とカラãƒ?•°は同数でなければなりませんã€?
043     * primaryKeys ã‚?unionClms などのæŒ?®šã?キー名ã?、ã?スタãƒ??ブルに存在するå¿?¦�がありますã?
044     * マスタãƒ??ブルと同じカラãƒ?•ª号でスレーブテーブルよりãƒ??タを読み出しますã?
045     * (カラãƒ?��ã‚?±žæ?は、異なってもかまã�?�¾せんがã?マスタãƒ??ブルに準拠しますã?)
046     * またã?単独(マスタãƒ??ブルのみ)で、和é›?�ˆと同等ã?、グルーãƒ?GROUP)を使用すると、指定ã?
047     * カラãƒ?�§のユニã?ク化を行うことが可能になりますã?グループå?ç�?�§は、å?行優先としã?
048     * ?’回目に現れたæƒ??を削除することになりますã?グルーãƒ?が指定された場合ã?ã€?
049     * スレーブテーブルは無視されますã?ã�?�šれã?処ç�?�«おいてもã?é›?�ˆ処ç�?‚’行う主キーで
050     * ä¸?—¦グループ化されますã?全体集å�?UNION_ALL)で処ç�?�™るå?合でもã?主キーがユニã?クで
051     * なã�??合ã?、ã?スター、スレーブã?å�?ƒ†ーブルでä¸?—¦グループ化された後で、ã?ージされますã?
052     * (マã?ジ後には、同ä¸?¸»キーを持つ行ã?存在しますã?)
053     * 全体集å�?UNION_ALL)の場合ã?み、mergeKeys を指定するå¿?¦�ã?ありません。その場合ã?ã€?
054     * キーなしã?ため、ã?スターとスレーブã?ãƒ??ブルを単に合æ?するã�?�‘になりますã?
055     *
056     * 処ç�?‰�後でのDBTableModelの件数は、以下ã?変数で取得することが可能ですã?
057     *  処ç�?‰�のマスターãƒ??ブル : {@DB.MASTER_COUNT}
058     *  処ç�?‰�のスレーブテーブル : {@DB.SLAVE_COUNT}
059     *  処ç�?¾?                  : {@DB.COUNT}
060     *
061     * @og.formSample
062     * ●形式ï¼?
063     *       ・<og:tableMerge
064     *             action        = "UNION_ALL|UNION|INTERSECT|MINUS|DIFFERENCE|UNION_CLM|ADD_CLM|GROUP|UNION_SELROW"
065     *             tableId       = "DEFAULT"        出力テーブルの tableId
066     *             scope         = "session"        出力テーブルの scope
067     *             masterTableId = "DEFAULT"        マスタãƒ??ブルの tableId
068     *             masterScope   = "session"        マスタãƒ??ブルの scope
069     *             slaveTableId  = "DEFAULT"        スレーブテーブルの tableId
070     *             slaveScope    = "request"        スレーブテーブルの scope
071     *             masterKeys    = "AA,BB,CC"       マスタãƒ??ブルのé›?�ˆ処ç�?‚’行う主キー
072     *             slaveKeys     = "AA,BB,CC"       スレーブテーブルのé›?�ˆ処ç�?‚’行う主キー(nullæ™?masterKeys)
073     *             diffKeys      = "DD,EE"          マスタãƒ??ブルのDIFFERENCE時ã?差åˆ?‚«ラãƒ?��
074     *             unionClms     = "DD,EE"          UNION_CLM,ADD_CLM時にスレーブからã?スタへ追åŠ?�™るカラãƒ?��
075     *             modifyClms    = "FF,GG"          DIFFERENCE時にスレーブからã?スタへ値を更新するカラãƒ?��
076     *             noSideEffect  = "false"          ãƒ??ブルモãƒ?ƒ«に対する副作用(true:なã�?false:ある)
077     *             useDiffData   = "true"           DIFFERENCE時に差åˆ??スレーブデータを追åŠ?�™るかどã�?�‹
078     *             useCheckOnly  = "false"          マスタãƒ??ブルの選択行ã?ãƒ??タのみを対象に処ç�?‚’行うかどã�?�‹
079     *             groupAddClms  = "FF,GG"          masterKeysでé›?�ˆ処ç�?�™るときに、相違データをCSV連結して残すカラãƒ?��
080     *             display       = "true"           処ç�?¦‚要を表示するかどã�?�‹
081     *         />
082     * ●body?šなã�?
083     *
084     * ●Tag定義??
085     *   <og:tableMerge
086     *       command            【TAG】コマンãƒ?NEW,RENEW)をセãƒ?ƒˆしまã�?初期値:NEW)
087     *       action             【TAG】アクションを指定しまã�?UNION_ALL|UNION|INTERSECT|MINUS|DIFFERENCE|UNION_CLM|ADD_CLM|GROUP|UNION_SELROW)
088     *       tableId            【TAG】å?力å?のtableIdを指定しまã�?(初期値:HybsSystem#TBL_MDL_KEY[=h_tblmdl])
089     *       scope              【TAG】å?力å?のscopeを指定しまã�?初期値:session)
090     *       masterTableId      【TAG】ã?スタãƒ??ブルのtableIdを指定しまã�?(初期値:HybsSystem#TBL_MDL_KEY[=h_tblmdl])
091     *       masterScope        【TAG】ã?スタãƒ??ブルのscopeを指定しまã�?初期値:session)
092     *       slaveTableId       【TAG】スレーブテーブルのtableIdを指定しまã�?(初期値:HybsSystem#TBL_MDL_KEY[=h_tblmdl])
093     *       slaveScope         【TAG】スレーブテーブルのscopeを指定しまã�?初期値:session)
094     *       masterKeys         【TAG】ã?スタãƒ??ブルのé›?�ˆ処ç�?‚’行う主キーを指定しまã�?
095     *       slaveKeys          【TAG】スレーブテーブルのé›?�ˆ処ç�?‚’行う主キーを指定しまã�?
096     *       diffKeys           【TAG】ã?スタãƒ??ブルのDIFFERENCE時ã?差åˆ?‚«ラãƒ?��ã‚?CSV形å¼?æŒ?®šしまã�?
097     *       unionClms          【TAG】スレーブからã?スタへ追åŠ?�™るカラãƒ?��をCSV形式でæŒ?®šしまã�?
098     *       modifyClms         【TAG】スレーブからã?スタへ値を更新するカラãƒ?��をCSV形式でæŒ?®šしまã�?
099     *       groupAddClms       【TAG】集合å?ç�?�™るときに、相違データをCSV連結して残すカラãƒ?��をCSV形式でæŒ?®šしまã�?
100     *       noSideEffect       【TAG】テーブルモãƒ?ƒ«に対する副作用の有無[true:なã�?false:ある]を指定しまã�?初期値:false:ある)
101     *       useDiffData        【TAG】差åˆ??スレーブデータを結果ãƒ??ブルに追åŠ?�™るかどã�?�‹を指定しまã�?初期値:true)
102     *       useCheckOnly       【TAG】ã?スタãƒ??ブルの選択行ã?ãƒ??タのみを対象に処ç�?‚’行うかどã�?�‹を指定しまã�?初期値:false)
103     *       display            【TAG】ã?ージの結果を表示するかどã�?�‹を指定しまã�?初期値:true)
104     *       mainTrans          【TAGã€?通常使ã�?�¾せん)タグで処ç�?�•れる処ç�?�Œメインとなるトランザクション処ç�?�‹どã�?�‹を指定しまã�?初期値:false)
105     *       caseKey            【TAG】このタグ自体を利用するかどã�?�‹の条件キーを指定しまã�?初期値:null)
106     *       caseVal            【TAG】このタグ自体を利用するかどã�?�‹の条件値を指定しまã�?初期値:null)
107     *       caseNN             【TAG】指定ã?値がã?null/ゼロæ–?­—å? でなã�??å�?Not Null=NN)は、このタグは使用されまã�?初期値:true)
108     *       caseNull           【TAG】指定ã?値がã?null/ゼロæ–?­—å? の場合ã?、このタグは使用されまã�?初期値:true)
109     *       separator          【TAG】groupAddClmsでæ–?­—å?をé?結するé?目区åˆ?‚Šæ–?­—をセãƒ?ƒˆしまã�?初期値:",")
110     *       debug              【TAG】デバッグæƒ??をå?力するかどã�?�‹[true/false]を指定しまã�?初期値:false)
111     *   />
112     *
113     * ●使用ä¾?
114     *     例ï¼?ãƒ?ƒ•ォルト以外にå¿?¦�な属æ?のみæŒ?®šするサンプル
115     *     <og:tableMerge action="UNION"
116     *           slaveScope = "request" masterKeys = "AA,BB,CC"
117     *     />
118     *
119     *         ・出力å?、ã?スターともに初期値は、tableId="DEFAULT" scope="session" ですã?
120     *           スレーブã?、tableId ã�?scope をけるå¿?¦�がある為、scope="request" を指定してã�?�¾すã?
121     *           比è¼?�™るカラãƒ?��は、ã?スタ、スレーブ同じであれば、ã?スタのみæŒ?®šでかまã�?�¾せんã€?
122     *
123     *     例ï¼?マスタ、スレーブともメモリに残らなã�?‚ˆã�?�« request で作æ?しますã?
124     *     <og:tableMerge action="INTERSECT"
125     *           masterScope  = "request"
126     *           slaveScope   = "request"
127     *           slaveTableId = "SLAVE"
128     *           masterKeys   = "AA,BB,CC"
129     *     />
130     *
131     *         ・マスタ、スレーブともメモリに残らなã�?‚ˆã�?�« request で作æ?した場合ã?ã€?
132     *           どちらかの TableId を変えるå¿?¦�がありますã?
133     *           出力å?は初期値の、tableId="DEFAULT" scope="session" ですã?
134     *
135     * @og.rev 3.8.0.9 (2005/10/17) 新規追åŠ?
136     * @og.group ?¤?¢登録
137     *
138     * @version  0.9.0      2000/10/17
139     * @author       Kazuhiko Hasegawa
140     * @since    JDK5.0,
141     */
142    public class TableMergeTag extends CommonTagSupport {
143            //* こã?プログラãƒ??VERSIONæ–?­—å?を設定しますã?       {@value} */
144            private static final String VERSION = "5.5.8.5 (2012/11/27)" ;
145    
146            private static final long serialVersionUID = 558520121127L ;
147    
148            /** action 引数に渡す事ã?出来ã‚?アクションコマンãƒ? 全体集å�?{@value} */
149            public static final String ACT_UNION_ALL        = "UNION_ALL" ;
150            /** action 引数に渡す事ã?出来ã‚?アクションコマンãƒ? 和集å�?{@value} */
151            public static final String ACT_UNION            = "UNION" ;
152            /** action 引数に渡す事ã?出来ã‚?アクションコマンãƒ? 積集å�?{@value} */
153            public static final String ACT_INTERSECT        = "INTERSECT" ;
154            /** action 引数に渡す事ã?出来ã‚?アクションコマンãƒ? 差é›?�ˆ{@value} */
155            public static final String ACT_MINUS            = "MINUS" ;
156            /** action 引数に渡す事ã?出来ã‚?アクションコマンãƒ? 差åˆ?›†å�?@value} */
157            public static final String ACT_DIFFERENCE       = "DIFFERENCE" ;
158            /** action 引数に渡す事ã?出来ã‚?アクションコマンãƒ? 列合成{@value} */
159            public static final String ACT_UNION_CLM        = "UNION_CLM" ;
160            /** action 引数に渡す事ã?出来ã‚?アクションコマンãƒ? 列合成{@value} */
161            public static final String ACT_ADD_CLM          = "ADD_CLM" ;
162            /** action 引数に渡す事ã?出来ã‚?アクションコマンãƒ? グルーãƒ?{@value} */
163            public static final String ACT_GROUP            = "GROUP" ;
164            /** action 引数に渡す事ã?出来ã‚?アクションコマンãƒ? グルーãƒ?{@value} */
165            public static final String ACT_UNION_SELROW     = "UNION_SELROW" ;// 4.3.2.0 (2008/09/11)
166    
167            /** action 引数に渡す事ã?出来ã‚?アクションコマンãƒ?リスãƒ? */
168            private static final String[] ACTION_LIST = new String[] {
169                    ACT_UNION_ALL , ACT_UNION , ACT_INTERSECT , ACT_MINUS , ACT_DIFFERENCE , ACT_UNION_CLM , ACT_ADD_CLM , ACT_GROUP, ACT_UNION_SELROW };
170    
171            /** command 引数に渡す事ã?出来ã‚?コマンãƒ? 新è¦?{@value} */
172            public static final String CMD_NEW       = "NEW" ;
173            /** command 引数に渡す事ã?出来ã‚?コマンãƒ? 再検索 {@value} */
174            public static final String CMD_RENEW = "RENEW" ;
175            /** command 引数に渡す事ã?出来ã‚?コマンãƒ?リスãƒ? */
176            private static final String[] COMMAND_LIST = new String[] { CMD_NEW , CMD_RENEW };
177    
178            private String  command         = CMD_NEW;
179    
180            private String  action          = null;
181            private String  tableId         = HybsSystem.TBL_MDL_KEY;               // 出力å?の tableId
182            private String  scope           = "session";                                            // 出力å?の scope
183    
184            private String  masterTableId   = HybsSystem.TBL_MDL_KEY;       // マスタãƒ??ブルの tableId
185            private String  masterScope             = "session";                                    // マスタãƒ??ブルの scope
186            private String  slaveTableId    = HybsSystem.TBL_MDL_KEY;       // スレーブテーブルの tableId
187            private String  slaveScope              = "request";                                    // スレーブテーブルの scope
188            private String  masterKeys              = null;                                                 // マスタãƒ??ブルのé›?�ˆ処ç�?‚’行う主キー
189            private String  slaveKeys               = null;                                                 // スレーブテーブルのé›?�ˆ処ç�?‚’行う主キー(nullæ™?masterKeys)
190            private String  diffKeys                = null;                                                 // マスタãƒ??ブルのDIFFERENCE時ã?差åˆ?‚«ラãƒ?��
191            private String  unionClms               = null;                                                 // UNION_CLM時にスレーブからã?スタへ追åŠ?�™るカラãƒ?��
192            private String  modifyClms              = null;                                                 // DIFFERENCE時にスレーブからã?スタへ値を更新するカラãƒ?��
193            private String  groupAddClms    = null;                                                 // 5.1.4.0 (2010/03/01) masterKeysでé›?�ˆ処ç�?�™るときに、相違データをCSV連結して残すカラãƒ?��
194            private boolean noSideEffect    = false;                                                // ãƒ??ブルモãƒ?ƒ«に対する副作用(true:なã�?false:ある)
195            private boolean useDiffData             = true;                                                 // DIFFERENCE時に差åˆ??スレーブデータを追åŠ?�™るかどã�?�‹
196            private boolean useCheckOnly    = false;                                                // マスタãƒ??ブルの選択行ã?ãƒ??タのみを対象に処ç�?‚’行うかどã�?�‹
197            private boolean display                 = true;
198            private boolean isMainTrans             = true;                                                 // 5.1.6.0 (2010/05/01) DBLastSqlの処ç�??見直ã�?
199            private String  separator               = ",";                                                  // 5.3.1.0 (2011/01/01) groupAddClmnsで結合する際ã?区åˆ?‚Šæ–?­?
200    
201            /**
202             * Taglibの終äº?‚¿グが見つかったときに処ç�?�™ã‚?doEndTag() ã‚?オーバã?ライドしますã?
203             *
204             * @og.rev 4.3.2.0 (2008/09/11) UNION_SELROWアクション対å¿?
205             * @og.rev 4.3.3.0 (2008/10/01) 処ç�?‰�後ã?ãƒ??ブル件数を取得できるようにする
206             * @og.rev 4.3.3.1 (2008/10/08) スレーブã?nullチェãƒ?‚¯追åŠ?
207             * @og.rev 5.1.6.0 (2010/05/01) DBLastSqlの処ç�??、DBTableModelが新規作æ?されたå?ç�?�§のみ行うã€?
208             * @og.rev 5.2.2.0 (2010/11/01) caseKey 、caseVal 属æ?対å¿?
209             *
210             * @return      後続å?ç�??æŒ?¤º
211             */
212            @Override
213            public int doEndTag() {
214                    debugPrint();           // 4.0.0 (2005/02/28)
215                    // 5.2.2.0 (2010/11/01) caseKey 、caseVal 属æ?対å¿?
216    //              if( ! check( command, COMMAND_LIST ) ) { return(EVAL_PAGE); }
217                    if( !useTag() || ! check( command, COMMAND_LIST ) ) { return(EVAL_PAGE); }
218    
219                    // 整合æ?チェãƒ?‚¯?šアクションリストとの存在チェãƒ?‚¯
220                    if( !check( action, ACTION_LIST ) ) {
221                            String errMsg = "æŒ?®šã?アクションは実行できません。アクションエラー"
222                                                            + HybsSystem.CR
223                                                            + "action=[" + action + "] "
224                                                            + HybsSystem.CR
225                                                            + "æŒ?®š可能なアクション:"
226                                                            + StringUtil.array2csv( ACTION_LIST ) ;
227                            throw new HybsSystemException( errMsg );
228                    }
229    
230                    // スレーブテーブルのé›?�ˆ処ç�?‚’行う主キー(nullæ™?masterKeys)
231                    if( slaveKeys == null ) { slaveKeys = masterKeys; }
232    
233                    super.setScope( masterScope );
234                    DBTableModel masterTable = (DBTableModel)getObject( masterTableId );
235    
236                    // 整合æ?チェãƒ?‚¯?šã?スタãƒ??ブルはå¿??
237                    if( masterTable == null ) {
238                            String errMsg = "マスタãƒ??ブルはå¿??ですã?"
239                                                    + HybsSystem.CR
240                                                    + "action=[" + action + "] "
241                                                    + "masterTableId=[" + masterTableId + "] "
242                                                    + "masterScope=[" + masterScope + "] " ;
243                            throw new HybsSystemException( errMsg );
244                    }
245                    if( noSideEffect ) { masterTable = cloneTable( masterTable ); }
246                    Map<String,Integer> masterMap = makeKeyMap( masterTable,masterKeys,useCheckOnly );
247    
248                    DBTableModel slaveTable = null;
249                    Map<String,Integer> slaveMap = null;
250    
251                    // 整合æ?チェãƒ?‚¯?šaction="GROUP" と "ADD_CLM" 以外では、スレーブテーブルはå¿??
252                    if( ! ACT_GROUP.equalsIgnoreCase( action ) && !ACT_ADD_CLM.equalsIgnoreCase( action ) ) {
253                            super.setScope( slaveScope );
254                            slaveTable = (DBTableModel)getObject( slaveTableId );
255    
256                            if( slaveTable == null ) {
257                                    String errMsg = "action=\"" + action + "\" 時には、スレーブテーブルがå¿?¦�ですã?"
258                                                            + HybsSystem.CR
259                                                            + "slaveTableId=[" + slaveTableId + "] "
260                                                            + "slaveScope=[" + slaveScope + "] " ;
261                                    throw new HybsSystemException( errMsg );
262                            }
263                            if( noSideEffect ) { slaveTable = cloneTable( slaveTable ); }
264                            slaveMap = makeKeyMap( slaveTable,slaveKeys,false );    // スレーブã?useCheckOnly無関ä¿?
265    
266                            // そã?場合ã?マスタとスレーブが同ä¸?ƒ¡モリ上ã?ãƒ??ブル(物ç�?š„に同じ)でなã�?º‹ã?
267                            if( slaveTable == masterTable ) {
268                                    String errMsg = "マスタとスレーブが同ä¸?ƒ¡モリになってã�?�¾すã?"
269                                                            + "通常、検索結果は TableId と Scope を別ã€?�«æŒ?®šしますã?"
270                                                            + HybsSystem.CR
271                                                            + "action=[" + action + "] "
272                                                            + "masterTableId=[" + masterTableId + "] "
273                                                            + "slaveTableId=[" + slaveTableId + "] "
274                                                            + "masterScope=[" + masterScope + "] "
275                                                            + "slaveScope=[" + slaveScope + "] " ;
276                                    throw new HybsSystemException( errMsg );
277                            }
278                    }
279    
280                    super.setScope( scope );
281                    useMainTrans( isMainTrans );                    // 5.1.6.0 (2010/05/01) DBLastSqlの処ç�??見直ã�?
282                    startQueryTransaction( tableId );               // 3.6.0.8 (2004/11/19)
283    
284                    // 設定å?の整合æ?チェãƒ?‚¯
285                    // 整合æ?チェãƒ?‚¯?šaction="UNION_ALL" と "GROUP"と "ADD_CLM"と "UNION_CLM" 以外では、masterKeys がå¿??
286                    if( ! ACT_UNION_ALL.equalsIgnoreCase( action )
287                            && !ACT_UNION_SELROW.equalsIgnoreCase( action ) // 4.3.2.0 (2008/09/11)
288                            && !ACT_GROUP.equalsIgnoreCase( action )
289                            && !ACT_ADD_CLM.equalsIgnoreCase( action )
290                            && !ACT_UNION_CLM.equalsIgnoreCase( action )
291                            && masterKeys == null ) {
292                                    String errMsg = "action=\"" + action + "\" 時には、masterKeys がå¿??ですã?"
293                                                            + HybsSystem.CR
294                                                            + "masterKeys=[" + masterKeys + "] ";
295                                    throw new HybsSystemException( errMsg );
296                    }
297    
298                    // 設定å?の整合æ?チェãƒ?‚¯
299                    // 整合æ?チェãƒ?‚¯?šaction="DIFFERENCE" では、diffKeys がå¿??
300                    if( ACT_DIFFERENCE.equalsIgnoreCase( action ) && diffKeys == null ) {
301                            String errMsg = "action=\"" + action + "\" 時には、diffKeys がå¿??ですã?"
302                                                    + HybsSystem.CR
303                                                    + "diffKeys=[" + diffKeys + "] ";
304                            throw new HybsSystemException( errMsg );
305                    }
306    
307                    // 設定å?の整合æ?チェãƒ?‚¯
308                    // 整合æ?チェãƒ?‚¯?šå?合æ?(UNION_CLM) と グルーãƒ?GROUP) と 列追åŠ?ADD_CLM) 以外では、テーブルカラãƒ?•°が同じであるå¿?¦�があるã€?
309                    if( ! ACT_UNION_CLM.equalsIgnoreCase( action )
310                             && !ACT_GROUP.equalsIgnoreCase( action )
311                             && !ACT_ADD_CLM.equalsIgnoreCase( action ) ) {
312                            int mClmSize = masterTable.getColumnCount();
313                            int sClmSize = slaveTable.getColumnCount();
314    
315                            if( mClmSize != sClmSize ) {
316                                    String errMsg = "action=\"" + action + "\" 時には、テーブルカラãƒ?•°が異なってはã�?�‘ませんã€?
317                                                            + HybsSystem.CR
318                                                            + "Master=" + mClmSize + " ,["
319                                                            + StringUtil.array2csv( masterTable.getNames() ) + "]"
320                                                            + HybsSystem.CR
321                                                            + "Slave =" + sClmSize + " ,["
322                                                            + StringUtil.array2csv( slaveTable.getNames() ) + "]";
323                                    throw new HybsSystemException( errMsg );
324                            }
325                    }
326    
327                    StringBuilder buf = null;
328                    if( display ) {
329                            buf = new StringBuilder();
330                            buf.append( action ).append( "(" );
331                            buf.append( " M[" ).append( masterTable.getRowCount() ).append( "]" );
332                            if( slaveTable != null ) {
333                                    buf.append( ",S[" ).append( slaveTable.getRowCount() ).append( "]" );
334                            }
335                    }
336    
337                    // 4.3.3.0 (2008/10/01)
338                    setRequestAttribute( "DB.MASTER_COUNT"   , String.valueOf( masterTable.getRowCount() ) );
339                    // 4.3.3.1 (2008/10/08) nullチェãƒ?‚¯
340                    if( slaveTable != null ) {
341                            setRequestAttribute( "DB.SLAVE_COUNT", String.valueOf( slaveTable.getRowCount() ) );
342                    }
343    
344                    DBTableModel table = null;
345                    if( ACT_UNION_ALL.equalsIgnoreCase( action ) ) {                        // 全体集å�?
346                            table = makeUnionAll( masterTable,slaveTable );
347                    }
348                    else if( ACT_UNION_SELROW.equalsIgnoreCase( action ) ) {        // 4.3.2.0 (2008/09/11) 全体集å�?slave表をmaster表のチェãƒ?‚¯行から追åŠ?
349                            table = makeUnionSelrow( masterTable,slaveTable );
350                    }
351                    else if( ACT_UNION.equalsIgnoreCase( action ) ) {                       // 和集å�?
352                            table = makeUnion( masterTable,masterMap,slaveTable,slaveMap );
353                    }
354                    else if( ACT_INTERSECT.equalsIgnoreCase( action ) ) {           // 積集å�?
355                            table = makeIntersect( masterTable,masterMap,slaveMap );
356                    }
357                    else if( ACT_MINUS.equalsIgnoreCase( action ) ) {                       // 差é›?�ˆ
358                            table = makeMinus( masterTable,masterMap,slaveMap );
359                    }
360                    else if( ACT_DIFFERENCE.equalsIgnoreCase( action ) ) {          // 差åˆ?›†å�?
361                            table = makeDifference( masterTable,masterMap,slaveTable,slaveMap );
362                    }
363                    else if( ACT_UNION_CLM.equalsIgnoreCase( action ) ) {           // 列合æˆ?
364                            if( unionClms == null ) {
365                                    String errMsg = "action=\"UNION_CLM\" 時には、unionClms がå¿??ですã?" ;
366                                    throw new HybsSystemException( errMsg );
367                            }
368    
369                            table = makeUnionClm( masterTable,slaveKeys,slaveTable,slaveMap );
370                    }
371                    else if( ACT_ADD_CLM.equalsIgnoreCase( action ) ) {             // 列追åŠ?
372                            if( unionClms == null ) {
373                                    String errMsg = "action=\"ADD_CLM\" 時には、unionClms がå¿??ですã?" ;
374                                    throw new HybsSystemException( errMsg );
375                            }
376    
377                            table = makeAddClm( masterTable );
378                    }
379                    else if( ACT_GROUP.equalsIgnoreCase( action ) ) {                       // グルーãƒ?
380                            table = makeGroup( masterTable );
381                    }
382    
383                    if( table != null ) {
384                            // 3.6.0.8 (2004/11/19) トランザクションチェãƒ?‚¯を行いますã?
385                            super.setScope( scope );
386                            if( ! commitTableObject( tableId, table ) ) {
387                                    return (SKIP_PAGE);
388                            }
389                    }
390    
391                    if( display ) {
392                            buf.append( " ) = [" ).append( table.getRowCount() ).append( "]" );
393                            jspPrint( buf.toString() );
394                    }
395    
396                    // 4.3.3.0 (2008/10/01)
397                    // 4.3.4.4 (2009/01/01)
398                    setRequestAttribute( "DB.COUNT"   , ( table == null ? 0 :String.valueOf( table.getRowCount() ) ) );
399    
400                    return(EVAL_PAGE);              // ペã?ジの残りを評価するã€?
401            }
402    
403            /**
404             * タグリブオブジェクトをリリースしますã?
405             * キャãƒ?‚·ュされて再利用されるã?で、フィールドã?初期設定を行いますã?
406             *
407             * @og.rev 5.1.4.0 (2010/03/01) groupAddClms 追åŠ?
408             * @og.rev 5.1.6.0 (2010/05/01) DBLastSqlの処ç�??、DBTableModelが新規作æ?されたå?ç�?�§のみ行うã€?
409             * @og.rev 5.3.1.0 (2011/01/01) separator追åŠ?
410             */
411            @Override
412            protected void release2() {
413                    super.release2();
414                    command                 = CMD_NEW;
415                    action                  = null;
416                    tableId                 = HybsSystem.TBL_MDL_KEY;               // 出力å?の tableId
417                    scope                   = "session";                                            // 出力å?の scope
418                    masterTableId   = HybsSystem.TBL_MDL_KEY;               // マスタãƒ??ブルの tableId
419                    masterScope             = "session";                                            // マスタãƒ??ブルの scope
420                    slaveTableId    = HybsSystem.TBL_MDL_KEY;               // スレーブテーブルの tableId
421                    slaveScope              = "request";                                            // スレーブテーブルの scope
422                    masterKeys              = null;                                                         // マスタãƒ??ブルのé›?�ˆ処ç�?‚’行う主キー
423                    slaveKeys               = null;                                                         // スレーブテーブルのé›?�ˆ処ç�?‚’行う主キー(nullæ™?masterKeys)
424                    diffKeys                = null;                                                         // マスタãƒ??ブルのDIFFERENCE時ã?差åˆ?‚«ラãƒ?��
425                    unionClms               = null;                                                         // スレーブからã?スタへ追åŠ?�™るカラãƒ?��
426                    modifyClms              = null;                                                         // スレーブからã?スタへ値を更新するカラãƒ?��
427                    groupAddClms    = null;                                                         // 5.1.4.0 (2010/03/01) masterKeysでé›?�ˆ処ç�?�™るときに、相違データをCSV連結して残すカラãƒ?��
428                    noSideEffect    = false;                                                        // ãƒ??ブルモãƒ?ƒ«に対する副作用(true:なã�?false:ある)
429                    useDiffData             = true;                                                         // DIFFERENCE時に差åˆ??スレーブデータを追åŠ?�™るかどã�?�‹
430                    useCheckOnly    = false;                                                        // マスタãƒ??ブルの選択行ã?ãƒ??タのみを対象に処ç�?‚’行うかどã�?�‹
431                    display                 = true;
432                    isMainTrans             = true;                 // 5.1.6.0 (2010/05/01) DBLastSqlの処ç�??見直ã�?
433                    separator               = ",";
434            }
435    
436            /**
437             * æŒ?®šã?ãƒ??ブルのæŒ?®šã?カラãƒ?CSV)より、行番号をã?ãƒ??化しますã?
438             * なおã?引数のãƒ??ブルにつã�?�¦は、主キーによるグループå?ç�?�Œ行われますã?(副作用あり)
439             *
440             * @og.rev 4.3.2.0 (2008/09/11) マスタキー未æŒ?®š時は何もしなã�?
441             * @og.rev 5.1.4.0 (2010/03/01) groupAddClms 追åŠ?
442             * @og.rev 5.3.1.0 (2011/01/01) groupAddClms の separatoræŒ?®š対å¿?
443             * @og.rev 5.5.8.5 (2012/11/27) 大æ–?­—ã?小文字を区別しなã�??
444             *
445             * @param       table   マップ作æ?å…??ãƒ??タãƒ??ブル(副作用あり)
446             * @param       keys    マップ作æ?の主キー(CSV形å¼?
447             * @param       useCheckOnly    チェãƒ?‚¯行ã?みを対象にするかどã�?�‹
448             *
449             * @return マップ化された主キーと行番号
450             */
451            private Map<String,Integer> makeKeyMap( final DBTableModel table, final String keys, final boolean useCheckOnly ) {
452    
453                    // カラãƒ?��をカラãƒ?•ª号に変換しますã?
454                    int[] clmNo = makeColumnNo( table,keys );
455                    int   clmSize = clmNo.length;
456                    if( clmSize == 0 ) {    // マスタキー未æŒ?®š時には全カラãƒ?‚’使用しますã?
457    //                      clmSize = table.getColumnCount();
458    //                      clmNo = new int[clmSize];
459    //                      for( int i=0; i<clmSize; i++ ) {
460    //                              clmNo[i] = i;
461    //                      }
462                            return null; // 4.3.2.0 (2008/09/11)
463                    }
464    
465                    // groupAddClms をカラãƒ?•ª号に変換しますã?
466                    int[] grpClmNo = makeColumnNo( table,groupAddClms );
467                    int   grpClmSize = grpClmNo.length;
468    
469                    Map<String,Integer> tempMap = new LinkedHashMap<String,Integer>();
470    
471                    // 注意:GROUP化ã?過程で ãƒ??ブル件数が動çš?�«変化しますã?
472                    StringBuilder buf ;
473                    for( int row=0; row<table.getRowCount(); row++ ) {
474                            if( useCheckOnly && table.getModifyType( row ).length() == 0 ) {
475                                    continue;
476                            }
477    
478                            buf = new StringBuilder();
479                            for( int i=0; i<clmSize; i++ ) {
480                                    buf.append( table.getValue( row,clmNo[i] ) ).append( "|" );
481                            }
482                            // 主キー連結文字å?
483    //                      String key = buf.toString();    // 主キー連結文字å?
484                            String key = buf.toString().toUpperCase(Locale.JAPAN);          // 5.5.8.5 (2012/11/27) 大æ–?­—ã?小文字を区別しなã�??
485                            if( tempMap.containsKey( key ) ) {
486                                    // 5.1.4.0 (2010/03/01) groupAddClms 追åŠ?
487                                    int orgRow = tempMap.get( key ).intValue() ;                            // 追åŠ?¸ˆみの行番号を取å¾?
488                                    for( int i=0; i<grpClmSize; i++ ) {
489                                            int clm    = grpClmNo[i];
490                                            String val1 = table.getValue( orgRow,clm ) ;                    // 既存ã?行ã?カラãƒ??ãƒ??タ
491                                            String val2 = table.getValue( row,clm ) ;                               // 削除する行ã?カラãƒ??ãƒ??タ
492                                            // 5.3.1.0 (2011/01/01)
493    //                                      table.setValueAt( val1 + "," + val2,orgRow,clm );               // CSV 連結ã?ãƒ??タを戻すã?
494                                            table.setValueAt( val1 + separator + val2,orgRow,clm );         // CSV 連結ã?ãƒ??タを戻すã?
495                                    }
496                                    table.removeValue( row );
497                                    row-- ;
498                            }
499                            else {                                                  // まã�??未登録の場å�?
500                                    tempMap.put( key,Integer.valueOf( row ) );
501                            }
502                    }
503    
504                    return tempMap;
505            }
506    
507            /**
508             * æŒ?®šã?マスタ,スレーブテーブルを使用して 全体集å�?処ç�?‚’実行しますã?
509             *
510             * @param       masterTbl       マスターãƒ??ブルモãƒ?ƒ«
511             * @param       slaveTbl        スレーブテーブルモãƒ?ƒ«
512             *
513             * @return      処ç�?µ�果のãƒ??ブルモãƒ?ƒ«
514             */
515            private DBTableModel makeUnionAll( final DBTableModel masterTbl,final DBTableModel slaveTbl ) {
516                    DBTableModel table = masterTbl;
517    
518                    for( int row=0; row<slaveTbl.getRowCount(); row++ ) {
519                            String[] vals = slaveTbl.getValues( row );
520                            table.addColumnValues( vals );
521                    }
522    
523                    return table;
524            }
525    
526            /**
527             * æŒ?®šã?マスタ,スレーブテーブルを使用して 全体集å�?処ç�?‚’実行しますã?
528             * スレーブ表は、ã?スタ表のチェãƒ?‚¯された行を起点として登録されますã?
529             * チェãƒ?‚¯されてã�?�ªã�??合ã?、スレーブ表は先é?から追åŠ?�•れますã?
530             *
531             * @og.rev 4.3.2.0 (2008/09/11) 新規作æ?
532             *
533             * @param       masterTbl       マスターãƒ??ブルモãƒ?ƒ«
534             * @param       slaveTbl        スレーブテーブルモãƒ?ƒ«
535             *
536             * @return      処ç�?µ�果のãƒ??ブルモãƒ?ƒ«
537             */
538            private DBTableModel makeUnionSelrow( final DBTableModel masterTbl,final DBTableModel slaveTbl ) {
539                    DBTableModel table = masterTbl;
540    
541                    int insRowNo = ( getParameterRows().length > 0 ) ? getParameterRows()[0] + 1 : 0 ;
542                    for( int row=0; row<slaveTbl.getRowCount(); row++ ) {
543                            String[] vals = slaveTbl.getValues( row );
544                            table.addValues( vals, insRowNo + row, false );
545                    }
546    
547                    return table;
548            }
549    
550            /**
551             * æŒ?®šã?マスタ,スレーブテーブルを使用して 和集å�?処ç�?‚’実行しますã?
552             *
553             * @og.rev 5.5.8.5 (2012/11/27) 大æ–?­—ã?小文字を区別しなã�??
554             *
555             * @param       masterTbl       マスターãƒ??ブルモãƒ?ƒ«
556             * @param       masterMap       マスターãƒ??ブルの主キーマッãƒ?
557             * @param       slaveTbl        スレーブテーブルモãƒ?ƒ«
558             * @param       slaveMap        スレーブテーブルの主キーマッãƒ?
559             *
560             * @return      処ç�?µ�果のãƒ??ブルモãƒ?ƒ«
561             */
562            private DBTableModel makeUnion( final DBTableModel masterTbl,final Map<String,Integer> masterMap,
563                                                                            final DBTableModel slaveTbl,final Map<String,Integer> slaveMap ) {
564                    DBTableModel table = masterTbl;
565    
566                    @SuppressWarnings("rawtypes")
567                    Map.Entry[] entry = slaveMap.entrySet().toArray( new Map.Entry[slaveMap.size()] );
568    
569                    int size = entry.length;
570                    for( int i=0; i<size; i++ ) {
571                            String key  = (String)entry[i].getKey();
572                            if( key != null ) { key = key.toUpperCase(Locale.JAPAN); }              // 5.5.8.5 (2012/11/27) 大æ–?­—ã?小文字を区別しなã�??
573                            if( ! masterMap.containsKey( key ) ) {          // マスタにスレーブデータが存在しなã�?
574                                    int row =  ((Integer)entry[i].getValue()).intValue();
575                                    String[] vals = slaveTbl.getValues( row );
576                                    table.addColumnValues( vals );
577                            }
578                    }
579                    return table;
580            }
581    
582            /**
583             * æŒ?®šã?マスタ,スレーブテーブルを使用して 積集å�?処ç�?‚’実行しますã?
584             *
585             * @og.rev 5.5.8.5 (2012/11/27) 大æ–?­—ã?小文字を区別しなã�??
586             *
587             * @param       masterTbl       マスターãƒ??ブルモãƒ?ƒ«
588             * @param       masterMap       マスターãƒ??ブルの主キーマッãƒ?
589             * @param       slaveMap        スレーブテーブルの主キーマッãƒ?
590             *
591             * @return      処ç�?µ�果のãƒ??ブルモãƒ?ƒ«
592             */
593            private DBTableModel makeIntersect( final DBTableModel masterTbl,final Map<String,Integer> masterMap, final Map<String,Integer> slaveMap ) {
594                    DBTableModel table = masterTbl;
595    
596                    @SuppressWarnings("rawtypes")
597                    Map.Entry[] entry = masterMap.entrySet().toArray( new Map.Entry[masterMap.size()] );
598    
599                    int size = entry.length;
600                    for( int i=0; i<size; i++ ) {
601                            String key  = (String)entry[i].getKey();
602                            if( key != null ) { key = key.toUpperCase(Locale.JAPAN); }              // 5.5.8.5 (2012/11/27) 大æ–?­—ã?小文字を区別しなã�??
603                            if( ! slaveMap.containsKey( key ) ) {           // スレーブにマスタが存在しなã�?
604                                    int row =  ((Integer)entry[i].getValue()).intValue();
605                                    table.rowDelete( row );                         // 論理削除
606                            }
607                    }
608    
609                    // 行番号が変わらなã�?‚ˆã�?�«é€??削除しますã?
610                    for( int row=table.getRowCount()-1; row>=0; row-- ) {
611    //                      if( DBTableModel.DELETE_TYPE.equals( table.getModifyType( row ) ) ) {
612                            if( DBTableModel.DELETE_TYPE.equalsIgnoreCase( table.getModifyType( row ) ) ) {         // 5.5.8.5 (2012/11/27) 大æ–?­—ã?小文字を区別しなã�??
613                                    table.removeValue( row );
614                            }
615                    }
616    
617                    return table;
618            }
619    
620            /**
621             * æŒ?®šã?マスタ,スレーブテーブルを使用して 差é›?�ˆ 処ç�?‚’実行しますã?
622             *
623             * @og.rev 5.5.8.5 (2012/11/27) 大æ–?­—ã?小文字を区別しなã�??
624             *
625             * @param       masterTbl       マスターãƒ??ブルモãƒ?ƒ«
626             * @param       masterMap       マスターãƒ??ブルの主キーマッãƒ?
627             * @param       slaveMap        スレーブテーブルの主キーマッãƒ?
628             *
629             * @return      処ç�?µ�果のãƒ??ブルモãƒ?ƒ«
630             */
631            private DBTableModel makeMinus( final DBTableModel masterTbl,final Map<String,Integer> masterMap,
632                                                                            final Map<String,Integer> slaveMap ) {
633                    DBTableModel table = masterTbl;
634    
635                    @SuppressWarnings("rawtypes")
636                    Map.Entry[] entry = masterMap.entrySet().toArray( new Map.Entry[masterMap.size()] );
637    
638                    int size = entry.length;
639                    for( int i=0; i<size; i++ ) {
640                            String key  = (String)entry[i].getKey();
641                            if( key != null ) { key = key.toUpperCase(Locale.JAPAN); }              // 5.5.8.5 (2012/11/27) 大æ–?­—ã?小文字を区別しなã�??
642                            if( slaveMap.containsKey( key ) ) {             // スレーブにマスタが存在する
643                                    int row =  ((Integer)entry[i].getValue()).intValue();
644                                    table.rowDelete( row );                         // 論理削除
645                            }
646                    }
647    
648                    // 行番号が変わらなã�?‚ˆã�?�«é€??削除しますã?
649                    for( int row=table.getRowCount()-1; row>=0; row-- ) {
650    //                      if( DBTableModel.DELETE_TYPE.equals( table.getModifyType( row ) ) ) {
651                            if( DBTableModel.DELETE_TYPE.equalsIgnoreCase( table.getModifyType( row ) ) ) {         // 5.5.8.5 (2012/11/27) 大æ–?­—ã?小文字を区別しなã�??
652                                    table.removeValue( row );
653                            }
654                    }
655    
656                    return table;
657            }
658    
659            /**
660             * æŒ?®šã?マスタ,スレーブテーブルを使用して 差åˆ?›†å�?処ç�?‚’実行しますã?
661             *
662             * @og.rev 5.5.8.5 (2012/11/27) 大æ–?­—ã?小文字を区別しなã�??
663             *
664             * @param       masterTbl       マスターãƒ??ブルモãƒ?ƒ«
665             * @param       masterMap       マスターãƒ??ブルの主キーマッãƒ?
666             * @param       slaveTbl        スレーブテーブルモãƒ?ƒ«
667             * @param       slaveMap        スレーブテーブルの主キーマッãƒ?
668             *
669             * @return      処ç�?µ�果のãƒ??ブルモãƒ?ƒ«
670             */
671            private DBTableModel makeDifference( final DBTableModel masterTbl,final Map<String,Integer> masterMap,
672                                                                                     final DBTableModel slaveTbl ,final Map<String,Integer> slaveMap ) {
673                    DBTableModel table = masterTbl;
674    
675                    // ãƒ??ブルの差åˆ?±žæ?のカラãƒ?•ª号を求めますã?(マスタ、スレーブå?é€?
676                    int[] diffClmNo = makeColumnNo( table,diffKeys );
677                    int diffClmSize = diffClmNo.length;
678    
679                    // スレーブからã?スタへ値の再セãƒ?ƒˆを行うカラãƒ?•ª号を求めますã?(マスタ、スレーブå?é€?
680                    int[] modClmNo = makeColumnNo( table,modifyClms );
681                    int modClmSize = modClmNo.length;
682    
683                    int clmSize = table.getColumnCount();
684                    DBTableModel newTable = DBTableModelUtil.newDBTable();
685                    newTable.init( clmSize );
686    
687                    // ãƒ??ブルの全カラãƒ?‚’新たに作æ?するãƒ??ブルにコピã?しますã?
688                    for( int i=0; i<clmSize; i++ ) {
689                            newTable.setDBColumn( i,table.getDBColumn( i ) );
690                    }
691    
692                    // スレーブã?先é?カラãƒ?�Œ、WRITABLE かどã�?�‹
693                    boolean writeFlag = "WRITABLE".equalsIgnoreCase( slaveTbl.getColumnName(0) );
694    
695                    @SuppressWarnings("rawtypes")
696                    Map.Entry[] entry = masterMap.entrySet().toArray( new Map.Entry[masterMap.size()] );
697    
698                    int size = entry.length;
699                    for( int i=0; i<size; i++ ) {
700                            String key  = (String)entry[i].getKey();
701                            if( key != null ) { key = key.toUpperCase(Locale.JAPAN); }              // 5.5.8.5 (2012/11/27) 大æ–?­—ã?小文字を区別しなã�??
702                            if( slaveMap.containsKey( key ) ) {             // スレーブにマスタが存在する
703                                    int mrow =  ((Integer)entry[i].getValue()).intValue();
704                                    int srow =  (slaveMap.get( key )).intValue();
705                                    boolean unmatched = false;
706                                    for( int j=0; j<diffClmSize; j++ ) {
707                                            String mval = table.getValue( mrow,diffClmNo[j] );
708                                            String sval = slaveTbl.getValue( srow,diffClmNo[j] );
709    //                                      if( mval != null && !mval.equals( sval ) ) { unmatched = true; break; }
710                                            if( mval != null && !mval.equalsIgnoreCase( sval ) ) { unmatched = true; break; }               // 5.5.8.5 (2012/11/27) 大æ–?­—ã?小文字を区別しなã�??
711                                    }
712    
713                                    if( unmatched ) {               // 属æ?æƒ??が異なるå?合ã?み処ç�?
714                                            // ãƒ??タのコピã?
715                                            String[] mvals = new String[clmSize];
716                                            System.arraycopy( table.getValues( mrow ),0,mvals,0 ,clmSize );
717    
718                                            // スレーブã?値をã?スタの値にセãƒ?ƒˆするã€?
719                                            for( int j=0; j<modClmSize; j++ ) {
720                                                    String val = slaveTbl.getValue( srow,modClmNo[j] );
721                                                    mvals[modClmNo[j]] = val;
722                                            }
723                                            newTable.addColumnValues( mvals );
724    
725                                            if( useDiffData ) {
726                                                    // ãƒ??タのコピã?
727                                                    String[] svals = new String[clmSize];
728                                                    System.arraycopy( slaveTbl.getValues( srow ),0,svals,0 ,clmSize );
729                                                    if( writeFlag ) { svals[0] = "0"; }     // 書き込み不許可
730                                                    for( int j=0; j<diffClmSize; j++ ) {
731                                                            int dclmNo = diffClmNo[j];
732                                                            String mval = mvals[dclmNo];
733                                                            String sval = svals[dclmNo];
734    //                                                      if( mval != null && !mval.equals( sval ) ) {
735                                                            if( mval != null && !mval.equalsIgnoreCase( sval ) ) {          // 5.5.8.5 (2012/11/27) 大æ–?­—ã?小文字を区別しなã�??
736                                                                    svals[dclmNo] = "<span class=\"unmatched\">" + sval + "</span>" ;
737                                                            }
738                                                    }
739                                                    newTable.addColumnValues( svals );
740            //                                      newTable.setRowWritable( newTable.getRowCount()-1,false );      // 書き込み不許可
741                                            }
742                                    }
743                            }
744                    }
745                    return newTable;
746            }
747    
748            /**
749             * æŒ?®šã?マスタ,スレーブテーブルを使用して 列合æˆ?処ç�?‚’実行しますã?
750             *
751             * すでに、ã?スタ にカラãƒ?�Œ存在してã�?‚‹場合ã?、å?の書き換えをã€?
752             * カラãƒ?�Œ存在しなければ、カラãƒ?‚’追åŠ?�—ますã?
753             * マスタとスレーブã?ãƒ??タ突合せ時のキーは、slaveKeys になりますã?
754             * これは、masterMap を使用しなã�?�“とを意味しますã?(masterKeys æŒ?®šによるGROUP化ã?
755             * 行いますã?masterKeys を指定しなã�??合ã?、サマライズなしで処ç�?�—ますã?)
756             * 具体的には、ã?スタãƒ??ブルのè¤?•°の行に対して、スレーブデータの値が設å®?
757             * される可能性があることを意味しますã?
758             *
759             * @og.rev 5.5.8.5 (2012/11/27) 大æ–?­—ã?小文字を区別しなã�??
760             *
761             * @param       masterTbl       マスターãƒ??ブルモãƒ?ƒ«
762             * @param       slaveKeys       スレーブキー
763             * @param       slaveTbl        スレーブテーブルモãƒ?ƒ«
764             * @param       slaveMap        スレーブテーブルの主キーマッãƒ?
765             *
766             * @return      処ç�?µ�果のãƒ??ブルモãƒ?ƒ«
767             */
768            private DBTableModel makeUnionClm( final DBTableModel masterTbl ,final String slaveKeys ,
769                                                                                    final DBTableModel slaveTbl ,final Map<String,Integer> slaveMap ) {
770    
771                    DBTableModel table = makeAddClm( masterTbl );
772    
773                    // カラãƒ?��をカラãƒ?•ª号に変換しますã?
774                    int[] keyClmNo = makeColumnNo( table,slaveKeys );
775    
776                    int[] mClmNo = makeColumnNo( table   ,unionClms );
777                    int[] sClmNo = makeColumnNo( slaveTbl,unionClms );
778                    int   addSize = mClmNo.length;          // unionClms の個数なので、ã?スタ、スレーブã?同ä¸?
779    
780                    // 突合せを行い、ã?ãƒ?ƒ�するカラãƒ?�«つã�?�¦、å?をセãƒ?ƒˆし直しますã?
781    //              Map.Entry[] entry = slaveMap.entrySet().toArray( new Map.Entry[slaveMap.size()] );
782    
783                    for( int row=0; row<table.getRowCount(); row++ ) {
784                            String[] mvals = table.getValues( row );
785                            StringBuilder buf = new StringBuilder();
786                            for( int i=0; i<keyClmNo.length; i++ ) {
787                                    buf.append( mvals[keyClmNo[i]] ).append( "|" );
788                            }
789                            // 主キー連結文字å?
790    //                      String key = buf.toString();    // 主キー連結文字å?
791                            String key = buf.toString().toUpperCase(Locale.JAPAN);          // 5.5.8.5 (2012/11/27) 大æ–?­—ã?小文字を区別しなã�??
792                            if( slaveMap.containsKey( key ) ) {             // スレーブにマスタに対応するデータが存在する
793                                    int slvRow =  (slaveMap.get( key )).intValue();
794                                    String[] svals = slaveTbl.getValues( slvRow );          // スレーブã?行番号
795                                    for( int j=0; j<addSize; j++ ) {
796                                            mvals[mClmNo[j]] = svals[sClmNo[j]];
797                                    }
798                                    table.setValues( mvals,row );
799                            }
800                    }
801                    table.resetModify();
802    
803                    return table;
804            }
805    
806            /**
807             * æŒ?®šã?マスタãƒ??ブルに 列追åŠ?処ç�?‚’実行しますã?
808             *
809             * すでに、ã?スタ にカラãƒ?�Œ存在してã�?‚‹場合ã?、å?の書き換えをã€?
810             * カラãƒ?�Œ存在しなければ、カラãƒ?‚’追åŠ?�—ますã?
811             *
812             * @param       masterTbl       マスターãƒ??ブルモãƒ?ƒ«
813             *
814             * @return      処ç�?µ�果のãƒ??ブルモãƒ?ƒ«
815             */
816            private DBTableModel makeAddClm( final DBTableModel masterTbl ) {
817                    String[]  addClms        = StringUtil.csv2Array( unionClms );
818                    int       addClmSize = addClms.length;
819                    boolean[] useAdd         = new boolean[addClmSize];
820                    int addSize = 0;
821                    for( int i=0; i<addClmSize; i++ ) {
822                            if( masterTbl.getColumnNo( addClms[i],false ) < 0 ) {        // 存在しなければ -1
823                                    useAdd[i] = true;
824                                    addSize++ ;
825                            }
826                            else {
827                                    useAdd[i] = false;              // マスタに存在すれば、追åŠ?¸�è¦?
828                            }
829                    }
830    
831                    int mstrClmSize = masterTbl.getColumnCount();
832                    int clmSize = mstrClmSize + addSize;
833    
834                    DBTableModel table = DBTableModelUtil.newDBTable();
835                    table.init( clmSize );
836                    int clmNo = 0;
837                    // マスタãƒ??ブルの全カラãƒ?‚’新たに作æ?するãƒ??ブルにコピã?しますã?
838                    for( int i=0; i<mstrClmSize; i++ ) {
839                            table.setDBColumn( clmNo++,masterTbl.getDBColumn( i ) );
840                    }
841                    // 追åŠ?�™るカラãƒ?‚’新たに作æ?するãƒ??ブルに追åŠ?�—ますã?
842                    String[] addClmVal = new String[addSize];       // 追åŠ??のみ
843                    int addCnt = 0;
844                    for( int i=0; i<addClmSize; i++ ) {
845                            if( useAdd[i] ) {
846                                    DBColumn column = getDBColumn( addClms[i] );
847                                    addClmVal[addCnt++] = nval( column.getDefault(),"" );
848                                    table.setDBColumn( clmNo++,column );
849                            }
850                    }
851                    // ä¸?—¦、すべてのマスタãƒ??タを新ãƒ??ブルにコピã?しますã?
852                    for( int row=0; row<masterTbl.getRowCount(); row++ ) {
853                            String[] vals = new String[clmSize];
854                            System.arraycopy( masterTbl.getValues( row ),0,vals,0 ,mstrClmSize );   // マスタãƒ??タのコピã?
855                            System.arraycopy( addClmVal,0,vals,mstrClmSize ,addSize );                              // 追åŠ??æƒ??の初期値
856                            table.addColumnValues( vals );
857                    }
858    
859                    return table;
860            }
861    
862            /**
863             * æŒ?®šã?マスタãƒ??ブルを使用して グルーãƒ?処ç�?‚’実行しますã?
864             *
865             * @param       masterTbl       マスターãƒ??ブルモãƒ?ƒ«
866             *
867             * @return      処ç�?µ�果のãƒ??ブルモãƒ?ƒ«
868             */
869            private DBTableModel makeGroup( final DBTableModel masterTbl ) {
870                    DBTableModel table = masterTbl;
871    
872                    return table;
873            }
874    
875            /**
876             * æŒ?®šã?ãƒ??ブルと同じãƒ??ブルを別オブジェクトとして作æ?しますã?
877             *
878             * @param       tbl     コピã?å…?ƒ†ーブルモãƒ?ƒ«
879             *
880             * @return      コピã?された新ãƒ??ブルモãƒ?ƒ«
881             */
882            private DBTableModel cloneTable( final DBTableModel tbl ) {
883                    int clmSize = tbl.getColumnCount();
884    
885                    DBTableModel table = DBTableModelUtil.newDBTable();
886                    table.init( clmSize );
887    
888                    // ãƒ??ブルの全カラãƒ?‚’新たに作æ?するãƒ??ブルにコピã?しますã?
889                    for( int i=0; i<clmSize; i++ ) {
890                            table.setDBColumn( i,tbl.getDBColumn( i ) );
891                    }
892                    // すべてのãƒ??タを新ãƒ??ブルにコピã?しますã?
893                    for( int row=0; row<tbl.getRowCount(); row++ ) {
894                            String[] vals = new String[clmSize];
895                            System.arraycopy( tbl.getValues( row ),0,vals,0 ,clmSize );     // ãƒ??タのコピã?
896                            table.addColumnValues( vals );
897                    }
898                    return table;
899            }
900    
901            /**
902             * æŒ?®šã?ãƒ??ブルより、カラãƒ??名に対応するカラãƒ?•ª号配å?を作æ?しますã?
903             *
904             * カラãƒ?��のCSVãƒ??タã�?æŒ?®šされなã�??å�?clmcsv == null)はã€?•·さ0ã?配å?を返しますã?
905             *
906             * @param       table   ãƒ??ブルモãƒ?ƒ«
907             * @param       clmcsv  カラãƒ?��のCSVãƒ??タ
908             *
909             * @return      カラãƒ?��に対応するã?列番号配å?(なければã€?•·さ0é?åˆ?
910             */
911            private int[] makeColumnNo( final DBTableModel table,final String clmcsv ) {
912    
913                    // マスタãƒ??ブルの差åˆ?±žæ?のカラãƒ?•ª号を求めますã?
914                    String[] clms = StringUtil.csv2Array( clmcsv );
915                    int[] clmNo = new int[clms.length];
916    
917                    // カラãƒ?��をカラãƒ?•ª号に変換しますã?
918                    for( int i=0; i<clms.length; i++ ) {
919                            clmNo[i] = table.getColumnNo( clms[i] );
920                    }
921    
922                    return clmNo;
923            }
924    
925            /**
926             * 【TAG】コマンãƒ?NEW,RENEW)をセãƒ?ƒˆしまã�?初期値:NEW)ã€?
927             *
928             * @og.tag
929             * コマンドã?,HTMLから(get/post)æŒ?®šされますã?で,CMD_xxx で設定される
930             * フィールド定数値のã�?�¥れかをã?æŒ?®šできますã?
931             * 初期値は NEW ですã?
932             *
933             * @param       cmd     コマンãƒ?public static final 宣è¨?�•れてã�?‚‹æ–?­—å?)
934             * @see         <a href="../../../../constant-values.html#org.opengion.hayabusa.taglib.TableMergeTag.CMD_NEW">コマンド定数</a>
935             */
936            public void setCommand( final String cmd ) {
937                    String cmd2 = getRequestParameter( cmd );
938                    if( cmd2 != null && cmd2.length() > 0 ) { command = cmd2.toUpperCase(Locale.JAPAN); }
939            }
940    
941            /**
942             * 【TAG】アクションを指定しまã�?UNION_ALL|UNION|INTERSECT|MINUS|DIFFERENCE|UNION_CLM|ADD_CLM|GROUP|UNION_SELROW)ã€?
943             *
944             * @og.tag
945             * æŒ?®šできるアクションは、å?体集å�?UNION_ALL)、å?体集å�?挿入位置æŒ?®?(UNION_SELROW)、和é›?�ˆ(UNION)
946             * 、積集å�?INTERSECT)、差é›?�ˆ(MINUS)、差åˆ?›†å�?DIFFERENCE)、å?合æ?(UNION_CLM)、å?追åŠ?ADD_CLM)ã€?グルーãƒ?GROUP)ですã?
947             * 列合成とグループ以外ã?処ç�?�§は、カラãƒ??とカラãƒ?•°は同数でなければなりませんã€?
948             * primaryKeys ã‚?unionClms などのæŒ?®šã?キー名ã?、ã?スタãƒ??ブルに存在するå¿?¦�がありますã?
949             * マスタãƒ??ブルと同じカラãƒ?•ª号でスレーブテーブルよりãƒ??タを読み出しますã?
950             * (カラãƒ?��ã‚?±žæ?は、異なってもかまã�?�¾せんがã?マスタãƒ??ブルに準拠しますã?)
951             * またã?単独(マスタãƒ??ブルのみ)で、和é›?�ˆと同等ã?、グルーãƒ?GROUP)を使用すると、指定ã?
952             * カラãƒ?�§のユニã?ク化を行うことが可能になりますã?グループå?ç�?�§は、å?行優先としã?
953             * ?’回目に現れたæƒ??を削除することになりますã?グルーãƒ?が指定された場合ã?ã€?
954             * スレーブテーブルは無視されますã?ã�?�šれã?処ç�?�«おいてもã?é›?�ˆ処ç�?‚’行う主キーで
955             * ä¸?—¦グループ化されますã?全体集å�?UNION_ALL)で処ç�?�™るå?合でもã?主キーがユニã?クで
956             * なã�??合ã?、ã?スター、スレーブã?å�?ƒ†ーブルでä¸?—¦グループ化された後で、ã?ージされますã?
957             * (マã?ジ後には、同ä¸?¸»キーを持つ行ã?存在しますã?)
958             * 全体集å�?UNION_ALL)の場合ã?み、mergeKeys を指定するå¿?¦�ã?ありません。その場合ã?ã€?
959             * キーなしã?ため、ã?スターとスレーブã?ãƒ??ブルを単に合æ?するã�?�‘になりますã?
960             *
961             * <table border="1" frame="box" rules="all" >
962             *   <caption>アクションの説æ˜?/caption>
963             *   <tr><th>action      </th><th>名称    </th><th>処ç�?¦‚è¦?                                                                                 </th><th>??/th><th>??/th><th>??/th><th>??/th><tr>
964             *   <tr><td>UNION_ALL   </td><td>全体集å�?/td><td>マスタとスレーブを合æ?
965             *   <tr><td>UNION_SELROW</td><td>全体集å�?/td><td>マスタとスレーブを合æ?(マスタ表のチェãƒ?‚¯行を起点に追åŠ?/td><td>â—?/td><td>ã€?/td><td>ã€?/td><td>ã€?/td><tr>
966             *   <tr><td>UNION       </td><td>和集å�? </td><td>マスタとスレーブã?ユニã?ク部のみ合æ?                                   </td><td>â—?/td><td>â—?/td><td>ã€?/td><td>ã€?/td><tr>
967             *   <tr><td>INTERSECT   </td><td>積集å�? </td><td>マスタとスレーブã?ユニã?ク部がä¸??するマスタのみ選æŠ?</td><td>â—?/td><td>â—?/td><td>ã€?/td><td>ã€?/td><tr>
968             *   <tr><td>MINUS       </td><td>差é›?�ˆ  </td><td>マスタからスレーブに存在するユニã?ク部を削除した残り       </td><td>â—?/td><td>â—?/td><td>ã€?/td><td>ã€?/td><tr>
969             *   <tr><td>DIFFERENCE  </td><td>差åˆ?›†å�?/td><td>ユニã?ク部がä¸??しã?差åˆ?‚«ラãƒ?�Œ異なるã?スタのみ選æŠ?</td><td>â—?/td><td>â—?/td><td>ã€?/td><td>â—?/td><tr>
970             *   <tr><td>UNION_CLM   </td><td>列合æˆ? </td><td>マスタとキーä¸??するスレーブã?カラãƒ?ƒ…報を追åŠ?  </td><td>â—?/td><td>â—?/td><td>â—?/td><td>ã€?/td><tr>
971             *   <tr><td>ADD_CLM     </td><td>列追åŠ? </td><td>UNION_CLMとの違いは、カラãƒ??み追åŠ?�™ることですã?       </td><td>ã€?/td><td>ã€?/td><td>â—?/td><td>ã€?/td><tr>
972             *   <tr><td>GROUP       </td><td>グルーãƒ?/td><td>マスタのユニã?ク部åŒ?                                                           </td><td>ã€?/td><td>ã€?/td><td>ã€?/td><td>ã€?/td><tr>
973             * </table>
974             *
975             * ※?šã?スタãƒ??ブルオブジェクトã?、常にå¿??
976             * ?‘:スレーブテーブルオブジェクトå¿??
977             * ?’:masterKeys 属æ?å¿??
978             * ?“:unionClms 属æ?å¿??(スレーブテーブルのカラãƒ?��またã?追åŠ?�™るカラãƒ?��)
979             * ?”:diffKeys 属æ?å¿??(DIFFERENCE時ã?差åˆ?‚«ラãƒ?��)、modifyClms 属æ?使用可能
980             *
981             * @param       action アクション(UNION_ALL|UNION|INTERSECT|MINUS|DIFFERENCE|UNION_CLM|ADD_CLM|GROUP|UNION_SELROW)
982             */
983            public void setAction( final String action ) {
984                    this.action = nval( getRequestParameter( action ),this.action );
985            }
986    
987            /**
988             * 【TAG】å?力å?のtableIdを指定しまã�?
989             *              (初期値:HybsSystem#TBL_MDL_KEY[={@og.value HybsSystem#TBL_MDL_KEY}])ã€?
990             *
991             * @og.tag
992             * é›?�ˆ処ç�?µ�果の DBTableModel をメモリにセãƒ?ƒˆする場合ã?キー(tableId)を指定しますã?
993             * (初期値:HybsSystem#TBL_MDL_KEY[={@og.value HybsSystem#TBL_MDL_KEY}])ã€?
994             *
995             * @param       tableId 出力å?のtableId
996             * @see         org.opengion.hayabusa.common.HybsSystem#TBL_MDL_KEY
997             */
998            public void setTableId( final String tableId ) {
999                    this.tableId = nval( getRequestParameter( tableId ),this.tableId );
1000            }
1001    
1002            /**
1003             * 【TAG】å?力å?のscopeを指定しまã�?初期値:session)ã€?
1004             *
1005             * @og.tag
1006             * é›?�ˆ処ç�?µ�果の DBTableModel をメモリにセãƒ?ƒˆする場合ã?スコープをæŒ?®šしますã?
1007             * ここでは、ã?スタã‚?‚¹レーブã?スコープ設定がå¿?¦�な為、superクラスのメソãƒ?ƒ‰ã‚?
1008             * オーバã?ライドしてこã?オブジェクトå?でキープしてã�?�¾すã?
1009             * 初期値は、session ですã?
1010             *
1011             * @param       scope   出力å?のscope
1012             */
1013            @Override
1014            public void setScope( final String scope ) {
1015                    this.scope = nval( getRequestParameter( scope ),this.scope );
1016            }
1017    
1018            /**
1019             * 【TAG】ã?スタãƒ??ブルのtableIdを指定しまã�?
1020             *              (初期値:HybsSystem#TBL_MDL_KEY[={@og.value HybsSystem#TBL_MDL_KEY}])ã€?
1021             *
1022             * @og.tag
1023             * é›?�ˆ処ç�??マスタとなã‚?DBTableModel をメモリから取り出すå?合ã?キー(tableId)を指定しますã?
1024             * (初期値:HybsSystem#TBL_MDL_KEY[={@og.value HybsSystem#TBL_MDL_KEY}])ã€?
1025             *
1026             * @param       masterTableId   マスタãƒ??ブルのtableId
1027             * @see         org.opengion.hayabusa.common.HybsSystem#TBL_MDL_KEY
1028             */
1029            public void setMasterTableId( final String masterTableId ) {
1030                    this.masterTableId = nval( getRequestParameter( masterTableId ),this.masterTableId );
1031            }
1032    
1033            /**
1034             * 【TAG】ã?スタãƒ??ブルのscopeを指定しまã�?初期値:session)ã€?
1035             *
1036             * @og.tag
1037             * é›?�ˆ処ç�??マスタとなã‚?DBTableModel をメモリから取り出すå?合ã?スコープをæŒ?®šしますã?
1038             * 初期値は、session ですã?
1039             *
1040             * @param       masterScope     マスタãƒ??ブルのscope
1041             */
1042            public void setMasterScope( final String masterScope ) {
1043                    this.masterScope = nval( getRequestParameter( masterScope ),this.masterScope );
1044            }
1045    
1046            /**
1047             * 【TAG】ã?スタãƒ??ブルのé›?�ˆ処ç�?‚’行う主キーを指定しますã?
1048             *
1049             * @og.tag
1050             * é›?�ˆ処ç�?‚’行う場合ã?、カラãƒ?��をã?カンマ区åˆ?‚Šæ–?­?CSV形å¼?でæŒ?®šしますã?
1051             * こã?キーのçµ?�¿合わせをå…?�«ã€?›†合å?ç�??突合せを行いますã?
1052             * なおã?アクションがグルーãƒ?GROUP)以外ã?処ç�?�§は、ã?スタとスレーブã?カラãƒ?•°と
1053             * 並びé ??、同じでなければなりません。カラãƒ?��は、各ã€?ˆ¥ã€?�§もかまã�?�¾せんã€?
1054             * アクションがå?体集å�?UNION_ALL)以外ã?場合ã?、å¿??属æ?になりますã?
1055             *
1056             * @param       masterKeys      マスタãƒ??ブルの主キーをCSV形式でæŒ?®?
1057             */
1058            public void setMasterKeys( final String masterKeys ) {
1059                    this.masterKeys = nval( getRequestParameter( masterKeys ),this.masterKeys );
1060            }
1061    
1062            /**
1063             * 【TAG】スレーブテーブルのé›?�ˆ処ç�?‚’行う主キーを指定しますã?
1064             *
1065             * @og.tag
1066             * é›?�ˆ処ç�?‚’行う場合ã?、カラãƒ?��をã?カンマ区åˆ?‚Šæ–?­?CSV形å¼?でæŒ?®šしますã?
1067             * こã?キーのçµ?�¿合わせをå…?�«ã€?›†合å?ç�??突合せを行いますã?
1068             * なおã?アクションがグルーãƒ?GROUP)以外ã?処ç�?�§は、ã?スタとスレーブã?カラãƒ?•°と
1069             * 並びé ??、同じでなければなりません。カラãƒ?��は、各ã€?ˆ¥ã€?�§もかまã�?�¾せんã€?
1070             * null の場合ã?、masterKeys と同じとしますã?
1071             *
1072             * @param       slaveKeys       スレーブテーブルの主キーをCSV形式でæŒ?®?
1073             */
1074            public void setSlaveKeys( final String slaveKeys ) {
1075                    this.slaveKeys = nval( getRequestParameter( slaveKeys ),this.slaveKeys );
1076            }
1077    
1078            /**
1079             * 【TAG】ã?スタãƒ??ブルのDIFFERENCE時ã?差åˆ?‚«ラãƒ?��ã‚?CSV形å¼?æŒ?®šしますã?
1080             *
1081             * @og.tag
1082             * アクションが差åˆ??ç�?DIFFERENCE)の場合に、差åˆ?ƒ�ェãƒ?‚¯を行うカラãƒ?��をã?
1083             * カンマ区åˆ?‚Šæ–?­?CSV形å¼?でæŒ?®šしますã?
1084             * 差åˆ??ç�?�¨は、masterKeys でæŒ?®šされたキーでは、ã?スタ、スレーブともに存在ã�?
1085             * かつ、このキー(diffKeys)でæŒ?®šされたキーの値が異なるã?スタレコードを
1086             * 抜き出しますã?
1087             * つまりã?主キーは存在しã?属æ?が異なる情報のピックアãƒ??になりますã?でã€?
1088             * ãƒ??タ更新(UPDATE)対象を見つける場合に使用できますã?
1089             * アクションが差åˆ??ç�?DIFFERENCE)の場合ã?、å¿??属æ?になりますã?
1090             *
1091             * @param       diffKeys        マスタãƒ??ブルの差åˆ?‚«ラãƒ?��をCSV形式でæŒ?®?
1092             * @see         #setMasterKeys( String )
1093             */
1094            public void setDiffKeys( final String diffKeys ) {
1095                    this.diffKeys = nval( getRequestParameter( diffKeys ),this.diffKeys );
1096            }
1097    
1098            /**
1099             * 【TAG】スレーブテーブルのtableIdを指定しまã�?
1100             *              (初期値:HybsSystem#TBL_MDL_KEY[={@og.value HybsSystem#TBL_MDL_KEY}])ã€?
1101             *
1102             * @og.tag
1103             * é›?�ˆ処ç�??スレーブとなã‚?DBTableModel をメモリから取り出すå?合ã?キー(tableId)を指定しますã?
1104             * なおã?アクションがグルーãƒ?GROUP)の場合ã?、スレーブテーブルは使用されませんã€?
1105             * (初期値:HybsSystem#TBL_MDL_KEY[={@og.value HybsSystem#TBL_MDL_KEY}])ã€?
1106             *
1107             * @param       slaveTableId    スレーブテーブルのtableId
1108             * @see         org.opengion.hayabusa.common.HybsSystem#TBL_MDL_KEY
1109             */
1110            public void setSlaveTableId( final String slaveTableId ) {
1111                    this.slaveTableId = nval( getRequestParameter( slaveTableId ),this.slaveTableId );
1112            }
1113    
1114            /**
1115             * 【TAG】スレーブテーブルのscopeを指定しまã�?初期値:session)ã€?
1116             *
1117             * @og.tag
1118             * é›?�ˆ処ç�??スレーブとなã‚?DBTableModel をメモリから取り出すå?合ã?スコープをæŒ?®šしますã?
1119             * なおã?アクションがグルーãƒ?GROUP)の場合ã?、スレーブテーブルは使用されませんã€?
1120             * 初期値は、session ですã?
1121             *
1122             * @param       slaveScope      スレーブテーブルのscope
1123             */
1124            public void setSlaveScope( final String slaveScope ) {
1125                    this.slaveScope = nval( getRequestParameter( slaveScope ),this.slaveScope );
1126            }
1127    
1128            /**
1129             * 【TAG】スレーブからã?スタへ追åŠ?�™るカラãƒ?��をCSV形式でæŒ?®šしますã?
1130             *
1131             * @og.tag
1132             * アクションがå?合æ?(UNION_CLM)またã?列追åŠ?ADD_CLM)の場合に使用されますã?
1133             * 列合æˆ?UNION_CLM)は、ã?スタとスレーブã?主キーに対して、ここでæŒ?®šã?スレーブã?
1134             * カラãƒ??名を、ã?スタの列に追åŠ?�—ますã?主キーがã?ãƒ?ƒ�しなã�?¡Œに関してはã€?
1135             * カラãƒ??初期値が適用されたデータを作æ?しますã?
1136             * 列追åŠ?ADD_CLM)は、ã?スタãƒ??ブルにæŒ?®šã?カラãƒ?‚’追åŠ?�™るだけですã?スレーブテーブルは
1137             * 参ç?しません。よって、主キーも指定不要ですã?
1138             *
1139             * @param       unionClms       列合成するカラãƒ?��をCSV形式でæŒ?®?
1140             */
1141            public void setUnionClms( final String unionClms ) {
1142                    this.unionClms = nval( getRequestParameter( unionClms ),this.unionClms );
1143            }
1144    
1145            /**
1146             * 【TAG】スレーブからã?スタへ値を更新するカラãƒ?��をCSV形式でæŒ?®šしますã?
1147             *
1148             * @og.tag
1149             * アクションが差åˆ??ç�?DIFFERENCE)の場合に、結果にマスタãƒ??ブルが抜きå?されますがã€?
1150             * 更新する場合に、スレーブ特有ã?ユニã?クキー(例:UNIQ)を用ã�?�¦更新する場合ã?
1151             * æŒ?®šã?カラãƒ??は、スレーブã?値にセãƒ?ƒˆしておきたい場合がありますã?
1152             * ここでは、指定ã?カラãƒ?�«つã�?�¦、å?ã�?�‘スレーブからã?スタへセãƒ?ƒˆしますã?
1153             * なおã?値の更新につã�?�¦は、ã?スタとスレーブが同ä¸?‚­ーとã�?�†制ç´?�Œありますã?
1154             *
1155             * @param       modifyClms      値を更新するカラãƒ?��をCSV形式でæŒ?®?
1156             */
1157            public void setModifyClms( final String modifyClms ) {
1158                    this.modifyClms = nval( getRequestParameter( modifyClms ),this.modifyClms );
1159            }
1160    
1161            /**
1162             * 【TAG】集合å?ç�?�™るときに、相違データをCSV連結して残すカラãƒ?��をCSV形式でæŒ?®šしますã?
1163             *
1164             * @og.tag
1165             * masterKeysでé›?�ˆ処ç�?�™るときにã€??常、最初に見つかった行データのみ残りますがã€?
1166             * ここにæŒ?®šしたカラãƒ?�«つã�?�¦は、発生é?度、è?åˆ??身のæƒ??に、CSV形式で連結して
1167             * ã�?��ますã?
1168             * こã?操作により、本来削除された情報がã??‘行ã?CSV形式で取得できる効果が得られますã?
1169             * これは、value タグの action="APPEND" をã?DBTableModel に対して実施するような感じですã?
1170             *
1171             * @og.rev 5.1.4.0 (2010/03/01) 新規追åŠ?
1172             *
1173             * @param       groupAddClms    相違データをCSV連結して残すカラãƒ?��をCSV形式でæŒ?®?
1174             */
1175            public void setGroupAddClms( final String groupAddClms ) {
1176                    this.groupAddClms = nval( getRequestParameter( groupAddClms ),this.groupAddClms );
1177            }
1178    
1179            /**
1180             * 【TAG】テーブルモãƒ?ƒ«に対する副作用の有無[true:なã�?false:ある]を指定しまã�?初期値:false:ある)ã€?
1181             *
1182             * @og.tag
1183             * すべての処ç�?�§、DBTableModel に対して、ユニã?ク化やグループ化などのé›?�ˆ処ç�?‚’
1184             * 行う過程で、ã?スタãƒ??ブルに対して直接処ç�?‚’行うと、副作用が発生しますã?
1185             * 同様に、スレーブテーブルにおいてもã?ä¸?—¦キー列でグループ化されるためã?副作用ã�?
1186             * 発生しますã?これは、無é§?�ªメモリ領域の確保と、テーブル(マスタ、スレーブとã‚?の
1187             * コピã?処ç�?™‚間ã?ç¯?´?�«なりますã?初期値の設定も副作用がある状態になってã�?�¾すã?
1188             * ところがã?都合によっては、色ã€?�ª action をé?続して行いたい場合など、毎回ã€?
1189             * ãƒ??タベã?スを検索するよりもメモリ上でコピã?したほã�?�Œ都合がよいケースではã€?
1190             * 副作用がå?なã�?‚ˆã�?�«、noSideEffect="true" に設定しますã?
1191             * ただしã?マスタ、スレーブともテーブルをコピã?を行い、結果のãƒ??ブルも派生する為ã€?
1192             * 通常ã€?¼’つの領域(マスタと結果は同じãƒ??ブルに書かれã‚?で良ã�?‰€をã??•つの領域ã�?
1193             * 作æ?されますã?
1194             * 初期値は、副作用があã‚?noSideEffect="false")ですã?
1195             *
1196             * @param       noSideEffect    ãƒ??ブルモãƒ?ƒ«に対する副作用 [true:なã�?false:ある]
1197             */
1198            public void setNoSideEffect( final String noSideEffect ) {
1199                    this.noSideEffect = nval( getRequestParameter( noSideEffect ),this.noSideEffect );
1200            }
1201    
1202            /**
1203             * 【TAG】差åˆ??スレーブデータを結果ãƒ??ブルに追åŠ?�™るかどã�?�‹を指定しまã�?初期値:true)ã€?
1204             *
1205             * @og.tag
1206             * アクションが差åˆ??ç�?DIFFERENCE)の場合に、結果にマスタãƒ??ブルが抜きå?されますがã€?
1207             * 差åˆ?¯¾象のスレーブデータと比è¼?�—たい場合がありますã?
1208             * こã?フラグã‚?true にセãƒ?ƒˆすると、書込み禁止属æ?が付いた状態で、スレーブデータã�?
1209             * 結果ãƒ??ブルに追åŠ?�•れますã?
1210             * なおã?こã?処ç�?�§はã€??常と異なりã?マスタãƒ??ブルにはグループ化の副作用は発生しますがã€?
1211             * 結果ãƒ??ブルは新規に作æ?され、å?頭行にå¿?�š WRITABLE カラãƒ?�Œ付加されますã?
1212             * 初期値は、true?š追åŠ?�™ã‚?ですã?
1213             *
1214             * @param       flag    スレーブデータを結果ãƒ??ブルに追åŠ?�™るかどã�?�‹(初期値:true)
1215             */
1216            public void setUseDiffData( final String flag ) {
1217                    useDiffData = nval( getRequestParameter( flag ),useDiffData );
1218            }
1219    
1220            /**
1221             * 【TAG】ã?スタãƒ??ブルの選択行ã?ãƒ??タのみを対象に処ç�?‚’行うかどã�?�‹を指定しまã�?初期値:false)ã€?
1222             *
1223             * @og.tag
1224             * 処ç�?¯¾象のマスタãƒ??ブルにつã�?�¦ã€?�¸択行がæŒ?®šされた場合にã€?�¸択行ã?みをå?ç�?¯¾象に
1225             * するかã?全件を対象にするかをæŒ?®šしますã?
1226             * 積集合や差åˆ?›†合など通常は、å?件を対象にすることになりますが、å?合æ?ã‚??追åŠ?�ªどã€?
1227             * マスタãƒ??ブルに対してのみ作用を及ぼすå?ç�?�§はã€?�¸択行ã?みを対象に処ç�?‚’行う事が
1228             * è€?�ˆられますã?そã?場合ã?初期グループ化と同じで、対象とする行が選択行ã?みになりますã?
1229             * 初期値は、false?šå?件対象 ですã?
1230             *
1231             * @param       flag    マスタãƒ??ブルの選択行ã?ãƒ??タのみを対象に処ç�?‚’行うかどã�?�‹(初期値:false)
1232             */
1233            public void setUseCheckOnly( final String flag ) {
1234                    useCheckOnly = nval( getRequestParameter( flag ),useCheckOnly );
1235            }
1236    
1237            /**
1238             * 【TAG】ã?ージの結果を表示するかどã�?�‹を指定しまã�?初期値:true)ã€?
1239             *
1240             * @og.tag
1241             * true で、ã?ージ結果を表示しますã? false では、何も表示しません(初期値:true)
1242             * マスタãƒ??ブルの件数はã€??常、キーでグループ化されるためã?入力件数と異なりますã?
1243             * 同様に、スレーブ件数も異なりますã?結果の件数は、å?ç�?µ�果が現実的かどã�?�‹の
1244             * 判断に使用されますã?
1245             * 初期値は、true?š表示する ですã?
1246             *
1247             * @param       flag    接続ã?結果を表示するかどã�?�‹(初期値:false)
1248             */
1249            public void setDisplay( final String flag ) {
1250                    display = nval( getRequestParameter( flag ),display );
1251            }
1252    
1253            /**
1254             * 【TAGã€?通常使ã�?�¾せん)タグで処ç�?�•れる処ç�?�Œメインとなるトランザクション処ç�?�‹どã�?�‹を指定しまã�?初期値:false)ã€?
1255             *
1256             * @og.tag
1257             * こã?値は、ファイルãƒ?‚¦ンロードå?ç�?�«影響しますã?こã?値がtrueにæŒ?®šされた時にcommitされたDBTableModelã�?
1258             * ファイルãƒ?‚¦ンロードã?対象の表になりますã?
1259             *
1260             * こã?パラメーターはã€??常、各タグにより実è£?�•れã?ユーザーが指定するå¿?¦�ã?ありませんã€?
1261             * ä½?�—ã€?つのJSPå†?�§DBTableModelがè¤?•°生æ?されるå?合に、前に処ç�?�—たDBTableModelにつã�?�¦ファイルãƒ?‚¦ンロードをさせたい
1262             * 場合ã?、後ろでDBTableModelを生成するタグで、æ?示çš?�«こã?値をfalseにæŒ?®šすることで、ファイルãƒ?‚¦ンロードå?ç�??対象から
1263             * 除外することができますã?
1264             *
1265             * @og.rev 5.1.6.0 (2010/05/01) 新規作æ?
1266             *
1267             * @param  flag メイントランザクションかどã�?�‹
1268             */
1269            public void setMainTrans( final String flag ) {
1270                    isMainTrans = nval( getRequestParameter( flag ),isMainTrans );
1271            }
1272    
1273            /**
1274             * 【TAG】groupAddClmsでæ–?­—å?をé?結するé?目区åˆ?‚Šæ–?­—をセãƒ?ƒˆしまã�?初期値:",")ã€?
1275             *
1276             * @og.tag
1277             * groupAddClmsでæ–?­—å?をé?結するé?目区åˆ?‚Šæ–?­—をセãƒ?ƒˆしまã�?初期値:",")ã€?
1278             * 初期値はã€?," に設定されてã�?�¾すã?
1279             *
1280             * @og.rev 5.3.1.0 (2011/01/01)
1281             *
1282             * @param   sepa        é ?›®区åˆ?‚Šæ–?­?初期値:",")
1283             */
1284            public void setSeparator( final String sepa ) {
1285                    separator = nval( getRequestParameter( sepa ),separator );
1286            }
1287    
1288            /**
1289             * こã?オブジェクトã?æ–?­—å?表現を返しますã?
1290             * 基本çš?�«ãƒ?ƒ�ãƒ?‚°目çš?�«使用しますã?
1291             *
1292             * @return こã?クラスのæ–?­—å?表現
1293             */
1294            @Override
1295            public String toString() {
1296                    return org.opengion.fukurou.util.ToString.title( this.getClass().getName() )
1297                                    .println( "VERSION"                     ,VERSION                )
1298                                    .println( "action"                      ,action                 )
1299                                    .println( "tableId"                     ,tableId                )
1300                                    .println( "scope"                       ,scope                  )
1301                                    .println( "masterTableId"       ,masterTableId  )
1302                                    .println( "masterScope"         ,masterScope    )
1303                                    .println( "slaveTableId"        ,slaveTableId   )
1304                                    .println( "slaveScope"          ,slaveScope             )
1305                                    .println( "masterKeys"          ,masterKeys             )
1306                                    .println( "diffKeys"            ,diffKeys               )
1307                                    .println( "unionClms"           ,unionClms              )
1308                                    .println( "modifyClms"          ,modifyClms             )
1309                                    .println( "noSideEffect"        ,noSideEffect   )
1310                                    .println( "useDiffData"         ,useDiffData    )
1311                                    .println( "useCheckOnly"        ,useCheckOnly   )
1312                                    .println( "display"                     ,display                )
1313                                    .println( "ACTION_LIST"         ,ACTION_LIST    )
1314                                    .println( "Other..."    ,getAttributes().getAttribute() )
1315                                    .fixForm().toString() ;
1316            }
1317    }