View Javadoc

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.impl;
17  
18  import org.apache.commons.jelly.DynaTag;
19  import org.apache.commons.jelly.JellyContext;
20  import org.apache.commons.jelly.JellyException;
21  import org.apache.commons.jelly.JellyTagException;
22  import org.apache.commons.jelly.Tag;
23  import org.apache.commons.jelly.TagLibrary;
24  import org.apache.commons.jelly.XMLOutput;
25  import org.apache.commons.jelly.expression.Expression;
26  import org.xml.sax.SAXException;
27  
28  import java.net.URL;
29  import java.util.Iterator;
30  import java.util.Map;
31  
32  /***
33   * <p><code>StaticTagScript</code> is a script that evaluates a StaticTag, a piece of static XML
34   * though its attributes or element content may contain dynamic expressions.
35   * The first time this tag evaluates, it may have become a dynamic tag, so it will check that
36   * a new dynamic tag has not been generated.</p>
37   *
38   * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
39   * @version $Revision: 239434 $
40   */
41  public class StaticTagScript extends TagScript {
42  
43      public StaticTagScript() {
44      }
45  
46      public StaticTagScript(TagFactory tagFactory) {
47          super(tagFactory);
48      }
49  
50  
51      // Script interface
52      //-------------------------------------------------------------------------
53      public void run(JellyContext context, XMLOutput output) throws JellyTagException {
54          try {
55              startNamespacePrefixes(output);
56          } catch (SAXException e) {
57              throw new JellyTagException("could not start namespace prefixes",e);
58          }
59  
60          Tag tag;
61          try {
62              tag = getTag(context);
63  
64              // lets see if we have a dynamic tag
65              if (tag instanceof StaticTag) {
66                  tag = findDynamicTag(context, (StaticTag) tag);
67              }
68  
69              setTag(tag,context);
70          } catch (JellyException e) {
71              throw new JellyTagException(e);
72          }
73  
74          URL rootURL = context.getRootURL();
75          URL currentURL = context.getCurrentURL();
76          try {
77              if ( tag == null ) {
78                  return;
79              }
80              tag.setContext(context);
81              setContextURLs(context);
82  
83              DynaTag dynaTag = (DynaTag) tag;
84  
85              // ### probably compiling this to 2 arrays might be quicker and smaller
86              for (Iterator iter = attributes.entrySet().iterator(); iter.hasNext();) {
87                  Map.Entry entry = (Map.Entry) iter.next();
88                  String name = (String) entry.getKey();
89                  if(name.indexOf(':')!=-1)
90                      name = name.substring(name.indexOf(':')+1);
91                  ExpressionAttribute expat = (ExpressionAttribute) entry.getValue();
92                  Expression expression = expat.exp;
93  
94                  Object value;
95  
96                  if ( Expression.class.isAssignableFrom( dynaTag.getAttributeType(name) ) ) {
97                      value = expression;
98                  } else {
99                      value = expression.evaluate(context);
100                 }
101 
102                 if( expat.prefix != null && expat.prefix.length() > 0 && tag instanceof StaticTag )
103                 {
104                     ((StaticTag) dynaTag).setAttribute(name,expat.prefix, expat.nsURI,value);
105                 }
106                 else
107                 {
108                     dynaTag.setAttribute(name, value);
109                 }
110             }
111 
112             tag.doTag(output);
113         }
114         catch (JellyTagException e) {
115             handleException(e);
116         }
117         catch (RuntimeException e) {
118             handleException(e);
119         } finally {
120             context.setCurrentURL(currentURL);
121             context.setRootURL(rootURL);
122         }
123 
124         try {
125             endNamespacePrefixes(output);
126         } catch (SAXException e) {
127             throw new JellyTagException("could not end namespace prefixes",e);
128         }
129     }
130 
131     /***
132      * Attempts to find a dynamically created tag that has been created since this
133      * script was compiled
134      */
135     protected Tag findDynamicTag(JellyContext context, StaticTag tag) throws JellyException {
136         // lets see if there's a tag library for this URI...
137         TagLibrary taglib = context.getTagLibrary( tag.getUri() );
138         if ( taglib != null ) {
139             Tag newTag = taglib.createTag( tag.getLocalName(), getSaxAttributes() );
140             if ( newTag != null ) {
141                 newTag.setParent( tag.getParent() );
142                 newTag.setBody( tag.getBody() );
143                 return newTag;
144             }
145         }
146         return tag;
147     }
148 }