1 16 package org.apache.cocoon.components.xpointer; 17 18 import org.xml.sax.SAXException ; 19 import org.xml.sax.Attributes ; 20 import org.xml.sax.Locator ; 21 import org.apache.cocoon.xml.AbstractXMLPipe; 22 import org.apache.cocoon.components.source.SourceUtil; 23 import org.apache.cocoon.ProcessingException; 24 25 import java.util.StringTokenizer ; 26 import java.util.ArrayList ; 27 import java.io.IOException ; 28 29 42 public class ElementPathPart implements PointerPart { 43 private String expression; 44 45 public ElementPathPart(String expression) { 46 this.expression = expression; 47 } 48 49 public boolean process(XPointerContext xpointerContext) throws SAXException { 50 PathInclusionPipe pipe = new PathInclusionPipe(expression, xpointerContext); 51 pipe.setConsumer(xpointerContext.getXmlConsumer()); 52 try { 53 SourceUtil.toSAX(xpointerContext.getSource(), pipe); 54 } catch (IOException e) { 55 throw new SAXException ("Exception while trying to XInclude data: " + e.getMessage(), e); 56 } catch (ProcessingException e) { 57 throw new SAXException ("Exception while trying to XInclude data: " + e.getMessage(), e); 58 } 59 return true; 60 } 61 62 public static class PathInclusionPipe extends AbstractXMLPipe { 63 64 private QName[] elementPath; 65 66 private int level; 67 68 private boolean include; 69 70 private int includeLevel; 71 72 73 private int levelToMatch; 74 private boolean done; 75 76 public PathInclusionPipe(String expression, XPointerContext xpointerContext) throws SAXException { 77 ArrayList path = new ArrayList (); 79 StringTokenizer tokenizer = new StringTokenizer (expression, "/"); 80 while (tokenizer.hasMoreTokens()) { 81 String token = tokenizer.nextToken(); 82 try { 83 path.add(QName.parse(token, xpointerContext)); 84 } catch (SAXException e) { 85 throw new SAXException ("Error in element path xpointer expression \"" + expression + "\": " + e.getMessage()); 86 } 87 } 88 if (path.size() < 1) 89 throw new SAXException ("Invalid element path xpointer expression \"" + expression + "\"."); 90 91 this.elementPath = (QName[])path.toArray(new QName[path.size()]); 92 this.level = -1; 93 this.include = false; 94 this.levelToMatch = 0; 95 this.done = false; 96 } 97 98 public void startElement(String namespaceURI, String localName, String raw, Attributes a) 99 throws SAXException { 100 level++; 101 102 if (include) { 103 super.startElement(namespaceURI, localName, raw, a); 104 return; 105 } 106 107 if (!done && level == levelToMatch && elementPath[level].matches(namespaceURI, localName)) { 108 levelToMatch++; 109 if (levelToMatch == elementPath.length) { 110 include = true; 111 done = true; 112 includeLevel = level; 113 } 114 } 115 } 116 117 public void endElement(String uri, String loc, String raw) 118 throws SAXException { 119 if (include && level == includeLevel) 120 include = false; 121 122 if (include) 123 super.endElement(uri, loc, raw); 124 125 level--; 126 } 127 128 public void setDocumentLocator(Locator locator) { 129 if (include) 130 super.setDocumentLocator(locator); 131 } 132 133 public void startDocument() 134 throws SAXException { 135 if (include) 136 super.startDocument(); 137 } 138 139 public void endDocument() 140 throws SAXException { 141 if (include) 142 super.endDocument(); 143 } 144 145 public void startPrefixMapping(String prefix, String uri) 146 throws SAXException { 147 super.startPrefixMapping(prefix, uri); 149 } 150 151 public void endPrefixMapping(String prefix) 152 throws SAXException { 153 super.endPrefixMapping(prefix); 155 } 156 157 public void characters(char c[], int start, int len) 158 throws SAXException { 159 if (include) 160 super.characters(c, start, len); 161 } 162 163 public void ignorableWhitespace(char c[], int start, int len) 164 throws SAXException { 165 if (include) 166 super.ignorableWhitespace(c, start, len); 167 } 168 169 public void processingInstruction(String target, String data) 170 throws SAXException { 171 if (include) 172 super.processingInstruction(target, data); 173 } 174 175 public void skippedEntity(String name) 176 throws SAXException { 177 if (include) 178 super.skippedEntity(name); 179 } 180 181 public void startDTD(String name, String publicId, String systemId) 182 throws SAXException { 183 if (include) 184 super.startDTD(name, publicId, systemId); 185 } 186 187 public void endDTD() 188 throws SAXException { 189 if (include) 190 super.endDTD(); 191 } 192 193 public void startEntity(String name) 194 throws SAXException { 195 if (include) 196 super.startEntity(name); 197 } 198 199 public void endEntity(String name) 200 throws SAXException { 201 if (include) 202 super.endEntity(name); 203 } 204 205 public void startCDATA() 206 throws SAXException { 207 if (include) 208 super.startCDATA(); 209 } 210 211 public void endCDATA() 212 throws SAXException { 213 if (include) 214 super.endCDATA(); 215 } 216 217 public void comment(char ch[], int start, int len) 218 throws SAXException { 219 if (include) 220 super.comment(ch, start, len); 221 } 222 223 public static class QName { 224 private String namespaceURI; 225 private String localName; 226 227 public QName(String namespaceURI, String localName) { 228 this.namespaceURI = namespaceURI; 229 this.localName = localName; 230 } 231 232 public static QName parse(String qName, XPointerContext xpointerContext) throws SAXException { 233 int pos = qName.indexOf(':'); 234 if (pos > 0) { 235 String prefix = qName.substring(0, pos); 236 String localName = qName.substring(pos + 1); 237 String namespaceURI = xpointerContext.prefixToNamespace(prefix); 238 if (namespaceURI == null) 239 throw new SAXException ("Namespace prefix \"" + prefix + "\" not declared."); 240 return new QName(prefix, localName); 241 } 242 return new QName("", qName); 243 } 244 245 public String getNamespaceURI() { 246 return namespaceURI; 247 } 248 249 public String getLocalName() { 250 return localName; 251 } 252 253 public boolean matches(String namespaceURI, String localName) { 254 return this.localName.equals(localName) && this.namespaceURI.equals(namespaceURI); 255 } 256 } 257 } 258 } 259 | Popular Tags |