1 package net.sf.saxon.style; 2 import net.sf.saxon.expr.*; 3 import net.sf.saxon.functions.Concat; 4 import net.sf.saxon.functions.SystemFunction; 5 import net.sf.saxon.instruct.SimpleContentConstructor; 6 import net.sf.saxon.trans.StaticError; 7 import net.sf.saxon.trans.XPathException; 8 import net.sf.saxon.type.Type; 9 import net.sf.saxon.value.Cardinality; 10 import net.sf.saxon.value.StringValue; 11 12 import java.util.ArrayList ; 13 import java.util.List ; 14 15 21 22 public abstract class AttributeValueTemplate { 23 24 private AttributeValueTemplate() {} 25 26 27 30 31 public static Expression make(String avt, 32 int lineNumber, 33 StaticContext env) throws XPathException { 34 35 List components = new ArrayList (5); 36 37 int i0, i1, i8, i9; 38 int len = avt.length(); 39 int last = 0; 40 while (last < len) { 41 42 i0 = avt.indexOf("{", last); 43 i1 = avt.indexOf("{{", last); 44 i8 = avt.indexOf("}", last); 45 i9 = avt.indexOf("}}", last); 46 47 if ((i0 < 0 || len < i0) && (i8 < 0 || len < i8)) { addStringComponent(components, avt, last, len); 49 break; 50 } else if (i8 >= 0 && (i0 < 0 || i8 < i0)) { if (i8 != i9) { StaticError err = new StaticError( 53 "Closing curly brace in attribute value template \"" + avt.substring(0,len) + "\" must be doubled"); 54 err.setErrorCode("XTSE0360"); 55 throw err; 56 } 57 addStringComponent(components, avt, last, i8 + 1); 58 last = i8 + 2; 59 } else if (i1 >= 0 && i1 == i0) { addStringComponent(components, avt, last, i1 + 1); 61 last = i1 + 2; 62 } else if (i0 >= 0) { if (i0 > last) { 64 addStringComponent(components, avt, last, i0); 65 } 66 Expression exp; 67 ExpressionParser parser = new ExpressionParser(); 68 exp = parser.parse(avt, i0 + 1, Token.RCURLY, lineNumber, env); 69 exp = exp.simplify(env); 70 last = parser.getTokenizer().currentTokenStartOffset + 1; 71 72 if (env.isInBackwardsCompatibleMode()) { 73 components.add(makeFirstItem(exp, env)); 74 } else { 75 components.add(new SimpleContentConstructor(exp, StringValue.SINGLE_SPACE).simplify(env)); 76 } 77 78 } else { 79 throw new IllegalStateException ("Internal error parsing AVT"); 80 } 81 } 82 83 85 if (components.size() == 0) { 86 return StringValue.EMPTY_STRING; 87 } 88 89 91 if (components.size() == 1) { 92 return ((Expression) components.get(0)).simplify(env); 93 } 94 95 97 Concat fn = (Concat) SystemFunction.makeSystemFunction("concat", components.size(), env.getNamePool()); 98 Expression[] args = new Expression[components.size()]; 99 components.toArray(args); 100 fn.setArguments(args); 101 fn.setLocationId(env.getLocationMap().allocateLocationId(env.getSystemId(), lineNumber)); 102 return fn.simplify(env); 103 104 } 105 106 private static void addStringComponent(List components, String avt, int start, int end) { 107 if (start < end) { 108 components.add(StringValue.makeStringValue(avt.substring(start, end))); 109 } 110 } 111 112 115 116 public static Expression makeFirstItem(Expression exp, StaticContext env) { 117 if (!Type.isSubType(exp.getItemType(), Type.ANY_ATOMIC_TYPE)) { 118 exp = new Atomizer(exp, env.getConfiguration()); 119 } 120 if (Cardinality.allowsMany(exp.getCardinality())) { 121 exp = new FirstItemExpression(exp); 122 } 123 if (!Type.isSubType(exp.getItemType(), Type.STRING_TYPE)) { 124 exp = new AtomicSequenceConverter(exp, Type.STRING_TYPE); 125 } 126 return exp; 127 } 128 129 } 130 131 | Popular Tags |