/* Copyright 2006-2008 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.codehaus.groovy.grails.plugins.quartz;
import groovy.lang.Closure;
import org.codehaus.groovy.grails.commons.AbstractInjectableGrailsClass;
import org.codehaus.groovy.grails.commons.GrailsClassUtils;
import org.codehaus.groovy.grails.plugins.quartz.config.TriggersConfigBuilder;
import org.quartz.CronExpression;
import org.quartz.JobExecutionContext;
import java.util.HashMap;
import java.util.Map;
/**
* Grails artefact class which represents a Quartz job.
*
* @author Micha?? K??ujszo
* @author Marcel Overdijk
* @author Sergey Nebolsin (nebolsin@gmail.com)
*
* @since 0.1
*/
public class DefaultGrailsTaskClass extends AbstractInjectableGrailsClass implements GrailsTaskClass, GrailsTaskClassProperty {
public static final String JOB = "Job";
private Map triggers = new HashMap();
public DefaultGrailsTaskClass(Class clazz) {
super(clazz, JOB);
validateProperties();
evaluateTriggers();
}
private void evaluateTriggers() {
// registering additional triggersClosure from 'triggersClosure' closure if present
Closure triggersClosure = (Closure) GrailsClassUtils.getStaticPropertyValue(getClazz(), "triggers");
TriggersConfigBuilder builder = new TriggersConfigBuilder(getFullName());
if(triggersClosure != null) {
builder.build(triggersClosure);
triggers = (Map) builder.getTriggers();
} else {
// backward compatibility
if(isCronExpressionConfigured()) {
triggers = builder.createEmbeddedCronTrigger(getStartDelay(), getCronExpression());
} else {
triggers = builder.createEmbeddedSimpleTrigger(getStartDelay(), getTimeout(), getRepeatCount());
}
}
}
private void validateProperties() {
Object obj = getPropertyValue(TIMEOUT);
if( obj != null && !(obj instanceof Integer || obj instanceof Long)) {
throw new IllegalArgumentException("Timeout property for job class " + getClazz().getName() + " must be Integer or Long");
}
if( obj != null && ((Number) obj).longValue() < 0 ) {
throw new IllegalArgumentException("Timeout property for job class " + getClazz().getName() + " is negative (possibly integer overflow error)");
}
obj = getPropertyValue(START_DELAY);
if( obj != null && !(obj instanceof Integer || obj instanceof Long)) {
throw new IllegalArgumentException("Start delay property for job class " + getClazz().getName() + " must be Integer or Long");
}
if( obj != null && ((Number) obj).longValue() < 0 ) {
throw new IllegalArgumentException("Start delay property for job class " + getClazz().getName() + " is negative (possibly integer overflow error)");
}
obj = getPropertyValue(REPEAT_COUNT);
if( obj != null && !(obj instanceof Integer)) {
throw new IllegalArgumentException("Repeat count property for job class " + getClazz().getName() + " must be Integer");
}
if( obj != null && ((Number) obj).intValue() < 0 ) {
throw new IllegalArgumentException("Repeat count property for job class " + getClazz().getName() + " is negative (possibly integer overflow error)");
}
obj = getPropertyValue(CRON_EXPRESSION);
if(obj != null && !CronExpression.isValidExpression(obj.toString())) {
throw new IllegalArgumentException("Cron expression '" + obj.toString() + "' for job class " + getClazz().getName() + " is not a valid cron expression");
}
}
public void execute() {
getMetaClass().invokeMethod( getReference().getWrappedInstance(), EXECUTE, new Object[] {} );
}
public void execute(JobExecutionContext context) {
getMetaClass().invokeMethod(getReference().getWrappedInstance(), EXECUTE, new Object[] {context});
}
public long getTimeout() {
Object obj = getPropertyValue( TIMEOUT );
if( obj == null ) return DEFAULT_TIMEOUT;
return ((Number)obj).longValue();
}
public long getStartDelay() {
Object obj = getPropertyValue(START_DELAY);
if( obj == null ) return DEFAULT_START_DELAY;
return ((Number)obj).longValue();
}
public int getRepeatCount() {
Object obj = getPropertyValue(REPEAT_COUNT);
if(obj == null) return DEFAULT_REPEAT_COUNT;
return ((Number)obj).intValue();
}
public String getCronExpression() {
String cronExpression = (String)getPropertyOrStaticPropertyOrFieldValue(CRON_EXPRESSION, String.class);
if( cronExpression == null || "".equals(cronExpression) ) return DEFAULT_CRON_EXPRESSION;
return cronExpression;
}
public String getGroup() {
String group = (String)getPropertyOrStaticPropertyOrFieldValue(GROUP, String.class);
if( group == null || "".equals(group) ) return DEFAULT_GROUP;
return group;
}
// not certain about this... feels messy
public boolean isCronExpressionConfigured() {
String cronExpression = (String)getPropertyOrStaticPropertyOrFieldValue(CRON_EXPRESSION, String.class);
return cronExpression != null;
}
public boolean isConcurrent() {
Boolean concurrent = (Boolean)getPropertyValue(CONCURRENT, Boolean.class);
return concurrent == null ? DEFAULT_CONCURRENT : concurrent.booleanValue();
}
public boolean isSessionRequired() {
Boolean sessionRequired = (Boolean)getPropertyValue(SESSION_REQUIRED, Boolean.class);
return sessionRequired == null ? DEFAULT_SESSION_REQUIRED : sessionRequired.booleanValue();
}
public boolean getVolatility() {
Boolean volatility = (Boolean) getPropertyValue(VOLATILITY, Boolean.class);
return volatility == null ? DEFAULT_VOLATILITY : volatility.booleanValue();
}
public boolean getDurability() {
Boolean durability = (Boolean) getPropertyValue(DURABILITY, Boolean.class);
return durability == null ? DEFAULT_DURABILITY : durability.booleanValue();
}
public Map getTriggers() {
return triggers;
}
}