001
014
015 package com.liferay.portal.kernel.dao.orm;
016
017 import com.liferay.portal.kernel.exception.PortalException;
018 import com.liferay.portal.kernel.exception.SystemException;
019 import com.liferay.portal.kernel.search.Document;
020 import com.liferay.portal.kernel.search.Indexer;
021 import com.liferay.portal.kernel.search.SearchEngineUtil;
022 import com.liferay.portal.service.BaseLocalService;
023
024 import java.lang.reflect.InvocationTargetException;
025 import java.lang.reflect.Method;
026
027 import java.util.ArrayList;
028 import java.util.Collection;
029 import java.util.List;
030
031
034 public abstract class BaseActionableDynamicQuery
035 implements ActionableDynamicQuery {
036
037 @Override
038 public void performActions() throws PortalException, SystemException {
039 long count = doPerformCount();
040
041 if (count > _interval) {
042 performActionsInMultipleIntervals();
043 }
044 else {
045 performActionsInSingleInterval();
046 }
047 }
048
049 public void performActions(long startPrimaryKey, long endPrimaryKey)
050 throws PortalException, SystemException {
051
052 DynamicQuery dynamicQuery = DynamicQueryFactoryUtil.forClass(
053 _clazz, _classLoader);
054
055 Property property = PropertyFactoryUtil.forName(
056 _primaryKeyPropertyName);
057
058 dynamicQuery.add(property.ge(startPrimaryKey));
059 dynamicQuery.add(property.lt(endPrimaryKey));
060
061 addDefaultCriteria(dynamicQuery);
062
063 addCriteria(dynamicQuery);
064
065 List<Object> objects = (List<Object>)executeDynamicQuery(
066 _dynamicQueryMethod, dynamicQuery);
067
068 for (Object object : objects) {
069 performAction(object);
070 }
071 }
072
073 @Override
074 public long performCount() throws PortalException, SystemException {
075 return doPerformCount();
076 }
077
078 @Override
079 public void setBaseLocalService(BaseLocalService baseLocalService)
080 throws SystemException {
081
082 _baseLocalService = baseLocalService;
083
084 Class<?> clazz = _baseLocalService.getClass();
085
086 try {
087 _dynamicQueryMethod = clazz.getMethod(
088 "dynamicQuery", DynamicQuery.class);
089 _dynamicQueryCountMethod = clazz.getMethod(
090 "dynamicQueryCount", DynamicQuery.class, Projection.class);
091 }
092 catch (NoSuchMethodException nsme) {
093 throw new SystemException(nsme);
094 }
095 }
096
097 @Override
098 public void setClass(Class<?> clazz) {
099 _clazz = clazz;
100 }
101
102 @Override
103 public void setClassLoader(ClassLoader classLoader) {
104 _classLoader = classLoader;
105 }
106
107 @Override
108 public void setCompanyId(long companyId) {
109 _companyId = companyId;
110 }
111
112 @Override
113 public void setGroupId(long groupId) {
114 _groupId = groupId;
115 }
116
117 @Override
118 public void setGroupIdPropertyName(String groupIdPropertyName) {
119 _groupIdPropertyName = groupIdPropertyName;
120 }
121
122 @Override
123 public void setInterval(int interval) {
124 _interval = interval;
125 }
126
127 @Override
128 public void setPrimaryKeyPropertyName(String primaryKeyPropertyName) {
129 _primaryKeyPropertyName = primaryKeyPropertyName;
130 }
131
132 @Override
133 public void setSearchEngineId(String searchEngineId) {
134 _searchEngineId = searchEngineId;
135 }
136
137 protected void addCriteria(DynamicQuery dynamicQuery) {
138 }
139
140 protected void addDefaultCriteria(DynamicQuery dynamicQuery) {
141 if (_companyId > 0) {
142 Property property = PropertyFactoryUtil.forName("companyId");
143
144 dynamicQuery.add(property.eq(_companyId));
145 }
146
147 if (_groupId > 0) {
148 Property property = PropertyFactoryUtil.forName(
149 _groupIdPropertyName);
150
151 dynamicQuery.add(property.eq(_groupId));
152 }
153 }
154
155 protected void addDocument(Document document) throws PortalException {
156 if (_documents == null) {
157 _documents = new ArrayList<Document>();
158 }
159
160 _documents.add(document);
161
162 if (_documents.size() >= _interval) {
163 indexInterval();
164 }
165 }
166
167 protected void addDocuments(Collection<Document> documents)
168 throws PortalException {
169
170 if (_documents == null) {
171 _documents = new ArrayList<Document>();
172 }
173
174 _documents.addAll(documents);
175
176 if (_documents.size() >= _interval) {
177 indexInterval();
178 }
179 }
180
181 protected long doPerformCount() throws PortalException, SystemException {
182 DynamicQuery dynamicQuery = DynamicQueryFactoryUtil.forClass(
183 _clazz, _classLoader);
184
185 addDefaultCriteria(dynamicQuery);
186
187 addCriteria(dynamicQuery);
188
189 return (Long)executeDynamicQuery(
190 _dynamicQueryCountMethod, dynamicQuery, getCountProjection());
191 }
192
193 protected Object executeDynamicQuery(
194 Method dynamicQueryMethod, Object... arguments)
195 throws PortalException, SystemException {
196
197 try {
198 return dynamicQueryMethod.invoke(_baseLocalService, arguments);
199 }
200 catch (InvocationTargetException ite) {
201 Throwable throwable = ite.getCause();
202
203 if (throwable instanceof PortalException) {
204 throw (PortalException)throwable;
205 }
206 else if (throwable instanceof SystemException) {
207 throw (SystemException)throwable;
208 }
209
210 throw new SystemException(ite);
211 }
212 catch (Exception e) {
213 throw new SystemException(e);
214 }
215 }
216
217 protected Projection getCountProjection() {
218 return ProjectionFactoryUtil.rowCount();
219 }
220
221 protected String getSearchEngineId() {
222 return _searchEngineId;
223 }
224
225 protected void indexInterval() throws PortalException {
226 if ((_documents == null) || _documents.isEmpty()) {
227 return;
228 }
229
230 SearchEngineUtil.updateDocuments(
231 _searchEngineId, _companyId, new ArrayList<Document>(_documents));
232
233 _documents.clear();
234 }
235
236 @SuppressWarnings("unused")
237 protected void intervalCompleted(long startPrimaryKey, long endPrimaryKey)
238 throws PortalException, SystemException {
239 }
240
241 protected abstract void performAction(Object object)
242 throws PortalException, SystemException;
243
244 protected void performActionsInMultipleIntervals()
245 throws PortalException, SystemException {
246
247 DynamicQuery dynamicQuery = DynamicQueryFactoryUtil.forClass(
248 _clazz, _classLoader);
249
250 Projection minPrimaryKeyProjection = ProjectionFactoryUtil.min(
251 _primaryKeyPropertyName);
252 Projection maxPrimaryKeyProjection = ProjectionFactoryUtil.max(
253 _primaryKeyPropertyName);
254
255 ProjectionList projectionList = ProjectionFactoryUtil.projectionList();
256
257 projectionList.add(minPrimaryKeyProjection);
258 projectionList.add(maxPrimaryKeyProjection);
259
260 dynamicQuery.setProjection(projectionList);
261
262 addDefaultCriteria(dynamicQuery);
263
264 addCriteria(dynamicQuery);
265
266 List<Object[]> results = (List<Object[]>)executeDynamicQuery(
267 _dynamicQueryMethod, dynamicQuery);
268
269 Object[] minAndMaxPrimaryKeys = results.get(0);
270
271 if ((minAndMaxPrimaryKeys[0] == null) ||
272 (minAndMaxPrimaryKeys[1] == null)) {
273
274 return;
275 }
276
277 long minPrimaryKey = (Long)minAndMaxPrimaryKeys[0];
278 long maxPrimaryKey = (Long)minAndMaxPrimaryKeys[1];
279
280 long startPrimaryKey = minPrimaryKey;
281 long endPrimaryKey = startPrimaryKey + _interval;
282
283 while (startPrimaryKey <= maxPrimaryKey) {
284 performActions(startPrimaryKey, endPrimaryKey);
285
286 indexInterval();
287
288 intervalCompleted(startPrimaryKey, endPrimaryKey);
289
290 startPrimaryKey = endPrimaryKey;
291 endPrimaryKey += _interval;
292 }
293 }
294
295 protected void performActionsInSingleInterval()
296 throws PortalException, SystemException {
297
298 DynamicQuery dynamicQuery = DynamicQueryFactoryUtil.forClass(
299 _clazz, _classLoader);
300
301 addDefaultCriteria(dynamicQuery);
302
303 addCriteria(dynamicQuery);
304
305 List<Object> objects = (List<Object>)executeDynamicQuery(
306 _dynamicQueryMethod, dynamicQuery);
307
308 for (Object object : objects) {
309 performAction(object);
310 }
311
312 indexInterval();
313 }
314
315 private BaseLocalService _baseLocalService;
316 private ClassLoader _classLoader;
317 private Class<?> _clazz;
318 private long _companyId;
319 private Collection<Document> _documents;
320 private Method _dynamicQueryCountMethod;
321 private Method _dynamicQueryMethod;
322 private long _groupId;
323 private String _groupIdPropertyName = "groupId";
324 private int _interval = Indexer.DEFAULT_INTERVAL;
325 private String _primaryKeyPropertyName;
326 private String _searchEngineId;
327
328 }