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

import fr.gouv.culture.oai.util.OAIUtilities;
import org.apache.cocoon.ProcessingException;
import org.apache.excalibur.source.Source;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;
import org.apache.cocoon.components.source.SourceUtil;

import java.util.Enumeration;
import java.util.Vector;
import java.io.IOException;


public class OAIRecordImpl extends OAIObjectImpl implements OAIRecord {

	protected String _oaiNamespace = null;
	protected String _identifier = null;
	protected String _datestamp = null;
	protected Vector _setSpecs = new Vector();
	protected boolean _isDeleted = false;
	protected OAIMetadataFormat _oaiMetadataFormat = null;
	protected Source _recordSource = null;
	protected Source _aboutSource = null;


	public void setOAINamspace(String namespace) {
		_oaiNamespace = namespace;
	}

	public String getOAINamspace() {
		return _oaiNamespace;
	}

	public String getIdentifier() {
		return _identifier;
	}

	public void setIdentifier(String identifier) {
		_identifier = identifier;
	}

	public String getDatestamp() {
		return _datestamp;
	}

	public void setDatestamp(String datestamp) {
		_datestamp = datestamp;
	}

	public void setSetSpecs(Vector setSpecs) {
		_setSpecs = setSpecs;
	}

	public void addSetSpec(String setSpec) {
		_setSpecs.add(setSpec);
	}

	public Enumeration getSetSpecs() {
		return _setSpecs.elements();
	}

	public void setIsDeleted(boolean isDeleted) {
		_isDeleted = isDeleted;
	}

	public boolean isDeleted() {
		return _isDeleted;
	}

	public void setMetadataFormat(OAIMetadataFormat format) {
		_oaiMetadataFormat = format;

	}

	public OAIMetadataFormat getMetaDataFormat() {
		return _oaiMetadataFormat;
	}

	public void setRecord(Source source) {
		_recordSource = source;
	}

	public Source getRecord() {
		return _recordSource;
	}

	public void setAbout(Source source) {
		_aboutSource = source;
	}

	public Source getAbout() {
		return _aboutSource;
	}


	public void identifier() throws SAXException {
		super.sendElement(getOAINamspace(), OAIObject.Node.Name.IDENTIFIER, OAIObject.Node.Name.IDENTIFIER, null, getIdentifier());
	}

	public void datestamp() throws SAXException {
		super.sendElement(getOAINamspace(), OAIObject.Node.Name.DATESTAMP, OAIObject.Node.Name.DATESTAMP, null, getDatestamp());

	}

	public void setSpecs() throws SAXException {
		super.sendElement(getOAINamspace(), OAIObject.Node.Name.IDENTIFIER, OAIObject.Node.Name.IDENTIFIER, null, getIdentifier());
	}

	public void header() throws SAXException {
		String status = null;
		if (_isDeleted)
			status = OAIObject.Node.Value.DELETED;
		AttributesImpl atts = new AttributesImpl();
		if (OAIUtilities.checkString(status))
			atts.addAttribute("", OAIObject.Node.Name.STATUS, OAIObject.Node.Name.STATUS, OAIObject.Node.Type.CDATA, status);
		super.startElement(getOAINamspace(), OAIObject.Node.Name.HEADER, OAIObject.Node.Name.HEADER, atts);
		identifier();
		datestamp();
		setSpecs();
		super.endElement(getOAINamspace(), OAIObject.Node.Name.HEADER, OAIObject.Node.Name.HEADER);

	}

	public void metadata() throws SAXException {
		super.startElement(getOAINamspace(), OAIObject.Node.Name.METADATA, OAIObject.Node.Name.METADATA, null);
		try {
			sendMetadata();
		} finally {
			super.endElement(getOAINamspace(), OAIObject.Node.Name.METADATA, OAIObject.Node.Name.METADATA);
		}
	}

	protected void sendMetadata() throws SAXException {
		try {
			SourceUtil.toSAX(_recordSource, this);
			//_recordSource.toSAX(this);
		} catch (ProcessingException e) {
			throw new SAXException(e);
		}
		catch (IOException e) {
			throw new SAXException(e);
		}
	}

	public void about() throws SAXException {
		super.startElement(getOAINamspace(), OAIObject.Node.Name.ABOUT, OAIObject.Node.Name.ABOUT, null);
		try {
			SourceUtil.toSAX(_aboutSource, this);
			//_aboutSource.toSAX(this);
		} catch (ProcessingException e) {
			throw new SAXException(e);
		}
		catch (IOException e) {
			throw new SAXException(e);
		} finally {
			super.endElement(getOAINamspace(), OAIObject.Node.Name.ABOUT, OAIObject.Node.Name.ABOUT);
		}
	}

	public void record() throws SAXException {
		super.startElement(getOAINamspace(), OAIObject.Node.Name.RECORD, OAIObject.Node.Name.RECORD, null);
		header();
		metadata();
		about();
		super.endElement(getOAINamspace(), OAIObject.Node.Name.RECORD, OAIObject.Node.Name.RECORD);
	}

	public void toSAX(ContentHandler contentHandler) throws SAXException {
		ContentHandler origHandler = super.contentHandler;
		super.setContentHandler(contentHandler);
		record();
		super.setContentHandler(origHandler);
	}

}
