/*
 * @(#)XDocument.java
 *
 * Copyright 2001 by Intelligent Technology Inc. All rights reserved.
 */
package jp.co.iti.fagot.fob.xml;

import org.w3c.dom.*;

import org.apache.xerces.dom.DocumentImpl;
import org.apache.xerces.dom.ElementDefinitionImpl;

import org.apache.xerces.utils.StringPool;

import jp.co.iti.fagot.fob.FobManager;

import jp.co.iti.fagot.util.ZDebug;
/**
 * Xerces DOM Treeを undoableにするためのドキュメントです。
 *
 * 次の方法で呼び出すとこのドキュメントが作成されます。
 *	DOMParser parser = new DOMParser();
 *	parser.setProperty("http://apache.org/xml/properties/dom/document-class-name",new String("class name"));
 *	InputSource in = new InputSource("file:/c:/work/R2/project/test/01Project.xml");
 *	parser.parse(in);
 *	doc = (DocDocument)parser.getDocument();
 *
 * 基本的に、org.apache.xerces.dom.DocumentImplのオーバライドですが、undoが必要である
 * ことが判明してからインプリメントします。
 *
 * @author  福島康治
 * @version 1.01 2001/03/22
 */
public class XDocument extends DocumentImpl {

	/**
	 * コンストラクタ
	 */
	public XDocument(){
//	createDocument();
	}

	//## プロパティ ###################################################
	/**
	 * データマネージャの取得
	 */
	public FobManager getFobManager(){
	return mFobManager ;
	}

	/**
	 * 更新状態の初期化
	 * ドキュメントが保存されたときに更新状態を初期化するために呼び出されます
	 */
	public void setModified() {
	mFobManager.setModified() ;
	}

	/**
	 * 更新状態の取得
	 */
	public boolean isModified() {
	return mFobManager.isModified() ;
	}

	//## データ操作####################################################
	/**
	 * トランザクション中か？
	 */
	public boolean isTransaction() {
	boolean bRet = false;
	if ( mFobManager != null ) {
		bRet = mFobManager.isTransaction();
	}
	return bRet;
	}

	/**
	 * トランザクションの開始
	 */
	public void beginTransaction() {
	if ( mFobManager != null ) {
		mFobManager.beginTransaction();
	}
	}

	/**
	 * コミット
	 */
	public void commit() {
	if ( mFobManager != null ) {
		mFobManager.commit();
	}
	}

	/**
	 * 追加コミット
	 */
	public void commitPlus() {
	if ( mFobManager != null ) {
		mFobManager.commitPlus();
	}
	}

	/**
	 * ロールバック
	 */
	public void rollback() {
	if ( mFobManager != null ) {
		mFobManager.rollback();
	}
	}

	//## IZUndoableインターフェイス ###################################
	/**
	 * undo
	 */
	public void doUndo() {
	mFobManager.undo() ;
	}

	/**
	 * redo
	 */
	public void doRedo() {
	mFobManager.redo() ;
	}

	/**
	 * undoの問い合わせ
	 */
	public boolean canUndo() {
	return mFobManager.canUndo() ;
	}

	/**
	 * redoの問い合わせ
	 */
	public boolean canRedo() {
	return mFobManager.canRedo() ;
	}

	//## オーバライド：ドキュメント操作 ###############################
	/**
	 * 挿入
	 */
    public Node insertBefore(Node newChild, Node refChild) throws DOMException {
//	ZDebug.trace("insert:"+newChild.toString());
	return super.insertBefore(newChild,refChild);
	}

	/**
	 * 削除
	 */
    public Node removeChild(Node oldChild) throws DOMException {
	ZDebug.trace("remove:"+oldChild.toString());
	return super.removeChild(oldChild);
	}

	/**
	 * 置換
	 */
    public Node replaceChild(Node newChild, Node oldChild) throws DOMException {
	ZDebug.trace("remove:"+oldChild.toString());
	return super.removeChild(oldChild);
	}

	//## オーバライド：DOMファクトリー ################################
	/**
	 * アトリビュート
	 */
	public Attr createAttribute(String name) throws DOMException {
//	ZDebug.trace("\t:create:"+name);
	return super.createAttribute(name);
	}

	/**
	 * データセクション
	 */
	public CDATASection createCDATASection(String data) throws DOMException {
	ZDebug.trace("\t:create:"+data);
	return super.createCDATASection(data);
	}

	/**
	 * コメント
	 */
	public Comment createComment(String data) {
//	ZDebug.trace("\t:create:"+data);
	return super.createComment(data);
	}

	/**
	 * ドキュメントフラグメント
	 */
	public DocumentFragment createDocumentFragment() {
	ZDebug.trace("\t:create:");
	return super.createDocumentFragment();
	}

	/**
	 * エレメント
	 */
	public Element createElement(String tagName) throws DOMException {
	ZDebug.trace("\t:create:"+tagName);
	return super.createElement(tagName);
	}

	/**
	 * エンティティリファレンス
	 */
	public EntityReference createEntityReference(String name) throws DOMException {
	ZDebug.trace("\t:create:"+name);
	return super.createEntityReference(name);
	}

	/**
	 * ProcessingInstruction
	 */
	public ProcessingInstruction createProcessingInstruction(String target, String data) throws DOMException {
	return super.createProcessingInstruction(target,data);
	}

	/**
	 * text
	 */
	public Text createTextNode(String data) {
	return super.createTextNode(data);
	}

	//## オーバライド：non-DOMファクトリー ############################
	/**
	 * ドキュメントタイプ(変更されないのでオーバライドしない)
	 */
/*
	public DocumentType createDocumentType(String qualifiedName,
                                           String publicID,
                                           String systemID)
        throws DOMException {
	ZDebug.trace("\t:create:"+qualifiedName+","+publicID+","+systemID);
	ZDebug.printStack();
	return super.createDocumentType(qualifiedName,publicID,systemID);
	}
*/
	/**
	 * エンティティ
	 */
	public Entity createEntity(String name) throws DOMException {
	ZDebug.trace("\t:create:"+name);
	return super.createEntity(name);
	}

	/**
	 * Notation
	 */
	public Notation createNotation(String name) throws DOMException {
	ZDebug.trace("\t:create:"+name);
	return super.createNotation(name);
	}

	/**
	 * ElementDefinition
	 */
	public ElementDefinitionImpl createElementDefinition(String name) throws DOMException {
//	ZDebug.trace("\t:create:"+name);
	return super.createElementDefinition(name);
	}

	//## オーバライド：non-DOMメソッド ################################
	/**
	 * インポート
	 */
	public Node importNode(Node source, boolean deep) throws DOMException {
	ZDebug.trace("\t:import:"+source.toString());
	return super.importNode(source,deep);
	}

	/**
	 * adopt
	 */
	public Node adoptNode(Node source) {
	ZDebug.trace("\t:adopt:"+source.toString());
	return super.adoptNode(source);
	}

	/**
	 * Identifier追加
	 */
	public void putIdentifier(String idName, Element element) {
	ZDebug.trace("\t:putIdentifier:"+idName+","+element.toString());
	super.putIdentifier(idName,element);
	}

	/**
	 * Identifier削除
	 */
	public void removeIdentifier(String idName) {
	ZDebug.trace("\t:removeIdentifier:"+idName);
	super.removeIdentifier(idName);
	}

	//## オーバライド：DOM2 NameSpace ファクトリー ####################
	/**
	 * エレメント
	 */
	public Element createElementNS(String namespaceURI, String qualifiedName) throws DOMException {
	ZDebug.trace("\t:create:"+namespaceURI+","+qualifiedName);
	return new XElementNS(this,namespaceURI,qualifiedName);
//	return super.createElementNS(namespaceURI,qualifiedName);
	}

	/**
	 * アトリビュート
	 */
	public Attr createAttributeNS(String namespaceURI, String qualifiedName) throws DOMException {
//	ZDebug.trace("\t:create:"+namespaceURI+","+qualifiedName);
	return super.createAttributeNS(namespaceURI,qualifiedName);
	}

	//## デバッグ #####################################################
	public static void dump(Node node) {
	switch ( node.getNodeType() ) {
	  case Node.DOCUMENT_NODE :
		ZDebug.trace("DumpDocument:"+node);
		DocumentType doctype = ( (Document) node ).getDoctype();
		ZDebug.trace("    doctype:"+doctype);
		break;
	  default:
		ZDebug.trace("Dump:"+node);
		break;
	}
	}

    /** Ensures that the internal tables are large enough. */
/*
    protected boolean ensureCapacity(int chunk, int index) {
	ZDebug.trace("!!!!");
	return super.ensureCapacity(chunk, index);
	}
*/
/*
    public short getNodeType(int nodeIndex, boolean free) {
	ZDebug.trace("!!!!fNodeType.length:"+fNodeType.length);
//DEBUG_PRINT_REF_COUNTS = true;
        int chunk = nodeIndex >> CHUNK_SHIFT;
        int index = nodeIndex & CHUNK_MASK;
			ZDebug.trace( "chunk:"+chunk+"\tindex:"+index);
            if (fNodeType[chunk] != null) {
					ZDebug.trace("\tfNodeType:"+fNodeType[chunk][index]);
			} else {
				ZDebug.trace( "fNodeType[chunk]=null");
			}
	        return super.getNodeType(nodeIndex, free);
    } // getNodeType(int):int
*/
	//## アトリビュート################################################
	/**
	 * Fobマネージャ
	 */
	protected FobManager	mFobManager = new FobManager();
}
