001: package org.apache.velocity.runtime.parser.node;
002:
003: /*
004: * Licensed to the Apache Software Foundation (ASF) under one
005: * or more contributor license agreements. See the NOTICE file
006: * distributed with this work for additional information
007: * regarding copyright ownership. The ASF licenses this file
008: * to you under the Apache License, Version 2.0 (the
009: * "License"); you may not use this file except in compliance
010: * with the License. You may obtain a copy of the License at
011: *
012: * http://www.apache.org/licenses/LICENSE-2.0
013: *
014: * Unless required by applicable law or agreed to in writing,
015: * software distributed under the License is distributed on an
016: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017: * KIND, either express or implied. See the License for the
018: * specific language governing permissions and limitations
019: * under the License.
020: */
021:
022: import java.util.ArrayList;
023: import java.util.List;
024:
025: import org.apache.velocity.context.InternalContextAdapter;
026: import org.apache.velocity.exception.MethodInvocationException;
027: import org.apache.velocity.runtime.parser.Parser;
028: import org.apache.velocity.runtime.parser.ParserVisitor;
029:
030: /**
031: * handles the range 'operator' [ n .. m ]
032: *
033: * Please look at the Parser.jjt file which is
034: * what controls the generation of this class.
035: *
036: * @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
037: */
038: public class ASTIntegerRange extends SimpleNode {
039: /**
040: * @param id
041: */
042: public ASTIntegerRange(int id) {
043: super (id);
044: }
045:
046: /**
047: * @param p
048: * @param id
049: */
050: public ASTIntegerRange(Parser p, int id) {
051: super (p, id);
052: }
053:
054: /**
055: * @see org.apache.velocity.runtime.parser.node.SimpleNode#jjtAccept(org.apache.velocity.runtime.parser.ParserVisitor, java.lang.Object)
056: */
057: public Object jjtAccept(ParserVisitor visitor, Object data) {
058: return visitor.visit(this , data);
059: }
060:
061: /**
062: * does the real work. Creates an Vector of Integers with the
063: * right value range
064: *
065: * @param context app context used if Left or Right of .. is a ref
066: * @return Object array of Integers
067: * @throws MethodInvocationException
068: */
069: public Object value(InternalContextAdapter context)
070: throws MethodInvocationException {
071: /*
072: * get the two range ends
073: */
074:
075: Object left = jjtGetChild(0).value(context);
076: Object right = jjtGetChild(1).value(context);
077:
078: /*
079: * if either is null, lets log and bail
080: */
081:
082: if (left == null || right == null) {
083: log.error((left == null ? "Left" : "Right")
084: + " side of range operator [n..m] has null value."
085: + " Operation not possible. "
086: + context.getCurrentTemplateName() + " [line "
087: + getLine() + ", column " + getColumn() + "]");
088: return null;
089: }
090:
091: /*
092: * if not an Integer, not much we can do either
093: */
094:
095: if (!(left instanceof Integer) || !(right instanceof Integer)) {
096: log
097: .error((!(left instanceof Integer) ? "Left"
098: : "Right")
099: + " side of range operator is not a valid type. "
100: + "Currently only integers (1,2,3...) and Integer type is supported. "
101: + context.getCurrentTemplateName()
102: + " [line "
103: + getLine()
104: + ", column "
105: + getColumn() + "]");
106:
107: return null;
108: }
109:
110: /*
111: * get the two integer values of the ends of the range
112: */
113:
114: int l = ((Integer) left).intValue();
115: int r = ((Integer) right).intValue();
116:
117: /*
118: * find out how many there are
119: */
120:
121: int nbrElements = Math.abs(l - r);
122: nbrElements += 1;
123:
124: /*
125: * Determine whether the increment is positive or negative.
126: */
127:
128: int delta = (l >= r) ? -1 : 1;
129:
130: /*
131: * Fill the range with the appropriate values.
132: */
133:
134: List elements = new ArrayList(nbrElements);
135: int value = l;
136:
137: for (int i = 0; i < nbrElements; i++) {
138: // TODO: JDK 1.4+ -> valueOf()
139: elements.add(new Integer(value));
140: value += delta;
141: }
142:
143: return elements;
144: }
145: }
|