1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * The contents of this file are subject to the terms of the Liferay Enterprise
5    * Subscription License ("License"). You may not use this file except in
6    * compliance with the License. You can obtain a copy of the License by
7    * contacting Liferay, Inc. See the License for the specific language governing
8    * permissions and limitations under the License, including but not limited to
9    * distribution rights of the Software.
10   *
11   *
12   *
13   */
14  
15  package com.liferay.portal.cache.key;
16  
17  import com.liferay.portal.kernel.cache.key.CacheKeyGenerator;
18  import com.liferay.portal.kernel.log.Log;
19  import com.liferay.portal.kernel.log.LogFactoryUtil;
20  import com.liferay.portal.kernel.nio.charset.CharsetEncoderUtil;
21  import com.liferay.portal.kernel.util.StringBundler;
22  import com.liferay.portal.kernel.util.StringPool;
23  
24  import java.nio.CharBuffer;
25  import java.nio.charset.CharsetEncoder;
26  
27  import java.security.MessageDigest;
28  import java.security.NoSuchAlgorithmException;
29  
30  /**
31   * <a href="JavaMD5CacheKeyGenerator.java.html"><b><i>View Source</i></b></a>
32   *
33   * @author Michael C. Han
34   * @author Shuyang Zhou
35   */
36  public class JavaMD5CacheKeyGenerator extends BaseCacheKeyGenerator {
37  
38      public JavaMD5CacheKeyGenerator() throws NoSuchAlgorithmException {
39          this(-1);
40      }
41  
42      public JavaMD5CacheKeyGenerator(int maxLength)
43          throws NoSuchAlgorithmException {
44  
45          _maxLength = maxLength;
46          _messageDigest = MessageDigest.getInstance(_ALGORITHM_MD5);
47          _charsetEncoder = CharsetEncoderUtil.getCharsetEncoder(StringPool.UTF8);
48      }
49  
50      public CacheKeyGenerator clone() {
51          try {
52              return new JavaMD5CacheKeyGenerator(_maxLength);
53          }
54          catch (NoSuchAlgorithmException nsae) {
55              throw new IllegalStateException(nsae.getMessage(), nsae);
56          }
57      }
58  
59      public String getCacheKey(String key) {
60          if ((_maxLength > -1) && (key.length() < _maxLength)) {
61              return key;
62          }
63  
64          try {
65              _messageDigest.update(_charsetEncoder.encode(CharBuffer.wrap(key)));
66  
67              byte[] bytes = _messageDigest.digest();
68  
69              return encodeCacheKey(bytes);
70          }
71          catch (Exception e) {
72              _log.error(e, e);
73  
74              return key;
75          }
76      }
77  
78      public String getCacheKey(String[] keys) {
79          return getCacheKey(new StringBundler(keys));
80      }
81  
82      public String getCacheKey(StringBundler sb) {
83          if ((_maxLength > -1) && (sb.length() < _maxLength)) {
84              return sb.toString();
85          }
86  
87          try {
88              for (int i = 0; i < sb.index(); i++) {
89                  String key = sb.stringAt(i);
90  
91                  _messageDigest.update(
92                      _charsetEncoder.encode(CharBuffer.wrap(key)));
93              }
94  
95              byte[] bytes = _messageDigest.digest();
96  
97              return encodeCacheKey(bytes);
98          }
99          catch (Exception e) {
100             _log.error(e, e);
101 
102             return sb.toString();
103         }
104     }
105 
106     public void setMaxLength(int maxLength) {
107         _maxLength = maxLength;
108     }
109 
110     protected String encodeCacheKey(byte[] bytes) {
111         for (int i = 0; i < bytes.length; i++) {
112             int value = bytes[i] & 0xff;
113 
114             _encodeBuffer[i * 2] = _HEX_CHARACTERS[value >> 4];
115             _encodeBuffer[i * 2 + 1] = _HEX_CHARACTERS[value & 0xf];
116         }
117 
118         return new String(_encodeBuffer);
119     }
120 
121     private static final String _ALGORITHM_MD5 = "MD5";
122 
123     private static final char[] _HEX_CHARACTERS = {
124         '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd',
125         'e', 'f'
126     };
127 
128     private static Log _log = LogFactoryUtil.getLog(
129         JavaMD5CacheKeyGenerator.class);
130 
131     private CharsetEncoder _charsetEncoder;
132     private char[] _encodeBuffer = new char[32];
133     private int _maxLength = -1;
134     private MessageDigest _messageDigest;
135 
136 }