1 package org.apache.velocity.runtime.parser.node; 2 3 /* 4 * Licensed to the Apache Software Foundation (ASF) under one 5 * or more contributor license agreements. See the NOTICE file 6 * distributed with this work for additional information 7 * regarding copyright ownership. The ASF licenses this file 8 * to you under the Apache License, Version 2.0 (the 9 * "License"); you may not use this file except in compliance 10 * with the License. You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, 15 * software distributed under the License is distributed on an 16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17 * KIND, either express or implied. See the License for the 18 * specific language governing permissions and limitations 19 * under the License. 20 */ 21 22 import org.apache.velocity.runtime.parser.Parser; 23 import org.apache.velocity.runtime.parser.StandardParserConstants; 24 import org.apache.velocity.runtime.parser.Token; 25 26 /** 27 * Utilities for dealing with the AST node structure. 28 * 29 * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a> 30 * @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a> 31 * @version $Id$ 32 */ 33 public class NodeUtils 34 { 35 /** 36 * Collect all the <SPECIAL_TOKEN>s that 37 * are carried along with a token. Special 38 * tokens do not participate in parsing but 39 * can still trigger certain lexical actions. 40 * In some cases you may want to retrieve these 41 * special tokens, this is simply a way to 42 * extract them. 43 * @param t the Token 44 * @return StrBuilder with the special tokens. 45 * @since 2.0.0 46 */ getSpecialText(Parser parser, Token t)47 public static StringBuilder getSpecialText(Parser parser, Token t) 48 { 49 StringBuilder sb = new StringBuilder(); 50 51 Token tmp_t = t.specialToken; 52 53 while (tmp_t.specialToken != null) 54 { 55 tmp_t = tmp_t.specialToken; 56 } 57 58 while (tmp_t != null) 59 { 60 String st = tmp_t.image; 61 62 for(int i = 0, is = st.length(); i < is; i++) 63 { 64 char c = st.charAt(i); 65 66 if ( c == parser.hash() || c == parser.dollar() ) 67 { 68 sb.append( c ); 69 } 70 71 /* 72 * more dreaded MORE hack :) 73 * 74 * looking for ("\\")*"$" sequences 75 */ 76 77 if ( c == '\\') 78 { 79 boolean ok = true; 80 boolean term = false; 81 82 int j = i; 83 for( ok = true; ok && j < is; j++) 84 { 85 char cc = st.charAt( j ); 86 87 if (cc == '\\') 88 { 89 /* 90 * if we see a \, keep going 91 */ 92 continue; 93 } 94 else if( cc == parser.dollar() ) 95 { 96 /* 97 * a $ ends it correctly 98 */ 99 term = true; 100 ok = false; 101 } 102 else 103 { 104 /* 105 * nah... 106 */ 107 ok = false; 108 } 109 } 110 111 if (term) 112 { 113 String foo = st.substring( i, j ); 114 sb.append( foo ); 115 i = j; 116 } 117 } 118 } 119 120 tmp_t = tmp_t.next; 121 } 122 return sb; 123 } 124 125 /** 126 * complete node literal 127 * @param t 128 * @return A node literal. 129 */ tokenLiteral( Parser parser, Token t )130 public static String tokenLiteral( Parser parser, Token t ) 131 { 132 // Look at kind of token and return "" when it's a block comment 133 if (t.kind == StandardParserConstants.MULTI_LINE_COMMENT) 134 { 135 return ""; 136 } 137 else if (t.specialToken == null || t.specialToken.image.startsWith(parser.lineComment())) 138 { 139 return t.image; 140 } 141 else 142 { 143 StringBuilder special = getSpecialText(parser, t); 144 if (special.length() > 0) 145 { 146 return special.append(t.image).toString(); 147 } 148 return t.image; 149 } 150 } 151 152 /** 153 * Fix children indentation in structured space gobbling mode. 154 * @param parent 155 * @param parentIndentation 156 */ fixIndentation(SimpleNode parent, String parentIndentation)157 public static void fixIndentation(SimpleNode parent, String parentIndentation) 158 { 159 IndentationFixer fixer = new IndentationFixer(parentIndentation); 160 parent.childrenAccept(fixer, null); 161 } 162 } 163