Package org.quartz

Source Code of org.quartz.JobDetail

/*
* Copyright 2004-2005 OpenSymphony
*
* 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.
*
*/

/*
* Previously Copyright (c) 2001-2004 James House
*/
package org.quartz;

import java.util.HashSet;
import java.util.Set;

import org.apache.commons.collections.SetUtils;
import org.quartz.utils.Key;

/**
* <p>
* Conveys the detail properties of a given <code>Job</code> instance.
* </p>
*
* <p>
* Quartz does not store an actual instance of a <code>Job</code> class, but
* instead allows you to define an instance of one, through the use of a <code>JobDetail</code>.
* </p>
*
* <p>
* <code>Job</code>s have a name and group associated with them, which
* should uniquely identify them within a single <code>{@link Scheduler}</code>.
* </p>
*
* <p>
* <code>Trigger</code>s are the 'mechanism' by which <code>Job</code>s
* are scheduled. Many <code>Trigger</code>s can point to the same <code>Job</code>,
* but a single <code>Trigger</code> can only point to one <code>Job</code>.
* </p>
*
* @see Job
* @see StatefulJob
* @see JobDataMap
* @see Trigger
*
* @author James House
* @author Sharada Jambula
*/
public class JobDetail implements Cloneable, java.io.Serializable {

    /*
     * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     *
     * Data members.
     *
     * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     */

    private String name;

    private String group = Scheduler.DEFAULT_GROUP;

    private String description;

    private Class jobClass;

    private JobDataMap jobDataMap;

    private boolean volatility = false;

    private boolean durability = false;

    private boolean shouldRecover = false;

    private Set jobListeners = SetUtils.orderedSet(new HashSet());

    private transient Key key = null;

    /*
    * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    *
    * Constructors.
    *
    * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    */

    /**
     * <p>
     * Create a <code>JobDetail</code> with no specified name or group, and
     * the default settings of all the other properties.
     * </p>
     *
     * <p>
     * Note that the {@link #setName(String)},{@link #setGroup(String)}and
     * {@link #setJobClass(Class)}methods must be called before the job can be
     * placed into a {@link Scheduler}
     * </p>
     */
    public JobDetail() {
        // do nothing...
    }

    /**
     * <p>
     * Create a <code>JobDetail</code> with the given name, and group, and
     * the default settings of all the other properties.
     * </p>
     *
     * @param group if <code>null</code>, Scheduler.DEFAULT_GROUP will be used.
     *
     * @exception IllegalArgumentException
     *              if nameis null or empty, or the group is an empty string.
     */
    public JobDetail(String name, String group, Class jobClass) {
        setName(name);
        setGroup(group);
        setJobClass(jobClass);
    }

    /**
     * <p>
     * Create a <code>JobDetail</code> with the given name, and group, and
     * the given settings of all the other properties.
     * </p>
     *
     * @param group if <code>null</code>, Scheduler.DEFAULT_GROUP will be used.
     *
     * @exception IllegalArgumentException
     *              if nameis null or empty, or the group is an empty string.
     */
    public JobDetail(String name, String group, Class jobClass,
                     boolean volatility, boolean durability, boolean recover) {
        setName(name);
        setGroup(group);
        setJobClass(jobClass);
        setVolatility(volatility);
        setDurability(durability);
        setRequestsRecovery(recover);
    }

    /*
     * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     *
     * Interface.
     *
     * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     */

    /**
     * <p>
     * Get the name of this <code>Job</code>.
     * </p>
     */
    public String getName() {
        return name;
    }

    /**
     * <p>
     * Set the name of this <code>Job</code>.
     * </p>
     *
     * @exception IllegalArgumentException
     *              if name is null or empty.
     */
    public void setName(String name) {
        if (name == null || name.trim().length() == 0) {
            throw new IllegalArgumentException("Job name cannot be empty.");
        }

        this.name = name;
    }

    /**
     * <p>
     * Get the group of this <code>Job</code>.
     * </p>
     */
    public String getGroup() {
        return group;
    }

    /**
     * <p>
     * Set the group of this <code>Job</code>.
     * </p>
     *
     * @param group if <code>null</code>, Scheduler.DEFAULT_GROUP will be used.
     *
     * @exception IllegalArgumentException
     *              if the group is an empty string.
     */
    public void setGroup(String group) {
        if (group != null && group.trim().length() == 0) {
            throw new IllegalArgumentException(
                    "Group name cannot be empty.");
        }

        if (group == null) {
            group = Scheduler.DEFAULT_GROUP;
        }

        this.group = group;
    }

    /**
     * <p>
     * Returns the 'full name' of the <code>JobDetail</code> in the format
     * "group.name".
     * </p>
     */
    public String getFullName() {
        return group + "." + name;
    }

    public Key getKey() {
        if(key == null) {
            key = new Key(getName(), getGroup());
        }

        return key;
    }

    /**
     * <p>
     * Return the description given to the <code>Job</code> instance by its
     * creator (if any).
     * </p>
     *
     * @return null if no description was set.
     */
    public String getDescription() {
        return description;
    }

    /**
     * <p>
     * Set a description for the <code>Job</code> instance - may be useful
     * for remembering/displaying the purpose of the job, though the
     * description has no meaning to Quartz.
     * </p>
     */
    public void setDescription(String description) {
        this.description = description;
    }

    /**
     * <p>
     * Get the instance of <code>Job</code> that will be executed.
     * </p>
     */
    public Class getJobClass() {
        return jobClass;
    }

    /**
     * <p>
     * Set the instance of <code>Job</code> that will be executed.
     * </p>
     *
     * @exception IllegalArgumentException
     *              if jobClass is null or the class is not a <code>Job</code>.
     */
    public void setJobClass(Class jobClass) {
        if (jobClass == null) {
            throw new IllegalArgumentException("Job class cannot be null.");
        }

        if (!Job.class.isAssignableFrom(jobClass)) {
            throw new IllegalArgumentException(
                    "Job class must implement the Job interface.");
        }

        this.jobClass = jobClass;
    }

    /**
     * <p>
     * Get the <code>JobDataMap</code> that is associated with the <code>Job</code>.
     * </p>
     */
    public JobDataMap getJobDataMap() {
        if (jobDataMap == null) {
            jobDataMap = new JobDataMap();
        }
        return jobDataMap;
    }

    /**
     * <p>
     * Set the <code>JobDataMap</code> to be associated with the <code>Job</code>.
     * </p>
     */
    public void setJobDataMap(JobDataMap jobDataMap) {
        this.jobDataMap = jobDataMap;
    }

    /**
     * <p>
     * Validates whether the properties of the <code>JobDetail</code> are
     * valid for submission into a <code>Scheduler</code>.
     *
     * @throws IllegalStateException
     *           if a required property (such as Name, Group, Class) is not
     *           set.
     */
    public void validate() throws SchedulerException {
        if (name == null) {
            throw new SchedulerException("Job's name cannot be null",
                    SchedulerException.ERR_CLIENT_ERROR);
        }

        if (group == null) {
            throw new SchedulerException("Job's group cannot be null",
                    SchedulerException.ERR_CLIENT_ERROR);
        }

        if (jobClass == null) {
            throw new SchedulerException("Job's class cannot be null",
                    SchedulerException.ERR_CLIENT_ERROR);
        }
    }

    /**
     * <p>
     * Set whether or not the <code>Job</code> should be persisted in the
     * <code>{@link org.quartz.spi.JobStore}</code> for re-use after program
     * restarts.
     * </p>
     *
     * <p>
     * If not explicitly set, the default value is <code>false</code>.
     * </p>
     */
    public void setVolatility(boolean volatility) {
        this.volatility = volatility;
    }

    /**
     * <p>
     * Set whether or not the <code>Job</code> should remain stored after it
     * is orphaned (no <code>{@link Trigger}s</code> point to it).
     * </p>
     *
     * <p>
     * If not explicitly set, the default value is <code>false</code>.
     * </p>
     */
    public void setDurability(boolean durability) {
        this.durability = durability;
    }

    /**
     * <p>
     * Set whether or not the the <code>Scheduler</code> should re-execute
     * the <code>Job</code> if a 'recovery' or 'fail-over' situation is
     * encountered.
     * </p>
     *
     * <p>
     * If not explicitly set, the default value is <code>false</code>.
     * </p>
     *
     * @see JobExecutionContext#isRecovering()
     */
    public void setRequestsRecovery(boolean shouldRecover) {
        this.shouldRecover = shouldRecover;
    }

    /**
     * <p>
     * Whether or not the <code>Job</code> should not be persisted in the
     * <code>{@link org.quartz.spi.JobStore}</code> for re-use after program
     * restarts.
     * </p>
     *
     * <p>
     * If not explicitly set, the default value is <code>false</code>.
     * </p>
     *
     * @return <code>true</code> if the <code>Job</code> should be garbage
     *         collected along with the <code>{@link Scheduler}</code>.
     */
    public boolean isVolatile() {
        return volatility;
    }

    /**
     * <p>
     * Whether or not the <code>Job</code> should remain stored after it is
     * orphaned (no <code>{@link Trigger}s</code> point to it).
     * </p>
     *
     * <p>
     * If not explicitly set, the default value is <code>false</code>.
     * </p>
     *
     * @return <code>true</code> if the Job should remain persisted after
     *         being orphaned.
     */
    public boolean isDurable() {
        return durability;
    }

    /**
     * <p>
     * Whether or not the <code>Job</code> implements the interface <code>{@link StatefulJob}</code>.
     * </p>
     */
    public boolean isStateful() {
        if (jobClass == null) {
            return false;
        }

        return (StatefulJob.class.isAssignableFrom(jobClass));
    }

    /**
     * <p>
     * Instructs the <code>Scheduler</code> whether or not the <code>Job</code>
     * should be re-executed if a 'recovery' or 'fail-over' situation is
     * encountered.
     * </p>
     *
     * <p>
     * If not explicitly set, the default value is <code>false</code>.
     * </p>
     *
     * @see JobExecutionContext#isRecovering()
     */
    public boolean requestsRecovery() {
        return shouldRecover;
    }

    /**
     * <p>
     * Add the specified name of a <code>{@link JobListener}</code> to the
     * end of the <code>Job</code>'s list of listeners.
     * </p>
     */
    public void addJobListener(String name) {
        if (jobListeners.add(name) == false) {
            throw new IllegalArgumentException(
                "Job listener '" + name + "' is already registered for job detail: " + getFullName());
        }
    }

    /**
     * <p>
     * Remove the specified name of a <code>{@link JobListener}</code> from
     * the <code>Job</code>'s list of listeners.
     * </p>
     *
     * @return true if the given name was found in the list, and removed
     */
    public boolean removeJobListener(String name) {
        return jobListeners.remove(name);
    }

    /**
     * <p>
     * Returns an array of <code>String</code> s containing the names of all
     * <code>{@link JobListener}</code>s assigned to the <code>Job</code>,
     * in the order in which they should be notified.
     * </p>
     */
    public String[] getJobListenerNames() {
        return (String[])jobListeners.toArray(new String[jobListeners.size()]);
    }

    /**
     * <p>
     * Return a simple string representation of this object.
     * </p>
     */
    public String toString() {
        return "JobDetail '" + getFullName() + "':  jobClass: '"
                + ((getJobClass() == null) ? null : getJobClass().getName())
                + " isStateful: " + isStateful() + " isVolatile: "
                + isVolatile() + " isDurable: " + isDurable()
                + " requestsRecovers: " + requestsRecovery();
    }

    public boolean equals(Object obj) {
        if (!(obj instanceof JobDetail)) {
            return false;
        }

        JobDetail other = (JobDetail) obj;

        if (other.getName() == null && getName() != null) {
            return false;
        }
        if (other.getName() != null && !other.getName().equals(getName())) {
            return false;
        }
       
        if (other.getGroup() == null && getGroup() != null) {
          return false;
        }
        if (other.getGroup() != null && !other.getGroup().equals(getGroup())) {
          return false;
        }
         
        return true;
    }

    public int hashCode() {
        return getFullName().hashCode();
    }
   
    public Object clone() {
        JobDetail copy;
        try {
            copy = (JobDetail) super.clone();
            copy.jobListeners = SetUtils.orderedSet(new HashSet());
            copy.jobListeners.addAll(jobListeners);
            if (jobDataMap != null) {
                copy.jobDataMap = (JobDataMap) jobDataMap.clone();
            }
        } catch (CloneNotSupportedException ex) {
            throw new IncompatibleClassChangeError("Not Cloneable.");
        }

        return copy;
    }
}
TOP

Related Classes of org.quartz.JobDetail

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.