Coverage report

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

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