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