Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
erp5
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Ludovic Kiefer
erp5
Commits
e7fd1555
Commit
e7fd1555
authored
Nov 30, 2011
by
Julien Muchembled
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
New Base.skinSuper method to reuse code from lower-priority skins
Purpose is to reduce code duplication.
parent
4e66566f
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
89 additions
and
52 deletions
+89
-52
product/ERP5Type/Base.py
product/ERP5Type/Base.py
+12
-0
product/ERP5Type/patches/CMFCoreSkinnable.py
product/ERP5Type/patches/CMFCoreSkinnable.py
+55
-52
product/ERP5Type/patches/CMFCoreSkinsTool.py
product/ERP5Type/patches/CMFCoreSkinsTool.py
+3
-0
product/ERP5Type/tests/testCachedSkinsTool.py
product/ERP5Type/tests/testCachedSkinsTool.py
+19
-0
No files found.
product/ERP5Type/Base.py
View file @
e7fd1555
...
...
@@ -59,6 +59,7 @@ from Products.ERP5Type import _dtmldir
from
Products.ERP5Type
import
PropertySheet
from
Products.ERP5Type
import
interfaces
from
Products.ERP5Type
import
Permissions
from
Products.ERP5Type.patches.CMFCoreSkinnable
import
SKINDATA
,
skinResolve
from
Products.ERP5Type.Utils
import
UpperCase
from
Products.ERP5Type.Utils
import
convertToUpperCase
,
convertToMixedCase
from
Products.ERP5Type.Utils
import
createExpressionContext
,
simple_decorator
...
...
@@ -2976,6 +2977,17 @@ class Base( CopyContainer,
if
fallback_script_id
is
not
None
:
return
getattr
(
self
,
fallback_script_id
)
security
.
declareProtected
(
Permissions
.
AccessContentsInformation
,
'skinSuper'
)
def
skinSuper
(
self
,
skin
,
id
):
self
.
pdb
()
if
id
[:
1
]
!=
'_'
and
id
[:
3
]
!=
'aq_'
:
skin_info
=
SKINDATA
.
get
(
thread
.
get_ident
())
if
skin_info
is
not
None
:
object
=
skinResolve
(
self
.
getPortalObject
(),
(
skin_info
[
0
],
skin
),
id
)
if
object
is
not
None
:
return
object
.
__of__
(
self
)
raise
AttributeError
(
id
)
# Predicate handling
security
.
declareProtected
(
Permissions
.
AccessContentsInformation
,
'asPredicate'
)
def
asPredicate
(
self
,
script_id
=
None
):
...
...
product/ERP5Type/patches/CMFCoreSkinnable.py
View file @
e7fd1555
...
...
@@ -30,6 +30,18 @@ from Acquisition import aq_base
during the same request.
"""
def
_initializeCache
(
skin_tool
,
skin_folder_id_list
):
skin_list
=
{}
for
skin_folder_id
in
skin_folder_id_list
[::
-
1
]:
try
:
skin_folder
=
getattr
(
skin_tool
,
skin_folder_id
)
except
AttributeError
:
LOG
(
__name__
,
WARNING
,
'Skin folder %s is in selection list'
' but does not exist.'
%
skin_folder_id
)
else
:
skin_list
.
update
(
dict
.
fromkeys
(
skin_folder
.
objectIds
(),
skin_folder_id
))
return
skin_list
def
CMFCoreSkinnableSkinnableObjectManager_initializeCache
(
self
):
'''
Initialize the cache on portal skins.
...
...
@@ -40,23 +52,50 @@ def CMFCoreSkinnableSkinnableObjectManager_initializeCache(self):
portal_skins
=
portal_skins
.
aq_base
skin_selection_mapping
=
{}
for
selection_name
,
skin_folder_id_string
in
portal_skins
.
_getSelections
().
iteritems
():
skin_list
=
{}
skin_folder_id_list
=
skin_folder_id_string
.
split
(
','
)
skin_folder_id_list
.
reverse
()
for
skin_folder_id
in
skin_folder_id_list
:
skin_folder
=
getattr
(
portal_skins
,
skin_folder_id
,
None
)
if
skin_folder
is
not
None
:
for
skin_id
in
skin_folder
.
objectIds
():
skin_list
[
skin_id
]
=
skin_folder_id
else
:
LOG
(
'__getattr__'
,
WARNING
,
'Skin folder %s is in selection list '
\
'but does not exist.'
%
(
skin_folder_id
,
))
skin_selection_mapping
[
selection_name
]
=
skin_list
skin_selection_mapping
[
selection_name
]
=
_initializeCache
(
portal_skins
,
skin_folder_id_string
.
split
(
','
))
portal_skins
.
_v_skin_location_list
=
skin_selection_mapping
return
skin_selection_mapping
Skinnable
.
SkinnableObjectManager
.
initializeCache
=
CMFCoreSkinnableSkinnableObjectManager_initializeCache
def
skinResolve
(
self
,
selection
,
name
):
try
:
portal_skins
=
aq_base
(
self
.
portal_skins
)
except
AttributeError
:
raise
AttributeError
,
name
try
:
skin_selection_mapping
=
portal_skins
.
_v_skin_location_list
reset
=
False
except
AttributeError
:
LOG
(
__name__
,
DEBUG
,
'Initial skin cache fill.'
' This should not happen often. Current thread id:%X'
%
get_ident
())
skin_selection_mapping
=
self
.
initializeCache
()
reset
=
True
while
True
:
try
:
skin_folder_id
=
skin_selection_mapping
[
selection
][
name
]
except
KeyError
:
if
selection
in
skin_selection_mapping
or
\
isinstance
(
selection
,
basestring
):
return
skin_list
=
portal_skins
.
_getSelections
()[
selection
[
0
]].
split
(
','
)
skin_selection_mapping
[
selection
]
=
skin_list
=
_initializeCache
(
portal_skins
,
skin_list
[
1
+
skin_list
.
index
(
selection
[
1
]):])
try
:
skin_folder_id
=
skin_list
[
name
]
except
KeyError
:
return
reset
=
True
try
:
return
aq_base
(
getattr
(
getattr
(
portal_skins
,
skin_folder_id
),
name
))
except
AttributeError
:
if
reset
:
return
# We cannot find a document referenced in the cache, so reset it.
skin_selection_mapping
=
self
.
initializeCache
()
reset
=
True
def
CMFCoreSkinnableSkinnableObjectManager___getattr__
(
self
,
name
):
'''
Looks for the name in an object with wrappers that only reach
...
...
@@ -71,46 +110,10 @@ def CMFCoreSkinnableSkinnableObjectManager___getattr__(self, name):
return
resolve
[
name
]
except
KeyError
:
if
name
not
in
ignore
:
try
:
portal_skins
=
aq_base
(
self
.
portal_skins
)
except
AttributeError
:
raise
AttributeError
,
name
try
:
skin_selection_mapping
=
portal_skins
.
_v_skin_location_list
except
AttributeError
:
LOG
(
'Skinnable Monkeypatch __getattr__'
,
DEBUG
,
'Initial skin cache fill. This should not happen often. Current thread id:%X'
%
(
get_ident
(),
))
skin_selection_mapping
=
self
.
initializeCache
()
try
:
skin_folder_id
=
skin_selection_mapping
[
skin_selection_name
][
name
]
except
KeyError
:
pass
else
:
object
=
getattr
(
getattr
(
portal_skins
,
skin_folder_id
),
name
,
None
)
if
object
is
not
None
:
resolve
[
name
]
=
object
.
aq_base
return
resolve
[
name
]
else
:
# We cannot find a document referenced in the cache.
# Try to find if there is any other candidate in another
# skin folder of lower priority.
selection_dict
=
portal_skins
.
_getSelections
()
candidate_folder_id_list
=
selection_dict
[
skin_selection_name
].
split
(
','
)
previous_skin_folder_id
=
skin_selection_mapping
[
skin_selection_name
][
name
]
del
skin_selection_mapping
[
skin_selection_name
][
name
]
if
previous_skin_folder_id
in
candidate_folder_id_list
:
previous_skin_index
=
candidate_folder_id_list
.
index
(
previous_skin_folder_id
)
candidate_folder_id_list
=
candidate_folder_id_list
[
previous_skin_index
+
1
:]
for
candidate_folder_id
in
candidate_folder_id_list
:
candidate_folder
=
getattr
(
portal_skins
,
candidate_folder_id
,
None
)
if
candidate_folder
is
not
None
:
object
=
getattr
(
candidate_folder
,
name
,
None
)
if
object
is
not
None
:
skin_selection_mapping
[
skin_selection_name
][
name
]
=
candidate_folder_id
resolve
[
name
]
=
object
.
aq_base
return
resolve
[
name
]
else
:
LOG
(
'__getattr__'
,
WARNING
,
'Skin folder %s is in selection list '
\
'but does not exist.'
%
(
candidate_folder_id
,
))
object
=
skinResolve
(
self
,
skin_selection_name
,
name
)
if
object
is
not
None
:
resolve
[
name
]
=
object
return
object
ignore
[
name
]
=
None
raise
AttributeError
(
name
)
...
...
product/ERP5Type/patches/CMFCoreSkinsTool.py
View file @
e7fd1555
...
...
@@ -55,6 +55,9 @@ def CMFCoreSkinsTool__updateCacheEntry(self, container_id, object_id):
skin_location_list
=
getattr
(
self
,
'_v_skin_location_list'
,
None
)
if
skin_location_list
is
not
None
:
self
.
_p_changed
=
1
for
selection_name
in
skin_location_list
.
keys
():
if
not
isinstance
(
selection_name
,
basestring
):
del
skin_location_list
[
selection_name
]
for
selection_name
,
skin_folder_id_string
in
self
.
_getSelections
().
iteritems
():
skin_folder_id_list
=
skin_folder_id_string
.
split
(
','
)
if
container_id
in
skin_folder_id_list
:
...
...
product/ERP5Type/tests/testCachedSkinsTool.py
View file @
e7fd1555
...
...
@@ -30,6 +30,7 @@ import unittest
import
transaction
from
Products.ERP5Type.tests.ERP5TypeTestCase
import
ERP5TypeTestCase
from
Products.ERP5Type.tests.utils
import
createZODBPythonScript
from
AccessControl.SecurityManagement
import
newSecurityManager
TESTED_SKIN_FOLDER_ID
=
'custom'
...
...
@@ -131,5 +132,23 @@ class TestCachedSkinsTool(ERP5TypeTestCase):
self
.
assertTrue
(
getattr
(
skinnable_object
,
searched_object_other_id
,
None
)
is
not
None
)
self
.
assertTrue
(
getattr
(
tested_skin_folder
,
searched_object_other_id
,
None
)
is
not
None
)
def
test_05_skinSuper
(
self
):
tested_skin_folder
=
self
.
getTestedSkinFolder
()
script_id
=
'Base_getOwnerId'
ob
=
self
.
portal
.
portal_activities
orig
=
getattr
(
ob
,
script_id
)()
self
.
assertEqual
(
orig
,
'ERP5TypeTestCase'
)
try
:
script
=
createZODBPythonScript
(
tested_skin_folder
,
script_id
,
''
,
'return not %r'
%
orig
)
self
.
assertEqual
(
getattr
(
ob
,
script_id
)(),
not
orig
)
script
.
ZPythonScript_edit
(
''
,
'return context.skinSuper(%r, %r)()'
%
(
TESTED_SKIN_FOLDER_ID
,
script_id
))
self
.
assertEqual
(
getattr
(
ob
,
script_id
)(),
orig
)
self
.
getSkinsTool
().
erp5_core
.
_delObject
(
script_id
)
self
.
assertRaises
(
AttributeError
,
getattr
(
ob
,
script_id
))
finally
:
transaction
.
abort
()
if
__name__
==
'__main__'
:
unittest
.
main
()
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment