1 //----------------------------------------------------------------------
2 //
3 // PerfectJPattern: "Design patterns are good but components are better!"
4 // IHandler.java Copyright (c) 2009 Giovanni Azua Garcia
5 // bravegag@hotmail.com
6 //
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License
9 // as published by the Free Software Foundation; either version 3
10 // of the License, or (at your option) any later version.
11 //
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, see <http://www.gnu.org/licenses/>.
19 //
20 //----------------------------------------------------------------------
21 package org.perfectjpattern.core.api.behavioral.chainofresponsibility;
22
23 /**
24 * <b>Chain of Responsibility Design Pattern</b>: Avoid coupling the sender of
25 * a request to its receiver by giving more than one object a chance to handle
26 * the request. Chain the receiving objects and pass the request along the chain
27 * until an object handles it. (Gamma et al, Design Patterns)<br/>
28 * <br/>
29 *
30 * <b>Responsibility</b>: Abstract definition of the "Handler".
31 *
32 * <ul>
33 * <li>Defines an interface for handling requests.</li>
34 * <li>Implements the Successor link.</li>
35 * </ul>
36 *
37 * <br/>
38 * Example usage:
39 * <pre><code>
40 * //
41 * // Create chain elements
42 * //
43 * IHandler myFirst = new ConcreteHandler();
44 * IHandler mySecond = new ConcreteHandler();
45 * IHandler myThird = new ConcreteHandler();
46 *
47 * //
48 * // Associate Handler elements
49 * //
50 * myFirst.setSuccessor(mySecond);
51 * mySecond.setSuccessor(myThird);
52 *
53 * //
54 * // Execute the first Handler that triggers the execution of the
55 * // complete chain.
56 * //
57 * myFirst.start(NullRequest.getInstance());
58 * </code></pre>
59 *
60 * @param <R> Request parameter type
61 *
62 * @author <a href="mailto:bravegag@hotmail.com">Giovanni Azua</a>
63 * @version $Revision: 1.0 $ $Date: Jun 23, 2007 1:27:25 PM $
64 */
65 public
66 interface IHandler<R>
67 {
68 //------------------------------------------------------------------------
69 // public
70 //------------------------------------------------------------------------
71 /**
72 * Returns true if this <code>IHandler</code> can handle the given request,
73 * false otherwise.
74 *
75 * @param aRequest Context-specific request to handle.
76 * @return true if this <code>IHandler</code> can handle the given request,
77 * false otherwise.
78 * @throws IllegalArgumentException 'aRequest' must not be null.
79 */
80 public boolean
81 canHandle(R aRequest)
82 throws IllegalArgumentException;
83
84 //------------------------------------------------------------------------
85 /**
86 * Triggers execution of the Chain if the target Handler is the first
87 * reference, otherwise implements the decision-making regarding forwarding
88 * the request to its successor <code>IHandler</code> instance.
89 *
90 * @param aRequest Context-specific request to handle.
91 * @throws IllegalArgumentException 'aRequest' must not be null.
92 */
93 public void
94 start(R aRequest)
95 throws IllegalArgumentException;
96
97 //------------------------------------------------------------------------
98 /**
99 * Handle the given request. Implements the actual handling logic and must
100 * not contain any decision-making regarding e.g. forwarding the request.
101 *
102 * @param aRequest Context-specific request to handle.
103 * @throws IllegalArgumentException 'aRequest' must not be null.
104 * @throws IllegalArgumentException 'aRequest' can not be handled.
105 */
106 public void
107 handle(R aRequest)
108 throws IllegalArgumentException;
109
110 //------------------------------------------------------------------------
111 /**
112 * Returns the Successor handler.
113 *
114 * @return Successor handler.
115 */
116 public IHandler<R>
117 getSuccessor();
118
119 //------------------------------------------------------------------------
120 /**
121 * Sets the Successor element.
122 *
123 * @param aSuccessor Successor handler
124 * @throws IllegalArgumentException 'aSuccessor' must not be null.
125 */
126 public void
127 setSuccessor(IHandler<R> aSuccessor)
128 throws IllegalArgumentException;
129
130 //------------------------------------------------------------------------
131 /**
132 * Set the <code>IChainStrategy</code> to this <code>IHandler</code>.
133 * <code>IChainStrategy</code> allows to easily modify how the
134 * Chain should behave. Possible implementations are e.g.
135 * <ul>
136 * <li>Halt as soon as the first Handler processes the request</li>
137 * <li>Let all handlers process the request</li>
138 * <li>Let the first N handlers process the request</li>
139 * </ul>
140 *
141 * @param aStrategy Continuation strategy defines how the chain should
142 * behave
143 * @throws IllegalArgumentException 'aStrategy' must not be null.
144 */
145 public void
146 setChainStrategy(IChainStrategy aStrategy)
147 throws IllegalArgumentException;
148 }