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.plugin.column;
017
018import org.opengion.hayabusa.common.HybsSystem;
019import org.opengion.hayabusa.common.HybsSystemException;
020import org.opengion.hayabusa.db.AbstractEditor;
021import org.opengion.hayabusa.db.CellEditor;
022import org.opengion.hayabusa.db.DBColumn;
023import org.opengion.hayabusa.db.Selection;
024import org.opengion.hayabusa.db.SelectionFactory;
025import org.opengion.fukurou.util.StringFormat;
026import org.opengion.fukurou.util.XHTMLTag;
027import org.opengion.fukurou.util.Attributes;
028import org.opengion.fukurou.util.TagBuffer;
029
030/**
031 * INDBMENU エディターは、カラムの表示パラメーターのSQL文を実行結果より、
032 * 作成したプルダウンメニューと、テキストフィールドによる入力の両方をサポートする、
033 * 編集に使用するクラスです。
034 *
035 * JavaScript によりテキストフィールドとメニュー(コンボボックス)を重ね合わせて
036 * 表示しておき、メニューで選択した値を、テキストフィールドに設定しています。
037 * このエディタを使用するには、jsp/common/inputMenu.js を予め使用できるように
038 * 設定しておく必要があります。
039 *
040 * このエディタはeventColumnに対応していません。
041 *
042 *  カラムの表示に必要な属性は, DBColumn オブジェクト より取り出します。
043 * このクラスは、DBColumn オブジェクト毎に1つ作成されます。
044 *
045 * @og.rev 3.5.6.2 (2004/07/05) 新規作成
046 * @og.group データ編集
047 *
048 * @version  4.0
049 * @author       Kazuhiko Hasegawa
050 * @since    JDK5.0,
051 */
052public class Editor_INDBMENU extends AbstractEditor {
053        //* このプログラムのVERSION文字列を設定します。   {@value} */
054        private static final String VERSION = "5.6.3.0 (2013/04/01)" ;
055
056        private static final String SEL1 = "<script type=\"text/javascript\">makeInputMenu('" ;
057        private static final String SEL2 = "');</script>" ;
058
059        private final String query ;
060        private final String dbid ;
061        private final String lang ;                             // 4.0.0 (2006/11/15)
062        private final boolean addNoValue ;              // 3.5.5.7 (2004/05/10)
063        private final boolean seqFlag ;                 // 3.6.0.6 (2004/10/22)
064        private final TagBuffer selTagBuffer = new TagBuffer() ;
065
066        /**
067         * デフォルトコンストラクター。
068         * このコンストラクターで、基本オブジェクトを作成します。
069         *
070         * @og.rev 3.6.0.6 (2004/10/22) シーケンスアクセス機能(seqFlag)を追加します
071         */
072        public Editor_INDBMENU() {
073                // 4.3.4.4 (2009/01/01)
074//              super();
075                query   = null;
076                dbid    = null;
077                lang    = null;                 // 4.0.0 (2006/11/15)
078                addNoValue = false;             // 3.5.5.7 (2004/05/10)
079                seqFlag    = false;             // 3.6.0.6 (2004/10/22)
080                name    = null;                 // 4.3.4.0 (2008/12/01)
081        }
082
083        /**
084         * コンストラクター。
085         *
086         * @og.rev 3.6.0.6 (2004/10/22) シーケンスアクセス機能(seqFlag)を追加します
087         * @og.rev 4.0.0.0 (2006/11/24) TextField分の属性設定
088         * @og.rev 5.6.3.0 (2013/04/01) プルダウンのonChangeの設定場所を変更
089         *
090         * @param       clm     DBColumnオブジェクト
091         */
092        private Editor_INDBMENU( final DBColumn clm ) {
093                super( clm );
094                tagBuffer.add( XHTMLTag.inputAttri( attributes ) );
095
096                addNoValue      = clm.isAddNoValue() ;          // 3.5.5.7 (2004/05/10)
097                query           = clm.getEditorParam();
098                dbid            = clm.getDbid();
099                lang            = clm.getLang();                        // 4.0.0 (2006/11/15)
100                seqFlag         = false;                // 3.6.0.6 (2004/10/22)
101                name            = clm.getName(); //4.3.4.0 (2008/12/01)
102
103                if( query == null || query.length() == 0 ) {
104                        String errMsg = "DBMENU Editor では、編集パラメータは必須です。"
105                                        + " name=[" + name + "]" + HybsSystem.CR ;
106                        throw new HybsSystemException( errMsg );
107                }
108
109                String  disabled = clm.isWritable() ? null : "disabled" ;
110
111                Attributes selAttri = new Attributes();
112                selAttri.set( "disabled"        ,disabled );
113//              selAttri.set( "onChange" ,"selChanged(this);" );        // INDBMENU 特有のJavaScript
114
115                selAttri.addAttributes( clm.getEditorAttributes() );
116                
117                selAttri.set( "onChange" ,"selChanged(this);" );        // INDBMENU 特有のJavaScript 5.6.3.0 (2013/03/01) 場所変更
118                
119                selTagBuffer.add( XHTMLTag.selectAttri( selAttri ) );
120        }
121
122        /**
123         * 各オブジェクトから自分のインスタンスを返します。
124         * 自分自身をキャッシュするのか、新たに作成するのかは、各サブクラスの実装に
125         * まかされます。
126         *
127         * @param       clm     DBColumnオブジェクト
128         *
129         * @return      CellEditorオブジェクト
130         */
131        public CellEditor newInstance( final DBColumn clm ) {
132                return new Editor_INDBMENU( clm );
133        }
134
135        /**
136         * データの編集用文字列を返します。
137         *
138         * ここでは、AAA:BBB:CCC:DDD という値を、$1,$2,$3,$4 に割り当てなおして、
139         * QUERYを実行します。また、$1 は、本来の値として、メニューの初期値設定等に
140         * 使用します。上記の例では、AAA が値で、それ以降は、引数になります。
141         * さらに、元の文字列"AAA:BBB:CCC:DDD"は、$0 に割り当てられます。割り当てがない
142         * 変数は、""(ゼロ文字列)として、扱われます。
143         *
144         * @og.rev 3.8.5.3 (2006/06/30) 位置を絶対位置指定(position:absolute;)
145         * @og.rev 4.3.7.2 (2009/06/15) 属性でidが出力される場合は、idを出力しない
146         *
147         * @param       value 入力値
148         *
149         * @return      データの編集用文字列
150         */
151        @Override
152        public String getValue( final String value ) {
153
154                // input タグの作成
155                TagBuffer intag = new TagBuffer( "input" );
156                intag.add( "name"    , name );
157                if( attributes.get( "id" ) == null || attributes.get( "id" ).length() == 0 ) { // 4.3.7.2 (2009/06/15)
158                        intag.add( "id"      , name );          // INDBMENU 特有のJavaScript用のキー
159                }
160                intag.add( "value"   , value );
161                intag.add( "size"    , size1 );
162                intag.add( tagBuffer.makeTag() );
163                intag.add( optAttr );
164
165                // select タグの作成
166                TagBuffer seltag = new TagBuffer( "select" );
167                seltag.add( "id"      , name + ".sel" );        // INDBMENU 特有のJavaScript用のキー
168                seltag.add( "style"   , "position:absolute;" ); // 3.8.5.3 (2006/06/30) 位置を絶対位置指定
169                seltag.add( selTagBuffer.makeTag() );
170                seltag.add( optAttr );
171
172                seltag = getOption( seltag,value );
173
174                return intag.makeTag() + HybsSystem.CR +
175                                seltag.makeTag() + HybsSystem.CR +
176                                SEL1 + name + SEL2;
177        }
178
179        /**
180         * name属性を変えた、データ表示/編集用のHTML文字列を作成します。
181         * テーブル上の name に 行番号を付加して、名前_行番号 で登録するキーを作成し,
182         * リクエスト情報を1つ毎のフィールドで処理できます。
183         *
184         * ここでは、AAA:BBB:CCC:DDD という値を、$1,$2,$3,$4 に割り当てなおして、
185         * QUERYを実行します。また、$1 は、本来の値として、メニューの初期値設定等に
186         * 使用します。上記の例では、AAA が値で、それ以降は、引数になります。
187         * さらに、元の文字列"AAA:BBB:CCC:DDD"は、$0 に割り当てられます。割り当てがない
188         * 変数は、""(ゼロ文字列)として、扱われます。
189         *
190         * @og.rev 3.8.5.1 (2006/04/28) makeInputMenu 呼び出し時の引数記述ミスを修正
191         * @og.rev 3.8.5.3 (2006/06/30) 位置を絶対位置指定(position:absolute;)
192         * @og.rev 4.3.7.2 (2009/06/15) 属性でidが出力される場合は、idを出力しない
193         *
194         * @param       row   行番号
195         * @param       value 入力値
196         *
197         * @return      データ表示/編集用の文字列
198         */
199        @Override
200        public String getValue( final int row,final String value ) {
201
202                String name2 = name + HybsSystem.JOINT_STRING + row ;
203
204                // input タグの作成
205                TagBuffer intag = new TagBuffer( "input" );
206                intag.add( "name"    , name2 );
207                if( attributes.get( "id" ) == null || attributes.get( "id" ).length() == 0 ) { // 4.3.7.2 (2009/06/15)
208                        intag.add( "id"      , name2 );         // INDBMENU 特有のJavaScript用のキー
209                }
210                intag.add( "value"   , value );
211                intag.add( "size"    , size2 );
212                intag.add( tagBuffer.makeTag() );
213                intag.add( optAttr );
214
215                // select タグの作成
216                TagBuffer seltag = new TagBuffer( "select" );
217                seltag.add( "id"      , name2 + ".sel" );               // INDBMENU 特有のJavaScript用のキー
218                seltag.add( "style"   , "position:absolute;" ); // 3.8.5.3 (2006/06/30) 位置を絶対位置指定
219                seltag.add( selTagBuffer.makeTag() );
220                seltag.add( optAttr );
221
222                seltag = getOption( seltag,value );
223
224                return intag.makeTag( row,value ) + HybsSystem.CR +
225                                seltag.makeTag( row,value ) + HybsSystem.CR +
226                                SEL1 + name2 + SEL2;
227        }
228
229        /**
230         * 初期値が選択済みの 選択肢(オプション)をTagBuffer に反映します。
231         * このオプションは、引数の値を初期値とするオプションタグ作成し、TagBuffer
232         * に値を設定して返します。
233         *
234         * ここでは、AAA:BBB:CCC:DDD という値を、$1,$2,$3,$4 に割り当てなおして、
235         * QUERYを実行します。また、$1 は、本来の値として、メニューの初期値設定等に
236         * 使用します。上記の例では、AAA が値で、それ以降は、引数になります。
237         * さらに、元の文字列"AAA:BBB:CCC:DDD"は、$0 に割り当てられます。割り当てがない
238         * 変数は、""(ゼロ文字列)として、扱われます。
239         * 又、$Cには自分自身のカラム名を割り当てます。
240         *
241         * @og.rev 3.5.5.7 (2004/05/10) getOption( String value )の廃止を受けて、新規作成
242         * @og.rev 3.6.0.6 (2004/10/22) シーケンスアクセス機能(seqFlag)を追加します
243         * @og.rev 4.0.0.0 (2006/11/15) SelectionFactory に lang 属性を追加します。
244         * @og.rev 4.3.4.0 (2008/12/01) $C対応
245         *
246         * @param       buf  反映させるTagBufferオブジェクト
247         * @param       value 選択されている値
248         *
249         * @return      オプションタグ
250         */
251        private TagBuffer getOption( final TagBuffer buf,final String value ) {
252
253                // StringFormat format = new StringFormat( query,value );
254                StringFormat format = new StringFormat( query, value, name ); // 4.3.4.0 (2008/12/01)
255                String newQuery = format.format();
256                String newValue = format.getValue();
257
258                Selection selection = SelectionFactory.newDBSelection( newQuery, dbid, lang );
259
260                if( addNoValue ) {
261                        buf.setBody( Selection.NO_VALUE_OPTION + selection.getOption( newValue, seqFlag ) );
262                }
263                else {
264                        buf.setBody( selection.getOption( newValue, seqFlag ) );
265                }
266
267                return buf;
268        }
269}