1 52 53 package freemarker.core; 54 55 import freemarker.template.*; 56 import java.util.*; 57 58 64 final class AddConcatExpression extends Expression { 65 66 private final Expression left; 67 private final Expression right; 68 69 AddConcatExpression(Expression left, Expression right) { 70 this.left = left; 71 this.right = right; 72 } 73 74 TemplateModel _getAsTemplateModel(Environment env) 75 throws TemplateException 76 { 77 TemplateModel leftModel = left.getAsTemplateModel(env); 78 TemplateModel rightModel = right.getAsTemplateModel(env); 79 if (leftModel instanceof TemplateNumberModel && rightModel instanceof TemplateNumberModel) 80 { 81 Number first = EvaluationUtil.getNumber((TemplateNumberModel) leftModel, left, env); 82 Number second = EvaluationUtil.getNumber((TemplateNumberModel) rightModel, right, env); 83 ArithmeticEngine ae = 84 env != null 85 ? env.getArithmeticEngine() 86 : getTemplate().getArithmeticEngine(); 87 return new SimpleNumber(ae.add(first, second)); 88 } 89 else if(leftModel instanceof TemplateSequenceModel && rightModel instanceof TemplateSequenceModel) 90 { 91 return new ConcatenatedSequence((TemplateSequenceModel)leftModel, (TemplateSequenceModel)rightModel); 92 } 93 else 94 { 95 try { 96 String s1 = getStringValue(leftModel, left, env); 97 if(s1 == null) s1 = "null"; 98 String s2 = getStringValue(rightModel, right, env); 99 if(s2 == null) s2 = "null"; 100 return new SimpleScalar(s1.concat(s2)); 101 } catch (NonStringException e) { 102 if (leftModel instanceof TemplateHashModel && rightModel instanceof TemplateHashModel) { 103 if (leftModel instanceof TemplateHashModelEx && rightModel instanceof TemplateHashModelEx) { 104 TemplateHashModelEx leftModelEx = (TemplateHashModelEx)leftModel; 105 TemplateHashModelEx rightModelEx = (TemplateHashModelEx)rightModel; 106 if (leftModelEx.size() == 0) { 107 return rightModelEx; 108 } else if (rightModelEx.size() == 0) { 109 return leftModelEx; 110 } else { 111 return new ConcatenatedHashEx(leftModelEx, rightModelEx); 112 } 113 } else { 114 return new ConcatenatedHash((TemplateHashModel)leftModel, 115 (TemplateHashModel)rightModel); 116 } 117 } else { 118 throw e; 119 } 120 } 121 } 122 } 123 124 boolean isLiteral() { 125 return constantValue != null || (left.isLiteral() && right.isLiteral()); 126 } 127 128 Expression _deepClone(String name, Expression subst) { 129 return new AddConcatExpression(left.deepClone(name, subst), right.deepClone(name, subst)); 130 } 131 132 public String getCanonicalForm() { 133 return left.getCanonicalForm() + " + " + right.getCanonicalForm(); 134 } 135 136 private static final class ConcatenatedSequence 137 implements 138 TemplateSequenceModel 139 { 140 private final TemplateSequenceModel left; 141 private final TemplateSequenceModel right; 142 143 ConcatenatedSequence(TemplateSequenceModel left, TemplateSequenceModel right) 144 { 145 this.left = left; 146 this.right = right; 147 } 148 149 public int size() 150 throws 151 TemplateModelException 152 { 153 return left.size() + right.size(); 154 } 155 156 public TemplateModel get(int i) 157 throws 158 TemplateModelException 159 { 160 int ls = left.size(); 161 return i < ls ? left.get(i) : right.get(i - ls); 162 } 163 } 164 165 private static class ConcatenatedHash 166 implements TemplateHashModel 167 { 168 protected final TemplateHashModel left; 169 protected final TemplateHashModel right; 170 171 ConcatenatedHash(TemplateHashModel left, TemplateHashModel right) 172 { 173 this.left = left; 174 this.right = right; 175 } 176 177 public TemplateModel get(String key) 178 throws TemplateModelException 179 { 180 TemplateModel model = right.get(key); 181 return (model != null) ? model : left.get(key); 182 } 183 184 public boolean isEmpty() 185 throws TemplateModelException 186 { 187 return left.isEmpty() && right.isEmpty(); 188 } 189 } 190 191 private static final class ConcatenatedHashEx 192 extends ConcatenatedHash 193 implements TemplateHashModelEx 194 { 195 private Set keySet; 196 private TemplateCollectionModel keys; 197 private TemplateCollectionModel values; 198 private int size; 199 200 ConcatenatedHashEx(TemplateHashModelEx left, TemplateHashModelEx right) 201 { 202 super(left, right); 203 } 204 205 public int size() throws TemplateModelException 206 { 207 initKeys(); 208 return size; 209 } 210 211 public TemplateCollectionModel keys() 212 throws TemplateModelException 213 { 214 initKeys(); 215 return keys; 216 } 217 218 public TemplateCollectionModel values() 219 throws TemplateModelException 220 { 221 initValues(); 222 return values; 223 } 224 225 private void initKeys() 226 throws TemplateModelException 227 { 228 if (keys == null) { 229 keySet = new HashSet(); 230 addKeys(keySet, (TemplateHashModelEx)this.left); 231 addKeys(keySet, (TemplateHashModelEx)this.right); 232 size = keySet.size(); 233 keys = new CollectionAndSequence(new SimpleSequence(keySet)); 234 } 235 } 236 237 private static void addKeys(Set set, TemplateHashModelEx hash) 238 throws TemplateModelException 239 { 240 TemplateModelIterator it = hash.keys().iterator(); 241 while (it.hasNext()) { 242 set.add(((TemplateScalarModel)it.next()).getAsString()); 243 } 244 } 245 246 private void initValues() 247 throws TemplateModelException 248 { 249 if (values == null) { 250 List list = new ArrayList(size()); 251 for (Iterator it = keySet.iterator(); it.hasNext();) { 252 list.add(get((String )it.next())); 253 } 254 values = new CollectionAndSequence(new SimpleSequence(list)); 255 } 256 } 257 } 258 } 259 | Popular Tags |