package org.apache.slide.projector.constraints;

import java.util.Iterator;
import java.util.List;

import org.apache.commons.contract.constraints.Constraints;
import org.apache.commons.xmlio.out.XMLStringWriter;
import org.apache.commons.xmlio.out.XMLWriter;
import org.apache.slide.projector.Projector;
import org.apache.slide.projector.value.Any;
import org.apache.slide.projector.value.URI;
import org.apache.slide.projector.value.URIValue;
import org.jdom.Element;

public class AnyFactory extends AbstractValueFactory {
	private final static String PROCESSOR = "processor";
	private final static String RESULT = "result";
	private final static String STORE = "store";
	private final static String KEY = "key";
	private final static String DOMAIN = "domain";
	
	public Class getValueClass() {
		return Any.class;
	}
	
	public String getElementName() {
    	return "value";
    }

	public Object load(Element element) {
        String processor = element.getAttributeValue("processor");
        String result = element.getAttributeValue("result");
        String store = element.getAttributeValue("store");
        if ( store == null ) store = Projector.NO_STORE;
        String key = element.getAttributeValue("key");
        String domain = element.getAttributeValue("domain");
        URI processorUri = ( processor == null ? null : new URIValue(processor) );
        Iterator children = element.getChildren().iterator();
    	Object input = null; 
        if ( children.hasNext() ) {
        	Element childElement = (Element)children.next();
        	input = ConstraintsManager.getInstance().loadValue(childElement);
        }
        return new Any(processor, input, result, store, key, domain);
	}
	    
	public void save(Object value, XMLStringWriter writer) {
		Any anyValue = (Any)value;
		if ( anyValue.getProcessorUri() == null ) {
			writer.writeEmptyElement(XMLWriter.createEmptyTag(getElementName(), new String[] { STORE, KEY, DOMAIN }, new String[] { anyValue.getStoreId(), anyValue.getKey(), anyValue.getDomain() }));
		} else {
			if ( anyValue.getInput() == null ) {
				writer.writeStartTag(XMLWriter.createStartTag(getElementName(), new String[] { PROCESSOR, RESULT, STORE, KEY, DOMAIN }, new String[] { anyValue.getProcessorUri().toString(), anyValue.getResult(), anyValue.getStoreId(), anyValue.getKey(), anyValue.getDomain() }));
			} else {
				writer.writeStartTag(XMLWriter.createStartTag(getElementName(), new String[] { PROCESSOR, RESULT }, new String[] { anyValue.getProcessorUri().toString(), anyValue.getResult() }));
				ConstraintsManager.getInstance().saveValue(anyValue.getInput(), writer);
				writer.writeEndTag(XMLWriter.createEndTag(getElementName()));
			}
		}
	}

	public Constraints loadDescriptor(Element element) {
    	AnyConstraints valueDescriptor = new AnyConstraints();
    	List allowedValueElements = element.getChildren("allowed-content-type");
    	for ( Iterator i = allowedValueElements.iterator(); i.hasNext(); ) {
    		Element allowedValueElement = (Element)i.next(); 
            String allowedValue = allowedValueElement.getTextTrim(); 
            valueDescriptor.addAllowedContentType(allowedValue);
    	}
    	return valueDescriptor;
    }
}