/**
 *  Copyright (c) 2012, 2016 Sme.UP and others.
 *  All rights reserved. This program and the accompanying materials
 *  are made available under the terms of the Eclipse Public License v1.0
 *  which accompanies this distribution, and is available at
 *  http://www.eclipse.org/legal/epl-v10.html
 *
 *
 * Contributors:
 *   Mattia Rocchi - Initial API and implementation
 */
package org.smeup.sys.dk.source.nio;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collections;

import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.impl.BasicEObjectImpl;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.smeup.sys.dk.source.QProject;
import org.smeup.sys.il.core.QObjectNameable;
import org.smeup.sys.rt.core.QApplication;

public class NIOObjectSerializer {

	private QApplication application;
	private ResourceSet resourceSet;

	public NIOObjectSerializer(QApplication application, ResourceSet resourceSet) {
		this.application = application;
		this.resourceSet = resourceSet;
	}

	public <T extends QObjectNameable> ByteArrayOutputStream serialize(QProject project, Class<T> klass, String name, T object) throws IOException {

		URI uri = buildURI(project, klass, name);

		NIOResourceImpl resource = (NIOResourceImpl) resourceSet.getResource(uri, false);
		if (resource == null)
			resource = (NIOResourceImpl) resourceSet.createResource(uri, "asup");
		else
			clearResource(resource);

		((BasicEObjectImpl) object).eSetResource(null, null);
		resource.getContents().add((EObject) object);

		ByteArrayOutputStream output = new ByteArrayOutputStream();
		resource.doSave(output, Collections.EMPTY_MAP);

		return output;

	}

	@SuppressWarnings("unchecked")
	public <T extends QObjectNameable> T deserialize(QProject project, Class<T> klass, String name, InputStream inputStream) throws IOException {

		URI uri = buildURI(project, klass, name);

		NIOResourceImpl resource = (NIOResourceImpl) resourceSet.getResource(uri, false);
		if (resource == null)
			resource = (NIOResourceImpl) resourceSet.createResource(uri, "asup");
		else
			clearResource(resource);

		resource.doLoad(inputStream, resourceSet.getLoadOptions());
		if (resource.getContents().isEmpty())
			return null;

		EObject eObject = resource.getContents().get(0);

		return (T) eObject;

	}

	private void clearResource(NIOResourceImpl resource) {
		BasicEObjectImpl oldObject = null;
		if (resource.isLoaded() && !resource.getContents().isEmpty()) {
			oldObject = (BasicEObjectImpl) resource.getContents().get(0);
			resource.getContents().clear();
			oldObject.eSetResource(resource, null);
		}
	}

	private <T extends QObjectNameable> URI buildURI(QProject project, Class<T> klass, String name) {

		String uri = "asup://" + application.getName() + "/" + project.getName() + "/" + klass.getSimpleName().toLowerCase().substring(1);
		URI eURI = URI.createURI(uri);
		
		// TODO remove me
		eURI = eURI.appendFragment(name);
		
		return eURI;
	}
}
@@ -1292,32 +1292,76 @@
  klass, name);%0A%0A
+%09%09synchronized (uri.toString().intern()) %7B%0A%09
 %09%09NIOResourceImp
@@ -1422,32 +1422,33 @@
 (uri, false);%0A%09%09
+%09
 if (resource == 
@@ -1445,32 +1445,33 @@
 source == null)%0A
+%09
 %09%09%09resource = (N
@@ -1521,37 +1521,39 @@
 uri, %22asup%22);%0A%09%09
+%09
 else%0A
+%09
 %09%09%09clearResource
@@ -1567,16 +1567,17 @@
 ce);%0A%0A%09%09
+%09
 ((BasicE
@@ -1622,16 +1622,17 @@
  null);%0A
+%09
 %09%09resour
@@ -1674,16 +1674,17 @@
 ct);%0A%0A%09%09
+%09
 ByteArra
@@ -1735,16 +1735,17 @@
 ream();%0A
+%09
 %09%09resour
@@ -1786,17 +1786,21 @@
 Y_MAP);%0A
-%0A
+%09%09%09%0A%09
 %09%09return
@@ -1808,16 +1808,19 @@
 output;%0A
+%09%09%7D
 %0A%09%7D%0A%0A%09@S
@@ -2037,16 +2037,60 @@
 name);%0A%0A
+%09%09synchronized (uri.toString().intern()) %7B%0A%09
 %09%09NIORes
@@ -2165,16 +2165,17 @@
 false);%0A
+%09
 %09%09if (re
@@ -2189,24 +2189,25 @@
 == null)%0A%09%09%09
+%09
 resource = (
@@ -2264,23 +2264,27 @@
 asup%22);%0A
+%09
 %09%09else
-%0A
+ %7B%0A%09
 %09%09%09clear
@@ -2303,17 +2303,23 @@
 ource);%0A
-%0A
+%09%09%09%7D%0A%0A%09
 %09%09resour
@@ -2370,24 +2370,25 @@
 tions());%0A%09%09
+%09
 if (resource
@@ -2412,24 +2412,25 @@
 Empty())%0A%09%09%09
+%09
 return null;
@@ -2431,16 +2431,17 @@
  null;%0A%0A
+%09
 %09%09EObjec
@@ -2483,17 +2483,21 @@
 get(0);%0A
-%0A
+%09%09%09%0A%09
 %09%09return
@@ -2510,16 +2510,19 @@
 Object;%0A
+%09%09%7D
 %0A%09%7D%0A%0A%09pr

Patch resource serialization