1 16 package org.apache.cocoon.woody.transformation; 17 18 import java.util.LinkedList ; 19 20 import org.apache.cocoon.woody.Constants; 21 import org.apache.cocoon.xml.AbstractXMLPipe; 22 import org.apache.cocoon.xml.SaxBuffer; 23 import org.apache.cocoon.xml.XMLConsumer; 24 import org.xml.sax.Attributes ; 25 import org.xml.sax.ContentHandler ; 26 import org.xml.sax.Locator ; 27 import org.xml.sax.SAXException ; 28 import org.xml.sax.ext.LexicalHandler ; 29 import org.xml.sax.helpers.AttributesImpl ; 30 31 40 public class EffectPipe extends AbstractXMLPipe { 41 42 protected static final int EVENT_SET_DOCUMENT_LOCATOR = 0; 43 protected static final int EVENT_START_DOCUMENT = 1; 44 protected static final int EVENT_END_DOCUMENT = 2; 45 protected static final int EVENT_START_PREFIX_MAPPING = 3; 46 protected static final int EVENT_END_PREFIX_MAPPING = 4; 47 protected static final int EVENT_START_ELEMENT = 5; 48 protected static final int EVENT_END_ELEMENT = 6; 49 protected static final int EVENT_ELEMENT = 7; 50 protected static final int EVENT_CHARACTERS = 8; 51 protected static final int EVENT_IGNORABLE_WHITESPACE = 9; 52 protected static final int EVENT_PROCESSING_INSTRUCTION =10; 53 protected static final int EVENT_SKIPPED_ENTITY =11; 54 protected static final int EVENT_START_DTD =12; 55 protected static final int EVENT_END_DTD =13; 56 protected static final int EVENT_START_ENTITY =14; 57 protected static final int EVENT_END_ENTITY =15; 58 protected static final int EVENT_START_CDATA =16; 59 protected static final int EVENT_END_CDATA =17; 60 protected static final int EVENT_COMMENT =18; 61 62 protected class Element { 63 public String prefix; 64 public String uri; 65 public String loc; 66 public String raw; 67 public Attributes attrs; 68 public boolean mine; 69 70 public Element() { 71 prefix = null; uri = null; loc = null; raw = null; attrs = Constants.EMPTY_ATTRS; mine = true; 72 } 73 74 public Element(String prefix, String uri) { 75 this.prefix = prefix; 76 this.uri = uri; 77 } 78 79 public Element(String uri, String loc, String raw, Attributes attrs) { 80 this.uri = uri; 81 this.loc = loc; 82 this.raw = raw; 83 this.attrs = Constants.EMPTY_ATTRS; 84 if (attrs == null) { 85 this.attrs = Constants.EMPTY_ATTRS; 86 mine = true; 87 } else { 88 this.attrs = attrs; 89 mine = false; 90 } 91 } 92 93 public void addAttributes(Attributes attrs) { 94 if (attrs != null) { 95 if (mine == true) { 96 if (this.attrs == Constants.EMPTY_ATTRS) { 97 this.attrs = attrs; 98 mine = false; 99 } else { 100 ((AttributesImpl )this.attrs).setAttributes(attrs); 101 } 102 } else { 103 this.attrs = new AttributesImpl (this.attrs); 104 ((AttributesImpl )this.attrs).setAttributes(attrs); 105 mine = true; 106 } 107 } 108 } 109 110 public void addAttribute(String uri, String loc, String raw, String type, String value) { 111 if (!mine || attrs == Constants.EMPTY_ATTRS) { 112 attrs = new AttributesImpl (attrs); 113 mine = true; 114 } 115 ((AttributesImpl )attrs).addAttribute(uri, loc, raw, type, value); 116 } 117 118 public void addAttribute(String prefix, String uri, String loc, String value) { 119 if (!mine || attrs == Constants.EMPTY_ATTRS) { 120 attrs = new AttributesImpl (attrs); 121 mine = true; 122 } 123 ((AttributesImpl )attrs).addAttribute(uri, loc, prefix + ":" +loc, "CDATA", value); 124 } 125 126 public void addAttribute(String loc, String value) { 127 if (!mine || attrs == Constants.EMPTY_ATTRS) { 128 attrs = new AttributesImpl (attrs); 129 mine = true; 130 } 131 ((AttributesImpl )attrs).addAttribute("", loc, loc, "CDATA", value); 132 } 133 134 public void claimAttributes() { 135 if (!mine) { 136 attrs = new AttributesImpl (attrs); 137 mine = true; 138 } 139 } 140 } 141 142 protected abstract class Handler { 143 public abstract Handler process() throws SAXException ; 144 } 145 146 protected class NullHandler extends Handler { 147 public Handler process() throws SAXException { 148 return this; 149 } 150 } 151 152 protected class BufferHandler extends Handler { 153 public Handler process() throws SAXException { 154 switch (event) { 155 case EVENT_ELEMENT: 156 return this; 157 default: 158 out.buffer(); 159 return this; 160 } 161 } 162 } 163 164 protected class Output extends AbstractXMLPipe { 165 private LinkedList buffers = null; 166 private SaxBuffer saxBuffer = null; 167 private LinkedList elements = null; 168 protected Element element = null; 169 170 public Output() { elements = new LinkedList (); } 171 172 public void startPrefixMapping() throws SAXException { 173 super.startPrefixMapping(input.prefix, input.uri); 174 } 175 176 public void endPrefixMapping() throws SAXException { 177 super.endPrefixMapping(input.prefix); 178 } 179 180 public void element(String prefix, String uri, String loc, Attributes attrs) throws SAXException { 181 element = new Element(uri, loc, prefix + ":" + loc, attrs); 182 } 183 184 public void element(String prefix, String uri, String loc) throws SAXException { 185 element(prefix, uri, loc, null); 186 } 187 188 public void element(String loc, Attributes attrs) throws SAXException { 189 element = new Element("", loc, loc, attrs); 190 } 191 192 public void element(String loc) throws SAXException { 193 element(loc, null); 194 } 195 196 public void element() throws SAXException { 197 element = new Element(input.uri, input.loc, input.raw, input.attrs); 198 } 199 200 public void attribute(String prefix, String uri, String name, String value) throws SAXException { 201 element.addAttribute(prefix, uri, name, value); 202 } 203 204 public void attribute(String name, String value) throws SAXException { 205 element.addAttribute(name, value); 206 } 207 208 public void copyAttribute(String prefix, String uri, String name) throws SAXException { 209 String value = null; 210 if (input.attrs != null && (value = input.attrs.getValue(uri, name)) != null) { 211 attribute(prefix, uri, name, value); 212 } else { 213 throw new SAXException ("Attribute \"" + name + "\" cannot be copied because it does not exist."); 214 } 215 } 216 217 public void attributes(Attributes attrs) throws SAXException { 218 element.addAttributes(attrs); 219 } 220 221 public void attributes() throws SAXException { 222 attributes(input.attrs); 223 } 224 225 public void startElement() throws SAXException { 226 if (element.attrs == null) { 227 element.attrs = Constants.EMPTY_ATTRS; 228 } 229 super.startElement(element.uri, element.loc, element.raw, element.attrs); 230 elements.addFirst(element); 231 element = null; 232 } 233 234 public void endElement() throws SAXException { 235 element = (Element)elements.removeFirst(); 236 super.endElement(element.uri, element.loc, element.raw); 237 element = null; 238 } 239 240 public void startElement(String uri, String loc, String raw, Attributes attrs) throws SAXException { 241 super.startElement(uri, loc, raw, attrs); 242 } 243 244 public void endElement(String uri, String loc, String raw) throws SAXException { 245 super.endElement(uri, loc, raw); 246 } 247 248 public void copy() throws SAXException { 249 switch(event) { 250 case EVENT_SET_DOCUMENT_LOCATOR: this.setDocumentLocator(locator); break; 251 case EVENT_START_DOCUMENT: this.startDocument(); break; 252 case EVENT_END_DOCUMENT: this.endDocument(); break; 253 case EVENT_START_PREFIX_MAPPING: this.startPrefixMapping(); break; 254 case EVENT_END_PREFIX_MAPPING: this.endPrefixMapping(); break; 255 case EVENT_START_ELEMENT: this.element(); attributes(); startElement(); break; 256 case EVENT_END_ELEMENT: this.endElement(); break; 257 case EVENT_CHARACTERS: this.characters(c, start, len); break; 258 case EVENT_IGNORABLE_WHITESPACE: this.ignorableWhitespace(c, start, len); break; 259 case EVENT_PROCESSING_INSTRUCTION: this.processingInstruction(target, data); break; 260 case EVENT_SKIPPED_ENTITY: this.skippedEntity(name); break; 261 case EVENT_START_DTD: this.startDTD(name, publicId, systemId); break; 262 case EVENT_END_DTD: this.endDTD(); break; 263 case EVENT_START_ENTITY: this.startEntity(name); break; 264 case EVENT_END_ENTITY: this.endEntity(name); break; 265 case EVENT_START_CDATA: this.startCDATA(); break; 266 case EVENT_END_CDATA: this.endCDATA(); break; 267 case EVENT_COMMENT: this.comment(c, start, len); break; 268 } 269 } 270 271 protected void bufferInit() { 272 if (saxBuffer != null) { 273 if (buffers == null) { 274 buffers = new LinkedList (); 275 } 276 buffers.addFirst(saxBuffer); 277 } 278 saxBuffer = new SaxBuffer(); 279 } 280 281 protected void bufferFini() { 282 if (buffers != null && buffers.size() > 0) { 283 saxBuffer = (SaxBuffer)buffers.removeFirst(); 284 } else { 285 saxBuffer = null; 286 } 287 } 288 289 protected SaxBuffer getBuffer() { 290 return saxBuffer; 291 } 292 293 public void buffer() throws SAXException { 294 switch(event) { 295 case EVENT_SET_DOCUMENT_LOCATOR: saxBuffer.setDocumentLocator(locator); break; 296 case EVENT_START_DOCUMENT: saxBuffer.startDocument(); break; 297 case EVENT_END_DOCUMENT: saxBuffer.endDocument(); break; 298 case EVENT_START_PREFIX_MAPPING: saxBuffer.startPrefixMapping(prefix, uri); break; 299 case EVENT_END_PREFIX_MAPPING: saxBuffer.endPrefixMapping(prefix); break; 300 case EVENT_START_ELEMENT: saxBuffer.startElement(input.uri, input.loc, input.raw, input.attrs); break; 301 case EVENT_END_ELEMENT: saxBuffer.endElement(input.uri, input.loc, input.raw); break; 302 case EVENT_CHARACTERS: saxBuffer.characters(c, start, len); break; 303 case EVENT_IGNORABLE_WHITESPACE: saxBuffer.ignorableWhitespace(c, start, len); break; 304 case EVENT_PROCESSING_INSTRUCTION: saxBuffer.processingInstruction(target, data); break; 305 case EVENT_SKIPPED_ENTITY: saxBuffer.skippedEntity(name); break; 306 case EVENT_START_DTD: saxBuffer.startDTD(name, publicId, systemId); break; 307 case EVENT_END_DTD: saxBuffer.endDTD(); break; 308 case EVENT_START_ENTITY: saxBuffer.startEntity(name); break; 309 case EVENT_END_ENTITY: saxBuffer.endEntity(name); break; 310 case EVENT_START_CDATA: saxBuffer.startCDATA(); break; 311 case EVENT_END_CDATA: saxBuffer.endCDATA(); break; 312 case EVENT_COMMENT: saxBuffer.comment(c, start, len); break; 313 } 314 } 315 } 316 317 318 protected int event = 0; 319 320 protected Handler nullHandler = new NullHandler(); 321 protected Handler bufferHandler = new BufferHandler(); 322 323 protected LinkedList handlers = null; 324 protected Handler handler = null; 325 326 protected LinkedList elements = null; 327 protected Element input = null; 328 329 protected Locator locator = null; 330 protected String name = null; 331 protected String publicId = null; 332 protected String systemId = null; 333 protected String target = null; 334 protected String data = null; 335 protected String prefix = null; 336 protected String uri = null; 337 protected char c[] = null; 338 protected int start = 0; 339 protected int len = 0; 340 341 public Output out = null; 342 343 public void init() { 344 handlers = new LinkedList (); 345 elements = new LinkedList (); 346 out = new Output(); 347 } 348 349 353 public void setConsumer(XMLConsumer consumer) { 354 super.setConsumer(consumer); 355 out.setConsumer(consumer); 356 } 357 358 public void setContentHandler(ContentHandler handler) { 359 super.setContentHandler(handler); 360 out.setContentHandler(handler); 361 } 362 363 public void setLexicalHandler(LexicalHandler handler) { 364 super.setLexicalHandler(handler); 365 out.setLexicalHandler(handler); 366 } 367 368 public void recycle() { 369 super.recycle(); 370 handlers = null; 371 elements = null; 372 out = null; 373 } 374 375 public void setDocumentLocator(Locator locator) { 376 this.locator = locator; 377 try { 378 event = EVENT_SET_DOCUMENT_LOCATOR; handler = handler.process(); 379 } catch(Exception e) { 380 throw new RuntimeException (e.getMessage()); 381 } 382 } 383 384 public void startDocument() throws SAXException { event = EVENT_START_DOCUMENT; handler = handler.process(); } 385 386 public void endDocument() throws SAXException { event = EVENT_END_DOCUMENT; handler = handler.process(); } 387 388 public void startPrefixMapping(String prefix, String uri) throws SAXException { 389 input = new Element(prefix, uri); 390 elements.addFirst(input); 391 event = EVENT_START_PREFIX_MAPPING; handler = handler.process(); 393 } 394 395 public void endPrefixMapping(String prefix) throws SAXException { 396 input = (Element)elements.removeFirst(); 397 event = EVENT_END_PREFIX_MAPPING; handler = handler.process(); 399 input = null; 400 } 401 402 public void startElement(String uri, String loc, String raw, Attributes attrs) throws SAXException { 403 input = new Element(uri, loc, raw, attrs); 404 elements.addFirst(input); 405 handlers.addFirst(handler); 406 event = EVENT_ELEMENT; handler = handler.process(); 407 event = EVENT_START_ELEMENT; handler = handler.process(); 408 } 409 410 public void endElement(String uri, String loc, String raw) throws SAXException { 411 input = (Element)elements.removeFirst(); 412 event = EVENT_END_ELEMENT; handler.process(); 413 handler = (Handler )handlers.removeFirst(); 414 input = null; 415 } 416 417 public void characters(char c[], int start, int len) throws SAXException { 418 this.c = c; this.start = start; this.len = len; 419 event = EVENT_CHARACTERS; handler = handler.process(); 420 } 421 422 public void ignorableWhitespace(char c[], int start, int len) throws SAXException { 423 this.c = c; this.start = start; this.len = len; 424 event = EVENT_IGNORABLE_WHITESPACE; handler = handler.process(); 425 } 426 427 public void processingInstruction(String target, String data) throws SAXException { 428 this.target = target; this.data = data; 429 event = EVENT_PROCESSING_INSTRUCTION; handler = handler.process(); 430 } 431 432 public void skippedEntity(String name) throws SAXException { 433 this.name = name; 434 event = EVENT_SKIPPED_ENTITY; handler = handler.process(); 435 } 436 437 public void startDTD(String name, String publicId, String systemId) throws SAXException { 438 this.name = name; this.publicId = publicId; this.systemId = systemId; 439 event = EVENT_START_DTD; handler = handler.process(); 440 } 441 442 public void endDTD() throws SAXException { event = EVENT_END_DTD; handler = handler.process(); } 443 444 public void startEntity(String name) throws SAXException { 445 this.name = name; 446 event = EVENT_START_ENTITY; handler = handler.process(); 447 } 448 449 public void endEntity(String name) throws SAXException { 450 this.name = name; 451 event = EVENT_END_ENTITY; handler = handler.process(); 452 } 453 454 public void startCDATA() throws SAXException { 455 event = EVENT_START_CDATA; handler = handler.process(); 456 } 457 458 public void endCDATA() throws SAXException { 459 event = EVENT_END_CDATA; handler = handler.process(); 460 } 461 462 public void comment(char c[], int start, int len) throws SAXException { 463 this.c = c; this.start = start; this.len = len; 464 event = EVENT_COMMENT; handler = handler.process(); 465 } 466 } 467 | Popular Tags |