Home » commons-chain-1.2-src » org.apache.commons » chain » impl » [javadoc | source]
    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.impl;
   18   
   19   
   20   import java.util.Collection;
   21   import java.util.Iterator;
   22   import org.apache.commons.chain.Chain;
   23   import org.apache.commons.chain.Command;
   24   import org.apache.commons.chain.Context;
   25   import org.apache.commons.chain.Filter;
   26   
   27   
   28   /**
   29    * <p>Convenience base class for {@link Chain} implementations.</p>
   30    *
   31    * @author Craig R. McClanahan
   32    * @version $Revision: 480477 $ $Date: 2006-11-29 08:34:52 +0000 (Wed, 29 Nov 2006) $
   33    */
   34   
   35   public class ChainBase implements Chain {
   36   
   37   
   38       // ----------------------------------------------------------- Constructors
   39   
   40   
   41       /**
   42        * <p>Construct a {@link Chain} with no configured {@link Command}s.</p>
   43        */
   44       public ChainBase() {
   45   
   46       }
   47   
   48   
   49       /**
   50        * <p>Construct a {@link Chain} configured with the specified
   51        * {@link Command}.</p>
   52        *
   53        * @param command The {@link Command} to be configured
   54        *
   55        * @exception IllegalArgumentException if <code>command</code>
   56        *  is <code>null</code>
   57        */
   58       public ChainBase(Command command) {
   59   
   60           addCommand(command);
   61   
   62       }
   63   
   64   
   65       /**
   66        * <p>Construct a {@link Chain} configured with the specified
   67        * {@link Command}s.</p>
   68        *
   69        * @param commands The {@link Command}s to be configured
   70        *
   71        * @exception IllegalArgumentException if <code>commands</code>,
   72        *  or one of the individual {@link Command} elements,
   73        *  is <code>null</code>
   74        */
   75       public ChainBase(Command[] commands) {
   76   
   77           if (commands == null) {
   78               throw new IllegalArgumentException();
   79           }
   80           for (int i = 0; i < commands.length; i++) {
   81               addCommand(commands[i]);
   82           }
   83   
   84       }
   85   
   86   
   87       /**
   88        * <p>Construct a {@link Chain} configured with the specified
   89        * {@link Command}s.</p>
   90        *
   91        * @param commands The {@link Command}s to be configured
   92        *
   93        * @exception IllegalArgumentException if <code>commands</code>,
   94        *  or one of the individual {@link Command} elements,
   95        *  is <code>null</code>
   96        */
   97       public ChainBase(Collection commands) {
   98   
   99           if (commands == null) {
  100               throw new IllegalArgumentException();
  101           }
  102           Iterator elements = commands.iterator();
  103           while (elements.hasNext()) {
  104               addCommand((Command) elements.next());
  105           }
  106   
  107       }
  108   
  109   
  110       // ----------------------------------------------------- Instance Variables
  111   
  112   
  113       /**
  114        * <p>The list of {@link Command}s configured for this {@link Chain}, in
  115        * the order in which they may delegate processing to the remainder of
  116        * the {@link Chain}.</p>
  117        */
  118       protected Command[] commands = new Command[0];
  119   
  120   
  121       /**
  122        * <p>Flag indicating whether the configuration of our commands list
  123        * has been frozen by a call to the <code>execute()</code> method.</p>
  124        */
  125       protected boolean frozen = false;
  126   
  127   
  128       // ---------------------------------------------------------- Chain Methods
  129   
  130   
  131       /**
  132        * See the {@link Chain} JavaDoc.
  133        *
  134        * @param command The {@link Command} to be added
  135        *
  136        * @exception IllegalArgumentException if <code>command</code>
  137        *  is <code>null</code>
  138        * @exception IllegalStateException if no further configuration is allowed
  139        */
  140       public void addCommand(Command command) {
  141   
  142           if (command == null) {
  143               throw new IllegalArgumentException();
  144           }
  145           if (frozen) {
  146               throw new IllegalStateException();
  147           }
  148           Command[] results = new Command[commands.length + 1];
  149           System.arraycopy(commands, 0, results, 0, commands.length);
  150           results[commands.length] = command;
  151           commands = results;
  152   
  153       }
  154   
  155   
  156       /**
  157        * See the {@link Chain} JavaDoc.
  158        *
  159        * @param context The {@link Context} to be processed by this
  160        *  {@link Chain}
  161        *
  162        * @throws Exception if thrown by one of the {@link Command}s
  163        *  in this {@link Chain} but not handled by a <code>postprocess()</code>
  164        *  method of a {@link Filter}
  165        * @throws IllegalArgumentException if <code>context</code>
  166        *  is <code>null</code>
  167        *
  168        * @return <code>true</code> if the processing of this {@link Context}
  169        *  has been completed, or <code>false</code> if the processing
  170        *  of this {@link Context} should be delegated to a subsequent
  171        *  {@link Command} in an enclosing {@link Chain}
  172        */
  173       public boolean execute(Context context) throws Exception {
  174   
  175           // Verify our parameters
  176           if (context == null) {
  177               throw new IllegalArgumentException();
  178           }
  179   
  180           // Freeze the configuration of the command list
  181           frozen = true;
  182   
  183           // Execute the commands in this list until one returns true
  184           // or throws an exception
  185           boolean saveResult = false;
  186           Exception saveException = null;
  187           int i = 0;
  188           int n = commands.length;
  189           for (i = 0; i < n; i++) {
  190               try {
  191                   saveResult = commands[i].execute(context);
  192                   if (saveResult) {
  193                       break;
  194                   }
  195               } catch (Exception e) {
  196                   saveException = e;
  197                   break;
  198               }
  199           }
  200   
  201           // Call postprocess methods on Filters in reverse order
  202           if (i >= n) { // Fell off the end of the chain
  203               i--;
  204           }
  205           boolean handled = false;
  206           boolean result = false;
  207           for (int j = i; j >= 0; j--) {
  208               if (commands[j] instanceof Filter) {
  209                   try {
  210                       result =
  211                           ((Filter) commands[j]).postprocess(context,
  212                                                              saveException);
  213                       if (result) {
  214                           handled = true;
  215                       }
  216                   } catch (Exception e) {
  217                         // Silently ignore
  218                   }
  219               }
  220           }
  221   
  222           // Return the exception or result state from the last execute()
  223           if ((saveException != null) && !handled) {
  224               throw saveException;
  225           } else {
  226               return (saveResult);
  227           }
  228   
  229       }
  230   
  231   
  232       // -------------------------------------------------------- Package Methods
  233   
  234   
  235       /**
  236        * <p>Return an array of the configured {@link Command}s for this
  237        * {@link Chain}.  This method is package private, and is used only
  238        * for the unit tests.</p>
  239        */
  240       Command[] getCommands() {
  241   
  242           return (commands);
  243   
  244       }
  245   
  246   
  247   }

Save This Page
Home » commons-chain-1.2-src » org.apache.commons » chain » impl » [javadoc | source]