    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 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 オブジェクト毎に１つ作成されます。
    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 = "5.3.4.0 (2011/04/01)" ;
    047
    048        private final int COLUMNS_MAXSIZE = HybsSystem.sysInt( "HTML_COLUMNS_MAXSIZE" );
    049        // viewタグで表示する場合のカラムの大きさ
    050        private final int VIEW_COLUMNS_MAXSIZE = HybsSystem.sysInt( "HTML_VIEW_COLUMNS_MAXSIZE" );
    051
    052        private  String         size1;
    053        private  String         size2;
    054
    055        private static final int COL = 0 ;
    056        private static final int ROW = 1 ;
    057        private static final String CODE = "Windows-31J";
    058
    059        private int     cols1   = 0 ;
    060        private int     cols2   = 0 ;
    061        private int     rows1   = 0 ;
    062        private int     rows2   = 0 ;
    063        private int maxColSize = HybsSystem.sysInt( "HTML_AUTOAREA_MAX_COL_SIZE" );
    064        private int maxRowSize = HybsSystem.sysInt( "HTML_AUTOAREA_MAX_ROW_SIZE" );
    065
    066        private final TagBuffer tagBuffer = new TagBuffer();
    067
    068        /**
    069         * デフォルトコンストラクター。
    070         * このコンストラクターで、基本オブジェクトを作成します。
    071         *
    072         */
    073        public Renderer_AUTOAREA() {
    074                // 何もありません。(super を呼び出しません)
    075        }
    076
    077        /**
    078         * コンストラクター
    079         * textareaのサイズを決めるため、sizeとrowを決定する
    080         * editorの計算を移植。
    081         *
    082         * @param       clm     DBColumnオブジェクト
    083         */
    084        private Renderer_AUTOAREA( final DBColumn clm ) {
    085                String size = clm.getViewLength();
    086                int maxlength = clm.getTotalSize();
    087
    088                if( size != null ) {
    089                        if( size.indexOf( ',' ) >= 0 ) {
    090                                size = size.substring( 0, size.indexOf( ',' ) );
    091                        }
    092                        size1 = size;
    093                        size2 = size;
    094                }
    095                else {
    096                        size1 = String.valueOf( clm.getFieldSize( maxlength, COLUMNS_MAXSIZE ) );
    097                        size2 = String.valueOf( clm.getFieldSize( maxlength, VIEW_COLUMNS_MAXSIZE ) );
    098                }
    099
    100                int r1 = clm.getTotalSize()/Integer.parseInt(size1) + 1;        // 4.0.0 (2005/01/31) メソッド名変更
    101                if( r1 > 5 ) { rows1 = 5; }
    102                else { rows1 = r1; }
    103
    104                int r2 = clm.getTotalSize()/Integer.parseInt(size2) + 1;        // 4.0.0 (2005/01/31) メソッド名変更
    105                if( r2 > 5 ) { rows2 = 5; }
    106                else { rows2 = r2; }
    107
    108                // 3.8.0.2 (2005/07/11) size に、"rows-maxRow,cols-maxCols" を指定
    109                String param = StringUtil.nval( clm.getRendererParam(),clm.getViewLength() );
    110                if( param != null && param.length() != 0 ) {
    111                        int prmAdrs = param.indexOf( ',' );
    112                        if( prmAdrs > 0 ) {
    113                                String rowStr = param.substring( 0,prmAdrs );
    114                                String colStr = param.substring( prmAdrs+1 );
    115
    116                                int rowAdrs = rowStr.indexOf( '-' );    // rows-maxRow 設定時 '-' がなければ、ただのrows
    117                                if( rowAdrs > 0 ) {
    118                                        rows1 = Integer.parseInt( rowStr.substring( 0,rowAdrs ) );
    119                                        maxRowSize = Integer.parseInt( rowStr.substring( rowAdrs+1 ) );
    120                                }
    121                                else {
    122                                        rows1 = Integer.parseInt( rowStr );
    123                                }
    124                                rows2 = rows1 ;
    125
    126                                int colAdrs = colStr.indexOf( '-' );    // cols-maxCols 設定時 '-' がなければ、ただのcols
    127                                if( colAdrs > 0 ) {
    128                                        cols1 = Integer.parseInt( colStr.substring( 0,colAdrs ) );
    129                                        maxColSize = Integer.parseInt( colStr.substring( colAdrs+1 ) );
    130                                }
    131                                else {
    132                                        cols1 = Integer.parseInt( colStr );
    133                                }
    134                                cols2 = cols1;
    135                        }
    136                }
    137        }
    138
    139        /**
    140         * 各オブジェクトから自分のインスタンスを返します。
    141         * 自分自身をキャッシュするのか、新たに作成するのかは、各サブクラスの実装に
    142         * まかされます。
    143         *
    144         * @param       clm     DBColumnオブジェクト
    145         *
    146         * @return      CellRendererオブジェクト
    147         */
    148        public CellRenderer newInstance( final DBColumn clm ) {
    149                return new Renderer_AUTOAREA( clm );
    150        }
    151
    152        /**
    153         * データの表示用文字列を返します。
    154         *
    155         * @param   value 入力値
    156         *
    157         * @return  データの表示用文字列
    158         */
    159        @Override
    160        public String getValue( final String value ) {
    161
    162                int[] rowcol = getRowsCols( value,cols1,rows1 );
    163
    164                TagBuffer tag = new TagBuffer( "textarea" );
    165                tag.add( "cols"    , String.valueOf( rowcol[COL] ) );
    166                tag.add( "rows"    , String.valueOf( rowcol[ROW] ) );
    167                tag.add( "readonly", "readonly" );
    168                tag.add( "class"   , "renderer-textarea" );
    169                tag.add( tagBuffer.makeTag() );
    170                tag.setBody( value );
    171
    172                return tag.makeTag();
    173        }
    174
    175        /**
    176         * データの表示用文字列を返します。
    177         *
    178         * @param   row   行番号
    179         * @param   value 入力値
    180         *
    181         * @return  データ表示用の文字列
    182         */
    183        @Override
    184        public String getValue( final int row,final String value ) {
    185
    186                int[] rowcol = getRowsCols( value,cols2,rows2 );
    187
    188                TagBuffer tag = new TagBuffer( "textarea" );
    189                tag.add( "cols"    , String.valueOf( rowcol[COL] ) );
    190                tag.add( "rows"    , String.valueOf( rowcol[ROW] ) );
    191                tag.add( "readonly", "readonly" );
    192                tag.add( "class"   , "renderer-textarea" );
    193                tag.add( tagBuffer.makeTag() );
    194                tag.setBody( value );
    195
    196                return tag.makeTag( row,value );
    197        }
    198
    199        /**
    200         * 自動表示する行列の数を求めます。
    201         * 行数は、引数の文字列中に含まれる 改行コードの個数を求めます。
    202         * 列数は、各行数のなかの最大桁数より求めます。これには半角、全角が含まれる為、
    203         * 半角換算での文字数ということになります。
    204         * 行数と列数が、初期設定の行数と列数より小さい場合は、初期設定値が使用されます。
    205         *
    206         * @param   value 入力値 表示文字列
    207         * @param       cols    最小カラム数
    208         * @param       rows    最小行数
    209         *
    210         * @return      自動計算した行列の配列
    211         */
    212        private int[] getRowsCols( final String value,final int cols, final int rows ) {
    213                if( value == null ) {
    214                        return new int[] { rows,cols };
    215                }
    216
    217                StringTokenizer token = new StringTokenizer( value, "\n", true );
    218
    219                int cntRow = 1;
    220                int maxCol = 0;
    221                while ( token.hasMoreTokens() ) {
    222                        String val = token.nextToken();
    223                        if( "\n".equals( val ) ) { cntRow++; }
    224                        else {
    225                                byte[] byteValue = StringUtil.makeByte( val,CODE );     // 3.5.5.3 (2004/04/09)
    226                                int byteSize = byteValue.length;
    227                                if( maxColSize > 0 && byteSize > maxColSize ) {         // 最大列数
    228                                        cntRow += byteSize / maxColSize;
    229                                        maxCol = maxColSize ;
    230                                }
    231                                else if( byteSize > maxCol ) { maxCol = byteSize; }
    232                        }
    233                        if( maxRowSize > 0 && cntRow >= maxRowSize ) {          // 最大行数
    234                                cntRow = maxRowSize;
    235                                break;
    236                        }
    237                }
    238
    239                maxCol += 2;    // マージン。フォントや画面サイズに影響する為、比率のほうがよい？
    240
    241                int[] rtn = new int[2];
    242                rtn[ROW] = (rows<cntRow) ? cntRow : rows ;
    243                rtn[COL] = (cols<maxCol) ? maxCol : cols ;
    244
    245                return rtn ;
    246        }
    247}