Changeset 816


Ignore:
Timestamp:
2008-11-25 14:48:03 (4 years ago)
Author:
bruno
Message:

Fixing the proper restore of the SourceResolver?.ACTIVE_SOURCE_CONTEXT thread local state.

To implement this, I was missing a try-finally-like construct around the processing of all events between the start and end step of the SourceContextSwitchBlock?. Rather than inventing something for this in the step-based execution model of the template engine, I decided to just invoke the template engine recursively so that I could rely on Java's try-finally.

This also uncovered a problem with the template inheritance: after executing the inherited template, the end steps of the already executed blocks of the inheriting template were not executed anymore.

Removed the ExecutionContext?.blockState that I had previously introduced, as it is now no longer necessary for the SourceContextSwitchBlock?. This could also be useful in other situations (like ElementBlock?), though in those cases recursive template execution could also solve the problem, I will think about that some other time.

Location:
trunk/universe/kauri-template/src
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/universe/kauri-template/src/main/java/org/kauriproject/template/DefaultTemplateExecutor.java

    r815 r816  
    1616package org.kauriproject.template; 
    1717 
    18 import org.apache.commons.logging.Log; 
    19 import org.apache.commons.logging.LogFactory; 
     18import org.xml.sax.SAXException; 
    2019 
    2120/** 
    22  * Default implementation. 
    23  *  
    24  * NOTE: We could remove the instance variable {@link #result} and instead make it a required parameter of the 
    25  * {@link #execute(CompiledTemplate)} method. 
     21 * The template executor is responsible for the execution of a template. 
    2622 */ 
    2723public class DefaultTemplateExecutor implements TemplateExecutor { 
    2824 
    29     private ExecutionContext context; 
    30     private TemplateResult result; 
     25    public void execute(Step startStep, Step endStep, ExecutionContext context, TemplateResult result) throws SAXException { 
     26        if (context.getExecutor() == null) { 
     27            context.setExecutor(this); 
     28        } 
    3129 
    32     public DefaultTemplateExecutor(ExecutionContext context, TemplateResult result) { 
    33         this.context = context; 
    34         this.result = result; 
    35     } 
    36  
    37     // TODO: Handle errors: failfast strategy ? (issue #41) 
    38     public void execute(CompiledTemplate compiledTemplate) { 
    39         try { 
    40             Step currentStep = compiledTemplate; 
    41             while (currentStep != null) { 
    42                 currentStep = currentStep.executeAndProceed(context, result); 
    43             } 
    44         } catch (Exception ex) { 
    45             // TODO (bruno) I've changed this log by a throw -- need to look closer at why 
    46             //               it was done this way 
    47             // log.error("An error occurred when executing the compiled template: " + ex); 
    48             throw new RuntimeException("An error occured executing the template.", ex); 
     30        Step currentStep = startStep; 
     31        while (currentStep != endStep) { 
     32            currentStep = currentStep.executeAndProceed(context, result); 
    4933        } 
    5034    } 
  • trunk/universe/kauri-template/src/main/java/org/kauriproject/template/DefaultTemplateService.java

    r656 r816  
    7979        } 
    8080        CompiledTemplate compiledTemplate = buildTemplate(templateLocation, executionContext); 
    81         DefaultTemplateExecutor executor = new DefaultTemplateExecutor(executionContext, result); 
    82         executor.execute(compiledTemplate); 
     81        DefaultTemplateExecutor executor = new DefaultTemplateExecutor(); 
     82        executor.execute(compiledTemplate, null, executionContext, result); 
    8383        result.flush(); 
    8484    } 
  • trunk/universe/kauri-template/src/main/java/org/kauriproject/template/DocumentBlock.java

    r686 r816  
    100100            } 
    101101 
    102             result.endDocument(); 
     102            if (!context.isInherited()) { 
     103                result.endDocument(); 
     104            } 
    103105            return super.executeAndProceed(context, result); 
    104106        } 
  • trunk/universe/kauri-template/src/main/java/org/kauriproject/template/ExecutionContext.java

    r808 r816  
    3030 
    3131    private SourceResolver sourceResolver; 
    32  
    3332    private TemplateContext templateContext; 
    34  
    3533    private FunctionRegistry functionRegistry; 
    36  
    37     private Stack<Object> blockState; 
     34    private TemplateExecutor executor; 
    3835 
    3936    private Map<String, MacroBlock> macroRegistry; 
     
    4340    private Stack<SuperBlock> superBlockStack; 
    4441 
    45     private boolean inherited = false; 
     42    private int inherited = 0; 
    4643 
    4744    public ExecutionContext() { 
     
    5451        this.templateContext = templateContext; 
    5552        this.functionRegistry = functionRegistry; 
    56         this.blockState = new Stack(); 
    5753        this.macroRegistry = new HashMap<String, MacroBlock>(); 
    5854        this.callerRegistry = new HashMap<String, CallMacroBlock>(); 
     
    8682    } 
    8783 
    88     public void setInherited(boolean inherited) { 
    89         this.inherited = inherited; 
     84    public void inheritInc() { 
     85        this.inherited++; 
     86    } 
     87 
     88    public void inheritDecr() { 
     89        this.inherited--; 
    9090    } 
    9191 
    9292    public boolean isInherited() { 
    93         return inherited; 
     93        return inherited > 0; 
    9494    } 
    9595 
     
    114114    } 
    115115 
    116     public Stack<Object> getBlockState() { 
    117         return blockState; 
     116    public TemplateExecutor getExecutor() { 
     117        return executor; 
     118    } 
     119 
     120    public void setExecutor(TemplateExecutor executor) { 
     121        this.executor = executor; 
    118122    } 
    119123} 
  • trunk/universe/kauri-template/src/main/java/org/kauriproject/template/OutputBlock.java

    r812 r816  
    119119                    } 
    120120 
    121                     context.setInherited(true); 
    122                     return baseTemplate.executeAndProceed(context, result); 
     121                    context.inheritInc(); 
     122                    context.getExecutor().execute(baseTemplate, null, context, result); 
     123                    context.inheritDecr(); 
     124                     
     125                    return getEndStep().getCompiledNext(); 
    123126                } 
    124127            } 
  • trunk/universe/kauri-template/src/main/java/org/kauriproject/template/SourceContextSwitchBlock.java

    r809 r816  
    3939        @Override 
    4040        public Step executeAndProceed(ExecutionContext context, TemplateResult result) throws SAXException { 
    41  
    42             Object sc = SourceResolver.ACTIVE_SOURCE_CONTEXT.get(); 
    43             context.getBlockState().push(sc); 
    44  
    45             SourceResolver.ACTIVE_SOURCE_CONTEXT.set(sourceContext); 
    46  
    47             return super.executeAndProceed(context, result); 
     41            Object oldSourceContext = SourceResolver.ACTIVE_SOURCE_CONTEXT.get(); 
     42            try { 
     43                SourceResolver.ACTIVE_SOURCE_CONTEXT.set(sourceContext); 
     44                context.getExecutor().execute(getCompiledNext(), getEndStep(), context, result); 
     45            } finally { 
     46                SourceResolver.ACTIVE_SOURCE_CONTEXT.set(oldSourceContext); 
     47            } 
     48            return getEndStep().getCompiledNext(); 
    4849        } 
    4950    } 
     
    5657        @Override 
    5758        public Step executeAndProceed(ExecutionContext context, TemplateResult result) throws SAXException { 
    58             Object sc = context.getBlockState().pop(); 
    59  
    60             if (sc != null) { 
    61                 SourceResolver.ACTIVE_SOURCE_CONTEXT.set(sc); 
    62             } else { 
    63                 SourceResolver.ACTIVE_SOURCE_CONTEXT.remove(); 
    64             } 
    65  
    66             return super.executeAndProceed(context, result); 
     59            return getCompiledNext(); 
    6760        } 
    6861    } 
  • trunk/universe/kauri-template/src/main/java/org/kauriproject/template/TemplateExecutor.java

    r38 r816  
    1 /* 
    2  * Copyright 2008 Outerthought bvba and Schaubroeck nv 
    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  */ 
    161package org.kauriproject.template; 
    172 
    18 /** 
    19  * A template executor is responsible for the execution of a specified compiled template. 
    20  */ 
     3import org.xml.sax.SAXException; 
     4 
    215public interface TemplateExecutor { 
    22  
    23     public void execute(CompiledTemplate compiledTemplate); 
     6    void execute(Step startStep, Step endStep, ExecutionContext context, TemplateResult result) throws SAXException; 
    247} 
  • trunk/universe/kauri-template/src/test/java/org/kauriproject/template/TemplateTestBase.java

    r656 r816  
    3535import org.xml.sax.InputSource; 
    3636import org.xml.sax.XMLReader; 
     37import org.xml.sax.SAXException; 
    3738 
    3839public class TemplateTestBase extends TestCase { 
     
    8687     */ 
    8788    protected void executeTemplate(CompiledTemplate compiledTemplate, TemplateResult result, 
    88             Map<String, Object> variables, double treshold) { 
     89            Map<String, Object> variables, double treshold) throws SAXException { 
    8990        // setup 
    9091        TemplateContext context = new DefaultTemplateContext(); 
     
    9596        execContext.setTemplateContext(context); 
    9697        execContext.setSourceResolver(sourceResolver); 
    97         DefaultTemplateExecutor executor = new DefaultTemplateExecutor(execContext, result); 
     98        DefaultTemplateExecutor executor = new DefaultTemplateExecutor(); 
    9899 
    99100        // monitor duration 
    100101        long start = new Date().getTime(); 
    101102        // execute template 
    102         executor.execute(compiledTemplate); 
     103        executor.execute(compiledTemplate, null, execContext, result); 
    103104        long end = new Date().getTime(); 
    104105 
Note: See TracChangeset for help on using the changeset viewer.