/*
Copyright (C) 2000-2010  Ministere de la culture et de la communication (France), AJLSM
See LICENCE file
*/
package fr.gouv.culture.sdx.thesaurus;

import java.io.ByteArrayOutputStream;
import java.io.IOException;

import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.avalon.framework.configuration.DefaultConfiguration;
import org.apache.avalon.framework.logger.NullLogger;
import org.apache.cocoon.serialization.XMLSerializer;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;

import fr.gouv.culture.sdx.utils.constants.Node;

public class LuceneThesaurusBuilder extends AbstractThesaurusBuilder {

    protected int openConcepts = 0;
    protected ByteArrayOutputStream conceptBytes = null;

    /** A configuration object needed to make sure we use Saxon */
    protected Configuration saxonConf = null;

    public void startElement(String uri, String loc, String raw, Attributes a)
            throws SAXException {

        if (uri.equals(Thesaurus.NAMESPACE_URI)) {
        	// If not already created, we create a configuration object in order
        	// to tell the XMLSerializer to use Saxon. This prevents the usage
        	// of Xalan, which has major bigs with parsing/serializing XML fragments
        	if ( saxonConf == null ) {
                saxonConf = new DefaultConfiguration("conf");
                DefaultConfiguration cfTf = new DefaultConfiguration("transformer-factory");
//                cfTf.setValue("com.icl.saxon.TransformerFactoryImpl");	// saxon 6
                cfTf.setValue("net.sf.saxon.TransformerFactoryImpl");		// saxon 8
                ((DefaultConfiguration)saxonConf).addChild(cfTf);
        	}
            if (loc.equals(Node.Name.CONCEPT)) {
                if (openConcepts == 0) {
                    XMLSerializer cBytes = new XMLSerializer();
                    cBytes.enableLogging(new NullLogger());
                    this.conceptBytes = new ByteArrayOutputStream();
                    try {
                        cBytes.configure(saxonConf);
                    	cBytes.setOutputStream(conceptBytes);
                    } catch (IOException e){
                    	throw new SAXException(e.getMessage(),e);
                    } catch (ConfigurationException e) {
                        throw new SAXException(e.getMessage(), e);
                    }
                    super.setConsumer(cBytes);
                    super.startDocument();
                    // TODO (MP) : Forcer la creation du document <concept/> dans l'espace de nom Thesaurus.NAMESPACE_URI. Declarer un startPrefixMapping/endPrefixMapping ne suffie pas.
                }
                openConcepts++;
            }
        }
        super.startElement(uri, loc, raw, a);
    }

    public void endElement(String uri, String loc, String raw)
            throws SAXException {

        super.endElement(uri, loc, raw);

        if (uri.equals(Thesaurus.NAMESPACE_URI)) {

            if (loc.equals(Node.Name.CONCEPT)) {
                openConcepts--;
                if (openConcepts == 0) {
                    super.endDocument();
                    if (this.conceptBytes != null) {
                        Concept concept = new LuceneConcept();
                        try {
                            this.conceptBytes.flush();
                        } catch (IOException e) {
                            throw new SAXException(e.getMessage(), e);
                        }
                        concept.setContent(this.conceptBytes.toByteArray());
                        concepts.add(concept);
                        this.conceptBytes = null;
                    }
                    super.recycle();
                }
            }

        }

    }


}
