1 /*
2 * Copyright (c) 2003 The Visigoth Software Society. All rights
3 * reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
16 *
17 * 3. The end-user documentation included with the redistribution, if
18 * any, must include the following acknowledgement:
19 * "This product includes software developed by the
20 * Visigoth Software Society (http://www.visigoths.org/)."
21 * Alternately, this acknowledgement may appear in the software itself,
22 * if and wherever such third-party acknowledgements normally appear.
23 *
24 * 4. Neither the name "FreeMarker", "Visigoth", nor any of the names of the
25 * project contributors may be used to endorse or promote products derived
26 * from this software without prior written permission. For written
27 * permission, please contact visigoths@visigoths.org.
28 *
29 * 5. Products derived from this software may not be called "FreeMarker" or "Visigoth"
30 * nor may "FreeMarker" or "Visigoth" appear in their names
31 * without prior written permission of the Visigoth Software Society.
32 *
33 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
34 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
35 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
36 * DISCLAIMED. IN NO EVENT SHALL THE VISIGOTH SOFTWARE SOCIETY OR
37 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
38 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
39 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
40 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
41 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
42 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
43 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
44 * SUCH DAMAGE.
45 * ====================================================================
46 *
47 * This software consists of voluntary contributions made by many
48 * individuals on behalf of the Visigoth Software Society. For more
49 * information on the Visigoth Software Society, please see
50 * http://www.visigoths.org/
51 */
52
53 package freemarker.core;
54
55 import freemarker.template;
56
57 /**
58 * Objects that represent instructions or expressions
59 * in the compiled tree representation of the template
60 * all descend from this abstract base class.
61 */
62 public abstract class TemplateObject {
63
64 private Template template;
65 int beginColumn, beginLine, endColumn, endLine;
66
67 final void setLocation(Template template, Token begin, Token end)
68 throws
69 ParseException
70 {
71 setLocation(template, begin.beginColumn, begin.beginLine, end.endColumn, end.endLine);
72 }
73
74 final void setLocation(Template template, Token begin, TemplateObject end)
75 throws
76 ParseException
77 {
78 setLocation(template, begin.beginColumn, begin.beginLine, end.endColumn, end.endLine);
79 }
80
81 final void setLocation(Template template, TemplateObject begin, Token end)
82 throws
83 ParseException
84 {
85 setLocation(template, begin.beginColumn, begin.beginLine, end.endColumn, end.endLine);
86 }
87
88 final void setLocation(Template template, TemplateObject begin, TemplateObject end)
89 throws
90 ParseException
91 {
92 setLocation(template, begin.beginColumn, begin.beginLine, end.endColumn, end.endLine);
93 }
94
95 public final int getBeginColumn() {
96 return beginColumn;
97 }
98
99 public final int getBeginLine() {
100 return beginLine;
101 }
102
103 public final int getEndColumn() {
104 return endColumn;
105 }
106
107 public final int getEndLine() {
108 return endLine;
109 }
110
111 void setLocation(Template template, int beginColumn, int beginLine, int endColumn, int endLine)
112 throws
113 ParseException
114 {
115 this.template = template;
116 this.beginColumn = beginColumn;
117 this.beginLine = beginLine;
118 this.endColumn = endColumn;
119 this.endLine = endLine;
120 }
121
122 static void assertNonNull(TemplateModel model, Expression exp, Environment env) throws InvalidReferenceException {
123 if (model == null) {
124 throw new InvalidReferenceException(
125 "Expression " + exp + " is undefined " +
126 exp.getStartLocation() + ".", env);
127 }
128 }
129
130 static TemplateException invalidTypeException(TemplateModel model, Expression exp, Environment env, String expected)
131 throws
132 TemplateException
133 {
134 assertNonNull(model, exp, env);
135 return new TemplateException(
136 "Expected " + expected + ". " +
137 exp + " evaluated instead to " +
138 model.getClass().getName() + " " +
139 exp.getStartLocation() + ".", env);
140 }
141 /**
142 * Returns a string that indicates
143 * where in the template source, this object is.
144 */
145 public String getStartLocation() {
146 String templateName = template != null ? template.getName() : "input";
147 return "on line "
148 + beginLine
149 + ", column "
150 + beginColumn
151 + " in "
152 + templateName;
153 }
154
155 public String getEndLocation() {
156 String templateName = template != null ? template.getName() : "input";
157 return "on line "
158 + endLine
159 + ", column "
160 + endColumn
161 + " in "
162 + templateName;
163 }
164
165 public final String getSource() {
166 if (template != null) {
167 return template.getSource(beginColumn, beginLine, endColumn, endLine);
168 } else {
169 return getCanonicalForm();
170 }
171 }
172
173 public String toString() {
174 try {
175 return getSource();
176 } catch (Exception e) { // REVISIT: A bit of a hack? (JR)
177 return getCanonicalForm();
178 }
179 }
180
181
182 /**
183 * @return whether the point in the template file specified by the
184 * column and line numbers is contained within this template object.
185 */
186 public boolean contains(int column, int line) {
187 if (line < beginLine || line > endLine) {
188 return false;
189 }
190 if (line == beginLine) {
191 if (column < beginColumn) {
192 return false;
193 }
194 }
195 if (line == endLine) {
196 if (column > endColumn) {
197 return false;
198 }
199 }
200 return true;
201 }
202
203 public Template getTemplate()
204 {
205 return template;
206 }
207
208 TemplateObject copyLocationFrom(TemplateObject from)
209 {
210 template = from.template;
211 beginColumn = from.beginColumn;
212 beginLine = from.beginLine;
213 endColumn = from.endColumn;
214 endLine = from.endLine;
215 return this;
216 }
217
218 abstract public String getCanonicalForm();
219 }