/*
* The Relaxer artifact
* Copyright (c) 2000-2004, ASAMI Tomoharu, All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package org.xmlsmartdoc.goldenport.lib;
import java.util.*;
import java.io.IOException;
import java.io.Writer;
import java.io.PrintWriter;
import java.io.Serializable;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
import org.w3c.dom.*;
/**
* RNSContext
*
* @since Jan. 14, 2001
* @version Jun. 21, 2005
* @author ASAMI, Tomoharu (asami@relaxer.org)
*/
public class RNSContext implements Serializable {
private final static String XML_NS
= "http://www.w3.org/XML/1998/namespace";
private final static String XMLNS_NS
= "http://www.w3.org/2000/xmlns/";
private IRNode rnode_;
private String namespaceUri_;
private Map prefixByUri_ = new HashMap();
private Map prefixByUriWeak_ = new HashMap();
private Map uriByPrefix_ = new HashMap();
private Map uriByPrefixWeak_ = new HashMap();
public RNSContext(IRNode rnode, String uri) {
rnode_ = rnode;
namespaceUri_ = uri;
declareNamespaceWeak("", uri);
}
// DOM input
public void declareNamespace(Element element) {
NamedNodeMap attrs = element.getAttributes();
int size = attrs.getLength();
for (int i = 0;i < size;i++) {
Attr attr = (Attr)attrs.item(i);
String qName = attr.getName();
if (qName.startsWith("xmlns:")) {
String uri = attr.getValue();
String prefix = qName.substring("xmlns:".length());
declareNamespace(prefix, uri);
if (prefix.equals(element.getPrefix())) {
_updateNamespaceUri(uri);
}
} else if (qName.startsWith("xmlns")) {
String uri = attr.getValue();
declareNamespace("", uri);
_updateNamespaceUri(uri);
}
}
}
// SAX input
public void declareNamespace(String prefix, String uri) {
prefixByUri_.put(uri, prefix);
uriByPrefix_.put(prefix, uri);
}
// SAX input
public void declareNamespaceWeak(String prefix, String uri) {
prefixByUriWeak_.put(uri, prefix);
uriByPrefixWeak_.put(prefix, uri);
}
// DOM output
public void setupNamespace(Element element) {
_setupNamespaceTagPrefix(element);
_setupNamespacePrefixDeclare(element);
}
private void _setupNamespaceTagPrefix(Element element) {
String uri = element.getNamespaceURI();
if (uri == null) {
uri = "";
}
String myPrefix = getPrefixByUri(uri);
if (myPrefix != null) {
if (!"".equals(myPrefix)) {
element.setPrefix(myPrefix);
}
IRNSContainer parent = (IRNSContainer)rnode_.rGetParentRNode();
if (parent == null) {
addPrefixDecl(element, myPrefix, uri);
return;
}
RNSContext parentContext = parent.rGetRNSContext();
String parentPrefix = parentContext.getPrefixByUri(uri);
if (!myPrefix.equals(parentPrefix)) {
addPrefixDecl(element, myPrefix, uri);
}
} else {
IRNSContainer parent = (IRNSContainer)rnode_.rGetParentRNode();
if (parent == null) {
if ("".equals(uri)) {
return;
}
addPrefixDecl(element, null, uri);
return;
}
RNSContext parentContext = parent.rGetRNSContext();
if (!uri.equals(parentContext.getNamespaceUri())) {
addPrefixDecl(element, myPrefix, uri);
return;
}
String parentPrefix = parentContext.getPrefixByUri(uri);
if (parentPrefix != null) {
addPrefixDecl(element, myPrefix, uri);
}
}
}
private void _setupNamespacePrefixDeclare(Element element) {
String uri = element.getNamespaceURI();
if (uri == null) {
uri = "";
}
Set keys = prefixByUri_.keySet();
Iterator iter = keys.iterator();
while (iter.hasNext()) {
String anotherUri = (String)iter.next();
if (!uri.equals(anotherUri)) {
String anotherPrefix = (String)prefixByUri_.get(anotherUri);
if (anotherPrefix != null) {
addPrefixDecl(element, anotherPrefix, anotherUri);
}
}
}
}
// DOM output
public void addPrefixDecl(Element element, String prefix, String uri) {
try {
_addPrefixDeclDOM2(element, prefix, uri);
} catch (DOMException e) {
_addPrefixDeclXerces(element, prefix, uri); // XXX
}
}
private void _addPrefixDeclXerces(
Element element,
String prefix,
String uri
) {
/*
if (uri == null || "".equals(uri)) {
return;
}
*/
if (uri == null) {
uri = "";
}
if (prefix == null || "".equals(prefix)) {
Document doc = element.getOwnerDocument();
Attr attr = doc.createAttribute("xmlns");
attr.setValue(uri);
element.setAttributeNode(attr);
} else {
Document doc = element.getOwnerDocument();
Attr attr = doc.createAttribute("xmlns:" + prefix);
attr.setValue(uri);
element.setAttributeNode(attr);
}
}
private void _addPrefixDeclDOM2(
Element element,
String prefix,
String uri
) {
/*
if (uri == null || "".equals(uri)) {
return;
}
*/
if (uri == null) {
uri = "";
}
if (prefix == null || "".equals(prefix)) {
Document doc = element.getOwnerDocument();
Attr attr = doc.createAttributeNS(XMLNS_NS, "xmlns");
attr.setValue(uri);
element.setAttributeNode(attr);
} else {
Document doc = element.getOwnerDocument();
Attr attr = doc.createAttributeNS(XMLNS_NS, "xmlns:" + prefix);
attr.setValue(uri);
element.setAttributeNode(attr);
}
}
// SAX output
public void startNSMappings(ContentHandler handler) {
startNSMappingsDeclare_(handler);
startNSMappingsWeak_(handler);
}
private void startNSMappingsDeclare_(ContentHandler handler) {
Set keys = prefixByUri_.keySet();
Iterator iter = keys.iterator();
while (iter.hasNext()) {
String uri = (String)iter.next();
String prefix = (String)prefixByUri_.get(uri);
try {
handler.startPrefixMapping(prefix, uri);
} catch (SAXException e) {
}
}
}
private void startNSMappingsWeak_(ContentHandler handler) {
Set keys = prefixByUriWeak_.keySet();
Iterator iter = keys.iterator();
while (iter.hasNext()) {
String uri = (String)iter.next();
if (isAlreadyDeclared_(uri)) {
continue;
}
String prefix = (String)prefixByUriWeak_.get(uri);
try {
handler.startPrefixMapping(prefix, uri);
} catch (SAXException e) {
}
}
}
// SAX output
public void endNSMappings(ContentHandler handler) {
endNSMappingsDeclare_(handler);
endNSMappingsWeak_(handler);
}
private void endNSMappingsDeclare_(ContentHandler handler) {
Set keys = prefixByUri_.keySet();
Iterator iter = keys.iterator();
while (iter.hasNext()) {
String uri = (String)iter.next();
String prefix = (String)prefixByUri_.get(uri);
try {
handler.endPrefixMapping(prefix);
} catch (SAXException e) {
}
}
}
private void endNSMappingsWeak_(ContentHandler handler) {
Set keys = prefixByUriWeak_.keySet();
Iterator iter = keys.iterator();
while (iter.hasNext()) {
String uri = (String)iter.next();
if (isAlreadyDeclared_(uri)) {
continue;
}
String prefix = (String)prefixByUriWeak_.get(uri);
try {
handler.endPrefixMapping(prefix);
} catch (SAXException e) {
}
}
}
// Text output
public void makeNSMappings(StringBuffer buffer) {
// if (rnode_.rGetParentRNode() == null &&
// getPrefixByUri(namespaceUri_) == null &&
// !"".equals(namespaceUri_)) {
// buffer.append(URelaxer.getNSMapping("", namespaceUri_));
// }
makeNSMappingsDeclare_(buffer);
makeNSMappingsWeak_(buffer);
}
private void makeNSMappingsDeclare_(StringBuffer buffer) {
Set keys = prefixByUri_.keySet();
Iterator iter = keys.iterator();
while (iter.hasNext()) {
String uri = (String)iter.next();
buffer.append(makeNSMapping(uri));
}
}
private void makeNSMappingsWeak_(StringBuffer buffer) {
Set keys = prefixByUriWeak_.keySet();
Iterator iter = keys.iterator();
while (iter.hasNext()) {
String uri = (String)iter.next();
String declare = makeNSMappingWeak(uri);
if (declare != null) {
buffer.append(declare);
}
}
}
public void makeNSMappings(Writer buffer) throws IOException {
// if (rnode_.rGetParentRNode() == null &&
// getPrefixByUri(namespaceUri_) == null &&
// !"".equals(namespaceUri_)) {
// buffer.write(URelaxer.getNSMapping("", namespaceUri_));
// }
makeNSMappingsDeclare_(buffer);
makeNSMappingsWeak_(buffer);
}
private void makeNSMappingsDeclare_(Writer buffer) throws IOException {
Set keys = prefixByUri_.keySet();
Iterator iter = keys.iterator();
while (iter.hasNext()) {
String uri = (String)iter.next();
buffer.write(makeNSMapping(uri));
}
}
private void makeNSMappingsWeak_(Writer buffer) throws IOException {
Set keys = prefixByUriWeak_.keySet();
Iterator iter = keys.iterator();
while (iter.hasNext()) {
String uri = (String)iter.next();
String declare = makeNSMappingWeak(uri);
if (declare != null) {
buffer.write(declare);
}
}
}
public void makeNSMappings(PrintWriter buffer) {
// if (rnode_.rGetParentRNode() == null &&
// getPrefixByUri(namespaceUri_) == null &&
// !"".equals(namespaceUri_)) {
// buffer.print(URelaxer.getNSMapping("", namespaceUri_));
// }
makeNSMappingsDeclare_(buffer);
makeNSMappingsWeak_(buffer);
}
private void makeNSMappingsDeclare_(PrintWriter buffer) {
Set keys = prefixByUri_.keySet();
Iterator iter = keys.iterator();
while (iter.hasNext()) {
String uri = (String)iter.next();
buffer.print(makeNSMapping(uri));
}
}
private void makeNSMappingsWeak_(PrintWriter buffer) {
Set keys = prefixByUriWeak_.keySet();
Iterator iter = keys.iterator();
while (iter.hasNext()) {
String uri = (String)iter.next();
String declare = makeNSMappingWeak(uri);
if (declare != null) {
buffer.print(declare);
}
}
}
public String makeQName(String uri, String localName) {
return (URelaxer.getQName(getPrefixByUri(uri), localName));
}
public void makeQName(String uri, String localName, StringBuffer buffer) {
URelaxer.makeQName(getPrefixByUri(uri), localName, buffer);
}
public void makeQName(String uri, String localName, Writer buffer)
throws IOException {
URelaxer.makeQName(getPrefixByUri(uri), localName, buffer);
}
public void makeQName(String uri, String localName, PrintWriter buffer) {
URelaxer.makeQName(getPrefixByUri(uri), localName, buffer);
}
public String makeNSMapping(String uri) {
String prefix = (String)prefixByUri_.get(uri);
if (prefix == null) {
return ("");
}
return (URelaxer.getNSMapping(prefix, uri));
}
public String makeNSMappingWeak(String uri) {
if (isAlreadyDeclared_(uri)) {
return (null);
}
String prefix = (String)prefixByUriWeak_.get(uri);
if (prefix == null) {
return ("");
}
return (URelaxer.getNSMapping(prefix, uri));
}
private boolean isAlreadyDeclared_(String uri) {
if (prefixByUri_.get(uri) != null) {
return (true);
}
IRNSContainer parent = (IRNSContainer)rnode_.rGetParentRNode();
if (parent == null) {
return (false);
}
return (parent.rGetRNSContext().isAlreadyDeclared_(uri));
}
public String getNamespaceUri() {
return (namespaceUri_);
}
private void _updateNamespaceUri(String uri) {
namespaceUri_ = uri;
}
public String getPrefix() {
return (getPrefixByUri(namespaceUri_));
}
public void setPrefix(String prefix) {
declareNamespace(prefix, namespaceUri_);
}
public String getPrefixByUri(String uri) {
if (XML_NS.equals(uri)) {
return ("xml");
}
if (XMLNS_NS.equals(uri)) {
return ("xmlns");
}
String prefix = (String)prefixByUri_.get(uri);
if (prefix != null) {
return (prefix);
}
IRNSContainer parent = (IRNSContainer)rnode_.rGetParentRNode();
if (parent == null) {
return ((String)prefixByUriWeak_.get(uri));
}
prefix = parent.rGetRNSContext().getPrefixByUri(uri);
if (prefix != null) {
return (prefix);
} else {
return ((String)prefixByUriWeak_.get(uri));
}
}
public String getUriByPrefix(String prefix) {
if ("xml".equals(prefix)) {
return (XML_NS);
}
if ("xmlns".equals(prefix)) {
return (XMLNS_NS);
}
String uri = (String)uriByPrefix_.get(prefix);
if (uri != null) {
return (uri);
}
IRNSContainer parent = (IRNSContainer)rnode_.rGetParentRNode();
if (parent == null) {
return ((String)uriByPrefixWeak_.get(prefix));
}
uri = parent.rGetRNSContext().getUriByPrefix(prefix);
if (uri != null) {
return (uri);
} else {
return ((String)uriByPrefixWeak_.get(prefix));
}
}
public String getDefaultNamespace() {
return (getUriByPrefix(""));
}
}