Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: org/apache/xalan/templates/ElemExtensionCall.java


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: ElemExtensionCall.java,v 1.38 2004/02/16 20:32:32 minchau Exp $
18   */
19  package org.apache.xalan.templates;
20  
21  import javax.xml.transform.TransformerException;
22  
23  import org.apache.xalan.extensions.ExtensionHandler;
24  import org.apache.xalan.extensions.ExtensionsTable;
25  import org.apache.xalan.res.XSLMessages;
26  import org.apache.xalan.res.XSLTErrorResources;
27  import org.apache.xalan.transformer.TransformerImpl;
28  import org.apache.xpath.XPathContext;
29  import org.xml.sax.SAXException;
30  
31  /**
32   * Implement an extension element.
33   * @see <a href="http://www.w3.org/TR/xslt#extension-element">extension-element in XSLT Specification</a>
34   * @xsl.usage advanced
35   */
36  public class ElemExtensionCall extends ElemLiteralResult
37  {
38  
39    /** The Namespace URI for this extension call element.
40     *  @serial          */
41    String m_extns;
42  
43    /** Language used by extension.
44     *  @serial          */
45    String m_lang;
46  
47    /** URL pointing to extension.
48     *  @serial          */
49    String m_srcURL;
50  
51    /** Source for script.
52     *  @serial          */
53    String m_scriptSrc;
54  
55    /** Declaration for Extension element. 
56     *  @serial          */
57    ElemExtensionDecl m_decl = null;
58  
59    /**
60     * Get an int constant identifying the type of element.
61     * @see org.apache.xalan.templates.Constants
62     *
63     *@return The token ID for this element
64     */
65    public int getXSLToken()
66    {
67      return Constants.ELEMNAME_EXTENSIONCALL;
68    }
69  
70    /**
71     * Return the node name.
72     *
73     * @return The element's name
74     */
75  
76    // public String getNodeName()
77    // {
78    // TODO: Need prefix.
79    // return localPart;
80    // }
81  
82    /**
83     * This function is called after everything else has been
84     * recomposed, and allows the template to set remaining
85     * values that may be based on some other property that
86     * depends on recomposition.
87     */
88    public void compose(StylesheetRoot sroot) throws TransformerException
89    {
90      super.compose(sroot);
91      m_extns = this.getNamespace();   
92      m_decl = getElemExtensionDecl(sroot, m_extns);
93      // Register the extension namespace if the extension does not have
94      // an ElemExtensionDecl ("component").
95      if (m_decl == null)
96        sroot.getExtensionNamespacesManager().registerExtension(m_extns);
97    }
98   
99    /**
100    * Return the ElemExtensionDecl for this extension element 
101    *
102    *
103    * @param stylesheet Stylesheet root associated with this extension element
104    * @param namespace Namespace associated with this extension element
105    *
106    * @return the ElemExtensionDecl for this extension element. 
107    */
108   private ElemExtensionDecl getElemExtensionDecl(StylesheetRoot stylesheet,
109           String namespace)
110   {
111 
112     ElemExtensionDecl decl = null;
113     int n = stylesheet.getGlobalImportCount();
114 
115     for (int i = 0; i < n; i++)
116     {
117       Stylesheet imported = stylesheet.getGlobalImport(i);
118 
119       for (ElemTemplateElement child = imported.getFirstChildElem();
120               child != null; child = child.getNextSiblingElem())
121       {
122         if (Constants.ELEMNAME_EXTENSIONDECL == child.getXSLToken())
123         {
124           decl = (ElemExtensionDecl) child;
125 
126           String prefix = decl.getPrefix();
127           String declNamespace = child.getNamespaceForPrefix(prefix);
128 
129           if (namespace.equals(declNamespace))
130           {
131             return decl;
132           }
133         }
134       }
135     }
136 
137     return null;
138   }
139   
140   /**
141    * Execute the fallbacks when an extension is not available.
142    *
143    * @param transformer non-null reference to the the current transform-time state.
144    * @param sourceNode non-null reference to the <a href="http://www.w3.org/TR/xslt#dt-current-node">current source node</a>.
145    * @param mode reference, which may be null, to the <a href="http://www.w3.org/TR/xslt#modes">current mode</a>.
146    *
147    * @throws TransformerException
148    */
149   private void executeFallbacks(
150           TransformerImpl transformer)
151             throws TransformerException
152   {
153     for (ElemTemplateElement child = m_firstChild; child != null;
154              child = child.m_nextSibling)
155     {
156       if (child.getXSLToken() == Constants.ELEMNAME_FALLBACK)
157       {
158         try
159         {
160           transformer.pushElemTemplateElement(child);
161           ((ElemFallback) child).executeFallback(transformer);
162         }
163         finally
164         {
165           transformer.popElemTemplateElement();
166         }
167       }
168     }
169 
170   }
171   
172   /**
173    * Return true if this extension element has a <xsl:fallback> child element.
174    *
175    * @return true if this extension element has a <xsl:fallback> child element.
176    */
177   private boolean hasFallbackChildren()
178   {
179     for (ElemTemplateElement child = m_firstChild; child != null;
180              child = child.m_nextSibling)
181     {
182       if (child.getXSLToken() == Constants.ELEMNAME_FALLBACK)
183         return true;
184     }
185     
186     return false;
187   }
188 
189 
190   /**
191    * Execute an extension.
192    *
193    * @param transformer non-null reference to the the current transform-time state.
194    * @param sourceNode non-null reference to the <a href="http://www.w3.org/TR/xslt#dt-current-node">current source node</a>.
195    * @param mode reference, which may be null, to the <a href="http://www.w3.org/TR/xslt#modes">current mode</a>.
196    *
197    * @throws TransformerException
198    */
199   public void execute(TransformerImpl transformer)
200             throws TransformerException
201   {
202 
203   if (TransformerImpl.S_DEBUG)
204     transformer.getTraceManager().fireTraceEvent(this);
205     try
206     {
207       transformer.getResultTreeHandler().flushPending();
208 
209       ExtensionsTable etable = transformer.getExtensionsTable();
210       ExtensionHandler nsh = etable.get(m_extns);
211 
212       if (null == nsh)
213       {
214         if (hasFallbackChildren())
215         {
216           executeFallbacks(transformer);
217         }
218         else
219         {
220     TransformerException te = new TransformerException(XSLMessages.createMessage(
221       XSLTErrorResources.ER_CALL_TO_EXT_FAILED, new Object[]{getNodeName()}));
222     transformer.getErrorListener().fatalError(te);
223         }
224         
225         return;
226       }
227 
228       try
229       {
230         nsh.processElement(this.getLocalName(), this, transformer,
231                            getStylesheet(), this);
232       }
233       catch (Exception e)
234       {
235 
236   if (hasFallbackChildren())
237     executeFallbacks(transformer);
238   else
239   {
240           if(e instanceof TransformerException)
241           {
242             TransformerException te = (TransformerException)e;
243             if(null == te.getLocator())
244               te.setLocator(this);
245             
246             transformer.getErrorListener().fatalError(te);            
247           }
248           else if (e instanceof RuntimeException)
249           {
250             transformer.getErrorListener().fatalError(new TransformerException(e));
251           }
252           else
253           {
254             transformer.getErrorListener().warning(new TransformerException(e));
255           }
256         }
257       }
258     }
259     catch(TransformerException e)
260     {
261       transformer.getErrorListener().fatalError(e);
262     }
263     catch(SAXException se) {
264       throw new TransformerException(se);
265     }
266   if (TransformerImpl.S_DEBUG)
267     transformer.getTraceManager().fireTraceEndEvent(this);
268   }
269 
270   /**
271    * Return the raw value of the attribute.
272    *
273    * @param rawName Raw name of the attribute to get
274    *
275    * @return the raw value of the attribute or null if not found
276    */
277   public String getAttribute(String rawName)
278   {
279 
280     AVT avt = getLiteralResultAttribute(rawName);
281 
282     if ((null != avt) && avt.getRawName().equals(rawName))
283     {
284       return avt.getSimpleString();
285     }
286 
287     return null;
288   }
289 
290   /**
291    * Return the value of the attribute interpreted as an Attribute
292    * Value Template (in other words, you can use curly expressions
293    * such as href="http://{website}".
294    *
295    * @param rawName Raw name of the attribute to get
296    * @param sourceNode non-null reference to the <a href="http://www.w3.org/TR/xslt#dt-current-node">current source node</a>.
297    * @param transformer non-null reference to the the current transform-time state.
298    *
299    * @return the value of the attribute
300    *
301    * @throws TransformerException
302    */
303   public String getAttribute(
304           String rawName, org.w3c.dom.Node sourceNode, TransformerImpl transformer)
305             throws TransformerException
306   {
307 
308     AVT avt = getLiteralResultAttribute(rawName);
309 
310     if ((null != avt) && avt.getRawName().equals(rawName))
311     {
312       XPathContext xctxt = transformer.getXPathContext();
313 
314       return avt.evaluate(xctxt, 
315             xctxt.getDTMHandleFromNode(sourceNode), 
316             this);
317     }
318 
319     return null;
320   }
321   
322   /**
323    * Accept a visitor and call the appropriate method 
324    * for this class.
325    * 
326    * @param visitor The visitor whose appropriate method will be called.
327    * @return true if the children of the object should be visited.
328    */
329   protected boolean accept(XSLTVisitor visitor)
330   {
331     return visitor.visitExtensionElement(this);
332   }
333 
334   
335 }