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