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