Tidied up original vis/client api classes. Reimplemented for new visualisation framework. Includes the extension point managers for charts and vizs.

James Williams James Williams 2014-07-11

removed web/org.ossmeter.platform.client.api/src/org/ossmeter/platform/client/api/mixins
removed web/org.ossmeter.platform.client.api/src/org/ossmeter/platform/client/api/mixins/model
removed web/org.ossmeter.platform.client.api/src/org/ossmeter/platform/client/api/mixins/model/ProjectMixin.java
removed web/org.ossmeter.platform.client.api/src/org/ossmeter/platform/client/api/mixins/NamedElementMixin.java
removed web/org.ossmeter.platform.client.api/src/org/ossmeter/platform/client/api/mixins/ProjectOverviewMixin.java
removed web/org.ossmeter.platform.client.api/src/org/ossmeter/platform/client/api/mixins/generateMixins.egx
removed web/org.ossmeter.platform.client.api/src/org/ossmeter/platform/client/api/mixins/package2configurationClass.egl
removed web/org.ossmeter.platform.client.api/src/org/ossmeter/platform/client/api/VisualisationExtensionPointManager.java
changed apps/org.ossmeter.platform.app.example/src/org/ossmeter/platform/app/example/DemoApp.java
changed platform/org.ossmeter.platform.visualisation/src/org/ossmeter/platform/visualisation/ChartExtensionPointManager.java
changed platform/org.ossmeter.platform.visualisation/src/org/ossmeter/platform/visualisation/MetricVisualisation.java
changed platform/org.ossmeter.platform.visualisation/src/org/ossmeter/platform/visualisation/MetricVisualisationExtensionPointManager.java
changed web/org.ossmeter.platform.client.api/src/org/ossmeter/platform/client/api/ApiApplication.java
changed web/org.ossmeter.platform.client.api/src/org/ossmeter/platform/client/api/MetricListResource.java
changed web/org.ossmeter.platform.client.api/src/org/ossmeter/platform/client/api/ProjectListResource.java
changed web/org.ossmeter.platform.client.api/src/org/ossmeter/platform/client/api/ProjectResource.java
changed web/org.ossmeter.platform.client.api/src/org/ossmeter/platform/client/api/Util.java
copied web/org.ossmeter.platform.client.api/src/org/ossmeter/platform/client/api/mixins/OssmeterMixins.java -> web/org.ossmeter.platform.client.api/src/org/ossmeter/platform/client/api/RawMetricListResource.java
copied web/org.ossmeter.platform.client.api/src/org/ossmeter/platform/client/api/mixins/PongoMixin.java -> web/org.ossmeter.platform.client.api/src/org/ossmeter/platform/client/api/RawProjectListResource.java
copied web/org.ossmeter.platform.client.api/src/org/ossmeter/platform/client/api/mixins/eclass2mixinclass.egl -> web/org.ossmeter.platform.client.api/src/org/ossmeter/platform/client/api/RawProjectResource.java
copied web/org.ossmeter.platform.client.api/src/org/ossmeter/platform/client/api/mixins/mixinUtil.eol -> web/org.ossmeter.platform.client.api/src/org/ossmeter/platform/client/api/MetricVisualisationResource.java
copied web/org.ossmeter.platform.client.api/src/org/ossmeter/platform/client/api/MetricsResource.java -> web/org.ossmeter.platform.client.api/src/org/ossmeter/platform/client/api/RawMetricResource.java
apps/org.ossmeter.platform.app.example/src/org/ossmeter/platform/app/example/DemoApp.java Diff Switch to side-by-side view
Loading...
platform/org.ossmeter.platform.visualisation/src/org/ossmeter/platform/visualisation/ChartExtensionPointManager.java Diff Switch to side-by-side view
Loading...
platform/org.ossmeter.platform.visualisation/src/org/ossmeter/platform/visualisation/MetricVisualisation.java Diff Switch to side-by-side view
Loading...
platform/org.ossmeter.platform.visualisation/src/org/ossmeter/platform/visualisation/MetricVisualisationExtensionPointManager.java Diff Switch to side-by-side view
Loading...
web/org.ossmeter.platform.client.api/src/org/ossmeter/platform/client/api/ApiApplication.java Diff Switch to side-by-side view
Loading...
web/org.ossmeter.platform.client.api/src/org/ossmeter/platform/client/api/MetricListResource.java Diff Switch to side-by-side view
Loading...
web/org.ossmeter.platform.client.api/src/org/ossmeter/platform/client/api/ProjectListResource.java Diff Switch to side-by-side view
Loading...
web/org.ossmeter.platform.client.api/src/org/ossmeter/platform/client/api/ProjectResource.java Diff Switch to side-by-side view
Loading...
web/org.ossmeter.platform.client.api/src/org/ossmeter/platform/client/api/Util.java Diff Switch to side-by-side view
Loading...
web/org.ossmeter.platform.client.api/src/org/ossmeter/platform/client/api/mixins/OssmeterMixins.java to web/org.ossmeter.platform.client.api/src/org/ossmeter/platform/client/api/RawMetricListResource.java
--- a/web/org.ossmeter.platform.client.api/src/org/ossmeter/platform/client/api/mixins/OssmeterMixins.java
+++ b/web/org.ossmeter.platform.client.api/src/org/ossmeter/platform/client/api/RawMetricListResource.java
@@ -1,24 +1,56 @@
-package org.ossmeter.platform.client.api.mixins;
+package org.ossmeter.platform.client.api;
 
-import org.ossmeter.platform.client.api.mixins.model.ProjectMixin;
-import org.ossmeter.repository.model.NamedElement;
-import org.ossmeter.repository.model.Project;
+import java.util.Iterator;
 
+import org.ossmeter.platform.IMetricProvider;
+import org.ossmeter.platform.Platform;
+import org.restlet.engine.header.Header;
+import org.restlet.resource.Get;
+import org.restlet.resource.ServerResource;
+import org.restlet.util.Series;
+
+import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.ObjectMapper;
-import com.googlecode.pongo.runtime.Pongo;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
 
-public class OssmeterMixins {
+public class RawMetricListResource extends ServerResource {
 
-	private static ObjectMapper instance;
 	
-	public static ObjectMapper getObjectMapper() {
+	
+	@Get("json")
+    public String represent() {
+		Series<Header> responseHeaders = (Series<Header>) getResponse().getAttributes().get("org.restlet.http.headers");
+		if (responseHeaders == null) {
+		    responseHeaders = new Series(Header.class);
+		    getResponse().getAttributes().put("org.restlet.http.headers", responseHeaders);
+		}
+		responseHeaders.add(new Header("Access-Control-Allow-Origin", "*"));
+		responseHeaders.add(new Header("Access-Control-Allow-Methods", "GET"));
+		
 		ObjectMapper mapper = new ObjectMapper();
+		ObjectNode res = mapper.createObjectNode();
+
+		Platform platform = Platform.getInstance();
+		ArrayNode metrics = mapper.createArrayNode();
+		res.put("metrics", metrics);
 		
-		mapper.addMixInAnnotations(Pongo.class, PongoMixin.class);
-		mapper.addMixInAnnotations(NamedElement.class, NamedElementMixin.class);
-		mapper.addMixInAnnotations(Project.class, ProjectMixin.class);
-//		mapper.addMixInAnnotations(EclipseForgeProject.class, ProjectMixin.class);
+		Iterator<IMetricProvider> it = platform.getMetricProviderManager().getMetricProviders().iterator();
 		
-		return mapper;
+		// TODO: do we want to return the list of all metrics, or the list of metrics that can be visualised?
+		while (it.hasNext()) {
+			ObjectNode metric = mapper.createObjectNode();
+			metrics.add(metric);
+			
+			IMetricProvider ip =  it.next();
+			
+			metric.put("name", ip.getFriendlyName());
+			metric.put("type", ip.getClass().getName());
+			metric.put("description", ip.getSummaryInformation());
+		}
+
+		return res.toString();
 	}
-} +
+	
+}
web/org.ossmeter.platform.client.api/src/org/ossmeter/platform/client/api/mixins/PongoMixin.java to web/org.ossmeter.platform.client.api/src/org/ossmeter/platform/client/api/RawProjectListResource.java
--- a/web/org.ossmeter.platform.client.api/src/org/ossmeter/platform/client/api/mixins/PongoMixin.java
+++ b/web/org.ossmeter.platform.client.api/src/org/ossmeter/platform/client/api/RawProjectListResource.java
@@ -1,37 +1,61 @@
-package org.ossmeter.platform.client.api.mixins;
+package org.ossmeter.platform.client.api;
 
-import com.fasterxml.jackson.annotation.JsonAutoDetect;
-import com.fasterxml.jackson.annotation.JsonIgnore;
-import com.googlecode.pongo.runtime.Pongo;
-import com.googlecode.pongo.runtime.PongoCollection;
-import com.mongodb.DBObject;
+import java.util.Iterator;
 
-@JsonAutoDetect( fieldVisibility = JsonAutoDetect.Visibility.NONE, 
-				getterVisibility = JsonAutoDetect.Visibility.PUBLIC_ONLY, 
-				setterVisibility = JsonAutoDetect.Visibility.NONE)
-public abstract class PongoMixin  {
+import org.ossmeter.platform.Platform;
+import org.ossmeter.repository.model.Project;
+import org.ossmeter.repository.model.ProjectRepository;
+import org.restlet.engine.header.Header;
+import org.restlet.resource.Get;
+import org.restlet.resource.ServerResource;
+import org.restlet.util.Series;
 
-	@JsonIgnore
-	abstract DBObject getDbObject();
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+public class RawProjectListResource extends ServerResource {
+
+	@Get("json")
+    public String represent() {
+		Series<Header> responseHeaders = (Series<Header>) getResponse().getAttributes().get("org.restlet.http.headers");
+		if (responseHeaders == null) {
+		    responseHeaders = new Series(Header.class);
+		    getResponse().getAttributes().put("org.restlet.http.headers", responseHeaders);
+		}
+		responseHeaders.add(new Header("Access-Control-Allow-Origin", "*"));
+		responseHeaders.add(new Header("Access-Control-Allow-Methods", "GET"));
+		
+		// TODO
+		boolean paging = getRequest().getAttributes().containsKey("page");
+		
+		Platform platform = Platform.getInstance();
+		ProjectRepository projectRepo = platform.getProjectRepositoryManager().getProjectRepository();
+		
+		Iterator<Project> it = projectRepo.getProjects().iterator();
 	
-	@JsonIgnore
-	abstract String getId();
+		ObjectMapper mapper = new ObjectMapper();
+		ArrayNode projects = mapper.createArrayNode();
+		
+		while (it.hasNext()) {
+			try {
+				Project project  = it.next();
+				
+				ObjectNode p = mapper.createObjectNode();
+				p.put("name", project.getName());
+				p.put("description", project.getDescription());
+				
+				projects.add(p);
+				
+			} catch (Exception e) {
+				System.err.println("Error: " + e.getMessage());
+				ObjectNode m = mapper.createObjectNode();
+				m.put("apicall", "list-all-projects");
+				return Util.generateErrorMessage(m, e.getMessage()).toString();
+			}			
+		}
+		return projects.toString();
+	}
+
 	
-	@JsonIgnore
-	abstract String getType();
-	
-	@JsonIgnore
-	abstract Pongo getContainer();
-
-	@JsonIgnore
-	abstract String getContainingFeature();
-	
-	@JsonIgnore
-	abstract PongoCollection getPongoCollection();
-	
-	@JsonIgnore
-	abstract String getPongoPath();
-	
-	@JsonIgnore
-	abstract boolean isReferencable();
-}+}
web/org.ossmeter.platform.client.api/src/org/ossmeter/platform/client/api/mixins/eclass2mixinclass.egl to web/org.ossmeter.platform.client.api/src/org/ossmeter/platform/client/api/RawProjectResource.java
--- a/web/org.ossmeter.platform.client.api/src/org/ossmeter/platform/client/api/mixins/eclass2mixinclass.egl
+++ b/web/org.ossmeter.platform.client.api/src/org/ossmeter/platform/client/api/RawProjectResource.java
@@ -1,25 +1,57 @@
-[%import "mixinUtil.eol";%]
-package org.ossmeter.platform.client.api.mixins.[%=c.ePackage.getLastPackageName()%];
+package org.ossmeter.platform.client.api;
 
-import java.util.List;
-import org.ossmeter.repository.model.*;
+import org.ossmeter.platform.Platform;
+import org.ossmeter.repository.model.Project;
+import org.ossmeter.repository.model.ProjectRepository;
+import org.restlet.data.Status;
+import org.restlet.engine.header.Header;
+import org.restlet.resource.Get;
+import org.restlet.resource.ServerResource;
+import org.restlet.util.Series;
 
-import com.fasterxml.jackson.annotation.JsonAutoDetect;
-import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
 
-@JsonAutoDetect( fieldVisibility = JsonAutoDetect.Visibility.NONE, 
-				getterVisibility = JsonAutoDetect.Visibility.PUBLIC_ONLY, 
-				setterVisibility = JsonAutoDetect.Visibility.PUBLIC_ONLY)
-public abstract class [%=c.name%]Mixin {
-
-	[%for (sf in c.eStructuralFeatures.select(sf|sf.isMany and sf.isAnnotatedWith("invisible"))) {%]
-	@JsonIgnore("[%=sf.name%]")
-	abstract List<[%=sf.eType.getJavaName()%]> get[%=sf.name.firstToUpperCase()%]();
+public class RawProjectResource extends ServerResource {
+	@Get
+	public String represent() {	
+		Series<Header> responseHeaders = (Series<Header>) getResponse().getAttributes().get("org.restlet.http.headers");
+		if (responseHeaders == null) {
+		    responseHeaders = new Series(Header.class);
+		    getResponse().getAttributes().put("org.restlet.http.headers", responseHeaders);
+		}
+		responseHeaders.add(new Header("Access-Control-Allow-Origin", "*"));
+		responseHeaders.add(new Header("Access-Control-Allow-Methods", "GET"));
+		
+		String projectName = (String) getRequest().getAttributes().get("name");
+		
+		Platform platform = Platform.getInstance();
+		ProjectRepository projectRepo = platform.getProjectRepositoryManager().getProjectRepository();
+		
+		// TODO: Do we need an Ossmeter mapper?
+		ObjectMapper mapper = new ObjectMapper();
+		
+		Project p = projectRepo.getProjects().findOneByShortName(projectName);
+		
+		if (p == null) {
+			getResponse().setStatus(Status.CLIENT_ERROR_BAD_REQUEST);
+			return Util.generateErrorMessage(generateRequestJson(mapper, projectName), "No project was found with the requested name.").toString();
+		}
+		
+		try {
+			// TODO:
+			return p.getDbObject().toString();//mapper.writeValueAsString(p);//
+		} catch (Exception e) {
+			e.printStackTrace();
+			return Util.generateErrorMessage(generateRequestJson(mapper, projectName), "An error occurred when converting the project to JSON: " + e.getMessage()).toString();
+		}
+	}
 	
-	[%}%]
-	[%for (sf in c.eStructuralFeatures.select(sf|not sf.isMany and sf.isAnnotatedWith("invisible"))) {%]
-	@JsonIgnore
-	abstract [%=sf.eType.getJavaName()%] get[%=sf.name.firstToUpperCase()%]();
+	private JsonNode generateRequestJson(ObjectMapper mapper, String projectName) {
+		ObjectNode n = mapper.createObjectNode();
+		n.put("project", projectName);
+		return n;
+	}
 	
-	[%}%]
-}+}
web/org.ossmeter.platform.client.api/src/org/ossmeter/platform/client/api/mixins/mixinUtil.eol to web/org.ossmeter.platform.client.api/src/org/ossmeter/platform/client/api/MetricVisualisationResource.java
--- a/web/org.ossmeter.platform.client.api/src/org/ossmeter/platform/client/api/mixins/mixinUtil.eol
+++ b/web/org.ossmeter.platform.client.api/src/org/ossmeter/platform/client/api/MetricVisualisationResource.java
@@ -1,35 +1,65 @@
-operation EModelElement isAnnotatedWith(anno : String) : Boolean {
-	return self.eAnnotations.selectOne(a | a.source = anno).isDefined();
-}
+package org.ossmeter.platform.client.api;
 
-operation EPackage getLastPackageName() {
-	return self.name.split("\\.").last().println();
-}
+import org.ossmeter.platform.Platform;
+import org.ossmeter.platform.visualisation.MetricVisualisation;
+import org.ossmeter.platform.visualisation.MetricVisualisationExtensionPointManager;
+import org.ossmeter.repository.model.Project;
+import org.ossmeter.repository.model.ProjectRepository;
+import org.restlet.data.Status;
+import org.restlet.engine.header.Header;
+import org.restlet.resource.Get;
+import org.restlet.resource.ServerResource;
+import org.restlet.util.Series;
 
-operation EClass getJavaExtends() : String {
-	if (self.eSuperTypes.size() > 0) {
-		return "extends " + self.eSuperTypes.get(0).getJavaName() + "Mixin";
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.mongodb.DB;
+
+public class MetricVisualisationResource extends ServerResource {
+
+	@Get
+	public String represent() {
+		Series<Header> responseHeaders = (Series<Header>) getResponse().getAttributes().get("org.restlet.http.headers");
+		if (responseHeaders == null) {
+		    responseHeaders = new Series(Header.class);
+		    getResponse().getAttributes().put("org.restlet.http.headers", responseHeaders);
+		}
+		responseHeaders.add(new Header("Access-Control-Allow-Origin", "*"));
+		responseHeaders.add(new Header("Access-Control-Allow-Methods", "GET"));
+		
+		String projectName = (String) getRequest().getAttributes().get("name");
+		String metricName = (String) getRequest().getAttributes().get("metricId");
+		String queryString = null;// FIXME: need to implement this
+		
+		Platform platform = Platform.getInstance();
+		ProjectRepository projectRepo = platform.getProjectRepositoryManager().getProjectRepository();
+		
+		Project project = projectRepo.getProjects().findOneByShortName(projectName);
+		if (project == null) {
+			getResponse().setStatus(Status.CLIENT_ERROR_BAD_REQUEST);
+			return Util.generateErrorMessage(generateRequestJson(projectName, metricName), "No project was found with the requested name.").toString();
+		}
+		
+		MetricVisualisationExtensionPointManager manager = MetricVisualisationExtensionPointManager.getInstance();
+		MetricVisualisation vis = manager.findVisualisationById(metricName);
+		
+		if (vis == null) {
+			return Util.generateErrorMessage(generateRequestJson(projectName, metricName), "No visualiser found with specified ID.").toString();
+		}
+		
+		DB db = platform.getMetricsRepository(project).getDb();
+		JsonNode visualisation = vis.visualise(db);
+		return visualisation.toString();
 	}
-	else {
-		return "";
+	
+	private JsonNode generateRequestJson(String projectName, String metricId) {
+		ObjectMapper mapper = new ObjectMapper();
+		ObjectNode r = mapper.createObjectNode();
+		
+		r.put("project", projectName);
+		r.put("metricId", metricId);
+		
+		return r;
 	}
 }
-
-operation EClassifier getJavaName() : String {
-	switch (self.name) {
-		case "EString": return "String";
-		case "ELong": return "long";
-		case "EInt": return "int";
-		case "EBoolean": return "boolean";
-		case "EFloat": return "float";
-		case "EIntegerObject": return "int";
-		case "EBooleanObject": return "boolean";
-		case "EDouble": return "double";
-		default: return self.name;
-	}
-}
-
-operation EClassifier getMixinClassName() : String {
-	var ann = self.eAnnotations.selectOne(a|a.source = "mixin");
-	return ann.details.selectOne(a | a.key="javaClass").value;
-}
web/org.ossmeter.platform.client.api/src/org/ossmeter/platform/client/api/MetricsResource.java to web/org.ossmeter.platform.client.api/src/org/ossmeter/platform/client/api/RawMetricResource.java
--- a/web/org.ossmeter.platform.client.api/src/org/ossmeter/platform/client/api/MetricsResource.java
+++ b/web/org.ossmeter.platform.client.api/src/org/ossmeter/platform/client/api/RawMetricResource.java
@@ -1,33 +1,23 @@
 package org.ossmeter.platform.client.api;
-
-import java.io.IOException;
-import java.util.List;
 
 import org.ossmeter.platform.IMetricProvider;
 import org.ossmeter.platform.Platform;
-import org.ossmeter.repository.model.MetricProvider;
 import org.ossmeter.repository.model.MetricProviderExecution;
 import org.ossmeter.repository.model.Project;
 import org.ossmeter.repository.model.ProjectRepository;
-import org.restlet.data.Form;
 import org.restlet.data.Status;
 import org.restlet.engine.header.Header;
-import org.restlet.representation.Representation;
 import org.restlet.resource.Get;
-import org.restlet.resource.Options;
 import org.restlet.resource.ServerResource;
 import org.restlet.util.Series;
 
-import com.fasterxml.jackson.core.JsonFactory;
-import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.node.JsonNodeFactory;
 import com.fasterxml.jackson.databind.node.ObjectNode;
-import com.googlecode.pongo.runtime.viz.PongoViz;
 import com.mongodb.DB;
 import com.mongodb.DBCollection;
 
-public class MetricsResource extends ServerResource {
+public class RawMetricResource extends ServerResource {
 
 	/**
 	 * TODO: Incomplete. [12th Sept, 2013]
@@ -60,58 +50,29 @@
 		Project project = projectRepo.getProjects().findOneByShortName(projectName);
 		if (project == null) {
 			getResponse().setStatus(Status.CLIENT_ERROR_BAD_REQUEST);
-			return Util.generateErrorMessage(generateRequestJson(projectName, metricName), "No project was found with the requested name.");
-		}
-
-		IMetricProvider metricProvider = null;
-		for (MetricProviderExecution mp : project.getExecutionInformation().getMetricProviderData()) {
-			for (IMetricProvider imp : platform.getMetricProviderManager().getMetricProviders()) { // This is ugly. Required as repo.model.MetricProvider doesn't have the info
-				if (imp.getShortIdentifier().equals(metricName)) {
-					metricProvider = imp;
-					break;
-				}
-			}
-		}
-		
-		if (metricProvider == null) {
-			getResponse().setStatus(Status.CLIENT_ERROR_BAD_REQUEST);
-			return Util.generateErrorMessage(generateRequestJson(projectName, metricName), "No metric was found with the requested identifier.");
+			return Util.generateErrorMessage(generateRequestJson(projectName, metricName), "No project was found with the requested name.").toString();
 		}
 
 		// Get collection from DB
 		DB projectDB = platform.getMetricsRepository(project).getDb();
-		DBCollection collection = projectDB.getCollection(metricProvider.getIdentifier());
 		
+		// TODO: essentially we want a mongoexport of the collection. Can we stream it?
+		// However this may also want to be filtered and aggregated? 
 		
-		
-		List<PongoViz> vizs = VisualisationExtensionPointManager.getInstance().getVisualisersForMetricProvider(metricProvider.getIdentifier(), projectDB);
-		for (PongoViz v : vizs) {
-			String vizString = v.getViz("json"); // FIXME hardcoded.
-			
-			ObjectMapper mapper = new ObjectMapper();
-			JsonFactory factory = mapper.getFactory();
-			JsonParser parser;
-			ObjectNode root;
-			try {
-				System.out.println(vizString);
-				parser = factory.createParser(vizString);
-				root = parser.readValueAsTree();
-			} catch (IOException e) {
-				e.printStackTrace();
-				return Util.generateErrorMessage(generateRequestJson(projectName, metricName), "An error occurred during JSON generation: " + e.getMessage());
-			}
-			JsonNodeFactory nodeFactory = JsonNodeFactory.instance;
-			root.set("friendlyName", nodeFactory.textNode(metricProvider.getFriendlyName()));
-			root.set("summary", nodeFactory.textNode(metricProvider.getSummaryInformation()));
-
-			return root.toString();// FIXME: only returns one.
-		}
-		
-		return Util.generateErrorMessage(generateRequestJson(projectName, metricName), "No visualiser found.");
+		ObjectMapper mapper = new ObjectMapper();
+		ObjectNode n = mapper.createObjectNode();
+		n.put("status", "unimplemented - sorry :(");
+		return n.toString();
 	}
 	
 	
-	private String generateRequestJson(String projectName, String metricId) {
-		return "{\"project\" : \"" + projectName + "\", \"metricId\" : \"" + metricId + "\" }";
+	private JsonNode generateRequestJson(String projectName, String metricId) {
+		ObjectMapper mapper = new ObjectMapper();
+		ObjectNode r = mapper.createObjectNode();
+		
+		r.put("project", projectName);
+		r.put("metricId", metricId);
+		
+		return r;
 	}
 }