Home | History | Annotate | Download | only in processor
      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: XSLTElementDef.java 468640 2006-10-28 06:53:53Z minchau $
     20  */
     21 package org.apache.xalan.processor;
     22 
     23 import java.util.Enumeration;
     24 import java.util.Hashtable;
     25 
     26 import org.apache.xalan.templates.Constants;
     27 import org.apache.xml.utils.QName;
     28 
     29 /**
     30  * This class defines the allowed structure for an element in a XSLT stylesheet,
     31  * is meant to reflect the structure defined in http://www.w3.org/TR/xslt#dtd, and the
     32  * mapping between Xalan classes and the markup elements in the XSLT instance.
     33  * This actually represents both text nodes and elements.
     34  */
     35 public class XSLTElementDef
     36 {
     37 
     38   /**
     39    * Construct an instance of XSLTElementDef.  This must be followed by a
     40    * call to build().
     41    */
     42   XSLTElementDef(){}
     43 
     44   /**
     45    * Construct an instance of XSLTElementDef.
     46    *
     47    * @param namespace  The Namespace URI, "*", or null.
     48    * @param name The local name (without prefix), "*", or null.
     49    * @param nameAlias A potential alias for the name, or null.
     50    * @param elements An array of allowed child element defs, or null.
     51    * @param attributes An array of allowed attribute defs, or null.
     52    * @param contentHandler The element processor for this element.
     53    * @param classObject The class of the object that this element def should produce.
     54    */
     55   XSLTElementDef(XSLTSchema schema, String namespace, String name, String nameAlias,
     56                  XSLTElementDef[] elements, XSLTAttributeDef[] attributes,
     57                  XSLTElementProcessor contentHandler, Class classObject)
     58   {
     59     build(namespace, name, nameAlias, elements, attributes, contentHandler,
     60           classObject);
     61     if ( (null != namespace)
     62     &&  (namespace.equals(Constants.S_XSLNAMESPACEURL)
     63         || namespace.equals(Constants.S_BUILTIN_EXTENSIONS_URL)
     64         || namespace.equals(Constants.S_BUILTIN_OLD_EXTENSIONS_URL)))
     65     {
     66       schema.addAvailableElement(new QName(namespace, name));
     67       if(null != nameAlias)
     68         schema.addAvailableElement(new QName(namespace, nameAlias));
     69     }
     70   }
     71 
     72 	/**
     73    * Construct an instance of XSLTElementDef.
     74    *
     75    * @param namespace  The Namespace URI, "*", or null.
     76    * @param name The local name (without prefix), "*", or null.
     77    * @param nameAlias A potential alias for the name, or null.
     78    * @param elements An array of allowed child element defs, or null.
     79    * @param attributes An array of allowed attribute defs, or null.
     80    * @param contentHandler The element processor for this element.
     81    * @param classObject The class of the object that this element def should produce.
     82    * @param has_required true if this element has required elements by the XSLT specification.
     83    */
     84   XSLTElementDef(XSLTSchema schema, String namespace, String name, String nameAlias,
     85                  XSLTElementDef[] elements, XSLTAttributeDef[] attributes,
     86                  XSLTElementProcessor contentHandler, Class classObject, boolean has_required)
     87   {
     88 		this.m_has_required = has_required;
     89     build(namespace, name, nameAlias, elements, attributes, contentHandler,
     90           classObject);
     91     if ( (null != namespace)
     92     &&  (namespace.equals(Constants.S_XSLNAMESPACEURL)
     93         || namespace.equals(Constants.S_BUILTIN_EXTENSIONS_URL)
     94         || namespace.equals(Constants.S_BUILTIN_OLD_EXTENSIONS_URL)))
     95     {
     96       schema.addAvailableElement(new QName(namespace, name));
     97       if(null != nameAlias)
     98         schema.addAvailableElement(new QName(namespace, nameAlias));
     99     }
    100 
    101   }
    102 
    103 	/**
    104    * Construct an instance of XSLTElementDef.
    105    *
    106    * @param namespace  The Namespace URI, "*", or null.
    107    * @param name The local name (without prefix), "*", or null.
    108    * @param nameAlias A potential alias for the name, or null.
    109    * @param elements An array of allowed child element defs, or null.
    110    * @param attributes An array of allowed attribute defs, or null.
    111    * @param contentHandler The element processor for this element.
    112    * @param classObject The class of the object that this element def should produce.
    113    * @param has_required true if this element has required elements by the XSLT specification.
    114    * @param required true if this element is required by the XSLT specification.
    115    */
    116   XSLTElementDef(XSLTSchema schema, String namespace, String name, String nameAlias,
    117                  XSLTElementDef[] elements, XSLTAttributeDef[] attributes,
    118                  XSLTElementProcessor contentHandler, Class classObject,
    119 								 boolean has_required, boolean required)
    120   {
    121     this(schema, namespace, name,  nameAlias,
    122                  elements, attributes,
    123                  contentHandler, classObject, has_required);
    124 		this.m_required = required;
    125   }
    126 
    127 	/**
    128    * Construct an instance of XSLTElementDef.
    129    *
    130    * @param namespace  The Namespace URI, "*", or null.
    131    * @param name The local name (without prefix), "*", or null.
    132    * @param nameAlias A potential alias for the name, or null.
    133    * @param elements An array of allowed child element defs, or null.
    134    * @param attributes An array of allowed attribute defs, or null.
    135    * @param contentHandler The element processor for this element.
    136    * @param classObject The class of the object that this element def should produce.
    137    * @param has_required true if this element has required elements by the XSLT specification.
    138    * @param required true if this element is required by the XSLT specification.
    139    * @param order the order this element should appear according to the XSLT specification.
    140    * @param multiAllowed whether this element is allowed more than once
    141    */
    142   XSLTElementDef(XSLTSchema schema, String namespace, String name, String nameAlias,
    143                  XSLTElementDef[] elements, XSLTAttributeDef[] attributes,
    144                  XSLTElementProcessor contentHandler, Class classObject,
    145 								 boolean has_required, boolean required, int order,
    146 								 boolean multiAllowed)
    147   {
    148 		this(schema, namespace, name,  nameAlias,
    149                  elements, attributes,
    150                  contentHandler, classObject, has_required, required);
    151 		this.m_order = order;
    152 		this.m_multiAllowed = multiAllowed;
    153   }
    154 
    155 	/**
    156    * Construct an instance of XSLTElementDef.
    157    *
    158    * @param namespace  The Namespace URI, "*", or null.
    159    * @param name The local name (without prefix), "*", or null.
    160    * @param nameAlias A potential alias for the name, or null.
    161    * @param elements An array of allowed child element defs, or null.
    162    * @param attributes An array of allowed attribute defs, or null.
    163    * @param contentHandler The element processor for this element.
    164    * @param classObject The class of the object that this element def should produce.
    165    * @param has_required true if this element has required elements by the XSLT specification.
    166    * @param required true if this element is required by the XSLT specification.
    167    * @param has_order whether this element has ordered child elements
    168    * @param order the order this element should appear according to the XSLT specification.
    169    * @param multiAllowed whether this element is allowed more than once
    170    */
    171   XSLTElementDef(XSLTSchema schema, String namespace, String name, String nameAlias,
    172                  XSLTElementDef[] elements, XSLTAttributeDef[] attributes,
    173                  XSLTElementProcessor contentHandler, Class classObject,
    174 								 boolean has_required, boolean required, boolean has_order, int order,
    175 								 boolean multiAllowed)
    176   {
    177 		this(schema, namespace, name,  nameAlias,
    178                  elements, attributes,
    179                  contentHandler, classObject, has_required, required);
    180 		this.m_order = order;
    181 		this.m_multiAllowed = multiAllowed;
    182     this.m_isOrdered = has_order;
    183   }
    184 
    185 	/**
    186    * Construct an instance of XSLTElementDef.
    187    *
    188    * @param namespace  The Namespace URI, "*", or null.
    189    * @param name The local name (without prefix), "*", or null.
    190    * @param nameAlias A potential alias for the name, or null.
    191    * @param elements An array of allowed child element defs, or null.
    192    * @param attributes An array of allowed attribute defs, or null.
    193    * @param contentHandler The element processor for this element.
    194    * @param classObject The class of the object that this element def should produce.
    195    * @param has_order whether this element has ordered child elements
    196    * @param order the order this element should appear according to the XSLT specification.
    197    * @param multiAllowed whether this element is allowed more than once
    198    */
    199   XSLTElementDef(XSLTSchema schema, String namespace, String name, String nameAlias,
    200                  XSLTElementDef[] elements, XSLTAttributeDef[] attributes,
    201                  XSLTElementProcessor contentHandler, Class classObject,
    202 								 boolean has_order, int order, boolean multiAllowed)
    203   {
    204     this(schema, namespace, name,  nameAlias,
    205                  elements, attributes,
    206                  contentHandler, classObject,
    207 								 order, multiAllowed);
    208 		this.m_isOrdered = has_order;
    209   }
    210 
    211 	/**
    212    * Construct an instance of XSLTElementDef.
    213    *
    214    * @param namespace  The Namespace URI, "*", or null.
    215    * @param name The local name (without prefix), "*", or null.
    216    * @param nameAlias A potential alias for the name, or null.
    217    * @param elements An array of allowed child element defs, or null.
    218    * @param attributes An array of allowed attribute defs, or null.
    219    * @param contentHandler The element processor for this element.
    220    * @param classObject The class of the object that this element def should produce.
    221    * @param order the order this element should appear according to the XSLT specification.
    222    * @param multiAllowed whether this element is allowed more than once
    223    */
    224   XSLTElementDef(XSLTSchema schema, String namespace, String name, String nameAlias,
    225                  XSLTElementDef[] elements, XSLTAttributeDef[] attributes,
    226                  XSLTElementProcessor contentHandler, Class classObject,
    227 								 int order, boolean multiAllowed)
    228   {
    229     this(schema, namespace, name, nameAlias, elements, attributes, contentHandler,
    230           classObject);
    231     this.m_order = order;
    232 		this.m_multiAllowed = multiAllowed;
    233   }
    234 
    235   /**
    236    * Construct an instance of XSLTElementDef that represents text.
    237    *
    238    * @param classObject The class of the object that this element def should produce.
    239    * @param contentHandler The element processor for this element.
    240    * @param type Content type, one of T_ELEMENT, T_PCDATA, or T_ANY.
    241    */
    242   XSLTElementDef(Class classObject, XSLTElementProcessor contentHandler,
    243                  int type)
    244   {
    245 
    246     this.m_classObject = classObject;
    247     this.m_type = type;
    248 
    249     setElementProcessor(contentHandler);
    250   }
    251 
    252   /**
    253    * Construct an instance of XSLTElementDef.
    254    *
    255    * @param namespace  The Namespace URI, "*", or null.
    256    * @param name The local name (without prefix), "*", or null.
    257    * @param nameAlias A potential alias for the name, or null.
    258    * @param elements An array of allowed child element defs, or null.
    259    * @param attributes An array of allowed attribute defs, or null.
    260    * @param contentHandler The element processor for this element.
    261    * @param classObject The class of the object that this element def should produce.
    262    */
    263   void build(String namespace, String name, String nameAlias,
    264              XSLTElementDef[] elements, XSLTAttributeDef[] attributes,
    265              XSLTElementProcessor contentHandler, Class classObject)
    266   {
    267 
    268     this.m_namespace = namespace;
    269     this.m_name = name;
    270     this.m_nameAlias = nameAlias;
    271     this.m_elements = elements;
    272     this.m_attributes = attributes;
    273 
    274     setElementProcessor(contentHandler);
    275 
    276     this.m_classObject = classObject;
    277 
    278 		if (hasRequired() && m_elements != null)
    279 		{
    280 			int n = m_elements.length;
    281 			for (int i = 0; i < n; i++)
    282 			{
    283 				XSLTElementDef def = m_elements[i];
    284 
    285 				if (def != null && def.getRequired())
    286 				{
    287 					if (m_requiredFound == null)
    288 						m_requiredFound = new Hashtable();
    289 					m_requiredFound.put(def.getName(), "xsl:" +def.getName());
    290 				}
    291 			}
    292 		}
    293   }
    294 
    295   /**
    296    * Tell if two objects are equal, when either one may be null.
    297    * If both are null, they are considered equal.
    298    *
    299    * @param obj1 A reference to the first object, or null.
    300    * @param obj2 A reference to the second object, or null.
    301    *
    302    * @return true if the to objects are equal by both being null or
    303    * because obj2.equals(obj1) returns true.
    304    */
    305   private static boolean equalsMayBeNull(Object obj1, Object obj2)
    306   {
    307     return (obj2 == obj1)
    308            || ((null != obj1) && (null != obj2) && obj2.equals(obj1));
    309   }
    310 
    311   /**
    312    * Tell if the two string refs are equal,
    313    * equality being defined as:
    314    * 1) Both strings are null.
    315    * 2) One string is null and the other is empty.
    316    * 3) Both strings are non-null, and equal.
    317    *
    318    * @param s1 A reference to the first string, or null.
    319    * @param s2 A reference to the second string, or null.
    320    *
    321    * @return true if Both strings are null, or if
    322    * one string is null and the other is empty, or if
    323    * both strings are non-null, and equal because
    324    * s1.equals(s2) returns true.
    325    */
    326   private static boolean equalsMayBeNullOrZeroLen(String s1, String s2)
    327   {
    328 
    329     int len1 = (s1 == null) ? 0 : s1.length();
    330     int len2 = (s2 == null) ? 0 : s2.length();
    331 
    332     return (len1 != len2) ? false
    333 						 : (len1 == 0) ? true
    334 								 : s1.equals(s2);
    335   }
    336 
    337   /** Content type enumerations    */
    338   static final int T_ELEMENT = 1, T_PCDATA = 2, T_ANY = 3;
    339 
    340   /**
    341    * The type of this element.
    342    */
    343   private int m_type = T_ELEMENT;
    344 
    345   /**
    346    * Get the type of this element.
    347    *
    348    * @return Content type, one of T_ELEMENT, T_PCDATA, or T_ANY.
    349    */
    350   int getType()
    351   {
    352     return m_type;
    353   }
    354 
    355   /**
    356    * Set the type of this element.
    357    *
    358    * @param t Content type, one of T_ELEMENT, T_PCDATA, or T_ANY.
    359    */
    360   void setType(int t)
    361   {
    362     m_type = t;
    363   }
    364 
    365   /**
    366    * The allowed namespace for this element.
    367    */
    368   private String m_namespace;
    369 
    370   /**
    371    * Get the allowed namespace for this element.
    372    *
    373    * @return The Namespace URI, "*", or null.
    374    */
    375   String getNamespace()
    376   {
    377     return m_namespace;
    378   }
    379 
    380   /**
    381    * The name of this element.
    382    */
    383   private String m_name;
    384 
    385   /**
    386    * Get the local name of this element.
    387    *
    388    * @return The local name of this element, "*", or null.
    389    */
    390   String getName()
    391   {
    392     return m_name;
    393   }
    394 
    395   /**
    396    * The name of this element.
    397    */
    398   private String m_nameAlias;
    399 
    400   /**
    401    * Get the name of this element.
    402    *
    403    * @return A potential alias for the name, or null.
    404    */
    405   String getNameAlias()
    406   {
    407     return m_nameAlias;
    408   }
    409 
    410   /**
    411    * The allowed elements for this type.
    412    */
    413   private XSLTElementDef[] m_elements;
    414 
    415   /**
    416    * Get the allowed elements for this type.
    417    *
    418    * @return An array of allowed child element defs, or null.
    419    * @xsl.usage internal
    420    */
    421   public XSLTElementDef[] getElements()
    422   {
    423     return m_elements;
    424   }
    425 
    426   /**
    427    * Set the allowed elements for this type.
    428    *
    429    * @param defs An array of allowed child element defs, or null.
    430    */
    431   void setElements(XSLTElementDef[] defs)
    432   {
    433     m_elements = defs;
    434   }
    435 
    436   /**
    437    * Tell if the namespace URI and local name match this
    438    * element.
    439    * @param uri The namespace uri, which may be null.
    440    * @param localName The local name of an element, which may be null.
    441    *
    442    * @return true if the uri and local name arguments are considered
    443    * to match the uri and local name of this element def.
    444    */
    445   private boolean QNameEquals(String uri, String localName)
    446   {
    447 
    448     return (equalsMayBeNullOrZeroLen(m_namespace, uri)
    449             && (equalsMayBeNullOrZeroLen(m_name, localName)
    450                 || equalsMayBeNullOrZeroLen(m_nameAlias, localName)));
    451   }
    452 
    453   /**
    454    * Given a namespace URI, and a local name, get the processor
    455    * for the element, or return null if not allowed.
    456    *
    457    * @param uri The Namespace URI, or an empty string.
    458    * @param localName The local name (without prefix), or empty string if not namespace processing.
    459    *
    460    * @return The element processor that matches the arguments, or null.
    461    */
    462   XSLTElementProcessor getProcessorFor(String uri, String localName)
    463 	{
    464 
    465     XSLTElementProcessor elemDef = null;  // return value
    466 
    467     if (null == m_elements)
    468       return null;
    469 
    470     int n = m_elements.length;
    471     int order = -1;
    472 		boolean multiAllowed = true;
    473     for (int i = 0; i < n; i++)
    474     {
    475       XSLTElementDef def = m_elements[i];
    476 
    477       // A "*" signals that the element allows literal result
    478       // elements, so just assign the def, and continue to
    479       // see if anything else matches.
    480       if (def.m_name.equals("*"))
    481       {
    482 
    483         // Don't allow xsl elements
    484         if (!equalsMayBeNullOrZeroLen(uri, Constants.S_XSLNAMESPACEURL))
    485 				{
    486           elemDef = def.m_elementProcessor;
    487 				  order = def.getOrder();
    488 					multiAllowed = def.getMultiAllowed();
    489 				}
    490       }
    491 			else if (def.QNameEquals(uri, localName))
    492 			{
    493 				if (def.getRequired())
    494 					this.setRequiredFound(def.getName(), true);
    495 				order = def.getOrder();
    496 				multiAllowed = def.getMultiAllowed();
    497 				elemDef = def.m_elementProcessor;
    498 				break;
    499 			}
    500 		}
    501 
    502 		if (elemDef != null && this.isOrdered())
    503 		{
    504 			int lastOrder = getLastOrder();
    505 			if (order > lastOrder)
    506 				setLastOrder(order);
    507 			else if (order == lastOrder && !multiAllowed)
    508 			{
    509 				return null;
    510 			}
    511 			else if (order < lastOrder && order > 0)
    512 			{
    513 				return null;
    514 			}
    515 		}
    516 
    517     return elemDef;
    518   }
    519 
    520   /**
    521    * Given an unknown element, get the processor
    522    * for the element.
    523    *
    524    * @param uri The Namespace URI, or an empty string.
    525    * @param localName The local name (without prefix), or empty string if not namespace processing.
    526    *
    527    * @return normally a {@link ProcessorUnknown} reference.
    528    * @see ProcessorUnknown
    529    */
    530   XSLTElementProcessor getProcessorForUnknown(String uri, String localName)
    531   {
    532 
    533     // XSLTElementProcessor lreDef = null; // return value
    534     if (null == m_elements)
    535       return null;
    536 
    537     int n = m_elements.length;
    538 
    539     for (int i = 0; i < n; i++)
    540     {
    541       XSLTElementDef def = m_elements[i];
    542 
    543       if (def.m_name.equals("unknown") && uri.length() > 0)
    544       {
    545         return def.m_elementProcessor;
    546       }
    547     }
    548 
    549     return null;
    550   }
    551 
    552   /**
    553    * The allowed attributes for this type.
    554    */
    555   private XSLTAttributeDef[] m_attributes;
    556 
    557   /**
    558    * Get the allowed attributes for this type.
    559    *
    560    * @return An array of allowed attribute defs, or null.
    561    */
    562   XSLTAttributeDef[] getAttributes()
    563   {
    564     return m_attributes;
    565   }
    566 
    567   /**
    568    * Given a namespace URI, and a local name, return the element's
    569    * attribute definition, if it has one.
    570    *
    571    * @param uri The Namespace URI, or an empty string.
    572    * @param localName The local name (without prefix), or empty string if not namespace processing.
    573    *
    574    * @return The attribute def that matches the arguments, or null.
    575    */
    576   XSLTAttributeDef getAttributeDef(String uri, String localName)
    577   {
    578 
    579     XSLTAttributeDef defaultDef = null;
    580     XSLTAttributeDef[] attrDefs = getAttributes();
    581     int nAttrDefs = attrDefs.length;
    582 
    583     for (int k = 0; k < nAttrDefs; k++)
    584     {
    585       XSLTAttributeDef attrDef = attrDefs[k];
    586       String uriDef = attrDef.getNamespace();
    587       String nameDef = attrDef.getName();
    588 
    589       if (nameDef.equals("*") && (equalsMayBeNullOrZeroLen(uri, uriDef) ||
    590           (uriDef != null && uriDef.equals("*") && uri!=null && uri.length() > 0 )))
    591       {
    592         return attrDef;
    593       }
    594       else if (nameDef.equals("*") && (uriDef == null))
    595       {
    596 
    597         // In this case, all attributes are legal, so return
    598         // this as the last resort.
    599         defaultDef = attrDef;
    600       }
    601       else if (equalsMayBeNullOrZeroLen(uri, uriDef)
    602                && localName.equals(nameDef))
    603       {
    604         return attrDef;
    605       }
    606     }
    607 
    608     if (null == defaultDef)
    609     {
    610       if (uri.length() > 0 && !equalsMayBeNullOrZeroLen(uri, Constants.S_XSLNAMESPACEURL))
    611       {
    612         return XSLTAttributeDef.m_foreignAttr;
    613       }
    614     }
    615 
    616     return defaultDef;
    617   }
    618 
    619   /**
    620    * If non-null, the ContentHandler/TransformerFactory for this element.
    621    */
    622   private XSLTElementProcessor m_elementProcessor;
    623 
    624   /**
    625    * Return the XSLTElementProcessor for this element.
    626    *
    627    * @return The element processor for this element.
    628    * @xsl.usage internal
    629    */
    630   public XSLTElementProcessor getElementProcessor()
    631   {
    632     return m_elementProcessor;
    633   }
    634 
    635   /**
    636    * Set the XSLTElementProcessor for this element.
    637    *
    638    * @param handler The element processor for this element.
    639    * @xsl.usage internal
    640    */
    641   public void setElementProcessor(XSLTElementProcessor handler)
    642   {
    643 
    644     if (handler != null)
    645     {
    646       m_elementProcessor = handler;
    647 
    648       m_elementProcessor.setElemDef(this);
    649     }
    650   }
    651 
    652   /**
    653    * If non-null, the class object that should in instantiated for
    654    * a Xalan instance of this element.
    655    */
    656   private Class m_classObject;
    657 
    658   /**
    659    * Return the class object that should in instantiated for
    660    * a Xalan instance of this element.
    661    *
    662    * @return The class of the object that this element def should produce, or null.
    663    */
    664   Class getClassObject()
    665   {
    666     return m_classObject;
    667   }
    668 
    669 	/**
    670    * If true, this has a required element.
    671    */
    672   private boolean m_has_required = false;
    673 
    674   /**
    675    * Get whether or not this has a required element.
    676    *
    677    * @return true if this this has a required element.
    678    */
    679   boolean hasRequired()
    680   {
    681     return m_has_required;
    682   }
    683 
    684 	/**
    685    * If true, this is a required element.
    686    */
    687   private boolean m_required = false;
    688 
    689   /**
    690    * Get whether or not this is a required element.
    691    *
    692    * @return true if this is a required element.
    693    */
    694   boolean getRequired()
    695   {
    696     return m_required;
    697   }
    698 
    699 	Hashtable m_requiredFound;
    700 
    701 	/**
    702    * Set this required element found.
    703    *
    704    */
    705   void setRequiredFound(String elem, boolean found)
    706   {
    707    if (m_requiredFound.get(elem) != null)
    708 		 m_requiredFound.remove(elem);
    709   }
    710 
    711 	/**
    712    * Get whether all required elements were found.
    713    *
    714    * @return true if all required elements were found.
    715    */
    716   boolean getRequiredFound()
    717   {
    718 		if (m_requiredFound == null)
    719 			return true;
    720     return m_requiredFound.isEmpty();
    721   }
    722 
    723 	/**
    724    * Get required elements that were not found.
    725    *
    726    * @return required elements that were not found.
    727    */
    728   String getRequiredElem()
    729   {
    730 		if (m_requiredFound == null)
    731 			return null;
    732 		Enumeration elems = m_requiredFound.elements();
    733 		String s = "";
    734 		boolean first = true;
    735 		while (elems.hasMoreElements())
    736 		{
    737 			if (first)
    738 				first = false;
    739 			else
    740 			 s = s + ", ";
    741 			s = s + (String)elems.nextElement();
    742 		}
    743     return s;
    744   }
    745 
    746 	boolean m_isOrdered = false;
    747 
    748 	/**
    749    * Get whether this element requires ordered children.
    750    *
    751    * @return true if this element requires ordered children.
    752    */
    753   boolean isOrdered()
    754   {
    755 		/*if (!m_CheckedOrdered)
    756 		{
    757 			m_CheckedOrdered = true;
    758 			m_isOrdered = false;
    759 			if (null == m_elements)
    760 				return false;
    761 
    762 			int n = m_elements.length;
    763 
    764 			for (int i = 0; i < n; i++)
    765 			{
    766 				if (m_elements[i].getOrder() > 0)
    767 				{
    768 					m_isOrdered = true;
    769 					return true;
    770 				}
    771 			}
    772 			return false;
    773 		}
    774 		else*/
    775 			return m_isOrdered;
    776   }
    777 
    778 	/**
    779    * the order that this element should appear, or -1 if not ordered
    780    */
    781   private int m_order = -1;
    782 
    783 	/**
    784    * Get the order that this element should appear .
    785    *
    786    * @return the order that this element should appear.
    787    */
    788   int getOrder()
    789   {
    790     return m_order;
    791   }
    792 
    793 	/**
    794    * the highest order of child elements have appeared so far,
    795    * or -1 if not ordered
    796    */
    797   private int m_lastOrder = -1;
    798 
    799 	/**
    800    * Get the highest order of child elements have appeared so far .
    801    *
    802    * @return the highest order of child elements have appeared so far.
    803    */
    804   int getLastOrder()
    805   {
    806     return m_lastOrder;
    807   }
    808 
    809 	/**
    810    * Set the highest order of child elements have appeared so far .
    811    *
    812    * @param order the highest order of child elements have appeared so far.
    813    */
    814   void setLastOrder(int order)
    815   {
    816     m_lastOrder = order ;
    817   }
    818 
    819 	/**
    820    * True if this element can appear multiple times
    821    */
    822   private boolean m_multiAllowed = true;
    823 
    824 	/**
    825    * Get whether this element can appear multiple times
    826    *
    827    * @return true if this element can appear multiple times
    828    */
    829   boolean getMultiAllowed()
    830   {
    831     return m_multiAllowed;
    832   }
    833 }
    834