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 addOrderCriteria(dynamicQuery);
067
068 List<Object> objects = (List<Object>)executeDynamicQuery(
069 _dynamicQueryMethod, dynamicQuery);
070
071 for (Object object : objects) {
072 performAction(object);
073 }
074 }
075
076 @Override
077 public long performCount() throws PortalException, SystemException {
078 return doPerformCount();
079 }
080
081 @Override
082 public void setBaseLocalService(BaseLocalService baseLocalService)
083 throws SystemException {
084
085 _baseLocalService = baseLocalService;
086
087 Class<?> clazz = _baseLocalService.getClass();
088
089 try {
090 _dynamicQueryMethod = clazz.getMethod(
091 "dynamicQuery", DynamicQuery.class);
092 _dynamicQueryCountMethod = clazz.getMethod(
093 "dynamicQueryCount", DynamicQuery.class, Projection.class);
094 }
095 catch (NoSuchMethodException nsme) {
096 throw new SystemException(nsme);
097 }
098 }
099
100 @Override
101 public void setClass(Class<?> clazz) {
102 _clazz = clazz;
103 }
104
105 @Override
106 public void setClassLoader(ClassLoader classLoader) {
107 _classLoader = classLoader;
108 }
109
110 @Override
111 public void setCompanyId(long companyId) {
112 _companyId = companyId;
113 }
114
115 @Override
116 public void setGroupId(long groupId) {
117 _groupId = groupId;
118 }
119
120 @Override
121 public void setGroupIdPropertyName(String groupIdPropertyName) {
122 _groupIdPropertyName = groupIdPropertyName;
123 }
124
125 @Override
126 public void setInterval(int interval) {
127 _interval = interval;
128 }
129
130 @Override
131 public void setPrimaryKeyPropertyName(String primaryKeyPropertyName) {
132 _primaryKeyPropertyName = primaryKeyPropertyName;
133 }
134
135 @Override
136 public void setSearchEngineId(String searchEngineId) {
137 _searchEngineId = searchEngineId;
138 }
139
140 protected void addCriteria(DynamicQuery dynamicQuery) {
141 }
142
143 protected void addOrderCriteria(DynamicQuery dynamicQuery) {
144 }
145
146 protected void addDefaultCriteria(DynamicQuery dynamicQuery) {
147 if (_companyId > 0) {
148 Property property = PropertyFactoryUtil.forName("companyId");
149
150 dynamicQuery.add(property.eq(_companyId));
151 }
152
153 if (_groupId > 0) {
154 Property property = PropertyFactoryUtil.forName(
155 _groupIdPropertyName);
156
157 dynamicQuery.add(property.eq(_groupId));
158 }
159 }
160
161 protected void addDocument(Document document) throws PortalException {
162 if (_documents == null) {
163 _documents = new ArrayList<Document>();
164 }
165
166 _documents.add(document);
167
168 if (_documents.size() >= _interval) {
169 indexInterval();
170 }
171 }
172
173 protected void addDocuments(Collection<Document> documents)
174 throws PortalException {
175
176 if (_documents == null) {
177 _documents = new ArrayList<Document>();
178 }
179
180 _documents.addAll(documents);
181
182 if (_documents.size() >= _interval) {
183 indexInterval();
184 }
185 }
186
187 protected long doPerformCount() throws PortalException, SystemException {
188 DynamicQuery dynamicQuery = DynamicQueryFactoryUtil.forClass(
189 _clazz, _classLoader);
190
191 addDefaultCriteria(dynamicQuery);
192
193 addCriteria(dynamicQuery);
194
195 return (Long)executeDynamicQuery(
196 _dynamicQueryCountMethod, dynamicQuery, getCountProjection());
197 }
198
199 protected Object executeDynamicQuery(
200 Method dynamicQueryMethod, Object... arguments)
201 throws PortalException, SystemException {
202
203 try {
204 return dynamicQueryMethod.invoke(_baseLocalService, arguments);
205 }
206 catch (InvocationTargetException ite) {
207 Throwable throwable = ite.getCause();
208
209 if (throwable instanceof PortalException) {
210 throw (PortalException)throwable;
211 }
212 else if (throwable instanceof SystemException) {
213 throw (SystemException)throwable;
214 }
215
216 throw new SystemException(ite);
217 }
218 catch (Exception e) {
219 throw new SystemException(e);
220 }
221 }
222
223 protected Projection getCountProjection() {
224 return ProjectionFactoryUtil.rowCount();
225 }
226
227 protected String getSearchEngineId() {
228 return _searchEngineId;
229 }
230
231 protected void indexInterval() throws PortalException {
232 if ((_documents == null) || _documents.isEmpty()) {
233 return;
234 }
235
236 if (Validator.isNull(_searchEngineId)) {
237 SearchEngineUtil.updateDocuments(
238 _companyId, new ArrayList<Document>(_documents));
239 }
240 else {
241 SearchEngineUtil.updateDocuments(
242 _searchEngineId, _companyId,
243 new ArrayList<Document>(_documents));
244 }
245
246 _documents.clear();
247 }
248
249 @SuppressWarnings("unused")
250 protected void intervalCompleted(long startPrimaryKey, long endPrimaryKey)
251 throws PortalException, SystemException {
252 }
253
254 protected abstract void performAction(Object object)
255 throws PortalException, SystemException;
256
257 protected void performActionsInMultipleIntervals()
258 throws PortalException, SystemException {
259
260 DynamicQuery dynamicQuery = DynamicQueryFactoryUtil.forClass(
261 _clazz, _classLoader);
262
263 Projection minPrimaryKeyProjection = ProjectionFactoryUtil.min(
264 _primaryKeyPropertyName);
265 Projection maxPrimaryKeyProjection = ProjectionFactoryUtil.max(
266 _primaryKeyPropertyName);
267
268 ProjectionList projectionList = ProjectionFactoryUtil.projectionList();
269
270 projectionList.add(minPrimaryKeyProjection);
271 projectionList.add(maxPrimaryKeyProjection);
272
273 dynamicQuery.setProjection(projectionList);
274
275 addDefaultCriteria(dynamicQuery);
276
277 addCriteria(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 }