blob: d2e3195bb3827b309a62c953d4f573d72d602cb1 [file] [log] [blame]
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 1999-2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xalan" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 1999, Lotus
* Development Corporation., http://www.lotus.com. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.xalan.serialize;
import javax.xml.transform.TransformerException;
import org.apache.xalan.transformer.TransformerImpl;
import org.apache.xml.dtm.DTM;
import org.apache.xml.serializer.NamespaceMappings;
import org.apache.xml.serializer.SerializationHandler;
import org.apache.xpath.XPathContext;
import org.apache.xpath.objects.XObject;
import org.xml.sax.SAXException;
/**
* Class that contains only static methods that are used to "serialize",
* these methods are used by Xalan and are not in org.apache.xml.serializer
* because they have dependancies on the packages org.apache.xpath or org.
* apache.xml.dtm or org.apache.xalan.transformer. The package org.apache.xml.
* serializer should not depend on Xalan or XSLTC.
* @xsl.usage internal
*/
public class SerializerUtils
{
/**
* Copy an DOM attribute to the created output element, executing
* attribute templates as need be, and processing the xsl:use
* attribute.
*
* @param handler SerializationHandler to which the attributes are added.
* @param attr Attribute node to add to SerializationHandler.
*
* @throws TransformerException
*/
public static void addAttribute(SerializationHandler handler, int attr)
throws TransformerException
{
TransformerImpl transformer =
(TransformerImpl) handler.getTransformer();
DTM dtm = transformer.getXPathContext().getDTM(attr);
if (SerializerUtils.isDefinedNSDecl(handler, attr, dtm))
return;
String ns = dtm.getNamespaceURI(attr);
if (ns == null)
ns = "";
// %OPT% ...can I just store the node handle?
try
{
handler.addAttribute(
ns,
dtm.getLocalName(attr),
dtm.getNodeName(attr),
"CDATA",
dtm.getNodeValue(attr));
}
catch (SAXException e)
{
// do something?
}
} // end copyAttributeToTarget method
/**
* Copy DOM attributes to the result element.
*
* @param src Source node with the attributes
*
* @throws TransformerException
*/
public static void addAttributes(SerializationHandler handler, int src)
throws TransformerException
{
TransformerImpl transformer =
(TransformerImpl) handler.getTransformer();
DTM dtm = transformer.getXPathContext().getDTM(src);
for (int node = dtm.getFirstAttribute(src);
DTM.NULL != node;
node = dtm.getNextAttribute(node))
{
addAttribute(handler, node);
}
}
/**
* Given a result tree fragment, walk the tree and
* output it to the SerializationHandler.
*
* @param obj Result tree fragment object
* @param support XPath context for the result tree fragment
*
* @throws org.xml.sax.SAXException
*/
public static void outputResultTreeFragment(
SerializationHandler handler,
XObject obj,
XPathContext support)
throws org.xml.sax.SAXException
{
int doc = obj.rtf();
DTM dtm = support.getDTM(doc);
if (null != dtm)
{
for (int n = dtm.getFirstChild(doc);
DTM.NULL != n;
n = dtm.getNextSibling(n))
{
handler.flushPending();
// I think. . . . This used to have a (true) arg
// to flush prefixes, will that cause problems ???
if (dtm.getNamespaceURI(n) == null)
handler.startPrefixMapping("", "");
dtm.dispatchToEvents(n, handler);
}
}
}
/**
* Copy <KBD>xmlns:</KBD> attributes in if not already in scope.
*
* As a quick hack to support ClonerToResultTree, this can also be used
* to copy an individual namespace node.
*
* @param src Source Node
* NEEDSDOC @param type
* NEEDSDOC @param dtm
*
* @throws TransformerException
*/
public static void processNSDecls(
SerializationHandler handler,
int src,
int type,
DTM dtm)
throws TransformerException
{
try
{
if (type == DTM.ELEMENT_NODE)
{
for (int namespace = dtm.getFirstNamespaceNode(src, true);
DTM.NULL != namespace;
namespace = dtm.getNextNamespaceNode(src, namespace, true))
{
// String prefix = dtm.getPrefix(namespace);
String prefix = dtm.getNodeNameX(namespace);
String desturi = handler.getNamespaceURIFromPrefix(prefix);
// String desturi = getURI(prefix);
String srcURI = dtm.getNodeValue(namespace);
if (!srcURI.equalsIgnoreCase(desturi))
{
handler.startPrefixMapping(prefix, srcURI, false);
}
}
}
else if (type == DTM.NAMESPACE_NODE)
{
String prefix = dtm.getNodeNameX(src);
// bjm - some changes here to get desturi
String desturi = handler.getNamespaceURIFromPrefix(prefix);
String srcURI = dtm.getNodeValue(src);
if (!srcURI.equalsIgnoreCase(desturi))
{
handler.startPrefixMapping(prefix, srcURI, false);
}
}
}
catch (org.xml.sax.SAXException se)
{
throw new TransformerException(se);
}
}
/**
* Returns whether a namespace is defined
*
*
* @param attr Namespace attribute node
* @param dtm The DTM that owns attr.
*
* @return True if the namespace is already defined in
* list of namespaces
*/
public static boolean isDefinedNSDecl(
SerializationHandler serializer,
int attr,
DTM dtm)
{
if (DTM.NAMESPACE_NODE == dtm.getNodeType(attr))
{
// String prefix = dtm.getPrefix(attr);
String prefix = dtm.getNodeNameX(attr);
String uri = serializer.getNamespaceURIFromPrefix(prefix);
// String uri = getURI(prefix);
if ((null != uri) && uri.equals(dtm.getStringValue(attr)))
return true;
}
return false;
}
/**
* This function checks to make sure a given prefix is really
* declared. It might not be, because it may be an excluded prefix.
* If it's not, it still needs to be declared at this point.
* TODO: This needs to be done at an earlier stage in the game... -sb
*
* @param ns Namespace URI of the element
* @param rawName Raw name of element (with prefix)
*
* NEEDSDOC @param dtm
* NEEDSDOC @param namespace
*
* @throws org.xml.sax.SAXException
*/
public static void ensureNamespaceDeclDeclared(
SerializationHandler handler,
DTM dtm,
int namespace)
throws org.xml.sax.SAXException
{
String uri = dtm.getNodeValue(namespace);
String prefix = dtm.getNodeNameX(namespace);
if ((uri != null && uri.length() > 0) && (null != prefix))
{
String foundURI;
NamespaceMappings ns = handler.getNamespaceMappings();
if (ns != null)
{
foundURI = ns.lookupNamespace(prefix);
if ((null == foundURI) || !foundURI.equals(uri))
{
handler.startPrefixMapping(prefix, uri, false);
}
}
}
}
}