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//
15// Model of document
16
17package org.ccil.cowan.tagsoup;
18import java.util.HashMap;
19import java.util.Locale;
20
21/**
22Abstract class representing a TSSL schema.
23Actual TSSL schemas are compiled into concrete subclasses of this class.
24**/
25
26public abstract class Schema {
27
28	public static final int M_ANY = 0xFFFFFFFF;
29	public static final int M_EMPTY = 0;
30	public static final int M_PCDATA = 1 << 30;
31	public static final int M_ROOT = 1 << 31;
32
33
34	public static final int F_RESTART = 1;
35	public static final int F_CDATA = 2;
36	public static final int F_NOFORCE = 4;
37
38	private HashMap theEntities =
39		new HashMap();		// String -> Character
40	private HashMap theElementTypes =
41		new HashMap();		// String -> ElementType
42
43	private String theURI = "";
44	private String thePrefix = "";
45	private ElementType theRoot = null;
46
47	/**
48	Add or replace an element type for this schema.
49	@param name Name (Qname) of the element
50	@param model Models of the element's content as a vector of bits
51	@param memberOf Models the element is a member of as a vector of bits
52	@param flags Flags for the element
53	**/
54
55	public void elementType(String name, int model, int memberOf, int flags) {
56		ElementType e = new ElementType(name, model, memberOf, flags, this);
57		theElementTypes.put(name.toLowerCase(Locale.ROOT), e);
58		if (memberOf == M_ROOT) theRoot = e;
59		}
60
61	/**
62	Get the root element of this schema
63	**/
64
65	public ElementType rootElementType() {
66		return theRoot;
67		}
68
69	/**
70	Add or replace a default attribute for an element type in this schema.
71	@param elemName Name (Qname) of the element type
72	@param attrName Name (Qname) of the attribute
73	@param type Type of the attribute
74	@param value Default value of the attribute; null if no default
75	**/
76
77	public void attribute(String elemName, String attrName,
78				String type, String value) {
79		ElementType e = getElementType(elemName);
80		if (e == null) {
81			throw new Error("Attribute " + attrName +
82				" specified for unknown element type " +
83				elemName);
84			}
85		e.setAttribute(attrName, type, value);
86		}
87
88	/**
89	Specify natural parent of an element in this schema.
90	@param name Name of the child element
91	@param parentName Name of the parent element
92	**/
93
94	public void parent(String name, String parentName) {
95		ElementType child = getElementType(name);
96		ElementType parent = getElementType(parentName);
97		if (child == null) {
98			throw new Error("No child " + name + " for parent " + parentName);
99			}
100		if (parent == null) {
101			throw new Error("No parent " + parentName + " for child " + name);
102			}
103		child.setParent(parent);
104		}
105
106	/**
107	Add to or replace a character entity in this schema.
108	@param name Name of the entity
109	@param value Value of the entity
110	**/
111
112	public void entity(String name, int value) {
113		theEntities.put(name, new Integer(value));
114		}
115
116	/**
117	Get an ElementType by name.
118	@param name Name (Qname) of the element type
119	@return The corresponding ElementType
120	**/
121
122	public ElementType getElementType(String name) {
123		return (ElementType)(theElementTypes.get(name.toLowerCase(Locale.ROOT)));
124		}
125
126	/**
127	Get an entity value by name.
128	@param name Name of the entity
129	@return The corresponding character, or 0 if none
130	**/
131
132	public int getEntity(String name) {
133//		System.err.println("%% Looking up entity " + name);
134		Integer ch = (Integer)theEntities.get(name);
135		if (ch == null) return 0;
136		return ch.intValue();
137		}
138
139	/**
140	Return the URI (namespace name) of this schema.
141	**/
142
143	public String getURI() {
144		return theURI;
145		}
146
147	/**
148	Return the prefix of this schema.
149	**/
150
151	public String getPrefix() {
152		return thePrefix;
153		}
154
155	/**
156	Change the URI (namespace name) of this schema.
157	**/
158
159	public void setURI(String uri) {
160		theURI = uri;
161		}
162
163	/**
164	Change the prefix of this schema.
165	**/
166
167	public void setPrefix(String prefix) {
168		thePrefix = prefix;
169		}
170
171	}
172