001
014
015 package com.liferay.portal.cache.key;
016
017 import com.liferay.portal.kernel.cache.key.CacheKeyGenerator;
018 import com.liferay.portal.kernel.log.Log;
019 import com.liferay.portal.kernel.log.LogFactoryUtil;
020 import com.liferay.portal.kernel.nio.charset.CharsetEncoderUtil;
021 import com.liferay.portal.kernel.util.StringBundler;
022 import com.liferay.portal.kernel.util.StringPool;
023
024 import java.nio.CharBuffer;
025 import java.nio.charset.CharsetEncoder;
026
027 import java.security.MessageDigest;
028 import java.security.NoSuchAlgorithmException;
029
030
034 public class JavaMD5CacheKeyGenerator extends BaseCacheKeyGenerator {
035
036 public JavaMD5CacheKeyGenerator() throws NoSuchAlgorithmException {
037 this(-1);
038 }
039
040 public JavaMD5CacheKeyGenerator(int maxLength)
041 throws NoSuchAlgorithmException {
042
043 _maxLength = maxLength;
044 _messageDigest = MessageDigest.getInstance(_ALGORITHM_MD5);
045 _charsetEncoder = CharsetEncoderUtil.getCharsetEncoder(StringPool.UTF8);
046 }
047
048 @Override
049 public CacheKeyGenerator clone() {
050 try {
051 return new JavaMD5CacheKeyGenerator(_maxLength);
052 }
053 catch (NoSuchAlgorithmException nsae) {
054 throw new IllegalStateException(nsae.getMessage(), nsae);
055 }
056 }
057
058 @Override
059 public String getCacheKey(String key) {
060 if ((_maxLength > -1) && (key.length() < _maxLength)) {
061 return key;
062 }
063
064 try {
065 _messageDigest.update(_charsetEncoder.encode(CharBuffer.wrap(key)));
066
067 byte[] bytes = _messageDigest.digest();
068
069 return encodeCacheKey(bytes);
070 }
071 catch (Exception e) {
072 _log.error(e, e);
073
074 return key;
075 }
076 }
077
078 @Override
079 public String getCacheKey(String[] keys) {
080 return getCacheKey(new StringBundler(keys));
081 }
082
083 @Override
084 public String getCacheKey(StringBundler sb) {
085 if ((_maxLength > -1) && (sb.length() < _maxLength)) {
086 return sb.toString();
087 }
088
089 try {
090 for (int i = 0; i < sb.index(); i++) {
091 String key = sb.stringAt(i);
092
093 _messageDigest.update(
094 _charsetEncoder.encode(CharBuffer.wrap(key)));
095 }
096
097 byte[] bytes = _messageDigest.digest();
098
099 return encodeCacheKey(bytes);
100 }
101 catch (Exception e) {
102 _log.error(e, e);
103
104 return sb.toString();
105 }
106 }
107
108 @Override
109 public boolean isCallingGetCacheKeyThreadSafe() {
110 return _CALLING_GET_CACHE_KEY_THREAD_SAFE;
111 }
112
113 public void setMaxLength(int maxLength) {
114 _maxLength = maxLength;
115 }
116
117 protected String encodeCacheKey(byte[] bytes) {
118 for (int i = 0; i < bytes.length; i++) {
119 int value = bytes[i] & 0xff;
120
121 _encodeBuffer[i * 2] = _HEX_CHARACTERS[value >> 4];
122 _encodeBuffer[i * 2 + 1] = _HEX_CHARACTERS[value & 0xf];
123 }
124
125 return new String(_encodeBuffer);
126 }
127
128 private static final String _ALGORITHM_MD5 = "MD5";
129
130 private static final boolean _CALLING_GET_CACHE_KEY_THREAD_SAFE = false;
131
132 private static final char[] _HEX_CHARACTERS = {
133 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd',
134 'e', 'f'
135 };
136
137 private static Log _log = LogFactoryUtil.getLog(
138 JavaMD5CacheKeyGenerator.class);
139
140 private CharsetEncoder _charsetEncoder;
141 private char[] _encodeBuffer = new char[32];
142 private int _maxLength = -1;
143 private MessageDigest _messageDigest;
144
145 }