EntityManager.java :  » XML » Piccolo » com » bluecast » xml » Java Open Source

Java Open Source » XML » Piccolo 
Piccolo » com » bluecast » xml » EntityManager.java
/*
 * $Id: EntityManager.java,v 1.6 2004/07/11 09:37:37 yuvalo Exp $
 *
 * (C) Copyright 2002-2004 by Yuval Oren. All rights reserved.
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package com.bluecast.xml;

import java.util.*;
import java.io.*;
import java.net.*;

import com.bluecast.util.*;
import org.xml.sax.*;


public class EntityManager {
    // Entity types
    static public final int GENERAL = 0;
    static public final int PARAMETER = 1;

    final private class Entry implements Entity {
        boolean isOpen = false;
        char[] value;
        String pubID, sysID, ndata;
        XMLInputReader reader = null;
        boolean isStandalone = false;

        Entry(String value) {
            pubID = sysID = ndata = null;
            this.value = value.toCharArray();
        }

        Entry(String pubID, String sysID) {
            this(pubID, sysID, null);
        }

        Entry(String pubID, String sysID, String ndata) {
            this.pubID = pubID;
            this.sysID = sysID;
            this.ndata = ndata;
        }

        public void open()
                throws RecursionException, SAXException, IOException {

            if (ndata != null) {
                throw new FatalParsingException("Cannot reference entity; unknown NDATA type '" + ndata + "'");
            }

            if (isOpen)
                throw new RecursionException();

            if (!isInternal()) {
                if (resolver == null) {
                    reader = new XMLStreamReader((new URL(sysID)).openStream(), true);
                } else {
                    InputSource source = resolver.resolveEntity(pubID, sysID);
                    if (source == null) {
                        reader = new XMLStreamReader((new URL(sysID)).openStream(), true);
                    }
                    else {
                        Reader r = source.getCharacterStream();
                        if (r != null)
                            reader = new XMLReaderReader(r, true);
                        else {
                            InputStream in;

                            in = source.getByteStream();
                            if (in != null)
                                reader = new XMLStreamReader(in, source.getEncoding(), true);
                            else
                                reader = new XMLStreamReader((new URL(source.getSystemId())).openStream(),
                                                              source.getEncoding(),true);
                        }
                    }
                }
                isStandalone = reader.isXMLStandalone();
            }
            isOpen = true;
        }

        public boolean isOpen() {
            return isOpen;
        }

        public void close() {
            isOpen = false;
            reader = null;
        }

        public String getSystemID() {
            return sysID;
        }

        public String getPublicID() {
            return pubID;
        }

        public boolean isStandalone() {
            return isStandalone;
        }

        public void setStandalone(boolean standalone) {
            isStandalone = standalone;
        }

        public boolean isInternal() {
            return (sysID == null);
        }

        public boolean isParsed() {
            return (ndata == null);
        }

        public String getDeclaredEncoding() {
            if (reader != null)
                return reader.getXMLDeclaredEncoding();
            else
                return null;
        }

        public boolean isStandaloneDeclared() {
            if (reader != null)
                return reader.isXMLStandaloneDeclared();
            else
                return false;
        }

        public String getXMLVersion() {
            if (reader != null)
                return reader.getXMLVersion();
            else
                return null;
        }


        public Reader getReader() {
            if (isInternal())
                return new CharArrayReader(value);
            else
                return reader;
        }

        public String stringValue() {
            return new String(value);
        }

        public char[] charArrayValue() {
            return value;
        }

    }


    private EntityResolver resolver;
    private Map[] entityMaps = new HashMap[]{new HashMap(), new HashMap()};
    private Map entitiesByURI = new HashMap();

    public EntityManager() {
        this(null);
    }

    public EntityManager(EntityResolver resolver) {
        setResolver(resolver);
    }

    public void setResolver(EntityResolver resolver) {
        this.resolver = resolver;
    }

    public EntityResolver getResolver() {
        return resolver;
    }

    /**
     * Defines an internal entity. Returns true if successful,
     * false if the entity was already defined.
     */
    public boolean putInternal(String name, String value, int type) {
        if (entityMaps[type].get(name) == null) {
            entityMaps[type].put(name, new Entry(value));
            return true;
        }

        return false;
    }

    /**
     * Defines an external entity. Returns true if successful,
     * false if the entity was already defined.
     */
    public boolean putExternal(Entity context, String name,
                               String pubID, String sysID, int type)
            throws MalformedURLException {

        if (entityMaps[type].get(name) == null) {
            // First we resolve the sysID in context of the entity
            sysID = resolveSystemID(context.getSystemID(), sysID);

            // TODO: perhaps we should do this with pubID too

            Entry e = new Entry(pubID, sysID);
            entityMaps[type].put(name, e);
            if (pubID != null && pubID.length() > 0)
                entitiesByURI.put(pubID, e);
            entitiesByURI.put(sysID, e);
            return true;
        }

        return false;
    }

    /**
     * Defines an unparsed entity. Returns true if successful,
     * false if the entity was already defined.
     */

    public boolean putUnparsed(Entity context, String name,
                               String pubID, String sysID, String ndata, int type)
            throws MalformedURLException {

        if (entityMaps[type].get(name) == null) {

            // TODO should unparsed entity system ID's be resolved?
            //sysID = resolveSystemID(context.getSystemID(),sysID);
            entityMaps[type].put(name, new Entry(pubID, sysID, ndata));
            return true;
        }

        return false;
    }

    public void clear() {
        entityMaps[GENERAL].clear();
        entityMaps[PARAMETER].clear();
        entitiesByURI.clear();
    }

    public Entity getByName(String name, int type) {
        return (Entry) entityMaps[type].get(name);
    }


    public Entity getByID(Entity context, String pubID, String sysID)
            throws MalformedURLException {
        Entity result = null;

        sysID = resolveSystemID(context.getSystemID(), sysID);

        result = (Entity) entitiesByURI.get(sysID);
        if (result != null)
            return result;

        if (pubID != null && pubID.length() > 0) {
            result = (Entity) entitiesByURI.get(pubID);
            if (result != null)
                return result;
        }

        // No entity exists for this URI; create one
        result = new Entry(pubID, sysID);
        if (pubID != null && pubID.length() > 0)
            entitiesByURI.put(pubID, result);
        entitiesByURI.put(sysID, result);

        return result;
    }

    static public
    String resolveSystemID(String contextSysID, String sysID)
            throws MalformedURLException {
        URL url;
        if (contextSysID != null)
            url = new URL(new URL(contextSysID), sysID);
        else
            url = new URL(sysID);

        return url.toString();
    }


}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.