package net.sf.saxon.style;
import net.sf.saxon.AugmentedSource;
import net.sf.saxon.Configuration;
import net.sf.saxon.PreparedStylesheet;
import net.sf.saxon.event.IDFilter;
import net.sf.saxon.expr.Expression;
import net.sf.saxon.instruct.Executable;
import net.sf.saxon.om.AttributeCollection;
import net.sf.saxon.om.StandardNames;
import net.sf.saxon.trans.XPathException;
import net.sf.saxon.tree.DocumentImpl;
import net.sf.saxon.tree.ElementImpl;
import net.sf.saxon.value.Whitespace;
import javax.xml.transform.Source;
import javax.xml.transform.TransformerException;
import javax.xml.transform.URIResolver;
/**
* Abstract class to represent xsl:include or xsl:import element in the stylesheet. <br>
* The xsl:include and xsl:import elements have mandatory attribute href
*/
public abstract class XSLGeneralIncorporate extends StyleElement {
String href;
DocumentImpl includedDoc;
/**
* isImport() returns true if this is an xsl:import declaration rather than an xsl:include
* @return true if this is an xsl:import declaration, false if it is an xsl:include
*/
public abstract boolean isImport();
public void prepareAttributes() throws XPathException {
AttributeCollection atts = getAttributeList();
for (int a=0; a<atts.getLength(); a++) {
int nc = atts.getNameCode(a);
String f = getNamePool().getClarkName(nc);
if (f.equals(StandardNames.HREF)) {
href = Whitespace.trim(atts.getValue(a));
} else {
checkUnknownAttribute(nc);
}
}
if (href==null) {
reportAbsence("href");
}
}
public void validate() throws XPathException {
checkEmpty();
checkTopLevel(isImport() ? "XTSE0190" : "XTSE0170");
}
/**
* Get the included or imported stylesheet module
* @param importer the module that requested the include or export (used to check for cycles)
* @param precedence the import precedence to be allocated to the included or imported module
* @return the xsl:stylesheet element at the root of the included/imported module
* @throws XPathException if any failure occurs
*/
public XSLStylesheet getIncludedStylesheet(XSLStylesheet importer, int precedence)
throws XPathException {
if (href==null) {
// error already reported
return null;
}
checkEmpty();
checkTopLevel((this instanceof XSLInclude ? "XTSE0170" : "XTSE0190"));
try {
XSLStylesheet thisSheet = (XSLStylesheet)getParent();
PreparedStylesheet pss = getPreparedStylesheet();
URIResolver resolver = pss.getCompilerInfo().getURIResolver();
Configuration config = pss.getConfiguration();
//System.err.println("GeneralIncorporate: href=" + href + " base=" + getBaseURI());
String relative = href;
String fragment = null;
int hash = relative.indexOf('#');
if (hash == 0 || relative.length() == 0) {
compileError("A stylesheet cannot " + getLocalPart() + " itself",
(this instanceof XSLInclude ? "XTSE0180" : "XTSE0210"));
return null;
} else if (hash == relative.length() - 1) {
relative = relative.substring(0, hash);
} else if (hash > 0) {
if (hash+1 < relative.length()) {
fragment = relative.substring(hash+1);
}
relative = relative.substring(0, hash);
}
Source source;
try {
source = resolver.resolve(relative, getBaseURI());
} catch (TransformerException e) {
throw XPathException.makeXPathException(e);
}
// if a user URI resolver returns null, try the standard one
// (Note, the standard URI resolver never returns null)
if (source==null) {
source = config.getSystemURIResolver().resolve(relative, getBaseURI());
}
if (fragment != null) {
IDFilter filter = new IDFilter(fragment);
source = AugmentedSource.makeAugmentedSource(source);
((AugmentedSource)source).addFilter(filter);
}
// check for recursion
XSLStylesheet anc = thisSheet;
if (source.getSystemId() != null) {
while(anc!=null) {
if (source.getSystemId().equals(anc.getSystemId())) {
compileError("A stylesheet cannot " + getLocalPart() + " itself",
(this instanceof XSLInclude ? "XTSE0180" : "XTSE0210"));
return null;
}
anc = anc.getImporter();
}
}
StyleNodeFactory snFactory = config.getStyleNodeFactory();
includedDoc = pss.loadStylesheetModule(source, snFactory);
// allow the included document to use "Literal Result Element as Stylesheet" syntax
ElementImpl outermost = includedDoc.getDocumentElement();
if (outermost instanceof LiteralResultElement) {
includedDoc = ((LiteralResultElement)outermost)
.makeStylesheet(getPreparedStylesheet(), snFactory);
outermost = includedDoc.getDocumentElement();
}
if (!(outermost instanceof XSLStylesheet)) {
compileError("Included document " + href + " is not a stylesheet", "XTSE0165");
return null;
}
XSLStylesheet incSheet = (XSLStylesheet)outermost;
incSheet.validate();
if (incSheet.validationError!=null) {
if (reportingCircumstances == REPORT_ALWAYS) {
incSheet.compileError(incSheet.validationError);
} else if (incSheet.reportingCircumstances == REPORT_UNLESS_FORWARDS_COMPATIBLE
// not sure if this can still happen
/*&& !incSheet.forwardsCompatibleModeIsEnabled()*/) {
incSheet.compileError(incSheet.validationError);
}
}
incSheet.setPrecedence(precedence);
incSheet.setImporter(importer);
incSheet.spliceIncludes(); // resolve any nested includes;
// Check the consistency of input-type-annotations
//assert thisSheet != null;
thisSheet.setInputTypeAnnotations(incSheet.getInputTypeAnnotationsAttribute() |
incSheet.getInputTypeAnnotations());
return incSheet;
} catch (XPathException err) {
err.setErrorCode("XTSE0165");
err.setIsStaticError(true);
compileError(err);
return null;
}
}
public Expression compile(Executable exec) throws XPathException {
return null;
// no action. The node will never be compiled, because it replaces itself
// by the contents of the included file.
}
}
//
// The contents of this file are subject to the Mozilla Public License Version 1.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.mozilla.org/MPL/
//
// Software distributed under the License is distributed on an "AS IS" basis,
// WITHOUT WARRANTY OF ANY KIND, either express or implied.
// See the License for the specific language governing rights and limitations under the License.
//
// The Original Code is: all this file.
//
// The Initial Developer of the Original Code is Michael H. Kay.
//
// Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
//
// Contributor(s): none.
//