View Javadoc

1   /*
2    * Copyright 1999-2004 The Apache Software Foundation
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.apache.commons.chain.generic;
17  
18  
19  import org.apache.commons.chain.Catalog;
20  import org.apache.commons.chain.CatalogFactory;
21  import org.apache.commons.chain.Command;
22  import org.apache.commons.chain.Context;
23  import org.apache.commons.chain.Filter;
24  
25  
26  /***
27   * <p>Look up a specified {@link Command} (which could also be a {@link Chain})
28   * in a {@link Catalog}, and delegate execution to it.  If the delegated-to
29   * {@link Command} is also a {@link Filter}, its <code>postprocess()</code>
30   * method will also be invoked at the appropriate time.</p>
31   *
32   * <p>The name of the {@link Command} can be specified either directly (via
33   * the <code>name</code> property) or indirectly (via the <code>nameKey</code>
34   * property).  Exactly one of these must be set.</p>
35   *
36   * <p>If the <code>optional</code> property is set to <code>true</code>,
37   * failure to find the specified command in the specified catalog will be
38   * silently ignored.  Otherwise, a lookup failure will trigger an
39   * <code>IllegalArgumentException</code>.</p>
40   *
41   * @author Craig R. McClanahan
42   * @version $Revision: 1.10 $ $Date: 2004/11/30 05:52:23 $
43   */
44  
45  public class LookupCommand implements Filter {
46  
47  
48      // -------------------------------------------------------------- Properties
49  
50  
51      private String catalogName = null;
52  
53  
54      /***
55       * <p>Return the name of the {@link Catalog} to be searched, or
56       * <code>null</code> to search the default {@link Catalog}.</p>
57       */
58      public String getCatalogName() {
59  
60          return (this.catalogName);
61  
62      }
63  
64  
65      /***
66       * <p>Set the name of the {@link Catalog} to be searched, or
67       * <code>null</code> to search the default {@link Catalog}.</p>
68       *
69       * @param catalogName The new {@link Catalog} name or <code>null</code>
70       */
71      public void setCatalogName(String catalogName) {
72  
73          this.catalogName = catalogName;
74  
75      }
76  
77  
78      private String name = null;
79  
80  
81      /***
82       * <p>Return the name of the {@link Command} that we will look up and
83       * delegate execution to.</p>
84       */
85      public String getName() {
86  
87          return (this.name);
88  
89      }
90  
91  
92      /***
93       * <p>Set the name of the {@link Command} that we will look up and
94       * delegate execution to.</p>
95       *
96       * @param name The new command name
97       */
98      public void setName(String name) {
99  
100         this.name = name;
101 
102     }
103 
104 
105     private String nameKey = null;
106 
107 
108     /***
109      * <p>Return the context attribute key under which the {@link Command}
110      * name is stored.</p>
111      */
112     public String getNameKey() {
113 
114         return (this.nameKey);
115 
116     }
117 
118 
119     /***
120      * <p>Set the context attribute key under which the {@link Command}
121      * name is stored.</p>
122      *
123      * @param nameKey The new context attribute key
124      */
125     public void setNameKey(String nameKey) {
126 
127         this.nameKey = nameKey;
128 
129     }
130 
131 
132     private boolean optional = false;
133 
134 
135     /***
136      * <p>Return <code>true</code> if locating the specified command
137      * is optional.</p>
138      */
139     public boolean isOptional() {
140 
141         return (this.optional);
142 
143     }
144 
145 
146     /***
147      * <p>Set the optional flag for finding the specified command.</p>
148      *
149      * @param optional The new optional flag
150      */
151     public void setOptional(boolean optional) {
152 
153         this.optional = optional;
154 
155     }
156 
157 
158 
159     // ---------------------------------------------------------- Filter Methods
160 
161 
162     /***
163      * <p>Look up the specified command, and (if found) execute it.</p>
164      *
165      * @param context The context for this request
166      *
167      * @exception IllegalArgumentException if no such {@link Command}
168      *  can be found and the <code>optional</code> property is set
169      *  to <code>false</code>
170      */
171     public boolean execute(Context context) throws Exception {
172 
173         Command command = getCommand(context);
174         if (command != null) {
175             return (command.execute(context));
176         } else {
177             return (false);
178         }
179 
180     }
181 
182 
183     /***
184      * <p>If the executed command was itself a {@link Filter}, call the
185      * <code>postprocess()</code> method of that {@link Filter} as well.</p>
186      *
187      * @param context The context for this request
188      * @param exception Any <code>Exception</code> thrown by command execution
189      *
190      * @exception Exception if thrown by the <code>postprocess()</code> method
191      */
192     public boolean postprocess(Context context, Exception exception) {
193 
194         Command command = getCommand(context);
195         if (command != null) {
196             if (command instanceof Filter) {
197                 return (((Filter) command).postprocess(context, exception));
198             }
199         }
200         return (false);
201 
202     }
203 
204 
205     // --------------------------------------------------------- Private Methods
206 
207 
208     /***
209      * <p>Return the {@link Command} instance to be delegated to.</p>
210      *
211      * @param context {@link Context} for this request
212      *
213      * @exception IllegalArgumentException if no such {@link Command}
214      *  can be found and the <code>optional</code> property is set
215      *  to <code>false</code>
216      */
217     private Command getCommand(Context context) {
218 
219         CatalogFactory catalogFactory = CatalogFactory.getInstance();
220         String catalogName = getCatalogName();
221         Catalog catalog = null;
222         if (catalogName == null) {
223             // use default catalog
224             catalog = catalogFactory.getCatalog();
225         } else {
226             catalog = catalogFactory.getCatalog(catalogName);
227         }
228         if (catalog == null) {
229             if (catalogName == null) {
230                 throw new IllegalArgumentException
231                     ("Cannot find default catalog");
232             } else {
233                 throw new IllegalArgumentException
234                     ("Cannot find catalog '" + catalogName + "'");
235             }
236         }
237 
238         Command command = null;
239         String name = getName();
240         if (name == null) {
241             name = (String) context.get(getNameKey());
242         }
243         if (name != null) {
244             command = catalog.getCommand(name);
245             if ((command == null) && !isOptional()) {
246                 if (catalogName == null) {
247                     throw new IllegalArgumentException
248                         ("Cannot find command '" + name
249                          + "' in default catalog");
250                 } else {
251                     throw new IllegalArgumentException
252                         ("Cannot find command '" + name
253                          + "' in catalog '" + catalogName + "'");
254                 }
255             }
256             return (command);
257         } else {
258             throw new IllegalArgumentException("No command name");
259         }
260 
261     }
262 
263 
264 }