001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.kernel.dao.orm;
016    
017    import com.liferay.portal.kernel.cache.key.CacheKeyGenerator;
018    import com.liferay.portal.kernel.cache.key.CacheKeyGeneratorUtil;
019    import com.liferay.portal.kernel.dao.shard.ShardUtil;
020    import com.liferay.portal.kernel.util.StringBundler;
021    import com.liferay.portal.kernel.util.StringPool;
022    import com.liferay.portal.kernel.util.StringUtil;
023    import com.liferay.portal.model.BaseModel;
024    
025    import java.io.Serializable;
026    
027    /**
028     * @author Brian Wing Shun Chan
029     * @author Shuyang Zhou
030     */
031    public class FinderPath {
032    
033            public FinderPath(
034                    boolean entityCacheEnabled, boolean finderCacheEnabled,
035                    Class<?> resultClass, String cacheName, String methodName,
036                    String[] params) {
037    
038                    this(
039                            entityCacheEnabled, finderCacheEnabled, resultClass, cacheName,
040                            methodName, params, -1);
041            }
042    
043            public FinderPath(
044                    boolean entityCacheEnabled, boolean finderCacheEnabled,
045                    Class<?> resultClass, String cacheName, String methodName,
046                    String[] params, long columnBitmask) {
047    
048                    _entityCacheEnabled = entityCacheEnabled;
049                    _finderCacheEnabled = finderCacheEnabled;
050                    _resultClass = resultClass;
051                    _cacheName = cacheName;
052                    _columnBitmask = columnBitmask;
053    
054                    if (BaseModel.class.isAssignableFrom(_resultClass)) {
055                            _cacheKeyGeneratorCacheName =
056                                    FinderCache.class.getName() + "#BaseModel";
057                    }
058                    else {
059                            _cacheKeyGeneratorCacheName = FinderCache.class.getName();
060                    }
061    
062                    CacheKeyGenerator cacheKeyGenerator =
063                            CacheKeyGeneratorUtil.getCacheKeyGenerator(
064                                    _cacheKeyGeneratorCacheName);
065    
066                    if (cacheKeyGenerator.isCallingGetCacheKeyThreadSafe()) {
067                            _cacheKeyGenerator = cacheKeyGenerator;
068                    }
069    
070                    _initCacheKeyPrefix(methodName, params);
071                    _initLocalCacheKeyPrefix();
072            }
073    
074            public Serializable encodeCacheKey(Object[] arguments) {
075                    StringBundler sb = new StringBundler(arguments.length * 2 + 3);
076    
077                    sb.append(ShardUtil.getCurrentShardName());
078                    sb.append(StringPool.PERIOD);
079                    sb.append(_cacheKeyPrefix);
080    
081                    for (Object arg : arguments) {
082                            sb.append(StringPool.PERIOD);
083                            sb.append(StringUtil.toHexString(arg));
084                    }
085    
086                    return _getCacheKey(sb);
087            }
088    
089            public Serializable encodeLocalCacheKey(Object[] arguments) {
090                    StringBundler sb = new StringBundler(arguments.length * 2 + 3);
091    
092                    sb.append(ShardUtil.getCurrentShardName());
093                    sb.append(StringPool.PERIOD);
094                    sb.append(_localCacheKeyPrefix);
095    
096                    for (Object arg : arguments) {
097                            sb.append(StringPool.PERIOD);
098                            sb.append(StringUtil.toHexString(arg));
099                    }
100    
101                    return _getCacheKey(sb);
102            }
103    
104            public String getCacheName() {
105                    return _cacheName;
106            }
107    
108            public long getColumnBitmask() {
109                    return _columnBitmask;
110            }
111    
112            public Class<?> getResultClass() {
113                    return _resultClass;
114            }
115    
116            public boolean isEntityCacheEnabled() {
117                    return _entityCacheEnabled;
118            }
119    
120            public boolean isFinderCacheEnabled() {
121                    return _finderCacheEnabled;
122            }
123    
124            public void setCacheKeyGeneratorCacheName(
125                    String cacheKeyGeneratorCacheName) {
126    
127                    if (cacheKeyGeneratorCacheName == null) {
128                            cacheKeyGeneratorCacheName = FinderCache.class.getName();
129                    }
130    
131                    _cacheKeyGeneratorCacheName = cacheKeyGeneratorCacheName;
132    
133                    CacheKeyGenerator cacheKeyGenerator =
134                            CacheKeyGeneratorUtil.getCacheKeyGenerator(
135                                    cacheKeyGeneratorCacheName);
136    
137                    if (cacheKeyGenerator.isCallingGetCacheKeyThreadSafe()) {
138                            _cacheKeyGenerator = cacheKeyGenerator;
139                    }
140                    else {
141                            _cacheKeyGenerator = null;
142                    }
143            }
144    
145            private Serializable _getCacheKey(StringBundler sb) {
146                    CacheKeyGenerator cacheKeyGenerator = _cacheKeyGenerator;
147    
148                    if (cacheKeyGenerator == null) {
149                            cacheKeyGenerator = CacheKeyGeneratorUtil.getCacheKeyGenerator(
150                                    _cacheKeyGeneratorCacheName);
151                    }
152    
153                    return cacheKeyGenerator.getCacheKey(sb);
154            }
155    
156            private void _initCacheKeyPrefix(String methodName, String[] params) {
157                    StringBundler sb = new StringBundler(params.length * 2 + 3);
158    
159                    sb.append(methodName);
160                    sb.append(_PARAMS_SEPARATOR);
161    
162                    for (String param : params) {
163                            sb.append(StringPool.PERIOD);
164                            sb.append(param);
165                    }
166    
167                    sb.append(_ARGS_SEPARATOR);
168    
169                    _cacheKeyPrefix = sb.toString();
170            }
171    
172            private void _initLocalCacheKeyPrefix() {
173                    _localCacheKeyPrefix = _cacheName.concat(StringPool.PERIOD).concat(
174                            _cacheKeyPrefix);
175            }
176    
177            private static final String _ARGS_SEPARATOR = "_A_";
178    
179            private static final String _PARAMS_SEPARATOR = "_P_";
180    
181            private CacheKeyGenerator _cacheKeyGenerator;
182            private String _cacheKeyGeneratorCacheName;
183            private String _cacheKeyPrefix;
184            private String _cacheName;
185            private long _columnBitmask;
186            private boolean _entityCacheEnabled;
187            private boolean _finderCacheEnabled;
188            private String _localCacheKeyPrefix;
189            private Class<?> _resultClass;
190    
191    }