1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * This library is free software; you can redistribute it and/or modify it under
5    * the terms of the GNU Lesser General Public License as published by the Free
6    * Software Foundation; either version 2.1 of the License, or (at your option)
7    * any later version.
8    *
9    * This library is distributed in the hope that it will be useful, but WITHOUT
10   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11   * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12   * details.
13   */
14  
15  package com.liferay.portal.service.persistence.impl;
16  
17  import com.liferay.portal.NoSuchModelException;
18  import com.liferay.portal.kernel.dao.orm.Dialect;
19  import com.liferay.portal.kernel.dao.orm.DynamicQuery;
20  import com.liferay.portal.kernel.dao.orm.ORMException;
21  import com.liferay.portal.kernel.dao.orm.OrderFactoryUtil;
22  import com.liferay.portal.kernel.dao.orm.ProjectionFactoryUtil;
23  import com.liferay.portal.kernel.dao.orm.Session;
24  import com.liferay.portal.kernel.dao.orm.SessionFactory;
25  import com.liferay.portal.kernel.exception.SystemException;
26  import com.liferay.portal.kernel.log.Log;
27  import com.liferay.portal.kernel.log.LogFactoryUtil;
28  import com.liferay.portal.kernel.util.ListUtil;
29  import com.liferay.portal.kernel.util.OrderByComparator;
30  import com.liferay.portal.kernel.util.StringBundler;
31  import com.liferay.portal.model.BaseModel;
32  import com.liferay.portal.model.ModelListener;
33  import com.liferay.portal.service.persistence.BasePersistence;
34  
35  import java.io.Serializable;
36  
37  import java.sql.Connection;
38  
39  import java.util.List;
40  
41  import javax.sql.DataSource;
42  
43  /**
44   * <a href="BasePersistenceImpl.java.html"><b><i>View Source</i></b></a>
45   *
46   * @author Brian Wing Shun Chan
47   * @author Shuyang Zhou
48   */
49  public class BasePersistenceImpl<T extends BaseModel<T>>
50      implements BasePersistence<T>, SessionFactory {
51  
52      public static final String COUNT_COLUMN_NAME = "COUNT_VALUE";
53  
54      public void clearCache() {
55      }
56  
57      public void clearCache(T model) {
58      }
59  
60      public void closeSession(Session session) {
61          _sessionFactory.closeSession(session);
62      }
63  
64      public long countWithDynamicQuery(DynamicQuery dynamicQuery)
65          throws SystemException {
66  
67          dynamicQuery.setProjection(ProjectionFactoryUtil.rowCount());
68  
69          List<?> results = findWithDynamicQuery(dynamicQuery);
70  
71          if (results.isEmpty()) {
72              return 0;
73          }
74          else {
75              return ((Long)results.get(0)).longValue();
76          }
77      }
78  
79      @SuppressWarnings("unused")
80      public T fetchByPrimaryKey(Serializable primaryKey) throws SystemException {
81          throw new UnsupportedOperationException();
82      }
83  
84      @SuppressWarnings("unused")
85      public T findByPrimaryKey(Serializable primaryKey)
86          throws NoSuchModelException, SystemException {
87  
88          throw new UnsupportedOperationException();
89      }
90  
91      @SuppressWarnings("unchecked")
92      public List findWithDynamicQuery(DynamicQuery dynamicQuery)
93          throws SystemException {
94  
95          Session session = null;
96  
97          try {
98              session = openSession();
99  
100             dynamicQuery.compile(session);
101 
102             return dynamicQuery.list();
103         }
104         catch (Exception e) {
105             throw processException(e);
106         }
107         finally {
108             closeSession(session);
109         }
110     }
111 
112     @SuppressWarnings("unchecked")
113     public List findWithDynamicQuery(
114             DynamicQuery dynamicQuery, int start, int end)
115         throws SystemException {
116 
117         Session session = null;
118 
119         try {
120             session = openSession();
121 
122             dynamicQuery.setLimit(start, end);
123 
124             dynamicQuery.compile(session);
125 
126             return dynamicQuery.list();
127         }
128         catch (Exception e) {
129             throw processException(e);
130         }
131         finally {
132             closeSession(session);
133         }
134     }
135 
136     @SuppressWarnings("unchecked")
137     public List findWithDynamicQuery(
138             DynamicQuery dynamicQuery, int start, int end,
139             OrderByComparator orderByComparator)
140         throws SystemException {
141 
142         OrderFactoryUtil.addOrderByComparator(dynamicQuery, orderByComparator);
143 
144         return findWithDynamicQuery(dynamicQuery, start, end);
145     }
146 
147     public DataSource getDataSource() {
148         return _dataSource;
149     }
150 
151     public Dialect getDialect() {
152         return _dialect;
153     }
154 
155     public ModelListener<T>[] getListeners() {
156         return listeners;
157     }
158 
159     public Session openNewSession(Connection connection) throws ORMException {
160         return _sessionFactory.openNewSession(connection);
161     }
162 
163     public Session openSession() throws ORMException {
164         return _sessionFactory.openSession();
165     }
166 
167     public SystemException processException(Exception e) {
168         if (!(e instanceof ORMException)) {
169             _log.error("Caught unexpected exception " + e.getClass().getName());
170         }
171 
172         if (_log.isDebugEnabled()) {
173             _log.debug(e, e);
174         }
175 
176         return new SystemException(e);
177     }
178 
179     public void registerListener(ModelListener<T> listener) {
180         List<ModelListener<T>> listenersList = ListUtil.fromArray(listeners);
181 
182         listenersList.add(listener);
183 
184         listeners = listenersList.toArray(
185             new ModelListener[listenersList.size()]);
186     }
187 
188     @SuppressWarnings("unused")
189     public T remove(Serializable primaryKey)
190         throws NoSuchModelException, SystemException {
191 
192         throw new UnsupportedOperationException();
193     }
194 
195     @SuppressWarnings("unused")
196     public T remove(T model) throws SystemException {
197         throw new UnsupportedOperationException();
198     }
199 
200     public void setDataSource(DataSource dataSource) {
201         _dataSource = dataSource;
202     }
203 
204     public void setSessionFactory(SessionFactory sessionFactory) {
205         _sessionFactory = sessionFactory;
206         _dialect = _sessionFactory.getDialect();
207     }
208 
209     public void unregisterListener(ModelListener<T> listener) {
210         List<ModelListener<T>> listenersList = ListUtil.fromArray(listeners);
211 
212         listenersList.remove(listener);
213 
214         listeners = listenersList.toArray(
215             new ModelListener[listenersList.size()]);
216     }
217 
218     /**
219      * Add, update, or merge, the model. This method also calls the model
220      * listeners to trigger the proper events associated with adding, deleting,
221      * or updating a model.
222      *
223      * @param  model the model to add, update, or merge
224      * @param  merge boolean value for whether to merge the entity. The default
225      *         value is false. Setting merge to true is more expensive and
226      *         should only be true when model is transient. See LEP-5473 for a
227      *         detailed discussion of this method.
228      * @return the model that was added, updated, or merged
229      */
230     public T update(T model, boolean merge) throws SystemException {
231         boolean isNew = model.isNew();
232 
233         for (ModelListener<T> listener : listeners) {
234             if (isNew) {
235                 listener.onBeforeCreate(model);
236             }
237             else {
238                 listener.onBeforeUpdate(model);
239             }
240         }
241 
242         model = updateImpl(model, merge);
243 
244         for (ModelListener<T> listener : listeners) {
245             if (isNew) {
246                 listener.onAfterCreate(model);
247             }
248             else {
249                 listener.onAfterUpdate(model);
250             }
251         }
252 
253         return model;
254     }
255 
256     @SuppressWarnings("unused")
257     public T updateImpl(T model, boolean merge) throws SystemException {
258         throw new UnsupportedOperationException();
259     }
260 
261     protected void appendOrderByComparator(
262         StringBundler query, String entityAlias,
263         OrderByComparator orderByComparator) {
264 
265         query.append(ORDER_BY_CLAUSE);
266 
267         String[] orderByFields = orderByComparator.getOrderByFields();
268 
269         for (int i = 0; i < orderByFields.length; i++) {
270             query.append(entityAlias);
271             query.append(orderByFields[i]);
272 
273             if ((i + 1) < orderByFields.length) {
274                 if (orderByComparator.isAscending()) {
275                     query.append(ORDER_BY_ASC_HAS_NEXT);
276                 }
277                 else {
278                     query.append(ORDER_BY_DESC_HAS_NEXT);
279                 }
280             }
281             else {
282                 if (orderByComparator.isAscending()) {
283                     query.append(ORDER_BY_ASC);
284                 }
285                 else {
286                     query.append(ORDER_BY_DESC);
287                 }
288             }
289         }
290     }
291 
292     protected static final String ORDER_BY_ASC = " ASC";
293 
294     protected static final String ORDER_BY_ASC_HAS_NEXT = " ASC, ";
295 
296     protected static final String ORDER_BY_CLAUSE = " ORDER BY ";
297 
298     protected static final String ORDER_BY_DESC = " DESC";
299 
300     protected static final String ORDER_BY_DESC_HAS_NEXT = " DESC, ";
301 
302     protected static final String WHERE_AND = " AND ";
303 
304     protected static final String WHERE_LESSER_THAN = " <= ? ";
305 
306     protected static final String WHERE_LESSER_THAN_HAS_NEXT = " <= ? AND ";
307 
308     protected static final String WHERE_GREATER_THAN = " >= ? ";
309 
310     protected static final String WHERE_GREATER_THAN_HAS_NEXT = " >= ? AND ";
311 
312     protected ModelListener<T>[] listeners = new ModelListener[0];
313 
314     private static Log _log = LogFactoryUtil.getLog(BasePersistenceImpl.class);
315 
316     private DataSource _dataSource;
317     private Dialect _dialect;
318     private SessionFactory _sessionFactory;
319 
320 }