1 16 package org.apache.cocoon.components.language.markup.xsp; 17 18 import org.apache.cocoon.components.language.markup.LogicsheetFilter; 19 import org.apache.cocoon.xml.AbstractXMLPipe; 20 import org.apache.cocoon.xml.AttributesImpl; 21 import org.apache.cocoon.xml.XMLConsumer; 22 import org.apache.cocoon.xml.XMLUtils; 23 24 import org.apache.commons.lang.StringUtils; 25 import org.xml.sax.Attributes ; 26 import org.xml.sax.ContentHandler ; 27 import org.xml.sax.SAXException ; 28 import org.xml.sax.ext.LexicalHandler ; 29 30 import java.util.LinkedList ; 31 32 38 public class XSPExpressionFilter extends LogicsheetFilter 39 implements XSPExpressionParser.Handler { 40 41 public static class XMLPipeAdapter extends AbstractXMLPipe { 42 private XSPExpressionFilter expressionFilter; 43 private AbstractXMLPipe additionalFilter; 44 45 public XMLPipeAdapter(XSPExpressionFilter expressionFilter, AbstractXMLPipe additionalFilter) { 46 this.additionalFilter = additionalFilter; 47 this.expressionFilter = expressionFilter; 48 super.setLexicalHandler(additionalFilter); 49 super.setContentHandler(expressionFilter); 50 expressionFilter.setContentHandler(additionalFilter); 51 } 52 53 public void setConsumer(XMLConsumer consumer) { 54 additionalFilter.setConsumer(consumer); 55 } 56 57 public void setContentHandler(ContentHandler handler) { 58 additionalFilter.setContentHandler(handler); 59 } 60 61 public void setLexicalHandler(LexicalHandler handler) { 62 additionalFilter.setLexicalHandler(handler); 63 } 64 } 65 66 67 68 private String markupURI; 69 70 71 private String markupPrefix; 72 73 74 private LinkedList interpolationStack = new LinkedList (); 75 76 77 private InterpolationSettings defaultInterpolationSettings; 78 79 80 private XSPExpressionParser expressionParser = new XSPExpressionParser(this); 81 82 83 84 public XSPExpressionFilter(XSPMarkupLanguage markup) { 85 this.markupURI = markup.getURI(); 86 this.markupPrefix = markup.getPrefix(); 87 88 defaultInterpolationSettings 90 = new InterpolationSettings(markup.hasAttrInterpolation(), 91 markup.hasTextInterpolation()); 92 } 93 94 97 public void startDocument() throws SAXException { 98 interpolationStack.clear(); 99 interpolationStack.addLast(defaultInterpolationSettings); 100 super.startDocument(); 101 } 102 103 110 public void startElement(String namespaceURI, String localName, String qName, Attributes attribs) 111 throws SAXException { 112 expressionParser.flush(); 113 114 attribs = pushInterpolationStack(attribs); 116 117 if (getInterpolationSettings().attrInterpolation) { 118 AttributesImpl staticAttribs = new AttributesImpl(); 120 AttributesImpl dynamicAttribs = new AttributesImpl(); 121 122 for (int i = 0; i < attribs.getLength(); ++i) { 124 String value = attribs.getValue(i); 125 126 if (value.indexOf("{#") != -1) { 127 dynamicAttribs.addAttribute(attribs.getURI(i), attribs.getLocalName(i), attribs.getQName(i), 129 attribs.getType(i), value); 130 } 131 else { 132 staticAttribs.addAttribute(attribs.getURI(i), attribs.getLocalName(i), attribs.getQName(i), 134 attribs.getType(i), value); 135 } 136 } 137 138 super.startElement(namespaceURI, localName, qName, staticAttribs); 140 141 for (int i = 0; i < dynamicAttribs.getLength(); ++i) { 143 AttributesImpl elemAttribs = new AttributesImpl(); 144 addAttribute(elemAttribs, "uri", dynamicAttribs.getURI(i)); 145 146 String qname = dynamicAttribs.getQName(i); 147 148 if (qname != null) { 149 addAttribute(elemAttribs, "prefix", StringUtils.left(qname, qname.indexOf(':'))); 150 } 151 152 addAttribute(elemAttribs, "name", dynamicAttribs.getLocalName(i)); 153 154 super.startElement(markupURI, "attribute", markupPrefix + ":attribute", elemAttribs); 155 expressionParser.consume(dynamicAttribs.getValue(i)); 156 expressionParser.flush(); 157 super.endElement(markupURI, "attribute", markupPrefix + ":attribute"); 158 } 159 } else { 160 super.startElement(namespaceURI, localName, qName, attribs); 162 } 163 } 164 165 170 private Attributes pushInterpolationStack(Attributes attribs) { 171 String valueAttr = attribs.getValue(markupURI, XSPMarkupLanguage.ATTR_INTERPOLATION); 172 String valueText = attribs.getValue(markupURI, XSPMarkupLanguage.TEXT_INTERPOLATION); 173 174 if (valueAttr == null && valueText == null ) { 176 interpolationStack.addLast(interpolationStack.getLast()); 177 return attribs; 178 } 179 180 182 InterpolationSettings lastSettings = (InterpolationSettings)interpolationStack.getLast(); 183 boolean attrInterpolation = lastSettings.attrInterpolation; 184 boolean textInterpolation = lastSettings.textInterpolation; 185 186 AttributesImpl cleanedAttribs = new AttributesImpl(attribs); 187 188 if (valueAttr != null) { 189 attrInterpolation = Boolean.valueOf(valueAttr).booleanValue(); 190 cleanedAttribs.removeAttribute(cleanedAttribs.getIndex(markupURI, XSPMarkupLanguage.ATTR_INTERPOLATION)); 191 } 192 193 if (valueText != null) { 194 textInterpolation = Boolean.valueOf(valueText).booleanValue(); 195 cleanedAttribs.removeAttribute(cleanedAttribs.getIndex(markupURI, XSPMarkupLanguage.TEXT_INTERPOLATION)); 196 } 197 198 interpolationStack.addLast(new InterpolationSettings(attrInterpolation, 199 textInterpolation)); 200 201 return cleanedAttribs; 202 } 203 204 207 public void endElement(String uri, String loc, String raw) throws SAXException { 208 expressionParser.flush(); 209 super.endElement(uri, loc, raw); 210 211 interpolationStack.removeLast(); 213 } 214 215 221 public void characters(char[] ch, int start, int length) throws SAXException { 222 if (getInterpolationSettings().textInterpolation) { 223 expressionParser.consume(ch, start, length); 225 } 226 else { 227 super.characters(ch, start, length); 229 } 230 } 231 232 238 public void handleText(char[] chars, int start, int length) throws SAXException { 239 super.characters(chars, start, length); 240 } 241 242 248 public void handleExpression(char[] chars, int start, int length) throws SAXException { 249 super.startElement(markupURI, "expr", markupPrefix + ":expr", XMLUtils.EMPTY_ATTRIBUTES); 250 super.characters(chars, start, length); 251 super.endElement(markupURI, "expr", markupPrefix + ":expr"); 252 } 253 254 261 protected void addAttribute(AttributesImpl attribs, String name, String value) { 262 if (value != null && value.length() > 0) { 263 attribs.addCDATAAttribute(name, value); 264 } 265 } 266 267 270 private InterpolationSettings getInterpolationSettings() { 271 return (InterpolationSettings)interpolationStack.getLast(); 272 } 273 274 277 private static class InterpolationSettings { 278 boolean attrInterpolation; 279 boolean textInterpolation; 280 281 InterpolationSettings(boolean attrInterpolation, boolean textInterpolation) { 282 this.attrInterpolation = attrInterpolation; 283 this.textInterpolation = textInterpolation; 284 } 285 } 286 } 287 | Popular Tags |