com.sun.xml.xsl.Template Maven / Gradle / Ivy
/*
* @(#)Template.java 1.9 99/01/27
*
* Copyright (c) 1998-1999 Sun Microsystems, Inc. All Rights Reserved.
*
* This software is the confidential and proprietary information of Sun
* Microsystems, Inc. ("Confidential Information"). You shall not
* disclose such Confidential Information and shall use it only in
* accordance with the terms of the license agreement you entered into
* with Sun.
*
* SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
* SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
* IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
* SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
* THIS SOFTWARE OR ITS DERIVATIVES.
*/
package com.sun.xml.xsl;
import org.w3c.dom.*;
import com.sun.xml.tree.*;
/**
* Instance of this class represent XSL templates.
*
* There are no user-serviceable parts inside this box.
*/
final class Template extends XslNode
{
private XslPattern matchPattern;
/**
* Constructs a XSL stylesheet document.
*/
public Template () { }
// package private
boolean match (Element e)
{
// match pattern will be NULL for interior pattern nodes
// but this method is only called for xsl:template nodes
return matchPattern.match (e, (StyleSheet) getOwnerDocument ());
}
public void startParse (ParseContext context)
{
try {
String pattern = getAttribute (StyleSheet.uri, "match");
if (pattern != null)
matchPattern = XslPattern.parse (pattern);
} catch (Exception e) {
e.printStackTrace ();
throw new RuntimeException (e.getMessage ());
}
}
/**
* Process an element to create a result tree fragment.
* It's known that the the element matches the pattern that
* applies to this template, and that this is the "best"
* (most important, as affected by stylesheet importing)
* match.
*/
// package private
void process (
ElementNode current,
Node output,
XslContext context
) {
DocumentEx outFactory = (DocumentEx) output.getOwnerDocument ();
// bletch -- there's no benefit to such special cases
if (outFactory == null) {
if (output instanceof DocumentEx)
outFactory = (DocumentEx) output;
else
throw new RuntimeException ("?? null factory ??");
}
// for each child, pattern match OR output
for (int i = 0; ; i++) {
Node node = this.item (i);
Node out;
if (node == null)
break;
switch (node.getNodeType ()) {
case TEXT_NODE:
case CDATA_SECTION_NODE:
{
boolean ignorable = true;
String data = node.getNodeValue ();
int length = data.length ();
// See if the text is potentially ignorable
for (int j = 0; j < length; j++) {
char c = data.charAt (j);
if (c == ' ' || c == '\t' || c == '\n' || c == '\r')
continue;
ignorable = false;
break;
}
// Most patterns have excess whitespace... disallowed
// at the top level!
if (output instanceof Document) {
if (ignorable)
continue;
throw new IllegalArgumentException (
"Can't have text outside of elements!");
}
// if !ignorable && !xml:space=".."
// && doc default isn't to preserve
// && not indenting output ...
out = outFactory.createTextNode (data);
output.appendChild (out);
continue;
}
case ELEMENT_NODE:
{
// by default, elements work like nested templates
if (node instanceof Template) {
NamedNodeMap attributes;
ElementNode outElement;
outElement = (ElementNode) outFactory.createElement (
node.getNodeName ());
// copy attributes ...
attributes = node.getAttributes ();
for (int j = 0; ; j++) {
Attr att;
att = (Attr) attributes.item (j);
if (att == null)
break;
if ("xsl:use".equals (att.getName ())) {
// 2.7.3 attribute value sets
} else if (att.getNodeValue ().indexOf ('{') >= 0) {
// 2.7.11.3 attribute value templates
} else {
outElement.setAttribute (att.getName (),
att.getNodeValue ());
}
}
((XslNode)node).process (current, outElement, context);
output.appendChild (outElement);
continue;
}
// other elements should be built-ins
if (node instanceof XslNode) {
((XslNode)node).process (current, output, context);
continue;
}
// !! else fatal error !!
}
continue;
// PIs, comments, DTD, entity refs ... dropped!
// worth revisiting all of those
}
}
}
}