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
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
iv
erp5
Commits
2b13e39f
Commit
2b13e39f
authored
Nov 07, 2016
by
iv
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ERP5Workflow: WIP for folder comparison
parent
b1d54882
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
1297 additions
and
34 deletions
+1297
-34
product/ERP5Type/Core/ERP5OFSFolder.py
product/ERP5Type/Core/ERP5OFSFolder.py
+938
-0
product/ERP5Type/Core/ERP5PersistentMappingFolder.py
product/ERP5Type/Core/ERP5PersistentMappingFolder.py
+204
-0
product/ERP5Type/Core/ERP5PersistentMappingIndexFolder.py
product/ERP5Type/Core/ERP5PersistentMappingIndexFolder.py
+48
-0
product/ERP5Type/Core/Folder.py
product/ERP5Type/Core/Folder.py
+107
-34
No files found.
product/ERP5Type/Core/ERP5OFSFolder.py
0 → 100644
View file @
2b13e39f
"""
Object Manager
"""
from
cgi
import
escape
from
cStringIO
import
StringIO
from
logging
import
getLogger
import
copy
import
fnmatch
import
marshal
import
os
import
re
import
sys
from
types
import
NoneType
from
AccessControl
import
ClassSecurityInfo
from
AccessControl.class_init
import
InitializeClass
from
AccessControl.Permission
import
getPermissions
from
AccessControl.Permissions
import
view_management_screens
from
AccessControl.Permissions
import
access_contents_information
from
AccessControl.Permissions
import
delete_objects
from
AccessControl.Permissions
import
ftp_access
from
AccessControl.Permissions
import
import_export_objects
from
AccessControl
import
getSecurityManager
from
AccessControl.ZopeSecurityPolicy
import
getRoles
from
Acquisition
import
aq_base
from
Acquisition
import
Implicit
from
App.Common
import
is_acquired
from
App.config
import
getConfiguration
from
App.Dialogs
import
MessageDialog
from
App.FactoryDispatcher
import
ProductDispatcher
from
App.Management
import
Navigation
from
App.Management
import
Tabs
from
App.special_dtml
import
DTMLFile
from
Persistence
import
Persistent
from
webdav.Collection
import
Collection
from
webdav.Lockable
import
ResourceLockedError
from
webdav.NullResource
import
NullResource
from
zExceptions
import
BadRequest
from
zope.interface
import
implements
from
zope.component.interfaces
import
ComponentLookupError
from
zope.event
import
notify
from
zope.lifecycleevent
import
ObjectAddedEvent
from
zope.lifecycleevent
import
ObjectRemovedEvent
from
zope.container.contained
import
notifyContainerModified
from
OFS.CopySupport
import
CopyContainer
from
OFS.interfaces
import
IObjectManager
from
OFS.Traversable
import
Traversable
from
OFS.event
import
ObjectWillBeAddedEvent
from
OFS.event
import
ObjectWillBeRemovedEvent
from
OFS.subscribers
import
compatibilityCall
from
OFS.XMLExportImport
import
importXML
from
OFS.XMLExportImport
import
exportXML
from
OFS.XMLExportImport
import
magic
from
Products.ERP5Type.Utils
import
sortValueList
from
Products.ERP5Type.Base
import
Base
from
Folder
import
FolderMixIn
,
OFS_HANDLER
from
Products.ERP5Type
import
Permissions
# Constants: __replaceable__ flags:
NOT_REPLACEABLE
=
0
REPLACEABLE
=
1
UNIQUE
=
2
LOG
=
getLogger
(
'ObjectManager'
)
# the name BadRequestException is relied upon by 3rd-party code
BadRequestException
=
BadRequest
customImporters
=
{
magic
:
importXML
,}
bad_id
=
re
.
compile
(
r'[^a-zA-Z0-9-_~,.$\
(
\)# @]'
).
search
def
checkValidId
(
self
,
id
,
allow_dup
=
0
):
# If allow_dup is false, an error will be raised if an object
# with the given id already exists. If allow_dup is true,
# only check that the id string contains no illegal chars;
# check_valid_id() will be called again later with allow_dup
# set to false before the object is added.
import
Globals
# for data
if
not
id
or
not
isinstance
(
id
,
str
):
if
isinstance
(
id
,
unicode
):
id
=
escape
(
id
)
raise
BadRequest
,
(
'Empty or invalid id specified'
,
id
)
if
bad_id
(
id
)
is
not
None
:
raise
BadRequest
,
(
'The id "%s" contains characters illegal in URLs.'
%
escape
(
id
))
if
id
in
(
'.'
,
'..'
):
raise
BadRequest
,
(
'The id "%s" is invalid because it is not traversable.'
%
id
)
if
id
.
startswith
(
'_'
):
raise
BadRequest
,
(
'The id "%s" is invalid because it begins with an underscore.'
%
id
)
if
id
.
startswith
(
'aq_'
):
raise
BadRequest
,
(
'The id "%s" is invalid because it begins with "aq_".'
%
id
)
if
id
.
endswith
(
'__'
):
raise
BadRequest
,
(
'The id "%s" is invalid because it ends with two underscores.'
%
id
)
if
not
allow_dup
:
obj
=
getattr
(
self
,
id
,
None
)
if
obj
is
not
None
:
# An object by the given id exists either in this
# ObjectManager or in the acquisition path.
flags
=
getattr
(
obj
,
'__replaceable__'
,
NOT_REPLACEABLE
)
if
hasattr
(
aq_base
(
self
),
id
):
# The object is located in this ObjectManager.
if
not
flags
&
REPLACEABLE
:
raise
BadRequest
,
(
'The id "%s" is invalid - it is already in use.'
%
id
)
# else the object is replaceable even if the UNIQUE
# flag is set.
elif
flags
&
UNIQUE
:
raise
BadRequest
,
(
'The id "%s" is reserved.'
%
id
)
if
id
==
'REQUEST'
:
raise
BadRequest
,
'REQUEST is a reserved name.'
if
'/'
in
id
:
raise
BadRequest
,
(
'The id "%s" contains characters illegal in URLs.'
%
id
)
class
BeforeDeleteException
(
Exception
):
pass
# raise to veto deletion
class
BreakoutException
(
Exception
):
pass
# raised to break out of loops
_marker
=
[]
class
ERP5OFSFolder
(
CopyContainer
,
Base
,
FolderMixIn
):
# Declarative security
security
=
ClassSecurityInfo
()
security
.
declareObjectProtected
(
Permissions
.
AccessContentsInformation
)
# don't use ERP5Type.Core.Folder methods being specific to B-Tree folders
_folder_handler
=
OFS_HANDLER
meta_type
=
'Object Manager'
meta_types
=
()
# Sub-object types that are specific to this object
_objects
=
()
security
.
declareProtected
(
view_management_screens
,
'manage_main'
)
manage_main
=
DTMLFile
(
'dtml/main'
,
globals
())
manage_index_main
=
DTMLFile
(
'dtml/index_main'
,
globals
())
manage_options
=
(
{
'label'
:
'Contents'
,
'action'
:
'manage_main'
},
)
isAnObjectManager
=
1
isPrincipiaFolderish
=
1
has_order_support
=
0
# See OrderSupport.py
# IPossibleSite API
_components
=
None
security
.
declarePublic
(
'getSiteManager'
)
def
getSiteManager
(
self
):
if
self
.
_components
is
None
:
raise
ComponentLookupError
(
'No component registry defined.'
)
return
self
.
_components
security
.
declareProtected
(
'Manage Site'
,
'setSiteManager'
)
def
setSiteManager
(
self
,
components
):
self
.
_components
=
components
def
__class_init__
(
self
):
try
:
mt
=
list
(
self
.
meta_types
)
except
AttributeError
:
mt
=
[]
for
b
in
self
.
__bases__
:
try
:
for
t
in
b
.
meta_types
:
if
t
not
in
mt
:
mt
.
append
(
t
)
except
AttributeError
:
pass
mt
.
sort
()
self
.
meta_types
=
tuple
(
mt
)
InitializeClass
(
self
)
# default__class_init__
def
_verifyObjectPaste
(
self
,
object
,
validate_src
=
1
):
# Verify whether the current user is allowed to paste the
# passed object into self. This is determined by checking
# to see if the user could create a new object of the same
# meta_type of the object passed in and checking that the
# user actually is allowed to access the passed in object
# in its existing context.
#
# Passing a false value for the validate_src argument will skip
# checking the passed in object in its existing context. This is
# mainly useful for situations where the passed in object has no
# existing context, such as checking an object during an import
# (the object will not yet have been connected to the acquisition
# heirarchy).
def
absattr
(
attr
):
if
callable
(
attr
):
return
attr
()
return
attr
if
not
hasattr
(
object
,
'meta_type'
):
raise
CopyError
(
MessageDialog
(
title
=
'Not Supported'
,
message
=
(
'The object <em>%s</em> does not support this'
\
' operation'
%
escape
(
absattr
(
object
.
id
))),
action
=
'manage_main'
))
if
not
hasattr
(
self
,
'all_meta_types'
):
raise
CopyError
(
MessageDialog
(
title
=
'Not Supported'
,
message
=
'Cannot paste into this object.'
,
action
=
'manage_main'
))
method_name
=
None
mt_permission
=
None
meta_types
=
absattr
(
self
.
all_meta_types
)
for
d
in
meta_types
:
if
d
[
'name'
]
==
object
.
meta_type
:
method_name
=
d
[
'action'
]
mt_permission
=
d
.
get
(
'permission'
)
break
if
mt_permission
is
not
None
:
sm
=
getSecurityManager
()
if
sm
.
checkPermission
(
mt_permission
,
self
):
if
validate_src
:
# Ensure the user is allowed to access the object on the
# clipboard.
try
:
parent
=
aq_parent
(
aq_inner
(
object
))
except
:
parent
=
None
if
not
sm
.
validate
(
None
,
parent
,
None
,
object
):
raise
Unauthorized
(
absattr
(
object
.
id
))
if
validate_src
==
2
:
# moving
if
not
sm
.
checkPermission
(
delete_objects
,
parent
):
raise
Unauthorized
(
'Delete not allowed.'
)
else
:
raise
CopyError
(
MessageDialog
(
title
=
'Insufficient Privileges'
,
message
=
(
'You do not possess the %s permission in the '
'context of the container into which you are '
'pasting, thus you are not able to perform '
'this operation.'
%
mt_permission
),
action
=
'manage_main'
))
else
:
pass
#raise CopyError(MessageDialog(
# title = 'Not Supported',
# message = ('The object <em>%s</em> does not support this '
# 'operation.' % escape(absattr(object.id))),
# action = 'manage_main'))
# XXX(WORKFLOW): for some reason, this does not return meta_types
# like 'ERP5 Interaction', 'ERP5 Transition', ...
# so manage_renameObject (CopySupport.py) fails
# this is why we have the _verifyObjectPaste redefined above and ignoring
# CopyError
def
all_meta_types
(
self
,
interfaces
=
None
):
# A list of products registered elsewhere
import
Products
external_candidates
=
[]
# Look at _product_meta_types, if there is one
_pmt
=
()
if
hasattr
(
self
,
'_product_meta_types'
):
_pmt
=
self
.
_product_meta_types
elif
hasattr
(
self
,
'aq_acquire'
):
try
:
_pmt
=
self
.
aq_acquire
(
'_product_meta_types'
)
except
:
pass
external_candidates
.
extend
(
list
(
_pmt
))
# Look at all globally visible meta types.
for
entry
in
getattr
(
Products
,
'meta_types'
,
()):
if
((
interfaces
is
not
None
)
or
(
entry
.
get
(
"visibility"
,
None
)
==
"Global"
)):
external_candidates
.
append
(
entry
)
# Filter the list of external candidates based on the
# specified interface constraint
if
interfaces
is
None
:
interface_constrained_meta_types
=
external_candidates
else
:
interface_constrained_meta_types
=
icmt
=
[]
for
entry
in
external_candidates
:
try
:
eil
=
entry
.
get
(
'interfaces'
,
None
)
if
eil
is
not
None
:
for
ei
in
eil
:
for
i
in
interfaces
:
if
ei
is
i
or
ei
.
extends
(
i
):
icmt
.
append
(
entry
)
raise
BreakoutException
# only append 1ce
except
BreakoutException
:
pass
# Meta types specified by this instance are not checked against the
# interface constraint. This is as it always has been, but Im not
# sure it is correct.
interface_constrained_meta_types
.
extend
(
list
(
self
.
meta_types
))
# Filter the list based on each meta-types's container_filter
meta_types
=
[]
for
entry
in
interface_constrained_meta_types
:
container_filter
=
entry
.
get
(
'container_filter'
,
None
)
if
container_filter
is
None
:
meta_types
.
append
(
entry
)
else
:
if
container_filter
(
self
):
meta_types
.
append
(
entry
)
return
meta_types
def
_subobject_permissions
(
self
):
return
getPermissions
()
def
filtered_meta_types
(
self
,
user
=
None
):
# Return a list of the types for which the user has
# adequate permission to add that type of object.
sm
=
getSecurityManager
()
meta_types
=
[]
if
callable
(
self
.
all_meta_types
):
all
=
self
.
all_meta_types
()
else
:
all
=
self
.
all_meta_types
for
meta_type
in
all
:
if
'permission'
in
meta_type
:
if
sm
.
checkPermission
(
meta_type
[
'permission'
],
self
):
meta_types
.
append
(
meta_type
)
else
:
meta_types
.
append
(
meta_type
)
return
meta_types
_checkId
=
checkValidId
def
_setOb
(
self
,
id
,
object
):
setattr
(
self
,
id
,
object
)
def
_delOb
(
self
,
id
):
delattr
(
self
,
id
)
def
_getOb
(
self
,
id
,
default
=
_marker
):
# FIXME: what we really need to do here is ensure that only
# sub-items are returned. That could have a measurable hit
# on performance as things are currently implemented, so for
# the moment we just make sure not to expose private attrs.
if
id
[:
1
]
!=
'_'
and
hasattr
(
aq_base
(
self
),
id
):
return
getattr
(
self
,
id
)
if
default
is
_marker
:
raise
AttributeError
,
id
return
default
security
.
declareProtected
(
access_contents_information
,
'hasObject'
)
def
hasObject
(
self
,
id
):
"""Indicate whether the folder has an item by ID.
This doesn't try to be more intelligent than _getOb, and doesn't
consult _objects (for performance reasons). The common use case
is to check that an object does *not* exist.
"""
if
(
id
in
(
'.'
,
'..'
)
or
id
.
startswith
(
'_'
)
or
id
.
startswith
(
'aq_'
)
or
id
.
endswith
(
'__'
)):
return
False
return
getattr
(
aq_base
(
self
),
id
,
None
)
is
not
None
def
_setObject
(
self
,
id
,
object
,
roles
=
None
,
user
=
None
,
set_owner
=
1
,
suppress_events
=
False
):
"""Set an object into this container.
Also sends IObjectWillBeAddedEvent and IObjectAddedEvent.
"""
ob
=
object
# better name, keep original function signature
v
=
self
.
_checkId
(
id
)
if
v
is
not
None
:
id
=
v
t
=
getattr
(
ob
,
'meta_type'
,
None
)
# If an object by the given id already exists, remove it.
for
object_info
in
self
.
_objects
:
if
object_info
[
'id'
]
==
id
:
self
.
_delObject
(
id
)
break
if
not
suppress_events
:
notify
(
ObjectWillBeAddedEvent
(
ob
,
self
,
id
))
self
.
_objects
=
self
.
_objects
+
({
'id'
:
id
,
'meta_type'
:
t
},)
self
.
_setOb
(
id
,
ob
)
ob
=
self
.
_getOb
(
id
)
if
set_owner
:
# TODO: eventify manage_fixupOwnershipAfterAdd
# This will be called for a copy/clone, or a normal _setObject.
ob
.
manage_fixupOwnershipAfterAdd
()
# Try to give user the local role "Owner", but only if
# no local roles have been set on the object yet.
if
getattr
(
ob
,
'__ac_local_roles__'
,
_marker
)
is
None
:
user
=
getSecurityManager
().
getUser
()
if
user
is
not
None
:
userid
=
user
.
getId
()
if
userid
is
not
None
:
ob
.
manage_setLocalRoles
(
userid
,
[
'Owner'
])
if
not
suppress_events
:
notify
(
ObjectAddedEvent
(
ob
,
self
,
id
))
notifyContainerModified
(
self
)
compatibilityCall
(
'manage_afterAdd'
,
ob
,
ob
,
self
)
return
id
def
manage_afterAdd
(
self
,
item
,
container
):
# Don't do recursion anymore, a subscriber does that.
pass
manage_afterAdd
.
__five_method__
=
True
def
manage_afterClone
(
self
,
item
):
# Don't do recursion anymore, a subscriber does that.
pass
manage_afterClone
.
__five_method__
=
True
def
manage_beforeDelete
(
self
,
item
,
container
):
# Don't do recursion anymore, a subscriber does that.
pass
manage_beforeDelete
.
__five_method__
=
True
def
_delObject
(
self
,
id
,
dp
=
1
,
suppress_events
=
False
):
"""Delete an object from this container.
Also sends IObjectWillBeRemovedEvent and IObjectRemovedEvent.
"""
ob
=
self
.
_getOb
(
id
)
compatibilityCall
(
'manage_beforeDelete'
,
ob
,
ob
,
self
)
if
not
suppress_events
:
notify
(
ObjectWillBeRemovedEvent
(
ob
,
self
,
id
))
self
.
_objects
=
tuple
([
i
for
i
in
self
.
_objects
if
i
[
'id'
]
!=
id
])
self
.
_delOb
(
id
)
# Indicate to the object that it has been deleted. This is
# necessary for object DB mount points. Note that we have to
# tolerate failure here because the object being deleted could
# be a Broken object, and it is not possible to set attributes
# on Broken objects.
try
:
ob
.
_v__object_deleted__
=
1
except
:
pass
if
not
suppress_events
:
notify
(
ObjectRemovedEvent
(
ob
,
self
,
id
))
notifyContainerModified
(
self
)
security
.
declareProtected
(
access_contents_information
,
'objectIds'
)
def
objectIds
(
self
,
meta_type
=
None
):
# Returns a list of subobject ids of the current object.
# If 'meta_type' is specified, returns objects whose meta_type
# matches 'meta_type'.
if
meta_type
is
not
None
:
if
type
(
meta_type
)
is
str
:
meta_type
=
[
meta_type
]
set
=
[]
for
ob
in
self
.
_objects
:
if
ob
[
'meta_type'
]
in
meta_type
:
set
.
append
(
ob
[
'id'
])
return
set
return
[
o
[
'id'
]
for
o
in
self
.
_objects
]
####################### modified methods ####################
# XXX(WORKFLOW): see all_meta_types
def
manage_renameObject
(
self
,
id
,
new_id
,
REQUEST
=
None
):
if
getattr
(
self
,
new_id
,
None
):
self
.
_delObject
(
new_id
)
return
CopyContainer
.
manage_renameObject
(
self
,
id
,
new_id
,
REQUEST
=
REQUEST
)
security
.
declareProtected
(
access_contents_information
,
'objectValues'
)
# modified to be compatible with ERP5.Core.Folder parameters, so that
# it is possible to filter on portal_type, ...
def
objectValues
(
self
,
spec
=
None
,
meta_type
=
None
,
portal_type
=
None
,
sort_on
=
None
,
sort_order
=
None
,
checked_permission
=
None
,
**
kw
):
# Returns list of objects contained in this folder.
# (no docstring to prevent publishing)
if
meta_type
is
not
None
:
spec
=
meta_type
if
self
.
_folder_handler
==
OFS_HANDLER
:
object_list
=
[
self
.
_getOb
(
id
)
for
id
in
self
.
objectIds
(
spec
)
]
if
portal_type
is
not
None
:
if
isinstance
(
portal_type
,
str
):
portal_type
=
(
portal_type
,)
object_list
=
filter
(
lambda
x
:
x
.
getPortalType
()
in
portal_type
,
object_list
)
if
checked_permission
is
not
None
:
checkPermission
=
getSecurityManager
().
checkPermission
object_list
=
[
o
for
o
in
object_list
if
checkPermission
(
checked_permission
,
o
)]
return
sortValueList
(
object_list
,
sort_on
,
sort_order
,
**
kw
)
####################### end of modified methods ####################
####################### hacked method ####################
def
_initBTrees
(
self
):
pass
####################### end of hacked methods ####################
security
.
declareProtected
(
access_contents_information
,
'objectItems'
)
def
objectItems
(
self
,
spec
=
None
):
# Returns a list of (id, subobject) tuples of the current object.
# If 'spec' is specified, returns only objects whose meta_type match
# 'spec'
return
[
(
id
,
self
.
_getOb
(
id
))
for
id
in
self
.
objectIds
(
spec
)
]
def
objectMap
(
self
):
# Return a tuple of mappings containing subobject meta-data
return
tuple
(
d
.
copy
()
for
d
in
self
.
_objects
)
security
.
declareProtected
(
access_contents_information
,
'objectIds_d'
)
def
objectIds_d
(
self
,
t
=
None
):
if
hasattr
(
self
,
'_reserved_names'
):
n
=
self
.
_reserved_names
else
:
n
=
()
if
not
n
:
return
self
.
objectIds
(
t
)
r
=
[]
a
=
r
.
append
for
id
in
self
.
objectIds
(
t
):
if
id
not
in
n
:
a
(
id
)
return
r
security
.
declareProtected
(
access_contents_information
,
'objectValues_d'
)
def
objectValues_d
(
self
,
t
=
None
):
return
map
(
self
.
_getOb
,
self
.
objectIds_d
(
t
))
security
.
declareProtected
(
access_contents_information
,
'objectItems_d'
)
def
objectItems_d
(
self
,
t
=
None
):
r
=
[]
a
=
r
.
append
g
=
self
.
_getOb
for
id
in
self
.
objectIds_d
(
t
):
a
((
id
,
g
(
id
)))
return
r
security
.
declareProtected
(
access_contents_information
,
'objectMap_d'
)
def
objectMap_d
(
self
,
t
=
None
):
if
hasattr
(
self
,
'_reserved_names'
):
n
=
self
.
_reserved_names
else
:
n
=
()
if
not
n
:
return
self
.
_objects
r
=
[]
a
=
r
.
append
for
d
in
self
.
_objects
:
if
d
[
'id'
]
not
in
n
:
a
(
d
.
copy
())
return
r
security
.
declareProtected
(
access_contents_information
,
'superValues'
)
def
superValues
(
self
,
t
):
# Return all of the objects of a given type located in
# this object and containing objects.
if
type
(
t
)
is
str
:
t
=
(
t
,)
obj
=
self
seen
=
{}
vals
=
[]
relativePhysicalPath
=
()
x
=
0
while
x
<
100
:
if
not
hasattr
(
obj
,
'_getOb'
):
break
get
=
obj
.
_getOb
if
hasattr
(
obj
,
'_objects'
):
for
i
in
obj
.
_objects
:
try
:
id
=
i
[
'id'
]
physicalPath
=
relativePhysicalPath
+
(
id
,)
if
(
physicalPath
not
in
seen
)
and
(
i
[
'meta_type'
]
in
t
):
vals
.
append
(
get
(
id
))
seen
[
physicalPath
]
=
1
except
:
pass
if
hasattr
(
obj
,
'aq_parent'
):
obj
=
obj
.
aq_parent
relativePhysicalPath
=
(
'..'
,)
+
relativePhysicalPath
else
:
return
vals
x
=
x
+
1
return
vals
manage_addProduct
=
ProductDispatcher
()
security
.
declareProtected
(
delete_objects
,
'manage_delObjects'
)
def
manage_delObjects
(
self
,
ids
=
[],
REQUEST
=
None
):
"""Delete a subordinate object
The objects specified in 'ids' get deleted.
"""
if
type
(
ids
)
is
str
:
ids
=
[
ids
]
if
not
ids
:
return
MessageDialog
(
title
=
'No items specified'
,
message
=
'No items were specified!'
,
action
=
'./manage_main'
,)
try
:
p
=
self
.
_reserved_names
except
:
p
=
()
for
n
in
ids
:
if
n
in
p
:
return
MessageDialog
(
title
=
'Not Deletable'
,
message
=
'<EM>%s</EM> cannot be deleted.'
%
escape
(
n
),
action
=
'./manage_main'
,)
while
ids
:
id
=
ids
[
-
1
]
v
=
self
.
_getOb
(
id
,
self
)
if
v
.
wl_isLocked
():
raise
ResourceLockedError
,
(
'Object "%s" is locked via WebDAV'
%
v
.
getId
())
if
v
is
self
:
raise
BadRequest
,
'%s does not exist'
%
escape
(
ids
[
-
1
])
self
.
_delObject
(
id
)
del
ids
[
-
1
]
if
REQUEST
is
not
None
:
return
self
.
manage_main
(
self
,
REQUEST
,
update_menu
=
1
)
security
.
declareProtected
(
access_contents_information
,
'tpValues'
)
def
tpValues
(
self
):
# Return a list of subobjects, used by tree tag.
r
=
[]
if
hasattr
(
aq_base
(
self
),
'tree_ids'
):
tree_ids
=
self
.
tree_ids
try
:
tree_ids
=
list
(
tree_ids
)
except
TypeError
:
pass
if
hasattr
(
tree_ids
,
'sort'
):
tree_ids
.
sort
()
for
id
in
tree_ids
:
if
hasattr
(
self
,
id
):
r
.
append
(
self
.
_getOb
(
id
))
else
:
obj_ids
=
self
.
objectIds
()
obj_ids
.
sort
()
for
id
in
obj_ids
:
o
=
self
.
_getOb
(
id
)
if
hasattr
(
aq_base
(
o
),
'isPrincipiaFolderish'
)
and
\
o
.
isPrincipiaFolderish
:
r
.
append
(
o
)
return
r
security
.
declareProtected
(
import_export_objects
,
'manage_exportObject'
)
def
manage_exportObject
(
self
,
id
=
''
,
download
=
None
,
toxml
=
None
,
RESPONSE
=
None
,
REQUEST
=
None
):
"""Exports an object to a file and returns that file."""
if
not
id
:
# can't use getId() here (breaks on "old" exported objects)
id
=
self
.
id
if
hasattr
(
id
,
'im_func'
):
id
=
id
()
ob
=
self
else
:
ob
=
self
.
_getOb
(
id
)
suffix
=
toxml
and
'xml'
or
'zexp'
if
download
:
f
=
StringIO
()
if
toxml
:
exportXML
(
ob
.
_p_jar
,
ob
.
_p_oid
,
f
)
else
:
ob
.
_p_jar
.
exportFile
(
ob
.
_p_oid
,
f
)
if
RESPONSE
is
not
None
:
RESPONSE
.
setHeader
(
'Content-type'
,
'application/data'
)
RESPONSE
.
setHeader
(
'Content-Disposition'
,
'inline;filename=%s.%s'
%
(
id
,
suffix
))
return
f
.
getvalue
()
cfg
=
getConfiguration
()
f
=
os
.
path
.
join
(
cfg
.
clienthome
,
'%s.%s'
%
(
id
,
suffix
))
if
toxml
:
exportXML
(
ob
.
_p_jar
,
ob
.
_p_oid
,
f
)
else
:
ob
.
_p_jar
.
exportFile
(
ob
.
_p_oid
,
f
)
if
REQUEST
is
not
None
:
return
self
.
manage_main
(
self
,
REQUEST
,
manage_tabs_message
=
'<em>%s</em> successfully exported to <em>%s</em>'
%
(
id
,
f
),
title
=
'Object exported'
)
security
.
declareProtected
(
import_export_objects
,
'manage_importExportForm'
)
manage_importExportForm
=
DTMLFile
(
'dtml/importExport'
,
globals
())
security
.
declareProtected
(
import_export_objects
,
'manage_importObject'
)
def
manage_importObject
(
self
,
file
,
REQUEST
=
None
,
set_owner
=
1
):
"""Import an object from a file"""
dirname
,
file
=
os
.
path
.
split
(
file
)
if
dirname
:
raise
BadRequest
,
'Invalid file name %s'
%
escape
(
file
)
for
impath
in
self
.
_getImportPaths
():
filepath
=
os
.
path
.
join
(
impath
,
'import'
,
file
)
if
os
.
path
.
exists
(
filepath
):
break
else
:
raise
BadRequest
,
'File does not exist: %s'
%
escape
(
file
)
self
.
_importObjectFromFile
(
filepath
,
verify
=
not
not
REQUEST
,
set_owner
=
set_owner
)
if
REQUEST
is
not
None
:
return
self
.
manage_main
(
self
,
REQUEST
,
manage_tabs_message
=
'<em>%s</em> successfully imported'
%
id
,
title
=
'Object imported'
,
update_menu
=
1
)
def
_importObjectFromFile
(
self
,
filepath
,
verify
=
1
,
set_owner
=
1
):
# locate a valid connection
connection
=
self
.
_p_jar
obj
=
self
while
connection
is
None
:
obj
=
obj
.
aq_parent
connection
=
obj
.
_p_jar
ob
=
connection
.
importFile
(
filepath
,
customImporters
=
customImporters
)
if
verify
:
self
.
_verifyObjectPaste
(
ob
,
validate_src
=
0
)
id
=
ob
.
id
if
hasattr
(
id
,
'im_func'
):
id
=
id
()
self
.
_setObject
(
id
,
ob
,
set_owner
=
set_owner
)
# try to make ownership implicit if possible in the context
# that the object was imported into.
ob
=
self
.
_getOb
(
id
)
ob
.
manage_changeOwnershipType
(
explicit
=
0
)
def
_getImportPaths
(
self
):
cfg
=
getConfiguration
()
paths
=
[]
zopehome
=
getattr
(
cfg
,
'zopehome'
,
None
)
if
zopehome
is
not
None
and
cfg
.
zopehome
is
not
None
:
paths
.
append
(
zopehome
)
if
not
cfg
.
instancehome
in
paths
:
paths
.
append
(
cfg
.
instancehome
)
if
not
cfg
.
clienthome
in
paths
:
paths
.
append
(
cfg
.
clienthome
)
return
paths
def
list_imports
(
self
):
listing
=
[]
for
impath
in
self
.
_getImportPaths
():
directory
=
os
.
path
.
join
(
impath
,
'import'
)
if
not
os
.
path
.
isdir
(
directory
):
continue
listing
+=
[
f
for
f
in
os
.
listdir
(
directory
)
if
f
.
endswith
(
'.zexp'
)
or
f
.
endswith
(
'.xml'
)]
listing
.
sort
()
return
listing
# FTP support methods
security
.
declareProtected
(
ftp_access
,
'manage_FTPlist'
)
def
manage_FTPlist
(
self
,
REQUEST
):
"""Directory listing for FTP.
"""
out
=
()
# check to see if we are being acquiring or not
ob
=
self
while
1
:
if
is_acquired
(
ob
):
raise
ValueError
(
'FTP List not supported on acquired objects'
)
if
not
hasattr
(
ob
,
'aq_parent'
):
break
ob
=
ob
.
aq_parent
files
=
list
(
self
.
objectItems
())
# recursive ride through all subfolders (ls -R) (ajung)
if
REQUEST
.
environ
.
get
(
'FTP_RECURSIVE'
,
0
)
==
1
:
all_files
=
copy
.
copy
(
files
)
for
f
in
files
:
if
(
hasattr
(
aq_base
(
f
[
1
]),
'isPrincipiaFolderish'
)
and
f
[
1
].
isPrincipiaFolderish
):
all_files
.
extend
(
findChildren
(
f
[
1
]))
files
=
all_files
# Perform globbing on list of files (ajung)
globbing
=
REQUEST
.
environ
.
get
(
'GLOBBING'
,
''
)
if
globbing
:
files
=
[
x
for
x
in
files
if
fnmatch
.
fnmatch
(
x
[
0
],
globbing
)]
files
.
sort
()
if
not
(
hasattr
(
self
,
'isTopLevelPrincipiaApplicationObject'
)
and
self
.
isTopLevelPrincipiaApplicationObject
):
files
.
insert
(
0
,(
'..'
,
self
.
aq_parent
))
files
.
insert
(
0
,
(
'.'
,
self
))
for
k
,
v
in
files
:
# Note that we have to tolerate failure here, because
# Broken objects won't stat correctly. If an object fails
# to be able to stat itself, we will ignore it, but log
# the error.
try
:
stat
=
marshal
.
loads
(
v
.
manage_FTPstat
(
REQUEST
))
except
:
LOG
.
error
(
"Failed to stat file '%s'"
%
k
,
exc_info
=
sys
.
exc_info
())
stat
=
None
if
stat
is
not
None
:
out
=
out
+
((
k
,
stat
),)
return
marshal
.
dumps
(
out
)
security
.
declareProtected
(
ftp_access
,
'manage_hasId'
)
def
manage_hasId
(
self
,
REQUEST
):
""" check if the folder has an object with REQUEST['id'] """
if
not
REQUEST
[
'id'
]
in
self
.
objectIds
():
raise
KeyError
(
REQUEST
[
'id'
])
security
.
declareProtected
(
ftp_access
,
'manage_FTPstat'
)
def
manage_FTPstat
(
self
,
REQUEST
):
"""Psuedo stat, used by FTP for directory listings.
"""
mode
=
0040000
from
AccessControl.User
import
nobody
# check to see if we are acquiring our objectValues or not
if
not
(
len
(
REQUEST
.
PARENTS
)
>
1
and
self
.
objectValues
()
==
REQUEST
.
PARENTS
[
1
].
objectValues
()):
try
:
if
getSecurityManager
().
validate
(
None
,
self
,
'manage_FTPlist'
,
self
.
manage_FTPlist
):
mode
=
mode
|
0770
except
:
pass
if
nobody
.
allowed
(
self
,
getRoles
(
self
,
'manage_FTPlist'
,
self
.
manage_FTPlist
,
())):
mode
=
mode
|
0007
mtime
=
self
.
bobobase_modification_time
().
timeTime
()
# get owner and group
owner
=
group
=
'Zope'
for
user
,
roles
in
self
.
get_local_roles
():
if
'Owner'
in
roles
:
owner
=
user
break
return
marshal
.
dumps
((
mode
,
0
,
0
,
1
,
owner
,
group
,
0
,
mtime
,
mtime
,
mtime
))
def
__delitem__
(
self
,
name
):
return
self
.
manage_delObjects
(
ids
=
[
name
])
def
__getitem__
(
self
,
key
):
if
key
in
self
:
return
self
.
_getOb
(
key
,
None
)
request
=
getattr
(
self
,
'REQUEST'
,
None
)
if
not
isinstance
(
request
,
(
str
,
NoneType
)):
method
=
request
.
get
(
'REQUEST_METHOD'
,
'GET'
)
if
(
request
.
maybe_webdav_client
and
method
not
in
(
'GET'
,
'POST'
)):
return
NullResource
(
self
,
key
,
request
).
__of__
(
self
)
raise
KeyError
,
key
def
__setitem__
(
self
,
key
,
value
):
return
self
.
_setObject
(
key
,
value
)
def
__contains__
(
self
,
name
):
return
name
in
self
.
objectIds
()
def
__iter__
(
self
):
return
iter
(
self
.
objectIds
())
def
__len__
(
self
):
return
len
(
self
.
objectIds
())
def
__nonzero__
(
self
):
return
True
security
.
declareProtected
(
access_contents_information
,
'get'
)
def
get
(
self
,
key
,
default
=
None
):
if
key
in
self
:
return
self
.
_getOb
(
key
,
default
)
return
default
security
.
declareProtected
(
access_contents_information
,
'keys'
)
def
keys
(
self
):
return
self
.
objectIds
()
security
.
declareProtected
(
access_contents_information
,
'items'
)
def
items
(
self
):
return
self
.
objectItems
()
security
.
declareProtected
(
access_contents_information
,
'values'
)
def
values
(
self
):
return
self
.
objectValues
()
# Don't InitializeClass, there is a specific __class_init__ on ObjectManager
# InitializeClass(ObjectManager)
def
findChildren
(
obj
,
dirname
=
''
):
""" recursive walk through the object hierarchy to
find all children of an object (ajung)
"""
lst
=
[]
for
name
,
child
in
obj
.
objectItems
():
if
(
hasattr
(
aq_base
(
child
),
'isPrincipiaFolderish'
)
and
child
.
isPrincipiaFolderish
):
lst
.
extend
(
findChildren
(
child
,
dirname
+
obj
.
id
+
'/'
))
else
:
lst
.
append
((
dirname
+
obj
.
id
+
"/"
+
name
,
child
))
return
lst
product/ERP5Type/Core/ERP5PersistentMappingFolder.py
0 → 100644
View file @
2b13e39f
from
Products.ERP5Type.Utils
import
sortValueList
from
Products.ERP5Type.Globals
import
Persistent
,
PersistentMapping
from
Products.ERP5Type
import
Permissions
from
AccessControl
import
ClassSecurityInfo
from
AccessControl
import
getSecurityManager
from
App.special_dtml
import
DTMLFile
from
zope.event
import
notify
from
OFS.event
import
ObjectWillBeAddedEvent
from
OFS.subscribers
import
compatibilityCall
from
zope.lifecycleevent
import
ObjectAddedEvent
from
zope.lifecycleevent
import
ObjectRemovedEvent
from
zope.container.contained
import
notifyContainerModified
from
OFS.Folder
import
Folder
from
Products.CMFCore.PortalFolder
import
PortalFolderBase
from
Products.ERP5Type.Base
import
Base
from
zLOG
import
LOG
_marker
=
[]
class
ERP5PersistentMappingFolder
(
PortalFolderBase
):
meta_type
=
'ERP5 Persistent Mapping Folder'
portal_type
=
'ERP5PersistentMappingFolder'
_object_dict
=
None
# Declarative security
security
=
ClassSecurityInfo
()
security
.
declareProtected
(
Permissions
.
ViewManagementScreens
,
'manage_main'
)
manage_main
=
DTMLFile
(
'contents'
,
globals
())
def
__init__
(
self
,
id
,
title
=
''
):
PortalFolderBase
.
__init__
(
self
,
id
,
title
)
self
.
_object_dict
=
PersistentMapping
()
def
__getattr__
(
self
,
name
):
if
self
.
_object_dict
is
None
:
LOG
(
"### self._object_dict is None"
,
0
,
''
)
raise
AttributeError
(
name
)
try
:
return
self
.
_object_dict
[
name
]
except
KeyError
:
LOG
(
"### KeyError for key "
+
name
+
" not in:"
,
0
,
self
.
_object_dict
)
raise
AttributeError
(
name
)
def
__len__
(
self
):
return
self
.
objectCount
()
security
.
declareProtected
(
Permissions
.
AccessContentsInformation
,
'get'
)
def
get
(
self
,
name
,
default
=
None
):
return
self
.
_getOb
(
name
,
default
)
def
__getitem__
(
self
,
name
):
return
self
.
_getOb
(
name
)
def
_setOb
(
self
,
object_id
,
object_value
):
if
self
.
_object_dict
is
None
:
self
.
_object_dict
=
PersistentMapping
()
self
.
_object_dict
[
object_id
]
=
object_value
def
_delOb
(
self
,
object_id
):
del
self
.
_object_dict
[
object_id
]
def
_getOb
(
self
,
object_id
,
default
=
_marker
):
"""
Return the named object from the folder.
"""
try
:
return
self
.
_object_dict
[
object_id
].
__of__
(
self
)
except
KeyError
:
if
default
is
_marker
:
raise
else
:
return
default
def
objectIds
(
self
,
spec
=
None
,
**
kw
):
# we don't plan to use meta_type now, so spec is just here for compatibility
assert
(
spec
is
None
)
return
self
.
_object_dict
.
keys
()
def
objectCount
(
self
):
return
len
(
self
.
_object_dict
)
def
objectItems
(
self
,
spec
=
None
):
assert
(
spec
is
None
)
return
self
.
_object_dict
def
objectIds_d
(
self
,
t
=
None
):
assert
(
t
is
None
)
return
objectIds
(
self
,
t
)
security
.
declareProtected
(
Permissions
.
AccessContentsInformation
,
'objectValues'
)
def
objectValues
(
self
,
spec
=
None
,
portal_type
=
None
,
sort_on
=
None
,
sort_order
=
None
,
checked_permission
=
None
,
**
kw
):
# Returns list of objects contained in this folder.
# (no docstring to prevent publishing)
assert
(
spec
is
None
)
if
self
.
_object_dict
is
None
:
return
[]
object_list
=
self
.
_object_dict
.
values
()
if
portal_type
is
not
None
:
if
isinstance
(
portal_type
,
str
):
portal_type
=
(
portal_type
,)
object_list
=
filter
(
lambda
x
:
x
.
getPortalType
()
in
portal_type
,
object_list
)
if
checked_permission
is
not
None
:
checkPermission
=
getSecurityManager
().
checkPermission
object_list
=
[
o
for
o
in
object_list
if
checkPermission
(
checked_permission
,
o
)]
return
sortValueList
(
object_list
,
sort_on
,
sort_order
,
**
kw
)
security
.
declareProtected
(
Permissions
.
AccessContentsInformation
,
'keys'
,
'items'
,
'values'
)
keys
=
objectIds
values
=
objectValues
items
=
objectItems
def
_setObject
(
self
,
id
,
object
,
roles
=
None
,
user
=
None
,
set_owner
=
True
,
suppress_events
=
False
):
ob
=
object
# better name, keep original function signature
v
=
self
.
_checkId
(
id
)
if
v
is
not
None
:
id
=
v
# If an object by the given id already exists, remove it.
if
id
in
self
:
self
.
_delObject
(
id
)
if
not
suppress_events
:
notify
(
ObjectWillBeAddedEvent
(
ob
,
self
,
id
))
self
.
_setOb
(
id
,
ob
)
ob
=
self
.
_getOb
(
id
)
if
set_owner
:
# TODO: eventify manage_fixupOwnershipAfterAdd
# This will be called for a copy/clone, or a normal _setObject.
ob
.
manage_fixupOwnershipAfterAdd
()
# Try to give user the local role "Owner", but only if
# no local roles have been set on the object yet.
if
getattr
(
ob
,
'__ac_local_roles__'
,
_marker
)
is
None
:
user
=
getSecurityManager
().
getUser
()
if
user
is
not
None
:
userid
=
user
.
getId
()
if
userid
is
not
None
:
ob
.
manage_setLocalRoles
(
userid
,
[
'Owner'
])
if
not
suppress_events
:
notify
(
ObjectAddedEvent
(
ob
,
self
,
id
))
notifyContainerModified
(
self
)
compatibilityCall
(
'manage_afterAdd'
,
ob
,
ob
,
self
)
return
id
def
_cleanup
(
self
):
cleaned
=
False
for
attribute
in
(
'_tree'
,
'_mt_index'
,
'_count'
):
try
:
if
object
.
__getattribute__
(
self
,
attribute
):
del
self
.
_tree
cleaned
=
True
except
AttributeError
:
pass
return
cleaned
def
has_key
(
self
,
key
):
if
(
key
in
(
'.'
,
'..'
)
or
key
.
startswith
(
'_'
)
or
key
.
startswith
(
'aq_'
)
or
key
.
endswith
(
'__'
)
or
self
.
_object_dict
is
None
):
return
False
return
self
.
_object_dict
.
get
(
key
,
None
)
is
not
None
hasObject
=
has_key
def
hashId
(
self
,
id
):
raise
NotImplementedError
def
_populateFromFolder
(
self
,
source
):
"""Fill this folder with the contents of another folder.
"""
for
name
in
source
.
objectIds
():
value
=
source
.
_getOb
(
name
,
None
)
if
value
is
not
None
:
self
.
_setOb
(
name
,
aq_base
(
value
))
def
tpValues
(
self
):
"""
Ensures the items don't show up in the left pane.
"""
# is this really useful?
return
()
def
_checkId
(
self
,
id
,
allow_dup
=
0
):
if
self
.
_object_dict
is
not
None
and
not
allow_dup
and
id
in
self
.
_object_dict
:
raise
BadRequestException
(
'The id "%s" is invalid--'
'it is already in use.'
%
id
)
product/ERP5Type/Core/ERP5PersistentMappingIndexFolder.py
0 → 100644
View file @
2b13e39f
from
ERP5PersistentMappingFolder
import
ERP5PersistentMappingFolder
from
Products.ERP5Type.Globals
import
PersistentMapping
from
Products.ERP5Type.Utils
import
sortValueList
from
Products.ERP5Type
import
Permissions
from
AccessControl
import
ClassSecurityInfo
class
ERP5PersistentMappingIndexFolder
(
ERP5PersistentMappingFolder
):
meta_type
=
'ERP5 Persistent Mapping Index Folder'
portal_type
=
'ERP5PersistentMappingIndexFolder'
# Declarative security
security
=
ClassSecurityInfo
()
security
.
declareObjectProtected
(
Permissions
.
AccessContentsInformation
)
def
__init__
(
self
):
ERP5PersistentMappingFolder
.
__init__
(
self
)
self
.
_object_index
=
PersistentMapping
()
def
_setOb
(
self
,
object_id
,
object_value
):
self
.
_object_dict
[
object_id
]
=
object_value
self
.
_object_index
[
object_id
]
=
{
'portal_type'
:
object_value
.
getPortalType
()}
def
_delOb
(
self
,
object_id
):
del
self
.
_object_dict
[
object_id
]
del
self
.
_object_index
[
object_id
]
security
.
declareProtected
(
Permissions
.
AccessContentsInformation
,
'objectValues'
)
def
objectValues
(
self
,
spec
=
None
,
meta_type
=
None
,
portal_type
=
None
,
sort_on
=
None
,
sort_order
=
None
,
checked_permission
=
None
,
**
kw
):
# Returns list of objects contained in this folder.
# (no docstring to prevent publishing)
if
meta_type
is
not
None
:
raise
NotImplementedError
object_list
=
self
.
_object_dict
.
values
()
if
portal_type
is
not
None
:
if
isinstance
(
portal_type
,
str
):
portal_type
=
(
portal_type
,)
object_list
=
[
self
.
_object_dict
[
key
]
for
key
in
self
.
_object_dict
.
keys
()
if
self
.
_object_index
[
key
][
'portal_type'
]
in
portal_type
]
if
checked_permission
is
not
None
:
checkPermission
=
getSecurityManager
().
checkPermission
object_list
=
[
o
for
o
in
object_list
if
checkPermission
(
checked_permission
,
o
)]
return
sortValueList
(
object_list
,
sort_on
,
sort_order
,
**
kw
)
product/ERP5Type/Core/Folder.py
View file @
2b13e39f
...
...
@@ -73,6 +73,7 @@ except ImportError:
class
HBTreeFolder2
:
pass
from
ERP5PersistentMappingFolder
import
ERP5PersistentMappingFolder
from
DateTime
import
DateTime
from
random
import
randint
...
...
@@ -536,10 +537,12 @@ class FolderMixIn(ExtensionClass.Base):
OFS_HANDLER
=
0
BTREE_HANDLER
=
1
HBTREE_HANDLER
=
2
PERSISTENT_MAPPING_HANDLER
=
3
InitializeClass
(
FolderMixIn
)
class
Folder
(
CopyContainer
,
CMFBTreeFolder
,
CMFHBTreeFolder
,
Base
,
FolderMixIn
):
class
Folder
(
CopyContainer
,
CMFBTreeFolder
,
CMFHBTreeFolder
,
ERP5PersistentMappingFolder
,
Base
,
FolderMixIn
):
"""
A Folder is a subclass of Base but not of XMLObject.
Folders are not considered as documents and are therefore
...
...
@@ -606,12 +609,14 @@ class Folder(CopyContainer, CMFBTreeFolder, CMFHBTreeFolder, Base, FolderMixIn):
description
=
None
# Per default we use BTree folder
_folder_handler
=
BTREE
_HANDLER
_folder_handler
=
PERSISTENT_MAPPING
_HANDLER
# Overload __init__ so that we do not take into account title
# This is required for test_23_titleIsNotDefinedByDefault
def
__init__
(
self
,
id
):
self
.
id
=
id
if
self
.
_folder_handler
==
PERSISTENT_MAPPING_HANDLER
:
ERP5PersistentMappingFolder
.
__init__
(
self
,
id
)
security
.
declarePublic
(
'newContent'
)
def
newContent
(
self
,
*
args
,
**
kw
):
...
...
@@ -736,13 +741,17 @@ class Folder(CopyContainer, CMFBTreeFolder, CMFHBTreeFolder, Base, FolderMixIn):
def
_initBTrees
(
self
):
if
self
.
_folder_handler
==
HBTREE_HANDLER
:
return
CMFHBTreeFolder
.
_initBTrees
(
self
)
el
se
:
el
if
self
.
_folder_handler
==
BTREE_HANDLER
:
return
CMFBTreeFolder
.
_initBTrees
(
self
)
else
:
raise
NotImplementedError
def
hashId
(
self
,
id
):
"""Return a hash of id
"""
if
self
.
_folder_handler
==
HBTREE_HANDLER
:
if
self
.
_folder_handler
==
PERSISTENT_MAPPING_HANDLER
:
return
ERP5PersistentMappingFolder
.
hashId
(
self
,
id
)
elif
self
.
_folder_handler
==
HBTREE_HANDLER
:
return
CMFHBTreeFolder
.
hashId
(
self
,
id
)
else
:
return
CMFBTreeFolder
.
hashId
(
self
,
id
)
...
...
@@ -750,7 +759,9 @@ class Folder(CopyContainer, CMFBTreeFolder, CMFHBTreeFolder, Base, FolderMixIn):
def
_populateFromFolder
(
self
,
source
):
"""Fill this folder with the contents of another folder.
"""
if
self
.
_folder_handler
==
HBTREE_HANDLER
:
if
self
.
_folder_handler
==
PERSISTENT_MAPPING_HANDLER
:
return
ERP5PersistentMappingFolder
.
_populateFromFolder
(
self
,
source
)
elif
self
.
_folder_handler
==
HBTREE_HANDLER
:
if
self
.
_htree
is
None
:
HBTreeFolder2Base
.
__init__
(
self
,
id
)
return
CMFHBTreeFolder
.
_populateFromFolder
(
self
,
source
)
...
...
@@ -762,13 +773,17 @@ class Folder(CopyContainer, CMFBTreeFolder, CMFHBTreeFolder, Base, FolderMixIn):
def
manage_fixCount
(
self
):
"""Calls self._fixCount() and reports the result as text.
"""
if
self
.
_folder_handler
==
HBTREE_HANDLER
:
if
self
.
_folder_handler
==
PERSISTENT_MAPPING_HANDLER
:
raise
NotImplementedError
elif
self
.
_folder_handler
==
HBTREE_HANDLER
:
return
CMFHBTreeFolder
.
manage_fixCount
(
self
)
else
:
return
CMFBTreeFolder
.
manage_fixCount
(
self
)
def
_fixCount
(
self
):
if
self
.
_folder_handler
==
HBTREE_HANDLER
:
if
self
.
_folder_handler
==
PERSISTENT_MAPPING_HANDLER
:
raise
NotImplementedError
elif
self
.
_folder_handler
==
HBTREE_HANDLER
:
return
CMFHBTreeFolder
.
_fixCount
(
self
)
else
:
return
CMFBTreeFolder
.
_fixCount
(
self
)
...
...
@@ -791,7 +806,9 @@ class Folder(CopyContainer, CMFBTreeFolder, CMFHBTreeFolder, Base, FolderMixIn):
def
manage_cleanup
(
self
):
"""Calls self._cleanup() and reports the result as text.
"""
if
self
.
_folder_handler
==
HBTREE_HANDLER
:
if
self
.
_folder_handler
==
PERSISTENT_MAPPING_HANDLER
:
raise
NotImplementedError
elif
self
.
_folder_handler
==
HBTREE_HANDLER
:
if
self
.
_htree
is
None
:
return
1
else
:
...
...
@@ -803,7 +820,9 @@ class Folder(CopyContainer, CMFBTreeFolder, CMFHBTreeFolder, Base, FolderMixIn):
return
CMFBTreeFolder
.
manage_cleanup
(
self
)
def
_cleanup
(
self
):
if
self
.
_folder_handler
==
HBTREE_HANDLER
:
if
self
.
_folder_handler
==
PERSISTENT_MAPPING_HANDLER
:
return
ERP5PersistentMappingFolder
.
_cleanup
(
self
)
elif
self
.
_folder_handler
==
HBTREE_HANDLER
:
if
self
.
_htree
is
None
:
return
1
else
:
...
...
@@ -818,7 +837,9 @@ class Folder(CopyContainer, CMFBTreeFolder, CMFHBTreeFolder, Base, FolderMixIn):
"""
Return the named object from the folder.
"""
if
self
.
_folder_handler
==
HBTREE_HANDLER
:
if
self
.
_folder_handler
==
PERSISTENT_MAPPING_HANDLER
:
return
ERP5PersistentMappingFolder
.
_getOb
(
self
,
id
,
*
args
,
**
kw
)
elif
self
.
_folder_handler
==
HBTREE_HANDLER
:
if
self
.
_htree
is
None
:
if
len
(
args
):
return
args
[
0
]
...
...
@@ -840,7 +861,9 @@ class Folder(CopyContainer, CMFBTreeFolder, CMFHBTreeFolder, Base, FolderMixIn):
def
_setOb
(
self
,
id
,
object
):
"""Store the named object in the folder.
"""
if
self
.
_folder_handler
==
HBTREE_HANDLER
:
if
self
.
_folder_handler
==
PERSISTENT_MAPPING_HANDLER
:
return
ERP5PersistentMappingFolder
.
_setOb
(
self
,
id
,
object
)
elif
self
.
_folder_handler
==
HBTREE_HANDLER
:
if
self
.
_htree
is
None
:
HBTreeFolder2Base
.
__init__
(
self
,
self
.
id
)
return
CMFHBTreeFolder
.
_setOb
(
self
,
id
,
object
)
...
...
@@ -852,7 +875,9 @@ class Folder(CopyContainer, CMFBTreeFolder, CMFHBTreeFolder, Base, FolderMixIn):
def
_delOb
(
self
,
id
):
"""Remove the named object from the folder.
"""
if
self
.
_folder_handler
==
HBTREE_HANDLER
:
if
self
.
_folder_handler
==
PERSISTENT_MAPPING_HANDLER
:
return
ERP5PersistentMappingFolder
.
_delOb
(
self
,
id
)
elif
self
.
_folder_handler
==
HBTREE_HANDLER
:
return
CMFHBTreeFolder
.
_delOb
(
self
,
id
)
else
:
return
CMFBTreeFolder
.
_delOb
(
self
,
id
)
...
...
@@ -860,7 +885,9 @@ class Folder(CopyContainer, CMFBTreeFolder, CMFHBTreeFolder, Base, FolderMixIn):
def
getBatchObjectListing
(
self
,
REQUEST
=
None
):
"""Return a structure for a page template to show the list of objects.
"""
if
self
.
_folder_handler
==
HBTREE_HANDLER
:
if
self
.
_folder_handler
==
PERSISTENT_MAPPING_HANDLER
:
raise
NotImplementedError
elif
self
.
_folder_handler
==
HBTREE_HANDLER
:
return
CMFHBTreeFolder
.
getBatchObjectListing
(
self
,
REQUEST
)
else
:
return
CMFBTreeFolder
.
getBatchObjectListing
(
self
,
REQUEST
)
...
...
@@ -868,14 +895,18 @@ class Folder(CopyContainer, CMFBTreeFolder, CMFHBTreeFolder, Base, FolderMixIn):
def
manage_object_workspace
(
self
,
ids
=
(),
REQUEST
=
None
):
'''Redirects to the workspace of the first object in
the list.'''
if
self
.
_folder_handler
==
HBTREE_HANDLER
:
if
self
.
_folder_handler
==
PERSISTENT_MAPPING_HANDLER
:
raise
NotImplementedError
elif
self
.
_folder_handler
==
HBTREE_HANDLER
:
return
CMFHBTreeFolder
.
manage_object_workspace
(
self
,
ids
,
REQUEST
)
else
:
return
CMFBTreeFolder
.
manage_object_workspace
(
self
,
ids
,
REQUEST
)
def
manage_main
(
self
,
*
args
,
**
kw
):
''' List content.'''
if
self
.
_folder_handler
==
HBTREE_HANDLER
:
if
self
.
_folder_handler
==
PERSISTENT_MAPPING_HANDLER
:
return
ERP5PersistentMappingFolder
.
manage_main
.
__of__
(
self
)(
self
,
*
args
,
**
kw
)
elif
self
.
_folder_handler
==
HBTREE_HANDLER
:
return
CMFHBTreeFolder
.
manage_main
.
__of__
(
self
)(
self
,
*
args
,
**
kw
)
else
:
return
CMFBTreeFolder
.
manage_main
.
__of__
(
self
)(
self
,
*
args
,
**
kw
)
...
...
@@ -883,14 +914,18 @@ class Folder(CopyContainer, CMFBTreeFolder, CMFHBTreeFolder, Base, FolderMixIn):
def
tpValues
(
self
):
"""Ensures the items don't show up in the left pane.
"""
if
self
.
_folder_handler
==
HBTREE_HANDLER
:
if
self
.
_folder_handler
==
PERSISTENT_MAPPING_HANDLER
:
return
ERP5PersistentMappingFolder
.
tpValues
(
self
)
elif
self
.
_folder_handler
==
HBTREE_HANDLER
:
return
CMFHBTreeFolder
.
tpValues
(
self
)
else
:
return
CMFBTreeFolder
.
tpValues
(
self
)
def
objectCount
(
self
):
"""Returns the number of items in the folder."""
if
self
.
_folder_handler
==
HBTREE_HANDLER
:
if
self
.
_folder_handler
==
PERSISTENT_MAPPING_HANDLER
:
return
ERP5PersistentMappingFolder
.
objectCount
(
self
)
elif
self
.
_folder_handler
==
HBTREE_HANDLER
:
if
self
.
_htree
is
None
:
return
0
return
CMFHBTreeFolder
.
objectCount
(
self
)
...
...
@@ -902,7 +937,9 @@ class Folder(CopyContainer, CMFBTreeFolder, CMFHBTreeFolder, Base, FolderMixIn):
def
has_key
(
self
,
id
):
"""Indicates whether the folder has an item by ID.
"""
if
self
.
_folder_handler
==
HBTREE_HANDLER
:
if
self
.
_folder_handler
==
PERSISTENT_MAPPING_HANDLER
:
return
ERP5PersistentMappingFolder
.
has_key
(
self
,
id
)
elif
self
.
_folder_handler
==
HBTREE_HANDLER
:
if
self
.
_htree
is
None
:
return
False
return
CMFHBTreeFolder
.
has_key
(
self
,
id
)
...
...
@@ -914,13 +951,17 @@ class Folder(CopyContainer, CMFBTreeFolder, CMFHBTreeFolder, Base, FolderMixIn):
def
getTreeIdList
(
self
,
htree
=
None
):
""" recursively build a list of btree ids
"""
if
self
.
_folder_handler
==
HBTREE_HANDLER
:
if
self
.
_folder_handler
==
PERSISTENT_MAPPING_HANDLER
:
raise
NotImplementedError
elif
self
.
_folder_handler
==
HBTREE_HANDLER
:
return
CMFHBTreeFolder
.
getTreeIdList
(
self
,
htree
)
else
:
return
CMFBTreeFolder
.
getTreeIdList
(
self
,
htree
)
def
objectIds
(
self
,
spec
=
None
,
**
kw
):
if
self
.
_folder_handler
==
HBTREE_HANDLER
:
if
self
.
_folder_handler
==
PERSISTENT_MAPPING_HANDLER
:
return
ERP5PersistentMappingFolder
.
objectIds
(
self
,
spec
=
spec
,
**
kw
)
elif
self
.
_folder_handler
==
HBTREE_HANDLER
:
if
self
.
_htree
is
None
:
return
[]
assert
spec
is
None
...
...
@@ -934,7 +975,9 @@ class Folder(CopyContainer, CMFBTreeFolder, CMFHBTreeFolder, Base, FolderMixIn):
return
CMFBTreeFolder
.
objectIds
(
self
,
spec
)
def
objectItems
(
self
,
spec
=
None
,
**
kw
):
if
self
.
_folder_handler
==
HBTREE_HANDLER
:
if
self
.
_folder_handler
==
PERSISTENT_MAPPING_HANDLER
:
return
ERP5PersistentMappingFolder
.
objectItems
(
self
,
spec
=
spec
)
elif
self
.
_folder_handler
==
HBTREE_HANDLER
:
if
self
.
_htree
is
None
:
return
[]
assert
spec
is
None
...
...
@@ -948,7 +991,9 @@ class Folder(CopyContainer, CMFBTreeFolder, CMFHBTreeFolder, Base, FolderMixIn):
return
CMFBTreeFolder
.
objectItems
(
self
,
spec
)
def
objectIds_d
(
self
,
t
=
None
):
if
self
.
_folder_handler
==
HBTREE_HANDLER
:
if
self
.
_folder_handler
==
PERSISTENT_MAPPING_HANDLER
:
return
ERP5PersistentMappingFolder
.
objectIds_d
(
self
,
t
)
elif
self
.
_folder_handler
==
HBTREE_HANDLER
:
if
self
.
_htree
is
None
:
return
{}
return
CMFHBTreeFolder
.
objectIds_d
(
self
,
t
)
...
...
@@ -958,13 +1003,17 @@ class Folder(CopyContainer, CMFBTreeFolder, CMFHBTreeFolder, Base, FolderMixIn):
return
CMFBTreeFolder
.
objectIds_d
(
self
,
t
)
def
_checkId
(
self
,
id
,
allow_dup
=
0
):
if
self
.
_folder_handler
==
HBTREE_HANDLER
:
if
self
.
_folder_handler
==
PERSISTENT_MAPPING_HANDLER
:
return
ERP5PersistentMappingFolder
.
_checkId
(
self
,
id
,
allow_dup
)
elif
self
.
_folder_handler
==
HBTREE_HANDLER
:
return
CMFHBTreeFolder
.
_checkId
(
self
,
id
,
allow_dup
)
else
:
return
CMFBTreeFolder
.
_checkId
(
self
,
id
,
allow_dup
)
def
_setObject
(
self
,
*
args
,
**
kw
):
if
self
.
_folder_handler
==
HBTREE_HANDLER
:
if
self
.
_folder_handler
==
PERSISTENT_MAPPING_HANDLER
:
return
ERP5PersistentMappingFolder
.
_setObject
(
self
,
*
args
,
**
kw
)
elif
self
.
_folder_handler
==
HBTREE_HANDLER
:
if
self
.
_htree
is
None
:
HBTreeFolder2Base
.
__init__
(
self
,
self
.
id
)
return
CMFHBTreeFolder
.
_setObject
(
self
,
*
args
,
**
kw
)
...
...
@@ -977,7 +1026,9 @@ class Folder(CopyContainer, CMFBTreeFolder, CMFHBTreeFolder, Base, FolderMixIn):
"""
Return the named object from the folder.
"""
if
self
.
_folder_handler
==
HBTREE_HANDLER
:
if
self
.
_folder_handler
==
PERSISTENT_MAPPING_HANDLER
:
return
ERP5PersistentMappingFolder
.
get
(
self
,
id
,
default
)
elif
self
.
_folder_handler
==
HBTREE_HANDLER
:
return
CMFHBTreeFolder
.
get
(
self
,
id
,
default
)
else
:
return
CMFBTreeFolder
.
get
(
self
,
id
,
default
)
...
...
@@ -989,13 +1040,18 @@ class Folder(CopyContainer, CMFBTreeFolder, CMFHBTreeFolder, Base, FolderMixIn):
The IDs are sequential to optimize access to objects
that are likely to have some relation.
"""
if
self
.
_folder_handler
==
HBTREE_HANDLER
:
if
self
.
_folder_handler
==
PERSISTENT_MAPPING_HANDLER
:
raise
NotImplementedError
elif
self
.
_folder_handler
==
HBTREE_HANDLER
:
return
CMFHBTreeFolder
.
generateId
(
self
,
prefix
,
suffix
,
rand_ceiling
)
else
:
return
CMFBTreeFolder
.
generateId
(
self
,
prefix
,
suffix
,
rand_ceiling
)
def
__getattr__
(
self
,
name
):
if
self
.
_folder_handler
==
HBTREE_HANDLER
:
if
self
.
_folder_handler
==
PERSISTENT_MAPPING_HANDLER
:
return
ERP5PersistentMappingFolder
.
__getattr__
(
self
,
name
)
#return ERP5PersistentMappingFolder.__getattr__(self, name)
elif
self
.
_folder_handler
==
HBTREE_HANDLER
:
return
CMFHBTreeFolder
.
__getattr__
(
self
,
name
)
else
:
if
self
.
_tree
is
None
:
...
...
@@ -1003,7 +1059,9 @@ class Folder(CopyContainer, CMFBTreeFolder, CMFHBTreeFolder, Base, FolderMixIn):
return
CMFBTreeFolder
.
__getattr__
(
self
,
name
)
def
__len__
(
self
):
if
self
.
_folder_handler
==
HBTREE_HANDLER
:
if
self
.
_folder_handler
==
PERSISTENT_MAPPING_HANDLER
:
return
ERP5PersistentMappingFolder
.
__len__
(
self
)
elif
self
.
_folder_handler
==
HBTREE_HANDLER
:
if
self
.
_htree
is
None
:
return
0
return
CMFHBTreeFolder
.
__len__
(
self
)
...
...
@@ -1013,7 +1071,9 @@ class Folder(CopyContainer, CMFBTreeFolder, CMFHBTreeFolder, Base, FolderMixIn):
return
CMFBTreeFolder
.
__len__
(
self
)
def
keys
(
self
,
*
args
,
**
kw
):
if
self
.
_folder_handler
==
HBTREE_HANDLER
:
if
self
.
_folder_handler
==
PERSISTENT_MAPPING_HANDLER
:
return
ERP5PersistentMappingFolder
.
keys
(
self
,
*
args
,
**
kw
)
elif
self
.
_folder_handler
==
HBTREE_HANDLER
:
if
self
.
_htree
is
None
:
return
[]
return
CMFHBTreeFolder
.
keys
(
self
,
*
args
,
**
kw
)
...
...
@@ -1023,7 +1083,9 @@ class Folder(CopyContainer, CMFBTreeFolder, CMFHBTreeFolder, Base, FolderMixIn):
return
CMFBTreeFolder
.
keys
(
self
,
*
args
,
**
kw
)
def
values
(
self
,
*
args
,
**
kw
):
if
self
.
_folder_handler
==
HBTREE_HANDLER
:
if
self
.
_folder_handler
==
PERSISTENT_MAPPING_HANDLER
:
return
ERP5PersistentMappingFolder
.
values
(
self
,
*
args
,
**
kw
)
elif
self
.
_folder_handler
==
HBTREE_HANDLER
:
if
self
.
_htree
is
None
:
return
[]
return
CMFHBTreeFolder
.
values
(
self
,
*
args
,
**
kw
)
...
...
@@ -1033,7 +1095,9 @@ class Folder(CopyContainer, CMFBTreeFolder, CMFHBTreeFolder, Base, FolderMixIn):
return
CMFBTreeFolder
.
values
(
self
,
*
args
,
**
kw
)
def
items
(
self
,
*
args
,
**
kw
):
if
self
.
_folder_handler
==
HBTREE_HANDLER
:
if
self
.
_folder_handler
==
PERSISTENT_MAPPING_HANDLER
:
return
ERP5PersistentMappingFolder
.
items
(
self
,
*
args
,
**
kw
)
elif
self
.
_folder_handler
==
HBTREE_HANDLER
:
if
self
.
_htree
is
None
:
return
[]
return
CMFHBTreeFolder
.
items
(
self
,
*
args
,
**
kw
)
...
...
@@ -1043,7 +1107,9 @@ class Folder(CopyContainer, CMFBTreeFolder, CMFHBTreeFolder, Base, FolderMixIn):
return
CMFBTreeFolder
.
items
(
self
,
*
args
,
**
kw
)
def
iteritems
(
self
,
*
args
,
**
kw
):
if
self
.
_folder_handler
==
HBTREE_HANDLER
:
if
self
.
_folder_handler
==
PERSISTENT_MAPPING_HANDLER
:
return
self
.
_object_dict
.
iteritem
(
*
args
,
**
kw
)
elif
self
.
_folder_handler
==
HBTREE_HANDLER
:
result
=
CMFHBTreeFolder
.
_htree_iteritems
(
self
,
*
args
,
**
kw
)
else
:
if
self
.
_tree
is
None
:
...
...
@@ -1052,7 +1118,9 @@ class Folder(CopyContainer, CMFBTreeFolder, CMFHBTreeFolder, Base, FolderMixIn):
return
NullIter
(((
x
,
y
.
__of__
(
self
))
for
x
,
y
in
result
))
def
hasObject
(
self
,
id
):
if
self
.
_folder_handler
==
HBTREE_HANDLER
:
if
self
.
_folder_handler
==
PERSISTENT_MAPPING_HANDLER
:
return
ERP5PersistentMappingFolder
.
hasObject
(
self
,
id
)
elif
self
.
_folder_handler
==
HBTREE_HANDLER
:
if
self
.
_htree
is
None
:
return
False
return
CMFHBTreeFolder
.
hasObject
(
self
,
id
)
...
...
@@ -1520,7 +1588,12 @@ class Folder(CopyContainer, CMFBTreeFolder, CMFHBTreeFolder, Base, FolderMixIn):
# (no docstring to prevent publishing)
if
meta_type
is
not
None
:
spec
=
meta_type
if
self
.
_folder_handler
==
BTREE_HANDLER
:
if
self
.
_folder_handler
==
PERSISTENT_MAPPING_HANDLER
:
return
ERP5PersistentMappingFolder
.
objectValues
(
self
,
spec
=
spec
,
portal_type
=
portal_type
,
sort_on
=
sort_on
,
sort_order
=
sort_order
,
checked_permission
=
checked_permission
)
elif
self
.
_folder_handler
==
BTREE_HANDLER
:
if
self
.
_tree
is
None
:
return
[]
object_list
=
CMFBTreeFolder
.
objectValues
(
self
,
spec
=
spec
)
...
...
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