001: /*
002: * Copyright (c) 2003 The Visigoth Software Society. All rights
003: * reserved.
004: *
005: * Redistribution and use in source and binary forms, with or without
006: * modification, are permitted provided that the following conditions
007: * are met:
008: *
009: * 1. Redistributions of source code must retain the above copyright
010: * notice, this list of conditions and the following disclaimer.
011: *
012: * 2. Redistributions in binary form must reproduce the above copyright
013: * notice, this list of conditions and the following disclaimer in
014: * the documentation and/or other materials provided with the
015: * distribution.
016: *
017: * 3. The end-user documentation included with the redistribution, if
018: * any, must include the following acknowledgement:
019: * "This product includes software developed by the
020: * Visigoth Software Society (http://www.visigoths.org/)."
021: * Alternately, this acknowledgement may appear in the software itself,
022: * if and wherever such third-party acknowledgements normally appear.
023: *
024: * 4. Neither the name "FreeMarker", "Visigoth", nor any of the names of the
025: * project contributors may be used to endorse or promote products derived
026: * from this software without prior written permission. For written
027: * permission, please contact visigoths@visigoths.org.
028: *
029: * 5. Products derived from this software may not be called "FreeMarker" or "Visigoth"
030: * nor may "FreeMarker" or "Visigoth" appear in their names
031: * without prior written permission of the Visigoth Software Society.
032: *
033: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
034: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
035: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
036: * DISCLAIMED. IN NO EVENT SHALL THE VISIGOTH SOFTWARE SOCIETY OR
037: * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
038: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
039: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
040: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
041: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
042: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
043: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
044: * SUCH DAMAGE.
045: * ====================================================================
046: *
047: * This software consists of voluntary contributions made by many
048: * individuals on behalf of the Visigoth Software Society. For more
049: * information on the Visigoth Software Society, please see
050: * http://www.visigoths.org/
051: */
052:
053: package freemarker.core;
054:
055: import freemarker.template.*;
056:
057: /**
058: * Objects that represent instructions or expressions
059: * in the compiled tree representation of the template
060: * all descend from this abstract base class.
061: */
062: public abstract class TemplateObject {
063:
064: private Template template;
065: int beginColumn, beginLine, endColumn, endLine;
066:
067: final void setLocation(Template template, Token begin, Token end)
068: throws ParseException {
069: setLocation(template, begin.beginColumn, begin.beginLine,
070: end.endColumn, end.endLine);
071: }
072:
073: final void setLocation(Template template, Token begin,
074: TemplateObject end) throws ParseException {
075: setLocation(template, begin.beginColumn, begin.beginLine,
076: end.endColumn, end.endLine);
077: }
078:
079: final void setLocation(Template template, TemplateObject begin,
080: Token end) throws ParseException {
081: setLocation(template, begin.beginColumn, begin.beginLine,
082: end.endColumn, end.endLine);
083: }
084:
085: final void setLocation(Template template, TemplateObject begin,
086: TemplateObject end) throws ParseException {
087: setLocation(template, begin.beginColumn, begin.beginLine,
088: end.endColumn, end.endLine);
089: }
090:
091: public final int getBeginColumn() {
092: return beginColumn;
093: }
094:
095: public final int getBeginLine() {
096: return beginLine;
097: }
098:
099: public final int getEndColumn() {
100: return endColumn;
101: }
102:
103: public final int getEndLine() {
104: return endLine;
105: }
106:
107: void setLocation(Template template, int beginColumn, int beginLine,
108: int endColumn, int endLine) throws ParseException {
109: this .template = template;
110: this .beginColumn = beginColumn;
111: this .beginLine = beginLine;
112: this .endColumn = endColumn;
113: this .endLine = endLine;
114: }
115:
116: static void assertNonNull(TemplateModel model, Expression exp,
117: Environment env) throws InvalidReferenceException {
118: if (model == null) {
119: throw new InvalidReferenceException("Expression " + exp
120: + " is undefined " + exp.getStartLocation() + ".",
121: env);
122: }
123: }
124:
125: static TemplateException invalidTypeException(TemplateModel model,
126: Expression exp, Environment env, String expected)
127: throws TemplateException {
128: assertNonNull(model, exp, env);
129: return new TemplateException("Expected " + expected + ". "
130: + exp + " evaluated instead to "
131: + model.getClass().getName() + " "
132: + exp.getStartLocation() + ".", env);
133: }
134:
135: /**
136: * Returns a string that indicates
137: * where in the template source, this object is.
138: */
139: public String getStartLocation() {
140: String templateName = template != null ? template.getName()
141: : "input";
142: return "on line " + beginLine + ", column " + beginColumn
143: + " in " + templateName;
144: }
145:
146: public String getEndLocation() {
147: String templateName = template != null ? template.getName()
148: : "input";
149: return "on line " + endLine + ", column " + endColumn + " in "
150: + templateName;
151: }
152:
153: public final String getSource() {
154: if (template != null) {
155: return template.getSource(beginColumn, beginLine,
156: endColumn, endLine);
157: } else {
158: return getCanonicalForm();
159: }
160: }
161:
162: public String toString() {
163: try {
164: return getSource();
165: } catch (Exception e) { // REVISIT: A bit of a hack? (JR)
166: return getCanonicalForm();
167: }
168: }
169:
170: /**
171: * @return whether the point in the template file specified by the
172: * column and line numbers is contained within this template object.
173: */
174: public boolean contains(int column, int line) {
175: if (line < beginLine || line > endLine) {
176: return false;
177: }
178: if (line == beginLine) {
179: if (column < beginColumn) {
180: return false;
181: }
182: }
183: if (line == endLine) {
184: if (column > endColumn) {
185: return false;
186: }
187: }
188: return true;
189: }
190:
191: public Template getTemplate() {
192: return template;
193: }
194:
195: TemplateObject copyLocationFrom(TemplateObject from) {
196: template = from.template;
197: beginColumn = from.beginColumn;
198: beginLine = from.beginLine;
199: endColumn = from.endColumn;
200: endLine = from.endLine;
201: return this ;
202: }
203:
204: abstract public String getCanonicalForm();
205: }
|