📄 jobschedulingdataprocessor.java
字号:
/**
* This rule is needed to fix <a href="http://jira.opensymphony.com/browse/QUARTZ-153">QUARTZ-153</a>.
* <p>
* Since the Jakarta Commons BeanUtils 1.6.x <code>ConvertUtils</code> class uses static utility
* methods, the <code>DateConverter</code> and <code>TimeZoneConverter</code> were
* overriding any previously registered converters for <code>java.util.Date</code> and
* <code>java.util.TimeZone</code>.
* <p>
* Jakarta Commons BeanUtils 1.7.x fixes this issue by internally using per-context-classloader
* pseudo-singletons (see <a href="http://jakarta.apache.org/commons/beanutils/commons-beanutils-1.7.0/RELEASE-NOTES.txt">
* http://jakarta.apache.org/commons/beanutils/commons-beanutils-1.7.0/RELEASE-NOTES.txt</a>).
* This ensures web applications in the same JVM are using independent converters
* based on their classloaders. However, the environment for QUARTZ-153 started Quartz
* using the <code>QuartzInitializationServlet</code> which started <code>JobInitializationPlugin</code>.
* In this case, the web classloader instances would be the same.
* <p>
* To make sure the converters aren't overridden by the <code>JobSchedulingDataProcessor</code>,
* it's easier to just override <code>BeanPropertySetterRule.end()</code> to convert the
* body text to the specified class using the specified converter.
*
* @author <a href="mailto:bonhamcm@thirdeyeconsulting.com">Chris Bonham</a>
*/
public class SimpleConverterRule extends BeanPropertySetterRule {
private Converter converter;
private Class clazz;
/**
* <p>Construct rule that sets the given property from the body text.</p>
*
* @param propertyName name of property to set
* @param converter converter to use
* @param clazz class to convert to
*/
public SimpleConverterRule(String propertyName, Converter converter, Class clazz) {
this.propertyName = propertyName;
if (converter == null) {
throw new IllegalArgumentException("Converter must not be null");
}
this.converter = converter;
if (clazz == null) {
throw new IllegalArgumentException("Class must not be null");
}
this.clazz = clazz;
}
/**
* Process the end of this element.
*
* @param namespace the namespace URI of the matching element, or an
* empty string if the parser is not namespace aware or the element has
* no namespace
* @param name the local name if the parser is namespace aware, or just
* the element name otherwise
*
* @exception NoSuchMethodException if the bean does not
* have a writeable property of the specified name
*/
public void end(String namespace, String name) throws Exception {
String property = propertyName;
if (property == null) {
// If we don't have a specific property name,
// use the element name.
property = name;
}
// Get a reference to the top object
Object top = this.digester.peek();
// log some debugging information
if (getDigester().getLogger().isDebugEnabled()) {
getDigester().getLogger().debug("[BeanPropertySetterRule]{" + getDigester().getMatch() +
"} Set " + top.getClass().getName() + " property " +
property + " with text " + bodyText);
}
// Force an exception if the property does not exist
// (BeanUtils.setProperty() silently returns in this case)
if (top instanceof DynaBean) {
DynaProperty desc =
((DynaBean) top).getDynaClass().getDynaProperty(property);
if (desc == null) {
throw new NoSuchMethodException ("Bean has no property named " + property);
}
} else /* this is a standard JavaBean */ {
PropertyDescriptor desc =
PropertyUtils.getPropertyDescriptor(top, property);
if (desc == null) {
throw new NoSuchMethodException("Bean has no property named " + property);
}
}
// Set the property only using this converter
Object value = converter.convert(clazz, bodyText);
PropertyUtils.setProperty(top, property, value);
}
}
/**
* This rule translates the trigger misfire instruction constant name into its
* corresponding value.
*
* <p>
* TODO Consider removing this class and using a
* <code>org.apache.commons.digester.Substitutor</code> strategy once
* Jakarta Commons Digester 1.6 is final.
* </p>
*
* @author <a href="mailto:bonhamcm@thirdeyeconsulting.com">Chris Bonham</a>
*/
public class MisfireInstructionRule extends BeanPropertySetterRule {
/**
* <p>Construct rule that sets the given property from the body text.</p>
*
* @param propertyName name of property to set
*/
public MisfireInstructionRule(String propertyName) {
this.propertyName = propertyName;
}
/**
* Process the body text of this element.
*
* @param namespace the namespace URI of the matching element, or an
* empty string if the parser is not namespace aware or the element has
* no namespace
* @param name the local name if the parser is namespace aware, or just
* the element name otherwise
* @param text The text of the body of this element
*/
public void body(String namespace, String name, String text)
throws Exception {
super.body(namespace, name, text);
this.bodyText = getConstantValue(bodyText);
}
/**
* Returns the value for the constant name.
* If the constant can't be found or any exceptions occur,
* return 0.
*
* @param constantName constant name.
* @return the value for the constant name.
*/
private String getConstantValue(String constantName) {
String value = "0";
Object top = this.digester.peek();
if (top != null) {
Class clazz = top.getClass();
try {
java.lang.reflect.Field field = clazz.getField(constantName);
Object fieldValue = field.get(top);
if (fieldValue != null) {
value = fieldValue.toString();
}
} catch (Exception e) {
// ignore
}
}
return value;
}
}
/**
* <p>Standard {@link Converter} implementation that converts an incoming
* String into a <code>java.util.Date</code> object, optionally using a
* default value or throwing a {@link ConversionException} if a conversion
* error occurs.</p>
*/
public final class DateConverter implements Converter {
// ----------------------------------------------------------- Constructors
/**
* Create a {@link Converter} that will throw a {@link ConversionException}
* if a conversion error occurs.
*/
public DateConverter() {
this.defaultValue = null;
this.useDefault = false;
}
/**
* Create a {@link Converter} that will return the specified default value
* if a conversion error occurs.
*
* @param defaultValue The default value to be returned
*/
public DateConverter(Object defaultValue) {
this.defaultValue = defaultValue;
this.useDefault = true;
}
public DateConverter(String[] formats) {
this();
int len = formats.length;
dateFormats = new DateFormat[len];
for (int i = 0; i < len; i++) {
dateFormats[i] = new SimpleDateFormat(formats[i]);
}
}
// ----------------------------------------------------- Instance Variables
/**
* The default value specified to our Constructor, if any.
*/
private Object defaultValue = null;
/**
* Should we return the default value on conversion errors?
*/
private boolean useDefault = true;
private DateFormat[] dateFormats;
// --------------------------------------------------------- Public Methods
/**
* Convert the specified input object into an output object of the
* specified type.
*
* @param type Data type to which this value should be converted
* @param value The input value to be converted
*
* @exception ConversionException if conversion cannot be performed
* successfully
*/
public Object convert(Class type, Object value) {
if (value == null) {
if (useDefault) {
return (defaultValue);
} else {
return (null);
}
}
if (String.class.equals(type)) {
if ((value instanceof Date) && (dateFormats != null)) {
return (dateFormats[0].format((Date) value));
} else {
return (value.toString());
}
}
if (value instanceof Date) {
return (value);
}
try {
if (Date.class.isAssignableFrom(type) && dateFormats != null) {
return parseDate(value);
} else {
return (value.toString());
}
} catch (Exception e) {
if (useDefault) {
return (defaultValue);
} else {
throw new ConversionException(e);
}
}
}
protected Date parseDate(Object value) throws ParseException {
Date date = null;
int len = dateFormats.length;
for (int i = 0; i < len; i++) {
try {
date = (dateFormats[i].parse(value.toString()));
break;
} catch (ParseException e) {
// if this is the last format, throw the exception
if (i == (len - 1)) {
throw e;
}
}
}
return date;
}
}
/**
* <p>Standard {@link Converter} implementation that converts an incoming
* String into a <code>java.util.TimeZone</code> object throwing a
* {@link ConversionException} if a conversion error occurs.</p>
*/
public final class TimeZoneConverter implements Converter {
// ----------------------------------------------------------- Constructors
/**
* Create a {@link Converter} that will throw a {@link ConversionException}
* if a conversion error occurs.
*/
public TimeZoneConverter() {
}
// --------------------------------------------------------- Public Methods
/**
* Convert the specified input object into an output object of the
* specified type.
*
* @param type Data type to which this value should be converted
* @param value The input value to be converted
*
* @exception ConversionException if conversion cannot be performed
* successfully
*/
public Object convert(Class type, Object value) {
if (value == null) {
return (null);
}
if (value instanceof TimeZone) {
return (value);
}
try {
if (String.class.equals(value.getClass())) {
return (TimeZone.getTimeZone((String) value));
} else {
return (value.toString());
}
} catch (Exception e) {
throw new ConversionException(e);
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -