• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // This file is part of TagSoup and is Copyright 2002-2008 by John Cowan.
2 //
3 // TagSoup is licensed under the Apache License,
4 // Version 2.0.  You may obtain a copy of this license at
5 // http://www.apache.org/licenses/LICENSE-2.0 .  You may also have
6 // additional legal rights not granted by this license.
7 //
8 // TagSoup is distributed in the hope that it will be useful, but
9 // unless required by applicable law or agreed to in writing, TagSoup
10 // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
11 // OF ANY KIND, either express or implied; not even the implied warranty
12 // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 
14 package org.ccil.cowan.tagsoup;
15 
16 /**
17 This class represents an element type in the schema.
18 An element type has a name, a content model vector, a member-of vector,
19 a flags vector, default attributes, and a schema to which it belongs.
20 @see Schema
21 */
22 
23 public class ElementType {
24 
25 	private String theName;		// element type name (Qname)
26 	private String theNamespace;	// element type namespace name
27 	private String theLocalName;	// element type local name
28 	private int theModel;		// bitmap: what the element contains
29 	private int theMemberOf;	// bitmap: what element is contained in
30 	private int theFlags;		// bitmap: element flags
31 	private AttributesImpl theAtts;	// default attributes
32 	private ElementType theParent;	// parent of this element type
33 	private Schema theSchema;	// schema to which this belongs
34 
35 	/**
36 	Construct an ElementType:
37 	but it's better to use Schema.element() instead.
38 	The content model, member-of, and flags vectors are specified as ints.
39 	@param name The element type name
40 	@param model ORed-together bits representing the content models
41 	   allowed in the content of this element type
42 	@param memberOf ORed-together bits representing the content models
43 	   to which this element type belongs
44 	@param flags ORed-together bits representing the flags associated
45 	   with this element type
46 	@param schema The schema with which this element type will be
47 	associated
48 	*/
49 
ElementType(String name, int model, int memberOf, int flags, Schema schema)50 	public ElementType(String name, int model, int memberOf, int flags, Schema schema) {
51 		theName = name;
52 		theModel = model;
53 		theMemberOf = memberOf;
54 		theFlags = flags;
55 		theAtts = new AttributesImpl();
56 		theSchema = schema;
57 		theNamespace = namespace(name, false);
58 		theLocalName = localName(name);
59 		}
60 
61 	/**
62 	Return a namespace name from a Qname.
63 	The attribute flag tells us whether to return an empty namespace
64 	name if there is no prefix, or use the schema default instead.
65 	@param name The Qname
66 	@param attribute True if name is an attribute name
67 	@return The namespace name
68 	**/
namespace(String name, boolean attribute)69 	public String namespace(String name, boolean attribute) {
70 		int colon = name.indexOf(':');
71 		if (colon == -1) {
72 			return attribute ? "" : theSchema.getURI();
73 			}
74 		String prefix = name.substring(0, colon);
75 		if (prefix.equals("xml")) {
76 			return "http://www.w3.org/XML/1998/namespace";
77 			}
78 		else {
79 			return ("urn:x-prefix:" + prefix).intern();
80 			}
81 		}
82 
83 	/**
84 	Return a local name from a Qname.
85 	@param name The Qname
86 	@return The local name
87 	**/
localName(String name)88 	public String localName(String name) {
89 		int colon = name.indexOf(':');
90 		if (colon == -1) {
91 			return name;
92 			}
93 		else {
94 			return name.substring(colon+1).intern();
95 			}
96 		}
97 
98 	/**
99 	Returns the name of this element type.
100 	@return The name of the element type
101 	*/
102 
name()103 	public String name() { return theName; }
104 
105 	/**
106 	Returns the namespace name of this element type.
107 	@return The namespace name of the element type
108 	*/
109 
namespace()110 	public String namespace() { return theNamespace; }
111 
112 	/**
113 	Returns the local name of this element type.
114 	@return The local name of the element type
115 	*/
116 
localName()117 	public String localName() { return theLocalName; }
118 
119 	/**
120 	Returns the content models of this element type.
121 	@return The content models of this element type as a vector of bits
122 	*/
123 
model()124 	public int model() { return theModel; }
125 
126 	/**
127 	Returns the content models to which this element type belongs.
128 	@return The content models to which this element type belongs as a
129 	   vector of bits
130 	*/
131 
memberOf()132 	public int memberOf() { return theMemberOf; }
133 
134 	/**
135 	Returns the flags associated with this element type.
136 	@return The flags associated with this element type as a vector of bits
137 	*/
138 
flags()139 	public int flags() { return theFlags; }
140 
141 	/**
142 	Returns the default attributes associated with this element type.
143 	Attributes of type CDATA that don't have default values are
144 	typically not included.  Other attributes without default values
145 	have an internal value of <tt>null</tt>.
146 	The return value is an AttributesImpl to allow the caller to mutate
147 	the attributes.
148 	*/
149 
atts()150 	public AttributesImpl atts() {return theAtts;}
151 
152 	/**
153 	Returns the parent element type of this element type.
154 	@return The parent element type
155 	*/
156 
parent()157 	public ElementType parent() {return theParent;}
158 
159 	/**
160 	Returns the schema which this element type is associated with.
161 	@return The schema
162 	*/
163 
schema()164 	public Schema schema() {return theSchema;}
165 
166 
167 	/**
168 	Returns true if this element type can contain another element type.
169 	That is, if any of the models in this element's model vector
170 	match any of the models in the other element type's member-of
171 	vector.
172 	@param other The other element type
173 	*/
174 
canContain(ElementType other)175 	public boolean canContain(ElementType other) {
176 		return (theModel & other.theMemberOf) != 0;
177 		}
178 
179 
180 	/**
181 	Sets an attribute and its value into an AttributesImpl object.
182 	Attempts to set a namespace declaration are ignored.
183 	@param atts The AttributesImpl object
184 	@param name The name (Qname) of the attribute
185 	@param type The type of the attribute
186 	@param value The value of the attribute
187 	*/
188 
setAttribute(AttributesImpl atts, String name, String type, String value)189 	public void setAttribute(AttributesImpl atts, String name, String type, String value) {
190 		if (name.equals("xmlns") || name.startsWith("xmlns:")) {
191 			return;
192 			}
193 ;
194 		String namespace = namespace(name, true);
195 		String localName = localName(name);
196 		int i = atts.getIndex(name);
197 		if (i == -1) {
198 			name = name.intern();
199 			if (type == null) type = "CDATA";
200 			if (!type.equals("CDATA")) value = normalize(value);
201 			atts.addAttribute(namespace, localName, name, type, value);
202 			}
203 		else {
204 			if (type == null) type = atts.getType(i);
205 			if (!type.equals("CDATA")) value=normalize(value);
206 			atts.setAttribute(i, namespace, localName, name, type, value);
207 			}
208 		}
209 
210 	/**
211 	Normalize an attribute value (ID-style).
212 	CDATA-style attribute normalization is already done.
213 	@param value The value to normalize
214 	@return The normalized value
215 	**/
normalize(String value)216 	public static String normalize(String value) {
217 		if (value == null) return value;
218 		value = value.trim();
219 		if (value.indexOf("  ") == -1) return value;
220 		boolean space = false;
221 		int len = value.length();
222 		StringBuffer b = new StringBuffer(len);
223 		for (int i = 0; i < len; i++) {
224 			char v = value.charAt(i);
225 			if (v == ' ') {
226 				if (!space) b.append(v);
227 				space = true;
228 				}
229 			else {
230 				b.append(v);
231 				space = false;
232 				}
233 			}
234 		return b.toString();
235 		}
236 
237 	/**
238 	Sets an attribute and its value into this element type.
239 	@param name The name of the attribute
240 	@param type The type of the attribute
241 	@param value The value of the attribute
242 	*/
243 
setAttribute(String name, String type, String value)244 	public void setAttribute(String name, String type, String value) {
245 		setAttribute(theAtts, name, type, value);
246 		}
247 
248 	/**
249 	Sets the models of this element type.
250 	@param model The content models of this element type as a vector of bits
251 	*/
252 
setModel(int model)253 	public void setModel(int model) { theModel = model; }
254 
255 	/**
256 	Sets the content models to which this element type belongs.
257 	@param memberOf The content models to which this element type belongs as a vector of bits
258 	*/
259 
setMemberOf(int memberOf)260 	public void setMemberOf(int memberOf) { theMemberOf = memberOf; }
261 
262 	/**
263 	Sets the flags of this element type.
264 	@param flags associated with this element type The flags as a vector of bits
265 	*/
266 
setFlags(int flags)267 	public void setFlags(int flags) { theFlags = flags; }
268 
269 	/**
270 	Sets the parent element type of this element type.
271 	@param parent The parent element type
272 	*/
273 
setParent(ElementType parent)274 	public void setParent(ElementType parent) { theParent = parent; }
275 
276 	}
277