From a0a43e3bf3deaee0a682e45b4e4b08db95722692 Mon Sep 17 00:00:00 2001
From: cramakri <cramakri>
Date: Tue, 30 Apr 2013 09:09:50 +0000
Subject: [PATCH] BIS-407 SP-634 : Moved all ipad framework classes to Java.

SVN: 28929
---
 .../ipad-read-service-v1/ipad_read.py         | 246 +++---------------
 .../lib/ipad-framework.jar                    | Bin 0 -> 21523 bytes
 .../ClientPreferencesRequestHandler.java      |   6 +-
 3 files changed, 37 insertions(+), 215 deletions(-)
 create mode 100644 openbis-ipad/source/core-plugins/ipad-ui/1/dss/reporting-plugins/ipad-read-service-v1/lib/ipad-framework.jar

diff --git a/openbis-ipad/source/core-plugins/ipad-ui/1/dss/reporting-plugins/ipad-read-service-v1/ipad_read.py b/openbis-ipad/source/core-plugins/ipad-ui/1/dss/reporting-plugins/ipad-read-service-v1/ipad_read.py
index c6852b01772..8723e7c8e06 100644
--- a/openbis-ipad/source/core-plugins/ipad-ui/1/dss/reporting-plugins/ipad-read-service-v1/ipad_read.py
+++ b/openbis-ipad/source/core-plugins/ipad-ui/1/dss/reporting-plugins/ipad-read-service-v1/ipad_read.py
@@ -1,6 +1,7 @@
+from ch.systemsx.cisd.openbis.ipad.v2.server import AbstractRequestHandler, ClientPreferencesRequestHandler, RootRequestHandler, DrillRequestHandler, NavigationRequestHandler, DetailRequestHandler, EmptyDataRequestHandler
 from ch.systemsx.cisd.openbis.dss.generic.shared.api.internal.v2 import MaterialIdentifierCollection
 from ch.systemsx.cisd.openbis.generic.shared.basic.dto import MaterialIdentifier
-from com.fasterxml.jackson.databind import ObjectMapper 
+from com.fasterxml.jackson.databind import ObjectMapper
 from ch.systemsx.cisd.openbis.generic.shared.api.v1.dto import SearchCriteria, SearchSubCriteria
 
 from datetime import datetime
@@ -21,188 +22,6 @@ def json_empty_dict():
   """Utility function to return an json-encoded empty dictionary"""
   return json_encoded_value({})
 
-class RequestHandler(object):
-	"""Abstract superclass for the handlers for concrete requests like ROOT.
-
-	This superclass defines behavior common to all requests.
-
-	Subclasses need to implement the method optional_headers(), which returns
-	a list of the optional headers they fill out.
-
-	Subclasses should implement retrieve_data to get the data they provide.
-
-	Subclasses should implement add_data_rows. In this method, they should call add_row.
-	The method add_row takes a dictionary as an argument. The keys of the dictionary match the
-	headers in the result columns. The dictionary should include data for the required columns
-	and optional ones they fill.
-
-	"""
-
-	def __init__(self, parameters, builder):
-		self.parameters = parameters
-		self.builder = builder
-		global searchService
-		self.searchService = searchService
-		self.headers = ['PERM_ID', 'REFCON'] + self.optional_headers()
-		
-	def entities_parameter(self):
-	  """A helper method to get the value of the entities parameter. Returns an empty list if no entities were specified"""
-	  entities = self.parameters.get('entities')
-	  if entities is None:
-	    return []
-	  return entities
-
-
-	def optional_headers(self):
-		"""Return a list of optional headers supported by this request. Sublass responsibility.
-
-		See add_headers() for the list of supported headers
-		"""
-		return []
-
-	def retrieve_data(self):
-		"""Get the data for the request. Subclass responsibility"""
-		pass
-
-	def add_data_rows(self):
-		"""Take the information from the data and put it into the table.
-		Subclass responsibility.
-		"""
-		pass
-
-	def add_headers(self):
-		"""Configure the headers for this request.
-
-		The possible headers come from the following list:
-			PERM_ID : A stable identifier for the object. (required)
-			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 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.
-			IDENTIFIER : An identifier for the object.
-			IMAGES : A map with keys coming from the set 'MARQUEE', 'TILED'. The values are image specs or lists of image specs.
-				Image specs are maps with the keys: 'URL' (a URL for the iamge) or 'DATA'. The data key contains a map that
-				includes the image data and may include some image metadata as well. This format has not yet been specified.
-			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.
-		"""
-		for header in self.headers:
-			self.builder.addHeader(header)
-
-	def add_row(self, entry):
-		"""Append a row of data to the table"""
-		row = self.builder.addRow()
-		for header in self.headers:
-			value = entry.get(header)
-			if value is not None:
-				row.setCell(header, value)
-			else:
-				row.setCell(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 process_request(self):
-		"""Execute the steps necessary to process the request."""
-		self.add_headers()
-		self.retrieve_data()
-		self.add_data_rows()
-
-class ClientPreferencesRequestHandler(object):
-	"""Abstract superclass for the handlers for CLIENT_PREFS request.
-
-	This request has a slightly different structure, since it does not return entities.
-
-	Subclasses should override the preferences_dict method to return the preferences dictionary. The superclass
-	implements this method with the default values for the standard keys.
-	"""
-
-	def __init__(self, parameters, builder):
-		self.parameters = parameters
-		self.builder = builder
-		self.headers = ['KEY', 'VALUE']
-
-	def preferences_dict(self):
-		"""The dictionary containing the value for the client preferences. 
-
-		Subclasses may override if they want to change any of the values. The best way to override is to call
-		default_preferences_dict then modify/extend the resulting dictionary"""
-		return self.default_preferences_dict()
-
-	def default_preferences_dict(self):
-		"""The dictionary containing the standard keys and and default values for those keys"""
-		prefs = { 
-			# The refresh interval is a value in seconds
-			'ROOT_SET_REFRESH_INTERVAL' : 60 * 30 
-		}
-		return prefs
-
-	def add_data_rows(self):
-		"""Take the information from the preferences dict and put it into the table."""
-		prefs = self.preferences_dict()
-		for key in prefs:
-			row = self.builder.addRow()
-			row.setCell('KEY', key)
-			row.setCell('VALUE', prefs[key])
-
-	def add_headers(self):
-		"""Configure the headers for this request.
-
-		For preference request, the headers are 
-			KEY : The key of the preference.
-			VALUE : The value of the preference.
-		"""
-		for header in self.headers:
-			self.builder.addHeader(header)
-
-	def process_request(self):
-		"""Execute the steps necessary to process the request."""
-		self.add_headers()
-		self.add_data_rows()
-
-class AllDataRequestHandler(RequestHandler):
-	"""Abstract Handler for the ALLDATA request."""
-
-	def optional_headers(self):
-		return ["CATEGORY", "SUMMARY_HEADER", "SUMMARY", "CHILDREN", "IDENTIFIER", "IMAGES", "PROPERTIES"]
-
-class EmptyDataRequestHandler(RequestHandler):
-	"""Return nothing to the caller."""
-
-	def add_data_rows(self):
-		pass
-
-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", "IMAGES", "PROPERTIES"]
-
-class NavigationRequestHandler(RequestHandler):
-	"""Abstract Handler for the NAVIGATION request."""
-
-	def optional_headers(self):
-		return ["CATEGORY", "SUMMARY_HEADER", "SUMMARY", "ROOT_LEVEL"]
-
 #
 # END Infrastructure
 #
@@ -419,14 +238,14 @@ class ExampleRootRequestHandler(RootRequestHandler):
 	"""Handler for the ROOT request."""
 
 	def entities_parameter(self):
-		entities = super(ExampleRootRequestHandler, self).entities_parameter()
+		entities = self.getEntitiesParameter()
 		if len(entities) == 0:
 			materials_nav = navigation_dict('Targets and Compounds', [])
 			probe_nav = navigation_dict('Probes', [])
 			return [materials_nav, probe_nav]
 		return entities
 
-	def retrieve_data(self):
+	def retrieveData(self):
 		# Check which navigational entities are being requested here
 		nav_entities = self.entities_parameter()
 		nav_perm_ids = [entity['PERM_ID'] for entity in nav_entities]
@@ -438,28 +257,29 @@ class ExampleRootRequestHandler(RootRequestHandler):
 		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):
+	def addDataRows(self):
 		nav_entities = self.entities_parameter()
 		nav_perm_ids = [entity['PERM_ID'] for entity in nav_entities]
 
 		if 'TARGETS AND COMPOUNDS' in nav_perm_ids:
 			children = [material_dict['PERM_ID'] for material_dict in self.material_dict_array]
 			materials_nav = navigation_dict('Targets and Compounds', children)
-			self.add_rows([materials_nav])
-			self.add_rows(self.material_dict_array)
+			self.addRows([materials_nav])
+			self.addRows(self.material_dict_array)
 
 		if 'PROBES' in nav_perm_ids:
 			children = [sample.getPermId() for sample in self.samples]
 			probe_nav = navigation_dict('Probes', children)
-			self.add_rows([probe_nav])
-			self.add_rows(samples_to_dict(self.samples, self.material_by_perm_id, {}))
+			self.addRows([probe_nav])
+			self.addRows(samples_to_dict(self.samples, self.material_by_perm_id, {}))
+
 
 class ExampleDrillRequestHandler(DrillRequestHandler):
 	"""Handler for the DRILL request."""
 
-	def retrieve_data(self):
+	def retrieveData(self):
 		# Drill only happens on samples
-		drill_samples = self.entities_parameter()
+		drill_samples = self.getEntitiesParameter()
 
 		self.samples = retrieve_samples(drill_samples)
 		material_identifiers = gather_materials(self.samples)
@@ -467,16 +287,17 @@ class ExampleDrillRequestHandler(DrillRequestHandler):
 		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 addDataRows(self):
+		self.addRows(self.material_dict_array)
+		self.addRows(samples_to_dict(self.samples, self.material_by_perm_id, {}))
+
 
 class ExampleDetailRequestHandler(DetailRequestHandler):
 	"""Handler for the DETAIL request."""
 
-	def retrieve_data(self):
+	def retrieveData(self):
 		# Get the data and add a row for each data item
-		entities = self.entities_parameter()
+		entities = self.getEntitiesParameter()
 		detail_samples = [entity for entity in entities if 'SAMPLE' == entity['REFCON']['entityKind']]
 		detail_materials = [entity for entity in entities if 'MATERIAL' == entity['REFCON']['entityKind']]
 
@@ -497,21 +318,22 @@ class ExampleDetailRequestHandler(DetailRequestHandler):
 		self.material_dict_array = materials_to_dict(materials_to_return, self.material_type_properties_definitions)
 		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, self.sample_type_properties_definitions))
+	def addDataRows(self):
+		self.addRows(self.material_dict_array)
+		self.addRows(samples_to_dict(self.samples, self.material_by_perm_id, self.sample_type_properties_definitions))
 
 class ExampleNavigationRequestHandler(NavigationRequestHandler):
 	"""Handler for the NAVIGATION request"""
-	def add_data_rows(self):
+	def addDataRows(self):
 		materials_nav = navigation_dict('Targets and Compounds', [])
 		probe_nav = navigation_dict('Probes', [])
-		self.add_rows([materials_nav, probe_nav])
+		self.addRows([materials_nav, probe_nav])
+
 
 class TestingNavigationRequestHandler(ExampleNavigationRequestHandler):
 	"""A version of the NAVIGATION request handler designed for testing"""
 
-	def add_data_rows(self):
+	def addDataRows(self):
 		hidden_entities = self.parameters.get("HIDE")
 		if hidden_entities is None:
 			hidden_entities = []
@@ -519,23 +341,23 @@ class TestingNavigationRequestHandler(ExampleNavigationRequestHandler):
 
 		if 'TARGETS AND COMPOUNDS' not in hidden_perm_ids:
 			materials_nav = navigation_dict('Targets and Compounds', [])
-			self.add_rows([materials_nav])
+			self.addRows([materials_nav])
 		if 'PROBES' not in hidden_perm_ids:
 			probe_nav = navigation_dict('Probes', [])
-			self.add_rows([probe_nav])
+			self.addRows([probe_nav])
 
 def aggregate(parameters, builder):
 	request_key = parameters.get('requestKey')
 	if 'CLIENT_PREFS' == request_key:
-		handler = ExampleClientPreferencesRequestHandler(parameters, builder)
+		handler = ExampleClientPreferencesRequestHandler(parameters, builder, searchService)
 	elif 'NAVIGATION' == request_key:
-		handler = TestingNavigationRequestHandler(parameters, builder)
+		handler = TestingNavigationRequestHandler(parameters, builder, searchService)
 	elif 'ROOT' == request_key:
-		handler = ExampleRootRequestHandler(parameters, builder)
+		handler = ExampleRootRequestHandler(parameters, builder, searchService)
 	elif 'DRILL' == request_key:
-		handler = ExampleDrillRequestHandler(parameters, builder)
+		handler = ExampleDrillRequestHandler(parameters, builder, searchService)
 	elif 'DETAIL' == request_key:
-		handler = ExampleDetailRequestHandler(parameters, builder)
+		handler = ExampleDetailRequestHandler(parameters, builder, searchService)
 	else:
-		handler = EmptyDataRequestHandler(parameters, builder)
-	handler.process_request()		
+		handler = EmptyDataRequestHandler(parameters, builder, searchService)
+	handler.processRequest()		
diff --git a/openbis-ipad/source/core-plugins/ipad-ui/1/dss/reporting-plugins/ipad-read-service-v1/lib/ipad-framework.jar b/openbis-ipad/source/core-plugins/ipad-ui/1/dss/reporting-plugins/ipad-read-service-v1/lib/ipad-framework.jar
new file mode 100644
index 0000000000000000000000000000000000000000..22ab38d03c7532d04a6dada46155779631697ecf
GIT binary patch
literal 21523
zcmeHPYj7Labv_G%To43B5#mFXs3$3j0w2&@wkRp$0~8^G4-vFv`XOlvu1H8AKmnj6
zDs~({6FZID)M;9~mD9#;)JNJVaU_vZow29Wq;;KkI^*eM`lE?w(m(CAGwrlLI-RKB
zxx2tFfCU9g)U>uK56s=Wch5cN+<VV=9v2wuE3#LS1OIu4-|QsQzbdj*zi*_Y)j!bV
z?e7@y_xOS%ZT&qzf1l_-`ak%KKwoRyUzhi_dj9f*zj}Lk$A`Or^0SYAW}~4#+40?H
zZ2!6zr0Vb)!T?S|wmtA>r*rRXJ$*Gq{OLw(XwsXQO(fN+#AR<NoEZ1Urq$?JIN=RX
zE92gaySxcCeo>8kJH`^pxDrYZs~2X}M6y?jjz`pZTPUI=67T=~`#%7wU36O}n?#52
zkETp^iB_IdE-K!L5}oi4j-69ONtsF{+FvMTe<qs}Ij5DlGNmTfctWCzfS^8;3`e~E
z%5=L#rNQt-R7uXnRf+ayK0T=23RZ&2csM%IZfen(Yd;Jc^4Lr`GOorYIu*#v=Y$$n
z<Kd7uF{#AWaqpB8RVLK&)6;RNJ)WHPD$`-FKNy~xj;JHbSVZlQjjNGPjc~`fGM$XY
zF;sa%RpOz^Af_f90?UE?1CA#W-mF1+jBpgHh$<1DVSms}jU|~>6$k=Ntu*N(5KbiV
zuraI2LO((q2{qZJMj{ejZpzPH7H8J#7>-@a(tv3K@=nS26B60Gpgx&uGS-v!Mj5T9
zH8RynG<biLmBXEj+_YArZA}Yusq?-4giPxsT45~rKrA}pq<Y%mqK&i(OEZFo6G~(T
z^IX)l{TMUez+*H@RAVv5F($b+L*nk(43?6UwosFcwv$JqvT@O5knLu&Eljr6nrt_d
z^`<x#Tc=w|s{Gncer=aTTP(OSEf((HzWs!gifE6E_R>Cy9Lbob2Z^ehw&&`Lw`w@5
z4$MrAsd2F%BytC0AtiD`iHCWA=#543*d>XMFZn`)%FnB_Jg6~2`pijGd{LVf^F!Sp
zV2cKmO6WYSi_T$1Tun^Jq6xJ(wYN6w>JqvXn@iV#(IC;W>`s>3E&D~wP7dnE)*kW=
z_n-E6JE%vZl3`y@*WiGYdg+)<{?wWg<9Ed4%51_#eH1`PCBY2x6hCg#gf49M=<PBM
zNVLkZv4R#8a8f@Fx#&0zgXY0-G@LvvQJq=Du2>`jYafn9#Zu{~5f?o|*vci!_;?4K
zlf2y@!)l35^Q%fEtz@YE!b}*ZHr?V>BF5ut)A~$v2_sjNxyWXxQwz;3Yx)ICbxZVt
zSun<#`&^!Pfrb3k7mooZwP-8zgd~+@iDMyk?%Fu~@fF%azQelxI>T#N5%%~*DM=J^
zkxUN0Qe9L=F20&@Q8}$};wtQ-Bh<ld=Ur4mD}hVN$uQ9MNd74+$os-VEuT=6Lnhaz
zGG#`^Cf1yr{n>36l3C3hye3fBp;w|aAaj3Ed6xyOjhEi2?hLlYGL&d*PNRh|?0>8T
z>luEHL<0*6u=qU!%)%JHXfm7(tBLd^IOqz1P1T#r=qdV~OiyE`410)aanUpMc`P7M
zV4-r=uNxYZ2Mn|NTn7GX7WD;sNv0Pisy65wMid783xp9$)v4*^EWaR;E3U$gRWGUl
zWUS#b7*@W5AA=?7#GO6^W%Mllf{VUPuR@+M+(iY>Cp!mb8|c^D+so*e=$B>s3b4{(
zB=yuquhCbr?4#;sFpvrLI*63f*XY+|`c;XZc#w<CMX%Ev&_`NKD9)_?v|GmV{DzCJ
z(wpoLD~SQYIvg;-Ov$9ca1E58H^`i28(}9TdMK;WVx{KJJDV8R#c#XlH|cjI3NEy0
z@6ml`qjZg(wp9-LJ&ABvjP)9apCdyr+Co@mW<G@hdEJqewJA_U&5la+Z5HykFf0#`
zO(fA#O(SU+NGG^x`q(IlsX}TZp+|x&^Y>iz3MqVb(?ws@uI60yGMjQ|Fg6npsXgHc
z{Oq-PqFr9uv<dGQvCa^lSFzp4bt%GM8#!?g>yPUyw*BHS?0x!qCE7|^?P#gO)4vCW
zBK$qu@*Y*cPL-bKmUpRoo@$He8U@i<|2kEP#`>GIex5el(cX^sEvfb`H)-2EHFJ9d
z+S^h@+U98o6Ip?`Z_;i-@;ex*i1y?EZQzn<H+bI*ZuTMAc!)goFzums>ZF4dpu=>M
zK0}XD2dUJBr-WEUaEe|Ba0i~z_aNlpt3&8-Lw^Fr;_BMkDkoF{$U~#1m`)+?Yr41%
z#qUt{Xpy@sIBIwMf^(Sk+tfeWe2WJATRb-@c(Ua>XlcB<@e<Kd@Yzdi$q(%xGx5^^
zK3C$on=0v1q3N}lk5O=LqsP&%am~Fd)4eLewbtti^s)oVpG-4)N-+9$+!v$&I?pXS
z?P<P2W1f~9H127=L1#U6_BoooLFWv0uAvfieiEb<$UBBf4q=MNp;lF}x<?~M5t>3j
zkkuCrU-5FWi8fv^tm1V-B)ee0Mt>$lpR8(rR*7*Wic&1i^t52wi&pMa?D-yzvHomg
zu1iE?STN$!I_Qi@bb;b%;gx89c|7~&sO8HEN~SrO$suwsn@GZv$VIwj!NJ+=moHnq
zY^TdP9L$0v)@B{+z&$%ppS97u^lYH{M<mbD^Vgf1uwCdyTUXD+AA13l^%B*>An-cZ
zR9>g+r~-<=BGwhJCf1+U!fS}vJNEwnP^}E4w6j6cWogC}o(hTAh<O^mVv<ABhp@B#
zx!a4cTfPWmroZ?chT+B248hOM)0ZUbzecq!^Yn`n6i^*N^LX<-{fdpy_UjV8ap#|m
z^{c7k22^kh+v^5Q!MsTo%{rg8P{r59mS@2$$#w@eu1E$0GN2MVw6iS-AKI4x1}_Pz
z9$fL}7-R<K=`HY;=J0_18hPvNDIN!!Tg7}GD6T91A(gkZ))mjuH?NVarPckr!hmsK
z!TXPycWoNCis9Y`Z|_k9{Ry?upVChH5%~Wz7^wG=;(U(==*L1HZ66Nm@_;G&ePO(v
z<P&Di1`3;mj76ZcT9~zBu@AM4!~J<5vix0CbO&9EA-_yd$+#3+xI>$%B;6)cHCkn!
znL8LMyE8=i1Nv54V}B?%(ObA@i`RhZ!ZZ$CBRBLSrtztM4~+RA;Z|tjpA9W&Gx#A0
z{0&mRAA*U$6B4J)U&`_{&~>qxt6-5>cFjm?OP-&7M=U3P=EO6Wvx?{0Np>OAvzm}A
z(CfSDrPqZ!UhL(t+;8J^1D{*Q!q-^)N67RO4ER&*p^pS>no7&{$&j$*c&mKhNLGLQ
z#jBlNZFB4X9qWfbo#>F)Gt3H?{K#GF$<arU<P{EjR;v22NL3%aABxtAYExzd-Xh#U
zk%Z)|SE&nXFDW>ur3Z<J^9Nl8NX?PZxkN1Li-wR29oG|njk(U9$rDW{xXfAc3}=@8
zL9?ru&Vrkx7M+Ytt0Za;#iqPx71SBxm!~4$b4ZPWDepMqj<IlbT+i_%E<zUE2{bR|
z|JAr)l2*gHz7$9JAz1H7XjJbWGwGu{X${rOoR7_|9gHan)vI0(sUm5V@ODkAq4Vmv
zFV!+K6OF177f^RSChbyOnf9L@P}!$c*jL`ID^Y}K>6hBgDj1$Y7&xUG4`tdY(JpIc
zgko{kdkkth$~6Lo6ItmOW!j7Zt=~&4k>6z%qC{bO5ouyA6&H?q{e$TTSeGH>+ORyb
zJZ`KQ2`=!Sfc0n#afw&==6P*FCh?x0h|A;=?RgV%3zZ?#%P}_%TP`+(5e#R>qUlAm
zlXlCT(#{uD@1eb!LA6D)f}vu+3tn9X2mibWdD!kS*Rl>sRB43Cy-H#d6Xyg9m1adE
zb(W^g6o<en!nSfW!k(UtJHwZ|MGnmnbNNqm1RI3wpK=5_MMXeR@Cf6(64y2$I}`bH
zT(Kv$^)|UjZy^e~N!8Z_&2v<D5{Q(#DAg{c>%#e9Uv>lDDWhuODF0m#M70Ax2#Dms
z|C`aH1!K0MhZnBaPW0G?clJ;t!VnHhJOcc-qExXJcjXXk8#O_&8gaE9R~y8Y2UqN7
zX_9dN7TmSsQ$hBCOdEP-+JsL-F~n;VI$^Q4;WhpTZ*a#P?bG~BLpuir4=i^nK#CQ~
zFTD-v__Y>Y7q{tQsHB}W(&y1NlDa6>E_97l!iup*DiLt7Mk*m^1E?7q=|&G9oTsDc
z(Tj-T7<%+Unto_vP;kQ-zDm~vp$BVZJ7{gu^^lf&I74a)t{PA0Ap=pL?tinhq;+8I
z8;DH#(~k~?;$K%Jj2L|=uAWunY7{mwv%s1Ku3r-1dUT11TjT6<K{##{gqNaXn=Z)w
zvDrI-UHTZM@Y&z`D2siwqoNylle3e?iu`U?L0PuD<hJuuUwq;@!>O!x!EV<WrHIw(
zQp6fjijb*3Ro62eVQ{cZQ`F}hb+AKHe4-=ph|dWl-3W`B>Mn9_sWKq!F{e8hRR-jW
z2MW$eY%JF2_2*Ytmd|?^y95v70iTt~>!7%i+Bext#(jW(M)I8Z7JP*4wgML{`xl~+
zz7s`J4A!llRc0dDW6HGO+Sk}e)eiPU>V^jgM@|QQBd1Xf9`*%$Px}W(e8X50PCy94
zq(iCq#rpB%;K+m;cOg1F0(cZ9@WHcO7Vw)rU%gwq6S&^#Lb#0DbJ6q+RFDcJ%$1GY
z{b;78Z&9q%Y2Xi%#H&m$tL{5Nj}Paz7O2V0A_(jCn2UDM&N5^|2W0BcE#3^$5Vix3
z1_Zf&lR2wsLN#QVMq~<Ryom>TF}sj*%A@p{Orv?qDUZ_=cPpoyqBAm`e&FR4g~m*E
zkOxt%C_^gstW1bWmj0y91WjTQr;jQXdS-_g#yJ<AC&W*SD&aYixSf_McHf8OTr@!!
z{twSql_A}Z;$o6!puep0*aAmp9^5&d?DIAmh0LdUGkz|ocv?oM=<_ZlZ=WlqB8X+4
zs{2{gmR@qvXQ_s5#}{4j<blW;6{W_z09BhQq~l<&2${EqN=vDdQw8EWJ3Ij7V?`#^
zhInEX{Q6fxgVTtOC}E(4gyb%lFzP(T@6cM5Ue<BxWdlktn{LoHjuDGQOu<nW!D8Dv
z5=EhB1#+kjKmiY0waBayQ5Q#Apse%9SE(vSBO<Ui(DLHB7MXD`R*IeNX`07ff=44z
zMTtra#W=9h0@WTdXev<E2DPJJl}$v&a2&AJ-llzs${q?dyC1HU9djI?b(|Cle@!;6
zx-x(`bO_PsaY0_oeAenRIS@Pgs0ZAp_}5yF3jQ&t_{+NeTS&ut>O)ZM4<Jw5$LY)C
zB3Ziw+1Znvb6?Ae?z(w;QlbO)I=g!v67QiR!qtXmT!w8lM^osGiuxOO^n^A`za9!B
zRIrLs!&*;IU|OC;rS24pX^$Z|JY$-QKAr7iu<V0ak_flCqGH2at5F`A1*0iZv|c<F
zS3qB+b#cB}q;&%r@==7h=#3?;3u&$>pv3r8x}u;-#}$P-i2jVIC<r0+iUJFvC4Hxm
zzKbF5odVMrO!{ut8Rv?^^P&L6EM-;{zz<hRUr6)Qjyn#*OQG}^@%e(5+2GN%nY|45
zXQ75GVkB+hl<Ff%sIhP`{E86_duOk9UaQ>r<sV`u`Qt-}LgQ5}k;7*u7CH>QQ3S!C
zxlf`Z_`S~))v#Qt!*(C@*v_1h{`ACoGL@y0xJFQ>o&IrBIad`BVR5m6s|+jozVefH
z`moT0z<SZ7qu>BC&t676ahI<Qd~%Na=M7=+^_vhGo=<%q4Vyh4*j^ZSM%5BnX$C+W
zEO{yZP6_`8SzR1tX}wKOK)mY~RcJ1Y8y&b%$$8xsNE0(SYi>#f5Uv_`oDQx53^8(4
z02Av(?+O%!)?%yFqg4Y6?zK)J%zCuhXoCS1{{WzP^-6Lsgc>A&j-W%KHhnl2Tlfnz
ztpXzs+&jHxc+l&-;>6vj7#>Vtn9`D*4l2jF&906S-_gNg<oQsAS`mDtzrSO6^mMPU
zquV#^V3?5gHV2n!9bLWtK=-h3z(Lh8fFd&#@SX4>6;w-gIOSlO8^mVf6u_c#gN#(`
z7^#ql{A8VzUnEi;EEuVBjma`dAt|&ZAXS^I+`{nbRp1oI*-ea3j&}f1MQ#@d*DHdf
z#qO2C(Gs^iI4ZlV5Np@mqIwOuxF)E@NFIQW2Vm6<2y3B@Xx9L&331bA+<`J8@J0b(
zO`<BwaMy(1P1r#k{b&Hjy_l9(6-7{H02oI)@tyzTxQWjEIfPH4fRpt-%B(V9sX(vX
zgB5wcLYhU)x~!LTa98tev(hP5S+vAt;b;vyLpnGUcC8}LZiVhn7z+96%U3(wE*<>V
zaiBSWIu@aj?szy7SupHt7D{O^RKpeomoa@A(?!U)w3zOMM~tJY$V_T<jZhMaT)4*f
zgyCx$!%<=URAcy|f-&4;w=aYEQi1qt3+)z$;xFqc-oPj>=Rxr~s=7sMGyq=*$jAop
z%>ZzY9yI`Oz`>u5xWh?a0p%QlHV7zZ0B;abUIZ9V0XX;KgHDnFbsKpMy!vn8)xW)U
z{F_e$tN7E2mkNd#HK~Lb1}v`ttb$L%c3V(fMyzGTS~|pX`n!DtBmN#ghp31{OZ@#E
zM}0vD)xrxL8Xm+~*hl=npcC1gwKA=-#It(-RfT(qN%5--#kBELj%S4*Ikz$f%Ye32
zfL3Rv-og;=t2&~!F`}(3$pdL3FdcQcYY?5TzD4UbaN7iYF@sw*qSID@8^@y>xU~r&
z!!4@4d{URetxd$F3~p_JFb@JT<9sgnY7yYZCv<JpW`JA8D_1-J>j%eL#sF;m=|P7=
z!EHdf7@iOZ<qL?&j@&QRWsqA2xg`WSb8>Y#Fthq0D${ws^cT<z{5>GO4A@z4V3yC6
zEQ8rnf!VrzDlQDr{(pvOlC28K+tiQunSXVUf4ndAU%sF68|ss6{Dpb`XY~tx1{DRD
zg`!xVUoa5A*JmEl>T8z9h%0IfAJOugN;%_MeF?=F?+gOyLM6Q0iMpJjt&aQ{Lr=jq
zDRk(3CGDIct%}FSkYC$f_>dL_ik#7`GX2JAC-K7#g$kIRUe6iIDu-?iHQ8SHP*zEs
zoZ+leAjWX3kr63WGE0{_XFMyf)EMtSdkY^guhrAXEQZg^rx={n34?KaknjE%)eq-n

literal 0
HcmV?d00001

diff --git a/openbis-ipad/source/java/ch/systemsx/cisd/openbis/ipad/v2/server/ClientPreferencesRequestHandler.java b/openbis-ipad/source/java/ch/systemsx/cisd/openbis/ipad/v2/server/ClientPreferencesRequestHandler.java
index c42b5f4f390..fb846edc74f 100644
--- a/openbis-ipad/source/java/ch/systemsx/cisd/openbis/ipad/v2/server/ClientPreferencesRequestHandler.java
+++ b/openbis-ipad/source/java/ch/systemsx/cisd/openbis/ipad/v2/server/ClientPreferencesRequestHandler.java
@@ -21,6 +21,7 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
+import ch.systemsx.cisd.openbis.dss.generic.shared.api.internal.v2.ISearchService;
 import ch.systemsx.cisd.openbis.generic.shared.managed_property.api.IRowBuilderAdaptor;
 import ch.systemsx.cisd.openbis.generic.shared.managed_property.api.ISimpleTableModelBuilderAdaptor;
 
@@ -48,11 +49,10 @@ public class ClientPreferencesRequestHandler implements IRequestHandler
      * 
      * @param parameters The request parameters.
      * @param builder A table model builder.
-     * @param searchService The service that supports searching for openBIS entities.
-     * @param optionalHeaders Non-required headers that are returned by this request.
+     * @param searchService Ignored.
      */
     protected ClientPreferencesRequestHandler(Map<String, Object> parameters,
-            ISimpleTableModelBuilderAdaptor builder)
+            ISimpleTableModelBuilderAdaptor builder, ISearchService searchService)
     {
         this.parameters = parameters;
         this.builder = builder;
-- 
GitLab