1 /** 2 * Redistribution and use of this software and associated documentation 3 * ("Software"), with or without modification, are permitted provided 4 * that the following conditions are met: 5 * 6 * 1. Redistributions of source code must retain copyright 7 * statements and notices. Redistributions must also contain a 8 * copy of this document. 9 * 10 * 2. Redistributions in binary form must reproduce the 11 * above copyright notice, this list of conditions and the 12 * following disclaimer in the documentation and/or other 13 * materials provided with the distribution. 14 * 15 * 3. The name "Exolab" must not be used to endorse or promote 16 * products derived from this Software without prior written 17 * permission of Intalio, Inc. For written permission, 18 * please contact info@exolab.org. 19 * 20 * 4. Products derived from this Software may not be called "Exolab" 21 * nor may "Exolab" appear in their names without prior written 22 * permission of Intalio, Inc. Exolab is a registered 23 * trademark of Intalio, Inc. 24 * 25 * 5. Due credit should be given to the Exolab Project 26 * (http://www.exolab.org/). 27 * 28 * THIS SOFTWARE IS PROVIDED BY INTALIO, INC. AND CONTRIBUTORS 29 * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT 30 * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 31 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 32 * INTALIO, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 33 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 34 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 35 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 37 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 38 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 39 * OF THE POSSIBILITY OF SUCH DAMAGE. 40 * 41 * Copyright 2000 (C) Intalio Inc. All Rights Reserved. 42 * 43 * $Id$ 44 */ 45 46 package org.exolab.castor.xml.dtd; 47 48 import java.util.HashSet; 49 import java.util.Hashtable; 50 import java.util.Iterator; 51 import java.util.Enumeration; 52 53 /** 54 * Implementation of DTD Element declaration specification. 55 * @author <a href="mailto:totok@intalio.com">Alexander Totok</a> 56 * @version $Revision$ $Date: 2006-04-25 15:08:23 -0600 (Tue, 25 Apr 2006) $ 57 */ 58 public class Element { 59 60 private static final short ANY = 0; 61 private static final short EMPTY = 1; 62 private static final short MIXED = 2; 63 private static final short ELEMENTS_ONLY = 3; 64 65 /** 66 * Name of the element. 67 */ 68 private String name; 69 70 /** 71 * DTD document owning this element 72 */ 73 private DTDdocument document; 74 75 /** 76 * Content type of the element. Value may be {@link #ANY ANY}, {@link #EMPTY EMPTY}, 77 * {@link #MIXED MIXED}, {@link #ELEMENTS_ONLY ELEMENTS_ONLY} or 78 * -1, if unspecified. 79 */ 80 private short contentType = -1; 81 82 /** 83 * Set of names of children of the element, 84 * if the element has <tt>MIXED</tt> content. 85 */ 86 private HashSet mixedChildren = null; 87 88 /** 89 * Content Particle representing content of the element, if the element has 90 * <tt>ELEMENTS_ONLY</tt> content. 91 */ 92 private ContentParticle content = null; 93 94 /** 95 * Attributes of the element. 96 */ 97 private Hashtable attributes; 98 99 /** 100 * Constructor, setting the name of the element and owning DTD document. 101 * @param document must not be null. 102 */ 103 public Element(DTDdocument document, String name) { 104 105 if (document == null) { 106 String err = "Element constructor: document must not be null."; 107 throw new IllegalArgumentException(err); 108 } 109 110 this.name = name; 111 this.document = document; 112 attributes = new Hashtable(); 113 } //-- Element 114 115 /** 116 * Constructor, setting owning DTD document of the element. 117 * @param document must not be null. 118 */ 119 public Element(DTDdocument document) { 120 this(document, null); 121 } //-- Element 122 123 /** 124 * Returns the name of the element. 125 */ 126 public String getName() { 127 return name; 128 } //-- getName 129 130 /** 131 * Returns DTD document owning this element. 132 */ 133 public DTDdocument getDocument() { 134 return document; 135 } //-- getDocument 136 137 /** 138 * Returns {@link java.util.Iterator iterator} of the set of mixed children, 139 * if of <tt>MIXED</tt> content, <tt>null</tt> otherwise. 140 */ 141 public Iterator getMixedContentChildren() { 142 if (isMixedContent()) return mixedChildren.iterator(); 143 return null; 144 } //-- getMixedContentChildren 145 146 /** 147 * Returns enumeration of the attributes of the element. 148 */ 149 public Enumeration getAttributes() { 150 return attributes.elements(); 151 } //-- getAttributes 152 153 /** 154 * Returns {@link org.exolab.castor.xml.dtd.ContentParticle Content Particle}, 155 * representing the content of the element, if has <tt>ELEMENTS_ONLY</tt> 156 * content, <tt>null</tt> otherwise. 157 */ 158 public ContentParticle getContent() { 159 if (isElemOnlyContent()) return content; 160 return null; 161 } //-- getContent 162 163 /** 164 * Sets the name of the element. 165 */ 166 public void setName(String name) { 167 this.name = name; 168 } //-- setName 169 170 /** 171 * Sets the content type of the element to <tt>ANY</tt>. 172 */ 173 public void setAnyContent() { 174 contentType = ANY; 175 } //-- setAnyContent 176 177 /** 178 * <b>True</b> if the element is of <tt>ANY</tt> content type, 179 * <b>false</b> otherwise. 180 */ 181 public boolean isAnyContent() { 182 return contentType == ANY; 183 } //-- isAnyContent 184 185 /** 186 * Sets the content type of the element to <tt>EMPTY</tt>. 187 */ 188 public void setEmptyContent() { 189 contentType = EMPTY; 190 } //-- setEmptyContent 191 192 /** 193 * <b>True</b> if the element is of <tt>EMPTY</tt> content type, <b>false</b> otherwise. 194 */ 195 public boolean isEmptyContent() { 196 return contentType == EMPTY; 197 } //-- isEmptyContent 198 199 /** 200 * Sets the content type of the element to <tt>MIXED</tt>. 201 */ 202 public void setMixedContent() { 203 contentType = MIXED; 204 mixedChildren = new HashSet(); 205 } //-- setMixedContent 206 207 /** 208 * <b>True</b> if the element is of <tt>MIXED</tt> content type, <b>false</b> otherwise. 209 */ 210 public boolean isMixedContent() { 211 return contentType == MIXED; 212 } //-- isMixedContent 213 214 /** 215 * Sets the content type of the element to <tt>ELEMENTS_ONLY</tt>. 216 * @param cp Content Particle representing content of the element. 217 */ 218 public void setElemOnlyContent(ContentParticle cp) { 219 contentType = ELEMENTS_ONLY; 220 content = cp; 221 } //-- setChildrenContent 222 223 /** 224 * <b>True</b> if the element is of <tt>ELEMENTS_ONLY</tt> content type, 225 * <b>false</b> otherwise. 226 */ 227 public boolean isElemOnlyContent() { 228 return contentType == ELEMENTS_ONLY; 229 } //-- isChildrenContent 230 231 /** 232 * Adds name of a <tt>child</tt> to the set of children's names. 233 * @throws DTDException if there already exists the child with the same name. 234 */ 235 public synchronized void addMixedContentChild(String child) throws DTDException { 236 if (mixedChildren.contains(child)) { 237 String err = "Element \"" + name + "\" already contains child element "; 238 err += "\"" + child + "\"."; 239 throw new DTDException(err); 240 } 241 mixedChildren.add(child); 242 } //-- addChild 243 244 /** 245 * Adds attribute to the element. If the element already has the attribute 246 * with the same name, does nothing. 247 */ 248 public synchronized void addAttribute(Attribute attribute) { 249 String name = attribute.getName(); 250 if (!attributes.containsKey(name)) attributes.put(name,attribute); 251 } //-- addAttribute 252 253 } //-- Element