View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *     http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.chain;
18  
19  /**
20   * A {@link Command} encapsulates a unit of processing work to be
21   * performed, whose purpose is to examine and/or modify the state of a
22   * transaction that is represented by a {@link Context}. Individual
23   * {@link Command}s can be assembled into a {@link Chain}, which allows
24   * them to either complete the required processing or delegate further
25   * processing to the next {@link Command} in the {@link Chain}.
26   *
27   * <p>{@link Command} implementations should be designed in a thread-safe
28   * manner, suitable for inclusion in multiple {@link Chain}s that might be
29   * processed by different threads simultaneously. In general, this implies
30   * that {@link Command} classes should not maintain state information in
31   * instance variables. Instead, state information should be maintained via
32   * suitable modifications to the attributes of the {@link Context} that is
33   * passed to the {@code execute()} command.</p>
34   *
35   * <p>{@link Command} implementations typically retrieve and store state
36   * information in the {@link Context} instance that is passed as a parameter
37   * to the {@code execute()} method, using particular keys into the
38   * {@code Map} that can be acquired via {@code Context.getAttributes()}. To
39   * improve interoperability of {@link Command} implementations, a useful
40   * design pattern is to expose the key values used as JavaBeans properties
41   * of the {@link Command} implementation class itself. For example, a
42   * {@link Command} that requires an input and an output key might implement
43   * the following properties:</p>
44   *
45   * <pre>
46   *   private String inputKey = "input";
47   *   public String getInputKey() {
48   *     return this.inputKey;
49   *   }
50   *   public void setInputKey(String inputKey) {
51   *     this.inputKey = inputKey;
52   *   }
53   *
54   *   private String outputKey = "output";
55   *   public String getOutputKey() {
56   *     return this.outputKey;
57   *   }
58   *   public void setOutputKey(String outputKey) {
59   *     this.outputKey = outputKey;
60   *   }
61   * </pre>
62   *
63   * <p>And the operation of accessing the "input" information in the context
64   * would be executed by calling:</p>
65   *
66   * <pre>
67   *   String input = (String) context.get(getInputKey());
68   * </pre>
69   *
70   * <p>instead of hard coding the attribute name. The use of the "Key"
71   * suffix on such property names is a useful convention to identify properties
72   * being used in this fashion, as opposed to JavaBeans properties that simply
73   * configure the internal operation of this {@link Command}.</p>
74   *
75   * @param <C> Type of the context associated with this command
76   *
77   * @author Craig R. McClanahan
78   * @version $Revision$ $Date$
79   */
80  public interface Command<C extends Context> {
81  
82      /**
83       * Commands should return {@code CONTINUE_PROCESSING} if the processing
84       * of the given {@link Context} should be delegated to a subsequent
85       * {@link Command} in an enclosing {@link Chain}.
86       *
87       * @since Chain 1.1
88       */
89      boolean CONTINUE_PROCESSING = false;
90  
91      /**
92       * Commands should return {@code PROCESSING_COMPLETE}
93       * if the processing of the given {@link Context}
94       * has been completed.
95       *
96       * @since Chain 1.1
97       */
98      boolean PROCESSING_COMPLETE = true;
99  
100     /**
101      * Execute a unit of processing work to be performed. This
102      * {@link Command} may either complete the required processing
103      * and return {@code true}, or delegate remaining processing
104      * to the next {@link Command} in a {@link Chain} containing this
105      * {@link Command} by returning {@code false}.
106      *
107      * @param context The {@link Context} to be processed by this
108      *        {@link Command}
109      *
110      * @return {@code true} if the processing of this {@link Context}
111      *         has been completed, or {@code false} if the processing
112      *         of this {@link Context} should be delegated to a
113      *         subsequent {@link Command} in an enclosing {@link Chain}
114      *
115      * @throws Exception general purpose exception return
116      *         to indicate abnormal termination
117      * @throws IllegalArgumentException if {@code context}
118      *         is {@code null}
119      */
120     boolean execute(C context) throws Exception;
121 }