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     */
016    package org.opengion.hayabusa.html;
017    
018    import org.opengion.hayabusa.common.HybsSystem;
019    import org.opengion.hayabusa.db.DBTableModel;
020    import org.opengion.fukurou.security.URLHashMap;
021    import org.opengion.fukurou.util.StringUtil;
022    import org.opengion.fukurou.util.Attributes;
023    import org.opengion.fukurou.util.XHTMLTag;
024    import org.opengion.fukurou.model.Formatter;
025    
026    import java.util.Map;
027    import java.util.HashMap;
028    import java.util.List;
029    import java.util.ArrayList;
030    import java.util.Arrays ;
031    
032    /**
033     * ViewLink インターフェース の実?ブジェクトです?
034     * これ?共通?スーパ?クラスとして ?表示フォー?例:HTML表示?に使?す?
035     *
036     * こ?クラスは、setter/getterメソ?の?ォルト実?提供して?す?
037     * ?表示フォー?対応したサブクラス上で, create() をオーバ?ライドして下さ??
038     *
039     * @og.rev 2.1.0.3 (2002/11/08) エンコード?開?終?ドレスを求める???修正
040     * @og.rev 4.0.0.0 (2005/08/31) 同?ラ???登録を許可します?
041     * @og.group 画面表示
042     *
043     * @version  4.0
044     * @author   Kazuhiko Hasegawa
045     * @since    JDK5.0,
046     */
047    public class ViewLink_LINK implements ViewMarker {
048            private static final String REQ_KEY = HybsSystem.URL_HASH_REQ_KEY ;
049    
050            private static final int ACCS_LVL = HybsSystem.sysInt( "URL_ACCESS_SECURITY_LEVEL" );
051    
052            private List<Attributes>          markData        = null;         // 4.0.0 (2005/08/31)
053    //      private Map<Integer,int[]>                formMap_c       = new HashMap<Integer,int[]>();   // 3.5.6.1 (2004/06/25)
054    //      private Map<Integer,String[]>     formMap_f       = new HashMap<Integer,String[]>();        // 3.5.6.1 (2004/06/25)
055            private Map<Integer,Formatter>    formMap         = new HashMap<Integer,Formatter>();
056            private DBTableModel            table       = null;
057            private int[]                           markCmlNo       = null;
058            private int[]                           isMark          = null;
059            // 2.1.0.3 (2002/11/08) エンコード?開?終?ドレスを求める???修正
060            private int[]               encodeIn    = null;         // 初期値:??
061            private int[]               encodeOut   = null;         // 初期値:??
062            private static final int        MARK_NULL   = -1;               // リンク未設?
063            private static final int        MARK_TRUE   = 1;                // リンク作?
064            private static final int        MARK_FALSE  = 0;                // リンク作?せず
065            // 3.5.2.0 (2003/10/20)
066            private String[]                        markKey         = null;
067            private String[]                        markLists       = null;
068            private int[]                           markListNo      = null;
069    
070            private boolean[]                       useURLCheck     = null; // 4.3.7.1 (2009/06/08)
071            private String[]                        urlCheckUser= null;     // 4.3.7.1 (2009/06/08)
072            private long[]                          urlCheckTime= null;     // 4.3.7.1 (2009/06/08)
073            
074            private String[]                        extToken        = null; // 5.8.2.1 (2014/12/13)
075    
076            private Map<Integer,List<Integer>>  clmMap  = new HashMap<Integer,List<Integer>>();     // 4.0.0 (2005/08/31)
077    
078            /**
079             * ?をクリア(初期?します?
080             *
081             * @og.rev 3.1.1.0 (2003/03/28) 同期メソ?(synchronized付き)を非同期に変更する?
082             * @og.rev 3.5.2.0 (2003/10/20) markLists,markListNo,markKey属?を追?
083             * @og.rev 3.5.6.1 (2004/06/25) formMap属?を追?
084             * @og.rev 4.3.7.1 (2009/06/08) URLチェ?属?追?
085             * @og.rev 5.8.2.1 (2014/12/13) extToken追?
086             */
087            public void clear() {
088                    markData        = null;         // 4.0.0 (2005/08/31)
089    //              formMap_c       = new HashMap<Integer,int[]>();           // 3.5.6.1 (2004/06/25)
090    //              formMap_f       = new HashMap<Integer,String[]>();        // 3.5.6.1 (2004/06/25)
091                    formMap         = new HashMap<Integer,Formatter>();
092                    table       = null;
093                    isMark      = null;
094                    encodeIn    = null;
095                    encodeOut   = null;
096                    markKey         = null;
097                    markLists       = null;
098                    markListNo      = null;
099                    clmMap          = new HashMap<Integer,List<Integer>>();     // 4.0.0 (2005/08/31)
100                    useURLCheck = null; // 4.3.7.1 (2009/06/08)
101                    urlCheckUser= null; // 4.3.7.1 (2009/06/08)
102                    urlCheckTime= null; // 4.3.7.1 (2009/06/08)
103                    extToken        = null; // 5.8.2.1 (2014/12/14)
104            }
105    
106            /**
107             * カラ?対するリンクアトリビュートをセ?します?
108             *
109             * @og.rev 3.1.0.0 (2003/03/20) Hashtable を使用して??で?同期でも構わな??を?HashMap に置換え?
110             * @og.rev 3.1.1.0 (2003/03/28) 同期メソ?(synchronized付き)を非同期に変更する?
111             * @og.rev 4.0.0.0 (2005/08/31) 同?ラ???登録を許可します?
112             *
113             * @param       attri   リンクアトリビュー?
114             */
115            public void addAttribute( final Attributes attri ) {
116                    if( markData == null ) { markData = new ArrayList<Attributes>(); }
117                    markData.add( attri );
118            }
119    
120            /**
121             * ?に DBTableModel をセ?します?
122             *
123             * @og.rev 2.1.0.3 (2002/11/08) エンコード?開?終?ドレスを求める???修正
124             * @og.rev 3.1.1.0 (2003/03/28) 同期メソ?(synchronized付き)を非同期に変更する?
125             * @og.rev 3.5.2.0 (2003/10/20) markLists,markListNo,markKey属?を追?
126             * @og.rev 3.5.5.0 (2004/03/12) xlink 属?によるリンク??作?方法??を追?
127             * @og.rev 3.5.6.1 (2004/06/25) DBTableModel の再設定に対応?
128             * @og.rev 3.5.6.2 (2004/07/05) linkFormat をパラメータで取得するよ?変更?
129             * @og.rev 3.8.1.1 (2005/11/21) linkFormat ?"[","]" をエンコードしてしまった?合に?戻します?
130             * @og.rev 4.0.0.0 (2005/08/31) 同?ラ???登録を許可します?
131             * @og.rev 4.3.7.1 (2009/06/08) URLチェ?機?追?
132             *
133             * @param  tbl DBTableModelオブジェク?
134             */
135            public void setDBTableModel( final DBTableModel tbl ) {
136                    table   = tbl;
137    //              String linkFormat       = null;
138                    int     count           = markData.size();                      // 4.0.0 (2005/08/31)
139    
140                    isMark          = new int[ count ];
141                    markKey         = new String[ count ];
142                    markCmlNo       = new int[ count ];
143                    markLists       = new String[ count ];
144                    markListNo      = new int[ count ];
145                    encodeIn    = new int[ count ];
146                    encodeOut   = new int[ count ];
147                    useURLCheck = new boolean[ count ];                             // 4.3.7.1 (2009/06/08)
148                    urlCheckUser= new String[ count ];                              // 4.3.7.1 (2009/06/08)
149                    urlCheckTime= new long[ count ];                                // 4.3.7.1 (2009/06/08)
150                    extToken        = new String[ count ];                          // 5.8.2.1 (2014/12/13)
151    
152                    Arrays.fill( isMark,MARK_FALSE );       // リンクの表示可否
153                    Arrays.fill( markCmlNo,-1 );            // リンクの可否を判断するカラ?号
154                    Arrays.fill( encodeIn ,10000 );         // 初期値:??
155                    Arrays.fill( encodeOut,-1 );            // 初期値:??
156                    Arrays.fill( useURLCheck, false );      // 4.3.7.1 (2009/06/08)
157                    Arrays.fill( urlCheckTime, 0L );        // 4.3.7.1 (2009/06/08)
158    
159                    // 4.0.0 (2005/08/31) 同?ラ???登録を許可します?
160                    for( int intKey=0; intKey<count; intKey++ ) {
161                            Attributes attri = markData.get( intKey );
162    
163                            String column = attri.get( "column" );
164                            int clm = table.getColumnNo( column );
165                            List<Integer> list = clmMap.get( clm );
166                            if( list == null ) { list = new ArrayList<Integer>(); }
167                            list.add( intKey );
168                            clmMap.put( clm,list );
169    
170                            String linkFormat = attri.get( "linkFormat" );
171                            linkFormat = StringUtil.replace( linkFormat,"%5B","[" );        // 3.8.1.1 (2005/11/21)
172                            linkFormat = StringUtil.replace( linkFormat,"%5D","]" );        // 3.8.1.1 (2005/11/21)
173    
174    //                      makeFormat( intKey,linkFormat );
175                            Formatter formatter = new Formatter( table );
176                            formatter.setFormat( linkFormat );
177                            formMap.put( intKey, formatter );
178    
179                            // URLエンコード用の?設定?こ??????タをURLエンコードする?
180                            String[] format = formatter.getFormat();
181                            boolean findHref = false;
182                            for( int j=0; j<format.length; j++ ) {
183                                    if( format[j] != null && format[j].indexOf( "href" ) >= 0 ) { findHref = true; }
184                                    if( findHref && format[j].indexOf( '?' ) >= 0   ) { encodeIn[intKey]  = j; }
185                                    if( findHref && format[j].indexOf( "\" " ) >= 0 ) { encodeOut[intKey] = j; findHref = false; }
186                            }
187    
188                            // 4.3.7.1 (2009/06/08)
189                            useURLCheck[intKey] = StringUtil.nval( attri.get( "useURLCheck" ), false );
190                            urlCheckUser[intKey] = StringUtil.nval( attri.get( "urlCheckUser" ), null );
191                            urlCheckTime[intKey] = StringUtil.nval( attri.get( "urlCheckTime" ), 0L );
192                            
193                            extToken[intKey] = StringUtil.nval( attri.get("extToken"),null); // 5.8.2.1 (2014/12/14)
194    
195                            makeOnLinkFormat( intKey,attri );
196                    }
197            }
198    
199            /**
200             * ??行?に対するマ?カー??を返します?
201             * こ?値は,すでにマ?カー??処?れて?為, RendererValue で
202             * 変換する??ありません?
203             * 引数の value はそ?カラ??値として利用されます?こ?値は、修飾済みの
204             * 値を与えることが可能です?
205             *
206             * @og.rev 2.1.0.3 (2002/11/08) エンコード?開?終?ドレスを求める???修正
207             * @og.rev 3.0.0.0 (2002/12/25) URLEncoder.encode ?StringUtil#urlEncode に置換え
208             * @og.rev 3.0.0.1 (2003/02/14) リンクの引数部?、RendererValue が適用される?を修正
209             * @og.rev 3.0.0.1 (2003/02/14) リンクの引数部?、RendererValue が適用される?を修正
210             * @og.rev 3.5.6.1 (2004/06/25) formMap属?を使用します?
211             * @og.rev 3.7.0.3 (2005/03/01) "{I}" ??に、行番号(row)を割り当てます?
212             * @og.rev 3.8.5.0 (2006/03/20) "{I}" ?"%7BI%7D" として、行番号(row)を割り当てます?
213             * @og.rev 4.3.7.1 (2009/06/08) URLチェ?機?追?
214             * @og.rev 4.3.7.4 (2009/07/01) 循環参?を解?
215             * @og.rev 5.2.3.0 (2010/12/01) URLのハッシュ?暗号化を行います?
216             * @og.rev 5.8.2.1 (2014/12/13) ト?クンプラグイン対?
217             *
218             * @param   row ???
219             * @param   clm ???
220             * @param   value カラ??値
221             *
222             * @return  row行,colum?のマ?カー??
223             */
224            public String getMarkerString( final int row,final int clm,final String value ) {
225                    int intKey = isOnLink(row,clm) ;
226                    if( intKey < 0 ) { return value; }
227    
228                    Formatter formatter = formMap.get( intKey );
229                    int[]    clmNo  = formatter.getClmNos();
230                    String[] format = formatter.getFormat();
231    
232    //              int[] clmNo = formMap_c.get( intKey );
233    //              String[] format = formMap_f.get( intKey );
234    
235                    StringBuilder strLink = new StringBuilder( HybsSystem.BUFFER_LARGE );
236                    int j=0;
237                    String val ;
238                    for( ; j<clmNo.length; j++ ) {
239                            strLink.append( format[j] );
240                            if( encodeIn[intKey] <= j && j < encodeOut[intKey] ) {
241    //                              val = table.getValue(row,clmNo[j]);
242                                    val = formatter.getValue(row,clmNo[j]);
243                                    strLink.append( StringUtil.urlEncode( val ) );
244                            }
245                            else if( clm == clmNo[j] ) {
246                                    strLink.append( value );
247                            }
248                            else {
249    //                              val = table.getValue(row,clmNo[j]);
250                                    val = formatter.getValue(row,clmNo[j]);
251                                    strLink.append( val );
252                            }
253                    }
254                    strLink.append( format[j] );
255    
256                    // 3.8.5.0 (2006/03/27) "{I}" と そ?エンコード文?"%7BI%7D" に、行番号(row)を割り当てます?
257                    String rtn = strLink.toString();
258                    String sRow = String.valueOf( row );
259                    rtn = StringUtil.replace( rtn,"{I}",sRow );
260                    rtn = StringUtil.replace( rtn,"%7BI%7D",sRow );
261    
262                    // 4.3.7.1 (2009/06/08)
263                    if( useURLCheck[intKey] ) {
264                            // 4.3.7.4 (2009/07/01)
265                            rtn = XHTMLTag.embedURLCheckKey( rtn, HybsSystem.URL_CHECK_KEY, urlCheckUser[intKey], urlCheckTime[intKey] );
266                    }
267                    
268                    // 5.8.2.1 (2014/12/13) ト?クンプラグイン対?
269                    if( extToken[intKey] != null && extToken[intKey].length() > 0 ){
270                            String[] tokens = StringUtil.csv2Array( extToken[intKey] );
271                            for( String tk :tokens ){
272                                    String cls = HybsSystem.sys( "CreateToken_" + tk ) ;    
273                                    CreateToken ct = (CreateToken)HybsSystem.newInstance( cls );
274                                    rtn = ct.embedToken( rtn, urlCheckTime[intKey], null );
275                            }
276                    }
277                    
278                    
279    
280                    // 5.2.3.0 (2010/12/01) URLのハッシュ?暗号?
281                    if( ACCS_LVL == 2 ) {
282                            // ACCS_LVL == 2 の場合?、外部のみ処?る?で、extOnly=true をセ?する?
283                            rtn = URLHashMap.makeUrlChange( rtn,REQ_KEY,true );
284                    }
285                    else if( ACCS_LVL == 3 ) {
286                            rtn = URLHashMap.makeUrlChange( rtn,REQ_KEY,false );
287                    }
288    
289                    return rtn ;
290            }
291    
292            /**
293             * リンクフォーマットを作?します?
294             *
295             * @og.rev 2.1.0.3 (2002/11/08) エンコード?開?終?ドレスを求める???修正
296             * @og.rev 3.5.6.1 (2004/06/25) formMap属?を使用します?
297             *
298             * @param       intKey  カラ?ーの番号
299             * @param       fmt     フォーマット文字?
300             */
301    //      private void makeFormat( final int intKey,final String fmt ) {
302    //              boolean findHref = false;
303    //
304    //              StringTokenizer token = new StringTokenizer( fmt,"[]" );
305    //              int count = token.countTokens() / 2 ;
306    //              int[] clmNo = new int[ count ];
307    //              String[] format      = new String[ count+1 ];
308    //              for( int j=0; j<count; j++ ) {
309    //                      format[j] = token.nextToken();
310    //                      clmNo[j]  = table.getColumnNo( token.nextToken() );
311    //
312    //                      // URLエンコード用の?設定?こ??????タをURLエンコードする?
313    //                      if( format[j] != null && format[j].indexOf( "href" ) >= 0 ) { findHref = true; }
314    //                      if( findHref && format[j].indexOf( '?' ) >= 0   ) { encodeIn[intKey]  = j; }
315    //                      if( findHref && format[j].indexOf( "\" " ) >= 0 ) { encodeOut[intKey] = j; findHref = false; }
316    //              }
317    //              format[count] = token.nextToken();
318    //              formMap_c.put( intKey, clmNo );
319    //              formMap_f.put( intKey, format );
320    //
321    //              if( format[count] != null && format[count].indexOf( "href" ) >= 0 ) { findHref = true; }
322    //              if( findHref && format[count].indexOf( '?' ) >= 0 )   { encodeIn[intKey]  = count; }
323    //              if( findHref && format[count].indexOf( "\" " ) >= 0 ) { encodeOut[intKey] = count; }
324    //      }
325    
326            /**
327             * リンクを張?張らな???カラ?号を求めます?
328             * また?int[列番号] isMark を?期化します?
329             *
330             * @og.rev 3.5.2.0 (2003/10/20) markLists,markListNo,markKey属?を追?
331             *
332             * @param       intKey  カラ?ーの番号
333             * @param       attri   アトリビュー?
334             */
335            private void makeOnLinkFormat( final int intKey,final Attributes attri ) {
336                    String onMark   = attri.get( "onLink" );
337                    String markList = attri.get( "markList" );
338    
339                    // 3.5.6.0 (2004/06/18) nullポインタの参?外しバグの対?
340                    // こ?ロジ?で値が設定済みであれば、以下?処??不要である?
341                    isMark[intKey] = MARK_NULL;
342                    if( onMark == null || onMark.length() == 0 ||
343                            markList == null || markList.length() == 0 ) {
344                                    isMark[intKey] = MARK_FALSE;
345                                    return ;        // 3.5.6.0 (2004/06/18)
346                    }
347                    else if( onMark.charAt( 0 ) != '[' && markList.charAt( 0 ) != '[' ) {
348                            isMark[intKey] = ( markList.indexOf( onMark ) >= 0 ) ? MARK_TRUE : MARK_FALSE;
349                            return ;        // 3.5.6.0 (2004/06/18)
350                    }
351    
352                    if( onMark.charAt( 0 ) == '[' ) {
353                            markCmlNo[intKey] = table.getColumnNo( onMark.substring( 1,onMark.length()-1 ));
354                    }
355                    else {
356                            markCmlNo[intKey]  = -1;
357                            markKey[intKey]    = onMark ;
358                    }
359    
360                    if( markList.charAt( 0 ) == '[' ) {
361                            markListNo[intKey] = table.getColumnNo( markList.substring( 1,markList.length()-1 ));
362                    }
363                    else {
364                            markListNo[intKey] = -1;
365                            markLists[intKey] = markList;
366                    }
367            }
368    
369            /**
370             * リンクを張るかど?を判断します?
371             * int[列番号] isMark には?未設?FALSE TRUE の状態を持っており?
372             * 列でリンクを張る状態が固定?場?例えば,onLink属?がデフォル?"true" の場?
373             * カラ?関係なく?同じ値を返すときに、使用します?
374             *
375             * @og.rev 3.5.2.0 (2003/10/20) markLists,markListNo,markKey属?を追?
376             * @og.rev 3.5.4.0 (2003/11/25) onMark ,markList ?null(また?ゼロストリング)の場合?、false とする?
377             * @og.rev 4.0.0.0 (2005/08/31) 同?ラ???登録を許可します?
378             *
379             * @param       row     列番号
380             * @param       clm     カラ?ーの名称
381             *
382             * @return      処?るリスト番号?1 の場合?、該当な?
383             */
384            private int isOnLink( final int row,final int clm ) {
385    
386                    List<Integer> list = clmMap.get( clm );
387                    if( list == null ) { return -1; }
388    
389                    for( int i=0; i<list.size(); i++ ) {
390                            int intKey = list.get( i );
391                            if( isMark[intKey] != MARK_NULL ) {
392                                    if( isMark[intKey] == MARK_TRUE ) { return intKey; }
393                                    else { continue; }
394                            }
395    
396                            String onMark ;
397                            if( markCmlNo[intKey] < 0 ) { onMark = markKey[intKey] ; }
398                            else { onMark = table.getValue( row,markCmlNo[intKey] ); }
399    
400                            // 3.5.4.0 (2003/11/25) 追?
401                            if( onMark == null || onMark.length() == 0 ) { continue; }
402    
403                            String markList ;
404                            if( markListNo[intKey] < 0 ) { markList = markLists[intKey] ; }
405                            else { markList = table.getValue( row,markListNo[intKey] ); }
406    
407                            // 3.5.4.0 (2003/11/25) 修正
408                            if( markList == null || markList.length() == 0 ) { continue; }
409    
410                            if( markList.indexOf( onMark ) >= 0 ) { return intKey; }
411                    }
412                    return -1;
413            }
414            
415            /**
416             * マ?カーされたカラ?号の配?を返します?
417             *
418             * これは特殊??、Edit機?で、カラ??をキャ?ュして?ときに?
419             * JSPのソース等?変更時に、変更が反?れな?応を行う場合?
420             * 通常の ViewFormのサブクラスから、Edit専用の ViewForm_HTMLSeqClmTable で
421             * 制御する場合?ViewMarkerのEditMarkerでは??常非表示?検索の場合)ですが
422             * Editのポップア??画面に、表示されてしま??を避けるため、noDisplay に
423             * 強制?するカラ?号が?です?
424             * あくまで、暫定?置です?Edit機?を改修するときに、この機?は削除します?
425             *
426             * ※ こ?処??、EditMarkerでのみ有効にします?
427             *
428             * @og.rev 5.8.6.0 (2015/04/03) 6.0.3.0の移?
429             *
430             * @return  マ?カーされたカラ?号の配?(常に?さ0?配?を返す)
431             */
432            public int[] getColumnNos() {
433                    return new int[0];
434            }
435    }