alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (DTD.java)

This example Java source code file (DTD.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

attributelist, awt, bitset, contentmodel, dtd, element, entity, file_version, general, hashtable, ioexception, net, network, object, string, stringtokenizer, util, vector

The DTD.java Java example source code

/*
 * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package javax.swing.text.html.parser;

import sun.awt.AppContext;

import java.io.PrintStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.IOException;
import java.io.FileNotFoundException;
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.util.Hashtable;
import java.util.Vector;
import java.util.BitSet;
import java.util.StringTokenizer;
import java.util.Enumeration;
import java.util.Properties;
import java.net.URL;

/**
 * The representation of an SGML DTD.  DTD describes a document
 * syntax and is used in parsing of HTML documents.  It contains
 * a list of elements and their attributes as well as a list of
 * entities defined in the DTD.
 *
 * @see Element
 * @see AttributeList
 * @see ContentModel
 * @see Parser
 * @author Arthur van Hoff
 */
public
class DTD implements DTDConstants {
    public String name;
    public Vector<Element> elements = new Vector();
    public Hashtable<String,Element> elementHash
        = new Hashtable<String,Element>();
    public Hashtable<Object,Entity> entityHash
        = new Hashtable<Object,Entity>();
    public final Element pcdata = getElement("#pcdata");
    public final Element html = getElement("html");
    public final Element meta = getElement("meta");
    public final Element base = getElement("base");
    public final Element isindex = getElement("isindex");
    public final Element head = getElement("head");
    public final Element body = getElement("body");
    public final Element applet = getElement("applet");
    public final Element param = getElement("param");
    public final Element p = getElement("p");
    public final Element title = getElement("title");
    final Element style = getElement("style");
    final Element link = getElement("link");
    final Element script = getElement("script");

    public static final int FILE_VERSION = 1;

    /**
     * Creates a new DTD with the specified name.
     * @param name the name, as a <code>String of the new DTD
     */
    protected DTD(String name) {
        this.name = name;
        defEntity("#RE", GENERAL, '\r');
        defEntity("#RS", GENERAL, '\n');
        defEntity("#SPACE", GENERAL, ' ');
        defineElement("unknown", EMPTY, false, true, null, null, null, null);
    }

    /**
     * Gets the name of the DTD.
     * @return the name of the DTD
     */
    public String getName() {
        return name;
    }

    /**
     * Gets an entity by name.
     * @return the <code>Entity corresponding to the
     *   <code>name String
     */
    public Entity getEntity(String name) {
        return entityHash.get(name);
    }

    /**
     * Gets a character entity.
     * @return the <code>Entity corresponding to the
     *    <code>ch character
     */
    public Entity getEntity(int ch) {
        return entityHash.get(Integer.valueOf(ch));
    }

    /**
     * Returns <code>true if the element is part of the DTD,
     * otherwise returns <code>false.
     *
     * @param  name the requested <code>String
     * @return <code>true if name exists as
     *   part of the DTD, otherwise returns <code>false
     */
    boolean elementExists(String name) {
        return !"unknown".equals(name) && (elementHash.get(name) != null);
    }

    /**
     * Gets an element by name. A new element is
     * created if the element doesn't exist.
     *
     * @param name the requested <code>String
     * @return the <code>Element corresponding to
     *   <code>name, which may be newly created
     */
    public Element getElement(String name) {
        Element e = elementHash.get(name);
        if (e == null) {
            e = new Element(name, elements.size());
            elements.addElement(e);
            elementHash.put(name, e);
        }
        return e;
    }

    /**
     * Gets an element by index.
     *
     * @param index the requested index
     * @return the <code>Element corresponding to
     *   <code>index
     */
    public Element getElement(int index) {
        return elements.elementAt(index);
    }

    /**
     * Defines an entity.  If the <code>Entity specified
     * by <code>name, type, and data
     * exists, it is returned; otherwise a new <code>Entity
     * is created and is returned.
     *
     * @param name the name of the <code>Entity as a String
     * @param type the type of the <code>Entity
     * @param data the <code>Entity's data
     * @return the <code>Entity requested or a new Entity
     *   if not found
     */
    public Entity defineEntity(String name, int type, char data[]) {
        Entity ent = entityHash.get(name);
        if (ent == null) {
            ent = new Entity(name, type, data);
            entityHash.put(name, ent);
            if (((type & GENERAL) != 0) && (data.length == 1)) {
                switch (type & ~GENERAL) {
                  case CDATA:
                  case SDATA:
                      entityHash.put(Integer.valueOf(data[0]), ent);
                    break;
                }
            }
        }
        return ent;
    }

    /**
     * Returns the <code>Element which matches the
     * specified parameters.  If one doesn't exist, a new
     * one is created and returned.
     *
     * @param name the name of the <code>Element
     * @param type the type of the <code>Element
     * @param omitStart <code>true if start should be omitted
     * @param omitEnd  <code>true if end should be omitted
     * @param content  the <code>ContentModel
     * @param atts the <code>AttributeList specifying the
     *    <code>Element
     * @return the <code>Element specified
     */
    public Element defineElement(String name, int type,
                       boolean omitStart, boolean omitEnd, ContentModel content,
                       BitSet exclusions, BitSet inclusions, AttributeList atts) {
        Element e = getElement(name);
        e.type = type;
        e.oStart = omitStart;
        e.oEnd = omitEnd;
        e.content = content;
        e.exclusions = exclusions;
        e.inclusions = inclusions;
        e.atts = atts;
        return e;
    }

    /**
     * Defines attributes for an {@code Element}.
     *
     * @param name the name of the <code>Element
     * @param atts the <code>AttributeList specifying the
     *    <code>Element
     */
    public void defineAttributes(String name, AttributeList atts) {
        Element e = getElement(name);
        e.atts = atts;
    }

    /**
     * Creates and returns a character <code>Entity.
     * @param name the entity's name
     * @return the new character <code>Entity
     */
    public Entity defEntity(String name, int type, int ch) {
        char data[] = {(char)ch};
        return defineEntity(name, type, data);
    }

    /**
     * Creates and returns an <code>Entity.
     * @param name the entity's name
     * @return the new <code>Entity
     */
    protected Entity defEntity(String name, int type, String str) {
        int len = str.length();
        char data[] = new char[len];
        str.getChars(0, len, data, 0);
        return defineEntity(name, type, data);
    }

    /**
     * Creates and returns an <code>Element.
     * @param name the element's name
     * @return the new <code>Element
     */
    protected Element defElement(String name, int type,
                       boolean omitStart, boolean omitEnd, ContentModel content,
                       String[] exclusions, String[] inclusions, AttributeList atts) {
        BitSet excl = null;
        if (exclusions != null && exclusions.length > 0) {
            excl = new BitSet();
            for (String str : exclusions) {
                if (str.length() > 0) {
                    excl.set(getElement(str).getIndex());
                }
            }
        }
        BitSet incl = null;
        if (inclusions != null && inclusions.length > 0) {
            incl = new BitSet();
            for (String str : inclusions) {
                if (str.length() > 0) {
                    incl.set(getElement(str).getIndex());
                }
            }
        }
        return defineElement(name, type, omitStart, omitEnd, content, excl, incl, atts);
    }

    /**
     * Creates and returns an <code>AttributeList.
     * @param name the attribute list's name
     * @return the new <code>AttributeList
     */
    protected AttributeList defAttributeList(String name, int type, int modifier, String value, String values, AttributeList atts) {
        Vector<String> vals = null;
        if (values != null) {
            vals = new Vector<String>();
            for (StringTokenizer s = new StringTokenizer(values, "|") ; s.hasMoreTokens() ;) {
                String str = s.nextToken();
                if (str.length() > 0) {
                    vals.addElement(str);
                }
            }
        }
        return new AttributeList(name, type, modifier, value, vals, atts);
    }

    /**
     * Creates and returns a new content model.
     * @param type the type of the new content model
     * @return the new <code>ContentModel
     */
    protected ContentModel defContentModel(int type, Object obj, ContentModel next) {
        return new ContentModel(type, obj, next);
    }

    /**
     * Returns a string representation of this DTD.
     * @return the string representation of this DTD
     */
    public String toString() {
        return name;
    }

    /**
     * The hashtable key of DTDs in AppContext.
     */
    private static final Object DTD_HASH_KEY = new Object();

    public static void putDTDHash(String name, DTD dtd) {
        getDtdHash().put(name, dtd);
    }

    /**
     * Returns a DTD with the specified <code>name.  If
     * a DTD with that name doesn't exist, one is created
     * and returned.  Any uppercase characters in the name
     * are converted to lowercase.
     *
     * @param name the name of the DTD
     * @return the DTD which corresponds to <code>name
     */
    public static DTD getDTD(String name) throws IOException {
        name = name.toLowerCase();
        DTD dtd = getDtdHash().get(name);
        if (dtd == null)
          dtd = new DTD(name);

        return dtd;
    }

    private static Hashtable<String, DTD> getDtdHash() {
        AppContext appContext = AppContext.getAppContext();

        Hashtable<String, DTD> result = (Hashtable) appContext.get(DTD_HASH_KEY);

        if (result == null) {
            result = new Hashtable<String, DTD>();

            appContext.put(DTD_HASH_KEY, result);
        }

        return result;
    }

    /**
     * Recreates a DTD from an archived format.
     * @param in  the <code>DataInputStream to read from
     */
    public void read(DataInputStream in) throws IOException {
        if (in.readInt() != FILE_VERSION) {
        }

        //
        // Read the list of names
        //
        String[] names = new String[in.readShort()];
        for (int i = 0; i < names.length; i++) {
            names[i] = in.readUTF();
        }


        //
        // Read the entities
        //
        int num = in.readShort();
        for (int i = 0; i < num; i++) {
            short nameId = in.readShort();
            int type = in.readByte();
            String name = in.readUTF();
            defEntity(names[nameId], type | GENERAL, name);
        }

        // Read the elements
        //
        num = in.readShort();
        for (int i = 0; i < num; i++) {
            short nameId = in.readShort();
            int type = in.readByte();
            byte flags = in.readByte();
            ContentModel m = readContentModel(in, names);
            String[] exclusions = readNameArray(in, names);
            String[] inclusions = readNameArray(in, names);
            AttributeList atts = readAttributeList(in, names);
            defElement(names[nameId], type,
                       ((flags & 0x01) != 0), ((flags & 0x02) != 0),
                       m, exclusions, inclusions, atts);
        }
    }

    private ContentModel readContentModel(DataInputStream in, String[] names)
                throws IOException {
        byte flag = in.readByte();
        switch(flag) {
            case 0:             // null
                return null;
            case 1: {           // content_c
                int type = in.readByte();
                ContentModel m = readContentModel(in, names);
                ContentModel next = readContentModel(in, names);
                return defContentModel(type, m, next);
            }
            case 2: {           // content_e
                int type = in.readByte();
                Element el = getElement(names[in.readShort()]);
                ContentModel next = readContentModel(in, names);
                return defContentModel(type, el, next);
            }
        default:
                throw new IOException("bad bdtd");
        }
    }

    private String[] readNameArray(DataInputStream in, String[] names)
                throws IOException {
        int num = in.readShort();
        if (num == 0) {
            return null;
        }
        String[] result = new String[num];
        for (int i = 0; i < num; i++) {
            result[i] = names[in.readShort()];
        }
        return result;
    }


    private AttributeList readAttributeList(DataInputStream in, String[] names)
                throws IOException  {
        AttributeList result = null;
        for (int num = in.readByte(); num > 0; --num) {
            short nameId = in.readShort();
            int type = in.readByte();
            int modifier = in.readByte();
            short valueId = in.readShort();
            String value = (valueId == -1) ? null : names[valueId];
            Vector<String> values = null;
            short numValues = in.readShort();
            if (numValues > 0) {
                values = new Vector<String>(numValues);
                for (int i = 0; i < numValues; i++) {
                    values.addElement(names[in.readShort()]);
                }
            }
result = new AttributeList(names[nameId], type, modifier, value,
                                       values, result);
            // We reverse the order of the linked list by doing this, but
            // that order isn't important.
        }
        return result;
    }

}

Other Java examples (source code examples)

Here is a short list of links related to this Java DTD.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.