1 package net.sf.saxon.instruct; 2 import net.sf.saxon.Controller; 3 import net.sf.saxon.style.StandardNames; 4 import net.sf.saxon.event.*; 5 import net.sf.saxon.expr.Expression; 6 import net.sf.saxon.expr.StaticProperty; 7 import net.sf.saxon.expr.XPathContext; 8 import net.sf.saxon.om.Item; 9 import net.sf.saxon.om.NodeInfo; 10 import net.sf.saxon.om.Validation; 11 import net.sf.saxon.pattern.NodeKindTest; 12 import net.sf.saxon.pull.UnconstructedElement; 13 import net.sf.saxon.trans.DynamicError; 14 import net.sf.saxon.trans.XPathException; 15 import net.sf.saxon.type.ItemType; 16 import net.sf.saxon.type.ValidationException; 17 18 19 25 26 public abstract class ElementCreator extends ParentNodeConstructor { 27 28 34 35 protected boolean inheritNamespaces = true; 36 37 public ElementCreator() { } 38 39 43 44 public ItemType getItemType() { 45 return NodeKindTest.ELEMENT; 46 } 47 48 55 56 public int computeSpecialProperties() { 57 return super.computeSpecialProperties() | 58 StaticProperty.SINGLE_DOCUMENT_NODESET; 59 } 60 61 64 65 public void setValidationMode(int mode) { 66 validation = mode; 67 } 68 69 72 73 public int getValidationMode() { 74 return validation; 75 } 76 77 public abstract int getNameCode(XPathContext context) 78 throws XPathException; 79 80 86 87 protected abstract void outputNamespaceNodes(XPathContext context, Receiver receiver) 88 throws XPathException; 89 90 95 96 public int[] getActiveNamespaces() throws XPathException { 97 return null; 98 } 99 100 104 105 public int getImplementationMethod() { 106 return Expression.PROCESS_METHOD | Expression.EVALUATE_METHOD; 107 } 108 109 116 public TailCall processLeavingTail(XPathContext context) 117 throws XPathException { 118 119 try { 120 121 int nameCode = getNameCode(context); 122 int typeCode = (validation == Validation.PRESERVE ? StandardNames.XS_ANY_TYPE : StandardNames.XDT_UNTYPED); 123 124 Controller controller = context.getController(); 125 XPathContext c2 = context; 126 SequenceReceiver out = context.getReceiver(); 127 128 Receiver validator = controller.getConfiguration().getElementValidator( 129 out, nameCode, locationId, 130 getSchemaType(), validation, 131 controller.getNamePool() 132 ); 133 134 if (validator != out) { 135 c2 = context.newMinorContext(); 136 c2.setOrigin(this); 137 out = new TreeReceiver(validator); 138 out.setPipelineConfiguration(controller.makePipelineConfiguration()); 139 c2.setReceiver(out); 140 } 141 int properties = (inheritNamespaces ? 0 : ReceiverOptions.DISINHERIT_NAMESPACES); 142 out.startElement(nameCode, typeCode, locationId, properties); 143 144 146 outputNamespaceNodes(c2, out); 147 148 content.process(c2); 150 151 out.endElement(); 153 return null; 154 155 } catch (DynamicError e) { 156 if (e.getXPathContext() == null) { 157 e.setXPathContext(context); 158 } 159 if (e.getLocator()==null) { 160 e.setLocator(this); 161 } 162 throw e; 163 } 164 } 165 166 170 171 public Item evaluateItem(XPathContext context) throws XPathException { 172 if (isLazyConstruction()) { 174 UnconstructedElement e = new UnconstructedElement(this, context); 175 e.setNameCode(getNameCode(context)); 178 return e; 179 } else { 180 return constructElement(context); 181 } 182 } 183 184 190 private NodeInfo constructElement(XPathContext context) throws XPathException { 191 try { 192 Controller controller = context.getController(); 193 XPathContext c2 = context.newMinorContext(); 194 c2.setOrigin(this); 195 SequenceReceiver old = c2.getReceiver(); 196 SequenceOutputter seq; 197 if (old instanceof SequenceWriter && !((SequenceWriter)old).hasOpenNodes()) { 198 seq = (SequenceOutputter)old; 201 } else { 202 seq = new SequenceOutputter(1); 203 } 204 seq.setPipelineConfiguration(controller.makePipelineConfiguration()); 205 206 int nameCode = getNameCode(c2); 207 int typeCode = (validation == Validation.PRESERVE ? StandardNames.XS_ANY_TYPE : StandardNames.XDT_UNTYPED); 208 209 Receiver validator = controller.getConfiguration().getElementValidator( 210 seq, nameCode, locationId, 211 getSchemaType(), validation, 212 controller.getNamePool() 213 ); 214 215 SequenceReceiver ini = seq; 216 if (validator == seq) { 217 c2.setTemporaryReceiver(seq); 218 } else { 219 TreeReceiver tr = new TreeReceiver(validator); 220 tr.setPipelineConfiguration(seq.getPipelineConfiguration()); 221 c2.setReceiver(tr); 222 ini = tr; 223 } 224 225 226 ini.open(); 227 int properties = (inheritNamespaces ? 0 : ReceiverOptions.DISINHERIT_NAMESPACES); 228 ini.startElement(nameCode, typeCode, locationId, properties); 229 230 outputNamespaceNodes(c2, ini); 232 233 content.process(c2); 234 235 ini.endElement(); 236 ini.close(); 237 238 return (NodeInfo)seq.popLastItem(); 240 241 } catch (XPathException err) { 242 if (err instanceof ValidationException) { 243 ((ValidationException)err).setSourceLocator(this); 244 ((ValidationException)err).setSystemId(getSystemId()); 245 } 246 if (err.getLocator() == null) { 247 err.setLocator(this); 248 } 249 if (err instanceof DynamicError && ((DynamicError)err).getXPathContext() == null) { 250 ((DynamicError)err).setXPathContext(context); 251 } 252 throw err; 253 } 254 } 255 } 256 257 | Popular Tags |