package com.localmatters.serializer.config;

import java.io.InputStreamReader;
import java.io.Reader;
import java.util.Collections;
import java.util.Map;

import org.dom4j.DocumentException;
import org.dom4j.io.SAXReader;
import org.springframework.beans.factory.annotation.Required;
import org.springframework.core.io.Resource;

import com.localmatters.serializer.serialization.Serialization;
import com.localmatters.util.objectfactory.LMObjectFactory;
import com.localmatters.util.refreshable.AbstractRefreshableContent;

/**
 * A refreshable in memory serialization manager
 */
public class InMemorySerializationManager extends AbstractRefreshableContent implements SerializationManager {
	protected static final String DEFAULT_ENCODING = "UTF-8";
	private Resource resource;
	private String encoding = DEFAULT_ENCODING;
	private Map<String, Serialization> serializations = Collections.emptyMap();
	private LMObjectFactory objectFactory;
	
	/**
	 * @see com.localmatters.util.refreshable.AbstractRefreshableContent#doRefresh()
	 */
	@Override
	protected void doRefresh() throws Exception {
		Reader reader = new InputStreamReader(getResource().getInputStream(), getEncoding());
		SAXReader saxReader = new SAXReader();
		SerializationElementHandler handler = new SerializationElementHandler(getObjectFactory());
		saxReader.addHandler("/" + SerializationElementHandler.TYPE_ROOT, handler);
		try {
			saxReader.read(reader);
		} catch (DocumentException e) {
			if (e.getNestedException() instanceof ConfigurationException) {
				throw (ConfigurationException) e.getNestedException();
			}
			throw new ConfigurationException(String.format("Unable to load the handlers configuration %s!", getContentSource()), e);
		}
		serializations = handler.getSerializations();
	}

	/**
	 * @see com.localmatters.serializer.config.SerializationManager#getSerialization(java.lang.String)
	 */
	public Serialization getSerialization(String id) {
		return serializations.get(id);
	}


	/**
	 * @see com.localmatters.util.refreshable.AbstractRefreshableContent#getContentSource()
	 */
	@Override
	public String getContentSource() {
		return getResource().getDescription();
	}

	/**
	 * @return The resource defining the configuration file
	 */
	public Resource getResource() {
		return resource;
	}

	/**
	 * @param resource The resource defining the configuration file
	 */
	@Required
	public void setResource(Resource resource) {
		this.resource = resource;
	}

	/**
	 * @return The encoding (default UTF-8)
	 */
	public String getEncoding() {
		return encoding;
	}

	/**
	 * @param encoding The encoding (default UTF-8)
	 */
	public void setEncoding(String encoding) {
		this.encoding = encoding;
	}

	/**
	 * @return The objectFactory
	 */
	public LMObjectFactory getObjectFactory() {
		return objectFactory;
	}

	/**
	 * @param objectFactory The objectFactory to set
	 */
	@Required
	public void setObjectFactory(LMObjectFactory objectFactory) {
		this.objectFactory = objectFactory;
	}
}

@@ -935,16 +935,47 @@
 ctory;%0A%09
+private boolean alwaysRefresh;%0A
 %0A%09/**%0A%09 
@@ -1955,24 +1955,69 @@
 tring id) %7B%0A
+%09%09if (isAlwaysRefresh()) %7B%0A%09%09%09refresh();%0A%09%09%7D%0A
 %09%09return ser
@@ -3003,24 +3003,24 @@
 tFactory) %7B%0A
-
 %09%09this.objec
@@ -3047,11 +3047,429 @@
 tory;%0A%09%7D
+%0A%0A%09/**%0A%09 * @return Whether the configuration should always be refreshed (this should%0A%09 * be true ONLY for development)%0A%09 */%0A%09public boolean isAlwaysRefresh() %7B%0A%09%09return alwaysRefresh;%0A%09%7D%0A%0A%09/**%0A%09 * @param alwaysRefresh Whether the configuration should always be refreshed%0A%09 * (this should be true ONLY for development)%0A%09 */%0A%09public void setAlwaysRefresh(boolean alwaysRefresh) %7B%0A%09%09this.alwaysRefresh = alwaysRefresh;%0A%09%7D
 %0A%7D%0A

Add a dev option to always reload the configuration file