001: /*
002: * Copyright 2004-2006 OpenSymphony
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License"); you may not
005: * use this file except in compliance with the License. You may obtain a copy
006: * 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, WITHOUT
012: * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
013: * License for the specific language governing permissions and limitations
014: * under the License.
015: */
016: package org.quartz.listeners;
017:
018: import java.util.LinkedList;
019: import java.util.List;
020: import java.util.Iterator;
021:
022: import org.quartz.JobListener;
023: import org.quartz.JobExecutionContext;
024: import org.quartz.JobExecutionException;
025: import org.quartz.JobDetail;
026:
027: /**
028: * Holds a List of references to JobListener instances and broadcasts all
029: * events to them (in order) - if the event is not excluded via filtering
030: * (read on).
031: *
032: * <p>The broadcasting behavior of this listener to delegate listeners may be
033: * more convenient than registering all of the listeners directly with the
034: * Trigger, and provides the flexibility of easily changing which listeners
035: * get notified.</p>
036: *
037: * <p>You may also register a number of Regular Expression patterns to match
038: * the events against. If one or more patterns are registered, the broadcast
039: * will only take place if the event applies to a job who's name/group
040: * matches one or more of the patterns.</p>
041: *
042: * @see #addListener(org.quartz.JobListener)
043: * @see #removeListener(org.quartz.JobListener)
044: * @see #removeListener(String)
045: * @see #addJobNamePattern(String)
046: * @see #addJobGroupPattern(String)
047: *
048: * @author James House (jhouse AT revolition DOT net)
049: */
050: public class FilterAndBroadcastJobListener implements JobListener {
051:
052: private String name;
053: private List listeners;
054: private List namePatterns = new LinkedList();
055: private List groupPatterns = new LinkedList();
056:
057: /**
058: * Construct an instance with the given name.
059: *
060: * (Remember to add some delegate listeners!)
061: *
062: * @param name the name of this instance
063: */
064: public FilterAndBroadcastJobListener(String name) {
065: if (name == null)
066: throw new IllegalArgumentException(
067: "Listener name cannot be null!");
068: this .name = name;
069: listeners = new LinkedList();
070: }
071:
072: /**
073: * Construct an instance with the given name, and List of listeners.
074: *
075: * @param name the name of this instance
076: * @param listeners the initial List of JobListeners to broadcast to.
077: */
078: public FilterAndBroadcastJobListener(String name, List listeners) {
079: this (name);
080: this .listeners.addAll(listeners);
081: }
082:
083: public String getName() {
084: return name;
085: }
086:
087: public void addListener(JobListener listener) {
088: listeners.add(listener);
089: }
090:
091: public boolean removeListener(JobListener listener) {
092: return listeners.remove(listener);
093: }
094:
095: public boolean removeListener(String listenerName) {
096: Iterator itr = listeners.iterator();
097: while (itr.hasNext()) {
098: JobListener jl = (JobListener) itr.next();
099: if (jl.getName().equals(listenerName)) {
100: itr.remove();
101: return true;
102: }
103: }
104: return false;
105: }
106:
107: public List getListeners() {
108: return java.util.Collections.unmodifiableList(listeners);
109: }
110:
111: /**
112: * If one or more name patterns are specified, only events relating to
113: * jobs who's name matches the given regular expression pattern
114: * will be dispatched to the delegate listeners.
115: *
116: * @param regularExpression
117: */
118: public void addJobNamePattern(String regularExpression) {
119: if (regularExpression == null)
120: throw new IllegalArgumentException(
121: "Expression cannot be null!");
122:
123: namePatterns.add(regularExpression);
124: }
125:
126: public List getJobNamePatterns() {
127: return namePatterns;
128: }
129:
130: /**
131: * If one or more group patterns are specified, only events relating to
132: * jobs who's group matches the given regular expression pattern
133: * will be dispatched to the delegate listeners.
134: *
135: * @param regularExpression
136: */
137: public void addJobGroupPattern(String regularExpression) {
138: if (regularExpression == null)
139: throw new IllegalArgumentException(
140: "Expression cannot be null!");
141:
142: groupPatterns.add(regularExpression);
143: }
144:
145: public List getJobGroupPatterns() {
146: return namePatterns;
147: }
148:
149: protected boolean shouldDispatch(JobExecutionContext context) {
150: JobDetail job = context.getJobDetail();
151:
152: if (namePatterns.size() == 0 && groupPatterns.size() == 0)
153: return true;
154:
155: Iterator itr = groupPatterns.iterator();
156: while (itr.hasNext()) {
157: String pat = (String) itr.next();
158: if (job.getGroup().matches(pat))
159: return true;
160: }
161:
162: itr = namePatterns.iterator();
163: while (itr.hasNext()) {
164: String pat = (String) itr.next();
165: if (job.getName().matches(pat))
166: return true;
167: }
168:
169: return false;
170: }
171:
172: public void jobToBeExecuted(JobExecutionContext context) {
173:
174: if (!shouldDispatch(context))
175: return;
176:
177: Iterator itr = listeners.iterator();
178: while (itr.hasNext()) {
179: JobListener jl = (JobListener) itr.next();
180: jl.jobToBeExecuted(context);
181: }
182: }
183:
184: public void jobExecutionVetoed(JobExecutionContext context) {
185:
186: if (!shouldDispatch(context))
187: return;
188:
189: Iterator itr = listeners.iterator();
190: while (itr.hasNext()) {
191: JobListener jl = (JobListener) itr.next();
192: jl.jobExecutionVetoed(context);
193: }
194: }
195:
196: public void jobWasExecuted(JobExecutionContext context,
197: JobExecutionException jobException) {
198:
199: if (!shouldDispatch(context))
200: return;
201:
202: Iterator itr = listeners.iterator();
203: while (itr.hasNext()) {
204: JobListener jl = (JobListener) itr.next();
205: jl.jobWasExecuted(context, jobException);
206: }
207: }
208:
209: }
|