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 setGroupIdPropertyName(String groupIdPropertyName) {
155                    _groupIdPropertyName = groupIdPropertyName;
156            }
157    
158            @Override
159            public void setInterval(int interval) {
160                    _interval = interval;
161            }
162    
163            @Override
164            public void setPrimaryKeyPropertyName(String primaryKeyPropertyName) {
165                    _primaryKeyPropertyName = primaryKeyPropertyName;
166            }
167    
168            protected void addCriteria(DynamicQuery dynamicQuery) {
169            }
170    
171            protected void addDefaultCriteria(DynamicQuery dynamicQuery) {
172                    if (_companyId > 0) {
173                            Property property = PropertyFactoryUtil.forName("companyId");
174    
175                            dynamicQuery.add(property.eq(_companyId));
176                    }
177    
178                    if (_groupId > 0) {
179                            Property property = PropertyFactoryUtil.forName(
180                                    _groupIdPropertyName);
181    
182                            dynamicQuery.add(property.eq(_groupId));
183                    }
184            }
185    
186            protected Object executeDynamicQuery(
187                            Method dynamicQueryMethod, Object... arguments)
188                    throws PortalException, SystemException {
189    
190                    try {
191                            return dynamicQueryMethod.invoke(_baseLocalService, arguments);
192                    }
193                    catch (InvocationTargetException ite) {
194                            Throwable throwable = ite.getCause();
195    
196                            if (throwable instanceof PortalException) {
197                                    throw (PortalException)throwable;
198                            }
199                            else if (throwable instanceof SystemException) {
200                                    throw (SystemException)throwable;
201                            }
202    
203                            throw new SystemException(ite);
204                    }
205                    catch (Exception e) {
206                            throw new SystemException(e);
207                    }
208            }
209    
210            protected Projection getCountProjection() {
211                    return ProjectionFactoryUtil.rowCount();
212            }
213    
214            protected abstract void performAction(Object object)
215                    throws PortalException, SystemException;
216    
217            private BaseLocalService _baseLocalService;
218            private ClassLoader _classLoader;
219            private Class<?> _clazz;
220            private long _companyId;
221            private Method _dynamicQueryCountMethod;
222            private Method _dynamicQueryMethod;
223            private long _groupId;
224            private String _groupIdPropertyName = "groupId";
225            private int _interval = Indexer.DEFAULT_INTERVAL;
226            private String _primaryKeyPropertyName;
227    
228    }