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.table;
017
018import java.io.File;
019import java.util.Locale;
020import java.util.Map ;
021import java.util.LinkedHashMap ;
022
023import org.opengion.hayabusa.common.HybsSystemException;
024import org.opengion.hayabusa.common.HybsSystem;
025import org.opengion.hayabusa.db.AbstractTableFilter;
026import org.opengion.hayabusa.db.DBTableModel;
027
028import org.opengion.fukurou.util.ErrorMessage;
029import org.opengion.fukurou.util.StringUtil;
030import org.opengion.fukurou.util.ImageResizer;
031
032/**
033 * TableFilter_THUMBNAIL は、TableFilter インターフェースを継承した、DBTableModel 処理用の
034 * 実装クラスです。
035 *
036 * ここでは、オリジナルファイルのサムネイルファイルを作成します。
037 * keys と vals に指定する値を以下に示します。
038 *
039 * <table border="1" frame="box" rules="all" >
040 *   <caption>keys と vals に指定する値</caption>
041 *   <tr><th>KEY        </th><th>VAL                        </th><th>(必須) </th><th>初期値 </th><th>解説                                                                   </th></tr>
042 *   <tr><td>PATH_CLM   </td><td>元ファイルのPATHカラムID   </td><td>必須   </td><td>       </td><td>元ファイルのコンテキストパスが登録されているカラムID                   </td></tr>
043 *   <tr><td>FILE_CLM   </td><td>元ファイルのFILEカラムID   </td><td>必須   </td><td>       </td><td>元ファイルのファイル名が登録されているカラムID                         </td></tr>
044 *   <tr><td>THUMB_CLM  </td><td>サムネイルのカラムID       </td><td>       </td><td>       </td><td>サムネイルのPATH/FILEが登録、または書き戻し用のカラムID                </td></tr>
045 *   <tr><td>THUMB_DIR  </td><td>サムネイルの管理フォルダ   </td><td>       </td><td>_thumb/</td><td>サムネイルを作成する中間管理フォルダ名                                 </td></tr>
046 *   <tr><td>THUMB_SUFIX</td><td>サムネイルの拡張子         </td><td>       </td><td>AUTO   </td><td>サムネイルの拡張子を指定します。AUTOは、元のままです。                 </td></tr>
047 *   <tr><td>OVERWRITE  </td><td>上書きするかどうか         </td><td>       </td><td>false  </td><td>サムネイルを作成する時、上書きするかどうかを指定します。               </td></tr>
048 *   <tr><td>MAX_SIZE   </td><td>サムネイルの最大ピクセル数 </td><td>       </td><td>128    </td><td>サムネイルを作成する時の画像ファイルの大きさ。比率はキープされます。   </td></tr>
049 * </table>
050 *
051 * 【解説】
052 * 1.PATH_CLM + FILE_CLMのカラム列の値が、元ファイルのコンテキストパス以下のファイルのアドレスになります。
053 * 2.サムネイルは通常、元フォルダに管理フォルダを作成し、その下に、元ファイルと同じ名前のサムネイルファイルを作成します。
054 *     つまり、PATH_CLM + THUMB_DIR + FILE_CLM + 拡張子が、サムネイルのファイル名になります。
055 * 3.THUMB_SUFIX を指定した場合は、サムネイルの拡張子を変更できます。初期値は、AUTOです。
056 *     AUTOの場合は、元ファイルと同じ拡張子が使われます。自分で指定する場合は、拡張子違いの元ファイルがあれば重複しますので注意が必要です。
057 * 4.サムネイルを作成できるのは、bmp/jpeg/png/gif/tif だけです。それ以外のファイルについては、ICONレンデラー等を使用して、自分でサムネイル表示するようにして下さい。
058 *     ただし、将来的には、xls/ppt/doc/pdf などの主要なファイルフォーマットのサムネイルは作成したいと考えています。
059 * 5.THUMB_CLM にサムネイルのファイル名が記述されている場合、その名前でサムネイルを作成します。このとき、OVERWRITE=true の場合は、既存ファイルの有無に関係なく
060 *     上書き(再作成)されます。OVERWRITE=false(初期値)の場合は、すでに存在していれば、そのままとします。
061 * 6.THUMB_CLM にサムネイルのファイル名が記述されていない場合は、標準のファイル名でサムネイルを作成して、THUMB_CLMカラムに書き戻します。
062 *     この場合、既存ファイルの有無に関係なく、上書き(再作成)されます。
063 * 7.THUMB_CLM が指定されていない場合は、カラムに書き戻し処理を行いません。(6.と同じで、書き戻しを行いません。)
064 * 8.MAX_SIZE は、サムネイルを作成する場合、縦、横の最大ピクセルに、縮小されます。比率は変わりません。これは物理的なサムネイルファイルのサイズです。
065 *
066 * なお、ドキュメント管理系で、自動スキャン取込みで、ファイルやフォルダの先頭に、アンダーバーがついている場合は、スキャン対象から外します。
067 * ドキュメントシステムから見た場合の、隠しファイルの扱いです。サムネイルも、デフォルトでは、アンダーバー付のフォルダに作成します。
068 * これは、自動スキャンで、サムネイルのサムネイルを作成することを避ける意味合いもあります。
069 * また、サムネイルの一括削除などに都合が良いと思います。
070 *
071 * パラメータは、tableFilterタグの keys, vals にそれぞれ記述するか、BODY 部にCSS形式で記述します。
072 * @og.formSample
073 * ●形式:
074 *      @ &lt;og:tableFilter classId="THUMBNAIL" keys="PATH_CLM,FILE_CLM" vals='"PATH,NMFILE"' /&gt;
075 *
076 *      A &lt;og:tableFilter classId="THUMBNAIL" &gt;
077 *               {
078 *                   PATH_CLM      :  元ファイルのPATHカラムID    (必須)                  元ファイルのコンテキストパスが登録されているカラムID
079 *                   FILE_CLM      :  元ファイルのFILEカラムID    (必須)                  元ファイルのファイル名が登録されているカラムID
080 *                   THUMB_CLM     :  サムネイルのカラムID                                サムネイルのPATH/FILEが登録、または書き戻し用のカラムID
081 *                   THUMB_DIR     :  サムネイルの管理フォルダ            初期値 _thumb/  サムネイルを作成する中間管理フォルダ名
082 *                   THUMB_SUFIX   :  サムネイルの拡張子                  初期値 AUTO     AUTOは元と同じ拡張子を使います。
083 *                   OVERWRITE     :  上書きするかどうか                  初期値 false    サムネイルを作成する時、上書きするかどうかを指定します。
084 *                   MAX_SIZE      :  サムネイルの最大ピクセル数          初期値 128      サムネイルを作成する時の画像ファイルの大きさ。比率はキープされます。
085 *               }
086 *         &lt;/og:tableFilter&gt;
087 *
088 * @og.rev 5.6.5.1 (2013/06/14) 新規追加
089 * @og.rev 5.6.6.0 (2013/07/05) keys の整合性チェックを追加
090 *
091 * @version  0.9.0  2000/10/17
092 * @author   Kazuhiko Hasegawa
093 * @since    JDK1.1,
094 */
095public class TableFilter_THUMBNAIL extends AbstractTableFilter {
096        //* このプログラムのVERSION文字列を設定します。   {@value} */
097        private static final String VERSION = "5.6.6.1 (2013/07/12)" ;
098
099        private static final String REAL_PATH = HybsSystem.sys( "REAL_PATH" );
100
101        /**
102         * keys の整合性チェックを行うための初期設定を行います。
103         *
104         * @og.rev 5.6.6.1 (2013/07/12) keys の整合性チェック対応
105         *
106         * @param       keysMap keys の整合性チェックを行うための Map
107         */
108        @Override
109        protected void init( final Map<String,String> keysMap ) {
110                keysMap.put( "PATH_CLM"         , "元ファイルのPATHカラムID (必須)"                                );
111                keysMap.put( "FILE_CLM"         , "元ファイルのFILEカラムID (必須)"                                );
112                keysMap.put( "THUMB_CLM"        , "サムネイルのカラムID"                                         );
113                keysMap.put( "THUMB_DIR"        , "サムネイルの管理フォルダ   (初期値 _thumb/)"        );
114                keysMap.put( "THUMB_SUFIX"      , "サムネイルの拡張子         (初期値 AUTO)"        );              // 5.6.6.1 (2013/07/12)
115                keysMap.put( "OVERWRITE"        , "上書きするかどうか         (初期値 false"        );
116                keysMap.put( "MAX_SIZE"         , "サムネイルの最大ピクセル数 (初期値 128"              );
117        }
118
119        /**
120         * DBTableModel処理を実行します。
121         *
122         * @og.rev 5.6.6.1 (2013/07/12) THUMB_SUFIXを追加
123         *
124         * @return 処理結果のDBTableModel
125         */
126        public DBTableModel execute() {
127                DBTableModel table = getDBTableModel();         // 5.5.2.6 (2012/05/25) インターフェースにgetterメソッド追加
128
129                String  path_clm                = StringUtil.nval( getValue( "PATH_CLM"         ) , null                );              // 必須項目
130                String  file_clm                = StringUtil.nval( getValue( "FILE_CLM"         ) , null                );              // 必須項目
131                String  thumb_clm               = StringUtil.nval( getValue( "THUMB_CLM"        ) , null                );              // なければ、値戻しをしない。
132                String  thumb_dir               = StringUtil.nval( getValue( "THUMB_DIR"        ) , "_thumb/"   );              // サムネイルフォルダ
133                String  thumb_sufix             = StringUtil.nval( getValue( "THUMB_SUFIX"      ) , "AUTO"              );              // 5.6.6.1 (2013/07/12) サムネイルの拡張子
134                boolean isOverwrite             = StringUtil.nval( getValue( "OVERWRITE"        ) , false               );              // サムネイルの再作成有無
135                int     max_size                = StringUtil.nval( getValue( "MAX_SIZE"         ) , 128                 );
136
137                int path_clmNo  = table.getColumnNo( path_clm , true  );                // 存在しない場合は、エラー
138                int file_clmNo  = table.getColumnNo( file_clm , true  );                // 存在しない場合は、エラー
139                int thumb_clmNo = table.getColumnNo( thumb_clm , false );               // 存在しない場合は、-1 を返す。
140
141                ErrorMessage errMessage = null;
142                int rowCnt = table.getRowCount();
143                for( int row=0; row<rowCnt; row++ ) {
144                        try {
145                                // オリジナルのファイルを構築します。
146                                String pathClmVal = table.getValue( row,path_clmNo );
147                                String fileClmVal = table.getValue( row,file_clmNo );
148                                File orgFile = new File( StringUtil.urlAppend( REAL_PATH , pathClmVal ),fileClmVal );           // オリジナルファイル名
149                                if( !orgFile.exists() ) {
150//                                      String errMsg = "元ファイルが存在しません。[" + orgFile.toString() + "]" ;                           // ファイルがなければエラー
151//                                      throw new RuntimeException( errMsg );
152                                        continue;                                                                                                                                                               // 5.6.6.0 (2013/07/05) なければ無視
153                                }
154
155                                // @ サムネイル作成対象の拡張子の場合のみ処理します。よって、sufix は存在することが保障されます。
156                                if( ImageResizer.isReaderSuffix( fileClmVal ) ) {
157                                        // サムネイルのファイルを構築します。
158                                        File thumbFile = null;
159                                        String thumbClmVal = null;
160                                        if( thumb_clmNo >= 0 ) {
161                                                thumbClmVal = table.getValue( row,thumb_clmNo );
162                                                if( thumbClmVal != null && thumbClmVal.length() > 0 ) {                      // サムネイルファイル名が指定された場合
163                                                        thumbFile = new File( REAL_PATH , thumbClmVal );
164                                                        if( !isOverwrite && thumbFile.exists() ) { continue; }          // ファイルが存在した場合は、処理しない
165                                                }
166                                                else {
167                                                        thumbClmVal = null;
168                                                }
169                                        }
170
171                                        // @-1 thumbClmVal が未定義(=null)の場合は、自分でファイル名を構築する
172                                        if( thumbClmVal == null ) {
173                                                // 元ファイルの拡張子を取り出します。(小文字化も行います。)
174                                                String sufix  = ImageResizer.getSuffix( fileClmVal );
175                                                String thumbName = fileClmVal ;
176                                                // 5.6.6.1 (2013/07/12) サムネイルの拡張子
177                                                if( ! "AUTO".equalsIgnoreCase( thumb_sufix ) ) {        // AUTO以外が指定された場合
178                                                        thumbName = fileClmVal.substring( 0,fileClmVal.length()-sufix.length() ) + thumb_sufix ;
179                                                }
180                                                // 5.6.6.1 (2013/07/12) 拡張子が bmp の場合の、png に置き換えはしない。
181//                                              if( "bmp".equalsIgnoreCase( sufix ) ) {
182//                                                      thumbName = fileClmVal.substring( 0,fileClmVal.length()-3 ) + "png" ;           // 拡張子が bmp の場合は、png に置き換えます。
183//                                              }
184
185                                                thumbClmVal = StringUtil.urlAppend( pathClmVal,thumb_dir,thumbName );                   // サムネイルのアドレス/ファイル名
186                                                thumbFile = new File( REAL_PATH , thumbClmVal );
187
188                                                if( thumb_clmNo >= 0) {
189                                                        table.setValueAt( thumbClmVal,row,thumb_clmNo );                        // サムネイルファイル名の書き戻し
190                                                }
191                                        }
192
193                                        // サムネイル保存先のディレクトリ作成
194                                        File parent = thumbFile.getParentFile();
195                                        if( !parent.exists() && !parent.mkdirs() ) {
196                                                String errMsg = "サムネイル保存先のディレクトリ作成に失敗しました。file=[" + parent.toString() + "]";
197                                                throw new HybsSystemException( errMsg );
198                                        }
199
200                                        // 実際のサムネイルの作成処理
201                                        ImageResizer imgRes = new ImageResizer( orgFile.getAbsolutePath() );            // 変換元のファイル名
202                                        imgRes.resizeByPixel( thumbFile.getAbsolutePath() , max_size );                         // 変換先のファイル名と画像の大きさ
203                                }
204                        }
205                        catch( RuntimeException ex ) {
206                                if( errMessage == null ) { errMessage = makeErrorMessage( "TableFilter_THUMBNAIL Error",ErrorMessage.NG ); }
207                                errMessage.addMessage( row+1,ErrorMessage.NG,ex.getMessage() );
208                        }
209                }
210
211                return table;
212        }
213}