KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > xalan > templates > ElemElement


1 /*
2  * Copyright 1999-2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 /*
17  * $Id: ElemElement.java,v 1.36 2004/02/24 03:55:47 zongaro Exp $
18  */

19 package org.apache.xalan.templates;
20
21 import javax.xml.transform.TransformerException JavaDoc;
22
23 import org.apache.xalan.res.XSLTErrorResources;
24 import org.apache.xalan.transformer.TransformerImpl;
25 import org.apache.xml.serializer.SerializationHandler;
26 import org.apache.xml.utils.QName;
27 import org.apache.xml.utils.XMLChar;
28 import org.apache.xpath.XPathContext;
29 import org.xml.sax.SAXException JavaDoc;
30
31 /**
32  * Implement xsl:element
33  * <pre>
34  * <!ELEMENT xsl:element %template;>
35  * <!ATTLIST xsl:element
36  * name %avt; #REQUIRED
37  * namespace %avt; #IMPLIED
38  * use-attribute-sets %qnames; #IMPLIED
39  * %space-att;
40  * >
41  * </pre>
42  * @see <a HREF="http://www.w3.org/TR/xslt#section-Creating-Elements-with-xsl:element">XXX in XSLT Specification</a>
43  * @xsl.usage advanced
44  */

45 public class ElemElement extends ElemUse
46 {
47
48   /**
49    * The name attribute is interpreted as an attribute value template.
50    * It is an error if the string that results from instantiating the
51    * attribute value template is not a QName.
52    * @serial
53    */

54   protected AVT m_name_avt = null;
55
56   /**
57    * Set the "name" attribute.
58    * The name attribute is interpreted as an attribute value template.
59    * It is an error if the string that results from instantiating the
60    * attribute value template is not a QName.
61    *
62    * @param v Name attribute to set for this element
63    */

64   public void setName(AVT v)
65   {
66     m_name_avt = v;
67   }
68
69   /**
70    * Get the "name" attribute.
71    * The name attribute is interpreted as an attribute value template.
72    * It is an error if the string that results from instantiating the
73    * attribute value template is not a QName.
74    *
75    * @return Name attribute for this element
76    */

77   public AVT getName()
78   {
79     return m_name_avt;
80   }
81
82   /**
83    * If the namespace attribute is present, then it also is interpreted
84    * as an attribute value template. The string that results from
85    * instantiating the attribute value template should be a URI reference.
86    * It is not an error if the string is not a syntactically legal URI reference.
87    * @serial
88    */

89   protected AVT m_namespace_avt = null;
90
91   /**
92    * Set the "namespace" attribute.
93    * If the namespace attribute is present, then it also is interpreted
94    * as an attribute value template. The string that results from
95    * instantiating the attribute value template should be a URI reference.
96    * It is not an error if the string is not a syntactically legal URI reference.
97    *
98    * @param v NameSpace attribute to set for this element
99    */

100   public void setNamespace(AVT v)
101   {
102     m_namespace_avt = v;
103   }
104
105   /**
106    * Get the "namespace" attribute.
107    * If the namespace attribute is present, then it also is interpreted
108    * as an attribute value template. The string that results from
109    * instantiating the attribute value template should be a URI reference.
110    * It is not an error if the string is not a syntactically legal URI reference.
111    *
112    * @return Namespace attribute for this element
113    */

114   public AVT getNamespace()
115   {
116     return m_namespace_avt;
117   }
118   
119   /**
120    * This function is called after everything else has been
121    * recomposed, and allows the template to set remaining
122    * values that may be based on some other property that
123    * depends on recomposition.
124    */

125   public void compose(StylesheetRoot sroot) throws TransformerException JavaDoc
126   {
127     super.compose(sroot);
128     
129     StylesheetRoot.ComposeState cstate = sroot.getComposeState();
130     java.util.Vector JavaDoc vnames = cstate.getVariableNames();
131     if(null != m_name_avt)
132       m_name_avt.fixupVariables(vnames, cstate.getGlobalsSize());
133     if(null != m_namespace_avt)
134       m_namespace_avt.fixupVariables(vnames, cstate.getGlobalsSize());
135   }
136
137
138   /**
139    * Get an int constant identifying the type of element.
140    * @see org.apache.xalan.templates.Constants
141    *
142    * @return The token ID for this element
143    */

144   public int getXSLToken()
145   {
146     return Constants.ELEMNAME_ELEMENT;
147   }
148
149   /**
150    * Return the node name.
151    *
152    * @return This element's name
153    */

154   public String JavaDoc getNodeName()
155   {
156     return Constants.ELEMNAME_ELEMENT_STRING;
157   }
158    
159   /**
160    * Resolve the namespace into a prefix. Meant to be
161    * overidded by elemAttribute if this class is derived.
162    *
163    * @param rhandler The current result tree handler.
164    * @param prefix The probable prefix if already known.
165    * @param nodeNamespace The namespace.
166    *
167    * @return The prefix to be used.
168    */

169   protected String JavaDoc resolvePrefix(SerializationHandler rhandler,
170                                  String JavaDoc prefix, String JavaDoc nodeNamespace)
171     throws TransformerException JavaDoc
172   {
173
174 // if (null != prefix && prefix.length() == 0)
175
// {
176
// String foundPrefix = rhandler.getPrefix(nodeNamespace);
177
//
178
// // System.out.println("nsPrefix: "+nsPrefix);
179
// if (null == foundPrefix)
180
// foundPrefix = "";
181
// }
182
return prefix;
183   }
184     
185   /**
186    * Create an element in the result tree.
187    * The xsl:element element allows an element to be created with a
188    * computed name. The expanded-name of the element to be created
189    * is specified by a required name attribute and an optional namespace
190    * attribute. The content of the xsl:element element is a template
191    * for the attributes and children of the created element.
192    *
193    * @param transformer non-null reference to the the current transform-time state.
194    *
195    * @throws TransformerException
196    */

197   public void execute(
198           TransformerImpl transformer)
199             throws TransformerException JavaDoc
200   {
201
202        if (TransformerImpl.S_DEBUG)
203          transformer.getTraceManager().fireTraceEvent(this);
204
205     SerializationHandler rhandler = transformer.getSerializationHandler();
206     XPathContext xctxt = transformer.getXPathContext();
207     int sourceNode = xctxt.getCurrentNode();
208     
209     
210     String JavaDoc nodeName = m_name_avt == null ? null : m_name_avt.evaluate(xctxt, sourceNode, this);
211
212     String JavaDoc prefix = null;
213     String JavaDoc nodeNamespace = "";
214
215     // Only validate if an AVT was used.
216
if ((nodeName != null) && (!m_name_avt.isSimple()) && (!XMLChar.isValidQName(nodeName)))
217     {
218       transformer.getMsgMgr().warn(
219         this, XSLTErrorResources.WG_ILLEGAL_ATTRIBUTE_VALUE,
220         new Object JavaDoc[]{ Constants.ATTRNAME_NAME, nodeName });
221
222       nodeName = null;
223     }
224
225     else if (nodeName != null)
226     {
227       prefix = QName.getPrefixPart(nodeName);
228
229       if (null != m_namespace_avt)
230       {
231         nodeNamespace = m_namespace_avt.evaluate(xctxt, sourceNode, this);
232         if (null == nodeNamespace ||
233             (prefix != null && prefix.length()>0 && nodeNamespace.length()== 0) )
234           transformer.getMsgMgr().error(
235               this, XSLTErrorResources.ER_NULL_URI_NAMESPACE);
236         else
237         {
238         // Determine the actual prefix that we will use for this nodeNamespace
239

240         prefix = resolvePrefix(rhandler, prefix, nodeNamespace);
241         if (null == prefix)
242           prefix = "";
243
244         if (prefix.length() > 0)
245           nodeName = (prefix + ":" + QName.getLocalPart(nodeName));
246         else
247           nodeName = QName.getLocalPart(nodeName);
248         }
249       }
250
251       // No namespace attribute was supplied. Use the namespace declarations
252
// currently in effect for the xsl:element element.
253
else
254       {
255         try
256         {
257           // Maybe temporary, until I get this worked out. test: axes59
258
nodeNamespace = getNamespaceForPrefix(prefix);
259
260           // If we get back a null nodeNamespace, that means that this prefix could
261
// not be found in the table. This is okay only for a default namespace
262
// that has never been declared.
263

264           if ( (null == nodeNamespace) && (prefix.length() == 0) )
265             nodeNamespace = "";
266           else if (null == nodeNamespace)
267           {
268             transformer.getMsgMgr().warn(
269               this, XSLTErrorResources.WG_COULD_NOT_RESOLVE_PREFIX,
270               new Object JavaDoc[]{ prefix });
271
272             nodeName = null;
273           }
274
275         }
276         catch (Exception JavaDoc ex)
277         {
278           transformer.getMsgMgr().warn(
279             this, XSLTErrorResources.WG_COULD_NOT_RESOLVE_PREFIX,
280             new Object JavaDoc[]{ prefix });
281
282           nodeName = null;
283         }
284       }
285     }
286
287     constructNode(nodeName, prefix, nodeNamespace, transformer);
288
289     if (TransformerImpl.S_DEBUG)
290       transformer.getTraceManager().fireTraceEndEvent(this);
291   }
292   
293   /**
294    * Construct a node in the result tree. This method is overloaded by
295    * xsl:attribute. At this class level, this method creates an element.
296    * If the node is null, we instantiate only the content of the node in accordance
297    * with section 7.1.2 of the XSLT 1.0 Recommendation.
298    *
299    * @param nodeName The name of the node, which may be <code>null</code>. If <code>null</code>,
300    * only the non-attribute children of this node will be processed.
301    * @param prefix The prefix for the namespace, which may be <code>null</code>.
302    * If not <code>null</code>, this prefix will be mapped and unmapped.
303    * @param nodeNamespace The namespace of the node, which may be not be <code>null</code>.
304    * @param transformer non-null reference to the the current transform-time state.
305    *
306    * @throws TransformerException
307    */

308   void constructNode(
309           String JavaDoc nodeName, String JavaDoc prefix, String JavaDoc nodeNamespace, TransformerImpl transformer)
310             throws TransformerException JavaDoc
311   {
312
313     boolean shouldAddAttrs;
314
315     try
316     {
317       SerializationHandler rhandler = transformer.getResultTreeHandler();
318
319       if (null == nodeName)
320       {
321         shouldAddAttrs = false;
322       }
323       else
324       {
325         if (null != prefix)
326         {
327           rhandler.startPrefixMapping(prefix, nodeNamespace, true);
328         }
329
330         rhandler.startElement(nodeNamespace, QName.getLocalPart(nodeName),
331                               nodeName);
332
333         super.execute(transformer);
334
335         shouldAddAttrs = true;
336       }
337
338       transformer.executeChildTemplates(this, shouldAddAttrs);
339
340       // Now end the element if name was valid
341
if (null != nodeName)
342       {
343         rhandler.endElement(nodeNamespace, QName.getLocalPart(nodeName),
344                             nodeName);
345         if (null != prefix)
346         {
347           rhandler.endPrefixMapping(prefix);
348         }
349       }
350     }
351     catch (SAXException JavaDoc se)
352     {
353       throw new TransformerException JavaDoc(se);
354     }
355   }
356   
357   /**
358    * Call the children visitors.
359    * @param visitor The visitor whose appropriate method will be called.
360    */

361   protected void callChildVisitors(XSLTVisitor visitor, boolean callAttrs)
362   {
363     if(callAttrs)
364     {
365       if(null != m_name_avt)
366         m_name_avt.callVisitors(visitor);
367         
368       if(null != m_namespace_avt)
369         m_namespace_avt.callVisitors(visitor);
370     }
371         
372     super.callChildVisitors(visitor, callAttrs);
373   }
374
375 }
376
Popular Tags