• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 Google Inc.
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 
17 package com.google.clearsilver.jsilver.interpreter;
18 
19 import com.google.clearsilver.jsilver.autoescape.EscapeMode;
20 import com.google.clearsilver.jsilver.data.Data;
21 import com.google.clearsilver.jsilver.exceptions.JSilverInterpreterException;
22 import com.google.clearsilver.jsilver.resourceloader.ResourceLoader;
23 import com.google.clearsilver.jsilver.syntax.node.PCommand;
24 import com.google.clearsilver.jsilver.template.Macro;
25 import com.google.clearsilver.jsilver.template.RenderingContext;
26 import com.google.clearsilver.jsilver.template.Template;
27 
28 import java.io.IOException;
29 
30 /**
31  * User defined macro that will be executed by the interpreter.
32  *
33  * NOTE: This is not thread safe and cannot be shared between RenderingContexts. This is taken care
34  * of by the TemplateInterpreter.
35  */
36 public class InterpretedMacro implements Macro {
37 
38   private final PCommand command;
39   private final Template owningTemplate;
40   private final String macroName;
41   private final String[] argumentNames;
42   private final TemplateInterpreter templateInterpreter;
43   private final RenderingContext owningContext;
44 
InterpretedMacro(PCommand command, Template owningTemplate, String macroName, String[] argumentNames, TemplateInterpreter templateInterpreter, RenderingContext owningContext)45   public InterpretedMacro(PCommand command, Template owningTemplate, String macroName,
46       String[] argumentNames, TemplateInterpreter templateInterpreter,
47       RenderingContext owningContext) {
48     this.command = command;
49     this.owningTemplate = owningTemplate;
50     this.macroName = macroName;
51     this.argumentNames = argumentNames;
52     this.templateInterpreter = templateInterpreter;
53     this.owningContext = owningContext;
54   }
55 
56   @Override
render(RenderingContext context)57   public void render(RenderingContext context) throws IOException {
58     assert context == owningContext : "Cannot render macro defined in another context";
59     context.pushExecutionContext(this);
60     boolean doRuntimeAutoEscaping = !(context.isRuntimeAutoEscaping());
61     if (doRuntimeAutoEscaping) {
62       context.startRuntimeAutoEscaping();
63     }
64     command.apply(templateInterpreter);
65     if (doRuntimeAutoEscaping) {
66       context.stopRuntimeAutoEscaping();
67     }
68     context.popExecutionContext();
69   }
70 
71   @Override
render(Data data, Appendable out, ResourceLoader resourceLoader)72   public void render(Data data, Appendable out, ResourceLoader resourceLoader) throws IOException {
73     render(createRenderingContext(data, out, resourceLoader));
74   }
75 
76   @Override
createRenderingContext(Data data, Appendable out, ResourceLoader resourceLoader)77   public RenderingContext createRenderingContext(Data data, Appendable out,
78       ResourceLoader resourceLoader) {
79     return owningTemplate.createRenderingContext(data, out, resourceLoader);
80   }
81 
82   @Override
getTemplateName()83   public String getTemplateName() {
84     return owningTemplate.getTemplateName();
85   }
86 
87   @Override
getEscapeMode()88   public EscapeMode getEscapeMode() {
89     return owningTemplate.getEscapeMode();
90   }
91 
92   @Override
getDisplayName()93   public String getDisplayName() {
94     return owningTemplate.getDisplayName() + ":" + macroName;
95   }
96 
97   @Override
getMacroName()98   public String getMacroName() {
99     return macroName;
100   }
101 
102   @Override
getArgumentName(int index)103   public String getArgumentName(int index) {
104     if (index >= argumentNames.length) {
105       // TODO: Make sure this behavior of failing if too many
106       // arguments are passed to a macro is consistent with JNI / interpreter.
107       throw new JSilverInterpreterException("Too many arguments supplied to macro " + macroName);
108     }
109     return argumentNames[index];
110   }
111 
112   @Override
getArgumentCount()113   public int getArgumentCount() {
114     return argumentNames.length;
115   }
116 }
117