Commit 0b0b5fa5 authored by Boris Kocherov's avatar Boris Kocherov Committed by Romain Courteaud

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 40220b0b
......@@ -5816,20 +5816,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_type_roles_list = list(self.getTemplatePortalTypeRoleList())
bt_wf_chain_list = list(self.getTemplatePortalTypeWorkflowChainList())
bt_path_list = list(self.getTemplatePathList())
for id in bt_portal_types_id_list:
portal_type = ttool.getTypeInfo(id)
if portal_type is None:
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 = []
hidden_content_type_list = []
property_sheet_list = []
base_category_list = []
action_list = []
if hasattr(portal_type, 'allowed_content_types'):
allowed_content_type_list = portal_type.allowed_content_types
if hasattr(portal_type, 'hidden_content_type_list'):
......@@ -5838,8 +5835,6 @@ Business Template is a set of definitions, such as skins, portal types and categ
property_sheet_list = portal_type.property_sheet_list
if hasattr(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:
allowed_id = id+' | '+a_id
......@@ -5861,10 +5856,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:
bt_base_category_list.append(base_cat_id)
for act_id in action_list:
action_id = id+' | '+act_id
if action_id not in bt_action_list:
bt_action_list.append(action_id)
for action in portal_type.getActionInformationList():
act_id = action.getId()
act_ref = action.getReference()
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)
if chain != '(Default)']:
......@@ -5878,6 +5892,7 @@ Business Template is a set of definitions, such as skins, portal types and categ
bt_base_category_list.sort()
bt_action_list.sort()
bt_wf_chain_list.sort()
bt_path_list.sort()
self.setTemplatePortalTypeWorkflowChainList(bt_wf_chain_list)
self.setTemplatePortalTypeRoleList(bt_portal_type_roles_list)
......@@ -5886,6 +5901,7 @@ Business Template is a set of definitions, such as skins, portal types and categ
self.setTemplatePortalTypePropertySheetList(bt_property_sheet_list)
self.setTemplatePortalTypeBaseCategoryList(bt_base_category_list)
self.setTemplateActionPathList(bt_action_list)
self.setTemplatePathList(bt_path_list)
def guessPortalTypes(self, **kw):
......
......@@ -580,8 +580,9 @@ class CopyContainer:
ob=ob._getCopy(self)
orig_id=ob.getId()
id=self._get_id(ob.getId())
result.append({'id':orig_id, 'new_id':id})
ob._setId(id)
id = ob.id
result.append({'id':orig_id, 'new_id':id})
if not is_indexable:
ob._setNonIndexable()
self._setObject(id, ob)
......@@ -616,9 +617,10 @@ class CopyContainer:
ob = aq_base(ob)
orig_id=id
id=self._get_id(id)
result.append({'id':orig_id, 'new_id':id })
ob._setId(id)
id = ob.id
result.append({'id':orig_id, 'new_id':id })
if not is_indexable:
ob._setNonIndexable()
self._setObject(id, ob, set_owner=0)
......
......@@ -35,9 +35,10 @@ from Products.CMFCore.Expression import Expression
from Products.ERP5Type import interfaces, Permissions, PropertySheet
from Products.ERP5Type.Permissions import AccessContentsInformation
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.
"""
......
......@@ -161,7 +161,7 @@ class FolderMixIn(ExtensionClass.Base):
temp_object=temp_object or temp_container,
**kw)
if temp_container:
container._setObject(new_id, new_instance.aq_base)
container._setObject(new_instance.id, new_instance.aq_base)
return new_instance
security.declareProtected(
......
......@@ -40,9 +40,10 @@ from Products.ERP5Type.ERP5Type \
import ERP5TYPE_SECURITY_GROUP_ID_GENERATION_SCRIPT
from Products.ERP5Type.Permissions import AccessContentsInformation
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.
Roles definitions defines local roles on ERP5Type documents. They are
......
......@@ -399,7 +399,7 @@ class ERP5TypeInformation(XMLObject,
ob.setDefaultReindexParameterDict(reindex_kw)
if is_indexable is not None:
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 getattr(base_ob, 'uid', None) is None:
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