/**
 * @(#)RHTMLAnalyzer.java
 * Copyright 2001 Nomura Research Institute, LTD. All rights reserved.
 * RID-3 : RID HTML Analizer
 * @author  Intelligent Technology Inc.
 * @version 1.00 2001/10/01-2001/12/28
 * @see 
 */
package	jp.co.nri.rid.analyzer;

/* JAVA */
import javax.swing.*;
import javax.swing.table.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;

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

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

/* rid */
import	jp.co.nri.Rid;
import	jp.co.nri.Ridual;
import	jp.co.nri.rid.xml.*;
import	jp.co.nri.rid.table.*;
import	jp.co.nri.rid.importer.*;
import	jp.co.nri.rid.mapper.*;
import	jp.co.nri.rid.error.*;

/**
 * インポートされたページを解析する。
 */

public class RHTMLAnalyzer implements iExceptionCode{
	private static final String PAGEUNIT		= "PageUnit";
	private static final String FILE			= "File";
	private static final String PAGE			= "Page";
	private static final String EXIST			= "Exist";
	private static final String TRUE			= "true";
	private static final String FALSE			= "false";
	private static final String KEY_TEMPLATE	= "rid.template.dir";
//	private static final String KEY_HTML		= "rid.html.dir";
	private static final String MAP_PROGRESS	= "progress_map.xml";
	private static final String XML_REPORT		= "report.xml";
	private static final String ELEMENT_ROOT	= "RidProject";
	private static final String SEPARATOR		= "/";
	private static final String SERVER			= "server";
	private static final String PAGETYPE		= "PageType";
	
	private static final String ZONEUNIT		= "ZoneUnit";
	
	private static final String LINKEDPAGE		= "LinkedPage";
	
	private static final String DETAIL			= "DetailInfo";
// 2003/05/19
	/** detailinfoプロパティ  **/
	private final static String ANALYZER_DETAILINFO		= "analyzer.detailinfo";
	
	private	documentBooster	myDocument;
	private	String			myMapfile;
	private	String			myHtmldir;
	private	Attribute		NotExistsAttribute;
	private	Attribute		ExistsAttribute;
	
//--------[[ constructor ]]----------------------------------------------------
	/**
	 * RID Document(Site.XML Resource.XML Document.XML)をAnalizeする。
	 * @since	1.00
	 */
	public RHTMLAnalyzer(Document document ,String projectdir) throws RidException{
		ZResource res = ZApp.getTheApp().getResource();
		
		myDocument	= new documentBooster(document);
		String tempdir = res.getString(KEY_TEMPLATE);
		if(null==tempdir) throw new RidException(new RidMessage().Error(ERR_NotFoundResourceKey,KEY_TEMPLATE));
//		String htmldir = res.getString(KEY_HTML);
//		if(null==htmldir) throw new RidException(new RidMessage().Error(ERR_NotFoundResourceKey,KEY_HTML));
		
		myMapfile	= projectdir+File.separator+tempdir+File.separator+MAP_PROGRESS;
//		myHtmldir	= projectdir+File.separator+htmldir;
		myHtmldir	= Ridual.getHtmlDir();
		ExistsAttribute		= new Attribute(EXIST ,TRUE);
		NotExistsAttribute	= new Attribute(EXIST ,FALSE);
	}
	
//	========[[ open method ]]==================================================
	/**
	 * analizeを実行する。
	 * @see		Attribute
	 * @exception	RidException	何らかの異常または警告があった
	 * @since	1.00
	 */
	public void analyze(JProgressBar progressBar, BaseURL baseURL) throws RidException{
		
		RWarningException errors = new RWarningException();
		
		// resource.xmlのリンク情報をリセット(LinkedPageUnitを全削除)
		documentBooster	resdocument	= new documentBooster((Document)ZInstance.map().get(Rid.DOCUMENT_RESOURCE));
		elementBooster resroot = resdocument.root();
		resroot.removeChildren(LINKEDPAGE);
		resroot.add(LINKEDPAGE);
		
		// ページユニット収集
		SiteXmlAnalizer sitexml = new SiteXmlAnalizer(myDocument);
		sitexml.resetLinkExist();
		
		SiteXmlAnalizer.UnitData[] unitdatas = sitexml.collecting(PAGEUNIT);
		if(null==unitdatas)	return;
		
		// ループ内で使うオブジェクト
		HTMLAnalyzer	analyzer	= new HTMLAnalyzer();
		Mapper			mapper		= new Mapper();
		ScriptingMapper	smapper		= new ScriptingMapper();
		documentBooster	sitedocument= new documentBooster((Document)ZInstance.map().get(Rid.DOCUMENT_SITE));
		
		LinkList		linklist	= new LinkList(sitedocument.root().element());
		LinkedPageList	linkedpagelist= new LinkedPageList(resdocument.root().element());
		
		ResourceMappingScript 	resms		= new ResourceMappingScript(resdocument.root(), linkedpagelist, baseURL);
		HyperLinkMappingScript	hyperlinkms	= new HyperLinkMappingScript(sitedocument.root(), linklist, baseURL);
		SWFMappingScript		swfms		= new SWFMappingScript(sitedocument.root(), baseURL, hyperlinkms, resms, new HashMap());
//		SSIMappingScript		ssims		= new SSIMappingScript(resdocument.root(), baseURL);
		SSIMappingScript		ssims		= new SSIMappingScript(resdocument.root(), resms);
		
		ZResource res = ZApp.getTheApp().getResource();
		try{
			StringTokenizer st = new StringTokenizer(res.getString(ANALYZER_DETAILINFO) ," ");
			while(st.hasMoreTokens()){
				String label= st.nextToken();
				String key	= ANALYZER_DETAILINFO+"."+label;
				if(res.getBoolean(key)){
					StringTokenizer tags = new StringTokenizer(res.getString(key+".tag"));
					while(tags.hasMoreTokens()){
						String tag = tags.nextToken();
						analyzer.list.put(tag, tag);
					}
				}
			}
		}catch(NullPointerException e){}
		
		analyzer.addFilter(resms.names());
		analyzer.addFilter(hyperlinkms.names());
		analyzer.addFilter(swfms.names());
		analyzer.addFilter(ssims.names());
		try{
			analyzer.addFilter(new MapXmlAnalizer(new documentBooster(myMapfile)).getInTag());
		}catch(javax.xml.parsers.ParserConfigurationException e){
			throw new RidException(new RidMessage().Error(ERR_CreateReportXml,e.toString()));
		}
		
//		analyzer.printFilter();
		
		ReportXml report;
		try{ report = new ReportXml(); }
		catch(javax.xml.parsers.ParserConfigurationException e){
			throw new RidException(new RidMessage().Error(ERR_CreateReportXml,e.toString()));
		}
		
		StringBuffer StrBuff;
		Attribute[] attributes;
		
		int mx = unitdatas.length;
		String mxstr = "/" + mx + " (pages)";
		progressBar.setMinimum(0);
		progressBar.setMaximum(mx);
		try{ progressBar.setIndeterminate(false); }
		catch(NoSuchMethodError e){}	// for java 1.3
		
		for(int i=0;i<mx;i++){
			int cnt = i+1;
			progressBar.setValue(cnt);
			progressBar.setString(cnt + mxstr);
			
			String filename = unitdatas[i].file;
			if(RIgnoreFiles.ignorefile(filename))	continue;
			elementBooster elem = unitdatas[i].element;
			boolean	isServerPage = SERVER.equals(elem.attribute(PAGETYPE));
			
			Attribute fileattribute	= new Attribute(FILE ,filename);
			
			report.flash();
			try{
				StrBuff = new StringBuffer(myHtmldir);
				StrBuff.append(File.separator);
				StrBuff.append(filename);
				
				elem.removeChildren(DETAIL);
				attributes = analyzer.analyze(StrBuff.toString(), elem.add(DETAIL));
				
				if(analyzer.getEmptyStack())	errors.add(WAR_HtmlSyntaxError,filename);
				
				if(!isServerPage)	report.add(PAGE ,fileattribute ,ExistsAttribute);
				report.add(PAGE ,fileattribute ,attributes);
			}
			catch(java.io.FileNotFoundException exc){
				if(!isServerPage)	report.add(PAGE ,fileattribute ,NotExistsAttribute);
			}
			catch(java.io.IOException exc){
				errors.add(WAR_HtmlReadError ,filename);
			}
			catch(javax.swing.text.BadLocationException exc){
				errors.add(WAR_HtmlBadLocationError ,filename);
			}
			catch(Throwable exc){
				errors.add(WAR_HtmlAnalize ,filename+" ("+exc.toString()+")");
				exc.printStackTrace();
			}
			
			try{ mapper.Type1Xml(myDocument.root().element() ,myMapfile ,report.element.element()); }
			catch(Exception e){  }
			
			linkedpagelist.reset(filename);
			try{ smapper.mapping(report.element ,resms); }
			catch(RWarningException e){ errors.add(e); }
			
			linklist.reset(filename);
			try{ smapper.mapping(report.element ,hyperlinkms); }
			catch(RWarningException e){ errors.add(e); }
			
			try{ smapper.mapping(report.element ,swfms); }
			catch(RWarningException e){ errors.add(e); }
			
			try{ smapper.mapping(report.element ,ssims); }
			catch(RWarningException e){ errors.add(e); }
		}
		
		if(0<errors.length()) throw new RidException(errors.getMessage());
	}
	
	private class ReportXml{
		private elementBooster myRoot;
		public	elementBooster element;
		
		public ReportXml() throws javax.xml.parsers.ParserConfigurationException{
			documentBooster doc = new documentBooster(XML_REPORT ,ELEMENT_ROOT);
			myRoot = doc.root();
		}
		
		public void flash(){ element = myRoot.newElement(ELEMENT_ROOT); }
		
		public void add(String tagname ,Attribute key ,Attribute[] attributes){
			elementBooster child = element.add(tagname);
			child.attribute(key.name ,key.value);
			int mx = attributes.length;
			for(int i=0;i<mx;i++){
				Attribute attr = attributes[i];
				String		value	= attr.value;
				Attribute[] options = attr.options();
				
				if((null==value) && (null==options))	continue;
				
				elementBooster grandchild = child.add(attr.name);
				grandchild.text(value);
				
				if(null!=options){
					int mx2 = options.length;
					for(int j=0;j<mx2;j++){
						grandchild.attribute(options[j].name ,options[j].value);
					}
				}
			}
		}
		
		public void add(String tagname ,Attribute key ,Attribute attribute){
			elementBooster child = element.add(tagname);
			child.attribute(key.name ,key.value);
			elementBooster grandchild = child.add(attribute.name);
			grandchild.text(attribute.value);
			
			Attribute[] options = attribute.options();
			if(null!=options){
				int mx = options.length;
				for(int j=0;j<mx;j++){
					grandchild.attribute(options[j].name ,options[j].value);
				}
			}
		}
	}
}