/*
 * (C) Copyright The MITRE Corporation 1999  All rights reserved. 
 * 
 * The contents of this file are subject to the Mozilla Public License 
 * Version 1.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.mozilla.org/MPL/ 
 * 
 * The program provided "as is" without any warranty express or 
 * implied, including the warranty of non-infringement and the implied 
 * warranties of merchantibility and fitness for a particular purpose. 
 * The Copyright owner will not be liable for any damages suffered by 
 * you as a result of using the Program. In no event will the Copyright 
 * owner be liable for any special, indirect or consequential damages or 
 * lost profits even if the Copyright owner has been advised of the 
 * possibility of their occurrence. 
 * 
 * Please see release.txt distributed with this file for more information. 
 * 
 */ 
// Tom Kneeland (01/13/2000) 
// 
//  Implementation of the Mozilla Wrapper classes for the Mozilla DOM to 
//  TransforMIIX DOM interface conversion.  Note that these wrapper classes are 
//  only interchangable with the TransforMIIX DOM at compile time.  They are 
//  merely a copy of the TransforMIIX interface/class structure wich then 
//  deffer their processing to a Mozilla object.  Complete interchangability 
//  would require the use of multiple inherritance using virtual base classes 
//  and RTTI which is not supported in Mozilla's cross platform domain. 
// 
//  NOTE:  The objects being wrapped are not deleted.  It is assumed that they 
//         will be deleted when the actual ("real") Mozilla Document is 
//         destroyed 
// 
//         Also note that the Document wrapper class maintains a hash table of 
//         wrapper object.  The objects are hashed based on the address of the 
//         mozilla object they are wrapping.  When ever a new wrapper object is 
//         created, the Hash Table should first be check to see if one already 
//         exists. 
// 
// Modification History: 
// Who  When        What 
// TK   02/11/2000  Added a default constructor for the Document class.  Simply 
//                  create an nsXMLDocument object is one is not provided. 
 
#ifndef MOZILLA_MITRE_DOM 
#define MOZILLA_MITRE_DOM 
 
#ifdef __BORLANDC__ 
#include <stdlib.h> 
#endif 
 
#include "MozillaString.h" 
#include "baseutils.h" 
#include "HashTable.h" 
 
//A bunch of Mozilla DOM headers 
#include "nsIDOMNode.h" 
#include "nsIDOMDocument.h" 
#include "nsIDOMElement.h" 
#include "nsIDOMProcessingInstruction.h" 
#include "nsIDOMAttr.h" 
#include "nsIDOMCDATASection.h" 
#include "nsIDOMText.h" 
#include "nsIDOMDOMImplementation.h" 
#include "nsIDOMDocumentType.h" 
#include "nsIDOMEntityReference.h" 
#include "nsIDOMDocumentFragment.h" 
#include "nsIDOMComment.h" 
#include "nsIDOMNodeList.h" 
#include "nsIDOMNotation.h" 
#include "nsIDOMEntity.h" 
#include "nsIDOMNamedNodeMap.h" 
#include "nsIDOMCharacterData.h" 
 
#ifndef NULL 
typedef 0 NULL; 
#endif 
 
 
typedef MozillaString DOMString; 
typedef UNICODE_CHAR DOM_CHAR; 
 
class NodeList; 
class NamedNodeMap; 
class Document; 
class Element; 
class Attr; 
class Text; 
class Comment; 
class CDATASection; 
class ProcessingInstruction; 
class EntityReference; 
class Entity; 
class DocumentType; 
class Notation; 
 
// 
//Wrapper class for nsIDOMDOMImplementation.  Convert to TransforMIIX 
//DOMImplementation interface. 
// 
class DOMImplementation : public MITREObject 
{ 
  public: 
    DOMImplementation(nsIDOMDOMImplementation* domImpl, Document* owner); 
    ~DOMImplementation(); 
 
    void setNSObj(nsIDOMDOMImplementation* domImpl); 
 
    virtual MBool hasFeature(const DOMString& feature, const DOMString& version) const; 
 
  private: 
    nsIDOMDOMImplementation* nsDOMImpl; 
 
    Document* ownerDocument; 
}; 
 
// 
// Definition and Implementation of the Node Wrapper class.  It provides the 
// generic Node interface, forwarding all functionality to its Mozilla 
// counterpart. 
// 
class Node : public MITREObject 
{ 
  public: 
    //Node type constants 
    //-- LF - changed to enum 
    enum NodeType { 
        ELEMENT_NODE = 1, 
        ATTRIBUTE_NODE, 
        TEXT_NODE, 
        CDATA_SECTION_NODE, 
        ENTITY_REFERENCE_NODE, 
        ENTITY_NODE, 
        PROCESSING_INSTRUCTION_NODE, 
        COMMENT_NODE, 
        DOCUMENT_NODE, 
        DOCUMENT_TYPE_NODE, 
        DOCUMENT_FRAGMENT_NODE, 
        NOTATION_NODE 
    }; 
 
    Node(); 
    Node(nsIDOMNode* node, Document* owner); 
    virtual ~Node(); 
 
    virtual void setNSObj(nsIDOMNode* node); 
    void setNSObj(nsIDOMNode* node, Document* owner); 
    nsIDOMNode* getNSObj(); 
 
    //Read functions 
    virtual const DOMString& getNodeName(); 
    virtual const DOMString& getNodeValue(); 
    virtual unsigned short getNodeType() const; 
    virtual Node* getParentNode(); 
    virtual NodeList* getChildNodes(); 
    virtual Node* getFirstChild(); 
    virtual Node* getLastChild(); 
    virtual Node* getPreviousSibling(); 
    virtual Node* getNextSibling(); 
    virtual NamedNodeMap* getAttributes(); 
    virtual Document* getOwnerDocument(); 
 
    //Write functions 
    virtual void setNodeValue(const DOMString& nodeValue); 
 
    //Node manipulation functions 
    virtual Node* insertBefore(Node* newChild, Node* refChild); 
    virtual Node* replaceChild(Node* newChild, Node* oldChild); 
    virtual Node* removeChild(Node* oldChild); 
    virtual Node* appendChild(Node* newChild); 
    virtual Node* cloneNode(MBool deep, Node* dest); 
 
    virtual MBool hasChildNodes() const; 
 
  protected: 
    //We want to maintain a pointer back to the owner document for Hash/ 
    //memory management. 
    Document* ownerDocument; 
 
  private: 
    nsIDOMNode* nsNode; 
 
    //Maintain a few DOMString objects to ensure proper handling of references 
    DOMString nodeName; 
    DOMString nodeValue; 
}; 
 
// 
//Wrapper class for nsIDOMNodeList.  Convert to TransforMIIX 
//NodeList interface. 
// 
class NodeList : public MITREObject 
{ 
  public: 
    NodeList(nsIDOMNodeList* nodeList, Document* owner); 
    ~NodeList(); 
 
    Node* item(UInt32 index); 
    UInt32 getLength(); 
  protected: 
    nsIDOMNodeList* nsNodeList; 
 
    Document* ownerDocument; 
}; 
 
 
// 
//Wrapper class for nsIDOMNamedNodeMap.  Convert to TransforMIIX 
//NameNodeMap interface. 
// 
class NamedNodeMap : public MITREObject 
{ 
  public: 
    NamedNodeMap(nsIDOMNamedNodeMap* namedNodeMap, Document* owner); 
    ~NamedNodeMap(); 
 
    Node* getNamedItem(const DOMString& name); 
    Node* setNamedItem(Node* arg); 
    Node* removeNamedItem(const DOMString& name); 
    Node* item(UInt32 index); 
    UInt32 getLength(); 
 
  private: 
    nsIDOMNamedNodeMap* nsNamedNodeMap; 
    Document* ownerDocument; 
}; 
 
// 
//Wrapper class for nsIDOMDocumentFragment.  Convert to TransforMIIX 
//DocumentFragment interface. 
// 
class DocumentFragment : public Node 
{ 
  public: 
    DocumentFragment(nsIDOMDocumentFragment* docFragment, Document* owner); 
    ~DocumentFragment(); 
 
    void setNSObj(nsIDOMDocumentFragment* docFragment); 
 
    //TK - Just deffer to the Node Implementation since it already has a pointer 
    //     to the proper "polymorphed" object. 
    //Override insertBefore to limit Elements to having only certain nodes as 
    //children 
    //Node* insertBefore(Node* newChild, Node* refChild); 
 
  private: 
    nsIDOMDocumentFragment* nsDocumentFragment; 
}; 
 
// 
//Wrapper class for nsIDOMDocument.  Convert to TransforMIIX 
//Document interface. 
// 
class Document : public Node 
{ 
  public: 
    Document(); 
    Document(nsIDOMDocument* document); 
    ~Document(); 
 
    virtual void setNSObj(nsIDOMDocument* node); 
 
    Element* getDocumentElement(); 
    DocumentType* getDoctype(); 
    DOMImplementation* getImplementation(); 
 
    //Provide a means to remove items from the wrapperHashTable 
    MITREObject* removeWrapper(Int32 hashValue); 
     
    //Provide a means to place a specific wrapper in the hash table 
    //This is needed to support the concept of "cloning" a node where 
    //a precreated destination wrapper is provided as a destination. 
    //We need to be able to remove the provided wrapper (above) so a new 
    //object can be associated with it, then placed back in the hash 
    void addWrapper(MITREObject* obj, Int32 hashValue); 
 
    //Factory functions for various node types.  These functions 
    //are responsible for storing the wrapper classes they create in  
    //the document's wrapperHashTable. 
    //Note the addition of the factory functions to "wrap" 
    //nsIDOM* objects. 
    DocumentFragment* createDocumentFragment(); 
    DocumentFragment* createDocumentFragment(nsIDOMDocumentFragment* fragment); 
     
    Element* createElement(const DOMString& tagName); 
    Element* createElement(nsIDOMElement* element); 
     
    Attr* createAttribute(const DOMString& name); 
    Attr* createAttribute(nsIDOMAttr* attr); 
 
    Text* createTextNode(const DOMString& theData); 
    Text* createTextNode(nsIDOMText* text); 
 
    Comment* createComment(const DOMString& theData); 
    Comment* createComment(nsIDOMComment* comment); 
 
    CDATASection* createCDATASection(const DOMString& theData); 
    CDATASection* createCDATASection(nsIDOMCDATASection* cdata); 
 
    ProcessingInstruction* createProcessingInstruction(const DOMString& target, 
                                                       const DOMString& data); 
    ProcessingInstruction* createProcessingInstruction( 
    			      nsIDOMProcessingInstruction* pi); 
 
    EntityReference* createEntityReference(const DOMString& name); 
    EntityReference* createEntityReference(nsIDOMEntityReference* entiyRef); 
 
    Entity* createEntity(nsIDOMEntity* entity); 
 
    Node* createNode(nsIDOMNode* node); 
    DOMString* createDOMString(nsString* str); 
    Notation* createNotation(nsIDOMNotation* notation); 
    DOMImplementation* createDOMImplementation(nsIDOMDOMImplementation* impl); 
    DocumentType* createDocumentType(nsIDOMDocumentType* doctype); 
    NodeList* createNodeList(nsIDOMNodeList* list); 
    NamedNodeMap* createNamedNodeMap(nsIDOMNamedNodeMap* map); 
 
    //Determine what kind of node this is, and create the appropriate wrapper 
    //for it. 
    Node* createWrapper(nsIDOMNode* node); 
 
    //TK - Just deffer to the Node implementation 
    // 
    //Override functions to enforce the One Element rule for documents, as well 
    //as limit documents to certain types of nodes. 
    //Node* insertBefore(Node* newChild, Node* refChild); 
    //Node* replaceChild(Node* newChild, Node* oldChild); 
    //Node* removeChild(Node* oldChild); 
 
  private: 
    nsIDOMDocument* nsDocument; 
 
    //Hash tables to maintain wrapper objects.   
    //NOTE:  Should we maintain separate hash table for NamedNodeMaps and 
    //       NodeLists? 
    HashTable wrapperHashTable; 
}; 
 
// 
//Wrapper class for nsIDOMElement.  Convert to TransforMIIX 
//Element interface. 
// 
class Element : public Node 
{ 
  public: 
  //Element(); 
    Element(nsIDOMElement* element, Document* owner); 
    ~Element(); 
 
    virtual void setNSObj(nsIDOMElement* element); 
 
    //TK - Just deffer to the Node Implementation 
    // 
    //Override insertBefore to limit Elements to having only certain nodes as 
    //children 
    //Node* insertBefore(Node* newChild, Node* refChild); 
 
    const DOMString& getTagName(); 
    const DOMString& getAttribute(const DOMString& name); 
    void setAttribute(const DOMString& name, const DOMString& value); 
    void removeAttribute(const DOMString& name); 
    Attr* getAttributeNode(const DOMString& name); 
    Attr* setAttributeNode(Attr* newAttr); 
    Attr* removeAttributeNode(Attr* oldAttr); 
    NodeList* getElementsByTagName(const DOMString& name); 
    void normalize(); 
 
  private: 
    nsIDOMElement* nsElement; 
}; 
 
// 
//Wrapper class for nsIDOMAttr.  Convert to TransforMIIX 
//Attr interface. 
// 
class Attr : public Node 
{ 
  public: 
    Attr(nsIDOMAttr* attr, Document* owner); 
    ~Attr(); 
 
    nsIDOMAttr* getNSAttr(); 
    virtual void setNSObj(nsIDOMAttr* attr); 
 
    const DOMString& getName(); 
    MBool getSpecified() const; 
    const DOMString& getValue(); 
    void setValue(const DOMString& newValue); 
 
    //TK - Simply deffer to Node Implementation 
    //Override the set and get member functions for a node's value to create a 
    //new TEXT node when set, and to interpret its children when read. 
    //void setNodeValue(const DOMString& nodeValue); 
    //const DOMString& getNodeValue(); 
 
    //Override insertBefore to limit Attr to having only certain nodes as 
    //children 
    //Node* insertBefore(Node* newChild, Node* refChild); 
 
  private: 
    // 
    //I don't think we need these since the MozillaString objects will 
    //delete their nsString objects when they are destroyed. 
    // 
    //We don't want to make any assumptions about the implementation of 
    //the NS attribute object, so keep these around to store the name and 
    //value of the attribute when requested by the user. 
    //We don't want to make any assumptions about the implementation of 
    //DOMString attrName; 
    //DOMString attrValue; 
 
    nsIDOMAttr* nsAttr; 
}; 
 
// 
//Wrapper class for nsIDOMCharacterData.  Convert to TransforMIIX 
//CharacterData interface. 
// 
class CharacterData : public Node 
{ 
  public: 
    virtual ~CharacterData(); 
 
    virtual void setNSObj(nsIDOMCharacterData* charData); 
 
    const DOMString& getData() const; 
    void setData(const DOMString& source); 
    Int32 getLength() const; 
 
    DOMString& substringData(Int32 offset, Int32 count, DOMString& dest); 
    void appendData(const DOMString& arg); 
    void insertData(Int32 offset, const DOMString& arg); 
    void deleteData(Int32 offset, Int32 count); 
    void replaceData(Int32 offset, Int32 count, const DOMString& arg); 
 
  protected: 
    CharacterData(nsIDOMCharacterData* charData, Document* owner); 
 
  private: 
    nsIDOMCharacterData* nsCharacterData; 
}; 
 
// 
//Wrapper class for nsIDOMText.  Convert to TransforMIIX 
//Text interface. 
// 
class Text : public CharacterData 
{ 
  public: 
    Text(nsIDOMText* text, Document* owner); 
    ~Text(); 
 
    virtual void setNSObj(nsIDOMText* text); 
 
    Text* splitText(Int32 offset); 
 
    //TK - simply deffer to Node implementation 
    //Override "child manipulation" function since Text Nodes can not have 
    //any children. 
    //Node* insertBefore(Node* newChild, Node* refChild); 
    //Node* replaceChild(Node* newChild, Node* oldChild); 
    //Node* removeChild(Node* oldChild); 
    //Node* appendChild(Node* newChild); 
 
  private: 
    nsIDOMText* nsText; 
}; 
 
// 
//Wrapper class for nsIDOMComment.  Convert to TransforMIIX 
//Comment interface. 
// 
class Comment : public CharacterData 
{ 
  public: 
    Comment(nsIDOMComment* comment, Document* owner); 
    ~Comment(); 
 
    virtual void setNSObj(nsIDOMComment* comment); 
 
    //TK - Simply defer to Node Implementation 
    //Override "child manipulation" function since Comment Nodes can not have 
    //any children. 
    //Node* insertBefore(Node* newChild, Node* refChild); 
    //Node* replaceChild(Node* newChild, Node* oldChild); 
    //Node* removeChild(Node* oldChild); 
    //Node* appendChild(Node* newChild); 
 
  private: 
    nsIDOMComment* nsComment; 
}; 
 
// 
//Wrapper class for nsIDOMCDATASection.  Convert to TransforMIIX 
//CDATASection interface. 
// 
class CDATASection : public Text 
{ 
  public: 
    CDATASection(nsIDOMCDATASection* cdataSection, Document* owner); 
    ~CDATASection(); 
 
    virtual void setNSObj(nsIDOMCDATASection* cdataSection); 
 
    //TK - Simply defer to Node Implementation 
    //Override "child manipulation" function since CDATASection Nodes can not 
    //have any children. 
    //Node* insertBefore(Node* newChild, Node* refChild); 
    //Node* replaceChild(Node* newChild, Node* oldChild); 
    //Node* removeChild(Node* oldChild); 
    //Node* appendChild(Node* newChild); 
 
  private: 
    nsIDOMCDATASection* nsCDATASection; 
}; 
 
// 
//Wrapper class for nsIDOMProcessingInstruction.  Convert to TransforMIIX 
//ProcessingInstruction interface. 
// 
class ProcessingInstruction : public Node 
{ 
  public: 
    ProcessingInstruction(nsIDOMProcessingInstruction* procInstr,  
			  Document* owner); 
    ~ProcessingInstruction(); 
 
    virtual void setNSObj(nsIDOMProcessingInstruction* procInstr); 
 
    const DOMString& getTarget() const; 
    const DOMString& getData() const; 
 
    void setData(const DOMString& theData); 
 
    //TK - Defer to Node Implementation 
    //Override "child manipulation" function since ProcessingInstruction Nodes 
    //can not have any children. 
    //Node* insertBefore(Node* newChild, Node* refChild); 
    //Node* replaceChild(Node* newChild, Node* oldChild); 
    //Node* removeChild(Node* oldChild); 
    //Node* appendChild(Node* newChild); 
 
  private: 
    nsIDOMProcessingInstruction* nsProcessingInstruction; 
}; 
 
// 
//Wrapper class for nsIDOMNotation.  Convert to TransforMIIX 
//Notation interface. 
// 
class Notation : public Node 
{ 
  public: 
    Notation(nsIDOMNotation* notation, Document* owner); 
    ~Notation(); 
 
    virtual void setNSObj(nsIDOMNotation* notation); 
 
    const DOMString& getPublicId() const; 
    const DOMString& getSystemId() const; 
 
    //TK - Simply Defer to Node Implemntation 
    //Override "child manipulation" function since Notation Nodes 
    //can not have any children. 
    //Node* insertBefore(Node* newChild, Node* refChild); 
    //Node* replaceChild(Node* newChild, Node* oldChild); 
    //Node* removeChild(Node* oldChild); 
    //Node* appendChild(Node* newChild); 
 
  private: 
    nsIDOMNotation* nsNotation; 
}; 
 
// 
//Wrapper class for nsIDOMEntity.  Convert to TransforMIIX 
//Entity interface. 
// 
class Entity : public Node 
{ 
  public: 
    Entity(nsIDOMEntity* entity, Document* owner); 
    ~Entity(); 
 
    virtual void setNSObj(nsIDOMEntity* entity); 
 
    const DOMString& getPublicId() const; 
    const DOMString& getSystemId() const; 
    const DOMString& getNotationName() const; 
 
    //TK - Defer to Node Implementation 
    //Override insertBefore to limit Entity to having only certain nodes as 
    //children 
    //Node* insertBefore(Node* newChild, Node* refChild); 
 
  private: 
    nsIDOMEntity* nsEntity; 
}; 
 
// 
//Wrapper class for nsIDOMEntityReference.  Convert to TransforMIIX 
//EntityReference interface. 
// 
class EntityReference : public Node 
{ 
  public: 
    EntityReference(nsIDOMEntityReference* entityReference, Document* owner); 
    ~EntityReference(); 
 
    virtual void setNSObj(nsIDOMEntityReference* entityReference); 
 
    //TK - Simply defer to Node Implementation 
    //Override insertBefore to limit EntityReference to having only certain 
    //nodes as children 
    //Node* insertBefore(Node* newChild, Node* refChild); 
 
  private: 
    nsIDOMEntityReference* nsEntityReference; 
}; 
 
// 
//Wrapper class for nsIDOMDocumentType.  Convert to TransforMIIX 
//Document interface. 
// 
class DocumentType : public Node 
{ 
  public: 
    DocumentType(); 
    DocumentType(nsIDOMDocumentType* documentType, Document* owner); 
    ~DocumentType(); 
 
    void setNSObj(nsIDOMDocumentType* documentType); 
 
    const DOMString& getName() const; 
    NamedNodeMap* getEntities(); 
    NamedNodeMap* getNotations(); 
 
    //TK - Simply deffer to Node Implementation 
    //Override "child manipulation" function since Notation Nodes 
    //can not have any children. 
    //Node* insertBefore(Node* newChild, Node* refChild); 
    //Node* replaceChild(Node* newChild, Node* oldChild); 
    //Node* removeChild(Node* oldChild); 
    //Node* appendChild(Node* newChild); 
 
  private: 
    nsIDOMDocumentType* nsDocumentType; 
}; 
 
//NULL string for use by Element::getAttribute() for when the attribute 
//spcified by "name" does not exist, and therefore shoud be "NULL". 
const DOMString NULL_STRING; 
 
#endif 
