KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > commons > jelly > tags > define > InvokeBodyTag


1 /*
2  * Copyright 2002,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.jelly.tags.define;
17
18 import org.apache.commons.jelly.JellyTagException;
19 import org.apache.commons.jelly.Script;
20 import org.apache.commons.jelly.Tag;
21 import org.apache.commons.jelly.TagSupport;
22 import org.apache.commons.jelly.XMLOutput;
23 import org.apache.commons.jelly.JellyContext;
24 import org.apache.commons.jelly.impl.DynamicTag;
25 import org.apache.commons.logging.Log;
26 import org.apache.commons.logging.LogFactory;
27
28 /**
29  * <invokeBody> tag is used inside a <tag> tag
30  * (i.e. the definition of a dynamic tag) to invoke the tags body when
31  * the tag is invoked.
32  *
33  * @author <a HREF="mailto:jstrachan@apache.org">James Strachan</a>
34  * @version $Revision: 155420 $
35  */

36 public class InvokeBodyTag extends TagSupport {
37
38     /** The Log to which logging calls will be made. */
39     private static final Log log = LogFactory.getLog(InvokeBodyTag.class);
40
41     public InvokeBodyTag() {
42     }
43
44     // Tag interface
45
//-------------------------------------------------------------------------
46
public void doTag(XMLOutput output) throws JellyTagException {
47         /* Try find find the body from the reserved 'org.apache.commons.jelly.body' variable.
48
49             But while doing os,
50             Consider a doubly nested <invokeBody/> invocations like the following sequence,
51             where tag A and B are DynamicTag:
52
53             <A>
54               <X/>
55             </A>
56
57             where A is defined as ...
58
59             <B>
60               <Y>
61                 <define:invokeBody/>
62               </Y>
63             </B>
64
65             where B is defined as ...
66
67             <Z>
68               <define:invokeBody/>
69             </Z>
70
71             For this to correctly expands to <Z><Y><X/></Y></Z>,
72             We need to find the <X/> as the body when we are executing <define:invokeBody/> inside <Y> tag.
73             To do this, body Tags (to be invoked) need to be maintained as a stack, and when <invokeBody/>
74             is invoked inside <Z>, we need to 'pop' the body so that the proper body (<X/>) will become
75             visible.
76         */

77
78         JellyContext c = context;
79         Script script = null;
80         while (c!=null) {
81             script = (Script) c.getVariables().get("org.apache.commons.jelly.body");
82             if(script!=null) break;
83             c = c.getParent();
84         }
85
86         if (script != null) {
87             // pop the top most body from the virtual '<invokeBody/> stack'
88
// this is necessary to make tha nested invocations work. see above.
89
c.removeVariable("org.apache.commons.jelly.body");
90             try {
91                 script.run(context, output);
92             } finally {
93                 c.setVariable("org.apache.commons.jelly.body",script);
94             }
95         }
96         else {
97             // note this mechanism does not work properly for arbitrarily
98
// nested dynamic tags. A better way is required.
99
Tag tag = findAncestorWithClass(this, DynamicTag.class);
100             if (tag == null) {
101                 throw new JellyTagException("Cannot invoke body, no dynamic tag is defined in this block");
102             }
103             else {
104                 tag.invokeBody(output);
105             }
106         }
107     }
108 }
109
Popular Tags