All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.sf.saxon.style.XSLGeneralIncorporate Maven / Gradle / Ivy

There is a newer version: 12.5
Show newest version
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2015 Saxonica Limited.
// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
// If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
// This Source Code Form is "Incompatible With Secondary Licenses", as defined by the Mozilla Public License, v. 2.0.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

package net.sf.saxon.style;

import net.sf.saxon.Configuration;
import net.sf.saxon.event.FilterFactory;
import net.sf.saxon.event.IDFilter;
import net.sf.saxon.event.ProxyReceiver;
import net.sf.saxon.event.Receiver;
import net.sf.saxon.functions.DocumentFn;
import net.sf.saxon.lib.AugmentedSource;
import net.sf.saxon.om.AttributeCollection;
import net.sf.saxon.om.DocumentURI;
import net.sf.saxon.om.TreeInfo;
import net.sf.saxon.trans.XPathException;
import net.sf.saxon.tree.linked.DocumentImpl;
import net.sf.saxon.tree.linked.ElementImpl;
import net.sf.saxon.value.Whitespace;

import javax.xml.transform.Source;
import javax.xml.transform.TransformerException;
import javax.xml.transform.URIResolver;
import java.util.Map;


/**
 * Abstract class to represent xsl:include or xsl:import element in the stylesheet. 
* The xsl:include and xsl:import elements have mandatory attribute href */ public abstract class XSLGeneralIncorporate extends StyleElement { private String href; /** * Ask whether this node is a declaration, that is, a permitted child of xsl:stylesheet * (including xsl:include and xsl:import). * * @return true for this element */ @Override public boolean isDeclaration() { return true; } /** * 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++) { String f = atts.getQName(a); if (f.equals("href")) { href = Whitespace.trim(atts.getValue(a)); } else { checkUnknownAttribute(atts.getNodeName(a)); } } if (href == null) { reportAbsence("href"); } } public void validate(ComponentDeclaration decl) throws XPathException { validateInstruction(); } public void validateInstruction() throws XPathException { checkEmpty(); checkTopLevel(isImport() ? "XTSE0190" : "XTSE0170", false); } /** * Get the included or imported stylesheet module * * @param importer the module that requested the include or import (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 */ /*@Nullable*/ public StylesheetModule getIncludedStylesheet(StylesheetModule importer, int precedence) throws XPathException { if (href == null) { // error already reported return null; } //checkEmpty(); //checkTopLevel((this instanceof XSLInclude ? "XTSE0170" : "XTSE0190")); try { PrincipalStylesheetModule psm = importer.getPrincipalStylesheetModule(); //PreparedStylesheet pss = psm.getPreparedStylesheet(); URIResolver resolver = getCompilation().getCompilerInfo().getURIResolver(); Configuration config = getConfiguration(); XSLStylesheet includedSheet; StylesheetModule incModule; DocumentURI key = DocumentFn.computeDocumentKey(href, getBaseURI(), resolver); includedSheet = (XSLStylesheet)psm.getStylesheetDocument(key); if (includedSheet != null) { // we already have the stylesheet document in cache; but we need to create a new module, // because the import precedence might be different. See test impincl30. incModule = new StylesheetModule(includedSheet, precedence); incModule.setImporter(importer); // check for recursion if (checkForRecursion(importer, incModule.getRootElement())) { return null; } } else { Map map = getCompilation().getStylesheetModules(); DocumentImpl includedDoc = (DocumentImpl)map.get(key); //System.err.println("GeneralIncorporate: href=" + href + " base=" + getBaseURI()); String relative = href; String fragment = null; int hash = relative.indexOf('#'); if (hash == 0 || relative.isEmpty()) { 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) { final String fragmentFinal = fragment; FilterFactory factory = new FilterFactory() { public ProxyReceiver makeFilter(Receiver next) { return new IDFilter(next, fragmentFinal); } }; source = AugmentedSource.makeAugmentedSource(source); ((AugmentedSource) source).addFilter(factory); } // check for recursion if (checkForRecursion(importer, source)) { return null; } //DocumentImpl includedDoc = StylesheetModule.loadStylesheetModule(source, getCompilation()); // allow the included document to use "Literal Result Element as Stylesheet" syntax ElementImpl outermost = includedDoc.getDocumentElement(); if (outermost instanceof LiteralResultElement) { includedDoc = ((LiteralResultElement) outermost).makeStylesheet(false); outermost = includedDoc.getDocumentElement(); } if (!(outermost instanceof XSLStylesheet)) { compileError("Included document " + href + " is not a stylesheet", "XTSE0165"); return null; } includedSheet = (XSLStylesheet) outermost; psm.putStylesheetDocument(key, includedSheet); incModule = new StylesheetModule(includedSheet, precedence); incModule.setImporter(importer); ComponentDeclaration decl = new ComponentDeclaration(incModule, includedSheet); includedSheet.validate(decl); if (includedSheet.validationError != null) { if (reportingCircumstances == REPORT_ALWAYS) { includedSheet.compileError(includedSheet.validationError); } else if (includedSheet.reportingCircumstances == REPORT_UNLESS_FORWARDS_COMPATIBLE // not sure if this can still happen /*&& !incSheet.forwardsCompatibleModeIsEnabled()*/) { includedSheet.compileError(includedSheet.validationError); } } } incModule.spliceIncludes(); // resolve any nested imports and includes; // Check the consistency of input-type-annotations //assert thisSheet != null; importer.setInputTypeAnnotations(includedSheet.getInputTypeAnnotationsAttribute() | incModule.getInputTypeAnnotations()); return incModule; } catch (XPathException err) { err.setErrorCode("XTSE0165"); err.setIsStaticError(true); compileError(err); return null; } } private boolean checkForRecursion(StylesheetModule importer, Source source) throws XPathException { StylesheetModule anc = importer; if (source.getSystemId() != null) { while (anc != null) { if (DocumentURI.normalizeURI(source.getSystemId()) .equals(DocumentURI.normalizeURI(anc.getRootElement().getSystemId()))) { compileError("A stylesheet cannot " + getLocalPart() + " itself", this instanceof XSLInclude ? "XTSE0180" : "XTSE0210"); return true; } anc = anc.getImporter(); } } return false; } public void compileDeclaration(Compilation compilation, ComponentDeclaration decl) throws XPathException { // no action. The node will never be compiled, because it replaces itself // by the contents of the included file. } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy