KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sf > saxon > instruct > ProcessingInstruction


1 package net.sf.saxon.instruct;
2
3 import net.sf.saxon.Err;
4 import net.sf.saxon.event.SequenceReceiver;
5 import net.sf.saxon.expr.*;
6 import net.sf.saxon.om.NamePool;
7 import net.sf.saxon.om.XMLChar;
8 import net.sf.saxon.pattern.NodeKindTest;
9 import net.sf.saxon.style.StandardNames;
10 import net.sf.saxon.trans.DynamicError;
11 import net.sf.saxon.trans.XPathException;
12 import net.sf.saxon.type.ItemType;
13 import net.sf.saxon.value.SequenceType;
14
15 import java.io.PrintStream JavaDoc;
16 import java.util.ArrayList JavaDoc;
17 import java.util.Iterator JavaDoc;
18
19 /**
20  * An xsl:processing-instruction element in the stylesheet.
21  */

22
23 public class ProcessingInstruction extends SimpleNodeConstructor {
24
25     private Expression name;
26
27     /**
28      * Create an xsl:processing-instruction instruction
29      * @param name the expression used to compute the name of the generated
30      * processing-instruction
31      */

32
33     public ProcessingInstruction(Expression name) {
34         this.name = name;
35         adoptChildExpression(name);
36     }
37
38     /**
39      * Get the name of this instruction for diagnostic and tracing purposes
40      * @return the string "xsl:processing-instruction"
41      */

42
43     public int getInstructionNameCode() {
44         return StandardNames.XSL_PROCESSING_INSTRUCTION;
45     }
46
47     public ItemType getItemType() {
48         return NodeKindTest.PROCESSING_INSTRUCTION;
49     }
50
51     public int getCardinality() {
52         return StaticProperty.EXACTLY_ONE;
53     }
54
55     public Expression simplify(StaticContext env) throws XPathException {
56         name = name.simplify(env);
57         return super.simplify(env);
58     }
59
60     public void localTypeCheck(StaticContext env, ItemType contextItemType) throws XPathException {
61         name = name.typeCheck(env, contextItemType);
62         adoptChildExpression(name);
63
64         RoleLocator role = new RoleLocator(RoleLocator.INSTRUCTION, "processing-instruction:name", 0, null);
65         role.setSourceLocator(this);
66         name = TypeChecker.staticTypeCheck(name, SequenceType.SINGLE_STRING, false, role, env);
67         adoptChildExpression(name);
68     }
69
70     public int getDependencies() {
71         return name.getDependencies() | super.getDependencies();
72     }
73
74     public Iterator JavaDoc iterateSubExpressions() {
75         ArrayList JavaDoc list = new ArrayList JavaDoc(6);
76         if (select != null) {
77             list.add(select);
78         }
79 // if (separator != null && !(separator instanceof StringValue)) {
80
// list.add(separator);
81
// }
82
list.add(name);
83         return list.iterator();
84     }
85
86     /**
87      * Offer promotion for subexpressions. The offer will be accepted if the subexpression
88      * is not dependent on the factors (e.g. the context item) identified in the PromotionOffer.
89      * By default the offer is not accepted - this is appropriate in the case of simple expressions
90      * such as constant values and variable references where promotion would give no performance
91      * advantage. This method is always called at compile time.
92      *
93      * @param offer details of the offer, for example the offer to move
94      * expressions that don't depend on the context to an outer level in
95      * the containing expression
96      * @exception XPathException if any error is detected
97      */

98
99     protected void promoteInst(PromotionOffer offer) throws XPathException {
100         name = doPromotion(name, offer);
101         super.promoteInst(offer);
102     }
103
104
105     /**
106      * Process this instruction, that is, produce a processing-instruction node in the
107      * result sequence.
108      * @param context the dynamic context of this transformation
109      * @throws XPathException if any non-recoverable dynamic error occurs
110      * @return always returns null in this implementation
111      */

112
113     public TailCall processLeavingTail(XPathContext context) throws XPathException {
114         String JavaDoc expandedName = evaluateName(context);
115         if (expandedName != null) {
116             String JavaDoc data = expandChildren(context).toString();
117             data = checkContent(data, context);
118             SequenceReceiver out = context.getReceiver();
119             out.processingInstruction(expandedName, data, locationId, 0);
120         }
121         return null;
122     }
123
124     /**
125      * Check the content of the node, and adjust it if necessary
126      *
127      * @param data the supplied content
128      * @return the original content, unless adjustments are needed
129      * @throws net.sf.saxon.trans.DynamicError
130      * if the content is invalid
131      */

132
133     protected String JavaDoc checkContent(String JavaDoc data, XPathContext context) throws DynamicError {
134         int hh;
135         while ((hh = data.indexOf("?>")) >= 0) {
136             if (isXSLT(context)) {
137                 data = data.substring(0, hh + 1) + ' ' + data.substring(hh + 1);
138             } else {
139                 DynamicError err = new DynamicError("Invalid characters (?>) in processing instruction", this);
140                 err.setErrorCode("XQDY0026");
141                 err.setXPathContext(context);
142                 context.getController().recoverableError(err);
143             }
144         }
145         return data;
146     }
147
148     protected int evaluateNameCode(XPathContext context) throws XPathException {
149         String JavaDoc expandedName = evaluateName(context);
150         if (expandedName==null) {
151             throw new SkipInstructionException("");
152         }
153         return context.getController().getNamePool().allocate("", "", expandedName);
154     }
155
156     /**
157      * Evaluate the name of the processing instruction. If it is invalid, report a recoverable error
158      * and return null.
159      * @param context
160      * @return the name of the processing instruction (an NCName), or null, incicating an invalid name
161      * @throws XPathException if evaluation fails, or if the recoverable error is treated as fatal
162      */

163     private String JavaDoc evaluateName(XPathContext context) throws XPathException {
164         String JavaDoc expandedName = name.evaluateAsString(context);
165         if (!(XMLChar.isValidNCName(expandedName))) {
166             DynamicError e = new DynamicError(
167                     "Processing instruction name " + Err.wrap(expandedName) + " is not a valid NCName");
168             e.setXPathContext(context);
169             e.setErrorCode((isXSLT(context) ? "XTDE0890" : "XQDY0041"));
170             throw dynamicError(this, e, context);
171         }
172         if (expandedName.equalsIgnoreCase("xml")) {
173             DynamicError e = new DynamicError(
174                     "Processing instructions cannot be named 'xml' in any combination of upper/lower case");
175             e.setXPathContext(context);
176             e.setErrorCode((isXSLT(context) ? "XTDE0890" : "XQDY0064"));
177             throw dynamicError(this, e, context);
178         }
179         return expandedName;
180     }
181
182     public void display(int level, NamePool pool, PrintStream JavaDoc out) {
183         out.println(ExpressionTool.indent(level) + "processing-instruction");
184         name.display(level + 1, pool, out);
185         super.display(level + 1, pool, out);
186     }
187
188 }
189
190 //
191
// The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
192
// you may not use this file except in compliance with the License. You may obtain a copy of the
193
// License at http://www.mozilla.org/MPL/
194
//
195
// Software distributed under the License is distributed on an "AS IS" basis,
196
// WITHOUT WARRANTY OF ANY KIND, either express or implied.
197
// See the License for the specific language governing rights and limitations under the License.
198
//
199
// The Original Code is: all this file.
200
//
201
// The Initial Developer of the Original Code is Michael H. Kay.
202
//
203
// Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
204
//
205
// Contributor(s): none.
206
//
207
Popular Tags