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.Indexer;
020    import com.liferay.portal.service.BaseLocalService;
021    
022    import java.lang.reflect.InvocationTargetException;
023    import java.lang.reflect.Method;
024    
025    import java.util.List;
026    
027    /**
028     * @author Brian Wing Shun Chan
029     */
030    public abstract class BaseActionableDynamicQuery
031            implements ActionableDynamicQuery {
032    
033            @Override
034            public void performActions() throws PortalException, SystemException {
035                    DynamicQuery dynamicQuery = DynamicQueryFactoryUtil.forClass(
036                            _clazz, _classLoader);
037    
038                    Projection minPrimaryKeyProjection = ProjectionFactoryUtil.min(
039                            _primaryKeyPropertyName);
040                    Projection maxPrimaryKeyProjection = ProjectionFactoryUtil.max(
041                            _primaryKeyPropertyName);
042    
043                    ProjectionList projectionList = ProjectionFactoryUtil.projectionList();
044    
045                    projectionList.add(minPrimaryKeyProjection);
046                    projectionList.add(maxPrimaryKeyProjection);
047    
048                    dynamicQuery.setProjection(projectionList);
049    
050                    addDefaultCriteria(dynamicQuery);
051                    addCriteria(dynamicQuery);
052    
053                    List<Object[]> results = (List<Object[]>)executeDynamicQuery(
054                            _dynamicQueryMethod, dynamicQuery);
055    
056                    Object[] minAndMaxPrimaryKeys = results.get(0);
057    
058                    if ((minAndMaxPrimaryKeys[0] == null) ||
059                            (minAndMaxPrimaryKeys[1] == null)) {
060    
061                            return;
062                    }
063    
064                    long minPrimaryKey = (Long)minAndMaxPrimaryKeys[0];
065                    long maxPrimaryKey = (Long)minAndMaxPrimaryKeys[1];
066    
067                    long startPrimaryKey = minPrimaryKey;
068                    long endPrimaryKey = startPrimaryKey + _interval;
069    
070                    while (startPrimaryKey <= maxPrimaryKey) {
071                            performActions(startPrimaryKey, endPrimaryKey);
072    
073                            startPrimaryKey = endPrimaryKey;
074                            endPrimaryKey += _interval;
075                    }
076            }
077    
078            public void performActions(long startPrimaryKey, long endPrimaryKey)
079                    throws PortalException, SystemException {
080    
081                    DynamicQuery dynamicQuery = DynamicQueryFactoryUtil.forClass(
082                            _clazz, _classLoader);
083    
084                    Property property = PropertyFactoryUtil.forName(
085                            _primaryKeyPropertyName);
086    
087                    dynamicQuery.add(property.ge(startPrimaryKey));
088                    dynamicQuery.add(property.lt(endPrimaryKey));
089    
090                    addDefaultCriteria(dynamicQuery);
091    
092                    addCriteria(dynamicQuery);
093    
094                    List<Object> objects = (List<Object>)executeDynamicQuery(
095                            _dynamicQueryMethod, dynamicQuery);
096    
097                    for (Object object : objects) {
098                            performAction(object);
099                    }
100            }
101    
102            @Override
103            public long performCount() throws PortalException, SystemException {
104                    DynamicQuery dynamicQuery = DynamicQueryFactoryUtil.forClass(
105                            _clazz, _classLoader);
106    
107                    addCriteria(dynamicQuery);
108                    addDefaultCriteria(dynamicQuery);
109    
110                    return (Long)executeDynamicQuery(
111                            _dynamicQueryCountMethod, dynamicQuery, getCountProjection());
112            }
113    
114            @Override
115            public void setBaseLocalService(BaseLocalService baseLocalService)
116                    throws SystemException {
117    
118                    _baseLocalService = baseLocalService;
119    
120                    Class<?> clazz = _baseLocalService.getClass();
121    
122                    try {
123                            _dynamicQueryMethod = clazz.getMethod(
124                                    "dynamicQuery", DynamicQuery.class);
125                            _dynamicQueryCountMethod = clazz.getMethod(
126                                    "dynamicQueryCount", DynamicQuery.class, Projection.class);
127                    }
128                    catch (NoSuchMethodException nsme) {
129                            throw new SystemException(nsme);
130                    }
131            }
132    
133            @Override
134            public void setClass(Class<?> clazz) {
135                    _clazz = clazz;
136            }
137    
138            @Override
139            public void setClassLoader(ClassLoader classLoader) {
140                    _classLoader = classLoader;
141            }
142    
143            @Override
144            public void setCompanyId(long companyId) {
145                    _companyId = companyId;
146            }
147    
148            @Override
149            public void setGroupId(long groupId) {
150                    _groupId = groupId;
151            }
152    
153            @Override
154            public void setInterval(int interval) {
155                    _interval = interval;
156            }
157    
158            @Override
159            public void setPrimaryKeyPropertyName(String primaryKeyPropertyName) {
160                    _primaryKeyPropertyName = primaryKeyPropertyName;
161            }
162    
163            protected void addCriteria(DynamicQuery dynamicQuery) {
164            }
165    
166            protected void addDefaultCriteria(DynamicQuery dynamicQuery) {
167                    if (_companyId > 0) {
168                            Property property = PropertyFactoryUtil.forName("companyId");
169    
170                            dynamicQuery.add(property.eq(_companyId));
171                    }
172    
173                    if (_groupId > 0) {
174                            Property property = PropertyFactoryUtil.forName("groupId");
175    
176                            dynamicQuery.add(property.eq(_groupId));
177                    }
178            }
179    
180            protected Object executeDynamicQuery(
181                            Method dynamicQueryMethod, Object... arguments)
182                    throws PortalException, SystemException {
183    
184                    try {
185                            return dynamicQueryMethod.invoke(_baseLocalService, arguments);
186                    }
187                    catch (InvocationTargetException ite) {
188                            Throwable throwable = ite.getCause();
189    
190                            if (throwable instanceof PortalException) {
191                                    throw (PortalException)throwable;
192                            }
193                            else if (throwable instanceof SystemException) {
194                                    throw (SystemException)throwable;
195                            }
196    
197                            throw new SystemException(ite);
198                    }
199                    catch (Exception e) {
200                            throw new SystemException(e);
201                    }
202            }
203    
204            protected Projection getCountProjection() {
205                    return ProjectionFactoryUtil.rowCount();
206            }
207    
208            protected abstract void performAction(Object object)
209                    throws PortalException, SystemException;
210    
211            private BaseLocalService _baseLocalService;
212            private ClassLoader _classLoader;
213            private Class<?> _clazz;
214            private long _companyId;
215            private Method _dynamicQueryCountMethod;
216            private Method _dynamicQueryMethod;
217            private long _groupId;
218            private int _interval = Indexer.DEFAULT_INTERVAL;
219            private String _primaryKeyPropertyName;
220    
221    }