package org.seasar.jsf.runtime;

import java.io.IOException;
import java.io.InputStream;

import org.cyberneko.html.parsers.SAXParser;
import org.seasar.framework.exception.IORuntimeException;
import org.seasar.framework.exception.SAXRuntimeException;
import org.seasar.jsf.JsfConfig;
import org.seasar.jsf.TagProcessor;
import org.seasar.jsf.TagProcessorTreeFactory;
import org.seasar.jsf.TagSelector;
import org.seasar.jsf.ViewTemplateFactory;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;

/**
 * @author higa
 *  
 */
public class TagProcessorTreeFactoryImpl implements TagProcessorTreeFactory {

	private TagSelectors tagSelectors = new TagSelectors();

	private String encoding = "Windows-31j";

	private JsfConfig jsfConfig;
	
	private ViewTemplateFactory viewTemplateFactory;

	public TagProcessorTreeFactoryImpl() {
	}

	public TagProcessor createTagProcessorTree(InputStream is) {
		XMLReader reader = createReader();
		TagProcessorHandler handler = new TagProcessorHandler(tagSelectors,
				jsfConfig, viewTemplateFactory);
		reader.setContentHandler(handler);
		try {
			reader.parse(new InputSource(is));
		} catch (SAXException ex) {
			throw new SAXRuntimeException(ex);
		} catch (IOException ex) {
			throw new IORuntimeException(ex);
		}
		return handler.getRoot();
	}

	public void addTagSelector(TagSelector tagSelector) {
		tagSelectors.addTagSelector(tagSelector);
	}
	
	public TagSelector getTagSelector(String namespaceURI, String localName,
			String qName, Attributes attributes) {
		
		return tagSelectors.getTagSelector(namespaceURI, localName, qName, attributes);
	}

	public void setEncoding(String encoding) {
		this.encoding = encoding;
	}

	public void setJsfConfig(JsfConfig jsfConfig) {
		this.jsfConfig = jsfConfig;
	}
	
	public void setViewTemplateFactory(ViewTemplateFactory viewTemplateFactory) {
		this.viewTemplateFactory = viewTemplateFactory;
	}

	protected XMLReader createReader() {
		XMLReader reader = null;
		try {
			reader = new TextuallyXMLFilter(new SAXParser());
			reader.setProperty(
					"http://cyberneko.org/html/properties/default-encoding",
					encoding);
			reader.setProperty(
					"http://cyberneko.org/html/properties/names/attrs",
					"default");
			reader.setProperty(
					"http://cyberneko.org/html/properties/names/elems",
					"match");
		} catch (SAXException ex) {
			throw new SAXRuntimeException(ex);
		}
		return reader;
	}
}