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
018// import java.util.StringTokenizer;
019
020import org.opengion.fukurou.util.StringUtil;
021import org.opengion.fukurou.util.TagBuffer;
022import org.opengion.hayabusa.common.HybsSystem;
023import org.opengion.hayabusa.db.AbstractRenderer;
024import org.opengion.hayabusa.db.CellRenderer;
025import org.opengion.hayabusa.db.DBColumn;
026
027/**
028 * AUTOAREA レンデラは、カラムのデータをテキストエリアで表示する場合に
029 * 使用するクラスです。
030 * readonlyのテキストエリアでclass=renderer-textareaとして出力し、
031 * name属性は付けません。(データは送信されません)
032 * エリアの縦、横サイズはエディタの自動拡張テキストエリア(AUTOAREA)と同様にして算出されます。
033 *
034 * カラムの表示に必要な属性は、DBColumn オブジェクト より取り出します。
035 * このクラスは、DBColumn オブジェクト毎に1つ作成されます。
036 *
037 * @og.rev 5.3.4.0 (2011/04/01) 新規作成
038 * @og.group データ編集
039 *
040 * @version  4.0
041 * @author   Hiroki Nakamura
042 * @since    JDK5.0,
043 */
044public class Renderer_AUTOAREA extends AbstractRenderer {
045        /** このプログラムのVERSION文字列を設定します。   {@value} */
046        private static final String VERSION = "8.5.6.1 (2024/03/29)" ;
047
048        private static final int COL = 0 ;
049        private static final int ROW = 1 ;
050
051        private final int COLUMNS_MAXSIZE = HybsSystem.sysInt( "HTML_COLUMNS_MAXSIZE" );
052        /** viewタグで表示する場合のカラムの大きさ */
053        private final int VIEW_COLUMNS_MAXSIZE = HybsSystem.sysInt( "HTML_VIEW_COLUMNS_MAXSIZE" );
054
055//      private static final String CODE = "Windows-31J";
056
057        // 8.5.6.1 (2024/03/29) cols,rows を String に変更します。
058//      private int     cols1   ;
059//      private int     cols2   ;
060//      private int     rows1   ;
061//      private int     rows2   ;
062        /** 検索時の列数1 */ private  String cols1;
063        /** 検索時の行数1 */ private  String rows1;
064        /** 登録時の列数2 */ private  String cols2;
065        /** 登録時の行数2 */ private  String rows2;
066        private int maxColSize = HybsSystem.sysInt( "HTML_AUTOAREA_MAX_COL_SIZE" );
067        private int maxRowSize = HybsSystem.sysInt( "HTML_AUTOAREA_MAX_ROW_SIZE" );
068
069        private final TagBuffer tagBuffer = new TagBuffer();
070
071        /**
072         * デフォルトコンストラクター。
073         * このコンストラクターで、基本オブジェクトを作成します。
074         *
075         * @og.rev 6.4.1.1 (2016/01/16) PMD refactoring. It is a good practice to call super() in a constructor
076         */
077        public Renderer_AUTOAREA() { super(); }         // これも、自動的に呼ばれるが、空のメソッドを作成すると警告されるので、明示的にしておきます。
078
079        /**
080         * DBColumnオブジェクトを指定したprivateコンストラクター。
081         *
082         * textareaのサイズを決めるため、sizeとrowを決定する
083         * editorの計算を移植。
084         *
085         * @og.rev 6.2.0.0 (2015/02/27) フィールドサイズ 追加(VIEW_LENGTHと分離して、役割を明確にする)
086         * @og.rev 8.5.5.1 (2024/02/29) spotbugs CT_CONSTRUCTOR_THROW(コンストラクタで、Excweptionを出さない)
087         * @og.rev 8.5.6.1 (2024/03/29) cols,rows を String に変更します。
088         *
089         * @param       clm     DBColumnオブジェクト
090         */
091        private Renderer_AUTOAREA( final DBColumn clm ) {
092                super();                // 6.4.1.1 (2016/01/16) PMD refactoring. It is a good practice to call super() in a constructor
093
094                // 6.2.0.0 (2015/02/27) フィールドサイズ 追加(VIEW_LENGTHと分離して、役割を明確にする)
095                final int size1 = clm.getFieldSize( COLUMNS_MAXSIZE      );
096                final int size2 = clm.getFieldSize( VIEW_COLUMNS_MAXSIZE );
097
098                final int r1 = clm.getTotalSize()/size1 + 1;                                    // 6.2.0.0 (2015/02/27)
099//              if( r1 > 5 ) { rows1 = 5; }
100//              else { rows1 = r1; }
101                if( r1 > 5 ) { rows1 = "5"; }
102                else { rows1 = String.valueOf( r1 ); }
103
104                final int r2 = clm.getTotalSize()/size2 + 1;                                    // 6.2.0.0 (2015/02/27)
105//              if( r2 > 5 ) { rows2 = 5; }
106//              else { rows2 = r2; }
107                if( r2 > 5 ) { rows2 = "5"; }
108                else { rows2 = String.valueOf( r2 ); }
109
110                // 3.8.0.2 (2005/07/11) size に、"rows-maxRow,cols-maxCols" を指定
111                final String param = StringUtil.nval( clm.getRendererParam(),clm.getViewLength() );
112                if( param != null && param.length() != 0 ) {
113                        final int prmAdrs = param.indexOf( ',' );
114                        if( prmAdrs > 0 ) {
115                                final String rowStr = param.substring( 0,prmAdrs );
116                                final String colStr = param.substring( prmAdrs+1 );
117
118                                // 8.5.5.1 (2024/02/29) spotbugs CT_CONSTRUCTOR_THROW(コンストラクタで、Excweptionを出さない)
119                                final int rowAdrs = rowStr.indexOf( '-' );      // rows-maxRow 設定時 '-' がなければ、ただのrows
120                                if( rowAdrs > 0 ) {
121//                                      rows1 = Integer.parseInt( rowStr.substring( 0,rowAdrs ) );
122//                                      maxRowSize = Integer.parseInt( rowStr.substring( rowAdrs+1 ) );
123                                        rows1 = StringUtil.nval( rowStr.substring( 0,rowAdrs ),rows1 );
124                                        maxRowSize = StringUtil.nval( rowStr.substring( rowAdrs+1 ),maxRowSize );
125                                }
126                                else {
127//                                      rows1 = Integer.parseInt( rowStr );
128                                        rows1 = StringUtil.nval( rowStr,rows1 );
129                                }
130                                rows2 = rows1 ;
131
132                                final int colAdrs = colStr.indexOf( '-' );      // cols-maxCols 設定時 '-' がなければ、ただのcols
133                                if( colAdrs > 0 ) {
134//                                      cols1 = Integer.parseInt( colStr.substring( 0,colAdrs ) );
135//                                      maxColSize = Integer.parseInt( colStr.substring( colAdrs+1 ) );
136//                                      cols1 = StringUtil.nval( colStr.substring( 0,colAdrs ),size1 );
137                                        cols1 = StringUtil.nval( colStr.substring( 0,colAdrs ),String.valueOf( size1 ) );
138                                        maxColSize = StringUtil.nval( colStr.substring( colAdrs+1 ),maxColSize );
139                                }
140                                else {
141//                                      cols1 = Integer.parseInt( colStr );
142//                                      cols1 = StringUtil.nval( colStr,size1 );
143                                        cols1 = StringUtil.nval( colStr,String.valueOf( size1 ) );
144                                }
145                                cols2 = cols1;
146                        }
147                }
148        }
149
150        /**
151         * 各オブジェクトから自分のインスタンスを返します。
152         * 自分自身をキャッシュするのか、新たに作成するのかは、各サブクラスの実装に
153         * まかされます。
154         *
155         * @param       clm     DBColumnオブジェクト
156         *
157         * @return      CellRendererオブジェクト
158         * @og.rtnNotNull
159         */
160        public CellRenderer newInstance( final DBColumn clm ) {
161                return new Renderer_AUTOAREA( clm );
162        }
163
164        /**
165         * データの表示用文字列を返します。
166         *
167         * @og.rev 6.0.4.0 (2014/11/28) ロジックの共通化
168         *
169         * @param   value 入力値
170         *
171         * @return  データの表示用文字列
172         * @og.rtnNotNull
173         */
174        @Override
175        public String getValue( final String value ) {
176                return getRowsColsValue( value==null ? "" : value, cols1, rows1 );
177        }
178
179        /**
180         * データの表示用文字列を返します。
181         *
182         * @og.rev 6.0.4.0 (2014/11/28) ロジックの共通化
183         *
184         * @param   row   行番号
185         * @param   value 入力値
186         *
187         * @return  データ表示用の文字列
188         * @og.rtnNotNull
189         */
190        @Override
191        public String getValue( final int row,final String value ) {
192                return getRowsColsValue( value==null ? "" : value, cols2, rows2 );
193        }
194
195        /**
196         * データ出力用の文字列を作成します。
197         * ファイル等に出力する形式を想定しますので、HTMLタグを含まない
198         * データを返します。
199         * 基本は、#getValue( String ) をそのまま返します。
200         *
201         * @og.rev 6.0.4.0 (2014/11/28) データ出力用のレンデラー
202         *
203         * @param   value 入力値
204         *
205         * @return  データ出力用の文字列
206         * @og.rtnNotNull
207         * @see         #getValue( String )
208         */
209        @Override
210        public String getWriteValue( final String value ) {
211                return value==null ? "" : value;
212        }
213
214        /**
215         * 自動表示する行列の数を求めて、値を返します。
216         * 行数は、引数の文字列中に含まれる 改行コードの個数を求めます。
217         * 列数は、各行数のなかの最大桁数より求めます。これには半角、全角が含まれる為、
218         * 半角換算での文字数ということになります。
219         * 行数と列数が、初期設定の行数と列数より小さい場合は、初期設定値が使用されます。
220         *
221         * @og.rev 6.0.4.0 (2014/11/28) ロジックの共通化
222         * @og.rev 8.5.6.1 (2024/03/29) cols,rows を String に変更します。
223         *
224         * @param   value 入力値 表示文字列
225         * @param       cols    最小カラム数
226         * @param       rows    最小行数
227         *
228         * @return  データ表示用の文字列
229         * @og.rtnNotNull
230         */
231//      private String getRowsColsValue( final String value,final int cols, final int rows ) {
232        private String getRowsColsValue( final String value,final String cols, final String rows ) {
233                // 6.0.4.0 (2014/11/28) null は引数に来ない。
234
235//              final StringTokenizer token = new StringTokenizer( value, "\n", true );
236//
237//              int cntRow = 1;
238//              int maxCol = 0;
239//              while( token.hasMoreTokens() ) {
240//                      final String val = token.nextToken();
241//                      if( "\n".equals( val ) ) { cntRow++; }
242//                      else {
243//                              final byte[] byteValue = StringUtil.makeByte( val,CODE );       // 3.5.5.3 (2004/04/09)
244//                              final int byteSize = byteValue.length;
245//                              if( maxColSize > 0 && byteSize > maxColSize ) {         // 最大列数
246//                                      cntRow += byteSize / maxColSize;
247//                                      maxCol = maxColSize ;
248//                              }
249//                              else if( byteSize > maxCol ) { maxCol = byteSize; }
250//                      }
251//                      if( maxRowSize > 0 && cntRow >= maxRowSize ) {          // 最大行数
252//                              cntRow = maxRowSize;
253//                              break;
254//                      }
255//              }
256//
257//              maxCol += 2;    // マージン。フォントや画面サイズに影響する為、比率のほうがよい?
258
259                final String[] rowcol = ColumnUtil.getRowsCols( value,cols,rows,maxColSize,maxRowSize );
260
261                // 6.0.4.0 (2014/11/28) 配列にいれずに、直接設定する。
262                // 6.0.4.0 (2014/11/28) タグを作成する処理も、ここで行います。
263                // 6.1.1.0 (2015/01/17) TagBufferの連結記述
264                return new TagBuffer( "textarea" )
265//                                      .add( "cols"    , String.valueOf( Math.max( cols,maxCol ) ) )           // 6.1.1.0 (2015/01/17) ソースの見やすさ優先
266//                                      .add( "rows"    , String.valueOf( Math.max( rows,cntRow ) ) )
267                                        .add( "cols"    , rowcol[COL] )
268                                        .add( "rows"    , rowcol[ROW] )
269                                        .add( "readonly", "readonly" )
270                                        .add( "class"   , "renderer-textarea" )
271                                        .add( tagBuffer.makeTag() )
272                                        .addBody( value )
273                                        .makeTag();
274        }
275}