package er.quartzscheduler.util;
import java.lang.reflect.Constructor;
import org.quartz.Job;
import org.quartz.simpl.SimpleClassLoadHelper;
import er.quartzscheduler.foundation.ERQSJob;
import er.quartzscheduler.foundation.ERQSJobDescription;
import er.quartzscheduler.util.ERQSUtilities.COJobInstanciationException.ErrorType;
/**
* ERQSUtilities helps you to call the methods:
* <ul>
* <li>willDelete</li>
* <li>willSave</li>
* <li>validateForDelete</li>
* <li>validateForSave</li>
* </ul>
*
* by instantiating an object based on the job description class path.<p>
*
* You can call directly ERQSUtilities.willSave(myJobDescriptionEO) for example but an instance of the job will be create each time.
* You can also call createJobInstance(myJobDescriptionEO) and call the above methods yourself.<p>
* Because the job class is not necessarily a subclass of ERQSJob (it can be a sub class of ERQSAbstractJob or just implement
* the interface Job), the methods willDelete, willSave, validateForDelete, validateForSave checks if the instantiated object
* is a ERQSJob object. If not the object is just returned.
*
* @author Philippe Rabier
*
*/
public class ERQSUtilities
{
/**
* This exception is thrown if the class to be instantiate doesn't exist or if it can't be instantiate like a wrong constructor
* for example.<p>
* Rather than create a hierarchy of classes corresponding to each different errors, we preferred to add an error type
* that gives more information about the error.
*
* @author Philippe Rabier
* @see ErrorType
*/
public static class COJobInstanciationException extends Exception
{
public enum ErrorType
{
CLASS_NOT_FOUND,
CONSTRUCTOR_ERROR,
INSTANCE_ERROR;
}
private static final long serialVersionUID = 1L;
private final ErrorType errorType;
public COJobInstanciationException(final String message, final ErrorType type)
{
super(message);
errorType = type;
}
public COJobInstanciationException(final String msg, final ErrorType type, final Throwable cause)
{
super(msg, cause);
errorType = type;
}
public Throwable getUnderlyingException()
{
return super.getCause();
}
public ErrorType getErrorType()
{
return errorType;
}
@Override
public String toString()
{
Throwable cause = getUnderlyingException();
if (cause == null || cause == this)
return super.toString();
else
return new StringBuilder().append(super.toString()).append(" [See nested exception: ").append(cause).append(']').toString();
}
}
public static Job createJobInstance(final ERQSJobDescription jobDescription) throws COJobInstanciationException
{
if (jobDescription == null)
throw new IllegalArgumentException("jobDescription can't be null");
SimpleClassLoadHelper loader = new SimpleClassLoadHelper();
Class<? extends Job> aJobClass = null;
try
{
aJobClass = (Class<? extends Job>) loader.loadClass(jobDescription.classPath());
} catch (ClassNotFoundException e)
{
throw new COJobInstanciationException("Class " + jobDescription.classPath() + " not found.", ErrorType.CLASS_NOT_FOUND);
}
Constructor<? extends Job> constructor = null;
try
{
constructor = aJobClass.getConstructor();
} catch (Exception e)
{
throw new COJobInstanciationException("Class " + jobDescription.classPath() + " not found.", ErrorType.CONSTRUCTOR_ERROR, e);
}
Job aJob = null;
try
{
aJob = constructor.newInstance();
} catch (Exception e)
{
throw new COJobInstanciationException("Class " + jobDescription.classPath() + " not found.", ErrorType.INSTANCE_ERROR, e);
}
return aJob;
}
public static Job willDelete(final ERQSJobDescription jobDescription) throws COJobInstanciationException
{
Job aJob = createJobInstance(jobDescription);
if (aJob instanceof ERQSJob)
((ERQSJob)aJob).willDelete(jobDescription);
return aJob;
}
public static Job willSave(final ERQSJobDescription jobDescription) throws COJobInstanciationException
{
Job aJob = createJobInstance(jobDescription);
if (aJob instanceof ERQSJob)
((ERQSJob)aJob).willSave(jobDescription);
return aJob;
}
public static Job validateForDelete(final ERQSJobDescription jobDescription) throws COJobInstanciationException
{
Job aJob = createJobInstance(jobDescription);
if (aJob instanceof ERQSJob)
((ERQSJob)aJob).validateForDelete(jobDescription);
return aJob;
}
public static Job validateForSave(final ERQSJobDescription jobDescription) throws COJobInstanciationException
{
Job aJob = createJobInstance(jobDescription);
if (aJob instanceof ERQSJob)
((ERQSJob)aJob).validateForSave(jobDescription);
return aJob;
}
}