package eu.dnetlib.enabling.datastructures;

import java.io.StringReader;
import java.util.Map;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.io.SAXReader;

import eu.dnetlib.enabling.annotations.DnetResource;
import eu.dnetlib.rmi.objects.is.DnetDataStructure;
import eu.dnetlib.rmi.soap.exceptions.InformationServiceException;

public abstract class AbstractXmlResource implements BaseResource {

	private transient Document doc;

	public AbstractXmlResource(final String xml) throws DocumentException {
		this.doc = new SAXReader().read(new StringReader(xml));
	}

	public final Document asDocument() {
		return doc;
	}

	public final String asXML() {
		return doc.asXML();
	}

	public String getCode() {
		return getCode(doc);
	}

	public String getName() {
		return getName(doc);
	}

	public Map<String, String> getProperties() {
		return getProperties(doc);
	}

	abstract protected String getName(Document doc);

	abstract protected String getCode(Document doc);

	abstract protected Map<String, String> getProperties(Document doc);

	protected String getDescription(final Document doc) {
		return "";
	}

	protected boolean isValid(final Document doc) {
		return true;
	}

	@Override
	public DnetDataStructure asDnetDataStructure() throws InformationServiceException {
		if (getClass().isAnnotationPresent(DnetResource.class)) {
			final DnetDataStructure ds = new DnetDataStructure();
			ds.setCode(getCode(doc));
			ds.setType(getClass().getAnnotation(DnetResource.class).type());
			ds.setValid(isValid(doc));
			ds.setName(getName(doc));
			ds.setDescription(getDescription(doc));
			ds.setProperties(getProperties(doc));
			ds.setContent(doc.asXML());
			return ds;
		} else {
			throw new InformationServiceException("Missing DnetResource annotation in class " + getClass());
		}
	}

}
