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.fukurou.security;
017    
018    
019    import java.util.Map;
020    import java.util.WeakHashMap;
021    import java.util.HashMap;
022    
023    /**
024     * URLHashMap は、セキュリ?強化?為の Hybs独自の暗号化クラスです?
025     *
026     * こ?クラスは、暗号化キーを受け取り?それに基づ?暗号?復号化を行います?
027     * ここでの暗号化?、秘?ー方式でバイト文字?に変換されたものを??6?アスキー?に
028     * 直して、扱って?す?よって、暗号?復号化?に、文字?として扱?とが可能です?
029     *
030     * @og.rev 5.2.2.0 (2010/11/01) 新規追?
031     * @og.group ライセンス管?
032     *
033     * @version  5.2.2.0 (2010/11/01)
034     * @author   Kazuhiko Hasegawa
035     * @since    JDK1.6,
036     */
037    public final class URLHashMap {
038            private static final int SIZE = 6000;
039            private static final Map<String,String> urlMap1 = new HashMap<String,String>( SIZE*4/3 );           // 現役世代1
040            private static       Map<String,String> urlMap2 = new HashMap<String,String>( SIZE*4/3 );           // 現役世代2
041            private static final Map<String,String> urlMap3 = new WeakHashMap<String,String>( SIZE*4/3 );       // 旧世代
042            private static final Object lock = new Object();
043    
044            /**
045             * ?ォルトコンストラクター
046             * これは、すべてstatic メソ?で構?されて?クラスなので、直接インスタンスの生?を禁止します?
047             *
048             * @og.rev 5.3.0.0 (2010/12/01) 新規追?
049             */
050            private URLHashMap() {
051                    // 直接インスタンスの生?を禁止
052            }
053    
054            /**
055             * URL をハ?ュ?暗号化して返します?
056             * 共通??簡易化するための、便利メソ?です?
057             * ここでのハッシュ?暗号化?、URLのパラメータ(?以降?部?のみ行います?
058             * また?ここで渡す文字?は、URLを含?字?なので、href のキーワードを
059             * 手がかりに? を探して、その部??み、変換します?
060             * href を含まな??合?、それ?体が URL と判断して? を探します?
061             * ? が存在しな?ースは、url をそのまま返します?
062             *
063             * URLのアドレスが?"/" から始まる?合?、?身のアドレスと判断し?ハッシュ処?行います?
064             * そうでな???http:// ?../ の場?は、暗号化??行います?
065             * 第?引数は、ハ?ュ?暗号化されたパラメータを指定するキーになります?(標準?、h_r)
066             * 処?選択します?
067             * href を含まず?'?' ?を含??合???' 以降を暗号化します?
068             *
069             * ハッシュの場合?こ?キーを?に、設定?を?部キャ?ュ(Map)に設定します?
070             * Map は?世代持っており、?部キャ?ュ(SIZE=6000)を?ると?世代目に移行し?
071             * さらに、?ると?世代目に移行します??世代目は、WeakHashMap を利用して?
072             * ため、?合によっては??タがなくなり?アクセス不?になって?可能性があります?
073             *
074             * @param       url     オリジナルのURL また?、URL を含?字?
075             * @param       hkey    パラメータのキーとして使用する??
076             * @param       extOnly 外部URLの場合?み処?実行する??true
077             *
078             * @return      変換されたURL を含?字?
079             */
080            public static String makeUrlChange( final String url , final String hkey , final boolean extOnly ) {
081                    if( url == null || hkey == null ) { return null; }
082                    // 外部のみ(extOnly=true)で、かつ、?部URLの形式?場合?引数そ?ままを返します?
083                    if( extOnly && url.indexOf( "href=\"/" ) >= 0 ) { return url; }
084    
085                    String rtnUrl = url;
086    
087                    int idx1 = url.indexOf( "href=\"" );
088                    int idx2 = url.indexOf( '?', idx1 );            // href??? がな?(idx1 == -1)でも正常に動作する?
089                    if( idx2 >= 0 ) {
090                            String url1 = url.substring( 0,idx2+1 );                // ??から '?' まで(?を含?
091                            int idx3 = url.indexOf( "\"",idx2+1 );
092                            if( idx3 >= 0 ) {
093                                    String url2 = url.substring( idx2+1,idx3 );             // 純粋なパラメータ部?
094                                    String url3 = url.substring( idx3 );                    // ?ルクオー?含?以?
095                                    // href="/ かど?。文字?の有効長があるかど?を?にチェ?して??
096                                    if( idx1 >= 0 && url.length() > idx1+7 && url.charAt( idx1+7 ) == '/' ) {
097                                            url2 = makeHashKey( url2 );
098                                    }
099                                    else {
100                                            url2 = makeEncrypt( url2 );
101                                    }
102                                    rtnUrl = url1 + hkey + "=" + url2 + url3 ;
103                            }
104                            // '?' はあるが????ルクオートがな??合???' から後ろすべてを暗号化する?
105                            else {
106                                    String url2 = url.substring( idx2+1 );          // ?以降?部?
107                                    rtnUrl = url1 + hkey + "=" + makeEncrypt( url2 ) ;
108                            }
109                    }
110    
111                    return rtnUrl;
112            }
113    
114            /**
115             * 引数の設定?をハ?ュ化したとき?値(?ハ?ュキー)を作?します?
116             * ??、このハッシュキーを?に、設定?を?部キャ?ュ(Map)に設定します?
117             * こ?Mapは、WeakHashMap を利用して?ため、?合によっては??タがなくなり?
118             * アクセス不?になって?可能性があります?
119             *
120             * @param       val     オリジナルの設定?
121             *
122             * @return      ハッシュキー
123             */
124            public static String makeHashKey( final String val ) {
125                    if( val == null ) { return ""; }
126    
127                    // ??最後に "X" を付けることで、ハ?ュ処?れたことを示す?
128                    String key = HybsCryptography.getMD5( val ) + "X";
129                    synchronized( lock ) {
130                            urlMap1.put( key,val );
131                    }
132                    return key;
133            }
134    
135            /**
136             * 引数の設定?を暗号化したとき?値を作?します?
137             * 暗号化なので、ハ?ュ化?時?用に、?部キャ?ュ(Map)に設定しません?
138             * 処?間等を??すると、外部URLの暗号化や?期にわたるURL(?、シス?の
139             * 外部にURLを渡す:例えば、メールでリンク先を送信するなど)の作?に使用します?
140             *
141             * @param       val     オリジナルの設定?
142             *
143             * @return      暗号化キー
144             */
145            public static String makeEncrypt( final String val ) {
146                    if( val == null ) { return ""; }
147    
148                    // ??最後に "Y" を付けることで、暗号化??れたことを示す?
149                    HybsCryptography crypt = new HybsCryptography();
150                    return crypt.encrypt( val ) + "Y";
151            }
152    
153            /**
154             * ??キーに対応した設定?を取り?します?
155             * ここでは、ハ?ュ?また? 暗号化されて?キーに対して?
156             * ハッシュキーであれば?連付けられた設定?を取り?し?暗号化キーで
157             * あれば、復号化??行います?
158             *
159             * @param       key     ハッシュ?暗号化されたキー
160             *
161             * @return      オリジナルの設定?
162             */
163            public static String getValue( final String key ) {
164                    if( key == null || key.isEmpty() ) { return null; }
165    
166                    String rtn = null;
167    
168                    char ch = key.charAt( key.length()-1 );
169                    if( ch == 'X' ) {
170                            synchronized( lock ) {
171                                    rtn = urlMap1.get( key );
172                                    if( rtn == null ) { rtn = urlMap2.get( key ); }
173                                    if( rtn == null ) { rtn = urlMap3.get( key ); }
174    
175                                    // ハッシュを作?するより取得する方が?度が少な??
176                                    if( urlMap1.size() > SIZE ) {
177                                            urlMap3.putAll( urlMap2 );
178                                            urlMap2 = new HashMap<String,String>( urlMap1 );
179                                            urlMap1.clear();
180                                    }
181                            }
182                    }
183                    else if( ch == 'Y' ) {
184                            HybsCryptography crypt = new HybsCryptography();
185                            rtn = crypt.decrypt( key.substring( 0,key.length()-1 ) );
186                    }
187    
188                    return rtn ;
189            }
190    }