/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 1999 The Apache Software Foundation.  All rights 
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:  
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xerces" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written 
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.apache.org.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

package org.apache.xerces.dom;

import org.w3c.dom.*;

/**
 * EntityReference models the XML &entityname; syntax, when used for
 * entities defined by the DOM. Entities hardcoded into XML, such as
 * character entities, should instead have been translated into text
 * by the code which generated the DOM tree.
 * <P>
 * An XML processor has the alternative of fully expanding Entities
 * into the normal document tree. If it does so, no EntityReference nodes
 * will appear.
 * <P>
 * Similarly, non-validating XML processors are not required to read
 * or process entity declarations made in the external subset or
 * declared in external parameter entities. Hence, some applications
 * may not make the replacement value available for Parsed Entities 
 * of these types.
 * <P>
 * EntityReference behaves as a read-only node, and the children of 
 * the EntityReference (which reflect those of the Entity, and should
 * also be read-only) give its replacement value, if any. They are 
 * supposed to automagically stay in synch if the DocumentType is 
 * updated with new values for the Entity.
 * <P>
 * The defined behavior makes efficient storage difficult for the DOM
 * implementor. We can't just look aside to the Entity's definition
 * in the DocumentType since those nodes have the wrong parent (unless
 * we can come up with a clever "imaginary parent" mechanism). We
 * must at least appear to clone those children... which raises the
 * issue of keeping the reference synchronized with its parent.
 * This leads me back to the "cached image of centrally defined data"
 * solution, much as I dislike it.
 * <P>
 * For now I have decided, since REC-DOM-Level-1-19980818 doesn't
 * cover this in much detail, that synchronization doesn't have to be
 * considered while the user is deep in the tree. That is, if you're
 * looking within one of the EntityReferennce's children and the Entity
 * changes, you won't be informed; instead, you will continue to access
 * the same object -- which may or may not still be part of the tree.
 * This is the same behavior that obtains elsewhere in the DOM if the
 * subtree you're looking at is deleted from its parent, so it's
 * acceptable here. (If it really bothers folks, we could set things
 * up so deleted subtrees are walked and marked invalid, but that's
 * not part of the DOM's defined behavior.)
 * <P>
 * As a result, only the EntityReference itself has to be aware of
 * changes in the Entity. And it can take advantage of the same
 * structure-change-monitoring code I implemented to support
 * DeepNodeList.
 * 
 * @version
 * @since  PR-DOM-Level-1-19980818.
 */
public class EntityReferenceImpl 
    extends ChildAndParentNode
    implements EntityReference {

    //
    // Constants
    //

    /** Serialization version. */
    static final long serialVersionUID = -7381452955687102062L;
    
    //
    // Data
    //

    /** Name of Entity referenced */
    protected String name;

    /** Entity changes. */
	//protected int entityChanges = -1;	

    /** Enable synchronize. */
    //protected boolean fEnableSynchronize = false;

    //
    // Constructors
    //

    /** Factory constructor. */
    public EntityReferenceImpl(DocumentImpl ownerDoc, String name) {
    	super(ownerDoc);
        this.name = name;
        isReadOnly(true);
    }
    
    //
    // Node methods
    //

    /** 
     * A short integer indicating what type of node this is. The named
     * constants for this value are defined in the org.w3c.dom.Node interface.
     */
    public short getNodeType() {
        return Node.ENTITY_REFERENCE_NODE;
    }

    /**
     * Returns the name of the entity referenced
     */
    public String getNodeName() {
        if (needsSyncData()) {
            synchronizeData();
        }
        return name;
    }

    // REVISIT: Return original entity reference code. -Ac

    /**
     * Perform synchronize() before accessing children.
     * 
     * @return org.w3c.dom.NodeList
     */
    public NodeList getChildNodes() {
    	synchronize();
    	return super.getChildNodes();
    }

    /**
     * Perform synchronize() before accessing children.
     * 
     * @return org.w3c.dom.NodeList
     */
    public Node getFirstChild() {
    	synchronize();
    	return super.getFirstChild();
    }

    /**
     * Perform synchronize() before accessing children.
     * 
     * @return org.w3c.dom.NodeList
     */
    public Node getLastChild() {
    	synchronize();
    	return super.getLastChild();
    }

    /**
     * Query the number of children in the entity definition.
     * (A bit more work than asking locally, but may be able to avoid
     * or defer building the clone subtree.)
     *
     * @return org.w3c.dom.NodeList
     */
    public int getLength() {
        synchronize();
    	return super.getLength();
    }

    /**
     * Returns whether this node has any children.
     * @return boolean
     */
    public boolean hasChildNodes() {
    	synchronize();
    	return super.hasChildNodes();
    }

    /** Returns the node at the given index. */
    public Node item(int index) {
    	synchronize();
    	return super.item(index);
    }


    /**
     * EntityReference's children are a reflection of those defined in the
     * named Entity. This method creates them if they haven't been created yet.
     * This doesn't really support editing the Entity though.
     */
    protected void synchronize() {
        if (firstChild != null) {
            return;
        }
    	DocumentType doctype;
    	NamedNodeMap entities;
    	EntityImpl entDef;
    	if (null != (doctype = getOwnerDocument().getDoctype()) && 
            null != (entities = doctype.getEntities())) {
            
            entDef = (EntityImpl)entities.getNamedItem(getNodeName());

            // No Entity by this name, stop here.
            if (entDef == null)
                return;

            // If entity's definition exists, clone its kids
            isReadOnly(false);
            for (Node defkid = entDef.getFirstChild();
                 defkid != null;
                 defkid = defkid.getNextSibling()) {
                Node newkid = defkid.cloneNode(true);
                insertBefore(newkid,null);
            }
            setReadOnly(true, true);
    	}
    }


    /**
     * Enable the synchronize method which may do cloning. This method is enabled
     * when the parser is done with an EntityReference.
    /***
    // revisit: enable editing of Entity
    public void enableSynchronize(boolean enableSynchronize) {
        fEnableSynchronize= enableSynchronize;
    }
    /***/

    /**
     * EntityReference's children are a reflection of those defined in the
     * named Entity. This method updates them if the Entity is changed.
     * <P>
     * It is unclear what the least-cost resynch mechanism is.
     * If we expect the kids to be shallow, and/or expect changes
     * to the Entity contents to be rare, wiping them all out
     * and recloning is simplest.
     * <P>
     * If we expect them to be deep,
     * it might be better to first decide which kids (if any)
     * persist, and keep the ones (if any) that are unchanged
     * rather than doing all the work of cloning them again.
     * But that latter gets into having to convolve the two child lists,
     * insert new information in the right order (and possibly reorder
     * the existing kids), and a few other complexities that I really
     * don't want to deal with in this implementation.
     * <P>
     * Note that if we decide that we need to update the EntityReference's
     * contents, we have to turn off the readOnly flag temporarily to do so.
     * When we get around to adding multitasking support, this whole method
     * should probably be an atomic operation.
     * 
     * @see DocumentTypeImpl
     * @see EntityImpl
     */
     // The Xerces parser invokes callbacks for startEnityReference
     // the parsed value of the entity EACH TIME, so it is actually 
     // easier to create the nodes through the callbacks rather than
     // clone the Entity.
    /***
    // revisit: enable editing of Entity
    private void synchronize() {
        if (!fEnableSynchronize) {
            return;
        }
    	DocumentType doctype;
    	NamedNodeMap entities;
    	EntityImpl entDef;
    	if (null != (doctype = getOwnerDocument().getDoctype()) && 
    		null != (entities = doctype.getEntities())) {
            
    		entDef = (EntityImpl)entities.getNamedItem(getNodeName());

    		// No Entity by this name. If we had a change count, reset it.
    		if(null==entDef)
    			entityChanges=-1;

    		// If no kids availalble, wipe any pre-existing children.
    		// (See discussion above.)
    		// Note that we have to use the superclass to avoid recursion
    		// through Synchronize.
    		readOnly=false;
    		if(null==entDef || !entDef.hasChildNodes())
    			for(Node kid=super.getFirstChild();
    				kid!=null;
    				kid=super.getFirstChild())
    				removeChild(kid);

    		// If entity's definition changed, clone its kids
    		// (See discussion above.)
    		if(null!=entDef && entDef.changes!=entityChanges) {
    			for(Node defkid=entDef.getFirstChild();
    				defkid!=null;
    				defkid=defkid.getNextSibling()) {
                    
    				NodeImpl newkid=(NodeImpl) defkid.cloneNode(true);
    				newkid.setReadOnly(true,true);
    				insertBefore(newkid,null);
    			}
    			entityChanges=entDef.changes;
    		}
    		readOnly=true;
    	}
    }
     /***/
    
} // class EntityReferenceImpl
