From 493cbfd38be3c72f0a376f6d7206dc61d73ea7e6 Mon Sep 17 00:00:00 2001
From: cramakri <cramakri>
Date: Mon, 22 Oct 2012 09:11:22 +0000
Subject: [PATCH] Initial step in switch to progressive retrieval of
 information

SVN: 27267
---
 openbis-ipad/core-plugin/readme.md            |  10 +-
 .../ipad-read-service-v1/ipad_read.py         | 109 ++++++++++++++++--
 2 files changed, 108 insertions(+), 11 deletions(-)

diff --git a/openbis-ipad/core-plugin/readme.md b/openbis-ipad/core-plugin/readme.md
index 54eea133ecc..321639e1065 100644
--- a/openbis-ipad/core-plugin/readme.md
+++ b/openbis-ipad/core-plugin/readme.md
@@ -90,7 +90,7 @@ The iPad data model tracks information for displaying and navigating between ent
 		</tr>
 		<tr>
 			<td>CATEGORY</td>
-			<td>A category identifier for showing the entity. If empty or None, then the the entity in this row is not shown in top level navigation views. Such entities may appear as children of other entities.</td>
+			<td>A category identifier for grouping entities.</td>
 			<td>Used to group entities together</td>
 			<td>openBIS entity type</td>
 		</tr>
@@ -112,6 +112,12 @@ The iPad data model tracks information for displaying and navigating between ent
 			<td>Shown in detail views.</td>
 			<td>openBIS properties</td>
 		</tr>
+		<tr>
+			<td>ROOT_LEVEL</td>
+			<td>True if the entity should be shown on the root level.</td>
+			<td>Used to construct the initial navigation view.</td>
+			<td>Empty means do not show. Non-empty means show.</td>
+		</tr>
 	</tbody>
 </table>
 
@@ -144,7 +150,7 @@ The communication model between the iPad and the service has been designed to tr
 			<td>None</td>
 			<td>Return root entities.</td>
 			<td>Used to initialize the root navigation view.</td>
-			<td>PERM_ID, REFCON, CATEGORY, SUMMARY_HEADER, SUMMARY, CHILDREN</td>
+			<td>PERM_ID, REFCON, CATEGORY, SUMMARY_HEADER, SUMMARY, CHILDREN, ROOT_LEVEL</td>
 		</tr>
 		<tr>
 			<td>DRILL</td>
diff --git a/openbis-ipad/ipad-example-data/ipad-ui/1/dss/reporting-plugins/ipad-read-service-v1/ipad_read.py b/openbis-ipad/ipad-example-data/ipad-ui/1/dss/reporting-plugins/ipad-read-service-v1/ipad_read.py
index 7e109f6deb1..c3fbe51da63 100644
--- a/openbis-ipad/ipad-example-data/ipad-ui/1/dss/reporting-plugins/ipad-read-service-v1/ipad_read.py
+++ b/openbis-ipad/ipad-example-data/ipad-ui/1/dss/reporting-plugins/ipad-read-service-v1/ipad_read.py
@@ -1,6 +1,7 @@
 from ch.systemsx.cisd.openbis.dss.generic.shared.api.internal.v1 import MaterialIdentifierCollection
 from ch.systemsx.cisd.openbis.generic.shared.basic.dto import MaterialIdentifier
 from com.fasterxml.jackson.databind import ObjectMapper 
+from ch.systemsx.cisd.openbis.generic.shared.api.v1.dto import SearchCriteria
 
 #
 # BEGIN Infrastructure
@@ -60,9 +61,7 @@ class RequestHandler:
 			REFCON : Data that is passed unchanged back to the server when a row is modified.
 				This can be used by the server to encode whatever it needs in order to
 				modify the row. (required)
-			CATEGORY : A category identifier for showing the entity. If empty or None, then the
-				the entity in this row is not shown in top level navigation views. Such entities
-				may appear as children of other entities.
+			CATEGORY : A category identifier for grouping entities.
 			SUMMARY_HEADER : A short summary of the entity.
 			SUMMARY : A potentially longer summary of the entity.
 			CHILDREN : The permIds of the children of this entity. Transmitted as JSON.
@@ -70,6 +69,7 @@ class RequestHandler:
 			IMAGE_URL : A url for an image associated with this entity. If None or empty, no
 				image is shown.
 			PROPERTIES : Properties (metadata) that should be displayed for this entity. Transmitted as JSON.
+			ROOT_LEVEL : True if the entity should be shown on the root level.
 
 		The relevant headers are determined by the request.
 		"""
@@ -80,16 +80,13 @@ class RequestHandler:
 		"""Append a row of data to the table"""
 		row = self.builder.addRow()
 		for header in self.headers:
-			row.setCell(header, entry.get(header))
+			row.setCell(header, str(entry.get(header)))
 
 	def add_rows(self, entities):
 		"""Take a collection of dictionaries and add a row for each one"""
 		for entry in entities:
 			self.add_row(entry)
 
-	def json_encoded_value(self, coll):
-		return ObjectMapper().writeValueAsString(coll)
-
 	def process_request(self):
 		"""Execute the steps necessary to process the request."""
 		self.add_headers()
@@ -102,6 +99,24 @@ class AllDataRequestHandler(RequestHandler):
 	def optional_headers(self):
 		return ["CATEGORY", "SUMMARY_HEADER", "SUMMARY", "CHILDREN", "IDENTIFIER", "IMAGE_URL", "PROPERTIES"]
 
+class RootRequestHandler(RequestHandler):
+	"""Abstract Handler for the ROOT request."""
+
+	def optional_headers(self):
+		return ["CATEGORY", "SUMMARY_HEADER", "SUMMARY", "CHILDREN", "ROOT_LEVEL"]
+
+class DrillRequestHandler(RequestHandler):
+	"""Abstract Handler for the DRILL request."""
+
+	def optional_headers(self):
+		return ["CATEGORY", "SUMMARY_HEADER", "SUMMARY", "CHILDREN"]
+
+class DetailRequestHandler(RequestHandler):
+	"""Abstract Handler for the DETAIL request."""
+
+	def optional_headers(self):
+		return ["CATEGORY", "SUMMARY_HEADER", "SUMMARY", "IDENTIFIER", "IMAGE_URL", "PROPERTIES"]
+
 #
 # END Infrastructure
 #
@@ -120,6 +135,7 @@ def material_to_dict(material):
 	material_dict['IDENTIFIER'] = material.getMaterialIdentifier()
 	material_dict['PERM_ID'] = material.getMaterialIdentifier()
 	refcon = {}
+	refcon['code'] =  material.getCode()
 	refcon['entityKind'] = 'MATERIAL'
 	refcon['entityType'] = material.getMaterialType()
 	material_dict['REFCON'] = json_encoded_value(refcon)
@@ -130,6 +146,7 @@ def material_to_dict(material):
 	else:
 		material_dict['SUMMARY'] = material.getPropertyValue("DESC")
 		material_dict['IMAGE_URL'] = ""
+		material_dict['ROOT_LEVEL'] = True
 
 	material_dict['CHILDREN'] = json_encoded_value([])
 
@@ -145,6 +162,7 @@ def sample_to_dict(five_ht_sample, material_by_perm_id):
 	sample_dict['IDENTIFIER'] = five_ht_sample.getSampleIdentifier()
 	sample_dict['PERM_ID'] = five_ht_sample.getPermId()
 	refcon = {}
+	refcon['code'] =  five_ht_sample.getCode()
 	refcon['entityKind'] = 'SAMPLE'
 	refcon['entityType'] = five_ht_sample.getSampleType()
 	sample_dict['REFCON'] = json_encoded_value(refcon)
@@ -158,6 +176,7 @@ def sample_to_dict(five_ht_sample, material_by_perm_id):
 	prop_names = ["DESC"]
 	properties = dict((name, five_ht_sample.getPropertyValue(name)) for name in prop_names if five_ht_sample.getPropertyValue(name) is not None)
 	sample_dict['PROPERTIES'] = json_encoded_value(properties)
+	sample_dict['ROOT_LEVEL'] = True
 	# Need to handle the material links as entity links: "TARGET", "COMPOUND"
 	return sample_dict
 
@@ -181,6 +200,13 @@ def samples_to_dict(samples, material_by_perm_id):
 	result = [sample_to_dict(sample, material_by_perm_id) for sample in samples]
 	return result
 
+def retrieve_samples(sample_perm_id_and_ref_cons):
+	sc = SearchCriteria()
+	for sample in sample_perm_id_and_ref_con:
+		code = sample['REFCON']['code']	
+		sc.addMatchClause(sc.MatchClause.createAttributeMatch(sc.MatchClauseAttribute.CODE, code))
+	return searchService.searchForSamples(sc)
+
 class ExampleAllDataRequestHandler(AllDataRequestHandler):
 	"""Handler for the ALLDATA request."""
 
@@ -196,6 +222,71 @@ class ExampleAllDataRequestHandler(AllDataRequestHandler):
 		self.add_rows(self.material_dict_array)
 		self.add_rows(samples_to_dict(self.samples, self.material_by_perm_id))
 
+class ExampleRootRequestHandler(RootRequestHandler):
+	"""Handler for the ROOT request."""
+
+	def retrieve_data(self):
+		# Get the data and add a row for each data item
+		self.samples = self.searchService.searchForSamples("DESC", "*", "5HT_PROBE")
+		material_identifiers = gather_materials(self.samples)
+		materials = self.searchService.listMaterials(material_identifiers)
+		self.material_dict_array = materials_to_dict(materials)
+		self.material_by_perm_id = dict([(material.getMaterialIdentifier(), material) for material in materials])
+
+	def add_data_rows(self):
+		self.add_rows(self.material_dict_array)
+		self.add_rows(samples_to_dict(self.samples, self.material_by_perm_id))
+
+class ExampleDrillRequestHandler(DrillRequestHandler):
+	"""Handler for the DRILL request."""
+
+	def retrieve_data(self):
+		# Drill only happens on samples
+		drill_samples = self.parameters['entities']
+
+		self.samples = retrieve_samples(drill_samples)
+		material_identifiers = gather_materials(self.samples)
+		materials = self.searchService.listMaterials(material_identifiers)
+		self.material_dict_array = materials_to_dict(materials)
+		self.material_by_perm_id = dict([(material.getMaterialIdentifier(), material) for material in materials])
+
+	def add_data_rows(self):
+		self.add_rows(self.material_dict_array)
+		self.add_rows(samples_to_dict(self.samples, self.material_by_perm_id))
+
+class ExampleDetailRequestHandler(DetailRequestHandler):
+	"""Handler for the DETAIL request."""
+
+	def retrieve_data(self):
+		# Get the data and add a row for each data item
+		entities = self.parameters['entities']
+		detail_samples = [entity for entity in entities and 'SAMPLE' == entity['REFCON']['entityKind']]
+		self.samples = retrieve_samples(detail_samples)
+
+		detail_materials = [entity for entity in entities and 'MATERIAL' == entity['REFCON']['entityKind']]
+		material_identifiers = MaterialIdentifierCollection()
+		for detail_material in detail_materials:
+			add_material_to_collection(detail_material, material_identifiers)
+
+		materials = self.searchService.listMaterials(material_identifiers)
+		self.material_dict_array = materials_to_dict(materials)
+		self.material_by_perm_id = dict([(material.getMaterialIdentifier(), material) for material in materials])
+
+	def add_data_rows(self):
+		self.add_rows(self.material_dict_array)
+		self.add_rows(samples_to_dict(self.samples, self.material_by_perm_id))
+
 def aggregate(parameters, builder):
-	handler = ExampleAllDataRequestHandler(parameters, builder)
-	handler.process_request()
+	request_key = parameters.get('requestKey')
+	if 'ROOT' == request_key:
+		handler = ExampleRootRequestHandler(parameters, builder)
+		handler.process_request()
+	elif 'DRILL' == request_key:
+		handler = ExampleDrillRequestHandler(parameters, builder)
+		handler.process_request()
+	elif 'DETAIL' == request_key:
+		handler = ExampleDetailRequestHandler(parameters, builder)
+		handler.process_request()
+	else:
+		handler = ExampleAllDataRequestHandler(parameters, builder)
+		handler.process_request()
-- 
GitLab