1 package com.genimen.djeneric.tools.generator.core.nodes; 2 3 import java.io.UnsupportedEncodingException ; 4 import java.util.HashMap ; 5 import java.util.Vector ; 6 7 import com.genimen.djeneric.tools.generator.core.DjentelParserEngine; 8 import com.genimen.djeneric.tools.generator.core.ParseException; 9 import com.genimen.djeneric.tools.generator.core.SimpleNode; 10 import com.genimen.djeneric.tools.generator.core.util.EvaluationException; 11 import com.genimen.djeneric.tools.generator.core.util.ObjectPath; 12 import com.genimen.djeneric.tools.generator.core.util.ParseContext; 13 14 public class UnstructuredNode extends SimpleNode 15 { 16 Vector _sections = new Vector (); 17 18 public UnstructuredNode(int i) 19 { 20 super(i); 21 } 22 23 public UnstructuredNode(DjentelParserEngine p, int i) 24 { 25 super(p, i); 26 } 27 28 public String toString() 29 { 30 return data; 31 } 32 33 public void setData(String value) throws ParseException 34 { 35 data = value; 36 37 parseSections(data); 38 } 39 40 public String getData() 41 { 42 return data; 43 } 44 45 private String data; 46 47 public String getName() 48 { 49 return "unstructured text"; 50 } 51 52 void parseSections(String data) throws ParseException 53 { 54 HashMap replaceablesCache = new HashMap (); 55 56 int line = beginLine; 57 58 if (data.length() == 0) return; 59 60 int idx = 0; 61 int startOfStr = 0; 62 boolean inKeyword = false; 63 StringBuffer sb = new StringBuffer (); 64 int col = 0; 65 int colOffset = beginColumn; 66 while (idx < data.length()) 67 { 68 char chr = data.charAt(idx); 69 if (chr == '\n') 70 { 71 colOffset = 0; 72 line++; 73 col = 0; 74 } 75 char next = '.'; 76 if (idx < data.length() - 1) next = data.charAt(idx + 1); 77 78 if (chr == '\\' && ((next == '\n') || (next == '\r'))) 80 { 81 idx++; 82 col++; 83 } 84 else if (chr == '%' && next == '%') 85 { 86 idx++; 87 col++; 88 sb.append(chr); 89 } 90 else if (chr == '%') 91 { 92 if (inKeyword) 93 { 94 try 95 { 96 String expr = sb.toString(); 97 Replaceable repl = (Replaceable) replaceablesCache.get(expr); 98 if (repl == null) 99 { 100 repl = new Replaceable(expr, line, colOffset + startOfStr); 101 replaceablesCache.put(expr, repl); 102 } 103 _sections.add(repl); 105 } 106 catch (ParseException pe) 107 { 108 pe.setLine(line + pe.getLine() - 1); 109 pe.setColumn(pe.getColumn() + colOffset + startOfStr); 110 throw pe; 111 } 112 sb.setLength(0); 113 inKeyword = false; 114 } 115 else 116 { 117 startOfStr = col; 118 _sections.add(sb.toString()); 119 sb.setLength(0); 120 inKeyword = true; 121 } 122 } 123 else if ((chr == '\n' || chr == '\r') && inKeyword) 124 { 125 throw new ParseException("Unclosed %token% encountered (" + sb.toString() + ") near line " + line + " column " 126 + col, line, col); 127 } 128 else sb.append(chr); 129 130 idx++; 131 col++; 132 } 133 if (inKeyword) throw new ParseException("Unclosed %token% encountered at end of line (" + sb.toString() 134 + ") near line " + line, line, 1); 135 _sections.add(sb.toString()); 136 } 137 138 public String evaluate(ParseContext context) throws ParseException 139 { 140 StringBuffer sb = new StringBuffer (data.length() + 1000); 141 142 for (int i = 0; i < _sections.size(); i++) 143 { 144 Object obj = _sections.get(i); 145 if (obj instanceof String ) sb.append((String ) obj); 146 else 147 { 148 Replaceable repl = null; 149 try 150 { 151 repl = (Replaceable) obj; 152 sb.append(repl.evaluate(context)); 153 } 154 catch (Exception x) 155 { 156 throw new ParseException(x, repl.getLine(), repl.getColumn()); 157 } 158 159 } 160 } 161 return sb.toString(); 162 } 163 164 } 165 166 class Replaceable 167 { 168 169 String _path; 170 ValueExpression _function = null; 171 int _line, _col; 172 173 public Replaceable(String path, int line, int col) throws ParseException 174 { 175 _line = line; 176 _col = col; 177 178 if (isExpression(path)) 179 { 180 try 181 { 182 _function = DjentelParserEngine.parseExpression(path); 183 ((SimpleNode) _function).setLineInfo(line, col); 184 } 185 catch (UnsupportedEncodingException uee) 186 { 187 throw new ParseException(uee, 0, 0); 188 } 189 } 190 _path = path; 191 } 192 193 public boolean isExpression(String str) 194 { 195 for (int i = 0; i < str.length(); i++) 196 if ("+-/*%()".indexOf(str.charAt(i)) != -1) return true; 197 return false; 198 } 199 200 public int getLine() 201 { 202 return _line; 203 } 204 205 public int getColumn() 206 { 207 return _col; 208 } 209 210 public ValueExpression getFunction() 211 { 212 return _function; 213 } 214 215 public String getPath() 216 { 217 return _path; 218 } 219 220 public String evaluate(ParseContext context) throws EvaluationException, ParseException 221 { 222 if (_function != null) return evaluateFunction(context); 223 else return evaluateProperty(context); 224 } 225 226 private String evaluateFunction(ParseContext context) throws ParseException 227 { 228 Object o = _function.getValue(context); 229 if (o != null) return o.toString(); 230 return ""; 231 } 232 233 private String getPropVal(String path, ParseContext context) throws EvaluationException 234 { 235 String value; 236 Object o = ObjectPath.evaluateProperty(path, context); 237 if (o == null) value = ""; 238 else value = o.toString(); 239 return value; 240 } 241 242 private String evaluateProperty(ParseContext context) throws EvaluationException 243 { 244 return getPropVal(getPath(), context); 245 } 246 247 } | Popular Tags |