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   */
48  public class BasePersistenceImpl<T extends BaseModel<T>>
49      implements BasePersistence<T>, SessionFactory {
50  
51      public static final String COUNT_COLUMN_NAME = "COUNT_VALUE";
52  
53      public void clearCache() {
54      }
55  
56      public void closeSession(Session session) {
57          _sessionFactory.closeSession(session);
58      }
59  
60      public int countWithDynamicQuery(DynamicQuery dynamicQuery)
61          throws SystemException {
62  
63          dynamicQuery.setProjection(ProjectionFactoryUtil.rowCount());
64  
65          List<Object> results = findWithDynamicQuery(dynamicQuery);
66  
67          if (results.isEmpty()) {
68              return 0;
69          }
70          else {
71              return ((Integer)results.get(0));
72          }
73      }
74  
75      @SuppressWarnings("unused")
76      public T fetchByPrimaryKey(Serializable primaryKey) throws SystemException {
77          throw new UnsupportedOperationException();
78      }
79  
80      @SuppressWarnings("unused")
81      public T findByPrimaryKey(Serializable primaryKey)
82          throws NoSuchModelException, SystemException {
83  
84          throw new UnsupportedOperationException();
85      }
86  
87      public List<Object> findWithDynamicQuery(DynamicQuery dynamicQuery)
88          throws SystemException {
89  
90          Session session = null;
91  
92          try {
93              session = openSession();
94  
95              dynamicQuery.compile(session);
96  
97              return dynamicQuery.list();
98          }
99          catch (Exception e) {
100             throw processException(e);
101         }
102         finally {
103             closeSession(session);
104         }
105     }
106 
107     public List<Object> findWithDynamicQuery(
108             DynamicQuery dynamicQuery, int start, int end)
109         throws SystemException {
110 
111         Session session = null;
112 
113         try {
114             session = openSession();
115 
116             dynamicQuery.setLimit(start, end);
117 
118             dynamicQuery.compile(session);
119 
120             return dynamicQuery.list();
121         }
122         catch (Exception e) {
123             throw processException(e);
124         }
125         finally {
126             closeSession(session);
127         }
128     }
129 
130     public List<Object> findWithDynamicQuery(
131             DynamicQuery dynamicQuery, int start, int end,
132             OrderByComparator orderByComparator)
133         throws SystemException {
134 
135         OrderFactoryUtil.addOrderByComparator(dynamicQuery, orderByComparator);
136 
137         return findWithDynamicQuery(dynamicQuery, start, end);
138     }
139 
140     public DataSource getDataSource() {
141         return _dataSource;
142     }
143 
144     public Dialect getDialect() {
145         return _dialect;
146     }
147 
148     public ModelListener<T>[] getListeners() {
149         return listeners;
150     }
151 
152     public Session openNewSession(Connection connection) throws ORMException {
153         return _sessionFactory.openNewSession(connection);
154     }
155 
156     public Session openSession() throws ORMException {
157         return _sessionFactory.openSession();
158     }
159 
160     public SystemException processException(Exception e) {
161         if (!(e instanceof ORMException)) {
162             _log.error("Caught unexpected exception " + e.getClass().getName());
163         }
164 
165         if (_log.isDebugEnabled()) {
166             _log.debug(e, e);
167         }
168 
169         return new SystemException(e);
170     }
171 
172     public void registerListener(ModelListener<T> listener) {
173         List<ModelListener<T>> listenersList = ListUtil.fromArray(listeners);
174 
175         listenersList.add(listener);
176 
177         listeners = listenersList.toArray(
178             new ModelListener[listenersList.size()]);
179     }
180 
181     @SuppressWarnings("unused")
182     public T remove(Serializable primaryKey)
183         throws NoSuchModelException, SystemException {
184 
185         throw new UnsupportedOperationException();
186     }
187 
188     @SuppressWarnings("unused")
189     public T remove(T model) throws SystemException {
190         throw new UnsupportedOperationException();
191     }
192 
193     public void setDataSource(DataSource dataSource) {
194         _dataSource = dataSource;
195     }
196 
197     public void setSessionFactory(SessionFactory sessionFactory) {
198         _sessionFactory = sessionFactory;
199         _dialect = _sessionFactory.getDialect();
200     }
201 
202     public void unregisterListener(ModelListener<T> listener) {
203         List<ModelListener<T>> listenersList = ListUtil.fromArray(listeners);
204 
205         listenersList.remove(listener);
206 
207         listeners = listenersList.toArray(
208             new ModelListener[listenersList.size()]);
209     }
210 
211     /**
212      * Add, update, or merge, the model. This method also calls the model
213      * listeners to trigger the proper events associated with adding, deleting,
214      * or updating a model.
215      *
216      * @param  model the model to add, update, or merge
217      * @param  merge boolean value for whether to merge the entity. The default
218      *         value is false. Setting merge to true is more expensive and
219      *         should only be true when model is transient. See LEP-5473 for a
220      *         detailed discussion of this method.
221      * @return the model that was added, updated, or merged
222      */
223     public T update(T model, boolean merge) throws SystemException {
224         boolean isNew = model.isNew();
225 
226         for (ModelListener<T> listener : listeners) {
227             if (isNew) {
228                 listener.onBeforeCreate(model);
229             }
230             else {
231                 listener.onBeforeUpdate(model);
232             }
233         }
234 
235         model = updateImpl(model, merge);
236 
237         for (ModelListener<T> listener : listeners) {
238             if (isNew) {
239                 listener.onAfterCreate(model);
240             }
241             else {
242                 listener.onAfterUpdate(model);
243             }
244         }
245 
246         return model;
247     }
248 
249     @SuppressWarnings("unused")
250     public T updateImpl(T model, boolean merge) throws SystemException {
251         throw new UnsupportedOperationException();
252     }
253 
254     protected void appendOrderByComparator(
255         StringBundler query, String entityAlias,
256         OrderByComparator orderByComparator) {
257 
258         query.append(ORDER_BY_CLAUSE);
259 
260         String[] orderByFields = orderByComparator.getOrderByFields();
261 
262         for (int i = 0; i < orderByFields.length; i++) {
263             query.append(entityAlias);
264             query.append(orderByFields[i]);
265 
266             if ((i + 1) < orderByFields.length) {
267                 if (orderByComparator.isAscending()) {
268                     query.append(ORDER_BY_ASC_HAS_NEXT);
269                 }
270                 else {
271                     query.append(ORDER_BY_DESC_HAS_NEXT);
272                 }
273             }
274             else {
275                 if (orderByComparator.isAscending()) {
276                     query.append(ORDER_BY_ASC);
277                 }
278                 else {
279                     query.append(ORDER_BY_DESC);
280                 }
281             }
282         }
283     }
284 
285     protected static final String ORDER_BY_ASC = " ASC";
286 
287     protected static final String ORDER_BY_ASC_HAS_NEXT = " ASC, ";
288 
289     protected static final String ORDER_BY_CLAUSE = " ORDER BY ";
290 
291     protected static final String ORDER_BY_DESC = " DESC";
292 
293     protected static final String ORDER_BY_DESC_HAS_NEXT = " DESC, ";
294 
295     protected ModelListener<T>[] listeners = new ModelListener[0];
296 
297     private static Log _log = LogFactoryUtil.getLog(BasePersistenceImpl.class);
298 
299     private DataSource _dataSource;
300     private Dialect _dialect;
301     private SessionFactory _sessionFactory;
302 
303 }