1
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.dao.orm.hibernate.SessionImpl;
29 import com.liferay.portal.kernel.dao.jdbc.DataAccess;
30 import com.liferay.portal.kernel.dao.orm.LockMode;
31 import com.liferay.portal.kernel.dao.orm.ObjectNotFoundException;
32 import com.liferay.portal.kernel.dao.orm.Query;
33 import com.liferay.portal.kernel.dao.orm.Session;
34 import com.liferay.portal.kernel.job.IntervalJob;
35 import com.liferay.portal.kernel.job.JobSchedulerUtil;
36 import com.liferay.portal.kernel.util.GetterUtil;
37 import com.liferay.portal.kernel.util.ListUtil;
38 import com.liferay.portal.service.persistence.impl.BasePersistenceImpl;
39 import com.liferay.portal.util.PropsKeys;
40 import com.liferay.portal.util.PropsUtil;
41
42 import java.sql.Connection;
43
44 import java.util.ArrayList;
45 import java.util.HashMap;
46 import java.util.Iterator;
47 import java.util.List;
48 import java.util.Map;
49
50 import org.hibernate.SessionFactory;
51
52
60 public class CounterPersistence extends BasePersistenceImpl {
61
62 public static int getCounterIncrement() {
63 return _COUNTER_INCREMENT;
64 }
65
66 public void afterPropertiesSet() {
67 JobSchedulerUtil.schedule(_connectionHeartbeatJob);
68 }
69
70 public synchronized Connection getConnection() throws Exception {
71 if ((_connection == null) || _connection.isClosed()) {
72 _connection = getDataSource().getConnection();
73
74 _connection.setAutoCommit(true);
75 }
76
77 return _connection;
78 }
79
80 public void destroy() {
81 JobSchedulerUtil.unschedule(_connectionHeartbeatJob);
82
83 DataAccess.cleanUp(_connection);
84 }
85
86 public List<String> getNames() throws SystemException {
87 Session session = null;
88
89 try {
90 Connection connection = getConnection();
91
92 session = new SessionImpl(_sessionFactory.openSession(connection));
93
94 List<String> list = new ArrayList<String>();
95
96 Query q = session.createQuery("FROM " + Counter.class.getName());
97
98 Iterator<Counter> itr = q.iterate();
99
100 while (itr.hasNext()) {
101 Counter counter = itr.next();
102
103 list.add(counter.getName());
104 }
105
106 return ListUtil.sort(list);
107 }
108 catch (Exception e) {
109 throw processException(e);
110 }
111 finally {
112 session.close();
113 }
114 }
115
116 public long increment() throws SystemException {
117 return increment(_NAME);
118 }
119
120 public long increment(String name) throws SystemException {
121 return increment(name, _MINIMUM_INCREMENT_SIZE);
122 }
123
124 public long increment(String name, int size)
125 throws SystemException {
126
127 if (size < _MINIMUM_INCREMENT_SIZE) {
128 size = _MINIMUM_INCREMENT_SIZE;
129 }
130
131 CounterRegister register = getCounterRegister(name);
132
133 synchronized (register) {
134 long newValue = register.getCurrentValue() + size;
135
136 if (newValue > register.getRangeMax()) {
137 Session session = null;
138
139 try {
140 Connection connection = getConnection();
141
142 session = new SessionImpl(
143 _sessionFactory.openSession(connection));
144
145 Counter counter = (Counter)session.get(
146 Counter.class, register.getName());
147
148 newValue = counter.getCurrentId() + 1;
149
150 long rangeMax =
151 counter.getCurrentId() + register.getRangeSize();
152
153 counter.setCurrentId(rangeMax);
154
155 session.save(counter);
156 session.flush();
157
158 register.setCurrentValue(newValue);
159 register.setRangeMax(rangeMax);
160 }
161 catch (Exception e) {
162 throw processException(e);
163 }
164 finally {
165 session.close();
166 }
167 }
168 else {
169 register.setCurrentValue(newValue);
170 }
171
172 return newValue;
173 }
174 }
175
176 public void rename(String oldName, String newName)
177 throws SystemException {
178
179 CounterRegister register = getCounterRegister(oldName);
180
181 synchronized (register) {
182 if (_registerLookup.containsKey(newName)) {
183 throw new SystemException(
184 "Cannot rename " + oldName + " to " + newName);
185 }
186
187 Session session = null;
188
189 try {
190 Connection connection = getConnection();
191
192 session = new SessionImpl(
193 _sessionFactory.openSession(connection));
194
195 Counter counter = (Counter)session.load(Counter.class, oldName);
196
197 long currentId = counter.getCurrentId();
198
199 session.delete(counter);
200
201 counter = new Counter();
202
203 counter.setName(newName);
204 counter.setCurrentId(currentId);
205
206 session.save(counter);
207
208 session.flush();
209 }
210 catch (ObjectNotFoundException onfe) {
211 }
212 catch (Exception e) {
213 throw processException(e);
214 }
215 finally {
216 session.close();
217 }
218
219 register.setName(newName);
220
221 _registerLookup.put(newName, register);
222 _registerLookup.remove(oldName);
223 }
224 }
225
226 public void reset(String name) throws SystemException {
227 CounterRegister register = getCounterRegister(name);
228
229 synchronized (register) {
230 Session session = null;
231
232 try {
233 Connection connection = getConnection();
234
235 session = new SessionImpl(
236 _sessionFactory.openSession(connection));
237
238 Counter counter = (Counter)session.load(Counter.class, name);
239
240 session.delete(counter);
241
242 session.flush();
243 }
244 catch (ObjectNotFoundException onfe) {
245 }
246 catch (Exception e) {
247 throw processException(e);
248 }
249 finally {
250 session.close();
251 }
252
253 _registerLookup.remove(name);
254 }
255 }
256
257 public void reset(String name, long size) throws SystemException {
258 CounterRegister register = createCounterRegister(name, size);
259
260 synchronized (register) {
261 _registerLookup.put(name, register);
262 }
263 }
264
265 public void setConnectionHeartbeatJob(IntervalJob connectionHeartbeatJob) {
266 _connectionHeartbeatJob = connectionHeartbeatJob;
267 }
268
269 public void setSessionFactory(SessionFactory sessionFactory) {
270 _sessionFactory = sessionFactory;
271 }
272
273 protected synchronized CounterRegister getCounterRegister(String name)
274 throws SystemException {
275
276 CounterRegister register = _registerLookup.get(name);
277
278 if (register == null) {
279 register = createCounterRegister(name);
280
281 _registerLookup.put(name, register);
282 }
283
284 return register;
285 }
286
287 protected synchronized CounterRegister createCounterRegister(String name)
288 throws SystemException {
289
290 return createCounterRegister(name, -1);
291 }
292
293 protected synchronized CounterRegister createCounterRegister(
294 String name, long size)
295 throws SystemException {
296
297 long rangeMin = 0;
298 long rangeMax = 0;
299
300 Session session = null;
301
302 try {
303 Connection connection = getConnection();
304
305 session = new SessionImpl(
306 _sessionFactory.openSession(connection));
307
308 Counter counter = (Counter)session.get(
309 Counter.class, name, LockMode.UPGRADE);
310
311 if (counter == null) {
312 rangeMin = _DEFAULT_CURRENT_ID;
313
314 counter = new Counter();
315
316 counter.setName(name);
317 }
318 else {
319 rangeMin = counter.getCurrentId();
320 }
321
322 if (size >= _DEFAULT_CURRENT_ID) {
323 rangeMin = size;
324 }
325
326 rangeMax = rangeMin + _COUNTER_INCREMENT;
327
328 counter.setCurrentId(rangeMax);
329
330 session.save(counter);
331 session.flush();
332 }
333 catch (Exception e) {
334 throw processException(e);
335 }
336 finally {
337 session.close();
338 }
339
340 CounterRegister register = new CounterRegister(
341 name, rangeMin, rangeMax, _COUNTER_INCREMENT);
342
343 return register;
344 }
345
346 private static final int _DEFAULT_CURRENT_ID = 0;
347
348 private static final int _MINIMUM_INCREMENT_SIZE = 1;
349
350 private static final int _COUNTER_INCREMENT = GetterUtil.getInteger(
351 PropsUtil.get(PropsKeys.COUNTER_INCREMENT), _MINIMUM_INCREMENT_SIZE);
352
353 private static final String _NAME = Counter.class.getName();
354
355 private static Map<String, CounterRegister> _registerLookup =
356 new HashMap<String, CounterRegister>();
357
358 private Connection _connection;
359 private IntervalJob _connectionHeartbeatJob;
360 private SessionFactory _sessionFactory;
361
362 }