001    /**
002     * Copyright (c) 2000-present 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 aQute.bnd.annotation.ProviderType;
018    
019    import com.liferay.portal.kernel.cache.key.CacheKeyGenerator;
020    import com.liferay.portal.kernel.cache.key.CacheKeyGeneratorUtil;
021    import com.liferay.portal.kernel.dao.shard.ShardUtil;
022    import com.liferay.portal.kernel.util.StringBundler;
023    import com.liferay.portal.kernel.util.StringPool;
024    import com.liferay.portal.kernel.util.StringUtil;
025    import com.liferay.portal.model.BaseModel;
026    
027    import java.io.Serializable;
028    
029    /**
030     * @author Brian Wing Shun Chan
031     * @author Shuyang Zhou
032     */
033    @ProviderType
034    public class FinderPath {
035    
036            public FinderPath(
037                    boolean entityCacheEnabled, boolean finderCacheEnabled,
038                    Class<?> resultClass, String cacheName, String methodName,
039                    String[] params) {
040    
041                    this(
042                            entityCacheEnabled, finderCacheEnabled, resultClass, cacheName,
043                            methodName, params, -1);
044            }
045    
046            public FinderPath(
047                    boolean entityCacheEnabled, boolean finderCacheEnabled,
048                    Class<?> resultClass, String cacheName, String methodName,
049                    String[] params, long columnBitmask) {
050    
051                    _entityCacheEnabled = entityCacheEnabled;
052                    _finderCacheEnabled = finderCacheEnabled;
053                    _resultClass = resultClass;
054                    _cacheName = cacheName;
055                    _columnBitmask = columnBitmask;
056    
057                    if (BaseModel.class.isAssignableFrom(_resultClass)) {
058                            _cacheKeyGeneratorCacheName =
059                                    FinderCache.class.getName() + "#BaseModel";
060                    }
061                    else {
062                            _cacheKeyGeneratorCacheName = FinderCache.class.getName();
063                    }
064    
065                    CacheKeyGenerator cacheKeyGenerator =
066                            CacheKeyGeneratorUtil.getCacheKeyGenerator(
067                                    _cacheKeyGeneratorCacheName);
068    
069                    if (cacheKeyGenerator.isCallingGetCacheKeyThreadSafe()) {
070                            _cacheKeyGenerator = cacheKeyGenerator;
071                    }
072                    else {
073                            _cacheKeyGenerator = null;
074                    }
075    
076                    _initCacheKeyPrefix(methodName, params);
077                    _initLocalCacheKeyPrefix();
078            }
079    
080            public Serializable encodeCacheKey(Object[] arguments) {
081                    StringBundler sb = null;
082    
083                    if (ShardUtil.isEnabled()) {
084                            sb = new StringBundler(arguments.length * 2 + 3);
085    
086                            sb.append(ShardUtil.getCurrentShardName());
087                            sb.append(StringPool.PERIOD);
088                    }
089                    else {
090                            sb = new StringBundler(arguments.length * 2 + 1);
091                    }
092    
093                    sb.append(_cacheKeyPrefix);
094    
095                    for (Object arg : arguments) {
096                            sb.append(StringPool.PERIOD);
097                            sb.append(StringUtil.toHexString(arg));
098                    }
099    
100                    return _getCacheKey(sb);
101            }
102    
103            public Serializable encodeLocalCacheKey(Object[] arguments) {
104                    StringBundler sb = null;
105    
106                    if (ShardUtil.isEnabled()) {
107                            sb = new StringBundler(arguments.length * 2 + 3);
108    
109                            sb.append(ShardUtil.getCurrentShardName());
110                            sb.append(StringPool.PERIOD);
111                    }
112                    else {
113                            sb = new StringBundler(arguments.length * 2 + 1);
114                    }
115    
116                    sb.append(_localCacheKeyPrefix);
117    
118                    for (Object arg : arguments) {
119                            sb.append(StringPool.PERIOD);
120                            sb.append(StringUtil.toHexString(arg));
121                    }
122    
123                    return _getCacheKey(sb);
124            }
125    
126            public String getCacheName() {
127                    return _cacheName;
128            }
129    
130            public long getColumnBitmask() {
131                    return _columnBitmask;
132            }
133    
134            public Class<?> getResultClass() {
135                    return _resultClass;
136            }
137    
138            public boolean isEntityCacheEnabled() {
139                    return _entityCacheEnabled;
140            }
141    
142            public boolean isFinderCacheEnabled() {
143                    return _finderCacheEnabled;
144            }
145    
146            private Serializable _getCacheKey(StringBundler sb) {
147                    CacheKeyGenerator cacheKeyGenerator = _cacheKeyGenerator;
148    
149                    if (cacheKeyGenerator == null) {
150                            cacheKeyGenerator = CacheKeyGeneratorUtil.getCacheKeyGenerator(
151                                    _cacheKeyGeneratorCacheName);
152                    }
153    
154                    return cacheKeyGenerator.getCacheKey(sb);
155            }
156    
157            private void _initCacheKeyPrefix(String methodName, String[] params) {
158                    StringBundler sb = new StringBundler(params.length * 2 + 3);
159    
160                    sb.append(methodName);
161                    sb.append(_PARAMS_SEPARATOR);
162    
163                    for (String param : params) {
164                            sb.append(StringPool.PERIOD);
165                            sb.append(param);
166                    }
167    
168                    sb.append(_ARGS_SEPARATOR);
169    
170                    _cacheKeyPrefix = sb.toString();
171            }
172    
173            private void _initLocalCacheKeyPrefix() {
174                    _localCacheKeyPrefix = _cacheName.concat(StringPool.PERIOD).concat(
175                            _cacheKeyPrefix);
176            }
177    
178            private static final String _ARGS_SEPARATOR = "_A_";
179    
180            private static final String _PARAMS_SEPARATOR = "_P_";
181    
182            private final CacheKeyGenerator _cacheKeyGenerator;
183            private final String _cacheKeyGeneratorCacheName;
184            private String _cacheKeyPrefix;
185            private final String _cacheName;
186            private final long _columnBitmask;
187            private final boolean _entityCacheEnabled;
188            private final boolean _finderCacheEnabled;
189            private String _localCacheKeyPrefix;
190            private final Class<?> _resultClass;
191    
192    }