1 package net.sf.saxon.style; 2 3 import net.sf.saxon.Controller; 4 import net.sf.saxon.event.ProxyReceiver; 5 import net.sf.saxon.event.StartTagBuffer; 6 import net.sf.saxon.expr.*; 7 import net.sf.saxon.instruct.SlotManager; 8 import net.sf.saxon.om.NamespaceConstant; 9 import net.sf.saxon.trans.StaticError; 10 import net.sf.saxon.trans.XPathException; 11 import net.sf.saxon.type.ItemType; 12 import net.sf.saxon.type.Type; 13 14 import javax.xml.transform.Source ; 15 import javax.xml.transform.TransformerException ; 16 import javax.xml.transform.URIResolver ; 17 import java.util.Stack ; 18 19 24 25 public class UseWhenFilter extends ProxyReceiver { 26 27 private StartTagBuffer startTag; 28 private int useWhenCode; 29 private int xslUseWhenCode; 30 private int defaultNamespaceCode; 31 private int depthOfHole = 0; 32 private boolean emptyStylesheetElement = false; 33 private Stack defaultNamespaceStack = new Stack (); 34 35 public UseWhenFilter(StartTagBuffer startTag) { 36 this.startTag = startTag; 37 } 38 39 42 43 public void open() throws XPathException { 44 useWhenCode = getNamePool().allocate("", "", "use-when") & 0xfffff; 45 xslUseWhenCode = getNamePool().allocate("xsl", NamespaceConstant.XSLT, "use-when"); 46 defaultNamespaceCode = getNamePool().allocate("", "", "xpath-default-namespace"); 47 super.open(); 48 } 49 50 57 58 public void startElement(int nameCode, int typeCode, int locationId, int properties) throws XPathException { 59 defaultNamespaceStack.push(startTag.getAttribute(defaultNamespaceCode)); 60 if (emptyStylesheetElement) { 61 depthOfHole = 1; 62 } 63 if (depthOfHole == 0) { 64 String useWhen; 65 if ((nameCode & 0xfffff) < 1024) { 66 useWhen = startTag.getAttribute(useWhenCode); 67 } else { 68 useWhen = startTag.getAttribute(xslUseWhenCode); 69 } 70 if (useWhen != null) { 71 try { 72 boolean b = evaluateUseWhen(useWhen, getDocumentLocator().getLineNumber(locationId)); 73 if (!b) { 74 int fp = nameCode & 0xfffff; 75 if (fp == StandardNames.XSL_STYLESHEET || fp == StandardNames.XSL_TRANSFORM) { 76 emptyStylesheetElement = true; 77 } else { 78 depthOfHole = 1; 79 return; 80 } 81 } 82 } catch (XPathException e) { 83 StaticError err = new StaticError("Error in use-when expression. " + e.getMessage()); 84 ExpressionLocation loc = new ExpressionLocation(); 85 loc.setSystemId(getDocumentLocator().getSystemId(locationId)); 86 loc.setLineNumber(getDocumentLocator().getLineNumber(locationId)); 87 err.setLocator(loc); 88 err.setErrorCode(e.getErrorCodeLocalPart()); 89 try { 90 getPipelineConfiguration().getErrorListener().fatalError(err); 91 } catch (TransformerException tex) { 92 throw StaticError.makeStaticError(tex); 93 } 94 throw err; 95 } 96 } 97 } else { 98 depthOfHole++; 99 } 100 super.startElement(nameCode, typeCode, locationId, properties); 101 } 102 103 116 117 public void namespace(int namespaceCode, int properties) throws XPathException { 118 if (depthOfHole == 0) { 119 super.namespace(namespaceCode, properties); 120 } 121 } 122 123 135 136 public void attribute(int nameCode, int typeCode, CharSequence value, int locationId, int properties) throws XPathException { 137 if (depthOfHole == 0) { 138 super.attribute(nameCode, typeCode, value, locationId, properties); 139 } 140 } 141 142 148 149 150 public void startContent() throws XPathException { 151 if (depthOfHole == 0) { 152 super.startContent(); 153 } 154 } 155 156 159 160 public void endElement() throws XPathException { 161 defaultNamespaceStack.pop(); 162 if (depthOfHole > 0) { 163 depthOfHole--; 164 } else { 165 super.endElement(); 166 } 167 } 168 169 172 173 public void characters(CharSequence chars, int locationId, int properties) throws XPathException { 174 if (depthOfHole == 0) { 175 super.characters(chars, locationId, properties); 176 } 177 } 178 179 182 183 public void processingInstruction(String target, CharSequence data, int locationId, int properties) { 184 } 186 187 190 191 public void comment(CharSequence chars, int locationId, int properties) throws XPathException { 192 } 194 195 198 199 public boolean evaluateUseWhen(String expression, int locationId) throws XPathException { 200 UseWhenStaticContext staticContext = new UseWhenStaticContext(getConfiguration(), startTag); 201 staticContext.setBaseURI(getDocumentLocator().getSystemId(locationId)); 203 for (int i=defaultNamespaceStack.size()-1; i>=0; i--) { 204 String uri = (String )defaultNamespaceStack.get(i); 205 if (uri != null) { 206 short code = getNamePool().getCodeForURI(uri); 207 staticContext.setDefaultElementNamespace(code); 208 break; 209 } 210 } 211 Expression expr = ExpressionTool.make(expression, staticContext, 212 0, Token.EOF, getDocumentLocator().getLineNumber(locationId)); 213 ItemType contextItemType = Type.ITEM_TYPE; 214 expr = expr.typeCheck(staticContext, contextItemType); 215 SlotManager stackFrameMap = getPipelineConfiguration().getConfiguration().makeSlotManager(); 216 ExpressionTool.allocateSlots(expr, stackFrameMap.getNumberOfVariables(), stackFrameMap); 217 Controller controller = new Controller(getConfiguration()); 218 controller.setURIResolver(new URIPreventer()); 219 XPathContext dynamicContext = controller.newXPathContext(); 220 dynamicContext = dynamicContext.newCleanContext(); 221 ((XPathContextMajor)dynamicContext).openStackFrame(stackFrameMap.getNumberOfVariables()); 222 return ExpressionTool.effectiveBooleanValue(expr.iterate(dynamicContext)); 223 } 224 225 228 229 private static class URIPreventer implements URIResolver { 230 243 public Source resolve(String href, String base) throws TransformerException { 244 throw new TransformerException ("No external documents are available within an [xsl]use-when expression"); 245 } 246 } 247 248 249 } 250 251 269 | Popular Tags |