Coverage report

  %line %branch
org.apache.commons.jelly.impl.TagScript
67% 
84% 

 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 java.io.IOException;
 19  
 import java.lang.reflect.InvocationTargetException;
 20  
 import java.net.MalformedURLException;
 21  
 import java.net.URL;
 22  
 import java.util.Collections;
 23  
 import java.util.Hashtable;
 24  
 import java.util.Iterator;
 25  
 import java.util.Map;
 26  
 import java.util.WeakHashMap;
 27  
 
 28  
 import org.apache.commons.beanutils.ConvertingWrapDynaBean;
 29  
 import org.apache.commons.beanutils.ConvertUtils;
 30  
 import org.apache.commons.beanutils.DynaBean;
 31  
 import org.apache.commons.beanutils.DynaProperty;
 32  
 
 33  
 import org.apache.commons.jelly.CompilableTag;
 34  
 import org.apache.commons.jelly.JellyContext;
 35  
 import org.apache.commons.jelly.JellyException;
 36  
 import org.apache.commons.jelly.JellyTagException;
 37  
 import org.apache.commons.jelly.DynaTag;
 38  
 import org.apache.commons.jelly.LocationAware;
 39  
 import org.apache.commons.jelly.NamespaceAwareTag;
 40  
 import org.apache.commons.jelly.Script;
 41  
 import org.apache.commons.jelly.Tag;
 42  
 import org.apache.commons.jelly.XMLOutput;
 43  
 import org.apache.commons.jelly.expression.Expression;
 44  
 
 45  
 import org.apache.commons.logging.Log;
 46  
 import org.apache.commons.logging.LogFactory;
 47  
 
 48  
 import org.xml.sax.Attributes;
 49  
 import org.xml.sax.Locator;
 50  
 import org.xml.sax.SAXException;
 51  
 
 52  
 /**
 53  
  * <p><code>TagScript</code> is a Script that evaluates a custom tag.</p>
 54  
  *
 55  
  * <b>Note</b> that this class should be re-entrant and used
 56  
  * concurrently by multiple threads.
 57  
  *
 58  
  * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
 59  
  * @version $Revision: 165507 $
 60  
  */
 61  
 public class TagScript implements Script {
 62  
 
 63  
     /** The Log to which logging calls will be made. */
 64  1001
     private static final Log log = LogFactory.getLog(TagScript.class);
 65  
 
 66  
 
 67  
     /** The attribute expressions that are created */
 68  19968
     protected Map attributes = new Hashtable();
 69  
 
 70  
     /** the optional namespaces Map of prefix -> URI of this single Tag */
 71  
     private Map tagNamespacesMap;
 72  
 
 73  
     /**
 74  
      * The optional namespace context mapping all prefixes -> URIs in scope
 75  
      * at the point this tag is used.
 76  
      * This Map is only created lazily if it is required by the NamespaceAwareTag.
 77  
      */
 78  
     private Map namespaceContext;
 79  
 
 80  
     /** the Jelly file which caused the problem */
 81  
     private String fileName;
 82  
 
 83  
     /** the qualified element name which caused the problem */
 84  
     private String elementName;
 85  
 
 86  
     /** the local (non-namespaced) tag name */
 87  
     private String localName;
 88  
 
 89  
     /** the line number of the tag */
 90  19968
     private int lineNumber = -1;
 91  
 
 92  
     /** the column number of the tag */
 93  19968
     private int columnNumber = -1;
 94  
 
 95  
     /** the factory of Tag instances */
 96  
     private TagFactory tagFactory;
 97  
 
 98  
     /** the body script used for this tag */
 99  
     private Script tagBody;
 100  
 
 101  
     /** the parent TagScript */
 102  
     private TagScript parent;
 103  
 
 104  
     /** the SAX attributes */
 105  
     private Attributes saxAttributes;
 106  
     
 107  
     /** the url of the script when parsed */
 108  19968
     private URL scriptURL = null;
 109  
     
 110  
     /** A synchronized WeakHashMap from the current Thread (key) to a Tag object (value).
 111  
      */
 112  19968
     private Map threadLocalTagCache = Collections.synchronizedMap(new WeakHashMap());
 113  
 
 114  
     /**
 115  
      * @return a new TagScript based on whether
 116  
      * the given Tag class is a bean tag or DynaTag
 117  
      */
 118  
     public static TagScript newInstance(Class tagClass) {
 119  19721
         TagFactory factory = new DefaultTagFactory(tagClass);
 120  19721
         return new TagScript(factory);
 121  
     }
 122  
 
 123  0
     public TagScript() {
 124  0
     }
 125  
 
 126  19968
     public TagScript(TagFactory tagFactory) {
 127  19968
         this.tagFactory = tagFactory;
 128  19968
     }
 129  
 
 130  
     public String toString() {
 131  13
         return super.toString() + "[tag=" + elementName + ";at=" + lineNumber + ":" + columnNumber + "]";
 132  
     }
 133  
 
 134  
     /**
 135  
      * Compiles the tags body
 136  
      */
 137  
     public Script compile() throws JellyException {
 138  19903
         if (tagBody != null) {
 139  19903
             tagBody = tagBody.compile();
 140  
         }
 141  19903
         return this;
 142  
     }
 143  
 
 144  
     /**
 145  
      * Sets the optional namespaces prefix -> URI map of
 146  
      * the namespaces attached to this Tag
 147  
      */
 148  
     public void setTagNamespacesMap(Map tagNamespacesMap) {
 149  
         // lets check that this is a thread-safe map
 150  1040
         if ( ! (tagNamespacesMap instanceof Hashtable) ) {
 151  1040
             tagNamespacesMap = new Hashtable( tagNamespacesMap );
 152  
         }
 153  1040
         this.tagNamespacesMap = tagNamespacesMap;
 154  1040
     }
 155  
 
 156  
     /**
 157  
      * Configures this TagScript from the SAX Locator, setting the column
 158  
      * and line numbers
 159  
      */
 160  
     public void setLocator(Locator locator) {
 161  19968
         setLineNumber( locator.getLineNumber() );
 162  19968
         setColumnNumber( locator.getColumnNumber() );
 163  19968
     }
 164  
 
 165  
 
 166  
     /** Add an initialization attribute for the tag.
 167  
      * This method must be called after the setTag() method
 168  
      */
 169  
     public void addAttribute(String name, Expression expression) {
 170  26130
         if (log.isDebugEnabled()) {
 171  0
             log.debug("adding attribute name: " + name + " expression: " + expression);
 172  
         }
 173  26130
         attributes.put(name, expression);
 174  26130
     }
 175  
 
 176  
     /**
 177  
      * Strips off the name of a script to create a new context URL
 178  
      * FIXME: Copied from JellyContext
 179  
      */
 180  
     private URL getJellyContextURL(URL url) throws MalformedURLException {
 181  19864
         String text = url.toString();
 182  19864
         int idx = text.lastIndexOf('/');
 183  19864
         text = text.substring(0, idx + 1);
 184  19864
         return new URL(text);
 185  
     }
 186  
 
 187  
     // Script interface
 188  
     //-------------------------------------------------------------------------
 189  
 
 190  
     /** Evaluates the body of a tag */
 191  
     public void run(JellyContext context, XMLOutput output) throws JellyTagException {
 192  12207
         URL rootURL = context.getRootURL();
 193  12207
         URL currentURL = context.getCurrentURL();
 194  
         try {
 195  12207
             Tag tag = getTag(context);
 196  12207
             if ( tag == null ) {
 197  
                 return;
 198  
             }
 199  12207
             tag.setContext(context);
 200  12207
             setContextURLs(context);
 201  
 
 202  12207
             if ( tag instanceof DynaTag ) {
 203  117
                 DynaTag dynaTag = (DynaTag) tag;
 204  
 
 205  
                 // ### probably compiling this to 2 arrays might be quicker and smaller
 206  117
                 for (Iterator iter = attributes.entrySet().iterator(); iter.hasNext();) {
 207  442
                     Map.Entry entry = (Map.Entry) iter.next();
 208  442
                     String name = (String) entry.getKey();
 209  442
                     Expression expression = (Expression) entry.getValue();
 210  
 
 211  442
                     Class type = dynaTag.getAttributeType(name);
 212  442
                     Object value = null;
 213  442
                     if (type != null && type.isAssignableFrom(Expression.class) && !type.isAssignableFrom(Object.class)) {
 214  0
                         value = expression;
 215  0
                     }
 216  
                     else {
 217  442
                         value = expression.evaluateRecurse(context);
 218  
                     }
 219  442
                     dynaTag.setAttribute(name, value);
 220  442
                 }
 221  117
             }
 222  
             else {
 223  
                 // treat the tag as a bean
 224  12090
                 DynaBean dynaBean = new ConvertingWrapDynaBean( tag );
 225  12090
                 for (Iterator iter = attributes.entrySet().iterator(); iter.hasNext();) {
 226  15782
                     Map.Entry entry = (Map.Entry) iter.next();
 227  15782
                     String name = (String) entry.getKey();
 228  15782
                     Expression expression = (Expression) entry.getValue();
 229  
 
 230  15782
                     DynaProperty property = dynaBean.getDynaClass().getDynaProperty(name);
 231  15782
                     if (property == null) {
 232  0
                         throw new JellyException("This tag does not understand the '" + name + "' attribute" );
 233  
                     }
 234  15782
                     Class type = property.getType();
 235  
 
 236  15782
                     Object value = null;
 237  15782
                     if (type.isAssignableFrom(Expression.class) && !type.isAssignableFrom(Object.class)) {
 238  8723
                         value = expression;
 239  8723
                     }
 240  
                     else {
 241  7059
                         value = expression.evaluateRecurse(context);
 242  
                     }
 243  15782
                     dynaBean.set(name, value);
 244  15782
                 }
 245  
             }
 246  
 
 247  12207
             tag.doTag(output);
 248  11570
             if (output != null) {
 249  11570
                 output.flush();
 250  
             }
 251  
         }
 252  637
         catch (JellyTagException e) {
 253  637
             handleException(e);
 254  0
         } catch (JellyException e) {
 255  0
             handleException(e);
 256  0
         } catch (IOException e) {
 257  0
             handleException(e);
 258  0
         } catch (RuntimeException e) {
 259  0
             handleException(e);
 260  
         }
 261  0
         catch (Error e) {
 262  
            /*
 263  
             * Not sure if we should be converting errors to exceptions,
 264  
             * but not trivial to remove because JUnit tags throw
 265  
             * Errors in the normal course of operation.  Hmm...
 266  
             */
 267  0
             handleException(e);
 268  
         } finally {
 269  12207
             context.setRootURL(rootURL);
 270  12207
             context.setCurrentURL(currentURL);
 271  12207
         }
 272  
 
 273  11570
     }
 274  
 
 275  
     /**
 276  
      * Set the context's root and current URL if not present
 277  
      * @param context
 278  
      * @throws JellyTagException
 279  
      */
 280  
     protected void setContextURLs(JellyContext context) throws JellyTagException {
 281  12363
         if ((context.getCurrentURL() == null || context.getRootURL() == class="keyword">null) && scriptURL != class="keyword">null)
 282  
         {
 283  806
             if (context.getRootURL() == null) context.setRootURL(scriptURL);
 284  806
             if (context.getCurrentURL() == null) context.setCurrentURL(scriptURL);
 285  
         }
 286  12363
     }
 287  
 
 288  
     // Properties
 289  
     //-------------------------------------------------------------------------
 290  
 
 291  
     /**
 292  
      * @return the tag to be evaluated, creating it lazily if required.
 293  
      */
 294  
     public Tag getTag(JellyContext context) throws JellyException {
 295  21034
         Thread t = Thread.currentThread();
 296  21034
         Tag tag = (Tag) threadLocalTagCache.get(t);
 297  21034
         if ( tag == null ) {
 298  9646
             tag = createTag();
 299  9646
             if ( tag != null ) {
 300  9646
                 threadLocalTagCache.put(t,tag);
 301  9646
                 configureTag(tag,context);
 302  
             }
 303  
         }
 304  21034
         return tag;
 305  
     }
 306  
 
 307  
     /**
 308  
      * Returns the Factory of Tag instances.
 309  
      * @return the factory
 310  
      */
 311  
     public TagFactory getTagFactory() {
 312  0
         return tagFactory;
 313  
     }
 314  
 
 315  
     /**
 316  
      * Sets the Factory of Tag instances.
 317  
      * @param tagFactory The factory to set
 318  
      */
 319  
     public void setTagFactory(TagFactory tagFactory) {
 320  0
         this.tagFactory = tagFactory;
 321  0
     }
 322  
 
 323  
     /**
 324  
      * Returns the parent.
 325  
      * @return TagScript
 326  
      */
 327  
     public TagScript getParent() {
 328  0
         return parent;
 329  
     }
 330  
 
 331  
     /**
 332  
      * Returns the tagBody.
 333  
      * @return Script
 334  
      */
 335  
     public Script getTagBody() {
 336  0
         return tagBody;
 337  
     }
 338  
 
 339  
     /**
 340  
      * Sets the parent.
 341  
      * @param parent The parent to set
 342  
      */
 343  
     public void setParent(TagScript parent) {
 344  19968
         this.parent = parent;
 345  19968
     }
 346  
 
 347  
     /**
 348  
      * Sets the tagBody.
 349  
      * @param tagBody The tagBody to set
 350  
      */
 351  
     public void setTagBody(Script tagBody) {
 352  19968
         this.tagBody = tagBody;
 353  19968
     }
 354  
 
 355  
     /**
 356  
      * @return the Jelly file which caused the problem
 357  
      */
 358  
     public String getFileName() {
 359  0
         return fileName;
 360  
     }
 361  
 
 362  
     /**
 363  
      * Sets the Jelly file which caused the problem
 364  
      */
 365  
     public void setFileName(String fileName) {
 366  19968
         this.fileName = fileName;
 367  
         try
 368  
         {
 369  19968
             this.scriptURL = getJellyContextURL(new URL(fileName));
 370  104
         } catch (MalformedURLException e) {
 371  104
             log.debug("error setting script url", e);
 372  19864
         }
 373  19968
     }
 374  
 
 375  
 
 376  
     /**
 377  
      * @return the element name which caused the problem
 378  
      */
 379  
     public String getElementName() {
 380  0
         return elementName;
 381  
     }
 382  
 
 383  
     /**
 384  
      * Sets the element name which caused the problem
 385  
      */
 386  
     public void setElementName(String elementName) {
 387  19968
         this.elementName = elementName;
 388  19968
     }
 389  
     /**
 390  
      * @return the line number of the tag
 391  
      */
 392  
     public int getLineNumber() {
 393  0
         return lineNumber;
 394  
     }
 395  
 
 396  
     /**
 397  
      * Sets the line number of the tag
 398  
      */
 399  
     public void setLineNumber(int lineNumber) {
 400  19968
         this.lineNumber = lineNumber;
 401  19968
     }
 402  
 
 403  
     /**
 404  
      * @return the column number of the tag
 405  
      */
 406  
     public int getColumnNumber() {
 407  0
         return columnNumber;
 408  
     }
 409  
 
 410  
     /**
 411  
      * Sets the column number of the tag
 412  
      */
 413  
     public void setColumnNumber(int columnNumber) {
 414  19968
         this.columnNumber = columnNumber;
 415  19968
     }
 416  
 
 417  
     /**
 418  
      * Returns the SAX attributes of this tag
 419  
      * @return Attributes
 420  
      */
 421  
     public Attributes getSaxAttributes() {
 422  9646
         return saxAttributes;
 423  
     }
 424  
 
 425  
     /**
 426  
      * Sets the SAX attributes of this tag
 427  
      * @param saxAttributes The saxAttributes to set
 428  
      */
 429  
     public void setSaxAttributes(Attributes saxAttributes) {
 430  19721
         this.saxAttributes = saxAttributes;
 431  19721
     }
 432  
 
 433  
     /**
 434  
      * Returns the local, non namespaced XML name of this tag
 435  
      * @return String
 436  
      */
 437  
     public String getLocalName() {
 438  0
         return localName;
 439  
     }
 440  
 
 441  
     /**
 442  
      * Sets the local, non namespaced name of this tag.
 443  
      * @param localName The localName to set
 444  
      */
 445  
     public void setLocalName(String localName) {
 446  19968
         this.localName = localName;
 447  19968
     }
 448  
 
 449  
 
 450  
     /**
 451  
      * Returns the namespace context of this tag. This is all the prefixes
 452  
      * in scope in the document where this tag is used which are mapped to
 453  
      * their namespace URIs.
 454  
      *
 455  
      * @return a Map with the keys are namespace prefixes and the values are
 456  
      * namespace URIs.
 457  
      */
 458  
     public synchronized Map getNamespaceContext() {
 459  0
         if (namespaceContext == null) {
 460  0
             if (parent != null) {
 461  0
                 namespaceContext = getParent().getNamespaceContext();
 462  0
                 if (tagNamespacesMap != null && !tagNamespacesMap.isEmpty()) {
 463  
                     // create a new child context
 464  0
                     Hashtable newContext = new Hashtable(namespaceContext.size()+1);
 465  0
                     newContext.putAll(namespaceContext);
 466  0
                     newContext.putAll(tagNamespacesMap);
 467  0
                     namespaceContext = newContext;
 468  0
                 }
 469  
             }
 470  
             else {
 471  0
                 namespaceContext = tagNamespacesMap;
 472  0
                 if (namespaceContext == null) {
 473  0
                     namespaceContext = new Hashtable();
 474  
                 }
 475  
             }
 476  
         }
 477  0
         return namespaceContext;
 478  
     }
 479  
 
 480  
     // Implementation methods
 481  
     //-------------------------------------------------------------------------
 482  
 
 483  
     /**
 484  
      * Factory method to create a new Tag instance.
 485  
      * The default implementation is to delegate to the TagFactory
 486  
      */
 487  
     protected Tag createTag() throws JellyException {
 488  9646
         if ( tagFactory != null) {
 489  9646
             return tagFactory.createTag(localName, getSaxAttributes());
 490  
         }
 491  0
         return null;
 492  
     }
 493  
 
 494  
 	
 495  
     /**
 496  
      * Compiles a newly created tag if required, sets its parent and body.
 497  
      */
 498  
     protected void configureTag(Tag tag, JellyContext context) throws JellyException {
 499  9646
         if (tag instanceof CompilableTag) {
 500  0
             ((CompilableTag) tag).compile();
 501  
         }
 502  9646
         Tag parentTag = null;
 503  9646
         if ( parent != null ) {
 504  8671
             parentTag = parent.getTag(context);
 505  
         }
 506  9646
         tag.setParent( parentTag );
 507  9646
         tag.setBody( tagBody );
 508  
 
 509  9646
         if (tag instanceof NamespaceAwareTag) {
 510  0
             NamespaceAwareTag naTag = (NamespaceAwareTag) tag;
 511  0
             naTag.setNamespaceContext(getNamespaceContext());
 512  
         }
 513  9646
         if (tag instanceof LocationAware) {
 514  0
             applyLocation((LocationAware) tag);
 515  
         }
 516  9646
     }
 517  
 
 518  
 
 519  
     /**
 520  
      * Allows the script to set the tag instance to be used, such as in a StaticTagScript
 521  
      * when a StaticTag is switched with a DynamicTag
 522  
      */
 523  
     protected void setTag(Tag tag, JellyContext context) {
 524  156
         Thread t = Thread.currentThread();
 525  156
         threadLocalTagCache.put(t,tag);
 526  156
     }
 527  
 
 528  
     /**
 529  
      * Output the new namespace prefixes used for this element
 530  
      */
 531  
     protected void startNamespacePrefixes(XMLOutput output) throws SAXException {
 532  156
         if ( tagNamespacesMap != null ) {
 533  13
             for ( Iterator iter = tagNamespacesMap.entrySet().iterator(); iter.hasNext(); ) {
 534  13
                 Map.Entry entry = (Map.Entry) iter.next();
 535  13
                 String prefix = (String) entry.getKey();
 536  13
                 String uri = (String) entry.getValue();
 537  13
                 output.startPrefixMapping(prefix, uri);
 538  13
             }
 539  
         }
 540  156
     }
 541  
 
 542  
     /**
 543  
      * End the new namespace prefixes mapped for the current element
 544  
      */
 545  
     protected void endNamespacePrefixes(XMLOutput output) throws SAXException {
 546  156
         if ( tagNamespacesMap != null ) {
 547  13
             for ( Iterator iter = tagNamespacesMap.keySet().iterator(); iter.hasNext(); ) {
 548  13
                 String prefix = (String) iter.next();
 549  13
                 output.endPrefixMapping(prefix);
 550  13
             }
 551  
         }
 552  156
     }
 553  
 
 554  
     /**
 555  
      * Converts the given value to the required type.
 556  
      *
 557  
      * @param value is the value to be converted. This will not be null
 558  
      * @param requiredType the type that the value should be converted to
 559  
      */
 560  
     protected Object convertType(Object value, Class requiredType)
 561  
         throws JellyException {
 562  0
         if (requiredType.isInstance(value)) {
 563  0
             return value;
 564  
         }
 565  0
         if (value instanceof String) {
 566  0
             return ConvertUtils.convert((String) value, requiredType);
 567  
         }
 568  0
         return value;
 569  
     }
 570  
 
 571  
     /**
 572  
      * Creates a new Jelly exception, adorning it with location information
 573  
      */
 574  
     protected JellyException createJellyException(String reason) {
 575  0
         return new JellyException(
 576  
             reason, fileName, elementName, columnNumber, lineNumber
 577  
         );
 578  
     }
 579  
 
 580  
     /**
 581  
      * Creates a new Jelly exception, adorning it with location information
 582  
      */
 583  
     protected JellyException createJellyException(String reason, Exception cause) {
 584  0
         if (cause instanceof JellyException) {
 585  0
             return (JellyException) cause;
 586  
         }
 587  
 
 588  0
         if (cause instanceof InvocationTargetException) {
 589  0
             return new JellyException(
 590  
                 reason,
 591  
                 ((InvocationTargetException) cause).getTargetException(),
 592  
                 fileName,
 593  
                 elementName,
 594  
                 columnNumber,
 595  
                 lineNumber);
 596  
         }
 597  0
         return new JellyException(
 598  
             reason, cause, fileName, elementName, columnNumber, lineNumber
 599  
         );
 600  
     }
 601  
 
 602  
     /**
 603  
      * A helper method to handle this Jelly exception.
 604  
      * This method adorns the JellyException with location information
 605  
      * such as adding line number information etc.
 606  
      */
 607  
     protected void handleException(JellyTagException e) throws JellyTagException {
 608  637
         if (log.isTraceEnabled()) {
 609  0
             log.trace( "Caught exception: " + e, e );
 610  
         }
 611  
 
 612  637
         applyLocation(e);
 613  
 
 614  637
         throw e;
 615  
     }
 616  
 
 617  
     /**
 618  
      * A helper method to handle this Jelly exception.
 619  
      * This method adorns the JellyException with location information
 620  
      * such as adding line number information etc.
 621  
      */
 622  
     protected void handleException(JellyException e) throws JellyTagException {
 623  0
         if (log.isTraceEnabled()) {
 624  0
             log.trace( "Caught exception: " + e, e );
 625  
         }
 626  
 
 627  0
         applyLocation(e);
 628  
 
 629  0
         throw new JellyTagException(e);
 630  
     }
 631  
 
 632  
     protected void applyLocation(LocationAware locationAware) {
 633  637
         if (locationAware.getLineNumber() == -1) {
 634  338
             locationAware.setColumnNumber(columnNumber);
 635  338
             locationAware.setLineNumber(lineNumber);
 636  
         }
 637  637
         if ( locationAware.getFileName() == null ) {
 638  338
             locationAware.setFileName( fileName );
 639  
         }
 640  637
         if ( locationAware.getElementName() == null ) {
 641  338
             locationAware.setElementName( elementName );
 642  
         }
 643  637
     }
 644  
 
 645  
     /**
 646  
      * A helper method to handle this non-Jelly exception.
 647  
      * This method will rethrow the exception, wrapped in a JellyException
 648  
      * while adding line number information etc.
 649  
      */
 650  
     protected void handleException(Exception e) throws JellyTagException {
 651  0
         if (log.isTraceEnabled()) {
 652  0
             log.trace( "Caught exception: " + e, e );
 653  
         }
 654  
 
 655  0
         if (e instanceof LocationAware) {
 656  0
             applyLocation((LocationAware) e);
 657  
         }
 658  
 
 659  0
         if ( e instanceof JellyException ) {
 660  0
             e.fillInStackTrace();
 661  
         }
 662  
 
 663  0
         if ( e instanceof InvocationTargetException) {
 664  0
             throw new JellyTagException( ((InvocationTargetException)e).getTargetException(),
 665  
                                       fileName,
 666  
                                       elementName,
 667  
                                       columnNumber,
 668  
                                       lineNumber );
 669  
         }
 670  
 
 671  0
         throw new JellyTagException(e, fileName, elementName, columnNumber, lineNumber);
 672  
     }
 673  
 
 674  
     /**
 675  
      * A helper method to handle this non-Jelly exception.
 676  
      * This method will rethrow the exception, wrapped in a JellyException
 677  
      * while adding line number information etc.
 678  
      *
 679  
      * Is this method wise?
 680  
      */
 681  
     protected void handleException(Error e) throws Error, JellyTagException {
 682  0
         if (log.isTraceEnabled()) {
 683  0
             log.trace( "Caught exception: " + e, e );
 684  
         }
 685  
 
 686  0
         if (e instanceof LocationAware) {
 687  0
             applyLocation((LocationAware) e);
 688  
         }
 689  
 
 690  0
         throw new JellyTagException(e, fileName, elementName, columnNumber, lineNumber);
 691  
     }
 692  
 }

This report is generated by jcoverage, Maven and Maven JCoverage Plugin.