    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.hayabusa.taglib;
    017
    018import org.opengion.hayabusa.resource.UserInfo;
    019import org.opengion.hayabusa.db.DBTableModel;
    020import org.opengion.hayabusa.db.Query;
    021import org.opengion.hayabusa.db.QueryFactory;
    022import org.opengion.fukurou.db.Transaction;
    023import org.opengion.fukurou.db.TransactionReal;
    024
    025import static org.opengion.fukurou.util.StringUtil.nval ;
    026
    027import java.util.Locale ;
    028import java.io.ObjectOutputStream;
    029import java.io.ObjectInputStream;
    030import java.io.IOException;
    031
    032/**
    033 * ユーザー情報を管理しているタグです。
    034 *
    035 * 設定した値は、{&#064;USER.XXXX} 形式で 取り出すことができます。
    036 * また、command 属性で 直接画面に値を書き出すことも可能です。
    037 *
    038 * 以下の値は UserInfo オブジェクトの項目から取得します。
    039 * ・USER.JNAME     ユーザー日本語名称
    040 * ・USER.ID        ユーザーＩＤ
    041 * ・USER.IDNO      USER.ID が５Byte以上の時のみ先頭１文字を除いたユーザーＩＤ
    042 * ・USER.INFO      ユーザー情報(ユーザーID：日本語名称)
    043 * ・USER.LANG      言語
    044 * ・USER.ROLES     ロール
    045 * ・USER.IPADDRESS IPアドレス
    046 * ・USER.LOGINTIME ログイン時刻
    047 *
    048 * 以下の値はあらかじめ、動的に作成されます。
    049 * ・USER.YMD       ８byte の今日のシステム日付
    050 * ・USER.YMDH    １４byte の今日のシステム日時
    051 *
    052 * それ以外は、外部より設定された値です。
    053 *
    054 * ※ このタグは、Transaction タグの対象です。
    055 *
    056 * @og.formSample
    057 * ●形式：&lt;og:userInfo command="[…]" key="[…]" value="[…]" /&gt;
    058 * ●body：あり(EVAL_BODY_BUFFERED:BODYを評価し、{&#064;XXXX} を解析します)
    059 *
    060 * ●Tag定義：
    061 *   &lt;og:userInfo
    062 *       command            【TAG】コマンド(SET,GET,NVLGET,REMOVE,SQL)をセットします(初期値:SET)
    063 *       key                【TAG】UserInfo に登録するキーをセットします(予約語:JNAME,ID,PASSWD,IDNO,INFO,LANG,ROLE,IPADDRESS,LOGINTIME)
    064 *       value              【TAG】UserInfo に登録する値をセットします
    065 *       dbid               【TAG】(通常は使いません)Queryオブジェクトを作成する時のDB接続IDを指定します
    066 *       save               【TAG】UserInfo に登録した値を永続化するかを指定します
    067 *       caseKey            【TAG】このタグ自体を利用するかどうかの条件キーを指定します(初期値:null)
    068 *       caseVal            【TAG】このタグ自体を利用するかどうかの条件値を指定します(初期値:null)
    069 *       caseNN             【TAG】指定の値が、null/ゼロ文字列 でない場合(Not Null=NN)は、このタグは使用されます(初期値:true)
    070 *       caseNull           【TAG】指定の値が、null/ゼロ文字列 の場合は、このタグは使用されます(初期値:true)
    071 *       debug              【TAG】デバッグ情報を出力するかどうか[true/false]を指定します(初期値:false)
    072 *   &gt;   ... Body ...
    073 *   &lt;/og:userInfo&gt;
    074 *
    075 * ●使用例
    076 *      &lt;og:userInfo
    077 *         command       = &quot;コマンド(SET,GET,NVLGET,REMOVE,SQL)をセットします(初期値:SET)。&quot;
    078 *         key           = &quot;UserInfo に登録するキーをセットします(予約語:JNAME,ID,PASSWD,IDNO,INFO,LANG,ROLE,IPADDRESS,LOGINTIME)。&quot;
    079 *         value         = &quot;UserInfo に登録する値をセットします。&quot;
    080 *         dbid          = &quot;(通常は使いません)Queryオブジェクトを作成する時のDB接続IDを指定します。&quot;
    081 *      &gt;
    082 *
    083 * @og.group その他部品
    084 *
    085 * @version  4.0
    086 * @author   Kazuhiko Hasegawa
    087 * @since    JDK5.0,
    088 */
    089public class UserInfoTag extends CommonTagSupport {
    090        //* このプログラムのVERSION文字列を設定します。   {@value} */
    091        private static final String VERSION = "5.3.8.0 (2011/08/01)" ;
    092
    093        private static final long serialVersionUID = 538020110801L ;
    094
    095        /** command 引数に渡す事の出来る コマンド  セット {@value} */
    096        public static final String CMD_SET   = "SET" ;
    097        /** command 引数に渡す事の出来る コマンド  ゲット {@value} */
    098        public static final String CMD_GET   = "GET" ;
    099        /** command 引数に渡す事の出来る コマンド  ゲット {@value} */
    100        public static final String CMD_REMOVE   = "REMOVE" ;
    101        /** command 引数に渡す事の出来る コマンド  ゲット {@value} */
    102        public static final String CMD_SQL   = "SQL" ;
    103        // 3.5.5.3 (2004/04/09) 値が null の場合は、""(ゼロ文字列)を返すNVLGETを採用
    104        /** command 引数に渡す事の出来る コマンド  NVLゲット {@value} */
    105        public static final String CMD_NVLGET   = "NVLGET" ;
    106
    107        // 3.5.5.3 (2004/04/09) 値が null の場合は、""(ゼロ文字列)を返すNVLGETを採用
    108        /** command 引数に渡す事の出来る コマンド リスト  */
    109        private static final String[] COMMAND_LIST = new String[] {
    110                CMD_SET , CMD_GET , CMD_NVLGET , CMD_REMOVE , CMD_SQL };
    111
    112        // 3.5.6.0 (2004/06/18) すべてを protected から private に変更します。
    113        private String                  command         = CMD_SET;
    114        private String                  key                     = null;
    115        private String                  value           = null;
    116//      private boolean                 isNullSet       = true;                 // NULL のときにセットし直すかどうか。
    117        private transient DBTableModel  table           = null;
    118        // 4.0.0.0 (2007/10/10) dbid の初期値を、"DEFAULT" から null に変更
    119//      private String                  dbid            = "DEFAULT";
    120        private String                  dbid            = null;
    121        private String                  sql                     = null;
    122        // 4.3.4.0 (2008/12/01) save属性追加
    123        private boolean                 save            = false;
    124
    125        /**
    126         * Taglibの開始タグが見つかったときに処理する doStartTag() を オーバーライドします。
    127         *
    128         * @og.rev 5.2.2.0 (2010/11/01) caseKey 、caseVal 属性対応
    129         *
    130         * @return      後続処理の指示
    131         */
    132        @Override
    133        public int doStartTag() {
    134                // 5.2.2.0 (2010/11/01) caseKey 、caseVal 属性対応
    135//              if( CMD_SQL.equals( command ) ) {
    136                if( useTag() && CMD_SQL.equals( command ) ) {
    137                        return( EVAL_BODY_BUFFERED );           // Body を評価する
    138                }
    139                else {
    140                        return( SKIP_BODY ); // Body を評価しない
    141                }
    142        }
    143
    144        /**
    145         * Taglibのタグ本体を処理する doAfterBody() を オーバーライドします。
    146         *
    147         * @og.rev 3.1.1.0 (2003/03/28) ボディの内容を取得する処理を、CommonTagSupport で行う。
    148         * @og.rev 3.6.0.8 (2004/11/19) エラー発生時に確実にリリースされるように try finally 追加
    149         * @og.rev 3.8.6.3 (2006/11/30) SQL 文の前後のスペースを取り除きます。
    150         * @og.rev 3.8.7.0 (2006/12/15) アクセスログ取得の為,ApplicationInfoオブジェクトを設定
    151         * @og.rev 4.0.0.0 (2005/01/31) lang ⇒ ResourceManager へ変更
    152         * @og.rev 5.1.9.0 (2010/08/01) TransactionTag 対応。上位に TransactionTag があれば、そこからConnection をもらう。
    153         * @og.rev 5.3.7.0 (2011/07/01) TransactionReal の引数変更
    154         * @og.rev 5.3.8.0 (2011/08/01) Transaction発生箇所でclose()
    155         *
    156         * @return      後続処理の指示(SKIP_BODY)
    157         */
    158        @Override
    159        public int doAfterBody() {
    160                sql = getBodyString().trim();
    161
    162                Query query = QueryFactory.newInstance();               // 4.0.0 (2005/01/31)
    163                Transaction tran = null;
    164                try {
    165                        // 5.1.9.0 (2010/08/01) TransactionTag 対応
    166//                      final Transaction tran ;
    167                        TransactionTag tranTag = (TransactionTag)findAncestorWithClass( this,TransactionTag.class );
    168                        if( tranTag == null ) {
    169//                              tran = new TransactionReal( dbid,getApplicationInfo() );
    170                                tran = new TransactionReal( getApplicationInfo() );             // 5.3.7.0 (2011/07/01) 引数変更
    171                        }
    172                        else {
    173                                tran = tranTag.getTransaction();
    174                        }
    175                        query.setTransaction( dbid,tran );      // 5.1.9.0 (2010/08/01) TransactionTag 対応
    176
    177//                      query.setConnectionID( dbid );
    178                        query.setResourceManager( getResource() );      // 4.0.0 (2005/01/31)
    179
    180                        query.setStatement( sql );
    181//                      query.setApplicationInfo( getApplicationInfo() );       // 3.8.7.0 (2006/12/15)
    182                        query.execute();
    183
    184                        table = query.getDBTableModel();
    185                }
    186                finally {
    187//                      if( query != null ) { query.close(); }
    188                        QueryFactory.close( query );
    189                        if( tran != null ) { tran.close(); }            // 5.3.8.0 (2011/08/01) Transaction発生箇所でclose()
    190                }
    191                return(SKIP_BODY);
    192        }
    193
    194        /**
    195         * Taglibの終了タグが見つかったときに処理する doEndTag() を オーバーライドします。
    196         *
    197         * @og.rev 3.1.1.2 (2003/04/04) Tomcat4.1 対応。release2() を doEndTag()で呼ぶ。
    198         * @og.rev 3.5.5.3 (2004/04/09) 値が null の場合は、""(ゼロ文字列)を返すフラグを採用
    199         * @og.rev 5.2.2.0 (2010/11/01) caseKey 、caseVal 属性対応
    200         *
    201         * @return      後続処理の指示
    202         */
    203        @Override
    204        public int doEndTag() {
    205                debugPrint();           // 4.0.0 (2005/02/28)
    206                // 5.2.2.0 (2010/11/01) caseKey 、caseVal 属性対応
    207//              if( check( command, COMMAND_LIST ) ) {
    208                if( useTag() && check( command, COMMAND_LIST ) ) {
    209                        commandExec( command );
    210
    211                        if( CMD_GET.equals( command ) ) {
    212                                jspPrint( value );
    213                        }
    214                        else if( CMD_NVLGET.equals( command ) ) {       // 3.5.5.3 (2004/04/09)
    215                                jspPrint( nval(value,"") );
    216                        }
    217                }
    218
    219                return(EVAL_PAGE);
    220        }
    221
    222        /**
    223         * タグリブオブジェクトをリリースします。
    224         * キャッシュされて再利用されるので、フィールドの初期設定を行います。
    225         *
    226         * @og.rev 2.0.0.4 (2002/09/27) カスタムタグの release() メソッドを、追加
    227         * @og.rev 3.1.1.2 (2003/04/04) Tomcat4.1 対応。release2() を doEndTag()で呼ぶ。
    228         * @og.rev 4.0.0.0 (2007/10/10) dbid の初期値を、"DEFAULT" から null に変更
    229         * @og.rev 4.3.4.0 (2008/12/01) save属性対応
    230         *
    231         */
    232        @Override
    233        protected void release2() {
    234                super.release2();
    235                command         = CMD_SET;
    236                key                     = null;
    237                value           = null;
    238//              isNullSet       = true;                 // NULL のときにセットし直すかどうか。
    239                table           = null;
    240//              dbid            = "DEFAULT";
    241                dbid            = null;
    242                sql                     = null;
    243                save            = false;
    244        }
    245
    246        /**
    247         * コマンドを実行します。
    248         *
    249         * コマンドは,HTMLから(get/post)指定されますので,setCommand()メソッドで
    250         * 登録します。
    251         * コマンドを登録すると同時に,実行も行ないます。
    252         *
    253         * @og.rev 3.5.5.3 (2004/04/09) 値が null の場合は、""(ゼロ文字列)を返すフラグを採用
    254         *
    255         * @param   command コマンド(public static final 宣言されている文字列)
    256         * @see         <a href="../../../../constant-values.html#org.opengion.hayabusa.taglib.UserInfoTag.CMD_GET">コマンド定数</a>
    257         */
    258        protected void commandExec( final String command ) {
    259                if( CMD_SQL.equals( command ) ) { setSQLAttribute() ; }
    260                else if( CMD_SET.equals(    command ) ) { setAttribute() ;    }
    261                else if( CMD_GET.equals(    command ) ) { getAttribute() ;    }
    262                else if( CMD_NVLGET.equals( command ) ) { getAttribute() ;    } // 3.5.5.3 (2004/04/09)
    263                else if( CMD_REMOVE.equals( command ) ) { removeAttribute() ; }
    264        }
    265
    266        /**
    267         * UserInfoの文字列を登録します。
    268         *
    269         * @og.rev 4.3.4.0 (2008/12/01) GE20(ユーザー定数)へ登録するかのフラグを追加
    270         *
    271         */
    272        private void setAttribute() {
    273//              if( isNullSet ) {
    274//                      setUserInfo( key, value );
    275                        setUserInfo( key, value, save );
    276//              }
    277        }
    278
    279        /**
    280         * UserInfoの文字列を作成します。
    281         *
    282         */
    283        private void getAttribute() {
    284                value = getUserInfo( key );
    285        }
    286
    287        /**
    288         * UserInfoの文字列を削除します。
    289         *
    290         * @og.rev 5.3.6.0 (2011/06/01) GE20(ユーザー定数)から削除するかのフラグを追加
    291         */
    292        private void removeAttribute() {
    293                UserInfo userInfo = getUser();
    294//              userInfo.removeAttribute( key );
    295                userInfo.removeAttribute( key, save );
    296        }
    297
    298        /**
    299         * UserInfoの文字列を指定のSQL文より作成します。
    300         *
    301         * @og.rev 4.3.4.0 (2008/12/01) GE20(ユーザー定数)へ登録するかのフラグを追加
    302         *
    303         */
    304        private void setSQLAttribute() {
    305                if( table == null || table.getRowCount() == 0 ) { return ; }
    306
    307                int row    = 0;
    308                int clmCnt = table.getColumnCount();
    309                for( int clm=0; clm<clmCnt; clm++ ) {
    310                        String clmkey = table.getColumnName( clm );
    311                        String clmval = table.getValue( row,clm );
    312//                      setUserInfo( clmkey,clmval );
    313                        setUserInfo( clmkey, clmval, save );
    314                }
    315        }
    316
    317        /**
    318         * 【TAG】コマンド(SET,GET,NVLGET,REMOVE,SQL)をセットします(初期値:SET)。
    319         *
    320         * @og.tag
    321         * コマンドは,HTMLから(get/post)指定されますので,CMD_xxx で設定される
    322         * フィールド定数値のいずれかを、指定できます。
    323         * 何も設定されない、または、null の場合は、"SET" が初期値にセットされます。
    324         * SQL の場合、検索結果の戻り値が複数存在する場合は、最初の１件目のみ使用します。
    325         *
    326         * @param       cmd コマンド(public static final 宣言されている文字列)
    327         * @see         <a href="../../../../constant-values.html#org.opengion.hayabusa.taglib.UserInfoTag.CMD_SET">コマンド定数</a>
    328         */
    329        public void setCommand( final String cmd ) {
    330                String cmd2 = getRequestParameter( cmd );
    331                if( cmd2 != null && cmd2.length() > 0 ) { command = cmd2.toUpperCase(Locale.JAPAN); }
    332        }
    333
    334        /**
    335         * 【TAG】UserInfo に登録するキーをセットします(予約語:JNAME,ID,PASSWD,IDNO,INFO,LANG,ROLE,IPADDRESS,LOGINTIME)。
    336         *
    337         * @og.tag UserInfo に登録するキーをセットします。
    338         *
    339         * @param       inkey UserInfo に登録するキー
    340         */
    341        public void setKey( final String inkey ) {
    342                key = getRequestParameter( inkey ).toUpperCase(Locale.JAPAN);
    343                if( key.startsWith( "USER." ) ) {
    344                        key = key.substring( 5 );
    345                }
    346        }
    347
    348        /**
    349         * 【TAG】UserInfo に登録する値をセットします。
    350         *
    351         * @og.tag UserInfo に登録する値をセットします。
    352         *
    353         * @param       val     UserInfoに登録する値
    354         */
    355        public void setValue( final String val ) {
    356                value = getRequestParameter( val );
    357        }
    358
    359        /**
    360         * 【TAG】UserInfo に登録した値を永続化するかを指定します。
    361         *
    362         * @og.tag
    363         * UserInfo に登録した値を永続化するかを指定します。
    364         * trueが指定された場合、UserInfoに設定された値は、GE20(ユーザー定数)に保存され、
    365         * UserInfoが再作成されるタイミングで自動的に復元されます。
    366         * ここで、登録された値は、そのユーザーの全てのロールに対して有効となります。
    367         * 初期値は、false(永続化しない)です。
    368         *
    369         * @param       sv      登録値を永続化するか
    370         */
    371        public void setSave( final String sv ) {
    372                save = nval( getRequestParameter( sv ),save );
    373        }
    374
    375//      /**
    376//       * 【廃止】Query を実行して、value に値をセットするかどうかを指定します。
    377//       *
    378//       * @og.tag
    379//       * 初期値は、実行しない ("false")
    380//       *
    381//       * @og.rev 3.1.0.1 (2003/03/26) query 属性を非推奨属性とします。内部では使用しません。
    382//       *
    383//       * @param   flag Query を実行する ("true")／実行しない(それ以外)
    384//       * @deprecated
    385//       */
    386//      @Deprecated public void setQuery( final String flag ) {
    387//              // ここでは処理を行いません。
    388//      }
    389
    390//      /**
    391//       * 【廃止】value が NULL の時に、設定するかどうか[true/false]を指定します(初期値:true)。
    392//       *
    393//       * @og.tag
    394//       * true の場合は, null のときでもセットします。
    395//       * false の場合は, null のときは、既存の値を置き換えません。
    396//       * 初期値は、null のときでもセットするです。 ("true")
    397//       *
    398//       * @param   flag NULL の時に、設定する ("true")／設定しない(それ以外)
    399//       * @deprecated
    400//       */
    401//      @Deprecated public void setNullSet( final String flag ) {
    402//              isNullSet = nval( getRequestParameter( flag ),isNullSet );
    403//      }
    404
    405        /**
    406         * 【TAG】(通常は使いません)Queryオブジェクトを作成する時のDB接続IDを指定します。
    407         *
    408         * @og.tag Queryオブジェクトを作成する時のDB接続IDを指定します。
    409         *
    410         * @param       id データベース接続ID
    411         */
    412        public void setDbid( final String id ) {
    413                dbid = nval( getRequestParameter( id ),dbid );
    414        }
    415
    416        /**
    417         * シリアライズ用のカスタムシリアライズ書き込みメソッド
    418         *
    419         * @og.rev 4.0.0.0 (2006/09/31) 新規追加
    420         * @serialData 一部のオブジェクトは、シリアライズされません。
    421         *
    422         * @param       strm    ObjectOutputStreamオブジェクト
    423         * @throws IOException  入出力エラーが発生した場合
    424         */
    425        private void writeObject( final ObjectOutputStream strm ) throws IOException {
    426                strm.defaultWriteObject();
    427        }
    428
    429        /**
    430         * シリアライズ用のカスタムシリアライズ読み込みメソッド
    431         *
    432         * ここでは、transient 宣言された内部変数の内、初期化が必要なフィールドのみ設定します。
    433         *
    434         * @og.rev 4.0.0.0 (2006/09/31) 新規追加
    435         * @serialData 一部のオブジェクトは、シリアライズされません。
    436         *
    437         * @param       strm    ObjectInputStreamオブジェクト
    438         * @see #release2()
    439         * @throws IOException  シリアライズに関する入出力エラーが発生した場合
    440         * @throws ClassNotFoundException       クラスを見つけることができなかった場合
    441         */
    442        private void readObject( final ObjectInputStream strm ) throws IOException , ClassNotFoundException {
    443                strm.defaultReadObject();
    444        }
    445
    446        /**
    447         * このオブジェクトの文字列表現を返します。
    448         * 基本的にデバッグ目的に使用します。
    449         *
    450         * @return このクラスの文字列表現
    451         */
    452        @Override
    453        public String toString() {
    454                return org.opengion.fukurou.util.ToString.title( this.getClass().getName() )
    455                                .println( "VERSION"                     ,VERSION        )
    456                                .println( "command"                     ,command        )
    457                                .println( "key"                         ,key            )
    458                                .println( "value"                       ,value          )
    459//                              .println( "isNullSet"           ,isNullSet      )
    460                                .println( "dbid"                        ,dbid           )
    461                                .println( "sql"                         ,sql            )
    462                                .println( "save"                        ,save           )
    463                                .println( "COMMAND_LIST"        ,COMMAND_LIST   )
    464                                .println( "Other..."    ,getAttributes().getAttribute() )
    465                                .fixForm().toString() ;
    466        }
    467}