1 package com.icl.saxon.style; 2 import com.icl.saxon.tree.AttributeCollection; 3 import com.icl.saxon.*; 4 import com.icl.saxon.om.*; 5 import com.icl.saxon.tree.NodeImpl; 6 import com.icl.saxon.functions.Concat; 7 import com.icl.saxon.expr.*; 8 import com.icl.saxon.output.*; 9 import javax.xml.transform.*; 10 import java.io.*; 11 import java.util.*; 12 13 16 17 public abstract class XSLGeneralVariable extends StyleElement { 18 19 protected int variableFingerprint = -1; 20 protected Expression select = null; 21 protected String simpleText = null; 22 protected boolean global; 23 protected Procedure procedure = null; protected boolean assignable = false; 25 protected boolean redundant = false; 26 27 31 32 public boolean mayContainTemplateBody() { 33 return true; 34 } 35 36 public boolean isGlobal() { 37 return (getParentNode() instanceof XSLStyleSheet); 38 } 39 40 45 46 public boolean isAssignable() { 47 return assignable; 48 } 49 50 53 54 public Procedure getOwningProcedure() throws TransformerConfigurationException { 55 NodeInfo node = this; 56 while (true) { 57 NodeInfo next = (NodeInfo)node.getParent(); 58 if (next instanceof XSLStyleSheet) { 59 if (node instanceof XSLTemplate) { 60 return ((XSLTemplate)node).getProcedure(); 61 } else if (node instanceof XSLGeneralVariable) { 62 return ((XSLGeneralVariable)node).getProcedure(); 63 } else if (node instanceof SAXONFunction) { 64 return ((SAXONFunction)node).getProcedure(); 65 } else if (node instanceof XSLAttributeSet) { 66 return ((XSLAttributeSet)node).getProcedure(); 67 } else { 68 compileError("Local variable must be declared within a template"); 69 return new Procedure(); } 71 } 72 node=next; 73 } 74 } 75 76 80 81 public void preprocess() throws TransformerConfigurationException 82 { 83 if (global) { 84 getPrincipalStyleSheet().allocateLocalSlots(procedure.getNumberOfVariables()); 85 } 86 } 87 88 91 92 public String getVariableName() { 93 return getAttributeValue("", "name"); 94 } 95 96 99 100 public int getVariableFingerprint() { 101 102 107 if (variableFingerprint==-1) { 108 StandardNames sn = getStandardNames(); 109 String nameAttribute = getAttributeValue(sn.NAME & 0xfffff); 110 if (nameAttribute==null) { 111 return -1; } 113 try { 114 variableFingerprint = makeNameCode(nameAttribute, false) & 0xfffff; 115 } catch (NamespaceException err) { 116 variableFingerprint = -1; 117 } 118 } 119 return variableFingerprint; 120 } 121 122 public void prepareAttributes() throws TransformerConfigurationException { 123 124 getVariableFingerprint(); 125 126 StandardNames sn = getStandardNames(); 127 AttributeCollection atts = getAttributeList(); 128 129 String selectAtt = null; 130 String assignAtt = null; 131 String nameAtt = null; 132 133 for (int a=0; a<atts.getLength(); a++) { 134 int nc = atts.getNameCode(a); 135 int f = nc & 0xfffff; 136 if (f==sn.NAME) { 137 nameAtt = atts.getValue(a); 138 } else if (f==sn.SELECT) { 139 selectAtt = atts.getValue(a); 140 } else if (f==sn.SAXON_ASSIGNABLE) { 141 assignAtt = atts.getValue(a); 142 } else { 143 checkUnknownAttribute(nc); 144 } 145 } 146 147 if (nameAtt==null) { 148 reportAbsence("name"); 149 } else if (!Name.isQName(nameAtt)) { 150 compileError("Variable name must be a valid QName"); 151 } 152 153 154 if (selectAtt!=null) { 155 select = makeExpression(selectAtt); 156 } 157 158 if (assignAtt!=null && assignAtt.equals("yes")) { 159 assignable=true; 160 } 161 } 162 163 public void validate() throws TransformerConfigurationException { 164 global = (getParentNode() instanceof XSLStyleSheet); 165 if (global) { 166 procedure = new Procedure(); 167 } 168 if (select!=null && getFirstChild()!=null) { 169 compileError("An " + getDisplayName() + " element with a select attribute must be empty"); 170 } 171 172 if (select==null) { 173 NodeImpl first = (NodeImpl)getFirstChild(); 174 if (first==null) { 175 select = new StringValue(""); 176 } else { 177 NodeImpl next = (NodeImpl)first.getNextSibling(); 178 if (next==null) { 179 if (first.getNodeType() == NodeInfo.TEXT) { 181 simpleText = first.getStringValue(); 183 } 184 } 185 } 186 } 187 } 188 189 192 193 public void checkDuplicateDeclaration() throws TransformerConfigurationException { 194 Binding binding = getVariableBinding(getVariableFingerprint()); 195 int thisPrecedence = this.getPrecedence(); 196 if (binding!=null) { 197 if (global) { 198 int otherPrecedence = ((XSLGeneralVariable)binding).getPrecedence(); 199 if (thisPrecedence == otherPrecedence) { 200 compileError("Duplicate global variable declaration"); 201 } else if (thisPrecedence < otherPrecedence) { 202 redundant = true; 203 } else { 204 ((XSLGeneralVariable)binding).redundant = true; 205 } 206 } else { 207 if (!binding.isGlobal()) { 208 compileError("Variable is already declared in this template"); 210 } 211 } 212 } 213 } 214 215 216 219 220 protected Value getSelectValue(Context context) throws TransformerException { 221 if (select==null) { 222 SingletonNodeSet fragment; 223 if (simpleText != null) { 224 fragment = new TextFragmentValue(simpleText, 225 getSystemId(), 226 context.getController()); 227 } else { 228 Controller c = context.getController(); 229 FragmentValue frag = new FragmentValue(c); 230 Outputter old = c.getOutputter(); 231 c.changeOutputDestination(null, frag.getEmitter()); 232 if (global && procedure.getNumberOfVariables()>0) { 233 Bindery bindery = context.getBindery(); 234 bindery.openStackFrame(new ParameterSet()); 235 processChildren(context); 236 bindery.closeStackFrame(); 237 } else { 238 processChildren(context); 239 } 240 c.resetOutputDestination(old); 241 frag.setBaseURI(getSystemId()); 242 fragment = frag; 243 } 244 if (forwardsCompatibleModeIsEnabled()) { 245 fragment.allowGeneralUse(); 246 } 247 return fragment; 248 249 } else { 250 context.setStaticContext(staticContext); 251 Value result = select.evaluate(context); 252 if (assignable && (result instanceof NodeSetIntent)) { 253 result = new NodeSetExtent(((NodeSetIntent)result).enumerate(), 254 context.getController()); 255 } 256 return result; 257 } 258 } 259 260 264 265 public Procedure getProcedure() { 266 return procedure; 267 } 268 269 270 } 271 272 | Popular Tags |