blob: 512798999702b1f236963102d7ae0b8c781c9e1f [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.
*/
/*
* $Id: SerializerUtils.java 468642 2006-10-28 06:55:10Z minchau $
*/
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), false);
}
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.getNodeType(n) == DTM.ELEMENT_NODE
&& 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);
// Brian M. - 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
*
* 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);
}
}
}
}
}