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(
075                    boolean shardEnabled, Object[] arguments) {
076    
077                    StringBundler sb = null;
078    
079                    if (shardEnabled) {
080                            sb = new StringBundler(arguments.length * 2 + 3);
081    
082                            sb.append(ShardUtil.getCurrentShardName());
083                            sb.append(StringPool.PERIOD);
084                    }
085                    else {
086                            sb = new StringBundler(arguments.length * 2 + 1);
087                    }
088    
089                    sb.append(_cacheKeyPrefix);
090    
091                    for (Object arg : arguments) {
092                            sb.append(StringPool.PERIOD);
093                            sb.append(StringUtil.toHexString(arg));
094                    }
095    
096                    return _getCacheKey(sb);
097            }
098    
099            public Serializable encodeLocalCacheKey(
100                    boolean shardEnabled, Object[] arguments) {
101    
102                    StringBundler sb = null;
103    
104                    if (shardEnabled) {
105                            sb = new StringBundler(arguments.length * 2 + 3);
106    
107                            sb.append(ShardUtil.getCurrentShardName());
108                            sb.append(StringPool.PERIOD);
109                    }
110                    else {
111                            sb = new StringBundler(arguments.length * 2 + 1);
112                    }
113    
114                    sb.append(_localCacheKeyPrefix);
115    
116                    for (Object arg : arguments) {
117                            sb.append(StringPool.PERIOD);
118                            sb.append(StringUtil.toHexString(arg));
119                    }
120    
121                    return _getCacheKey(sb);
122            }
123    
124            public String getCacheName() {
125                    return _cacheName;
126            }
127    
128            public long getColumnBitmask() {
129                    return _columnBitmask;
130            }
131    
132            public Class<?> getResultClass() {
133                    return _resultClass;
134            }
135    
136            public boolean isEntityCacheEnabled() {
137                    return _entityCacheEnabled;
138            }
139    
140            public boolean isFinderCacheEnabled() {
141                    return _finderCacheEnabled;
142            }
143    
144            public void setCacheKeyGeneratorCacheName(
145                    String cacheKeyGeneratorCacheName) {
146    
147                    if (cacheKeyGeneratorCacheName == null) {
148                            cacheKeyGeneratorCacheName = FinderCache.class.getName();
149                    }
150    
151                    _cacheKeyGeneratorCacheName = cacheKeyGeneratorCacheName;
152    
153                    CacheKeyGenerator cacheKeyGenerator =
154                            CacheKeyGeneratorUtil.getCacheKeyGenerator(
155                                    cacheKeyGeneratorCacheName);
156    
157                    if (cacheKeyGenerator.isCallingGetCacheKeyThreadSafe()) {
158                            _cacheKeyGenerator = cacheKeyGenerator;
159                    }
160                    else {
161                            _cacheKeyGenerator = null;
162                    }
163            }
164    
165            private Serializable _getCacheKey(StringBundler sb) {
166                    CacheKeyGenerator cacheKeyGenerator = _cacheKeyGenerator;
167    
168                    if (cacheKeyGenerator == null) {
169                            cacheKeyGenerator = CacheKeyGeneratorUtil.getCacheKeyGenerator(
170                                    _cacheKeyGeneratorCacheName);
171                    }
172    
173                    return cacheKeyGenerator.getCacheKey(sb);
174            }
175    
176            private void _initCacheKeyPrefix(String methodName, String[] params) {
177                    StringBundler sb = new StringBundler(params.length * 2 + 3);
178    
179                    sb.append(methodName);
180                    sb.append(_PARAMS_SEPARATOR);
181    
182                    for (String param : params) {
183                            sb.append(StringPool.PERIOD);
184                            sb.append(param);
185                    }
186    
187                    sb.append(_ARGS_SEPARATOR);
188    
189                    _cacheKeyPrefix = sb.toString();
190            }
191    
192            private void _initLocalCacheKeyPrefix() {
193                    _localCacheKeyPrefix = _cacheName.concat(StringPool.PERIOD).concat(
194                            _cacheKeyPrefix);
195            }
196    
197            private static final String _ARGS_SEPARATOR = "_A_";
198    
199            private static final String _PARAMS_SEPARATOR = "_P_";
200    
201            private CacheKeyGenerator _cacheKeyGenerator;
202            private String _cacheKeyGeneratorCacheName;
203            private String _cacheKeyPrefix;
204            private String _cacheName;
205            private long _columnBitmask;
206            private boolean _entityCacheEnabled;
207            private boolean _finderCacheEnabled;
208            private String _localCacheKeyPrefix;
209            private Class<?> _resultClass;
210    
211    }