package de.faustedition.document;

import static de.faustedition.xml.XPathUtil.xpath;

import java.io.IOException;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.SortedSet;
import java.util.TreeSet;

import javax.xml.xpath.XPathExpression;

import org.restlet.data.Status;
import org.restlet.representation.Representation;
import org.restlet.resource.Get;
import org.restlet.resource.ServerResource;
import org.restlet.routing.Router;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;

import com.google.common.base.Throwables;
import com.google.common.collect.Iterables;

import de.faustedition.ApplicationContextFinder;
import de.faustedition.graph.FaustGraph;
import de.faustedition.template.TemplateRepresentationFactory;
import de.faustedition.xml.NodeListWrapper;
import de.faustedition.xml.XMLStorage;
import de.faustedition.xml.XMLUtil;

@Component
public class ArchiveRouter extends Router implements InitializingBean {

	@Autowired
	private ApplicationContext applicationContext;

	@Override
	public void afterPropertiesSet() throws Exception {
		ApplicationContextFinder<ArchiveResource> archiveResource = new ApplicationContextFinder<ArchiveResource>(applicationContext, ArchiveResource.class);
		attach("", archiveResource);
		attach("{id}", archiveResource);
	}

	@Component
	@Scope(BeanDefinition.SCOPE_PROTOTYPE)
	public static class ArchiveResource extends ServerResource {

		@Autowired
		private XMLStorage xmlStorage;

		@Autowired
		private TemplateRepresentationFactory viewFactory;

		@Autowired
		private FaustGraph graph;

		@Get
		public Representation render() {
			final Map<String, Object> model = new HashMap<String, Object>();
			final String id = (String) getRequestAttributes().get("id");

			final org.w3c.dom.Document archives;
			try {
				archives = XMLUtil.parse(xmlStorage.getInputSource(ArchiveInitializer.ARCHIVE_DESCRIPTOR_URI));
			} catch (SAXException e) {
				throw Throwables.propagate(e);
			} catch (IOException e) {
				throw Throwables.propagate(e);
			}

			if (id == null) {
				model.put("archives", archives.getDocumentElement());
				return viewFactory.create("document/archives", getRequest().getClientInfo(), model);
			}

			Archive archive = graph.getArchives().findById(id);
			if (archive == null) {
				getResponse().setStatus(Status.CLIENT_ERROR_NOT_FOUND, id);
				return null;
			}

			final SortedSet<Document> archivalUnits = new TreeSet<Document>(new Comparator<Document>() {
				@Override
				public int compare(Document o1, Document o2) {
					final String o1cn = o1.getMetadataValue("callnumber");
					final String o2cn = o2.getMetadataValue("callnumber");
					if (o1cn != null && o2cn != null) {
						int order = o1cn.compareTo(o2cn);
						if (order != 0) return order;
					}
					return o1.getSource().compareTo(o2.getSource());

					//return (o1cn == null || o2cn == null) ? 0 : o1cn.compareTo(o2cn);
				}
			});

			Iterables.addAll(archivalUnits, Iterables.filter(archive, Document.class));
			model.put("archivalUnits", archivalUnits);

			final XPathExpression xpathById = xpath("/f:archives/f:archive[@id='" + id + "']");
			final Element archiveData = new NodeListWrapper<Element>(xpathById, archives).singleResult(Element.class);
			if (archiveData == null) {
				getResponse().setStatus(Status.CLIENT_ERROR_NOT_FOUND, id);
				return null;
			}
			model.put("archive", archiveData);

			return viewFactory.create("document/archive", getRequest().getClientInfo(), model);
		}
	}
}

@@ -39,134 +39,175 @@
 ort 
-static de.faustedition.xml.XPathUtil.xpath;%0A%0Aimport java.io.IOException;%0Aimport java.util.Comparator;%0Aimport java.util.HashM
+com.google.common.base.Throwables;%0Aimport com.google.common.collect.Iterables;%0Aimport de.faustedition.ApplicationContextFinder;%0Aimport de.faustedition.graph.FaustGr
 ap
+h
 ;%0Aim
@@ -215,118 +215,182 @@
 ort 
-java.util.Map;%0Aimport java.util.SortedSet;%0Aimport java.util.TreeSet;%0A%0Aimport javax.xml.xpath.XPathExpression;%0A
+de.faustedition.template.TemplateRepresentationFactory;%0Aimport de.faustedition.xml.NodeListWrapper;%0Aimport de.faustedition.xml.XMLStorage;%0Aimport de.faustedition.xml.XMLUtil;
 %0Aimp
@@ -996,330 +996,103 @@
 ort 
-com.google.common.base.Throwables;%0Aimport com.google.common.collect.Iterables;%0A%0Aimport de.faustedition.ApplicationContextFinder;%0Aimport de.faustedition.graph.FaustGraph;%0Aimport de.faustedition.template.TemplateRepresentationFactory;%0Aimport de.faustedition.xml.NodeListWrapper
+javax.xml.xpath.XPathExpression;%0Aimport java.io.IOException;%0Aimport java.util.*
 ;%0A
+%0A
 import 
-de.faustedition.xml.XMLStorage;%0Aimport
+static
  de.
@@ -1109,22 +1109,30 @@
 on.xml.X
-MLUtil
+PathUtil.xpath
 ;%0A%0A@Comp
@@ -3091,82 +3091,8 @@
 ());
-%0A%0A%09%09%09%09%09//return (o1cn == null %7C%7C o2cn == null) ? 0 : o1cn.compareTo(o2cn);
 %0A%09%09%09

remove comment