Commit e2f7b3fb authored by Boris Kocherov's avatar Boris Kocherov

generate action and role id with prefix ( 'action_REFERENCE_%d' and 'role_%d' )

change of copy, move, create object code ( now constructor of object can change generated id)
transparently migrate of old id
regenerate id if reference is changed
parent 02a07723
...@@ -6065,20 +6065,17 @@ Business Template is a set of definitions, such as skins, portal types and categ ...@@ -6065,20 +6065,17 @@ Business Template is a set of definitions, such as skins, portal types and categ
bt_portal_types_id_list = list(self.getTemplatePortalTypeIdList()) bt_portal_types_id_list = list(self.getTemplatePortalTypeIdList())
bt_portal_type_roles_list = list(self.getTemplatePortalTypeRoleList()) bt_portal_type_roles_list = list(self.getTemplatePortalTypeRoleList())
bt_wf_chain_list = list(self.getTemplatePortalTypeWorkflowChainList()) bt_wf_chain_list = list(self.getTemplatePortalTypeWorkflowChainList())
bt_path_list = list(self.getTemplatePathList())
for id in bt_portal_types_id_list: for id in bt_portal_types_id_list:
portal_type = ttool.getTypeInfo(id) portal_type = ttool.getTypeInfo(id)
if portal_type is None: if portal_type is None:
continue continue
if portal_type.getRoleInformationList():
if id not in bt_portal_type_roles_list:
bt_portal_type_roles_list.append(id)
allowed_content_type_list = [] allowed_content_type_list = []
hidden_content_type_list = [] hidden_content_type_list = []
property_sheet_list = [] property_sheet_list = []
base_category_list = [] base_category_list = []
action_list = []
if hasattr(portal_type, 'allowed_content_types'): if hasattr(portal_type, 'allowed_content_types'):
allowed_content_type_list = portal_type.allowed_content_types allowed_content_type_list = portal_type.allowed_content_types
if hasattr(portal_type, 'hidden_content_type_list'): if hasattr(portal_type, 'hidden_content_type_list'):
...@@ -6087,8 +6084,6 @@ Business Template is a set of definitions, such as skins, portal types and categ ...@@ -6087,8 +6084,6 @@ Business Template is a set of definitions, such as skins, portal types and categ
property_sheet_list = portal_type.property_sheet_list property_sheet_list = portal_type.property_sheet_list
if hasattr(portal_type, 'base_category_list'): if hasattr(portal_type, 'base_category_list'):
base_category_list = portal_type.base_category_list base_category_list = portal_type.base_category_list
for action in portal_type.getActionInformationList():
action_list.append(action.getReference())
for a_id in allowed_content_type_list: for a_id in allowed_content_type_list:
allowed_id = id+' | '+a_id allowed_id = id+' | '+a_id
...@@ -6110,10 +6105,29 @@ Business Template is a set of definitions, such as skins, portal types and categ ...@@ -6110,10 +6105,29 @@ Business Template is a set of definitions, such as skins, portal types and categ
if base_cat_id not in bt_base_category_list: if base_cat_id not in bt_base_category_list:
bt_base_category_list.append(base_cat_id) bt_base_category_list.append(base_cat_id)
for act_id in action_list: for action in portal_type.getActionInformationList():
action_id = id+' | '+act_id act_id = action.getId()
if action_id not in bt_action_list: act_ref = action.getReference()
bt_action_list.append(action_id) try:
bt_action_list.remove(id + ' | ' + act_id)
except ValueError:
pass
try:
bt_action_list.remove(id + ' | ' + act_ref)
except ValueError:
pass
action_path = "portal_types/" + id + "/" + act_id
if action_path not in bt_path_list:
bt_path_list.append(action_path)
for role in portal_type.getRoleInformationList():
role_path = "portal_types/" + id + "/" + role.getId()
if role_path not in bt_path_list:
bt_path_list.append(role_path)
try:
bt_portal_type_roles_list.remove(id)
except ValueError:
pass
for workflow_id in [chain for chain in wtool.getChainFor(id) for workflow_id in [chain for chain in wtool.getChainFor(id)
if chain != '(Default)']: if chain != '(Default)']:
...@@ -6127,6 +6141,7 @@ Business Template is a set of definitions, such as skins, portal types and categ ...@@ -6127,6 +6141,7 @@ Business Template is a set of definitions, such as skins, portal types and categ
bt_base_category_list.sort() bt_base_category_list.sort()
bt_action_list.sort() bt_action_list.sort()
bt_wf_chain_list.sort() bt_wf_chain_list.sort()
bt_path_list.sort()
self.setTemplatePortalTypeWorkflowChainList(bt_wf_chain_list) self.setTemplatePortalTypeWorkflowChainList(bt_wf_chain_list)
self.setTemplatePortalTypeRoleList(bt_portal_type_roles_list) self.setTemplatePortalTypeRoleList(bt_portal_type_roles_list)
...@@ -6135,6 +6150,7 @@ Business Template is a set of definitions, such as skins, portal types and categ ...@@ -6135,6 +6150,7 @@ Business Template is a set of definitions, such as skins, portal types and categ
self.setTemplatePortalTypePropertySheetList(bt_property_sheet_list) self.setTemplatePortalTypePropertySheetList(bt_property_sheet_list)
self.setTemplatePortalTypeBaseCategoryList(bt_base_category_list) self.setTemplatePortalTypeBaseCategoryList(bt_base_category_list)
self.setTemplateActionPathList(bt_action_list) self.setTemplateActionPathList(bt_action_list)
self.setTemplatePathList(bt_path_list)
security.declareProtected(Permissions.AccessContentsInformation, security.declareProtected(Permissions.AccessContentsInformation,
......
...@@ -561,8 +561,9 @@ class CopyContainer: ...@@ -561,8 +561,9 @@ class CopyContainer:
ob=ob._getCopy(self) ob=ob._getCopy(self)
orig_id=ob.getId() orig_id=ob.getId()
id=self._get_id(ob.getId()) id=self._get_id(ob.getId())
result.append({'id':orig_id, 'new_id':id})
ob._setId(id) ob._setId(id)
id = ob.id
result.append({'id':orig_id, 'new_id':id})
if not is_indexable: if not is_indexable:
ob._setNonIndexable() ob._setNonIndexable()
self._setObject(id, ob) self._setObject(id, ob)
...@@ -597,9 +598,10 @@ class CopyContainer: ...@@ -597,9 +598,10 @@ class CopyContainer:
ob = aq_base(ob) ob = aq_base(ob)
orig_id=id orig_id=id
id=self._get_id(id) id=self._get_id(id)
result.append({'id':orig_id, 'new_id':id })
ob._setId(id) ob._setId(id)
id = ob.id
result.append({'id':orig_id, 'new_id':id })
if not is_indexable: if not is_indexable:
ob._setNonIndexable() ob._setNonIndexable()
self._setObject(id, ob, set_owner=0) self._setObject(id, ob, set_owner=0)
......
...@@ -35,9 +35,10 @@ from Products.CMFCore.Expression import Expression ...@@ -35,9 +35,10 @@ from Products.CMFCore.Expression import Expression
from Products.ERP5Type import interfaces, Permissions, PropertySheet from Products.ERP5Type import interfaces, Permissions, PropertySheet
from Products.ERP5Type.Permissions import AccessContentsInformation from Products.ERP5Type.Permissions import AccessContentsInformation
from Products.ERP5Type.XMLObject import XMLObject from Products.ERP5Type.XMLObject import XMLObject
from Products.ERP5Type.gen_id_from_reference import GenerateIdFromReferenceMixin
class ActionInformation(XMLObject): class ActionInformation(GenerateIdFromReferenceMixin('action'), XMLObject):
""" """
ActionInformation is an ERP5 type which will eventually replace respective ActionInformation from CMF. ActionInformation is an ERP5 type which will eventually replace respective ActionInformation from CMF.
""" """
......
...@@ -163,7 +163,7 @@ class FolderMixIn(ExtensionClass.Base): ...@@ -163,7 +163,7 @@ class FolderMixIn(ExtensionClass.Base):
temp_object=temp_object or temp_container, temp_object=temp_object or temp_container,
**kw) **kw)
if temp_container: if temp_container:
container._setObject(new_id, new_instance.aq_base) container._setObject(new_instance.id, new_instance.aq_base)
return new_instance return new_instance
security.declareProtected( security.declareProtected(
......
...@@ -40,9 +40,10 @@ from Products.ERP5Type.ERP5Type \ ...@@ -40,9 +40,10 @@ from Products.ERP5Type.ERP5Type \
import ERP5TYPE_SECURITY_GROUP_ID_GENERATION_SCRIPT import ERP5TYPE_SECURITY_GROUP_ID_GENERATION_SCRIPT
from Products.ERP5Type.Permissions import AccessContentsInformation from Products.ERP5Type.Permissions import AccessContentsInformation
from Products.ERP5Type.XMLObject import XMLObject from Products.ERP5Type.XMLObject import XMLObject
from Products.ERP5Type.gen_id_from_reference import GenerateIdFromReferenceMixin
class RoleInformation(XMLObject): class RoleInformation(GenerateIdFromReferenceMixin('role'), XMLObject):
""" Represent a role definition. """ Represent a role definition.
Roles definitions defines local roles on ERP5Type documents. They are Roles definitions defines local roles on ERP5Type documents. They are
......
...@@ -401,7 +401,7 @@ class ERP5TypeInformation(XMLObject, ...@@ -401,7 +401,7 @@ class ERP5TypeInformation(XMLObject,
ob.setDefaultReindexParameterDict(reindex_kw) ob.setDefaultReindexParameterDict(reindex_kw)
if is_indexable is not None: if is_indexable is not None:
base_ob.isIndexable = is_indexable base_ob.isIndexable = is_indexable
container._setObject(id, base_ob) container._setObject(base_ob.id, base_ob)
# if no activity tool, the object has already an uid # if no activity tool, the object has already an uid
if getattr(base_ob, 'uid', None) is None: if getattr(base_ob, 'uid', None) is None:
ob.uid = portal.portal_catalog.newUid() ob.uid = portal.portal_catalog.newUid()
......
# -*- coding: utf-8 -*-
##############################################################################
# Copyright (c) 2010 Nexedi SA and Contributors. All Rights Reserved.
# Julien Muchembled <jm@nexedi.com>,
# Boris Kocherov <bk@raskon.ru>
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsibility of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# guarantees and support are strongly advised to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
##############################################################################
from Products.CMFActivity.Errors import ActivityPendingError
from Products.ERP5Type.CopySupport import CopyContainer
from zLOG import LOG, WARNING
def GenerateIdFromReferenceMixin(prefix):
prefix_ = prefix + "_"
class GenerateIdAsReferenceMixin(object):
def __init__(self, ob_id):
if not ob_id.startswith(prefix_):
ob_id = prefix_ + ob_id
self.id = ob_id
def cb_isMoveable(self):
return self.cb_userHasCopyOrMovePermission()
def __migrate(self):
self._setIdByRefernce()
def _genIdByRefernce(self, old_id=None, reference=None):
if not old_id:
old_id = self.id
if not reference:
reference = getattr(self, 'reference', None)
if reference:
base_id = new_id = "_".join((prefix, reference))
else:
base_id = new_id = prefix
if old_id != new_id and not old_id.startswith(new_id + "_"):
parent = self.getParentValue()
if not reference:
new_id = base_id + "_" + old_id
int_ob_id = 0
while 0 <= int_ob_id <= 100:
if new_id not in parent:
break
int_ob_id += 1
new_id = base_id + "_%d" % (int_ob_id,)
if new_id in parent:
int_ob_id = parent.generateNewId()
new_id = base_id + "_%d" % (int_ob_id,)
if new_id in parent:
LOG("GenerateIdFromReferenceMixin", WARNING, "Skipping migration id of %r in %r"
" %s, due to ID conflict" % (new_id, parent.getId(), parent.getPortalType()))
else:
return new_id
return None
def _setIdByRefernce(self, old_id=None, reference=None):
new_id = self._genIdByRefernce(old_id, reference)
if new_id:
try:
self.setId(new_id)
except ActivityPendingError:
parent = self.getParentValue()
LOG("GenerateIdFromReferenceMixin", WARNING, "Skipping update id of %r in %r"
" %s, due to pending activities" % (old_id, parent.getId(), parent.getPortalType()))
def getId(self, default=None):
"""
It's only for migration.
it' can be removed if all instances updating
"""
ob_id = self._baseGetId(default)
migration = getattr(self, '_v_idmigration', False)
if not migration and not ob_id.startswith(prefix_):
self._v_idmigration = True
new_id = self._genIdByRefernce(old_id=ob_id)
try:
self.setId(new_id)
except ActivityPendingError:
parent = self.getParentValue()
LOG("GenerateIdFromReferenceMixin", WARNING, "Skipping migration of %r in %r"
" %s, due to pending activities" % (old_id, parent.getId(), parent.getPortalType()))
return new_id
return ob_id
def _setId(self, ob_id):
"""
update id for moved and copied objects
"""
if not ob_id.startswith(prefix_):
ob_id = prefix_ + ob_id
return CopyContainer._setId(self, ob_id)
def _setReference(self, value):
"""
update id if reference change
"""
self._setIdByRefernce(reference=value)
self._baseSetReference(value)
return GenerateIdAsReferenceMixin
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