1   /**
2    * Copyright (c) 2000-2008 Liferay, Inc. All rights reserved.
3    *
4    * Permission is hereby granted, free of charge, to any person obtaining a copy
5    * of this software and associated documentation files (the "Software"), to deal
6    * in the Software without restriction, including without limitation the rights
7    * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8    * copies of the Software, and to permit persons to whom the Software is
9    * furnished to do so, subject to the following conditions:
10   *
11   * The above copyright notice and this permission notice shall be included in
12   * all copies or substantial portions of the Software.
13   *
14   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20   * SOFTWARE.
21   */
22  
23  package com.liferay.counter.service.persistence;
24  
25  import com.liferay.counter.model.Counter;
26  import com.liferay.counter.model.CounterRegister;
27  import com.liferay.portal.SystemException;
28  import com.liferay.portal.kernel.util.GetterUtil;
29  import com.liferay.portal.service.persistence.BasePersistence;
30  import com.liferay.portal.spring.hibernate.HibernateUtil;
31  import com.liferay.portal.util.PropsUtil;
32  
33  import java.util.ArrayList;
34  import java.util.Collections;
35  import java.util.HashMap;
36  import java.util.Iterator;
37  import java.util.List;
38  import java.util.Map;
39  
40  import org.hibernate.LockMode;
41  import org.hibernate.ObjectNotFoundException;
42  import org.hibernate.Query;
43  import org.hibernate.Session;
44  
45  /**
46   * <a href="CounterPersistence.java.html"><b><i>View Source</i></b></a>
47   *
48   * @author Brian Wing Shun Chan
49   * @author Harry Mark
50   *
51   */
52  public class CounterPersistence extends BasePersistence {
53  
54      public CounterPersistence() {
55      }
56  
57      public List<String> getNames() throws SystemException {
58          Session session = null;
59  
60          try {
61              session = openSession();
62  
63              List<String> list = new ArrayList<String>();
64  
65              Query q = session.createQuery("FROM " + Counter.class.getName());
66  
67              Iterator<Counter> itr = q.iterate();
68  
69              while (itr.hasNext()) {
70                  Counter counter = itr.next();
71  
72                  list.add(counter.getName());
73              }
74  
75              Collections.sort(list);
76  
77              return list;
78          }
79          catch (Exception e) {
80              throw HibernateUtil.processException(e);
81          }
82          finally {
83              closeSession(session);
84          }
85      }
86  
87      public long increment() throws SystemException {
88          return increment(_NAME);
89      }
90  
91      public long increment(String name) throws SystemException {
92          return increment(name, _MINIMUM_INCREMENT_SIZE);
93      }
94  
95      public long increment(String name, int size)
96          throws SystemException {
97  
98          if (size < _MINIMUM_INCREMENT_SIZE) {
99              size = _MINIMUM_INCREMENT_SIZE;
100         }
101 
102         CounterRegister register = getCounterRegister(name);
103 
104         synchronized (register) {
105             long newValue = register.getCurrentValue() + size;
106 
107             if (newValue > register.getRangeMax()) {
108                 Session session = null;
109 
110                 try {
111                     session = openSession();
112 
113                     Counter counter = (Counter)session.get(
114                         Counter.class, register.getName(), LockMode.UPGRADE);
115 
116                     newValue = counter.getCurrentId() + 1;
117 
118                     long rangeMax =
119                         counter.getCurrentId() + register.getRangeSize();
120 
121                     counter.setCurrentId(rangeMax);
122 
123                     session.save(counter);
124                     session.flush();
125 
126                     register.setCurrentValue(newValue);
127                     register.setRangeMax(rangeMax);
128                 }
129                 catch (Exception e) {
130                     throw HibernateUtil.processException(e);
131                 }
132                 finally {
133                     closeSession(session);
134                 }
135             }
136             else {
137                 register.setCurrentValue(newValue);
138             }
139 
140             return newValue;
141         }
142     }
143 
144     public void rename(String oldName, String newName)
145         throws SystemException {
146 
147         CounterRegister register = getCounterRegister(oldName);
148 
149         synchronized (register) {
150             if (_registerLookup.containsKey(newName)) {
151                 throw new SystemException(
152                     "Cannot rename " + oldName + " to " + newName);
153             }
154 
155             Session session = null;
156 
157             try {
158                 session = openSession();
159 
160                 Counter counter = (Counter)session.load(Counter.class, oldName);
161 
162                 long currentId = counter.getCurrentId();
163 
164                 session.delete(counter);
165 
166                 counter = new Counter();
167 
168                 counter.setName(newName);
169                 counter.setCurrentId(currentId);
170 
171                 session.save(counter);
172 
173                 session.flush();
174             }
175             catch (ObjectNotFoundException onfe) {
176             }
177             catch (Exception e) {
178                 throw HibernateUtil.processException(e);
179             }
180             finally {
181                 closeSession(session);
182             }
183 
184             register.setName(newName);
185 
186             _registerLookup.put(newName, register);
187             _registerLookup.remove(oldName);
188         }
189     }
190 
191     public void reset(String name) throws SystemException {
192         CounterRegister register = getCounterRegister(name);
193 
194         synchronized (register) {
195             Session session = null;
196 
197             try {
198                 session = openSession();
199 
200                 Counter counter = (Counter)session.load(Counter.class, name);
201 
202                 session.delete(counter);
203 
204                 session.flush();
205             }
206             catch (ObjectNotFoundException onfe) {
207             }
208             catch (Exception e) {
209                 throw HibernateUtil.processException(e);
210             }
211             finally {
212                 closeSession(session);
213             }
214 
215             _registerLookup.remove(name);
216         }
217     }
218 
219     public void reset(String name, long size) throws SystemException {
220         CounterRegister register = createCounterRegister(name, size);
221 
222         synchronized (register) {
223             _registerLookup.put(name, register);
224         }
225     }
226 
227     protected synchronized CounterRegister getCounterRegister(String name)
228         throws SystemException {
229 
230         CounterRegister register = _registerLookup.get(name);
231 
232         if (register == null) {
233             register = createCounterRegister(name);
234 
235             _registerLookup.put(name, register);
236         }
237 
238         return register;
239     }
240 
241     protected synchronized CounterRegister createCounterRegister(String name)
242         throws SystemException {
243 
244         return createCounterRegister(name, -1);
245     }
246 
247     protected synchronized CounterRegister createCounterRegister(
248             String name, long size)
249         throws SystemException {
250 
251         long rangeMin = 0;
252         long rangeMax = 0;
253 
254         Session session = null;
255 
256         try {
257             session = openSession();
258 
259             Counter counter = (Counter)session.get(
260                 Counter.class, name, LockMode.UPGRADE);
261 
262             if (counter == null) {
263                 rangeMin = _DEFAULT_CURRENT_ID;
264 
265                 counter = new Counter();
266 
267                 counter.setName(name);
268             }
269             else {
270                 rangeMin = counter.getCurrentId();
271             }
272 
273             if (size >= _DEFAULT_CURRENT_ID) {
274                 rangeMin = size;
275             }
276 
277             rangeMax = rangeMin + _COUNTER_INCREMENT;
278 
279             counter.setCurrentId(rangeMax);
280 
281             session.save(counter);
282             session.flush();
283         }
284         finally {
285             closeSession(session);
286         }
287 
288         CounterRegister register = new CounterRegister(
289             name, rangeMin, rangeMax, _COUNTER_INCREMENT);
290 
291         return register;
292     }
293 
294     private static final int _DEFAULT_CURRENT_ID = 0;
295 
296     private static final int _MINIMUM_INCREMENT_SIZE = 1;
297 
298     private static final int _COUNTER_INCREMENT = GetterUtil.getInteger(
299         PropsUtil.get(PropsUtil.COUNTER_INCREMENT), _MINIMUM_INCREMENT_SIZE);
300 
301     private static final String _NAME = Counter.class.getName();
302 
303     private static Map<String, CounterRegister> _registerLookup =
304         new HashMap<String, CounterRegister>();
305 
306 }