Commit 31145217 authored by Jérome Perrin's avatar Jérome Perrin

refactor CatalogMethodTemplateItem to dynamically record *all* methods

properties by checking catalog properties.
remove bogus '_check_catalog' method that breaks testBusinessTemplate.
fix resutl_table_list typo.



git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@6978 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent 31c9dc60
...@@ -77,12 +77,16 @@ from urllib import pathname2url, url2pathname ...@@ -77,12 +77,16 @@ from urllib import pathname2url, url2pathname
from difflib import unified_diff from difflib import unified_diff
# those attributes from CatalogMethodTemplateItem are kept for
# backward compatibility
catalog_method_list = ('_is_catalog_list_method_archive', catalog_method_list = ('_is_catalog_list_method_archive',
'_is_uncatalog_method_archive', '_is_uncatalog_method_archive',
'_is_clear_method_archive', '_is_filtered_archive') '_is_clear_method_archive',
'_is_filtered_archive',)
catalog_method_filter_list = ('_filter_expression_archive', '_filter_expression_instance_archive', catalog_method_filter_list = ('_filter_expression_archive',
'_filter_type_archive') '_filter_expression_instance_archive',
'_filter_type_archive',)
def removeAll(entry): def removeAll(entry):
...@@ -1408,22 +1412,44 @@ class PortalTypeBaseCategoryTemplateItem(PortalTypeAllowedContentTypeTemplateIte ...@@ -1408,22 +1412,44 @@ class PortalTypeBaseCategoryTemplateItem(PortalTypeAllowedContentTypeTemplateIte
class_property = 'base_category_list' class_property = 'base_category_list'
class CatalogMethodTemplateItem(ObjectTemplateItem): class CatalogMethodTemplateItem(ObjectTemplateItem):
"""Template Item for catalog methods.
This template item stores catalog method and install them in the
default catalog.
The use Catalog makes for methods is saved as well and recreated on
installation.
"""
def __init__(self, id_list, tool_id='portal_catalog', **kw): def __init__(self, id_list, tool_id='portal_catalog', **kw):
ObjectTemplateItem.__init__(self, id_list, tool_id=tool_id, **kw) ObjectTemplateItem.__init__(self, id_list, tool_id=tool_id, **kw)
self._is_catalog_list_method_archive = PersistentMapping() # a mapping to store properties of methods.
self._is_uncatalog_method_archive = PersistentMapping() # the mapping contains an entry for each method, and this entry is
self._is_clear_method_archive = PersistentMapping() # another mapping having the id of the catalog property as key and a
# boolean value to say wether the method is part of this catalog
# configuration property.
self._method_properties = PersistentMapping()
self._is_filtered_archive = PersistentMapping() self._is_filtered_archive = PersistentMapping()
self._filter_expression_archive = PersistentMapping() self._filter_expression_archive = PersistentMapping()
self._filter_expression_instance_archive = PersistentMapping() self._filter_expression_instance_archive = PersistentMapping()
self._filter_type_archive = PersistentMapping() self._filter_type_archive = PersistentMapping()
def _extractMethodProperties(self, catalog, method_id):
"""Extracts properties for a given method in the catalog.
Returns a mapping of property name -> boolean """
method_properties = PersistentMapping()
for prop in catalog._properties:
if prop.get('select_variable') == 'getCatalogMethodIds':
if prop['type'] == 'selection' and \
getattr(catalog, prop['id']) == method_id:
method_properties[prop['id']] = 1
elif prop['type'] == 'multiple selection' and \
method_id in getattr(catalog, prop['id']):
method_properties[prop['id']] = 1
return method_properties
def build(self, context, **kw): def build(self, context, **kw):
ObjectTemplateItem.build(self, context, **kw) ObjectTemplateItem.build(self, context, **kw)
self._check_catalog(context)
def _check_catalog(self, context):
try: try:
catalog = context.portal_catalog.getSQLCatalog() catalog = context.portal_catalog.getSQLCatalog()
except KeyError: except KeyError:
...@@ -1431,17 +1457,25 @@ class CatalogMethodTemplateItem(ObjectTemplateItem): ...@@ -1431,17 +1457,25 @@ class CatalogMethodTemplateItem(ObjectTemplateItem):
if catalog is None: if catalog is None:
LOG('BusinessTemplate build', 0, 'catalog not found') LOG('BusinessTemplate build', 0, 'catalog not found')
return return
# upgrade old
if not hasattr(self, '_method_properties'):
self._method_properties = PersistentMapping()
for obj in self._objects.values(): for obj in self._objects.values():
method_id = obj.id method_id = obj.id
self._is_catalog_list_method_archive[method_id] = method_id in catalog.sql_catalog_object_list self._method_properties[method_id] = self._extractMethodProperties(
self._is_uncatalog_method_archive[method_id] = method_id in catalog.sql_uncatalog_object catalog, method_id)
self._is_clear_method_archive[method_id] = method_id in catalog.sql_clear_catalog
self._is_filtered_archive[method_id] = 0 self._is_filtered_archive[method_id] = 0
if catalog.filter_dict.has_key(method_id): if catalog.filter_dict.has_key(method_id):
self._is_filtered_archive[method_id] = catalog.filter_dict[method_id]['filtered'] self._is_filtered_archive[method_id] = \
self._filter_expression_archive[method_id] = catalog.filter_dict[method_id]['expression'] catalog.filter_dict[method_id]['filtered']
self._filter_expression_instance_archive[method_id] = catalog.filter_dict[method_id]['expression_instance'] self._filter_expression_archive[method_id] = \
self._filter_type_archive[method_id] = catalog.filter_dict[method_id]['type'] catalog.filter_dict[method_id]['expression']
self._filter_expression_instance_archive[method_id] = \
catalog.filter_dict[method_id]['expression_instance']
self._filter_type_archive[method_id] = \
catalog.filter_dict[method_id]['type']
def export(self, context, bta, **kw): def export(self, context, bta, **kw):
if len(self._objects.keys()) == 0: if len(self._objects.keys()) == 0:
...@@ -1464,17 +1498,19 @@ class CatalogMethodTemplateItem(ObjectTemplateItem): ...@@ -1464,17 +1498,19 @@ class CatalogMethodTemplateItem(ObjectTemplateItem):
f = open(object_path, 'wt') f = open(object_path, 'wt')
xml_data = '<catalog_method>' xml_data = '<catalog_method>'
for method in catalog_method_list:
value = getattr(self, method, 0)[method_id] for method_property, value in self._method_properties[method_id].items():
xml_data += os.linesep+' <item key="%s" type="int">' %(method,) xml_data += os.linesep+' <item key="%s" type="int">' %(method_property,)
xml_data += os.linesep+' <value>%s</value>' %(str(int(value))) xml_data += os.linesep+' <value>%s</value>' %(value,)
xml_data += os.linesep+' </item>' xml_data += os.linesep+' </item>'
if catalog.filter_dict.has_key(method_id): if catalog.filter_dict.has_key(method_id):
xml_data += os.linesep+' <item key="_is_filtered_archive" type="int">'
xml_data += os.linesep+' <value>1</value>'
xml_data += os.linesep+' </item>'
for method in catalog_method_filter_list: for method in catalog_method_filter_list:
value = getattr(self, method, '')[method_id] value = getattr(self, method, '')[method_id]
if method == '_filter_expression_instance_archive': if method != '_filter_expression_instance_archive':
pass
else:
if type(value) in (type(''), type(u'')): if type(value) in (type(''), type(u'')):
xml_data += os.linesep+' <item key="%s" type="str">' %(method,) xml_data += os.linesep+' <item key="%s" type="str">' %(method,)
xml_data += os.linesep+' <value>%s</value>' %(str(value)) xml_data += os.linesep+' <value>%s</value>' %(str(value))
...@@ -1485,7 +1521,7 @@ class CatalogMethodTemplateItem(ObjectTemplateItem): ...@@ -1485,7 +1521,7 @@ class CatalogMethodTemplateItem(ObjectTemplateItem):
xml_data += os.linesep+' <value>%s</value>' %(str(item)) xml_data += os.linesep+' <value>%s</value>' %(str(item))
xml_data += os.linesep+' </item>' xml_data += os.linesep+' </item>'
xml_data += os.linesep+'</catalog_method>' xml_data += os.linesep+'</catalog_method>'
f.write(str(xml_data)) f.write(xml_data)
f.close() f.close()
# Function to generate XML Code Manually # Function to generate XML Code Manually
...@@ -1500,7 +1536,6 @@ class CatalogMethodTemplateItem(ObjectTemplateItem): ...@@ -1500,7 +1536,6 @@ class CatalogMethodTemplateItem(ObjectTemplateItem):
def install(self, context, trashbin, **kw): def install(self, context, trashbin, **kw):
ObjectTemplateItem.install(self, context, trashbin, **kw) ObjectTemplateItem.install(self, context, trashbin, **kw)
self._check_catalog(context)
try: try:
catalog = context.portal_catalog.getSQLCatalog() catalog = context.portal_catalog.getSQLCatalog()
except KeyError: except KeyError:
...@@ -1542,14 +1577,49 @@ class CatalogMethodTemplateItem(ObjectTemplateItem): ...@@ -1542,14 +1577,49 @@ class CatalogMethodTemplateItem(ObjectTemplateItem):
for obj in values: for obj in values:
method_id = obj.id method_id = obj.id
is_catalog_list_method = int(self._is_catalog_list_method_archive[method_id]) # Restore catalog properties for methods
is_uncatalog_method = int(self._is_uncatalog_method_archive[method_id]) if hasattr(self, '_method_properties'):
is_clear_method = int(self._is_clear_method_archive[method_id]) for key in self._method_properties.get(method_id, {}).keys():
is_filtered = int(self._is_filtered_archive[method_id]) old_value = getattr(catalog, key, None)
if isinstance(old_value, str):
setattr(catalog, key, method_id)
elif isinstance(old_value, list) or isinstance(old_value, tuple):
if method_id not in old_value:
new_value = list(old_value) + [method_id]
new_value.sort()
setattr(catalog, key, tuple(new_value))
# Restore filter
if self._is_filtered_archive.get(method_id, 0):
expression = self._filter_expression_archive[method_id]
if context.getTemplateFormatVersion() == 1:
expr_instance = Expression(expression)
else:
expr_instance = self._filter_expression_instance_archive[method_id]
filter_type = self._filter_type_archive[method_id]
catalog.filter_dict[method_id] = PersistentMapping()
catalog.filter_dict[method_id]['filtered'] = 1
catalog.filter_dict[method_id]['expression'] = expression
catalog.filter_dict[method_id]['expression_instance'] = expr_instance
catalog.filter_dict[method_id]['type'] = filter_type
elif method_id in catalog.filter_dict.keys():
catalog.filter_dict[method_id]['filtered'] = 0
# backward compatibility
if hasattr(self, '_is_catalog_list_method_archive'):
LOG("BusinessTemplate.CatalogMethodTemplateItem", 0,
"installing old style catalog method configuration")
is_catalog_list_method = int(
self._is_catalog_list_method_archive[method_id])
is_uncatalog_method = int(
self._is_uncatalog_method_archive[method_id])
is_clear_method = int(
self._is_clear_method_archive[method_id])
if is_catalog_list_method and method_id not in sql_catalog_object_list: if is_catalog_list_method and method_id not in sql_catalog_object_list:
sql_catalog_object_list.append(method_id) sql_catalog_object_list.append(method_id)
elif not is_catalog_list_method and method_id in sql_catalog_object_list: elif not is_catalog_list_method and\
method_id in sql_catalog_object_list:
sql_catalog_object_list.remove(method_id) sql_catalog_object_list.remove(method_id)
if is_uncatalog_method and method_id not in sql_uncatalog_object: if is_uncatalog_method and method_id not in sql_uncatalog_object:
...@@ -1562,21 +1632,6 @@ class CatalogMethodTemplateItem(ObjectTemplateItem): ...@@ -1562,21 +1632,6 @@ class CatalogMethodTemplateItem(ObjectTemplateItem):
elif not is_clear_method and method_id in sql_clear_catalog: elif not is_clear_method and method_id in sql_clear_catalog:
sql_clear_catalog.remove(method_id) sql_clear_catalog.remove(method_id)
if is_filtered:
expression = self._filter_expression_archive[method_id]
if context.getTemplateFormatVersion() == 1:
expr_instance = Expression(expression)
else:
expr_instance = self._filter_expression_instance_archive[method_id]
filter_type = self._filter_type_archive[method_id]
catalog.filter_dict[method_id] = PersistentMapping()
catalog.filter_dict[method_id]['filtered'] = 1
catalog.filter_dict[method_id]['expression'] = expression
catalog.filter_dict[method_id]['expression_instance'] = expr_instance
catalog.filter_dict[method_id]['type'] = filter_type
elif method_id in catalog.filter_dict.keys():
catalog.filter_dict[method_id]['filtered'] = 0
sql_catalog_object_list.sort() sql_catalog_object_list.sort()
catalog.sql_catalog_object_list = tuple(sql_catalog_object_list) catalog.sql_catalog_object_list = tuple(sql_catalog_object_list)
sql_uncatalog_object.sort() sql_uncatalog_object.sort()
...@@ -1605,25 +1660,22 @@ class CatalogMethodTemplateItem(ObjectTemplateItem): ...@@ -1605,25 +1660,22 @@ class CatalogMethodTemplateItem(ObjectTemplateItem):
value = self._archive[object_path] value = self._archive[object_path]
if value is not None: if value is not None:
values.append(value) values.append(value)
# Make copies of attributes of the default catalog of portal_catalog.
sql_catalog_object_list = list(catalog.sql_catalog_object_list)
sql_uncatalog_object = list(catalog.sql_uncatalog_object)
sql_clear_catalog = list(catalog.sql_clear_catalog)
for obj in values: for obj in values:
method_id = obj.id method_id = obj.id
if method_id in sql_catalog_object_list: # remove method references in portal_catalog
sql_catalog_object_list.remove(method_id) for catalog_prop in catalog._properties:
if method_id in sql_uncatalog_object: if catalog_prop.get('select_variable') == 'getCatalogMethodIds'\
sql_uncatalog_object.remove(method_id) and catalog_prop['type'] == 'multiple selection':
if method_id in sql_clear_catalog: old_value = getattr(catalog, catalog_prop['id'], ())
sql_clear_catalog.remove(method_id) if method_id in old_value:
new_value = list(old_value)
new_value.remove(method_id)
setattr(catalog, catalog_prop['id'], new_value)
if catalog.filter_dict.has_key(method_id): if catalog.filter_dict.has_key(method_id):
del catalog.filter_dict[method_id] del catalog.filter_dict[method_id]
catalog.sql_catalog_object_list = tuple(sql_catalog_object_list)
catalog.sql_uncatalog_object = tuple(sql_uncatalog_object)
catalog.sql_clear_catalog = tuple(sql_clear_catalog)
# uninstall objects # uninstall objects
ObjectTemplateItem.uninstall(self, context, **kw) ObjectTemplateItem.uninstall(self, context, **kw)
...@@ -1637,7 +1689,7 @@ class CatalogMethodTemplateItem(ObjectTemplateItem): ...@@ -1637,7 +1689,7 @@ class CatalogMethodTemplateItem(ObjectTemplateItem):
connection=obj._p_jar connection=obj._p_jar
obj = connection.importFile(file, customImporters=customImporters) obj = connection.importFile(file, customImporters=customImporters)
self._objects[file_name[:-4]] = obj self._objects[file_name[:-4]] = obj
elif '.catalog_keys' in file_name: else:
# recreate data mapping specific to catalog method # recreate data mapping specific to catalog method
path, name = os.path.split(file_name) path, name = os.path.split(file_name)
id = string.split(name, '.')[0] id = string.split(name, '.')[0]
...@@ -1661,8 +1713,11 @@ class CatalogMethodTemplateItem(ObjectTemplateItem): ...@@ -1661,8 +1713,11 @@ class CatalogMethodTemplateItem(ObjectTemplateItem):
LOG('BusinessTemplate import CatalogMethod, type unknown', 0, key_type) LOG('BusinessTemplate import CatalogMethod, type unknown', 0, key_type)
continue continue
if key in catalog_method_list or key in catalog_method_filter_list: if key in catalog_method_list or key in catalog_method_filter_list:
dict = getattr(self, key) dict = getattr(self, key, {})
dict[id] = value dict[id] = value
else:
# new style key
self._method_properties.setdefault(id, PersistentMapping())[key] = 1
class ActionTemplateItem(ObjectTemplateItem): class ActionTemplateItem(ObjectTemplateItem):
...@@ -2625,7 +2680,7 @@ class CatalogResultTableTemplateItem(BaseTemplateItem): ...@@ -2625,7 +2680,7 @@ class CatalogResultTableTemplateItem(BaseTemplateItem):
else: else:
raise NotFound, 'key %r not found in catalog' %(key,) raise NotFound, 'key %r not found in catalog' %(key,)
if len(key_list) > 0: if len(key_list) > 0:
self._objects[self.__class__.__name__+os.sep+'resutl_table_list'] = key_list self._objects[self.__class__.__name__+os.sep+'result_table_list'] = key_list
def _importFile(self, file_name, file): def _importFile(self, file_name, file):
list = [] list = []
...@@ -2666,7 +2721,7 @@ class CatalogResultTableTemplateItem(BaseTemplateItem): ...@@ -2666,7 +2721,7 @@ class CatalogResultTableTemplateItem(BaseTemplateItem):
for key in keys: for key in keys:
if key not in sql_search_tables: if key not in sql_search_tables:
sql_search_tables.append(key) sql_search_tables.append(key)
catalog.sql_search_tables = sql_search_tables catalog.sql_search_tables = list(sql_search_tables)
def uninstall(self, context, **kw): def uninstall(self, context, **kw):
try: try:
...@@ -3791,6 +3846,20 @@ Business Template is a set of definitions, such as skins, portal types and categ ...@@ -3791,6 +3846,20 @@ Business Template is a set of definitions, such as skins, portal types and categ
self.portal_templates.updateLocalConfiguration(self, **kw) self.portal_templates.updateLocalConfiguration(self, **kw)
local_configuration = self.portal_templates.getLocalConfiguration(self) local_configuration = self.portal_templates.getLocalConfiguration(self)
# always created a trash bin because we may to save object already present
# but not in a previous business templates apart at creation of a new site
if trash_tool is not None and (len(object_to_update) > 0 or len(self.portal_templates.objectIds()) > 1):
trashbin = trash_tool.newTrashBin(self.getTitle(), self)
else:
trashbin = None
# Install everything
if len(object_to_update) > 0 or force:
for item_name in self._item_name_list:
item = getattr(self, item_name, None)
if item is not None:
item.install(local_configuration, force=force, object_to_update=object_to_update, trashbin=trashbin)
# update catalog if necessary # update catalog if necessary
update_catalog=0 update_catalog=0
catalog_method = getattr(self, '_catalog_method_item', None) catalog_method = getattr(self, '_catalog_method_item', None)
...@@ -3814,20 +3883,6 @@ Business Template is a set of definitions, such as skins, portal types and categ ...@@ -3814,20 +3883,6 @@ Business Template is a set of definitions, such as skins, portal types and categ
LOG('Business Template', 0, 'Updating SQL Catalog') LOG('Business Template', 0, 'Updating SQL Catalog')
catalog.manage_catalogClear() catalog.manage_catalogClear()
# always created a trash bin because we may to save object already present
# but not in a previous business templates apart at creation of a new site
if trash_tool is not None and (len(object_to_update) > 0 or len(self.portal_templates.objectIds()) > 1):
trashbin = trash_tool.newTrashBin(self.getTitle(), self)
else:
trashbin = None
# Install everything
if len(object_to_update) > 0 or force:
for item_name in self._item_name_list:
item = getattr(self, item_name, None)
if item is not None:
item.install(local_configuration, force=force, object_to_update=object_to_update, trashbin=trashbin)
# get objects to remove # get objects to remove
# do remove after because we may need backup object from installation # do remove after because we may need backup object from installation
remove_object_dict = {} remove_object_dict = {}
...@@ -4263,7 +4318,6 @@ Business Template is a set of definitions, such as skins, portal types and categ ...@@ -4263,7 +4318,6 @@ Business Template is a set of definitions, such as skins, portal types and categ
'CatalogRequestKey' : '_catalog_request_key_item', 'CatalogRequestKey' : '_catalog_request_key_item',
'CatalogMultivalueKey' : '_catalog_multivalue_key_item', 'CatalogMultivalueKey' : '_catalog_multivalue_key_item',
'CatalogTopicKey' : '_catalog_topic_key_item', 'CatalogTopicKey' : '_catalog_topic_key_item',
'CatalogMethod' : '_catalog_method_item',
} }
object_id = REQUEST.object_id object_id = REQUEST.object_id
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment