001: package net.sf.saxon.style;
002:
003: import net.sf.saxon.Configuration;
004: import net.sf.saxon.PreparedStylesheet;
005: import net.sf.saxon.expr.Expression;
006: import net.sf.saxon.instruct.Executable;
007: import net.sf.saxon.om.AttributeCollection;
008: import net.sf.saxon.trans.StaticError;
009: import net.sf.saxon.trans.XPathException;
010: import net.sf.saxon.tree.DocumentImpl;
011: import net.sf.saxon.tree.ElementImpl;
012:
013: import javax.xml.transform.Source;
014: import javax.xml.transform.TransformerException;
015:
016: /**
017: * Abstract class to represent xsl:include or xsl:import element in the stylesheet. <br>
018: * The xsl:include and xsl:import elements have mandatory attribute href
019: */
020:
021: public abstract class XSLGeneralIncorporate extends StyleElement {
022:
023: String href;
024: DocumentImpl includedDoc;
025:
026: /**
027: * isImport() returns true if this is an xsl:import statement rather than an xsl:include
028: */
029:
030: public abstract boolean isImport();
031:
032: public void prepareAttributes() throws XPathException {
033:
034: AttributeCollection atts = getAttributeList();
035:
036: for (int a = 0; a < atts.getLength(); a++) {
037: int nc = atts.getNameCode(a);
038: String f = getNamePool().getClarkName(nc);
039: if (f == StandardNames.HREF) {
040: href = atts.getValue(a).trim();
041: } else {
042: checkUnknownAttribute(nc);
043: }
044: }
045:
046: if (href == null) {
047: reportAbsence("href");
048: }
049: }
050:
051: public void validate() throws XPathException {
052: // The node will never be validated, because it replaces itself
053: // by the contents of the included file.
054: checkEmpty();
055: checkTopLevel(null);
056: }
057:
058: public XSLStylesheet getIncludedStylesheet(XSLStylesheet importer,
059: int precedence) throws XPathException {
060:
061: if (href == null) {
062: // error already reported
063: return null;
064: }
065:
066: checkEmpty();
067: checkTopLevel((this instanceof XSLInclude ? "XTSE0170"
068: : "XTSE0190"));
069:
070: try {
071: XSLStylesheet this Sheet = (XSLStylesheet) getParent();
072: PreparedStylesheet pss = getPreparedStylesheet();
073: Configuration config = pss.getConfiguration();
074:
075: // System.err.println("GeneralIncorporate: href=" + href + " base=" + getBaseURI());
076: Source source;
077: try {
078: source = config.getURIResolver().resolve(href,
079: getBaseURI());
080: } catch (TransformerException e) {
081: throw StaticError.makeStaticError(e);
082: }
083:
084: // if a user URI resolver returns null, try the standard one
085: // (Note, the standard URI resolver never returns null)
086: if (source == null) {
087: source = config.getSystemURIResolver().resolve(href,
088: getBaseURI());
089: }
090:
091: // check for recursion
092:
093: XSLStylesheet anc = this Sheet;
094:
095: if (source.getSystemId() != null) {
096: while (anc != null) {
097: if (source.getSystemId().equals(anc.getSystemId())) {
098: compileError(
099: "A stylesheet cannot " + getLocalPart()
100: + " itself",
101: (this instanceof XSLInclude ? "XTSE0180"
102: : "XTSE0210"));
103: return null;
104: }
105: anc = anc.getImporter();
106: }
107: }
108:
109: StyleNodeFactory snFactory = new StyleNodeFactory(config);
110: includedDoc = PreparedStylesheet.loadStylesheetModule(
111: source, config, getNamePool(), snFactory);
112:
113: // allow the included document to use "Literal Result Element as Stylesheet" syntax
114:
115: ElementImpl outermost = includedDoc.getDocumentElement();
116:
117: if (outermost instanceof LiteralResultElement) {
118: includedDoc = ((LiteralResultElement) outermost)
119: .makeStylesheet(getPreparedStylesheet(),
120: snFactory);
121: outermost = includedDoc.getDocumentElement();
122: }
123:
124: if (!(outermost instanceof XSLStylesheet)) {
125: compileError("Included document " + href
126: + " is not a stylesheet", "XTSE0165");
127: return null;
128: }
129: XSLStylesheet incSheet = (XSLStylesheet) outermost;
130:
131: if (incSheet.validationError != null) {
132: if (reportingCircumstances == REPORT_ALWAYS) {
133: incSheet.compileError(incSheet.validationError);
134: } else if (incSheet.reportingCircumstances == REPORT_UNLESS_FORWARDS_COMPATIBLE
135: // not sure if this can still happen
136: /*&& !incSheet.forwardsCompatibleModeIsEnabled()*/) {
137: incSheet.compileError(incSheet.validationError);
138: }
139: }
140:
141: incSheet.setPrecedence(precedence);
142: incSheet.setImporter(importer);
143: incSheet.spliceIncludes(); // resolve any nested includes;
144:
145: // Check the consistency of input-type-annotations
146: this Sheet.setInputTypeAnnotations(incSheet
147: .getInputTypeAnnotationsAttribute()
148: | incSheet.getInputTypeAnnotations());
149:
150: return incSheet;
151:
152: } catch (XPathException err) {
153: err.setErrorCode("XTSE0165");
154: compileError(err);
155: return null;
156: }
157: }
158:
159: public Expression compile(Executable exec) throws XPathException {
160: return null;
161: // no action. The node will never be compiled, because it replaces itself
162: // by the contents of the included file.
163: }
164: }
165:
166: //
167: // The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
168: // you may not use this file except in compliance with the License. You may obtain a copy of the
169: // License at http://www.mozilla.org/MPL/
170: //
171: // Software distributed under the License is distributed on an "AS IS" basis,
172: // WITHOUT WARRANTY OF ANY KIND, either express or implied.
173: // See the License for the specific language governing rights and limitations under the License.
174: //
175: // The Original Code is: all this file.
176: //
177: // The Initial Developer of the Original Code is Michael H. Kay.
178: //
179: // Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
180: //
181: // Contributor(s): none.
182: //
|