Home | History | Annotate | Download | only in templates
      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: ElemPI.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.utils.XML11Char;
     28 import org.apache.xpath.XPathContext;
     29 
     30 /**
     31  * Implement xsl:processing-instruction.
     32  * <pre>
     33  * <!ELEMENT xsl:processing-instruction %char-template;>
     34  * <!ATTLIST xsl:processing-instruction
     35  *   name %avt; #REQUIRED
     36  *   %space-att;
     37  * >
     38  * </pre>
     39  * @see <a href="http://www.w3.org/TR/xslt#section-Creating-Processing-Instructions">section-Creating-Processing-Instructions in XSLT Specification</a>
     40  * @xsl.usage advanced
     41  */
     42 public class ElemPI extends ElemTemplateElement
     43 {
     44     static final long serialVersionUID = 5621976448020889825L;
     45 
     46   /**
     47    * The xsl:processing-instruction element has a required name
     48    * attribute that specifies the name of the processing instruction node.
     49    * The value of the name attribute is interpreted as an
     50    * attribute value template.
     51    * @serial
     52    */
     53   private AVT m_name_atv = null;
     54 
     55   /**
     56    * Set the "name" attribute.
     57    * DJD
     58    *
     59    * @param v Value for the name attribute
     60    */
     61   public void setName(AVT v)
     62   {
     63     m_name_atv = v;
     64   }
     65 
     66   /**
     67    * Get the "name" attribute.
     68    * DJD
     69    *
     70    * @return The value of the "name" attribute
     71    */
     72   public AVT getName()
     73   {
     74     return m_name_atv;
     75   }
     76 
     77   /**
     78    * This function is called after everything else has been
     79    * recomposed, and allows the template to set remaining
     80    * values that may be based on some other property that
     81    * depends on recomposition.
     82    */
     83   public void compose(StylesheetRoot sroot) throws TransformerException
     84   {
     85     super.compose(sroot);
     86     java.util.Vector vnames = sroot.getComposeState().getVariableNames();
     87     if(null != m_name_atv)
     88       m_name_atv.fixupVariables(vnames, sroot.getComposeState().getGlobalsSize());
     89   }
     90 
     91 
     92 
     93   /**
     94    * Get an int constant identifying the type of element.
     95    * @see org.apache.xalan.templates.Constants
     96    *
     97    * @return The token ID for the element
     98    */
     99   public int getXSLToken()
    100   {
    101     return Constants.ELEMNAME_PI;
    102   }
    103 
    104   /**
    105    * Return the node name.
    106    *
    107    * @return The element's name
    108    */
    109   public String getNodeName()
    110   {
    111     return Constants.ELEMNAME_PI_STRING;
    112   }
    113 
    114   /**
    115    * Create a processing instruction in the result tree.
    116    * The content of the xsl:processing-instruction element is a
    117    * template for the string-value of the processing instruction node.
    118    * @see <a href="http://www.w3.org/TR/xslt#section-Creating-Processing-Instructions">section-Creating-Processing-Instructions in XSLT Specification</a>
    119    *
    120    * @param transformer non-null reference to the the current transform-time state.
    121    *
    122    * @throws TransformerException
    123    */
    124   public void execute(
    125           TransformerImpl transformer)
    126             throws TransformerException
    127   {
    128 
    129     XPathContext xctxt = transformer.getXPathContext();
    130     int sourceNode = xctxt.getCurrentNode();
    131 
    132     String piName = m_name_atv == null ? null : m_name_atv.evaluate(xctxt, sourceNode, this);
    133 
    134     // Ignore processing instruction if name is null
    135     if (piName == null) return;
    136 
    137     if (piName.equalsIgnoreCase("xml"))
    138     {
    139      	transformer.getMsgMgr().warn(
    140         this, XSLTErrorResources.WG_PROCESSINGINSTRUCTION_NAME_CANT_BE_XML,
    141               new Object[]{ Constants.ATTRNAME_NAME, piName });
    142 		return;
    143     }
    144 
    145     // Only check if an avt was used (ie. this wasn't checked at compose time.)
    146     // Ignore processing instruction, if invalid
    147     else if ((!m_name_atv.isSimple()) && (!XML11Char.isXML11ValidNCName(piName)))
    148     {
    149      	transformer.getMsgMgr().warn(
    150         this, XSLTErrorResources.WG_PROCESSINGINSTRUCTION_NOTVALID_NCNAME,
    151               new Object[]{ Constants.ATTRNAME_NAME, piName });
    152 		return;
    153     }
    154 
    155     // Note the content model is:
    156     // <!ENTITY % instructions "
    157     // %char-instructions;
    158     // | xsl:processing-instruction
    159     // | xsl:comment
    160     // | xsl:element
    161     // | xsl:attribute
    162     // ">
    163     String data = transformer.transformToString(this);
    164 
    165     try
    166     {
    167       transformer.getResultTreeHandler().processingInstruction(piName, data);
    168     }
    169     catch(org.xml.sax.SAXException se)
    170     {
    171       throw new TransformerException(se);
    172     }
    173   }
    174 
    175   /**
    176    * Add a child to the child list.
    177    *
    178    * @param newChild Child to add to child list
    179    *
    180    * @return The child just added to the child list
    181    *
    182    * @throws DOMException
    183    */
    184   public ElemTemplateElement appendChild(ElemTemplateElement newChild)
    185   {
    186 
    187     int type = ((ElemTemplateElement) newChild).getXSLToken();
    188 
    189     switch (type)
    190     {
    191 
    192     // char-instructions
    193     case Constants.ELEMNAME_TEXTLITERALRESULT :
    194     case Constants.ELEMNAME_APPLY_TEMPLATES :
    195     case Constants.ELEMNAME_APPLY_IMPORTS :
    196     case Constants.ELEMNAME_CALLTEMPLATE :
    197     case Constants.ELEMNAME_FOREACH :
    198     case Constants.ELEMNAME_VALUEOF :
    199     case Constants.ELEMNAME_COPY_OF :
    200     case Constants.ELEMNAME_NUMBER :
    201     case Constants.ELEMNAME_CHOOSE :
    202     case Constants.ELEMNAME_IF :
    203     case Constants.ELEMNAME_TEXT :
    204     case Constants.ELEMNAME_COPY :
    205     case Constants.ELEMNAME_VARIABLE :
    206     case Constants.ELEMNAME_MESSAGE :
    207 
    208       // instructions
    209       // case Constants.ELEMNAME_PI:
    210       // case Constants.ELEMNAME_COMMENT:
    211       // case Constants.ELEMNAME_ELEMENT:
    212       // case Constants.ELEMNAME_ATTRIBUTE:
    213       break;
    214     default :
    215       error(XSLTErrorResources.ER_CANNOT_ADD,
    216             new Object[]{ newChild.getNodeName(),
    217                           this.getNodeName() });  //"Can not add " +((ElemTemplateElement)newChild).m_elemName +
    218 
    219     //" to " + this.m_elemName);
    220     }
    221 
    222     return super.appendChild(newChild);
    223   }
    224 }
    225