blob: a7ade2d45aa0912c2d9aed98436537fee954dbdb [file] [log] [blame]
// This file is part of TagSoup and is Copyright 2002-2008 by John Cowan.
//
// TagSoup is licensed under the Apache License,
// Version 2.0. You may obtain a copy of this license at
// http://www.apache.org/licenses/LICENSE-2.0 . You may also have
// additional legal rights not granted by this license.
//
// TagSoup is distributed in the hope that it will be useful, but
// unless required by applicable law or agreed to in writing, TagSoup
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
// OF ANY KIND, either express or implied; not even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//
//
// Model of document
using System;
using System.Collections;
namespace TagSoup
{
/// <summary>
/// Abstract class representing a TSSL schema.
/// Actual TSSL schemas are compiled into concrete subclasses of this class.
/// </summary>
public abstract class Schema
{
public const int M_ANY = -1;//0xFFFFFFFF;
public const int M_EMPTY = 0;
public const int M_PCDATA = 1 << 30;
public const int M_ROOT = 1 << 31;
public const int F_RESTART = 1;
public const int F_CDATA = 2;
public const int F_NOFORCE = 4;
private readonly Hashtable theEntities = new Hashtable(); // string -> Character
private readonly Hashtable theElementTypes = new Hashtable(); // string -> ElementType
private string theURI = "";
private string thePrefix = "";
private ElementType theRoot;
/// <summary>
/// Add or replace an element type for this schema.
/// </summary>
/// <param name="name"> Name (Qname) of the element</param>
/// <param name="model">Models of the element's content as a vector of bits</param>
/// <param name="memberOf">Models the element is a member of as a vector of bits</param>
/// <param name="flags">Flags for the element</param>
public virtual void ElementType(string name, int model, int memberOf, int flags)
{
var e = new ElementType(name, model, memberOf, flags, this);
theElementTypes[name.ToLowerInvariant()] = e;
if (memberOf == M_ROOT)
{
theRoot = e;
}
}
/// <summary>
/// Gets or sets the root element of this schema
/// </summary>
public virtual ElementType RootElementType => theRoot;
/// <summary>
/// Add or replace a default attribute for an element type in this schema.
/// </summary>
/// <param name="elemName">Name (Qname) of the element type</param>
/// <param name="attrName">Name (Qname) of the attribute</param>
/// <param name="type">Type of the attribute</param>
/// <param name="value">Default value of the attribute; null if no default</param>
public virtual void Attribute(string elemName, string attrName, string type, string value)
{
ElementType e = GetElementType(elemName);
if (e == null)
{
throw new Exception("Attribute " + attrName + " specified for unknown element type " + elemName);
}
e.SetAttribute(attrName, type, value);
}
/// <summary>
/// Specify natural parent of an element in this schema.
/// </summary>
/// <param name="name">Name of the child element</param>
/// <param name="parentName">Name of the parent element</param>
public virtual void Parent(string name, string parentName)
{
ElementType child = GetElementType(name);
ElementType parent = GetElementType(parentName);
if (child == null)
{
throw new Exception("No child " + name + " for parent " + parentName);
}
if (parent == null)
{
#pragma warning disable IDE0016 // Use 'throw' expression
throw new Exception("No parent " + parentName + " for child " + name);
#pragma warning restore IDE0016 // Use 'throw' expression
}
child.Parent = parent;
}
/// <summary>
/// Add to or replace a character entity in this schema.
/// </summary>
/// <param name="name">Name of the entity</param>
/// <param name="value">Value of the entity</param>
public virtual void Entity(string name, int value)
{
theEntities[name] = value;
}
/// <summary>
/// Get an <see cref="TagSoup.ElementType"/> by name.
/// </summary>
/// <param name="name">Name (Qname) of the element type</param>
/// <returns>The corresponding <see cref="TagSoup.ElementType"/></returns>
public virtual ElementType GetElementType(string name)
{
return (ElementType)(theElementTypes[name.ToLowerInvariant()]);
}
/// <summary>
/// Get an entity value by name.
/// </summary>
/// <param name="name">Name of the entity</param>
/// <returns>The corresponding character, or 0 if none</returns>
public virtual int GetEntity(string name)
{
// System.err.println("%% Looking up entity " + name);
if (theEntities.ContainsKey(name))
{
return (int)theEntities[name];
}
return 0;
}
/// <summary>
/// Gets or sets the URI (namespace name) of this schema.
/// </summary>
public virtual string Uri
{
get => theURI;
set => theURI = value;
}
/// <summary>
/// Gets ot sets the prefix of this schema.
/// </summary>
public virtual string Prefix
{
get => thePrefix;
set => thePrefix = value;
}
}
}