def get_aq_provider(obj): parent = obj.aq_parent if parent is app: raise SchemaEditorError(self.translate('atse_no_provider', default="No Schema provider found")) if ISchemaEditor.providedBy(parent): return parent else: return get_aq_provider(parent)
def lookup_provider(self): """ First searches for parent provider then checks tool """ provider = None try: provider = self.aq_parent if not ISchemaEditor.providedBy(provider): if provider.__class__.__name__ == 'FactoryTool': return provider.aq_parent raise SchemaEditorError, '' # We redirect lookup per default to the tool except SchemaEditorError: tool = getToolByName(self, config.TOOL_NAME, None) if not tool: raise LookupError('Tool %s for managing schema not found!' % config.TOOL_NAME) provider = tool return provider
def Schema(self, schema_id=None): """ Retrieve schema from parent object. The client class should override the method as Schema(self) and then call his method of the baseclass with the corresponding schema_id. """ # Schema() seems to be called during the construction phase when there is # no acquisition context. So we return the default schema itself. # ATT: mind the difference btn 'hasattr' and 'shasattr' (latter strips acq) if not hasattr(self, 'aq_parent') or self.id.find('atse-ptypedummy')>=0: if shasattr(self, 'schema'): return self._wrap_schema(self.schema) else: raise ValueError('Instance has no "schema" attribute defined') provider = self.lookup_provider() if not ISchemaEditor.providedBy(provider): raise SchemaEditorError, 'Provider -- %s -- can not be recognized as Archetypes Schema Editor! Perhaps you are using ParentManagedSchema derived objects with Tool. A tool can only manage ToolManagedSchema (ParentOrToolManagedSchema) derived objects.' % str(provider).replace('<', '').replace('>','') if not self.lookup_provider().atse_isSchemaRegistered(self.portal_type): return self._wrap_schema(self.schema) # If we're called by the generated methods we can not rely on # the id and need to check for portal_type if not schema_id: schema_id = self.portal_type # Otherwise get the schema from the parent through # acquisition and assign it to a volatile attribute for performance # reasons self._v_schema = getattr(self, '_v_schema', None) if self._v_schema is None: # looking for changes in the schema held by the object LOG('ATSchemaEditorNG', INFO, 'Looking up changes via lookupChanges() - _v_schema is None') self._v_schema = self._lookupChanges(schema_id) if not shasattr(self, '_md'): self.initializeArchetype() for field in self._v_schema.fields(): ########################################################## # Fake accessor and mutator methods ########################################################## # XXX currently only honoring explicitly specified mutators # or accessors if the method exists on the object. if # the methods are autogenerated the specified names will # not be honored. name = field.getName() def atse_get_method(self=self, name=name, *args, **kw): return self.getField(name).get(self, **kw) def atse_getRaw_method(self=self, name=name, *args, **kw): return self.getField(name).getRaw(self, **kw) # workaround for buggy widget/keyword AT template that # uses field.accessor as catalog index name *grrrr* # XXX find another way to fix that if name != 'subject': accessor_name = getattr(field, 'accessor', None) if accessor_name and shasattr(self, accessor_name): pass # the accessor exists, we're cool else: v_name = '_v_%s_accessor' % name accessor_name = v_name setattr(self, v_name, atse_get_method) field.accessor = accessor_name # the edit accessor and the regular accessor can be the # same in most cases, but not for ReferenceFields # XXX any other cases? # test for special cases where there is no # getter with conformant naming scheme con_name = capitalize(field.getName()) dogenerate = not shasattr(self, 'get%s' % con_name) edit_accessor_name = getattr(field, 'edit_accessor', None) if edit_accessor_name and shasattr(self, edit_accessor_name) and not dogenerate: pass # the edit_accessor_name exists, we're cool else: edit_v_name = '_v_%s_edit_accessor' % name edit_accessor_name = edit_v_name field_type = str(field.type).upper() if field_type == 'REFERENCE': setattr(self, edit_accessor_name, atse_getRaw_method) else: setattr(self, edit_accessor_name, atse_get_method) field.edit_accessor = edit_accessor_name def atse_set_method(value, self=self, name=name, *args, **kw): if name != 'id': self.getField(name).set(self, value, **kw) # saving id directly (avoiding unicode problems) else: self.setId(value) mutator_name = getattr(field, 'mutator', None) if mutator_name and shasattr(self, mutator_name): pass # the mutator exists, we're cool else: v_name = '_v_%s_mutator' % name mutator_name = v_name setattr(self, v_name, atse_set_method) field.mutator = mutator_name # Check if we need to update our own properties try: value = field.get(self) except: field.set(self, field.default) return self._wrap_schema(self._v_schema)