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 */
21package org.apache.xalan.processor;
22
23import java.util.Enumeration;
24import java.util.Hashtable;
25
26import org.apache.xalan.templates.Constants;
27import 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 */
35public 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