001    /**
002     * Copyright (c) 2000-present 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.dao.orm.hibernate;
016    
017    import com.liferay.portal.kernel.dao.orm.Criterion;
018    import com.liferay.portal.kernel.dao.orm.DynamicQuery;
019    import com.liferay.portal.kernel.dao.orm.Order;
020    import com.liferay.portal.kernel.dao.orm.Projection;
021    import com.liferay.portal.kernel.dao.orm.ProjectionFactoryUtil;
022    import com.liferay.portal.kernel.dao.orm.QueryUtil;
023    import com.liferay.portal.kernel.dao.orm.Session;
024    import com.liferay.portal.kernel.util.ListUtil;
025    
026    import java.util.ArrayList;
027    import java.util.Collections;
028    import java.util.List;
029    
030    import org.hibernate.Criteria;
031    import org.hibernate.criterion.DetachedCriteria;
032    
033    /**
034     * @author Brian Wing Shun Chan
035     */
036    public class DynamicQueryImpl implements DynamicQuery {
037    
038            public DynamicQueryImpl(DetachedCriteria detachedCriteria) {
039                    _detachedCriteria = detachedCriteria;
040            }
041    
042            @Override
043            public DynamicQuery add(Criterion criterion) {
044                    CriterionImpl criterionImpl = (CriterionImpl)criterion;
045    
046                    _detachedCriteria.add(criterionImpl.getWrappedCriterion());
047    
048                    return this;
049            }
050    
051            @Override
052            public DynamicQuery addOrder(Order order) {
053                    OrderImpl orderImpl = (OrderImpl)order;
054    
055                    _detachedCriteria.addOrder(orderImpl.getWrappedOrder());
056    
057                    return this;
058            }
059    
060            @Override
061            public void compile(Session session) {
062                    org.hibernate.Session hibernateSession =
063                            (org.hibernate.Session)session.getWrappedSession();
064    
065                    _criteria = _detachedCriteria.getExecutableCriteria(hibernateSession);
066    
067                    if ((_start == null) && (_end == null)) {
068                            return;
069                    }
070    
071                    int start = QueryUtil.ALL_POS;
072    
073                    if (_start != null) {
074                            start = _start.intValue();
075                    }
076    
077                    int end = QueryUtil.ALL_POS;
078    
079                    if (_end != null) {
080                            end = _end.intValue();
081                    }
082    
083                    if ((start == QueryUtil.ALL_POS) && (end == QueryUtil.ALL_POS)) {
084                            return;
085                    }
086                    else if ((start < QueryUtil.ALL_POS) && (end < QueryUtil.ALL_POS)) {
087                            _criteria = _criteria.setFirstResult(0);
088                            _criteria = _criteria.setMaxResults(0);
089    
090                            _requiresProcessing = false;
091    
092                            return;
093                    }
094    
095                    if (start < 0) {
096                            start = 0;
097                    }
098    
099                    _criteria = _criteria.setFirstResult(start);
100    
101                    if (end == QueryUtil.ALL_POS) {
102                            return;
103                    }
104    
105                    if (start <= end) {
106                            end = end - start;
107                    }
108                    else {
109                            end = 0;
110                    }
111    
112                    _criteria = _criteria.setMaxResults(end);
113    
114                    if (end == 0) {
115                            _requiresProcessing = false;
116                    }
117            }
118    
119            public DetachedCriteria getDetachedCriteria() {
120                    return _detachedCriteria;
121            }
122    
123            @Override
124            @SuppressWarnings("rawtypes")
125            public List list() {
126                    return list(true);
127            }
128    
129            @Override
130            @SuppressWarnings("rawtypes")
131            public List list(boolean unmodifiable) {
132                    if (!_requiresProcessing) {
133                            if (unmodifiable) {
134                                    return Collections.emptyList();
135                            }
136    
137                            return new ArrayList<>();
138                    }
139    
140                    List list = _criteria.list();
141    
142                    if (unmodifiable) {
143                            return Collections.unmodifiableList(list);
144                    }
145                    else {
146                            return ListUtil.copy(list);
147                    }
148            }
149    
150            @Override
151            public void setLimit(int start, int end) {
152                    _start = Integer.valueOf(start);
153                    _end = Integer.valueOf(end);
154            }
155    
156            @Override
157            public DynamicQuery setProjection(Projection projection) {
158                    return setProjection(projection, true);
159            }
160    
161            @Override
162            public DynamicQuery setProjection(
163                    Projection projection, boolean useColumnAlias) {
164    
165                    if (!useColumnAlias) {
166                            projection = ProjectionFactoryUtil.sqlProjection(
167                                    _detachedCriteria.getAlias() + "_." + projection.toString(),
168                                    null, null);
169                    }
170    
171                    ProjectionImpl projectionImpl = (ProjectionImpl)projection;
172    
173                    _detachedCriteria.setProjection(projectionImpl.getWrappedProjection());
174    
175                    return this;
176            }
177    
178            @Override
179            public String toString() {
180                    if (_criteria != null) {
181                            return _criteria.toString();
182                    }
183    
184                    return super.toString();
185            }
186    
187            private Criteria _criteria;
188            private final DetachedCriteria _detachedCriteria;
189            private Integer _end;
190            private boolean _requiresProcessing = true;
191            private Integer _start;
192    
193    }