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