package uk.org.taverna.scufl2.rdfxml;

import java.net.URI;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;

import uk.org.taverna.scufl2.api.common.Scufl2Tools;
import uk.org.taverna.scufl2.api.common.URITools;
import uk.org.taverna.scufl2.api.common.WorkflowBean;
import uk.org.taverna.scufl2.api.container.WorkflowBundle;
import uk.org.taverna.scufl2.api.io.ReaderException;
import uk.org.taverna.scufl2.rdfxml.jaxb.ObjectFactory;

public class AbstractParser {

	protected JAXBContext jaxbContext;

	protected final ThreadLocal<ParserState> parserState;

	protected Scufl2Tools scufl2Tools = new Scufl2Tools();
	protected Unmarshaller unmarshaller;
	protected URITools uriTools = new URITools();

	public AbstractParser() {
		parserState = new ThreadLocal<ParserState>() {
			@Override
			protected ParserState initialValue() {
				return new ParserState();
			};
		};
		createMarshaller();
	}

	public AbstractParser(ThreadLocal<ParserState> parserState) {
		this.parserState = parserState;
		createMarshaller();
	}

	protected void clearParserState() {
		parserState.remove();
	}

	private void createMarshaller() {
		try {
			jaxbContext = JAXBContext.newInstance(ObjectFactory.class);
			unmarshaller = jaxbContext.createUnmarshaller();
		} catch (JAXBException e) {
			throw new IllegalStateException(
					"Can't create JAXBContext/unmarshaller", e);
		}
	}

	protected ParserState getParserState() {
		return parserState.get();
	}

	protected void mapBean(String about, WorkflowBean bean) {
		if (about == null) {
			return;
		}
		URI aboutUri = getParserState().getCurrentBase().resolve(about);
		mapBean(aboutUri, bean);
	}

	protected void mapBean(URI uri, WorkflowBean bean) {
		getParserState().getUriToBean().put(uri, bean);
		getParserState().getBeanToUri().put(bean, uri);
	}

	protected URI resolve(String uri) {
		return getParserState().getCurrentBase().resolve(uri);
	}

	protected WorkflowBean resolveBeanUri(URI uri) {
		WorkflowBean workflowBean = getParserState().getUriToBean().get(uri);
		if (workflowBean != null) {
			return workflowBean;
		}
		return uriTools.resolveUri(uri,
				getParserState().getCurrent(WorkflowBundle.class));
	}

	protected <T extends WorkflowBean> T resolveBeanUri(String resource,
			Class<T> beanType) throws ReaderException {
				URI uri = resolve(resource);
				WorkflowBean bean = resolveBeanUri(uri);
				if (bean == null) {
					throw new ReaderException("Can't find workflow bean for resource " + resource);
				}
				if (! beanType.isInstance(bean)) {
					throw new ReaderException("Wrong type for workflow bean " + resource + ", expected " + beanType.getSimpleName() + " but was " + bean.getClass().getSimpleName());
				}
				return beanType.cast(bean);
			}

}
@@ -1952,282 +1952,8 @@
 %09%7D%0A%0A
-%09protected WorkflowBean resolveBeanUri(URI uri) %7B%0A%09%09WorkflowBean workflowBean = getParserState().getUriToBean().get(uri);%0A%09%09if (workflowBean != null) %7B%0A%09%09%09return workflowBean;%0A%09%09%7D%0A%09%09return uriTools.resolveUri(uri,%0A%09%09%09%09getParserState().getCurrent(WorkflowBundle.class));%0A%09%7D%0A%0A
 %09pro
@@ -2508,9 +2508,339 @@
 ;%0A%09%09%09%7D%0A%0A
+%09protected WorkflowBean resolveBeanUri(URI uri) %7B%0A%09%09WorkflowBean workflowBean = getParserState().getUriToBean().get(uri);%0A%09%09if (workflowBean != null) %7B%0A%09%09%09return workflowBean;%0A%09%09%7D%0A%09%09uri = getParserState().getCurrentBase().resolve(uri);%0A%09%09return uriTools.resolveUri(uri,%0A%09%09%09%09getParserState().getCurrent(WorkflowBundle.class));%0A%09%7D%0A%0A
 %7D

Resolve locally the URI before using uritools