1 52 53 package freemarker.core; 54 55 import java.util.ArrayList ; 56 import freemarker.template.*; 57 58 62 final class DynamicKeyName extends Expression { 63 64 private final Expression nameExpression; 65 private final Expression target; 66 67 DynamicKeyName(Expression target, Expression nameExpression) { 68 this.target = target; 69 this.nameExpression = nameExpression; 70 } 71 72 TemplateModel _getAsTemplateModel(Environment env) throws TemplateException 73 { 74 TemplateModel targetModel = target.getAsTemplateModel(env); 75 assertNonNull(targetModel, target, env); 76 if (nameExpression instanceof Range) { 77 return dealWithRangeKey(targetModel, (Range) nameExpression, env); 78 } 79 TemplateModel keyModel = nameExpression.getAsTemplateModel(env); 80 if(keyModel == null) { 81 if(env.isClassicCompatible()) { 82 keyModel = TemplateScalarModel.EMPTY_STRING; 83 } 84 else { 85 assertNonNull(keyModel, nameExpression, env); 86 } 87 } 88 if (keyModel instanceof TemplateNumberModel) { 89 int index = EvaluationUtil.getNumber(keyModel, nameExpression, env).intValue(); 90 return dealWithNumericalKey(targetModel, index, env); 91 } 92 if (keyModel instanceof TemplateScalarModel) { 93 String key = EvaluationUtil.getString((TemplateScalarModel)keyModel, nameExpression, env); 94 return dealWithStringKey(targetModel, key, env); 95 } 96 throw invalidTypeException(keyModel, nameExpression, env, "number, range, or string"); 97 } 98 99 100 private TemplateModel dealWithNumericalKey(TemplateModel targetModel, 101 int index, 102 Environment env) 103 throws TemplateException 104 { 105 if (targetModel instanceof TemplateSequenceModel) { 106 TemplateSequenceModel tsm = (TemplateSequenceModel) targetModel; 107 int size = Integer.MAX_VALUE; 108 try { 109 size = tsm.size(); 110 } catch (Exception e) {} 111 return index<size ? tsm.get(index) : null; 112 } 113 114 try 115 { 116 String s = target.getStringValue(env); 117 try { 118 return new SimpleScalar(s.substring(index, index+1)); 119 } catch (RuntimeException re) { 120 throw new TemplateException("", re, env); 121 } 122 } 123 catch(NonStringException e) 124 { 125 throw invalidTypeException(targetModel, target, env, "number, sequence, or string"); 126 } 127 } 128 129 130 private TemplateModel dealWithStringKey(TemplateModel targetModel, 131 String key, 132 Environment env) 133 throws TemplateException 134 { 135 if(targetModel instanceof TemplateHashModel) { 136 return((TemplateHashModel) targetModel).get(key); 137 } 138 throw invalidTypeException(targetModel, target, env, "hash"); 139 } 140 141 private TemplateModel dealWithRangeKey(TemplateModel targetModel, 142 Range range, 143 Environment env) 144 throws TemplateException 145 { 146 int start = EvaluationUtil.getNumber(range.left, env).intValue(); 147 int end = EvaluationUtil.getNumber(range.right, env).intValue(); 148 if (targetModel instanceof TemplateSequenceModel) { 149 TemplateSequenceModel sequence = (TemplateSequenceModel) targetModel; 150 ArrayList list = new ArrayList (1+Math.abs(start-end)); 151 if (start>end) { 152 for (int i = start; i>=end; i--) { 153 list.add(sequence.get(i)); 154 } 155 } 156 else { 157 for (int i = start; i<=end; i++) { 158 list.add(sequence.get(i)); 159 } 160 } 161 return new SimpleSequence(list); 162 } 163 164 try 165 { 166 String s = target.getStringValue(env); 167 try { 168 return new SimpleScalar(s.substring(start, end+1)); 169 } catch (RuntimeException re) { 170 String msg = "Error " + getStartLocation(); 171 throw new TemplateException(msg, re, env); 172 } 173 } 174 catch(NonStringException e) 175 { 176 throw invalidTypeException(target.getAsTemplateModel(env), target, env, "number, scalar, or sequence"); 177 } 178 } 179 180 public String getCanonicalForm() { 181 return target.getCanonicalForm() 182 + "[" 183 + nameExpression.getCanonicalForm() 184 + "]"; 185 } 186 187 boolean isLiteral() { 188 return constantValue != null || (target.isLiteral() && nameExpression.isLiteral()); 189 } 190 191 Expression _deepClone(String name, Expression subst) { 192 return new DynamicKeyName(target.deepClone(name, subst), nameExpression.deepClone(name, subst)); 193 } 194 } 195 | Popular Tags |