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.dao.orm.LockMode;
29  import com.liferay.portal.kernel.dao.orm.ObjectNotFoundException;
30  import com.liferay.portal.kernel.dao.orm.Query;
31  import com.liferay.portal.kernel.dao.orm.Session;
32  import com.liferay.portal.kernel.util.GetterUtil;
33  import com.liferay.portal.service.persistence.impl.BasePersistenceImpl;
34  import com.liferay.portal.util.PropsKeys;
35  import com.liferay.portal.util.PropsUtil;
36  
37  import java.util.ArrayList;
38  import java.util.Collections;
39  import java.util.HashMap;
40  import java.util.Iterator;
41  import java.util.List;
42  import java.util.Map;
43  
44  /**
45   * <a href="CounterPersistence.java.html"><b><i>View Source</i></b></a>
46   *
47   * @author Brian Wing Shun Chan
48   * @author Harry Mark
49   *
50   */
51  public class CounterPersistence extends BasePersistenceImpl {
52  
53      public CounterPersistence() {
54      }
55  
56      public List<String> getNames() throws SystemException {
57          Session session = null;
58  
59          try {
60              session = openSession();
61  
62              List<String> list = new ArrayList<String>();
63  
64              Query q = session.createQuery("FROM " + Counter.class.getName());
65  
66              Iterator<Counter> itr = q.iterate();
67  
68              while (itr.hasNext()) {
69                  Counter counter = itr.next();
70  
71                  list.add(counter.getName());
72              }
73  
74              Collections.sort(list);
75  
76              return list;
77          }
78          catch (Exception e) {
79              throw processException(e);
80          }
81          finally {
82              closeSession(session);
83          }
84      }
85  
86      public long increment() throws SystemException {
87          return increment(_NAME);
88      }
89  
90      public long increment(String name) throws SystemException {
91          return increment(name, _MINIMUM_INCREMENT_SIZE);
92      }
93  
94      public long increment(String name, int size)
95          throws SystemException {
96  
97          if (size < _MINIMUM_INCREMENT_SIZE) {
98              size = _MINIMUM_INCREMENT_SIZE;
99          }
100 
101         CounterRegister register = getCounterRegister(name);
102 
103         synchronized (register) {
104             long newValue = register.getCurrentValue() + size;
105 
106             if (newValue > register.getRangeMax()) {
107                 Session session = null;
108 
109                 try {
110                     session = openSession();
111 
112                     Counter counter = (Counter)session.get(
113                         Counter.class, register.getName(), LockMode.UPGRADE);
114 
115                     newValue = counter.getCurrentId() + 1;
116 
117                     long rangeMax =
118                         counter.getCurrentId() + register.getRangeSize();
119 
120                     counter.setCurrentId(rangeMax);
121 
122                     session.save(counter);
123                     session.flush();
124 
125                     register.setCurrentValue(newValue);
126                     register.setRangeMax(rangeMax);
127                 }
128                 catch (Exception e) {
129                     throw processException(e);
130                 }
131                 finally {
132                     closeSession(session);
133                 }
134             }
135             else {
136                 register.setCurrentValue(newValue);
137             }
138 
139             return newValue;
140         }
141     }
142 
143     public void rename(String oldName, String newName)
144         throws SystemException {
145 
146         CounterRegister register = getCounterRegister(oldName);
147 
148         synchronized (register) {
149             if (_registerLookup.containsKey(newName)) {
150                 throw new SystemException(
151                     "Cannot rename " + oldName + " to " + newName);
152             }
153 
154             Session session = null;
155 
156             try {
157                 session = openSession();
158 
159                 Counter counter = (Counter)session.load(Counter.class, oldName);
160 
161                 long currentId = counter.getCurrentId();
162 
163                 session.delete(counter);
164 
165                 counter = new Counter();
166 
167                 counter.setName(newName);
168                 counter.setCurrentId(currentId);
169 
170                 session.save(counter);
171 
172                 session.flush();
173             }
174             catch (ObjectNotFoundException onfe) {
175             }
176             catch (Exception e) {
177                 throw processException(e);
178             }
179             finally {
180                 closeSession(session);
181             }
182 
183             register.setName(newName);
184 
185             _registerLookup.put(newName, register);
186             _registerLookup.remove(oldName);
187         }
188     }
189 
190     public void reset(String name) throws SystemException {
191         CounterRegister register = getCounterRegister(name);
192 
193         synchronized (register) {
194             Session session = null;
195 
196             try {
197                 session = openSession();
198 
199                 Counter counter = (Counter)session.load(Counter.class, name);
200 
201                 session.delete(counter);
202 
203                 session.flush();
204             }
205             catch (ObjectNotFoundException onfe) {
206             }
207             catch (Exception e) {
208                 throw processException(e);
209             }
210             finally {
211                 closeSession(session);
212             }
213 
214             _registerLookup.remove(name);
215         }
216     }
217 
218     public void reset(String name, long size) {
219         CounterRegister register = createCounterRegister(name, size);
220 
221         synchronized (register) {
222             _registerLookup.put(name, register);
223         }
224     }
225 
226     protected synchronized CounterRegister getCounterRegister(String name) {
227         CounterRegister register = _registerLookup.get(name);
228 
229         if (register == null) {
230             register = createCounterRegister(name);
231 
232             _registerLookup.put(name, register);
233         }
234 
235         return register;
236     }
237 
238     protected synchronized CounterRegister createCounterRegister(String name) {
239         return createCounterRegister(name, -1);
240     }
241 
242     protected synchronized CounterRegister createCounterRegister(
243         String name, long size) {
244 
245         long rangeMin = 0;
246         long rangeMax = 0;
247 
248         Session session = null;
249 
250         try {
251             session = openSession();
252 
253             Counter counter = (Counter)session.get(
254                 Counter.class, name, LockMode.UPGRADE);
255 
256             if (counter == null) {
257                 rangeMin = _DEFAULT_CURRENT_ID;
258 
259                 counter = new Counter();
260 
261                 counter.setName(name);
262             }
263             else {
264                 rangeMin = counter.getCurrentId();
265             }
266 
267             if (size >= _DEFAULT_CURRENT_ID) {
268                 rangeMin = size;
269             }
270 
271             rangeMax = rangeMin + _COUNTER_INCREMENT;
272 
273             counter.setCurrentId(rangeMax);
274 
275             session.save(counter);
276             session.flush();
277         }
278         finally {
279             closeSession(session);
280         }
281 
282         CounterRegister register = new CounterRegister(
283             name, rangeMin, rangeMax, _COUNTER_INCREMENT);
284 
285         return register;
286     }
287 
288     private static final int _DEFAULT_CURRENT_ID = 0;
289 
290     private static final int _MINIMUM_INCREMENT_SIZE = 1;
291 
292     private static final int _COUNTER_INCREMENT = GetterUtil.getInteger(
293         PropsUtil.get(PropsKeys.COUNTER_INCREMENT), _MINIMUM_INCREMENT_SIZE);
294 
295     private static final String _NAME = Counter.class.getName();
296 
297     private static Map<String, CounterRegister> _registerLookup =
298         new HashMap<String, CounterRegister>();
299 
300 }