KickJava   Java API By Example, From Geeks To Geeks.

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


1 package net.sf.saxon.instruct;
2 import net.sf.saxon.Err;
3 import net.sf.saxon.event.ReceiverOptions;
4 import net.sf.saxon.event.SequenceReceiver;
5 import net.sf.saxon.expr.*;
6 import net.sf.saxon.om.Item;
7 import net.sf.saxon.om.NamePool;
8 import net.sf.saxon.om.Orphan;
9 import net.sf.saxon.pattern.NodeKindTest;
10 import net.sf.saxon.style.StandardNames;
11 import net.sf.saxon.trans.StaticError;
12 import net.sf.saxon.trans.XPathException;
13 import net.sf.saxon.type.*;
14 import net.sf.saxon.value.StringValue;
15 import net.sf.saxon.value.Value;
16 import net.sf.saxon.value.Whitespace;
17
18 import java.io.PrintStream JavaDoc;
19
20 /**
21 * An xsl:value-of element in the stylesheet. <br>
22 * The xsl:value-of element takes attributes:<ul>
23 * <li>a mandatory attribute select="expression".
24 * This must be a valid String expression</li>
25 * <li>an optional disable-output-escaping attribute, value "yes" or "no"</li>
26 * <li>an optional separator attribute. This is handled at compile-time: if the separator attribute
27 * is present, the select expression passed in here will be a call to the string-join() function.</li>
28 * </ul>
29 */

30
31 public final class ValueOf extends SimpleNodeConstructor {
32
33     private int options;
34     private boolean isNumberingInstruction = false; // set to true if generated by xsl:number
35
private boolean noNodeIfEmpty;
36
37     public ValueOf(Expression select, boolean disable, boolean noNodeIfEmpty) {
38         this.select = select;
39         this.options = (disable ? ReceiverOptions.DISABLE_ESCAPING : 0);
40         this.noNodeIfEmpty = noNodeIfEmpty;
41         adoptChildExpression(select);
42
43         // If value is fixed, test whether there are any special characters that might need to be
44
// escaped when the time comes for serialization
45
if (select instanceof StringValue) {
46             boolean special = false;
47             CharSequence JavaDoc val = ((StringValue)select).getStringValueCS();
48             for (int k=0; k<val.length(); k++) {
49                 char c = val.charAt(k);
50                 if ((int)c<33 || (int)c>126 ||
51                          c=='<' || c=='>' || c=='&') {
52                     special = true;
53                     break;
54                  }
55             }
56             if (!special) {
57                 this.options |= ReceiverOptions.NO_SPECIAL_CHARS;
58             }
59         }
60     }
61
62     /**
63      * Indicate that this is really an xsl:nunber instruction
64      */

65
66     public void setIsNumberingInstruction() {
67         isNumberingInstruction = true;
68     }
69
70     /**
71     * Get the name of this instruction for diagnostic and tracing purposes
72     */

73
74     public int getInstructionNameCode() {
75         if (isNumberingInstruction) {
76             return StandardNames.XSL_NUMBER;
77         } else if (select instanceof StringValue) {
78             return StandardNames.XSL_TEXT;
79         } else {
80             return StandardNames.XSL_VALUE_OF;
81         }
82     }
83
84     /**
85     * Offer promotion for subexpressions. The offer will be accepted if the subexpression
86     * is not dependent on the factors (e.g. the context item) identified in the PromotionOffer.
87     * By default the offer is not accepted - this is appropriate in the case of simple expressions
88     * such as constant values and variable references where promotion would give no performance
89     * advantage. This method is always called at compile time.
90     *
91     * @param offer details of the offer, for example the offer to move
92     * expressions that don't depend on the context to an outer level in
93     * the containing expression
94     * @exception XPathException if any error is detected
95     */

96
97     protected void promoteInst(PromotionOffer offer) throws XPathException {
98         super.promoteInst(offer);
99     }
100
101     public ItemType getItemType() {
102         return NodeKindTest.TEXT;
103     }
104
105     public int computeCardinality() {
106         if (noNodeIfEmpty) {
107             return StaticProperty.ALLOWS_ZERO_OR_ONE;
108         } else {
109             return StaticProperty.EXACTLY_ONE;
110         }
111     }
112
113     public void localTypeCheck(StaticContext env, ItemType contextItemType) {
114
115     }
116
117     /**
118       * Check statically that the results of the expression are capable of constructing the content
119       * of a given schema type.
120       *
121       * @param parentType The schema type
122       * @param env the static context
123       * @param whole
124       * @throws net.sf.saxon.trans.XPathException
125       * if the expression doesn't match the required content type
126       */

127
128      public void checkPermittedContents(SchemaType parentType, StaticContext env, boolean whole) throws XPathException {
129          // if the expression is a constant value, check that it is valid for the type
130
if (select instanceof Value) {
131              SimpleType stype = null;
132              if (parentType instanceof SimpleType && whole) {
133                  stype = (SimpleType)parentType;
134              } else if (parentType instanceof ComplexType && ((ComplexType)parentType).isSimpleContent()) {
135                  stype = ((ComplexType)parentType).getSimpleContentType();
136              }
137              if (whole && stype != null && !stype.isNamespaceSensitive()) {
138                         // Can't validate namespace-sensitive content statically
139
XPathException err = stype.validateContent(((Value)select).getStringValue(), null, env.getConfiguration());
140                  if (err != null) {
141                      err.setLocator(this);
142                      throw err;
143                  }
144                  return;
145              }
146              if (parentType instanceof ComplexType &&
147                      !((ComplexType)parentType).isSimpleContent() &&
148                      !((ComplexType)parentType).isMixedContent() &&
149                      !Whitespace.isWhite(((Value)select).getStringValue())) {
150                  StaticError err = new StaticError("Complex type " + parentType.getDescription() +
151                          " does not allow text content " +
152                          Err.wrap(((Value)select).getStringValue()));
153                  err.setLocator(this);
154                  err.setIsTypeError(true);
155                  throw err;
156              }
157          }
158      }
159
160     public TailCall processLeavingTail(XPathContext context) throws XPathException {
161         SequenceReceiver out = context.getReceiver();
162         Item item = select.evaluateItem(context);
163         if (item != null) {
164             out.characters(item.getStringValueCS(), locationId, options);
165         }
166         return null;
167     }
168
169     public Item evaluateItem(XPathContext context) throws XPathException {
170         try {
171             CharSequence JavaDoc val;
172             Item item = select.evaluateItem(context);
173             if (item == null) {
174                 if (noNodeIfEmpty) {
175                     return null;
176                 } else {
177                     val = "";
178                 }
179             } else {
180                 val = item.getStringValueCS();
181             }
182             Orphan o = new Orphan(context.getController().getConfiguration());
183             o.setNodeKind(Type.TEXT);
184             o.setStringValue(val);
185             return o;
186         } catch (XPathException err) {
187             if (err.getLocator() == null) {
188                 err.setLocator(this);
189             }
190             throw err;
191         }
192     }
193
194     /**
195      * Display this instruction as an expression, for diagnostics
196      */

197
198     public void display(int level, NamePool pool, PrintStream JavaDoc out) {
199         out.println(ExpressionTool.indent(level) + "value-of");
200         select.display(level+1, pool, out);
201     }
202 }
203
204 //
205
// The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
206
// you may not use this file except in compliance with the License. You may obtain a copy of the
207
// License at http://www.mozilla.org/MPL/
208
//
209
// Software distributed under the License is distributed on an "AS IS" basis,
210
// WITHOUT WARRANTY OF ANY KIND, either express or implied.
211
// See the License for the specific language governing rights and limitations under the License.
212
//
213
// The Original Code is: all this file.
214
//
215
// The Initial Developer of the Original Code is Michael H. Kay.
216
//
217
// Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
218
//
219
// Contributor(s): none.
220
//
221
Popular Tags