1 16 package org.apache.cocoon.transformation.helpers; 17 18 import java.util.ArrayList ; 19 import java.util.Map ; 20 21 import org.w3c.dom.NamedNodeMap ; 22 import org.w3c.dom.Node ; 23 import org.w3c.dom.NodeList ; 24 25 import org.xml.sax.Attributes ; 26 import org.xml.sax.ContentHandler ; 27 import org.xml.sax.SAXException ; 28 import org.xml.sax.helpers.AttributesImpl ; 29 30 39 public class MirrorRecorder 40 extends NOPRecorder 41 implements EventRecorder, Cloneable { 42 43 private ArrayList events; 44 45 static class NullEvent implements EventRecorder { 47 private String s; 48 49 public NullEvent(String s) { 50 this.s = s; 51 } 52 53 public String name() { 54 return s; 55 } 56 57 public void send(ContentHandler handler) 58 throws SAXException { 59 } 60 61 public Object clone() { 62 return new NullEvent(s); 63 } 64 65 public String toString() { 66 return "{" + s + "}"; 67 } 68 } 69 70 static class StartEvent implements EventRecorder { 71 private String uri, name, raw; 72 private Attributes attr; 73 74 public StartEvent(String namespace, String name, String raw, 75 Attributes attr) { 76 this.uri = namespace; 77 this.name = name; 78 this.raw = raw; 79 this.attr = new AttributesImpl (attr); 80 } 81 82 public void send(ContentHandler handler) 83 throws SAXException { 84 handler.startElement(uri, name, raw, attr); 85 } 86 87 public Object clone() { 88 return new StartEvent(uri, name, raw, attr); 89 } 90 91 public String toString() { 92 StringBuffer str = new StringBuffer ("<" + raw); 93 if (attr != null) { 94 for(int i = 0; i < attr.getLength(); ++i) { 95 str.append(" " + attr.getQName(i) + "=\"" + attr.getValue(i) + "\""); 96 } 97 } 98 99 return str.append(">").toString(); 100 } 101 } 102 103 static class EndEvent implements EventRecorder { 104 private String uri, name, raw; 105 106 public EndEvent(String namespace, String name, String raw) { 107 this.uri = namespace; 108 this.name = name; 109 this.raw = raw; 110 } 111 112 public Object clone() { 113 return new EndEvent(uri, name, raw); 114 } 115 116 public void send(ContentHandler handler) 117 throws SAXException { 118 handler.endElement(uri, name, raw); 119 } 120 121 public String toString() { 122 return "</" + raw + ">"; 123 } 124 } 125 126 static class CharacterEvent implements EventRecorder { 127 private String ch; 128 129 public CharacterEvent(char ary[], int start, int length) { 130 ch = new String (ary, start, length); 131 } 132 133 public CharacterEvent(String ch) { 134 this.ch = ch; 135 } 136 137 public Object clone() { 138 return new CharacterEvent(ch); 139 } 140 141 public void send(ContentHandler handler) 142 throws SAXException { 143 handler.characters(ch.toCharArray(), 0, ch.length()); 144 } 145 146 public String toString() { 147 return ch; 148 } 149 } 150 151 152 public MirrorRecorder() { 153 this.events = new ArrayList (); 154 } 155 156 public MirrorRecorder(Node n) { 157 this.events = new ArrayList (); 158 159 if(n != null) { 160 NodeList childs = n.getChildNodes(); 161 for(int i = 0; i < childs.getLength(); ++i) { 162 try { 163 nodeToEvents(childs.item(i)); 164 } catch (SAXException e) { 165 } 167 } 168 } 169 } 170 171 private void nodeToEvents(Node n) throws SAXException { 172 switch(n.getNodeType()) { 173 case Node.ELEMENT_NODE: 174 Attributes attrs; 175 if(n.getAttributes() instanceof Attributes ) { 176 attrs = (Attributes ) n.getAttributes(); 177 } else { 178 NamedNodeMap map = n.getAttributes(); 179 attrs = new AttributesImpl (); 180 181 for(int i = 0; i < map.getLength(); ++i) { 182 Node node = map.item(i); 183 final String ns = node.getNamespaceURI() == null? "" : node.getNamespaceURI(); 184 final String ln = node.getLocalName() == null? node.getNodeName() : node.getLocalName(); 185 ((AttributesImpl ) attrs).addAttribute(ns, 186 ln, 187 node.getNodeName(), 188 "CDATA", 189 node.getNodeValue()); 190 } 191 } 192 193 final String ns = n.getNamespaceURI() == null? "" : n.getNamespaceURI(); 194 final String ln = n.getLocalName() == null? n.getNodeName() : n.getLocalName(); 195 startElement(ns, ln, n.getNodeName(), attrs); 196 if (n.hasChildNodes()) { 197 NodeList childs = n.getChildNodes(); 198 for(int i = 0; i < childs.getLength(); ++i) { 199 nodeToEvents(childs.item(i)); 200 } 201 } 202 203 endElement(ns, ln, n.getNodeName()); 204 break; 205 case Node.CDATA_SECTION_NODE: 206 case Node.TEXT_NODE: 207 characters(n.getNodeValue()); 208 break; 209 } 210 } 211 212 public MirrorRecorder(MirrorRecorder n) { 213 this.events = new ArrayList (); 214 for(int i = 0; i < n.events.size(); ++i) { 215 EventRecorder e = (EventRecorder) n.events.get(i); 216 this.events.add(e.clone()); 217 } 218 } 219 220 public Object clone() { 221 return new MirrorRecorder(this); 222 } 223 224 public void startElement(String namespace, String name, String raw, 225 Attributes attr) 226 throws SAXException { 227 events.add(new StartEvent(namespace, name, raw, attr)); 228 } 229 230 public void endElement(String namespace, String name, String raw) 231 throws SAXException { 232 events.add(new EndEvent(namespace, name, raw)); 233 } 234 235 public void characters(char ary[], int start, int length) 236 throws SAXException { 237 characters(new String (ary, start, length)); 238 } 239 240 public void characters(String tmp) throws SAXException { 241 int i = 0, j = 0; 242 243 while(tmp.length() > 0) { 244 i = tmp.indexOf('{', i); 245 if(i == -1) { 246 events.add(new CharacterEvent(tmp)); 247 return; 248 } else { 249 if(i >= 0) { 250 events.add(new CharacterEvent(tmp.substring(0, i))); 251 } 252 253 j = tmp.indexOf('}', i); 254 if(j != -1) { 255 events.add(new NullEvent(tmp.substring(i + 1, j))); 256 tmp = tmp.substring(j + 1, tmp.length()); 257 i = 0; 258 } 259 } 260 } 261 } 262 263 public void send(ContentHandler handler) throws SAXException { 264 for(int i = 0; i < events.size(); ++i) { 265 ((EventRecorder) (events.get(i))).send(handler); 266 } 267 } 268 269 public void send(ContentHandler handler, Map params) throws SAXException 270 { 271 EventRecorder param; 272 273 for(int i = 0; i < events.size(); ++i) { 274 if(events.get(i) instanceof NullEvent) { 275 param = (EventRecorder) params.get(((NullEvent) events.get(i)).name()); 276 if(param != null) 277 param.send(handler); 278 } else { 279 ((EventRecorder) (events.get(i))).send(handler); 280 } 281 } 282 } 283 284 public String text() { 285 StringBuffer s = new StringBuffer (); 286 287 for(int i = 0; i < events.size(); ++i) { 288 s.append(events.get(i).toString()); 289 } 290 return(s.toString()); 291 } 292 293 public String toString() { 294 StringBuffer s = new StringBuffer ("MirrorRecorder: "); 295 s.append(String.valueOf(events.size()) + " event(s)"); 296 s.append("\ntext: "); 297 for(int i = 0; i < events.size(); ++i) { 298 if(events.get(i) instanceof CharacterEvent) { 299 s.append(events.get(i).toString()); 300 } 301 } 302 303 return s.toString(); 304 } 305 306 public void recycle() { 307 events.clear(); 308 } 309 310 public boolean empty() { 311 return events.size() == 0; 312 } 313 } 314 | Popular Tags |