/**
 * @(#)RXMLTableModel.java
 * Copyright 2001 Nomura Research Institute, LTD. All rights reserved.
 * RID-3 : XML用TableModel
 * @author  Intelligent Technology Inc.
 * @version 1.00 2001/10/01-2002/03/26
 * @see aUnitTableModel
 */
package	jp.co.nri.rid.table;

/* JAVA */
import	java.util.*;
import	javax.swing.table.AbstractTableModel;

/* W3C */
import	org.w3c.dom.Document;

/* rid */
import	jp.co.nri.Rid;
import	jp.co.nri.rid.xml.*;
import	jp.co.nri.rid.table.comparator.*;

/* ITI */
import jp.co.iti.fagot.util.*;

/**
 * aUnitTableModelを実装したクラス。
 */
public class RXMLTableModel extends aUnitTableModel{
	private elementBooster mySiteRoot;
	private elementBooster myResourceRoot;
	private elementBooster myDocumentRoot;

	/**
	 * @param	document	ドキュメント。
	 * @param	clmdefs		カラム定義。
	 * @see		ClmDef
	 * @since	1.00
	 */
	public RXMLTableModel(Document document ,ClmDefs clmdefs){
		super(document ,clmdefs);
	}
	
	/**
	 * 指定タグ名のUnitを収集する。
	 * @param	tagnames	タグ名配列
	 * @since	1.00
	 */
	protected void collecting(String[] tagnames){
		mySiteRoot		= new documentBooster((Document)ZInstance.map().get(Rid.DOCUMENT_SITE)).root();
		myResourceRoot	= new documentBooster((Document)ZInstance.map().get(Rid.DOCUMENT_RESOURCE)).root();
		myDocumentRoot	= new documentBooster((Document)ZInstance.map().get(Rid.DOCUMENT_DOCUMENT)).root();
		
		RClmDefs clm = (RClmDefs)myClm;
		LineFactory factory = new LineFactory(clm);
		elementBooster root = myDocument.root();
		int mx = tagnames.length;
		for(int i=0;i<mx;i++){
			String tagname = tagnames[i];
			elementBooster[] children = root.offspring(tagname);
			if(null==children)	return;
			
			factory.loaddef(tagname);
			
			int mx2 = children.length;
			for(int j=0;j<mx2;j++){
//				myElements.add(children[j]);
				LineItem line = factory.lineitem(children[j]);
				myElements.add(line);
			}
		}
	}
	
	private class LineFactory{
		private RClmDefs	myClm;
		private ClmData[]	myClmDatas;
		private int			myDataCount;
		private UnitMap		myUnitMap;
		
		public LineFactory(RClmDefs clmdefs){ myClm = clmdefs; }
		public void loaddef(String tagname){
			myUnitMap = new UnitMap();
			
			ClmDef[] defs	= myClm.tagEdge(tagname);
			myDataCount		= defs.length;
			
			myClmDatas = new ClmData[myDataCount];
			for(int i=0;i<myDataCount;i++){
				ClmData	data	= new ClmData(defs[i].name ,tagname ,myClm);
				myClmDatas[i]	= data;
			}
		}
		
		public LineItem lineitem(elementBooster element){
			elementBooster root = element.document().root();
			
			LineItem line = new LineItem(element);
			
			for(int i=0;i<myDataCount;i++){
				ClmData data = myClmDatas[i];
				elementBooster elem = null;
				if(null!=data.runit){
					StringTokenizer st = new StringTokenizer(data.runit ," ");
					for(int k=st.countTokens();0<k;k--){
						String runit = st.nextToken();
//						elem = myUnitMap.unit(data.runit ,data.rkey ,getKey(element ,data.key) ,(null==data.rroot) ? root : data.rroot);
						elem = myUnitMap.unit(runit ,data.rkey ,getKey(element ,data.key) ,(null==data.rroot) ? root : data.rroot);
						if(null!=elem)	break;
					}
				}
				else	elem = element;
				
				line.cellitem(data.name ,new CellItem(elem ,(null==data.rattr) ? data.name : data.rattr ));
			}
			
			return line;
		}
	}
	
	private String getKey(elementBooster element ,String keyname){
		StringTokenizer st = new StringTokenizer(keyname ,".");
		for(int i=st.countTokens()-1;0<i;i--){
			element = element.child(st.nextToken());
		}
		
		return element.attribute(st.nextToken());
	}
	
	private class ClmData{
		public String name;
		public elementBooster rroot	= null;
		public String runit			= null;
		public String rattr;
		public String key;
		public String rkey;
		
		public ClmData(String Name ,String tagname ,RClmDefs defs){
			name	= Name;
//			runit	= defs.attributemap.unit(tagname ,name);
			String rname	= defs.attributemap.unit(tagname ,name);
			rattr	= defs.attributemap.attr(tagname ,name);
			
			key		= defs.keymap.mykey(tagname ,rname);
			rkey	= defs.keymap.unitkey(tagname ,rname);
			
			String rdu	= defs.keymap.unitname(tagname ,rname);
			if(null!=rdu){
				StringTokenizer st = new StringTokenizer(rdu ,".");
				switch(st.countTokens()){
				case 1:
					runit		= rdu;
					break;
				case 2:
					String rdocument= st.nextToken();
					runit			= st.nextToken();
					if("site".equals(rdocument))			rroot = mySiteRoot;
					else if("resource".equals(rdocument))	rroot = myResourceRoot;
					else if("document".equals(rdocument))	rroot = myDocumentRoot;
					break;
				}
			}
		}
	}
}
