001
014
015 package com.liferay.portal.kernel.dao.orm;
016
017 import com.liferay.portal.kernel.concurrent.ThreadPoolExecutor;
018 import com.liferay.portal.kernel.exception.PortalException;
019 import com.liferay.portal.kernel.exception.SystemException;
020 import com.liferay.portal.kernel.executor.PortalExecutorManagerUtil;
021 import com.liferay.portal.kernel.search.Indexer;
022 import com.liferay.portal.kernel.transaction.Propagation;
023 import com.liferay.portal.kernel.transaction.TransactionAttribute;
024 import com.liferay.portal.kernel.transaction.TransactionInvokerUtil;
025 import com.liferay.portal.model.BaseModel;
026 import com.liferay.portal.service.BaseLocalService;
027
028 import java.lang.reflect.InvocationTargetException;
029 import java.lang.reflect.Method;
030
031 import java.util.ArrayList;
032 import java.util.List;
033 import java.util.concurrent.Callable;
034 import java.util.concurrent.Future;
035
036
040 public class DefaultActionableDynamicQuery implements ActionableDynamicQuery {
041
042 public static final TransactionAttribute REQUIRES_NEW_TRANSACTION_ATTRIBUTE;
043
044 static {
045 TransactionAttribute.Builder builder =
046 new TransactionAttribute.Builder();
047
048 builder.setPropagation(Propagation.REQUIRES_NEW);
049 builder.setRollbackForClasses(
050 PortalException.class, SystemException.class);
051
052 REQUIRES_NEW_TRANSACTION_ATTRIBUTE = builder.build();
053 }
054
055 @Override
056 public AddCriteriaMethod getAddCriteriaMethod() {
057 return _addCriteriaMethod;
058 }
059
060 @Override
061 public AddOrderCriteriaMethod getAddOrderCriteriaMethod() {
062 return _addOrderCriteriaMethod;
063 }
064
065 @Override
066 public PerformActionMethod<?> getPerformActionMethod() {
067 return _performActionMethod;
068 }
069
070 @Override
071 public PerformCountMethod getPerformCountMethod() {
072 return _performCountMethod;
073 }
074
075 @Override
076 public boolean isParallel() {
077 return _parallel;
078 }
079
080 @Override
081 public void performActions() throws PortalException {
082 try {
083 long previousPrimaryKey = -1;
084
085 while (true) {
086 long lastPrimaryKey = doPerformActions(previousPrimaryKey);
087
088 if (lastPrimaryKey < 0) {
089 return;
090 }
091
092 intervalCompleted(previousPrimaryKey, lastPrimaryKey);
093
094 previousPrimaryKey = lastPrimaryKey;
095 }
096 }
097 finally {
098 actionsCompleted();
099 }
100 }
101
102 @Override
103 public long performCount() throws PortalException {
104 if (_performCountMethod != null) {
105 return _performCountMethod.performCount();
106 }
107
108 DynamicQuery dynamicQuery = DynamicQueryFactoryUtil.forClass(
109 _modelClass, _classLoader);
110
111 addDefaultCriteria(dynamicQuery);
112
113 addCriteria(dynamicQuery);
114
115 return (Long)executeDynamicQuery(
116 _dynamicQueryCountMethod, dynamicQuery, getCountProjection());
117 }
118
119 @Override
120 public void setAddCriteriaMethod(AddCriteriaMethod addCriteriaMethod) {
121 _addCriteriaMethod = addCriteriaMethod;
122 }
123
124 @Override
125 public void setAddOrderCriteriaMethod(
126 AddOrderCriteriaMethod addOrderCriteriaMethod) {
127
128 _addOrderCriteriaMethod = addOrderCriteriaMethod;
129 }
130
131 @Override
132 public void setBaseLocalService(BaseLocalService baseLocalService) {
133 _baseLocalService = baseLocalService;
134
135 Class<?> clazz = _baseLocalService.getClass();
136
137 try {
138 _dynamicQueryMethod = clazz.getMethod(
139 "dynamicQuery", DynamicQuery.class);
140 _dynamicQueryCountMethod = clazz.getMethod(
141 "dynamicQueryCount", DynamicQuery.class, Projection.class);
142 }
143 catch (NoSuchMethodException nsme) {
144 throw new SystemException(nsme);
145 }
146 }
147
148
151 @Deprecated
152 @Override
153 public void setClass(Class<?> modelClass) {
154 _modelClass = modelClass;
155 }
156
157 @Override
158 public void setClassLoader(ClassLoader classLoader) {
159 _classLoader = classLoader;
160 }
161
162 @Override
163 public void setCompanyId(long companyId) {
164 _companyId = companyId;
165 }
166
167 @Override
168 public void setGroupId(long groupId) {
169 _groupId = groupId;
170 }
171
172 @Override
173 public void setGroupIdPropertyName(String groupIdPropertyName) {
174 _groupIdPropertyName = groupIdPropertyName;
175 }
176
177 @Override
178 public void setInterval(int interval) {
179 _interval = interval;
180 }
181
182 @Override
183 public void setModelClass(Class<?> modelClass) {
184 _modelClass = modelClass;
185 }
186
187 @Override
188 public void setParallel(boolean parallel) {
189 _parallel = parallel;
190 }
191
192 @Override
193 public void setPerformActionMethod(
194 PerformActionMethod<?> performActionMethod) {
195
196 _performActionMethod = performActionMethod;
197 }
198
199 @Override
200 public void setPerformCountMethod(PerformCountMethod performCountMethod) {
201 _performCountMethod = performCountMethod;
202 }
203
204 @Override
205 public void setPrimaryKeyPropertyName(String primaryKeyPropertyName) {
206 _primaryKeyPropertyName = primaryKeyPropertyName;
207 }
208
209 @Override
210 public void setTransactionAttribute(
211 TransactionAttribute transactionAttribute) {
212
213 _transactionAttribute = transactionAttribute;
214 }
215
216
219 protected void actionsCompleted() throws PortalException {
220 }
221
222 protected void addCriteria(DynamicQuery dynamicQuery) {
223 if (_addCriteriaMethod != null) {
224 _addCriteriaMethod.addCriteria(dynamicQuery);
225 }
226 }
227
228 protected void addDefaultCriteria(DynamicQuery dynamicQuery) {
229 if (_companyId > 0) {
230 Property property = PropertyFactoryUtil.forName("companyId");
231
232 dynamicQuery.add(property.eq(_companyId));
233 }
234
235 if (_groupId > 0) {
236 Property property = PropertyFactoryUtil.forName(
237 _groupIdPropertyName);
238
239 dynamicQuery.add(property.eq(_groupId));
240 }
241 }
242
243 protected void addOrderCriteria(DynamicQuery dynamicQuery) {
244 if (_addOrderCriteriaMethod != null) {
245 _addOrderCriteriaMethod.addOrderCriteria(dynamicQuery);
246 }
247 else {
248 dynamicQuery.addOrder(
249 OrderFactoryUtil.asc(_primaryKeyPropertyName));
250 }
251 }
252
253 protected long doPerformActions(long previousPrimaryKey)
254 throws PortalException {
255
256 final DynamicQuery dynamicQuery = DynamicQueryFactoryUtil.forClass(
257 _modelClass, _classLoader);
258
259 Property property = PropertyFactoryUtil.forName(
260 _primaryKeyPropertyName);
261
262 dynamicQuery.add(property.gt(previousPrimaryKey));
263
264 dynamicQuery.setLimit(0, _interval);
265
266 addDefaultCriteria(dynamicQuery);
267
268 addCriteria(dynamicQuery);
269
270 addOrderCriteria(dynamicQuery);
271
272 Callable<Long> callable = new Callable<Long>() {
273
274 @Override
275 public Long call() throws Exception {
276 List<Object> objects = (List<Object>)executeDynamicQuery(
277 _dynamicQueryMethod, dynamicQuery);
278
279 if (objects.isEmpty()) {
280 return -1L;
281 }
282
283 if (_parallel) {
284 List<Future<Void>> futures = new ArrayList<>(
285 objects.size());
286
287 for (final Object object : objects) {
288 futures.add(
289 _threadPoolExecutor.submit(
290 new Callable<Void>() {
291
292 @Override
293 public Void call() throws PortalException {
294 performAction(object);
295
296 return null;
297 }
298
299 }));
300 }
301
302 for (Future<Void> future : futures) {
303 future.get();
304 }
305 }
306 else {
307 for (Object object : objects) {
308 performAction(object);
309 }
310 }
311
312 if (objects.size() < _interval) {
313 return -1L;
314 }
315
316 BaseModel<?> baseModel = (BaseModel<?>)objects.get(
317 objects.size() - 1);
318
319 return (Long)baseModel.getPrimaryKeyObj();
320 }
321
322 };
323
324 TransactionAttribute transactionAttribute = getTransactionAttribute();
325
326 try {
327 if (transactionAttribute == null) {
328 return callable.call();
329 }
330 else {
331 return TransactionInvokerUtil.invoke(
332 transactionAttribute, callable);
333 }
334 }
335 catch (Throwable t) {
336 if (t instanceof PortalException) {
337 throw (PortalException)t;
338 }
339
340 if (t instanceof SystemException) {
341 throw (SystemException)t;
342 }
343
344 throw new SystemException(t);
345 }
346 }
347
348 protected Object executeDynamicQuery(
349 Method dynamicQueryMethod, Object... arguments)
350 throws PortalException {
351
352 try {
353 return dynamicQueryMethod.invoke(_baseLocalService, arguments);
354 }
355 catch (InvocationTargetException ite) {
356 Throwable throwable = ite.getCause();
357
358 if (throwable instanceof PortalException) {
359 throw (PortalException)throwable;
360 }
361 else if (throwable instanceof SystemException) {
362 throw (SystemException)throwable;
363 }
364
365 throw new SystemException(ite);
366 }
367 catch (Exception e) {
368 throw new SystemException(e);
369 }
370 }
371
372 protected long getCompanyId() {
373 return _companyId;
374 }
375
376 protected Projection getCountProjection() {
377 return ProjectionFactoryUtil.rowCount();
378 }
379
380 protected int getInterval() {
381 return _interval;
382 }
383
384 protected Class<?> getModelClass() {
385 return _modelClass;
386 }
387
388 protected TransactionAttribute getTransactionAttribute() {
389 return _transactionAttribute;
390 }
391
392 @SuppressWarnings("unused")
393 protected void intervalCompleted(long startPrimaryKey, long endPrimaryKey)
394 throws PortalException {
395 }
396
397 protected void performAction(Object object) throws PortalException {
398 if (_performActionMethod != null) {
399 _performActionMethod.performAction(object);
400 }
401 }
402
403 private AddCriteriaMethod _addCriteriaMethod;
404 private AddOrderCriteriaMethod _addOrderCriteriaMethod;
405 private BaseLocalService _baseLocalService;
406 private ClassLoader _classLoader;
407 private long _companyId;
408 private Method _dynamicQueryCountMethod;
409 private Method _dynamicQueryMethod;
410 private long _groupId;
411 private String _groupIdPropertyName = "groupId";
412 private int _interval = Indexer.DEFAULT_INTERVAL;
413 private Class<?> _modelClass;
414 private boolean _parallel;
415
416 @SuppressWarnings("rawtypes")
417 private PerformActionMethod _performActionMethod;
418
419 private PerformCountMethod _performCountMethod;
420 private String _primaryKeyPropertyName;
421 private final ThreadPoolExecutor _threadPoolExecutor =
422 PortalExecutorManagerUtil.getPortalExecutor(
423 DefaultActionableDynamicQuery.class.getName());
424 private TransactionAttribute _transactionAttribute;
425
426 }