blob: 73f49566056bd2671da5049f56218ccdd1009ff6 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cocoon.transformation.helpers;
import java.util.ArrayList;
import java.util.Map;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;
/**
* Consume elements start/end and characters events and reproduce them.
*
* WARNING: THIS CLASS DOES NOT WORK PROPERLY WITH NAMESPACES
*
* @deprecated The only user of this class (I18nTransformer) now uses ParamSaxBuffer
* @author <a href="mailto:mattam@netcourrier.com">Matthieu Sozeau</a>
* @version CVS $Id$
*/
public class MirrorRecorder
extends NOPRecorder
implements EventRecorder, Cloneable {
private ArrayList events;
// Used for indexing (parameters)
static class NullEvent implements EventRecorder {
private String s;
public NullEvent(String s) {
this.s = s;
}
public String name() {
return s;
}
public void send(ContentHandler handler)
throws SAXException {
}
public Object clone() {
return new NullEvent(s);
}
public String toString() {
return "{" + s + "}";
}
}
static class StartEvent implements EventRecorder {
private String uri, name, raw;
private Attributes attr;
public StartEvent(String namespace, String name, String raw,
Attributes attr) {
this.uri = namespace;
this.name = name;
this.raw = raw;
this.attr = new AttributesImpl(attr);
}
public void send(ContentHandler handler)
throws SAXException {
handler.startElement(uri, name, raw, attr);
}
public Object clone() {
return new StartEvent(uri, name, raw, attr);
}
public String toString() {
StringBuffer str = new StringBuffer("<" + raw);
if (attr != null) {
for(int i = 0; i < attr.getLength(); ++i) {
str.append(" " + attr.getQName(i) + "=\"" + attr.getValue(i) + "\"");
}
}
return str.append(">").toString();
}
}
static class EndEvent implements EventRecorder {
private String uri, name, raw;
public EndEvent(String namespace, String name, String raw) {
this.uri = namespace;
this.name = name;
this.raw = raw;
}
public Object clone() {
return new EndEvent(uri, name, raw);
}
public void send(ContentHandler handler)
throws SAXException {
handler.endElement(uri, name, raw);
}
public String toString() {
return "</" + raw + ">";
}
}
static class CharacterEvent implements EventRecorder {
private String ch;
public CharacterEvent(char ary[], int start, int length) {
ch = new String(ary, start, length);
}
public CharacterEvent(String ch) {
this.ch = ch;
}
public Object clone() {
return new CharacterEvent(ch);
}
public void send(ContentHandler handler)
throws SAXException {
handler.characters(ch.toCharArray(), 0, ch.length());
}
public String toString() {
return ch;
}
}
public MirrorRecorder() {
this.events = new ArrayList();
}
public MirrorRecorder(Node n) {
this.events = new ArrayList();
if(n != null) {
NodeList childs = n.getChildNodes();
for(int i = 0; i < childs.getLength(); ++i) {
try {
nodeToEvents(childs.item(i));
} catch (SAXException e) {
// FIXME: what to do?
}
}
}
}
private void nodeToEvents(Node n) throws SAXException {
switch(n.getNodeType()) {
case Node.ELEMENT_NODE:
Attributes attrs;
if(n.getAttributes() instanceof Attributes) {
attrs = (Attributes) n.getAttributes();
} else {
NamedNodeMap map = n.getAttributes();
attrs = new AttributesImpl();
for(int i = 0; i < map.getLength(); ++i) {
Node node = map.item(i);
final String ns = node.getNamespaceURI() == null? "" : node.getNamespaceURI();
final String ln = node.getLocalName() == null? node.getNodeName() : node.getLocalName();
((AttributesImpl) attrs).addAttribute(ns,
ln,
node.getNodeName(),
"CDATA",
node.getNodeValue());
}
}
final String ns = n.getNamespaceURI() == null? "" : n.getNamespaceURI();
final String ln = n.getLocalName() == null? n.getNodeName() : n.getLocalName();
startElement(ns, ln, n.getNodeName(), attrs);
if (n.hasChildNodes()) {
NodeList childs = n.getChildNodes();
for(int i = 0; i < childs.getLength(); ++i) {
nodeToEvents(childs.item(i));
}
}
endElement(ns, ln, n.getNodeName());
break;
case Node.CDATA_SECTION_NODE:
case Node.TEXT_NODE:
characters(n.getNodeValue());
break;
}
}
public MirrorRecorder(MirrorRecorder n) {
this.events = new ArrayList();
for(int i = 0; i < n.events.size(); ++i) {
EventRecorder e = (EventRecorder) n.events.get(i);
this.events.add(e.clone());
}
}
public Object clone() {
return new MirrorRecorder(this);
}
public void startElement(String namespace, String name, String raw,
Attributes attr)
throws SAXException {
events.add(new StartEvent(namespace, name, raw, attr));
}
public void endElement(String namespace, String name, String raw)
throws SAXException {
events.add(new EndEvent(namespace, name, raw));
}
public void characters(char ary[], int start, int length)
throws SAXException {
characters(new String(ary, start, length));
}
public void characters(String tmp) throws SAXException {
int i = 0, j = 0;
while(tmp.length() > 0) {
i = tmp.indexOf('{', i);
if(i == -1) {
events.add(new CharacterEvent(tmp));
return;
} else {
if(i >= 0) {
events.add(new CharacterEvent(tmp.substring(0, i)));
}
j = tmp.indexOf('}', i);
if(j != -1) {
events.add(new NullEvent(tmp.substring(i + 1, j)));
tmp = tmp.substring(j + 1, tmp.length());
i = 0;
}
}
}
}
public void send(ContentHandler handler) throws SAXException {
for(int i = 0; i < events.size(); ++i) {
((EventRecorder) (events.get(i))).send(handler);
}
}
public void send(ContentHandler handler, Map params) throws SAXException
{
EventRecorder param;
for(int i = 0; i < events.size(); ++i) {
if(events.get(i) instanceof NullEvent) {
param = (EventRecorder) params.get(((NullEvent) events.get(i)).name());
if(param != null)
param.send(handler);
} else {
((EventRecorder) (events.get(i))).send(handler);
}
}
}
public String text() {
StringBuffer s = new StringBuffer();
for(int i = 0; i < events.size(); ++i) {
s.append(events.get(i).toString());
}
return(s.toString());
}
public String toString() {
StringBuffer s = new StringBuffer("MirrorRecorder: ");
s.append(String.valueOf(events.size()) + " event(s)");
s.append("\ntext: ");
for(int i = 0; i < events.size(); ++i) {
if(events.get(i) instanceof CharacterEvent) {
s.append(events.get(i).toString());
}
}
return s.toString();
}
public void recycle() {
events.clear();
}
public boolean empty() {
return events.size() == 0;
}
}