KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sf > saxon > style > XSLResultDocument


1 package net.sf.saxon.style;
2 import net.sf.saxon.Configuration;
3 import net.sf.saxon.expr.Expression;
4 import net.sf.saxon.expr.ExpressionTool;
5 import net.sf.saxon.instruct.Executable;
6 import net.sf.saxon.instruct.ResultDocument;
7 import net.sf.saxon.om.*;
8 import net.sf.saxon.trans.XPathException;
9 import net.sf.saxon.type.ItemType;
10 import net.sf.saxon.type.SchemaType;
11 import net.sf.saxon.value.EmptySequence;
12 import net.sf.saxon.value.StringValue;
13
14 import java.util.*;
15
16 /**
17 * An xsl:result-document (formerly saxon:output) element in the stylesheet. <BR>
18 * The xsl:result-document element takes an attribute HREF="filename". The filename will
19 * often contain parameters, e.g. {position()} to ensure that a different file is produced
20 * for each element instance. <BR>
21 * There is a further attribute "name" which determines the format of the
22 * output file, it identifies the name of an xsl:output element containing the output
23 * format details.
24 */

25
26 public class XSLResultDocument extends StyleElement {
27
28     private static final HashSet fans = new HashSet(25); // formatting attribute names
29

30     static {
31         fans.add(StandardNames.METHOD);
32         fans.add(StandardNames.OUTPUT_VERSION);
33         fans.add(StandardNames.BYTE_ORDER_MARK);
34         fans.add(StandardNames.INDENT);
35         fans.add(StandardNames.ENCODING);
36         fans.add(StandardNames.MEDIA_TYPE);
37         fans.add(StandardNames.DOCTYPE_SYSTEM);
38         fans.add(StandardNames.DOCTYPE_PUBLIC);
39         fans.add(StandardNames.OMIT_XML_DECLARATION);
40         fans.add(StandardNames.STANDALONE);
41         fans.add(StandardNames.CDATA_SECTION_ELEMENTS);
42         fans.add(StandardNames.INCLUDE_CONTENT_TYPE);
43         fans.add(StandardNames.ESCAPE_URI_ATTRIBUTES);
44         fans.add(StandardNames.UNDECLARE_PREFIXES);
45         fans.add(StandardNames.NORMALIZATION_FORM);
46         fans.add(StandardNames.SAXON_NEXT_IN_CHAIN);
47         fans.add(StandardNames.SAXON_CHARACTER_REPRESENTATION);
48         fans.add(StandardNames.SAXON_INDENT_SPACES);
49         fans.add(StandardNames.SAXON_REQUIRE_WELL_FORMED);
50     }
51
52     private Expression href;
53     private int format = -1; // fingerprint of required xsl:output element
54
private int validationAction = Validation.STRIP;
55     private SchemaType schemaType = null;
56     private HashMap serializationAttributes = new HashMap(20);
57
58     /**
59     * Determine whether this node is an instruction.
60     * @return true - it is an instruction
61     */

62
63     public boolean isInstruction() {
64         return true;
65     }
66
67     /**
68     * Determine whether this type of element is allowed to contain a template-body
69     * @return true: yes, it may contain a template-body
70     */

71
72     public boolean mayContainSequenceConstructor() {
73         return true;
74     }
75
76    /**
77      * Determine the type of item returned by this instruction (only relevant if
78      * it is an instruction). Default implementation returns Type.ITEM, indicating
79      * that we don't know, it might be anything. Returns null in the case of an element
80      * such as xsl:sort or xsl:variable that can appear in a sequence constructor but
81      * contributes nothing to the result sequence.
82      * @return the item type returned
83      */

84
85     protected ItemType getReturnedItemType() {
86         return null;
87     }
88
89     public void prepareAttributes() throws XPathException {
90         AttributeCollection atts = getAttributeList();
91
92         String JavaDoc formatAttribute = null;
93         String JavaDoc hrefAttribute = null;
94         String JavaDoc validationAtt = null;
95         String JavaDoc typeAtt = null;
96         String JavaDoc useCharacterMapsAtt = null;
97
98
99         for (int a=0; a<atts.getLength(); a++) {
100             int nc = atts.getNameCode(a);
101             String JavaDoc f = getNamePool().getClarkName(nc);
102             if (f==StandardNames.FORMAT) {
103                 formatAttribute = atts.getValue(a).trim();
104             } else if (f==StandardNames.HREF) {
105                 hrefAttribute = atts.getValue(a).trim();
106             } else if (f==StandardNames.VALIDATION) {
107                 validationAtt = atts.getValue(a).trim();
108             } else if (f==StandardNames.TYPE) {
109                 typeAtt = atts.getValue(a).trim();
110             } else if (f==StandardNames.USE_CHARACTER_MAPS) {
111                 useCharacterMapsAtt = atts.getValue(a).trim();
112             } else if (fans.contains(f) || !(f.startsWith("{}"))) {
113                 // this is a serialization attribute
114
String JavaDoc val = atts.getValue(a).trim();
115                 Expression exp = makeAttributeValueTemplate(val);
116                 serializationAttributes.put(new Integer JavaDoc(nc&0xfffff), exp);
117             } else {
118                 checkUnknownAttribute(nc);
119             }
120         }
121
122         if (hrefAttribute==null) {
123             //href = StringValue.EMPTY_STRING;
124
} else {
125             href = makeAttributeValueTemplate(hrefAttribute);
126         }
127
128         if (formatAttribute!=null) {
129             try {
130                 format = makeNameCode(formatAttribute.trim()) & 0xfffff;
131             } catch (NamespaceException err) {
132                 compileError(err.getMessage(), "XTSE0280");
133             } catch (XPathException err) {
134                 compileError(err.getMessage());
135             }
136         }
137
138         if (validationAtt==null) {
139             validationAction = getContainingStylesheet().getDefaultValidation();
140         } else {
141             validationAction = Validation.getCode(validationAtt);
142             if (validationAction != Validation.STRIP && !getConfiguration().isSchemaAware(Configuration.XSLT)) {
143                 compileError("To perform validation, a schema-aware XSLT processor is needed", "XTSE1660");
144             }
145             if (validationAction == Validation.INVALID) {
146                 compileError("Invalid value of @validation attribute", "XTSE0020");
147             }
148         }
149         if (typeAtt!=null) {
150             if (!getConfiguration().isSchemaAware(Configuration.XSLT)) {
151                 compileError("The @type attribute is available only with a schema-aware XSLT processor", "XTSE1660");
152             }
153             schemaType = getSchemaType(typeAtt);
154         }
155
156         if (typeAtt != null && validationAtt != null) {
157             compileError("The @validation and @type attributes are mutually exclusive", "XTSE1505");
158         }
159
160         if (useCharacterMapsAtt != null) {
161             String JavaDoc s = XSLOutput.prepareCharacterMaps(this, useCharacterMapsAtt, new Properties());
162             serializationAttributes.put(
163                     new Integer JavaDoc(getNamePool().allocate("", "", StandardNames.USE_CHARACTER_MAPS)),
164                     new StringValue(s));
165         }
166     }
167
168     public void validate() throws XPathException {
169         checkWithinTemplate();
170         if (!getPreparedStylesheet().getConfiguration().isAllowExternalFunctions()) {
171             compileError("xsl:result-document is disabled when extension functions are disabled");
172         }
173         href = typeCheck("href", href);
174         Iterator it = serializationAttributes.keySet().iterator();
175         boolean methodSpecified = false;
176         while (it.hasNext()) {
177             Integer JavaDoc fp = (Integer JavaDoc)it.next();
178             String JavaDoc displayName = getNamePool().getDisplayName(fp.intValue());
179             if (displayName.equals(StandardNames.METHOD)) {
180                 methodSpecified = true;
181             }
182             final Expression exp1 = (Expression)serializationAttributes.get(fp);
183             final Expression exp2 = typeCheck(displayName, exp1);
184             if (exp1 != exp2) {
185                 serializationAttributes.put(fp, exp2);
186             }
187         }
188
189
190     }
191
192     public Expression compile(Executable exec) throws XPathException {
193         Properties props;
194         try {
195             props = getPrincipalStylesheet().gatherOutputProperties(format);
196         } catch (XPathException err) {
197             compileError("Named output format has not been defined", "XTSE1460");
198             return null;
199         }
200
201         // If no serialization method was specified, we can work it out statically if the
202
// first contained instruction is a literal result element. This saves effort at run-time.
203

204         Integer JavaDoc key = new Integer JavaDoc(getNamePool().allocate("", "", StandardNames.METHOD));
205         if (props.getProperty("method") == null && serializationAttributes.get(key) == null) {
206             AxisIterator kids = iterateAxis(Axis.CHILD);
207             NodeInfo first = (NodeInfo)kids.next();
208             if (first instanceof LiteralResultElement) {
209                 if (first.getFingerprint() == getNamePool().allocate("", NamespaceConstant.XHTML, "html")) {
210                     if (backwardsCompatibleModeIsEnabled()) {
211                         props.setProperty("method", "xml");
212                     } else {
213                         props.setProperty("method", "xhtml");
214                     }
215                 } else if (first.getLocalPart().equalsIgnoreCase("html") && first.getURI().equals("")) {
216                     props.setProperty("method", "html");
217                 } else {
218                     props.setProperty("method", "xml");
219                 }
220             }
221         }
222
223         ArrayList fixed = new ArrayList(10);
224         boolean needsNamespaceContext = false;
225         for (Iterator it=serializationAttributes.keySet().iterator(); it.hasNext();) {
226             Integer JavaDoc fp = (Integer JavaDoc)it.next();
227             Expression exp = (Expression)serializationAttributes.get(fp);
228             if (exp instanceof StringValue) {
229                 String JavaDoc s = ((StringValue)exp).getStringValue();
230                 try {
231                     ResultDocument.setSerializationProperty(props, fp.intValue(), s,
232                             getNamePool(), getStaticContext().getNamespaceResolver());
233                     fixed.add(fp);
234                 } catch (XPathException e) {
235                     if (NamespaceConstant.SAXON.equals(e.getErrorCodeNamespace())) {
236                         compileWarning(e.getMessage(), e.getErrorCodeLocalPart());
237                     } else {
238                         compileError(e);
239                     }
240                 }
241             } else {
242                 String JavaDoc lname = getNamePool().getLocalName(fp.intValue());
243                 if (lname.equals("method") || lname.equals("cdata-section-elements")) {
244                     needsNamespaceContext = true;
245                 }
246             }
247         }
248         for (Iterator it=fixed.iterator(); it.hasNext();) {
249             serializationAttributes.remove(it.next());
250         }
251
252         ResultDocument inst = new ResultDocument(props,
253                                               href,
254                                               getBaseURI(),
255                                               validationAction,
256                                               schemaType,
257                                               serializationAttributes,
258                                               (needsNamespaceContext ? getStaticContext().getNamespaceResolver() : null));
259
260         Expression b = compileSequenceConstructor(exec, iterateAxis(Axis.CHILD), true);
261         if (b == null) {
262             b = EmptySequence.getInstance();
263         }
264         inst.setContent(b);
265         ExpressionTool.makeParentReferences(inst);
266         return inst;
267     }
268
269 }
270
271 //
272
// The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
273
// you may not use this file except in compliance with the License. You may obtain a copy of the
274
// License at http://www.mozilla.org/MPL/
275
//
276
// Software distributed under the License is distributed on an "AS IS" basis,
277
// WITHOUT WARRANTY OF ANY KIND, either express or implied.
278
// See the License for the specific language governing rights and limitations under the License.
279
//
280
// The Original Code is: all this file.
281
//
282
// The Initial Developer of the Original Code is Michael H. Kay.
283
//
284
// Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
285
//
286
// Additional Contributor(s): Brett Knights [brett@knightsofthenet.com]
287
//
288
Popular Tags