001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. The ASF licenses this file to You
004: * under the Apache License, Version 2.0 (the "License"); you may not
005: * use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License. For additional information regarding
015: * copyright in this work, please see the NOTICE file in the top level
016: * directory of this distribution.
017: */
018:
019: package org.apache.roller.business.hibernate;
020:
021: import java.util.Calendar;
022: import java.util.Date;
023: import org.apache.commons.logging.Log;
024: import org.apache.commons.logging.LogFactory;
025: import org.apache.roller.RollerException;
026: import org.apache.roller.business.runnable.ThreadManagerImpl;
027: import org.apache.roller.business.runnable.RollerTask;
028: import org.apache.roller.business.RollerFactory;
029: import org.apache.roller.pojos.TaskLockData;
030: import org.hibernate.Criteria;
031: import org.hibernate.HibernateException;
032: import org.hibernate.Session;
033: import org.hibernate.criterion.Expression;
034:
035: /**
036: * Hibernate implementation of the TaskLockManager interface.
037: *
038: * This implementation extends the base ThreadManagerImpl class and provides
039: * locking abilities which are managed through the database.
040: */
041: public class HibernateThreadManagerImpl extends ThreadManagerImpl {
042:
043: private static Log log = LogFactory
044: .getLog(HibernateThreadManagerImpl.class);
045:
046: private HibernatePersistenceStrategy strategy = null;
047:
048: public HibernateThreadManagerImpl(HibernatePersistenceStrategy strat) {
049: super ();
050:
051: log.debug("Instantiating Hibernate Thread Manager");
052:
053: this .strategy = strat;
054: }
055:
056: /**
057: * Try to aquire a lock for a given RollerTask.
058: *
059: * Remember, locks are only given if ...
060: * 1. the task is not currently locked and it's past the next scheduled
061: * run time for the particular task
062: * 2. the task *is* locked, but its lease has expired
063: */
064: public boolean acquireLock(RollerTask task) {
065:
066: boolean lockAcquired = false;
067:
068: TaskLockData taskLock = null;
069: try {
070: taskLock = this .getTaskLockByName(task.getName());
071:
072: // null here just means hasn't been initialized yet
073: if (taskLock == null) {
074: taskLock = new TaskLockData();
075: taskLock.setName(task.getName());
076: taskLock.setLocked(false);
077: }
078: } catch (RollerException ex) {
079: log.warn("Error getting TaskLockData", ex);
080: return false;
081: }
082:
083: Date now = new Date();
084: Date nextRun = taskLock.getNextRun(task.getInterval());
085: if (!taskLock.isLocked()
086: && (nextRun == null || now.after(nextRun))) {
087:
088: // set appropriate values for TaskLock and save it
089: taskLock.setLocked(true);
090: taskLock.setTimeAquired(now);
091: taskLock.setTimeLeased(task.getLeaseTime());
092: taskLock.setLastRun(now);
093:
094: try {
095: // save it *and* flush
096: this .saveTaskLock(taskLock);
097: RollerFactory.getRoller().flush();
098: lockAcquired = true;
099: } catch (RollerException ex) {
100: log.warn("Error saving TaskLockData", ex);
101: lockAcquired = false;
102: }
103: }
104:
105: return lockAcquired;
106: }
107:
108: /**
109: * Try to release the lock for a given RollerTask.
110: */
111: public boolean releaseLock(RollerTask task) {
112:
113: boolean lockReleased = false;
114:
115: TaskLockData taskLock = null;
116: try {
117: taskLock = this .getTaskLockByName(task.getName());
118: } catch (RollerException ex) {
119: log.warn("Error getting TaskLockData", ex);
120: return false;
121: }
122:
123: if (taskLock != null && taskLock.isLocked()) {
124: // set appropriate values for TaskLock and save it
125: Date now = new Date();
126: taskLock.setLocked(false);
127:
128: try {
129: // save it *and* flush
130: this .saveTaskLock(taskLock);
131: RollerFactory.getRoller().flush();
132: lockReleased = true;
133: } catch (RollerException ex) {
134: log.warn("Error saving TaskLockData", ex);
135: lockReleased = false;
136: }
137: } else if (taskLock != null && !taskLock.isLocked()) {
138: // if lock is already released then don't fret about it
139: lockReleased = true;
140: }
141:
142: return lockReleased;
143: }
144:
145: /**
146: * Is a task currently locked?
147: */
148: public boolean isLocked(RollerTask task) {
149:
150: // default is "true"!
151: boolean locked = true;
152:
153: try {
154: TaskLockData taskLock = this .getTaskLockByName(task
155: .getName());
156: if (taskLock != null) {
157: locked = taskLock.isLocked();
158: } else {
159: // if taskLock is null, but we didn't get an exception then
160: // that means this lock hasn't been initialized yet
161: locked = false;
162: }
163: } catch (RollerException ex) {
164: log.warn("Error getting TaskLockData", ex);
165: }
166:
167: return locked;
168: }
169:
170: private TaskLockData getTaskLockByName(String name)
171: throws RollerException {
172:
173: // do lookup
174: try {
175: Session session = ((HibernatePersistenceStrategy) this .strategy)
176: .getSession();
177: Criteria criteria = session
178: .createCriteria(TaskLockData.class);
179:
180: criteria.add(Expression.eq("name", name));
181: TaskLockData taskLock = (TaskLockData) criteria
182: .uniqueResult();
183:
184: return taskLock;
185: } catch (HibernateException e) {
186: throw new RollerException(e);
187: }
188: }
189:
190: private void saveTaskLock(TaskLockData data) throws RollerException {
191: this.strategy.store(data);
192: }
193:
194: }
|