KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > jcorporate > expresso > ext > struts > taglib > ControllerUtils


1 /* ====================================================================
2  * The Jcorporate Apache Style Software License, Version 1.2 05-07-2002
3  *
4  * Copyright (c) 1995-2002 Jcorporate Ltd. All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  * notice, this list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright
14  * notice, this list of conditions and the following disclaimer in
15  * the documentation and/or other materials provided with the
16  * distribution.
17  *
18  * 3. The end-user documentation included with the redistribution,
19  * if any, must include the following acknowledgment:
20  * "This product includes software developed by Jcorporate Ltd.
21  * (http://www.jcorporate.com/)."
22  * Alternately, this acknowledgment may appear in the software itself,
23  * if and wherever such third-party acknowledgments normally appear.
24  *
25  * 4. "Jcorporate" and product names such as "Expresso" must
26  * not be used to endorse or promote products derived from this
27  * software without prior written permission. For written permission,
28  * please contact info@jcorporate.com.
29  *
30  * 5. Products derived from this software may not be called "Expresso",
31  * or other Jcorporate product names; nor may "Expresso" or other
32  * Jcorporate product names appear in their name, without prior
33  * written permission of Jcorporate Ltd.
34  *
35  * 6. No product derived from this software may compete in the same
36  * market space, i.e. framework, without prior written permission
37  * of Jcorporate Ltd. For written permission, please contact
38  * partners@jcorporate.com.
39  *
40  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
41  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
42  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
43  * DISCLAIMED. IN NO EVENT SHALL JCORPORATE LTD OR ITS CONTRIBUTORS
44  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
45  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
46  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
47  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
48  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
49  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
50  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51  * SUCH DAMAGE.
52  * ====================================================================
53  *
54  * This software consists of voluntary contributions made by many
55  * individuals on behalf of the Jcorporate Ltd. Contributions back
56  * to the project(s) are encouraged when you make modifications.
57  * Please send them to support@jcorporate.com. For more information
58  * on Jcorporate Ltd. and its products, please see
59  * <http://www.jcorporate.com/>.
60  *
61  * Portions of this software are based upon other open source
62  * products and are subject to their respective licenses.
63  */

64
65 package com.jcorporate.expresso.ext.struts.taglib;
66
67 import com.jcorporate.expresso.core.ExpressoConstants;
68 import com.jcorporate.expresso.core.controller.Block;
69 import com.jcorporate.expresso.core.controller.ControllerElement;
70 import com.jcorporate.expresso.core.controller.ControllerException;
71 import com.jcorporate.expresso.core.controller.ControllerResponse;
72 import com.jcorporate.expresso.core.controller.Input;
73 import com.jcorporate.expresso.core.controller.Output;
74 import com.jcorporate.expresso.core.controller.Transition;
75 import com.jcorporate.expresso.core.misc.StringUtil;
76 import org.apache.commons.beanutils.ConvertUtils;
77 import org.apache.commons.beanutils.PropertyUtils;
78 import org.apache.log4j.Logger;
79
80 import javax.servlet.jsp.JspException JavaDoc;
81 import javax.servlet.jsp.PageContext JavaDoc;
82 import java.lang.reflect.InvocationTargetException JavaDoc;
83 import java.util.StringTokenizer JavaDoc;
84 import java.util.Vector JavaDoc;
85
86
87 /**
88  * Utilities for use by the extended "expresso-aware" Struts tags
89  *
90  * @author Michael P. Nash
91  */

92 public final class ControllerUtils {
93     private static Logger log = Logger.getLogger("expresso.ext.struts.taglib.ControllerUtils");
94
95
96     /**
97      * <p/>
98      * We interpret property names as follows: A "normal" name (e.g. no special
99      * characters) should represent the contents of an output object. If there
100      * is no such output, it's an error. A name with "/" delimiters in it
101      * indicates a "nested" property. The "final" name in the path is the name
102      * of the property we are after. A name containing "." indicates a
103      * property of an input or output (we look for inputs first, then
104      * outputs).
105      * </p>
106      * <p/>
107      * <p/>
108      * Note that the parameter <code>ignore</code> is not actually used and
109      * will be removed in future versions
110      * </p>
111      *
112      * @param pageContext the JSP page context
113      * @param name the name of the bean to retrieve
114      * @param property the name of the bean property to retrieve
115      * @param ignore Ignore errors and return null if the bean property isn't
116      * found?
117      * @return java.lang.String representing the specific bean property
118      * @throws JspException upon error
119      */

120     public static String JavaDoc getBeanProperty(PageContext JavaDoc pageContext, String JavaDoc name,
121                                          String JavaDoc property, boolean ignore)
122             throws JspException JavaDoc {
123         /* If we're given a "name" parameter, then we're looking for a specific bean
124          * (which should be a ControllerElement) in the current page context
125          */

126         if (!StringUtil.notNull(name).equals("")) {
127             return getSpecificBeanProperty(pageContext, name, property, ignore);
128         }
129
130         ControllerResponse myResponse = getResponse(pageContext);
131
132         if (myResponse == null) {
133             throw new JspException JavaDoc("No controller response found");
134         }
135         try {
136             if ('@' == property.charAt(0)) {
137                 return myResponse.getAttribute(property.substring(1));
138             }
139             if (property.indexOf("/") >= 0) {
140                 return nestedProperty(pageContext, null, property, false);
141             } else if (property.indexOf(".") >= 0) {
142                 String JavaDoc prefixName = property.substring(0,
143                         property.indexOf("."));
144                 String JavaDoc propertyName = property.substring(property.indexOf(".") +
145                         1);
146
147                 Input i = myResponse.getInput(prefixName);
148
149                 if (i != null) {
150                     return inputProperty(i, propertyName, false);
151                 }
152
153                 Output o = myResponse.getOutput(prefixName);
154
155                 if (o != null) {
156                     return outputProperty(o, propertyName, false);
157                 }
158
159                 Transition t = myResponse.getTransition(prefixName);
160
161                 if (t != null) {
162                     return transitionProperty(t, propertyName, false);
163                 }
164
165                 Block b = myResponse.getBlock(prefixName);
166
167                 if (b != null) {
168                     return blockProperty(b, propertyName, false);
169                 }
170
171                 throw new JspException JavaDoc("No input, output, block or transition named '" +
172                         prefixName + "'");
173             } else if (property.indexOf("@") >= 0) {
174                 String JavaDoc prefixName = property.substring(0, property.indexOf("@"));
175                 String JavaDoc propertyName = property.substring(property.indexOf("@") +
176                         1);
177
178                 Input i = myResponse.getInput(prefixName);
179
180                 if (i != null) {
181                     return inputProperty(i, propertyName, false);
182
183
184                 }
185
186                 Output o = myResponse.getOutput(prefixName);
187
188                 if (o != null) {
189                     return outputProperty(o, propertyName, false);
190
191
192                 }
193
194                 Transition t = myResponse.getTransition(prefixName);
195
196                 if (t != null) {
197                     return transitionProperty(t, propertyName, false);
198
199
200                 }
201
202                 Block b = myResponse.getBlock(prefixName);
203
204                 if (b != null) {
205                     return blockProperty(b, propertyName, false);
206
207
208                 }
209
210                 throw new JspException JavaDoc("No input, output, block or transition named '" +
211                         prefixName + "'");
212             }
213
214
215             Output o = myResponse.getOutput(property);
216
217             if (o == null) {
218                 if (ignore) {
219                     return null;
220                 }
221
222                 throw new JspException JavaDoc("No such output as '" + property + "'");
223             }
224
225             return o.getContent();
226         } catch (ControllerException ce) {
227             throw new JspException JavaDoc(ce.getMessage());
228         }
229     } /* getBeanProperty(PageContext, String) */
230
231
232     /**
233      * Get the current ControllerResponse object from the session
234      *
235      * @param pageContext the jsp page context
236      * @return a ControllerResponse generated from the page.
237      */

238     public static final ControllerResponse getResponse(PageContext JavaDoc pageContext) {
239         ControllerResponse returnValue = (ControllerResponse) pageContext
240                 .getAttribute(ExpressoConstants.CONTROLLER_RESPONSE_KEY,
241                         PageContext.REQUEST_SCOPE);
242         if (returnValue == null) {
243             returnValue = (ControllerResponse) pageContext
244                     .getAttribute(ExpressoConstants.CONTROLLER_RESPONSE_KEY,
245                             PageContext.PAGE_SCOPE);
246         }
247         return returnValue;
248     } /* getResponse(PageContext) */
249
250
251     /**
252      * Get a property from a specific ControllerElement stored as a bean in the
253      * current page
254      *
255      * @param pageContext the JSP page context
256      * @param name the name of the bean to retrieve
257      * @param property the name of the bean property to retrieve
258      * @param ignore Unused and to be removed in a future release
259      * @return java.lang.String representing the specific bean property
260      * @throws JspException upon error
261      */

262     public static String JavaDoc getSpecificBeanProperty(PageContext JavaDoc pageContext,
263                                                  String JavaDoc name, String JavaDoc property,
264                                                  boolean ignore)
265             throws JspException JavaDoc {
266         if (log.isDebugEnabled()) {
267             log.debug("Looking for bean '" + name + "', property '" +
268                     StringUtil.notNull(property) + "'");
269         }
270         if (StringUtil.notNull(property).indexOf("/") >= 0) {
271             if (log.isDebugEnabled()) {
272                 log.debug("Looking for nested property '" + property +
273                         "' of bean '" + StringUtil.notNull(name) + "'");
274             }
275
276             return nestedProperty(pageContext, name, property, false);
277         }
278
279         Object JavaDoc obj = pageContext.getAttribute(name, PageContext.PAGE_SCOPE);
280         if (obj == null) {
281             obj = pageContext.getAttribute(name, PageContext.REQUEST_SCOPE);
282
283             if (obj == null) {
284                 obj = pageContext.getAttribute(name, PageContext.SESSION_SCOPE);
285             }
286         }
287
288         ControllerElement ce = null;
289
290         if (obj instanceof ControllerElement) {
291             ce = (ControllerElement) obj;
292             if (log.isDebugEnabled()) {
293                 log.debug("Bean '" + name + "' is a '" + ce.getClass().getName() +
294                         "'");
295             }
296         } else {
297             if (obj == null) {
298                 return null;
299             }
300
301             return obj.toString();
302         }
303         if (ce instanceof Output) {
304             Output o = (Output) ce;
305
306             if (property != null && property.length() > 0) {
307                 return outputProperty(o, property, false);
308             }
309
310             return o.getContent();
311         }
312         if (ce instanceof Input) {
313             Input i = (Input) ce;
314
315             if (property != null && property.length() > 0) {
316                 return inputProperty(i, property, false);
317             }
318         }
319         if (ce instanceof Transition) {
320             Transition t = (Transition) ce;
321
322             if (property != null && property.length() > 0) {
323                 return transitionProperty(t, property, false);
324             }
325         }
326         if (ce instanceof Block) {
327             Block b = (Block) ce;
328
329             if (property != null && property.length() > 0) {
330                 return blockProperty(b, property, false);
331             }
332         }
333
334         return null;
335     } /* getSpecificBeanProperty() */
336
337
338     /**
339      * Determines if the defined name and property combination exists
340      * in the ControllerResponse for the page context
341      *
342      * @param pageContext The Jsp Page Context to retrieve the ControllerResponse
343      * from
344      * @param name The name of the bean to be searching for. If not null then
345      * we're looking for a bean other than ControllerReponse
346      * @param property The name of the property (possibly nested) to retrieve
347      * @return true if the system can find the defined element
348      * @throws JspException on issues like Type Mismatches.
349      */

350     public static boolean exists(PageContext JavaDoc pageContext, String JavaDoc name,
351                                  String JavaDoc property)
352             throws JspException JavaDoc {
353         if (name == null || name.length() == 0) {
354             if (property == null || property.length() == 0) {
355                 throw new JspException JavaDoc("Name or Property must not be null");
356             }
357
358             if ("inputs".equals(property)) {
359                 ControllerResponse res = getResponse(pageContext);
360                 if (res != null) {
361                     Vector JavaDoc v = res.getInputs();
362
363                     if (v != null) {
364                         if (v.size() > 0) {
365                             return true;
366                         }
367                     }
368                 }
369                 return false;
370             } else if ("outputs".equals(property)) {
371                 ControllerResponse res = getResponse(pageContext);
372                 if (res != null) {
373                     Vector JavaDoc v = res.getOutputs();
374
375                     if (v != null) {
376                         if (v.size() > 0) {
377                             return true;
378                         }
379                     }
380                 }
381                 return false;
382             } else if ("blocks".equals(property)) {
383                 ControllerResponse res = getResponse(pageContext);
384                 if (res != null) {
385                     Vector JavaDoc v = res.getBlocks();
386
387                     if (v != null) {
388                         if (v.size() > 0) {
389                             return true;
390                         }
391                     }
392                 }
393                 return false;
394             } else if ("transitions".equals(property)) {
395                 ControllerResponse res = getResponse(pageContext);
396                 if (res != null) {
397                     Vector JavaDoc v = res.getTransitions();
398
399                     if (v != null) {
400                         if (v.size() > 0) {
401                             return true;
402                         }
403                     }
404                 }
405                 return false;
406             }
407
408         }
409
410         if (log.isDebugEnabled()) {
411             log.debug("Looking for element '" + StringUtil.notNull(property) +
412                     "' in bean '" + StringUtil.notNull(name) + "'");
413         }
414
415         if (StringUtil.notNull(property).indexOf("/") >= 0) {
416             if (nestedProperty(pageContext, name, property, true) != null) {
417                 return true;
418             } else {
419                 return false;
420             }
421         }
422
423         ControllerElement ce = findElement(pageContext, name, property);
424
425         if (ce == null) {
426             if (log.isDebugEnabled()) {
427                 log.debug("No such element '" + StringUtil.notNull(property) +
428                         "' in bean '" + StringUtil.notNull(name) + "'");
429             }
430
431             return false;
432         }
433         if (name == null) {
434             if (log.isDebugEnabled()) {
435                 log.debug("Name is null - returning true from exists");
436                 log.debug("Found element " + ce.getName()
437                         + " matching property " +
438                         property);
439             }
440
441             return true;
442         }
443         if (property == null) {
444             if (log.isDebugEnabled()) {
445                 log.debug("Property is null -returning true from exists");
446             }
447
448             return true;
449         }
450
451         if (log.isDebugEnabled()) {
452             log.debug("Property is not null - looking for property '" + property +
453                     "' of '" + ce.getName() + "'");
454         }
455
456         try {
457             if (ce.getNested(property) != null) {
458                 return true;
459             } else {
460
461                 /* might be an actual property name of the bean */
462                 String JavaDoc propVal = getSpecificBeanProperty(pageContext, name,
463                         property, false);
464
465                 if (propVal == null || propVal.length() == 0) {
466                     return false;
467                 } else {
468                     return true;
469                 }
470             }
471         } catch (ControllerException cee) {
472             return false;
473         }
474     }
475
476     /**
477      * Inteprets the lead argument for InputTag expression where
478      * the bean expression is a scope for the type of controller
479      * that should be retrieved from the
480      * <code>ControllerResponse</code>.
481      *
482      * <p>The bean expression is a string, which must be formatted as
483      * <em>"&lt;ELEMENT-SCOPE&gt; : &lt;ELEMENT-NAME&gt;"</em>.
484      * </p>
485      *
486      * <p>
487      * Where ELEMENT-SCOPE is a string member of
488      * <code>block</code>,
489      * <code>input</code>,
490      * <code>output</code>, and
491      * <code>transition</code>.
492      * <br>
493      *
494      * The ELEMENT-NAME specifies the name of the controller element
495      * to retrieve.
496      * </p>
497      *
498      * <p> Here is an example of what we are trying to achieve with
499      * this method. This is taken from the eForum:
500      * <pre>
501      * &lt;html:textarea name="block:optionsBlock"
502      * property="/signature" cols="80" rows="6" /&gt;
503      * </pre>
504      *
505      * <p><b>IDEA</b>: Should this method support
506      * nested controller elements
507      * </p>
508      *
509      * @param pageContext the page context
510      * @param beanExpr the bean expression
511      * @return ControllerElement the controller element
512      * @throws ControllerException if problem occurs retrieving the element
513      */

514     public static ControllerElement interpretLeadElement(
515             PageContext JavaDoc pageContext, String JavaDoc beanExpr )
516         throws ControllerException
517     {
518         if ( beanExpr == null )
519             return null;
520         
521         ControllerResponse controllerResponse = getResponse( pageContext );
522         ControllerElement element = null;
523         int pos = beanExpr.indexOf(':');
524         if ( pos >= 0 ) {
525             String JavaDoc scope = beanExpr.substring( 0, pos );
526             String JavaDoc name = beanExpr.substring( pos+1 );
527             if ( scope.equals("block") )
528                 element = controllerResponse.getBlock( name );
529             else if ( scope.equals("input") )
530                 element = controllerResponse.getInput( name );
531             else if ( scope.equals("output") )
532                 element = controllerResponse.getOutput( name );
533             else if ( scope.equals("transition") )
534                 element = controllerResponse.getTransition( name );
535         }
536         return element;
537     }
538     
539     
540     /**
541      * Finds a controller element specified by name and/or property
542      *
543      * @param pageContext The jsp page context
544      * @param name the name of the bean to get. may be null if we're looking
545      * for top level controller elements.
546      * @param property the property to retrieve. If we have both a name AND a property,
547      * then the property must start with a &quot;/&quot; and then each successive
548      * forward slash indicates walking through nested controller elements until we
549      * find what we're looking for.
550      * @return <code>ControllerElement</code> or null.
551      */

552     public static ControllerElement findElement(PageContext JavaDoc pageContext,
553                                                 String JavaDoc name, String JavaDoc property) {
554         /* If we're handed a "name" then look for a bean by this name to get the nested element from */
555         if ((name != null) && (name.length() > 0)) {
556             ControllerElement ce = (ControllerElement) pageContext.getAttribute(name, PageContext.PAGE_SCOPE);
557
558             if ( ce == null ) {
559                 try {
560                     ce = interpretLeadElement( pageContext, name );
561                 }
562                 catch ( ControllerException excp ) {
563                     log.error( "Failure to retrieve lead element from controller response", excp );
564                 }
565             }
566             
567             /* We're looking for sub elements then */
568             if (property != null && property.length() > 0 && property.charAt(0) == '/') {
569                 StringTokenizer JavaDoc stok = new StringTokenizer JavaDoc(property, "/");
570                 ControllerElement currentElement = ce;
571                 while (stok.hasMoreTokens()) {
572                     String JavaDoc aProperty = stok.nextToken();
573                     ControllerElement tempElement = null;
574                     try {
575                         tempElement = currentElement.getNested(aProperty);
576                     } catch (ControllerException ex) {
577                         log.error("Unable to find nested element of " +
578                                 currentElement.getName() + " named " + aProperty,
579                                 ex);
580                         return null;
581                     }
582                     if (tempElement == null) {
583                         log.error("Unable to find nested element of " +
584                                 currentElement.getName() + " named " + aProperty);
585                         return null;
586                     }
587
588                     currentElement = tempElement;
589
590                 }
591                 return currentElement;
592             }
593
594             return ce;
595         }
596
597         ControllerResponse res = getResponse(pageContext);
598
599         try {
600             ControllerElement ce = null;
601
602             if (property != null && property.length() > 0 && property.charAt(0) == '/') {
603                 StringTokenizer JavaDoc stok = new StringTokenizer JavaDoc(property, "/");
604                 ControllerElement currentElement = ce;
605                 while (stok.hasMoreTokens()) {
606                     String JavaDoc aProperty = stok.nextToken();
607                     ControllerElement tempElement = null;
608                     try {
609                         if (currentElement != null) {
610                             tempElement = currentElement.getNested(aProperty);
611                         } else {
612                             //
613
//We're at a root element, we'll have to try
614
//inputs, outputs, transitions, or blocks to find
615
//the nested element We try blocks first since nesting
616
//usually occurs in blocks.
617
//
618
tempElement = res.getBlock(aProperty);
619
620                             if (tempElement == null) {
621                                 tempElement = res.getInput(aProperty);
622                             }
623                             if (tempElement == null) {
624                                 tempElement = res.getOutput(aProperty);
625                             }
626
627
628                             if (tempElement == null) {
629                                 tempElement = res.getTransition(aProperty);
630                             }
631
632                         }
633                     } catch (ControllerException ex) {
634                         if (currentElement == null) {
635                             currentElement = new Output();
636                             currentElement.setName("<Root Element>");
637                         }
638
639                         log.error("Unable to find nested element of " +
640                                 currentElement.getName() + " named " + aProperty,
641                                 ex);
642                         return null;
643                     }
644
645                     if (tempElement == null) {
646                         if (currentElement == null) {
647                             currentElement = new Output();
648                             currentElement.setName("<ControllerResponse Root>");
649                         }
650                         log.error("Unable to find nested element of " +
651                                 currentElement.getName() + " named " + aProperty);
652                         return null;
653                     }
654
655                     currentElement = tempElement;
656
657                 }
658                 return currentElement;
659             }
660
661
662             /* Is there any input, output, block or transition by this name? */
663             ce = res.getInput(property);
664
665             if (ce != null) {
666                 return ce;
667             }
668
669             ce = res.getOutput(property);
670
671             if (ce != null) {
672                 return ce;
673             }
674
675             ce = res.getTransition(property);
676
677             if (ce != null) {
678                 return ce;
679             }
680
681             ce = res.getBlock(property);
682
683             if (ce != null) {
684                 return ce;
685             }
686         } catch (ControllerException ce) {
687             log.error(ce);
688         }
689
690         if (log.isDebugEnabled()) {
691             log.debug("No such ControllerElement '" + property +
692                     "' in the ControllerResponse");
693         }
694
695         return null;
696     }
697
698     /**
699      * Find an input out of the ControllerReponse
700      *
701      * @param pageContext
702      * @param property
703      * @return
704      */

705     public static Input findInput(PageContext JavaDoc pageContext, String JavaDoc property)
706             throws JspException JavaDoc {
707
708         /* get the designated Input object */
709         Input myInput = null;
710
711         myInput = getResponse(pageContext).getInput(property);
712
713         if (myInput == null) {
714             throw new JspException JavaDoc("No such input as '" + property +
715                     "' in controller response");
716         }
717
718         return myInput;
719     }
720
721
722     /**
723      * Locate and return the transition named by the specified property
724      */

725     public static Transition findTransition(PageContext JavaDoc pageContext,
726                                             String JavaDoc property)
727             throws JspException JavaDoc {
728         /* get the designated Transition object */
729         Transition myTransition = null;
730
731         try {
732             myTransition = getResponse(pageContext).getTransition(property);
733
734             if (myTransition == null) {
735                 throw new JspException JavaDoc("No such transition as '" + property +
736                         "' in controller response");
737             }
738         } catch (ControllerException ce) {
739             log.error(ce);
740             throw new JspException JavaDoc("Error accessing transition '" + property +
741                     "':" + ce.getMessage());
742         }
743
744         return myTransition;
745     }
746
747
748     /**
749      * If we were asked for a property that contains a "/", then we're referring to either a property of
750      * or a value of a "nested" property
751      *
752      * @param pageContext
753      * @param name
754      * @param property
755      * @return the requested property
756      * @deprecated use nestedProperty(PageContext, name, property, checkExists) instead
757      */

758     public static String JavaDoc nestedProperty(PageContext JavaDoc pageContext, String JavaDoc name,
759                                         String JavaDoc property)
760             throws JspException JavaDoc {
761         String JavaDoc path = null;
762
763         if (property.indexOf(".") >= 0) {
764             path = property.substring(0, property.indexOf("."));
765         } else {
766             path = property;
767         }
768
769         StringTokenizer JavaDoc stk = new StringTokenizer JavaDoc(path, "/");
770         String JavaDoc oneName = null;
771         ControllerElement ce = null;
772
773         if (name != null) {
774             ce = (ControllerElement) pageContext.getAttribute(name,
775                     PageContext.PAGE_SCOPE);
776
777             if (log.isDebugEnabled()) {
778                 log.debug("Looking for nested property '" +
779                         StringUtil.notNull(property) + "' in bean '" + name +
780                         "'");
781             }
782         }
783         while (stk.hasMoreTokens()) {
784             oneName = stk.nextToken();
785
786             if (log.isDebugEnabled()) {
787                 log.debug("Getting name '" + oneName + "'");
788             }
789             /* If this is the first item in the "chain" */
790             if (ce == null) {
791                 ce = findElement(pageContext, null, oneName);
792
793                 if (ce == null) {
794                     throw new JspException JavaDoc("Cannot locate top element of nested chain '" +
795                             property + "', no element called '" + oneName +
796                             "' exists.");
797                 }
798             } else { /* if */
799
800                 try {
801                     ce = ce.getNested(oneName);
802                 } catch (ControllerException ece) {
803                     log.error(ece);
804                     throw new JspException JavaDoc("Unable to access nested object '" +
805                             oneName + "' in element '" +
806                             ce.getName());
807                 }
808                 if (ce == null) {
809                     return null;
810                 }
811             } /* else */
812
813         } /* while */
814
815         /* Now we're at the bottom of the chain */
816         if (property.indexOf(".") >= 0) {
817             String JavaDoc suffix = property.substring(property.indexOf(".") + 1);
818
819             if (ce instanceof Output) {
820                 return outputProperty((Output) ce, suffix, false);
821             } else if (ce instanceof Transition) {
822                 return transitionProperty((Transition) ce, suffix, false);
823             } else if (ce instanceof Input) {
824                 return inputProperty((Input) ce, suffix, false);
825             } else if (ce instanceof Block) {
826                 return blockProperty((Block) ce, suffix, false);
827             }
828         } else if (property.indexOf("@") >= 0) {
829             String JavaDoc suffix = property.substring(property.indexOf("@") + 1);
830
831             if (ce instanceof Output) {
832                 return outputProperty((Output) ce, suffix, false);
833             } else if (ce instanceof Transition) {
834                 return transitionProperty((Transition) ce, suffix, false);
835             } else if (ce instanceof Input) {
836                 return inputProperty((Input) ce, suffix, false);
837             } else if (ce instanceof Block) {
838                 return blockProperty((Block) ce, suffix, false);
839             }
840         }
841
842         if (ce instanceof Output) {
843             Output o = (Output) ce;
844
845             return o.getContent();
846         } else {
847             return ce.getName() + ", no contents";
848         }
849     } /* nestedProperty(ControllerResponse, property) */
850
851     /**
852      * If we were asked for a property that contains a "/", then we're referring to either a property of
853      * or a value of a "nested" property
854      *
855      * @param pageContext
856      * @param name
857      * @param property
858      * @param checkExists
859      * @return the requested property
860      */

861     public static String JavaDoc nestedProperty(PageContext JavaDoc pageContext, String JavaDoc name,
862                                         String JavaDoc property, boolean checkExists)
863             throws JspException JavaDoc {
864         String JavaDoc path = null;
865
866         if (property.indexOf(".") >= 0) {
867             path = property.substring(0, property.indexOf("."));
868         } else {
869             path = property;
870         }
871
872         StringTokenizer JavaDoc stk = new StringTokenizer JavaDoc(path, "/");
873         String JavaDoc oneName = null;
874         ControllerElement ce = null;
875
876         if (name != null) {
877             ce = (ControllerElement) pageContext.getAttribute(name,
878                     PageContext.PAGE_SCOPE);
879
880             if (log.isDebugEnabled()) {
881                 log.debug("Looking for nested property '" +
882                         StringUtil.notNull(property) + "' in bean '" + name +
883                         "'");
884             }
885         }
886         while (stk.hasMoreTokens()) {
887             oneName = stk.nextToken();
888
889             if (log.isDebugEnabled()) {
890                 log.debug("Getting name '" + oneName + "'");
891             }
892 /* If this is the first item in the "chain" */
893             if (ce == null) {
894                 ce = findElement(pageContext, null, oneName);
895
896                 if (ce == null) {
897                     throw new JspException JavaDoc("Cannot locate top element of nested chain '" +
898                             property + "', no element called '" + oneName +
899                             "' exists.");
900                 }
901             } else { /* if */
902
903                 try {
904                     ce = ce.getNested(oneName);
905                 } catch (ControllerException ece) {
906                     log.error(ece);
907                     throw new JspException JavaDoc("Unable to access nested object '" +
908                             oneName + "' in element '" +
909                             ce.getName());
910                 }
911                 if (ce == null) {
912                     return null;
913                 }
914             } /* else */
915
916         } /* while */
917
918 /* Now we're at the bottom of the chain */
919         if (property.indexOf(".") >= 0) {
920             String JavaDoc suffix = property.substring(property.indexOf(".") + 1);
921
922             if (ce instanceof Output) {
923                 return outputProperty((Output) ce, suffix, checkExists);
924             } else if (ce instanceof Transition) {
925                 return transitionProperty((Transition) ce, suffix, checkExists);
926             } else if (ce instanceof Input) {
927                 return inputProperty((Input) ce, suffix, checkExists);
928             } else if (ce instanceof Block) {
929                 return blockProperty((Block) ce, suffix, checkExists);
930             }
931         } else if (property.indexOf("@") >= 0) {
932             String JavaDoc suffix = property.substring(property.indexOf("@") + 1);
933
934             if (ce instanceof Output) {
935                 return outputProperty((Output) ce, suffix, false);
936             } else if (ce instanceof Transition) {
937                 return transitionProperty((Transition) ce, suffix, false);
938             } else if (ce instanceof Input) {
939                 return inputProperty((Input) ce, suffix, false);
940             } else if (ce instanceof Block) {
941                 return blockProperty((Block) ce, suffix, false);
942             }
943         }
944
945         if (ce instanceof Output) {
946             Output o = (Output) ce;
947
948             return o.getContent();
949         } else {
950             return ce.getName() + ", no contents";
951         }
952     } /* nestedProperty(ControllerResponse, property) */
953
954
955     private static String JavaDoc blockProperty(Block b, String JavaDoc propName, boolean checkExists)
956             throws JspException JavaDoc {
957
958         String JavaDoc propValue = elementProperty(b, propName);
959         if ('@' == propName.charAt(0) && propValue == null) {
960             if (checkExists) {
961                 return null;
962             }
963             propValue = "";
964         }
965
966         if (propValue != null) {
967             return propValue;
968         }
969
970         if (propName.equals("type")) {
971             return "block";
972         }
973
974         throw new JspException JavaDoc("No such property as '" + propName +
975                 "' in Block '" + b.getName() + "'");
976
977     } /* blockProperty(Block, String) */
978
979     private static String JavaDoc elementProperty(ControllerElement ce,
980                                           String JavaDoc propName) {
981
982         if ('@' == (propName.charAt(0))) {
983             return (String JavaDoc) ce.getAttribute(propName.substring(1));
984         }
985
986         if (propName.equals("label")) {
987             return ce.getLabel();
988         } else if (propName.equals("description")) {
989             return ce.getDescription();
990         } else if (propName.equals("name")) {
991             return ce.getName();
992         } else if (propName.equals("defaultValue") && ce instanceof Input) {
993             return ((Input) ce).getDefaultValue();
994         }
995
996         return null;
997     }
998
999     /**
1000     * Get the named property of a specific input element
1001     *
1002     * @param i the input to query
1003     * @param propName the property name to query
1004     * @param checkExists true if we are checking for the existence of the property, false otherwise
1005     * @return String for the property value
1006     * @throws JspException if there is no property listed by that name
1007     */

1008    private static String JavaDoc inputProperty(Input i, String JavaDoc propName, boolean checkExists)
1009            throws JspException JavaDoc {
1010
1011        String JavaDoc propValue = elementProperty(i, propName);
1012        if ('@' == propName.charAt(0) && propValue == null) {
1013            if (checkExists) {
1014                return null;
1015            }
1016            propValue = "";
1017        }
1018
1019        if (propValue != null) {
1020            return propValue;
1021        }
1022
1023        if (propName.equals("type")) {
1024            return "input";
1025        } else if (propName.equals("defaultValue")) {
1026            return i.getDefaultValue();
1027        }
1028        throw new JspException JavaDoc("No such property as '" + propName +
1029                "' in Input '" + i.getName() + "'");
1030
1031    } /* inputProperty(Input, String) */
1032
1033
1034    private static String JavaDoc outputProperty(Output o, String JavaDoc propName, boolean checkExists)
1035            throws JspException JavaDoc {
1036
1037        String JavaDoc propValue = elementProperty(o, propName);
1038        if ('@' == propName.charAt(0) && propValue == null) {
1039            if (checkExists) {
1040                return null;
1041            }
1042            propValue = "";
1043        }
1044
1045        if (propValue != null) {
1046            return propValue;
1047        }
1048
1049        if (propName.equals("type")) {
1050            return "output";
1051        }
1052
1053        throw new JspException JavaDoc("No such property as '" + propName +
1054                "' in Output '" + o.getName() + "'");
1055
1056    }
1057
1058
1059    private static String JavaDoc transitionProperty(Transition t, String JavaDoc propName, boolean checkExists)
1060            throws JspException JavaDoc {
1061        try {
1062            if (log.isDebugEnabled()) {
1063                log.debug("Looking for property '" + propName +
1064                        "' from transition '" + t.getName() + "'");
1065            }
1066
1067            String JavaDoc propValue = elementProperty(t, propName);
1068            if ('@' == propName.charAt(0) && propValue == null) {
1069                if (checkExists) {
1070                    return null;
1071                }
1072                propValue = "";
1073            }
1074
1075            if (propValue != null) {
1076                return propValue;
1077            }
1078
1079            if (propName.equals("type")) {
1080                return "transition";
1081            } else if (propName.equals("url")) {
1082                return t.getUrl();
1083            } else if (propName.equals("params")) {
1084                return t.getParamString();
1085            }
1086
1087            //
1088
//New, access any property
1089
//
1090
try {
1091                return (String JavaDoc) ConvertUtils.convert(PropertyUtils.getProperty(t, propName));
1092            } catch (IllegalAccessException JavaDoc ex) {
1093                throw new JspException JavaDoc("Property '" + propName +
1094                        "' in Transition '" + t.getName() +
1095                        "' exists, but is not 'public'");
1096            } catch (NoSuchMethodException JavaDoc ex) {
1097                throw new JspException JavaDoc("No such property as '" + propName +
1098                        "' in Transition '" + t.getName() + "'");
1099            }
1100
1101        } catch (InvocationTargetException JavaDoc ex) {
1102            log.error(ex);
1103            throw new JspException JavaDoc("Unable to access property from Transition:" +
1104                    ex.getMessage());
1105        } catch (ControllerException ce) {
1106            log.error(ce);
1107            throw new JspException JavaDoc("Unable to access property from Transition:" +
1108                    ce.getMessage());
1109        }
1110    }
1111
1112}
1113
1114/* ControllerUtils */
Popular Tags