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