def generatePropertyAccessorNameList(property): """ Generates the possible accessor names for given property. FIXME: Should not exist here, but as accessor generation system. """ from Products.ERP5Type.Utils import UpperCase res = [] cased_id = UpperCase(property['id']) for hidden in ('', '_'): for getset in ('get', 'set', 'has'): # 'is', for default in ('', 'Default', 'Translated'): for value in ('', 'Value', 'TranslationDomain'): for multivalued in ('', 'List', 'Set'): res.append('%s%s%s%s%s%s' % (hidden, getset, default, cased_id, value, multivalued)) if property.has_key('acquired_property_id') and \ property['type'] == 'content': for aq_property_id in property['acquired_property_id']: cased_id = UpperCase('%s_%s' % (property['id'], aq_property_id)) for hidden in ('', '_'): for getset in ('get', 'set'): for default in ('', 'Default'): for multivalued in ('', 'List'): res.append('%s%s%s%s%s' % (hidden, getset, default, cased_id, multivalued)) return res
def generateCategoryAccessorNameList(category): """ Generates the possible accessor names for given category. FIXME: Should not exist here, but as accessor generation system. """ from Products.ERP5Type.Utils import UpperCase cased_id = UpperCase(category) res = [ '%s%sIds' % (cased_id[0].lower(), cased_id[1:]), '%s%sValues' % (cased_id[0].lower(), cased_id[1:]) ] for hidden in ('', '_'): for default in ('', 'Default'): for multivalued in ('', 'List', 'Set'): for attribute in ('', 'TranslatedTitle', 'Uid', 'LogicalPath', 'Id', 'TitleOrId', 'Reference', 'Title'): res.append('%sget%s%s%s%s' % (hidden, default, cased_id, attribute, multivalued)) for attribute in ('', 'Value', 'Uid'): res.append('%sset%s%s%s%s' % (hidden, default, cased_id, attribute, multivalued)) return res
def applyCategoryAsRelatedValueAccessor(accessor_holder, category_id, category_tool): """ Take one category_id, generate and apply all related value accessors implied by this category, and apply/set them to the accessor_holder """ cat_object = category_tool.get(category_id, None) if cat_object is not None: read_permission = Permissions.__dict__.get( cat_object.getReadPermission(), Permissions.AccessContentsInformation) else: read_permission = Permissions.AccessContentsInformation uppercase_category_id = UpperCase(category_id) # two special cases accessor_name = uppercase_category_id[0].lower( ) + uppercase_category_id[1:] accessor = RelatedValue.ListGetter(accessor_name + 'RelatedValues', category_id) accessor_holder.registerAccessor(accessor, read_permission) accessor = RelatedValue.IdListGetter(accessor_name + 'RelatedIds', category_id) accessor_holder.registerAccessor(accessor, read_permission) for accessor_class, accessor_name_list in related_accessor_definition_dict.items( ): for accessor_name in accessor_name_list: accessor = accessor_class(accessor_name % uppercase_category_id, category_id) accessor_holder.registerAccessor(accessor, read_permission)
def generatePortalTypeAccessors(cls, site, portal_type_category_list): category_tool = getattr(site, 'portal_categories', None) for category_id in portal_type_category_list: # we need to generate only categories defined on portal type CategoryProperty.applyDefinitionOnAccessorHolder( cls, category_id, category_tool) portal_workflow = getattr(site, 'portal_workflow', None) if portal_workflow is None: if not getattr(site, '_v_bootstrapping', False): LOG( "ERP5Type.Dynamic", WARNING, "Could not generate workflow methods for %s" % cls.__name__) else: initializePortalTypeDynamicWorkflowMethods(cls, portal_workflow) # portal type group methods, isNodeType, isResourceType... from Products.ERP5Type.ERP5Type import ERP5TypeInformation # XXX possible optimization: # generate all methods on Base accessor holder, with all methods # returning False, and redefine on portal types only those returning True, # aka only those for the group they belong to for group in ERP5TypeInformation.defined_group_list: value = cls.__name__ in site._getPortalGroupedTypeSet(group) accessor_name = 'is' + UpperCase(group) + 'Type' method = ConstantGetter(accessor_name, group, value) cls.registerAccessor(method, Permissions.AccessContentsInformation) from Products.ERP5Type.Cache import initializePortalCachingProperties initializePortalCachingProperties(site)
def Listbox_getBrainValue(self, brain, obj, select, can_check_local_property, editable_field=None): """ ListBox.py / getValueList """ tales = False # Use a widget, if any. if editable_field is not None: # XXX we need to take care of whether the editable field is # a proxy field or not, because a proxy field may inherit a # tales expression from a template field, and the API is not # unified. get_tales = getattr(editable_field, 'get_recursive_tales', editable_field.get_tales) tales = get_tales('default') if tales: default_field_value = editable_field.__of__(obj).get_value('default', cell=brain) # If a tales expression is not defined, get a skin, an accessor or a property. if not tales: if (can_check_local_property) and (getattr(aq_self(brain), select, None) is not None): default_field_value = getattr(brain, select) else: try: # Get the trailing part. try: property_id = select[select.rindex('.') + 1:] except ValueError: property_id = select try: accessor_name = 'get%s' % UpperCase(property_id) # Make sure the object have the attribute, and this is not # acquired, but still get the attribute on the acquisition wrapper getattr(aq_base(obj), accessor_name) default_field_value = getattr(obj, accessor_name) except AttributeError: default_field_value = getattr(obj, property_id, None) except (AttributeError, KeyError, Unauthorized): default_field_value = None # If the value is callable, evaluate it. if callable(default_field_value): try: try: default_field_value = default_field_value(brain=brain) except TypeError: default_field_value = default_field_value() except (ConflictError, RuntimeError): raise except Exception: default_field_value = None # Listbox.py forces result to be an empty string # This is not needed in hal # if default_field_value is None: # default_field_value = '' return default_field_value
def _getPropertyFromDocument(self, document, property_id): if document is None: return None # XXX here we don't use Base.getProperty() but try to call accessor # directly to make acquired property # (eg. payment_condition_efficiency) working. accessor_name = 'get' + UpperCase(property_id) return getattr(document, accessor_name)()
def _applyRoundingModel(self, rounding_model): document = self.__dict__['_ob'] roundValue = rounding_model.roundValue def decorate(original_getter): return lambda *args, **kw: roundValue(original_getter(*args, **kw)) for property_id in rounding_model.getRoundedPropertyIdList(): assert property_id not in self._rounding_model_dict self._rounding_model_dict[property_id] = rounding_model getter_name = 'get%s' % UpperCase(property_id) getter = getattr(document, getter_name, None) setter_name = '_set%s' % UpperCase(property_id) setter = getattr(document, setter_name, None) if setter is not None: # round the property value itself setter(roundValue(getter())) # tell getProperty not to round it again self._rounded_value_set.add(property_id) elif getter is not None: # cannot round the property value now so do it dynamically setattr(self, getter_name, decorate(getter))
def _applyRangeOnAccessorHolder(cls, property_dict, accessor_holder, kind, portal): acquisition_accessor_id = property_dict.get('acquisition_accessor_id', None) if acquisition_accessor_id is not None: property_dict['acquisition_accessor_id'] = '%sRange%s' % \ (acquisition_accessor_id, kind.capitalize()) property_dict['alt_accessor_id'] = ('get' + \ UpperCase(property_dict['reference']),) super(AcquiredProperty, cls)._applyRangeOnAccessorHolder(property_dict, accessor_holder, kind, portal)
def _applyDefinitionFormatDictOnAccessorHolder(reference, definition_dict, accessor_holder, argument_list, permission): """ Apply a definition dict, a format string defining the accessor name as the key (formatted with the given reference) and the accessor class to be used as the value, on the given accessor holder class. The accessor class given in the definition dict is instanciated with the given argument list and the the accessor is protected using the given permission (which may be either read if it is a getter or tester, or write if it is a setter), it is then registered on the accessor holder. For most cases, the reference is used in the accessor name but there are exceptions, such as translation accessors. @param reference: Reference to be used to format accessor name @type reference: str @param definition_dict: Definition of accessors being created @type definition_dict: dict @param accessor_holder: Accessor holder to applied the accessors on @type accessor_holder: Products.ERP5Type.dynamic.accessor_holder.AccessorHolderType @param argument_list: Arguments to be given to the accessor class constructor @type argument_list: list @param permission: Permission to be applied on the accessor @type permission: str """ uppercase_reference = UpperCase(reference) for format, klass in definition_dict.iteritems(): name = format % uppercase_reference instance = klass(name, reference, *argument_list) accessor_holder.registerAccessor(instance, permission) # Public setters actually just calls the private one and then # perform a re-indexing if name.startswith('_set'): instance = Alias.Reindex(name[1:], name) accessor_holder.registerAccessor(instance, permission)
from Products.ERP5Type.Utils import UpperCase portal = context.getPortalObject() workflow_tool = portal.portal_workflow for workflow in workflow_tool.getWorkflowsFor(context): # Exclude interaction workflows and edit_workflow if workflow.state_var != 'state': return getattr(context, 'getTranslated%sTitle' % UpperCase(workflow.state_var))()
def applyDefinitionOnAccessorHolder(cls, property_dict, accessor_holder, portal, do_register=True): """ Apply getters, setters and testers for a list property or a primitive property. This class method may be called to apply a property dictionnary on an accessor holder. While applyOnAccessorHolder is commonly used to apply a property on an *existing* ZODB Property Sheet, this method can be used to apply accessors from a Property not defined in a ZODB Property Sheet. The property dictionnary must define all the attributes listed in the class docstring. The TALES Expression in the given property dict are considered to have been already evaluated, as performed through applyOnAccessorHolder by asDict method. @param property_dict: Property to generate getter for @type property_dict: dict @param accessor_holder: Accessor holder to applied the accessors on @type accessor_holder: Products.ERP5Type.dynamic.accessor_holder.AccessorHolderType @param portal: Portal object @type portal: Products.ERP5.ERP5Site.ERP5Site @param do_register: Register the property in the Zope property map @type do_register: bool """ # Some attributes are required to generate accessors, if they have # not been set properly, then don't generate them at all for this # Property if property_dict['reference'] is None or \ property_dict['elementary_type'] is None or \ property_dict['elementary_type'] not in type_definition: raise ValueError("Invalid type or reference") # Create range accessors if relevant if property_dict['range']: for kind in ('min', 'max'): cls._applyRangeOnAccessorHolder(property_dict.copy(), accessor_holder, kind, portal) # Create translation accessors if relevant if property_dict['translatable']: translated_property_dict = property_dict.copy() if translated_property_dict['property_default'] is None: translated_property_dict['property_default'] = '' # Make accessors such as getTranslatedProperty translated_reference = 'translated_' + property_dict['reference'] argument_list = (translated_property_dict['reference'], translated_property_dict['elementary_type'], None, translated_property_dict['property_default']) cls._applyDefinitionFormatDictOnAccessorHolder( translated_reference, cls._translated_getter_definition_dict, accessor_holder, argument_list, translated_property_dict['read_permission']) cls._applyTranslationLanguageOnAccessorHolder( translated_property_dict, accessor_holder, portal) # make accessor to translation_domain # first create default one as a normal property translation_domain_reference = translated_property_dict['reference'] + \ '_translation_domain' translation_domain_property_dict = { 'reference': translation_domain_reference, 'elementary_type': 'string', 'property_default': '', 'multivalued': False, 'storage_id': None, 'range': False, 'translatable': False, 'read_permission': translated_property_dict['read_permission'], 'write_permission': translated_property_dict['write_permission'] } # This will always be a StandardProperty, so avoid calling # super() here StandardProperty.applyDefinitionOnAccessorHolder( translation_domain_property_dict, accessor_holder, portal, do_register=False) # Then override getPropertyTranslationDomain accessor accessor = Translation.PropertyTranslationDomainGetter( 'get' + UpperCase(translation_domain_reference), translation_domain_reference, 'string', property_dict['translation_domain']) accessor_holder.registerAccessor( accessor, translated_property_dict['read_permission']) # After applying specific getters, setters and testers, apply # common getters, setters and testers cls._applyGetterDefinitionDictOnAccessorHolder(property_dict, accessor_holder) cls._applySetterDefinitionDictOnAccessorHolder(property_dict, accessor_holder) cls._applyTesterDefinitionDictOnAccessorHolder(property_dict, accessor_holder) # By default, register the property as a Zope property map, by # adding it to _properties, which will be later used by # PropertyManager if do_register: property_map = cls._asPropertyMap(property_dict) if property_map: accessor_holder._properties.append(property_map)
from ZODB.POSException import ConflictError from zExceptions import Unauthorized method = context.z_catalog_fulltext_list property_list = method.arguments_src.split() parameter_dict = {x: [] for x in property_list} for group_object in object_list: tmp_dict = {} try: obj = group_object.object for property in property_list: getter = getattr(obj, property, None) if callable(getter): value = getter() else: value = getattr(obj, 'get%s' % UpperCase(property))() tmp_dict[property] = value except ConflictError: raise except Unauthorized: # should happen in tricky testERP5Catalog tests only # Fake activity success: if indexation cannot View document, ignore it. group_object.result = None except Exception: group_object.raised() else: for property, value in tmp_dict.iteritems(): parameter_dict[property].append(value) group_object.result = None if parameter_dict: return method(**parameter_dict)
def _applyTranslationAcquiredOnAccessorHolder(cls, property_dict, accessor_holder, portal): try: localizer = portal._getOb('Localizer') except AttributeError: # TODO: should pbe merged with StandardProperty? if not getattr(portal, '_v_bootstrapping', False): LOG("ERP5Type.Core.StandardProperty", WARNING, "Localizer is missing. Accessors can not be generated") return for acquired_property_id in property_dict[ 'content_acquired_property_id']: key = 'translated_' + acquired_property_id # Language-dependent accessors for language in localizer.get_languages(): language_key = language.replace('-', '_') + '_' + key capitalised_composed_id = UpperCase("%s_%s" % \ (property_dict['reference'], language_key)) cls._applyTranslationAcquiredGetterDefinitionDictOnAccessorHolder( capitalised_composed_id, language_key, property_dict, accessor_holder) setter_instance = AcquiredPropertyAccessor.DefaultSetter( '_set' + capitalised_composed_id, language_key, property_dict['elementary_type'], property_dict['content_portal_type'], language_key, property_dict['acquisition_base_category'], property_dict['acquisition_portal_type'], property_dict['acquisition_accessor_id'], property_dict['acquisition_copy_value'], property_dict['acquisition_mask_value'], property_dict['storage_id'], property_dict['alt_accessor_id'], property_dict['acquisition_object_id'], (property_dict['elementary_type'] in list_types or \ property_dict['multivalued']), (property_dict['elementary_type'] == 'tales')) accessor_holder.registerAccessor( setter_instance, property_dict['write_permission']) alias_reindex_setter = Alias.Reindex( 'set' + capitalised_composed_id, '_set' + capitalised_composed_id) accessor_holder.registerAccessor( alias_reindex_setter, property_dict['write_permission']) alias_reindex_setter = Alias.Reindex( 'setDefault' + capitalised_composed_id, '_set' + capitalised_composed_id) accessor_holder.registerAccessor( alias_reindex_setter, property_dict['write_permission']) # Language-independent accessors if acquired_property_id in \ property_dict['content_translation_acquired_property_id']: capitalised_composed_id = UpperCase('%s_%s' % \ (property_dict['reference'], key)) cls._applyTranslationAcquiredGetterDefinitionDictOnAccessorHolder( capitalised_composed_id, key, property_dict, accessor_holder)
def _getMessage(self, message_id): """ Get the message corresponding to this message_id. """ return getattr(self, 'get' + UpperCase(message_id))()
def applyDefinitionOnAccessorHolder(cls, accessor_holder, category_id, portal): try: cat_object = portal.portal_categories._getOb(category_id) except KeyError: if portal.hasObject('portal_categories'): LOG("ERP5Type.Core.CategoryProperty", WARNING, "Base Category %r is missing. Accessors can not be generated." % \ category_id) return except TypeError: # category_id is None raise ValueError("Invalid category reference") # Create free text accessors. # XXX These are only for backward compatibility. storage_id = None if category_id == 'group': storage_id = 'group' elif category_id == 'site': storage_id = 'location' property_dict = { 'reference': '%s_free_text' % category_id, 'elementary_type': 'text', 'property_default': '', 'multivalued': False, 'storage_id': storage_id, 'range': False, 'translatable': False, 'description': 'free text to specify %s' % category_id, 'read_permission': Permissions.AccessContentsInformation, 'write_permission': Permissions.ModifyPortalContent } StandardProperty.applyDefinitionOnAccessorHolder(property_dict, accessor_holder, portal, do_register=False) # Get read and write permission read_permission = Permissions.__dict__.get( cat_object.getReadPermission(), Permissions.AccessContentsInformation) write_permission = Permissions.__dict__.get( cat_object.getWritePermission(), Permissions.ModifyPortalContent) # Actually create accessors uppercase_category_id = UpperCase(category_id) # three special cases accessor = Category.Tester('has' + uppercase_category_id, category_id) accessor_holder.registerAccessor(accessor, read_permission) accessor_name = uppercase_category_id[0].lower( ) + uppercase_category_id[1:] accessor = Value.ListGetter(accessor_name + 'Values', category_id) accessor_holder.registerAccessor(accessor, read_permission) accessor = Value.IdListGetter(accessor_name + 'Ids', category_id) accessor_holder.registerAccessor(accessor, read_permission) # then getters for id_format, accessor_class in cls.getter_definition_dict.iteritems( ): accessor_name = id_format % uppercase_category_id # XXX getSourceReference/getDestinationReference are already generated by # 'source_reference' and 'destination_reference' standard properties. To # prevent name conflict, we don't generate them as a category accessor. if not (SOURCE_DESTINATION_REFERENCE_LEGACY and accessor_name in ('getSourceReference', 'getDestinationReference')): public_accessor = accessor_class(accessor_name, category_id) accessor_holder.registerAccessor(public_accessor, read_permission) # create the private getter on the fly instead of having a definition dict # that's twice the size for the same info accessor_name = '_category' + accessor_name[0].upper( ) + accessor_name[1:] private_accessor = accessor_class(accessor_name, category_id) accessor_holder.registerAccessor(private_accessor, read_permission) # and setters for id_format, accessor_class in cls.setter_definition_dict.iteritems( ): accessor_name = id_format % uppercase_category_id # XXX setSourceReference/setDestinationReference are already generated by # 'source_reference' and 'destination_reference' standard properties. To # prevent name conflict, we don't generate them as a category accessor. if SOURCE_DESTINATION_REFERENCE_LEGACY and accessor_name in ( 'setSourceReference', 'setDestinationReference'): continue accessor = accessor_class(accessor_name, category_id) accessor_holder.registerAccessor(accessor, write_permission) # TODO: merge with StandardProperty if accessor_name.startswith('_set'): accessor = Alias.Reindex(accessor_name[1:], accessor_name) accessor_holder.registerAccessor(accessor, write_permission) # Only add the category ID if it is not already in _categories, # which may happen when getting the categories with acquisition if category_id not in accessor_holder._categories: accessor_holder._categories.append(category_id)