1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements. See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership. The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the  "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 /*
19  * $Id: ElemValueOf.java 468643 2006-10-28 06:56:03Z minchau $
20  */
21 package org.apache.xalan.templates;
22 
23 import javax.xml.transform.TransformerException;
24 
25 import org.apache.xalan.res.XSLTErrorResources;
26 import org.apache.xalan.transformer.TransformerImpl;
27 import org.apache.xml.dtm.DTM;
28 import org.apache.xml.serializer.SerializationHandler;
29 import org.apache.xpath.Expression;
30 import org.apache.xpath.XPath;
31 import org.apache.xpath.XPathContext;
32 import org.apache.xpath.objects.XObject;
33 import org.xml.sax.SAXException;
34 
35 /**
36  * Implement xsl:value-of.
37  * <pre>
38  * <!ELEMENT xsl:value-of EMPTY>
39  * <!ATTLIST xsl:value-of
40  *   select %expr; #REQUIRED
41  *   disable-output-escaping (yes|no) "no"
42  * >
43  * </pre>
44  * @see <a href="http://www.w3.org/TR/xslt#value-of">value-of in XSLT Specification</a>
45  * @xsl.usage advanced
46  */
47 public class ElemValueOf extends ElemTemplateElement
48 {
49     static final long serialVersionUID = 3490728458007586786L;
50 
51   /**
52    * The select expression to be executed.
53    * @serial
54    */
55   private XPath m_selectExpression = null;
56 
57   /**
58    * True if the pattern is a simple ".".
59    * @serial
60    */
61   private boolean m_isDot = false;
62 
63   /**
64    * Set the "select" attribute.
65    * The required select attribute is an expression; this expression
66    * is evaluated and the resulting object is converted to a
67    * string as if by a call to the string function.
68    *
69    * @param v The value to set for the "select" attribute.
70    */
setSelect(XPath v)71   public void setSelect(XPath v)
72   {
73 
74     if (null != v)
75     {
76       String s = v.getPatternString();
77 
78       m_isDot = (null != s) && s.equals(".");
79     }
80 
81     m_selectExpression = v;
82   }
83 
84   /**
85    * Get the "select" attribute.
86    * The required select attribute is an expression; this expression
87    * is evaluated and the resulting object is converted to a
88    * string as if by a call to the string function.
89    *
90    * @return The value of the "select" attribute.
91    */
getSelect()92   public XPath getSelect()
93   {
94     return m_selectExpression;
95   }
96 
97   /**
98    * Tells if this element should disable escaping.
99    * @serial
100    */
101   private boolean m_disableOutputEscaping = false;
102 
103   /**
104    * Set the "disable-output-escaping" attribute.
105    * Normally, the xml output method escapes & and < (and
106    * possibly other characters) when outputting text nodes.
107    * This ensures that the output is well-formed XML. However,
108    * it is sometimes convenient to be able to produce output
109    * that is almost, but not quite well-formed XML; for
110    * example, the output may include ill-formed sections
111    * which are intended to be transformed into well-formed
112    * XML by a subsequent non-XML aware process. For this reason,
113    * XSLT provides a mechanism for disabling output escaping.
114    * An xsl:value-of or xsl:text element may have a
115    * disable-output-escaping attribute; the allowed values
116    * are yes or no; the default is no; if the value is yes,
117    * then a text node generated by instantiating the xsl:value-of
118    * or xsl:text element should be output without any escaping.
119    * @see <a href="http://www.w3.org/TR/xslt#disable-output-escaping">disable-output-escaping in XSLT Specification</a>
120    *
121    * @param v The value to set for the "disable-output-escaping" attribute.
122    */
setDisableOutputEscaping(boolean v)123   public void setDisableOutputEscaping(boolean v)
124   {
125     m_disableOutputEscaping = v;
126   }
127 
128   /**
129    * Get the "disable-output-escaping" attribute.
130    * Normally, the xml output method escapes & and < (and
131    * possibly other characters) when outputting text nodes.
132    * This ensures that the output is well-formed XML. However,
133    * it is sometimes convenient to be able to produce output
134    * that is almost, but not quite well-formed XML; for
135    * example, the output may include ill-formed sections
136    * which are intended to be transformed into well-formed
137    * XML by a subsequent non-XML aware process. For this reason,
138    * XSLT provides a mechanism for disabling output escaping.
139    * An xsl:value-of or xsl:text element may have a
140    * disable-output-escaping attribute; the allowed values
141    * are yes or no; the default is no; if the value is yes,
142    * then a text node generated by instantiating the xsl:value-of
143    * or xsl:text element should be output without any escaping.
144    * @see <a href="http://www.w3.org/TR/xslt#disable-output-escaping">disable-output-escaping in XSLT Specification</a>
145    *
146    * @return The value of the "disable-output-escaping" attribute.
147    */
getDisableOutputEscaping()148   public boolean getDisableOutputEscaping()
149   {
150     return m_disableOutputEscaping;
151   }
152 
153   /**
154    * Get an integer representation of the element type.
155    *
156    * @return An integer representation of the element, defined in the
157    *     Constants class.
158    * @see org.apache.xalan.templates.Constants
159    */
getXSLToken()160   public int getXSLToken()
161   {
162     return Constants.ELEMNAME_VALUEOF;
163   }
164 
165   /**
166    * This function is called after everything else has been
167    * recomposed, and allows the template to set remaining
168    * values that may be based on some other property that
169    * depends on recomposition.
170    *
171    * NEEDSDOC @param sroot
172    *
173    * @throws TransformerException
174    */
compose(StylesheetRoot sroot)175   public void compose(StylesheetRoot sroot) throws TransformerException
176   {
177 
178     super.compose(sroot);
179 
180     java.util.Vector vnames = sroot.getComposeState().getVariableNames();
181 
182     if (null != m_selectExpression)
183       m_selectExpression.fixupVariables(
184         vnames, sroot.getComposeState().getGlobalsSize());
185   }
186 
187   /**
188    * Return the node name.
189    *
190    * @return The node name
191    */
getNodeName()192   public String getNodeName()
193   {
194     return Constants.ELEMNAME_VALUEOF_STRING;
195   }
196 
197   /**
198    * Execute the string expression and copy the text to the
199    * result tree.
200    * The required select attribute is an expression; this expression
201    * is evaluated and the resulting object is converted to a string
202    * as if by a call to the string function. The string specifies
203    * the string-value of the created text node. If the string is
204    * empty, no text node will be created. The created text node will
205    * be merged with any adjacent text nodes.
206    * @see <a href="http://www.w3.org/TR/xslt#value-of">value-of in XSLT Specification</a>
207    *
208    * @param transformer non-null reference to the the current transform-time state.
209    *
210    * @throws TransformerException
211    */
execute(TransformerImpl transformer)212   public void execute(TransformerImpl transformer) throws TransformerException
213   {
214 
215     XPathContext xctxt = transformer.getXPathContext();
216     SerializationHandler rth = transformer.getResultTreeHandler();
217 
218     try
219     {
220       // Optimize for "."
221         xctxt.pushNamespaceContext(this);
222 
223         int current = xctxt.getCurrentNode();
224 
225         xctxt.pushCurrentNodeAndExpression(current, current);
226 
227         if (m_disableOutputEscaping)
228           rth.processingInstruction(
229             javax.xml.transform.Result.PI_DISABLE_OUTPUT_ESCAPING, "");
230 
231         try
232         {
233           Expression expr = m_selectExpression.getExpression();
234 
235             expr.executeCharsToContentHandler(xctxt, rth);
236         }
237         finally
238         {
239           if (m_disableOutputEscaping)
240             rth.processingInstruction(
241               javax.xml.transform.Result.PI_ENABLE_OUTPUT_ESCAPING, "");
242 
243           xctxt.popNamespaceContext();
244           xctxt.popCurrentNodeAndExpression();
245         }
246     }
247     catch (SAXException se)
248     {
249       throw new TransformerException(se);
250     }
251     catch (RuntimeException re) {
252     	TransformerException te = new TransformerException(re);
253     	te.setLocator(this);
254     	throw te;
255     }
256   }
257 
258   /**
259    * Add a child to the child list.
260    *
261    * @param newChild Child to add to children list
262    *
263    * @return Child just added to children list
264    *
265    * @throws DOMException
266    */
appendChild(ElemTemplateElement newChild)267   public ElemTemplateElement appendChild(ElemTemplateElement newChild)
268   {
269 
270     error(XSLTErrorResources.ER_CANNOT_ADD,
271           new Object[]{ newChild.getNodeName(),
272                         this.getNodeName() });  //"Can not add " +((ElemTemplateElement)newChild).m_elemName +
273 
274     //" to " + this.m_elemName);
275     return null;
276   }
277 
278   /**
279    * Call the children visitors.
280    * @param visitor The visitor whose appropriate method will be called.
281    */
callChildVisitors(XSLTVisitor visitor, boolean callAttrs)282   protected void callChildVisitors(XSLTVisitor visitor, boolean callAttrs)
283   {
284   	if(callAttrs)
285   		m_selectExpression.getExpression().callVisitors(m_selectExpression, visitor);
286     super.callChildVisitors(visitor, callAttrs);
287   }
288 
289 }
290