package org.apache.slide.projector.constraints;

import java.io.ByteArrayInputStream;

import org.apache.commons.contract.Context;
import org.apache.commons.contract.constraints.CastException;
import org.apache.commons.contract.constraints.Constraints;
import org.apache.commons.contract.constraints.ValidationException;
import org.apache.commons.i18n.LocalizedError;
import org.apache.commons.i18n.LocalizedText;
import org.apache.slide.projector.value.DocumentValue;
import org.apache.slide.projector.value.Streamable;
import org.apache.slide.projector.value.XMLValue;
import org.jdom.DocType;

public class XMLConstraints implements Constraints {
    public static final XMLConstraints UNCONSTRAINED = new XMLConstraints();

    protected boolean constrained;
    protected DocType allowedDocType;

    public XMLConstraints() {
        this.constrained = false;
    }

    public XMLConstraints(String allowedDocType) {
        this.constrained = true;
        this.allowedDocType = new DocType(allowedDocType);
    }

    public boolean isConstrained() {
        return constrained;
    }

    public Object cast(Object value, Context context) throws CastException { 
    	if ( value instanceof XMLValue ) {
    		return value;
    	} else if ( value instanceof Streamable ) {
    		try {
    			return new DocumentValue(((Streamable)value).getInputStream());
    		} catch ( Exception e ) {
    			throw new CastException(new LocalizedError("uncastableXMLValue", new Object[] { value }), e);
    		}
    	} 
    	try {
    	    return new DocumentValue(new ByteArrayInputStream(value.toString().getBytes("UTF-8")));
    	} catch ( Exception e ) {
    	    throw new CastException(new LocalizedError("uncastableXMLValue", new Object[] { value }), e);
    	}
    }
    
    public void validate(Object value, Context context) throws ValidationException {
		if ( constrained && !((XMLValue)value).getDocumentType().equals(allowedDocType)) {
			throw new ValidationException(new LocalizedError("invalidXMLValue", new String[] { ((XMLValue)value).getDocumentType().toString() }));
		}
    }

    /* (non-Javadoc)
     * @see org.apache.commons.contract.constraints.Constraints#verboseConstraints()
     */
    public LocalizedText verboseConstraints() {
        // TODO Auto-generated method stub
        return null;
    }
}