View Javadoc
1   /**
2    * This file Copyright (c) 2013-2018 Magnolia International
3    * Ltd.  (http://www.magnolia-cms.com). All rights reserved.
4    *
5    *
6    * This file is dual-licensed under both the Magnolia
7    * Network Agreement and the GNU General Public License.
8    * You may elect to use one or the other of these licenses.
9    *
10   * This file is distributed in the hope that it will be
11   * useful, but AS-IS and WITHOUT ANY WARRANTY; without even the
12   * implied warranty of MERCHANTABILITY or FITNESS FOR A
13   * PARTICULAR PURPOSE, TITLE, or NONINFRINGEMENT.
14   * Redistribution, except as permitted by whichever of the GPL
15   * or MNA you select, is prohibited.
16   *
17   * 1. For the GPL license (GPL), you can redistribute and/or
18   * modify this file under the terms of the GNU General
19   * Public License, Version 3, as published by the Free Software
20   * Foundation.  You should have received a copy of the GNU
21   * General Public License, Version 3 along with this program;
22   * if not, write to the Free Software Foundation, Inc., 51
23   * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
24   *
25   * 2. For the Magnolia Network Agreement (MNA), this file
26   * and the accompanying materials are made available under the
27   * terms of the MNA which accompanies this distribution, and
28   * is available at http://www.magnolia-cms.com/mna.html
29   *
30   * Any modifications to this file must keep this entire header
31   * intact.
32   *
33   */
34  package info.magnolia.commands.chain;
35  
36  import java.util.Collection;
37  import java.util.Collections;
38  import java.util.LinkedList;
39  import java.util.List;
40  
41  import org.slf4j.Logger;
42  import org.slf4j.LoggerFactory;
43  
44  
45  /**
46   * Replacement for org.apache.commons.chain.impl.ChainBase. Base Chain
47   * implementation.
48   */
49  public class ChainBase implements Chain {
50  
51      private final static Logger log = LoggerFactory.getLogger(ChainBase.class);
52  
53      protected List<Command> commands = new LinkedList<Command>();
54  
55      protected boolean frozen = false;
56  
57      public ChainBase() {
58      }
59  
60      public ChainBase(Command command) {
61          addCommand(command);
62      }
63  
64      public ChainBase(Command... commands) {
65          for (Command command : commands) {
66              addCommand(command);
67          }
68      }
69  
70      public ChainBase(Collection<Command> commands) {
71          this(commands.toArray(new Command[0]));
72      }
73  
74      @Override
75      public void addCommand(Command command) {
76          if (command == null) {
77              throw new IllegalArgumentException();
78          }
79          if (frozen) {
80              throw new IllegalStateException();
81          }
82          commands.add(command);
83      }
84  
85      @Override
86      public boolean execute(Context context) throws Exception {
87          // Verify our parameters
88          if (context == null) {
89              throw new IllegalArgumentException();
90          }
91          // Freeze the configuration of the command list
92          frozen = true;
93          // Execute the commands in this list until one returns true
94          // or throws an exception
95          boolean saveResult = false;
96          Exception saveException = null;
97          int i = 0;
98          int n = commands.size();
99          for (i = 0; i < n; i++) {
100             try {
101                 saveResult = commands.get(i).execute(context);
102                 if (saveResult) {
103                     break;
104                 }
105             } catch (Exception e) {
106                 saveException = e;
107                 break;
108             }
109         }
110         // Call postprocess methods on Filters in reverse order
111         if (i >= n) { // Fell off the end of the chain
112             i--;
113         }
114         boolean handled = false;
115         boolean result = false;
116         for (int j = i; j >= 0; j--) {
117             if (commands.get(j) instanceof Filter) {
118                 try {
119                     result = ((Filter) commands.get(j)).postprocess(context, saveException);
120                     if (result) {
121                         handled = true;
122                     }
123                 } catch (Exception e) {
124                     // Silently ignore
125                 }
126             }
127         }
128         // Return the exception or result state from the last execute()
129         if ((saveException != null) && !handled) {
130             throw saveException;
131         }
132         return (saveResult);
133     }
134 
135     /**
136      * Returns <b>unmodifiable</b> list of commands.
137      */
138     public List<Command> getCommands() {
139         return Collections.unmodifiableList(commands);
140     }
141 
142     @Override
143     public Command clone() throws CloneNotSupportedException {
144         ChainBaseChainBase.html#ChainBase">ChainBase copy = new ChainBase();
145         for (Command c : this.commands) {
146             copy.addCommand(c.clone());
147         }
148         return copy;
149     }
150 
151 }