001    /**
002     * Copyright (c) 2000-2010 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.jpa;
016    
017    import com.liferay.portal.dao.orm.common.SQLTransformer;
018    import com.liferay.portal.kernel.dao.orm.CacheMode;
019    import com.liferay.portal.kernel.dao.orm.ORMException;
020    import com.liferay.portal.kernel.dao.orm.Query;
021    import com.liferay.portal.kernel.dao.orm.ScrollableResults;
022    import com.liferay.portal.kernel.util.ListUtil;
023    import com.liferay.portal.kernel.util.StringBundler;
024    import com.liferay.portal.kernel.util.StringPool;
025    import com.liferay.portal.kernel.util.UnmodifiableList;
026    
027    import java.io.Serializable;
028    
029    import java.sql.Timestamp;
030    
031    import java.util.Date;
032    import java.util.HashMap;
033    import java.util.Iterator;
034    import java.util.List;
035    import java.util.Map;
036    
037    import javax.persistence.FlushModeType;
038    
039    /**
040     * @author Prashant Dighe
041     * @author Brian Wing Shun Chan
042     */
043    public class QueryImpl implements Query {
044    
045            public QueryImpl(SessionImpl sessionImpl, String queryString) {
046                    this.sessionImpl = sessionImpl;
047                    this.queryString = _hqlTojpql(SQLTransformer.transform(queryString));
048            }
049    
050            public int executeUpdate() throws ORMException {
051                    try {
052                            return sessionImpl.executeUpdate(
053                                    queryString, parameterMap, firstResult, maxResults,
054                                    flushModeType, sqlQuery, entityClass);
055                    }
056                    catch (Exception e) {
057                            throw ExceptionTranslator.translate(e);
058                    }
059            }
060    
061            public Iterator<?> iterate() throws ORMException {
062                    return iterate(true);
063            }
064    
065            public Iterator<?> iterate(boolean unmodifiable) throws ORMException {
066                    try {
067                            return list(unmodifiable).iterator();
068                    }
069                    catch (Exception e) {
070                            throw ExceptionTranslator.translate(e);
071                    }
072            }
073    
074            public List<?> list() throws ORMException {
075                    return list(true);
076            }
077    
078            public List<?> list(boolean unmodifiable) throws ORMException {
079                    try {
080                            List<?> list = sessionImpl.list(
081                                    queryString, parameterMap, firstResult, maxResults,
082                                    flushModeType, sqlQuery, entityClass);
083    
084                            if (unmodifiable) {
085                                    return new UnmodifiableList<Object>(list);
086                            }
087                            else {
088                                    return ListUtil.copy(list);
089                            }
090                    }
091                    catch (Exception e) {
092                            throw ExceptionTranslator.translate(e);
093                    }
094            }
095    
096            public ScrollableResults scroll() throws ORMException {
097                    try {
098                            return new ScrollableResultsImpl(list());
099                    }
100                    catch (Exception e) {
101                            throw ExceptionTranslator.translate(e);
102                    }
103            }
104    
105            public Query setBoolean(int pos, boolean value) {
106                    parameterMap.put(pos, value);
107    
108                    return this;
109            }
110    
111            public Query setCacheable(boolean cacheable) {
112                    return this;
113            }
114    
115            public Query setCacheMode(CacheMode cacheMode) {
116                    return this;
117            }
118    
119            public Query setCacheRegion(String cacheRegion) {
120                    return this;
121            }
122    
123            public Query setDouble(int pos, double value) {
124                    parameterMap.put(pos, Double.valueOf(value));
125    
126                    return this;
127            }
128    
129            public Query setFirstResult(int firstResult) {
130                    this.firstResult = firstResult;
131    
132                    return this;
133            }
134    
135            public Query setFloat(int pos, float value) {
136                    parameterMap.put(pos, Float.valueOf(value));
137    
138                    return this;
139            }
140    
141            public Query setFlushMode(FlushModeType flushModeType) {
142                    this.flushModeType = flushModeType;
143    
144                    return this;
145            }
146    
147            public Query setInteger(int pos, int value) {
148                    parameterMap.put(pos, Integer.valueOf(value));
149    
150                    return this;
151            }
152    
153            public Query setLong(int pos, long value) {
154                    parameterMap.put(pos, Long.valueOf(value));
155    
156                    return this;
157            }
158    
159            public Query setMaxResults(int maxResults) {
160                    this.maxResults = maxResults;
161    
162                    return this;
163            }
164    
165            public Query setSerializable(int pos, Serializable value) {
166                    parameterMap.put(pos, value);
167    
168                    return this;
169            }
170    
171            public Query setShort(int pos, short value) {
172                    parameterMap.put(pos, Short.valueOf(value));
173    
174                    return this;
175            }
176    
177            public Query setString(int pos, String value) {
178                    parameterMap.put(pos, value);
179    
180                    return this;
181            }
182    
183            public Query setTimestamp(int pos, Timestamp value) {
184                    Date date = null;
185    
186                    if (value != null) {
187                            date = new Date(value.getTime());
188                    }
189    
190                    parameterMap.put(pos, date);
191    
192                    return this;
193            }
194    
195            public Object uniqueResult() throws ORMException {
196                    try {
197                            return sessionImpl.uniqueResult(
198                                    queryString, parameterMap, firstResult, maxResults,
199                                    flushModeType, sqlQuery, entityClass);
200                    }
201                    catch (Exception e) {
202                            throw ExceptionTranslator.translate(e);
203                    }
204            }
205    
206            private String _hqlTojpql(String queryString) {
207                    queryString = _transformPositionalParams(queryString);
208    
209                    queryString = queryString.replaceAll(_HQL_NOT_EQUALS, _JPQL_NOT_EQUALS);
210                    queryString = queryString.replaceAll(
211                            _HQL_COMPOSITE_ID_MARKER, _JPQL_DOT_SEPARTOR);
212    
213                    return queryString;
214            }
215    
216            private String _transformPositionalParams(String queryString) {
217                    if (queryString.indexOf(StringPool.QUESTION) == -1) {
218                            return queryString;
219                    }
220    
221                    StringBundler sb = new StringBundler();
222    
223                    int i = 1;
224                    int from = 0;
225                    int to = 0;
226    
227                    while ((to = queryString.indexOf(StringPool.QUESTION, from)) != -1) {
228                            sb.append(queryString.substring(from, to));
229                            sb.append(StringPool.QUESTION);
230                            sb.append(i++);
231    
232                            from = to + 1;
233                    }
234    
235                    sb.append(queryString.substring(from, queryString.length()));
236    
237                    return sb.toString();
238            }
239    
240            protected Class<?> entityClass = null;
241            protected int firstResult = -1;
242            protected FlushModeType flushModeType = null;
243            protected int maxResults = -1;
244            protected Map<Integer, Object> parameterMap =
245                    new HashMap<Integer, Object>();
246            protected String queryString;
247            protected SessionImpl sessionImpl;
248            protected boolean sqlQuery = false;
249    
250            private static final String _HQL_COMPOSITE_ID_MARKER = "\\.id\\.";
251    
252            private static final String _HQL_NOT_EQUALS = "!=";
253    
254            private static final String _JPQL_DOT_SEPARTOR = ".";
255    
256            private static final String _JPQL_NOT_EQUALS = "<>";
257    
258    }