1 package net.sf.saxon.instruct; 2 3 import net.sf.saxon.expr.*; 4 import net.sf.saxon.om.*; 5 import net.sf.saxon.trans.XPathException; 6 import net.sf.saxon.type.ItemType; 7 import net.sf.saxon.type.Type; 8 import net.sf.saxon.value.StringValue; 9 import net.sf.saxon.value.Cardinality; 10 import net.sf.saxon.value.AtomicValue; 11 12 import java.io.PrintStream ; 13 import java.util.Iterator ; 14 15 20 21 public class SimpleContentConstructor extends ComputedExpression { 22 23 Expression select; 24 Expression separator; 25 boolean isSingleton = false; 26 boolean isAtomic = false; 27 28 public SimpleContentConstructor(Expression select, Expression separator) { 29 this.select = select; 30 this.separator = separator; 31 adoptChildExpression(select); 32 adoptChildExpression(separator); 33 } 34 35 39 40 protected int computeCardinality() { 41 return StaticProperty.EXACTLY_ONE; 42 43 } 44 45 public Expression typeCheck(StaticContext env, ItemType contextItemType) throws XPathException { 46 select = select.typeCheck(env, contextItemType); 47 separator = separator.typeCheck(env, contextItemType); 48 if (!Cardinality.allowsMany(select.getCardinality())) { 49 isSingleton = true; 50 } 51 if (Type.isSubType(select.getItemType(), Type.ANY_ATOMIC_TYPE)) { 52 isAtomic = true; 53 } 54 return this; 55 } 56 57 public Expression optimize(Optimizer opt, StaticContext env, ItemType contextItemType) throws XPathException { 58 select = select.optimize(opt, env, contextItemType); 59 separator = separator.optimize(opt, env, contextItemType); 60 return this; 61 } 62 63 75 76 public ItemType getItemType() { 77 return Type.STRING_TYPE; 78 } 79 80 88 89 public void display(int level, NamePool pool, PrintStream out) { 90 out.println(ExpressionTool.indent(level) + "construct simple content"); 91 select.display(level+1, pool, out); 92 separator.display(level+1, pool, out); 93 } 94 95 104 105 public Expression simplify(StaticContext env) throws XPathException { 106 select = select.simplify(env); 107 if (select instanceof AtomicValue) { 108 return select; 109 } 110 separator = separator.simplify(env); 111 return this; 112 } 113 114 121 122 public Iterator iterateSubExpressions() { 123 return new PairIterator(select, separator); 124 } 125 126 142 143 public Expression promote(PromotionOffer offer) throws XPathException { 144 Expression exp = offer.accept(this); 145 if (exp!=null) { 146 return exp; 147 } else { 148 select = doPromotion(select, offer); 149 separator = doPromotion(separator, offer); 150 return this; 151 } 152 } 153 154 169 170 public Item evaluateItem(XPathContext context) throws XPathException { 171 SequenceIterator iter; 172 if (isSingleton) { 173 Item item = select.evaluateItem(context); 175 if (item == null || item instanceof StringValue) { 176 return item; 177 } else if (item instanceof AtomicValue) { 178 return ((AtomicValue)item).convert(Type.STRING, context); 179 } else { 180 iter = SingletonIterator.makeIterator(item); 181 } 182 } else { 183 iter = select.iterate(context); 184 } 185 FastStringBuffer sb = new FastStringBuffer(1024); 186 boolean prevText = false; 187 boolean first = true; 188 CharSequence sep = null; 189 while (true) { 190 Item item = iter.next(); 191 if (item==null) { 192 break; 193 } 194 if (item instanceof NodeInfo) { 195 if (((NodeInfo)item).getNodeKind() == Type.TEXT) { 196 CharSequence s = item.getStringValueCS(); 197 if (s.length() > 0) { 198 if (!first && !prevText) { 199 if (sep == null) { 200 sep = separator.evaluateItem(context).getStringValueCS(); 201 } 202 sb.append(sep); 203 } 204 first = false; 205 sb.append(s); 206 prevText = true; 207 } 208 } else { 209 prevText = false; 210 SequenceIterator iter2 = item.getTypedValue(); 211 while (true) { 212 Item item2 = iter2.next(); 213 if (item2 == null) { 214 break; 215 } 216 if (!first) { 217 if (sep == null) { 218 sep = separator.evaluateItem(context).getStringValueCS(); 219 } 220 sb.append(sep); 221 } 222 first = false; 223 sb.append(item2.getStringValueCS()); 224 } 225 } 226 } else { 227 if (!first) { 228 if (sep == null) { 229 sep = separator.evaluateItem(context).getStringValueCS(); 230 } 231 sb.append(sep); 232 } 233 first = false; 234 sb.append(item.getStringValueCS()); 235 } 236 } 237 return StringValue.makeStringValue(sb.condense()); 238 } 239 240 244 245 public int getImplementationMethod() { 246 return Expression.EVALUATE_METHOD; 247 } 248 249 } 250 251 252 | Popular Tags |