add transition event, automatic indexing of states
git-svn-id: svn://svn.cy55.de/Zope3/src/loops/trunk@2560 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
parent
54d238afe9
commit
883656bd1e
5 changed files with 63 additions and 12 deletions
|
@ -230,8 +230,8 @@ class Concept(Contained, Persistent):
|
||||||
registry = component.getUtility(IRelationRegistry)
|
registry = component.getUtility(IRelationRegistry)
|
||||||
for rel in self.getChildRelations(predicates, child):
|
for rel in self.getChildRelations(predicates, child):
|
||||||
if order is None or rel.order == order:
|
if order is None or rel.order == order:
|
||||||
notify(DeassignmentEvent(self, rel))
|
|
||||||
registry.unregister(rel)
|
registry.unregister(rel)
|
||||||
|
notify(DeassignmentEvent(self, rel))
|
||||||
|
|
||||||
def deassignParent(self, parent, predicates=None):
|
def deassignParent(self, parent, predicates=None):
|
||||||
parent.deassignChild(self, predicates)
|
parent.deassignChild(self, predicates)
|
||||||
|
@ -269,8 +269,8 @@ class Concept(Contained, Persistent):
|
||||||
registry = component.getUtility(IRelationRegistry)
|
registry = component.getUtility(IRelationRegistry)
|
||||||
for rel in self.getResourceRelations(predicates, resource):
|
for rel in self.getResourceRelations(predicates, resource):
|
||||||
if order is None or rel.order == order:
|
if order is None or rel.order == order:
|
||||||
notify(DeassignmentEvent(self, rel))
|
|
||||||
registry.unregister(rel)
|
registry.unregister(rel)
|
||||||
|
notify(DeassignmentEvent(self, rel))
|
||||||
|
|
||||||
# combined children+resources query
|
# combined children+resources query
|
||||||
|
|
||||||
|
|
|
@ -22,13 +22,16 @@ Basic implementations for stateful objects and adapters.
|
||||||
$Id$
|
$Id$
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
from zope.app.catalog.interfaces import ICatalog
|
||||||
from zope import component
|
from zope import component
|
||||||
from zope.component import adapts
|
from zope.component import adapts, adapter
|
||||||
|
|
||||||
|
from cybertools.meta.interfaces import IOptions
|
||||||
from cybertools.stateful.base import Stateful as BaseStateful
|
from cybertools.stateful.base import Stateful as BaseStateful
|
||||||
from cybertools.stateful.base import StatefulAdapter
|
from cybertools.stateful.base import StatefulAdapter, IndexInfo
|
||||||
from cybertools.stateful.interfaces import IStatesDefinition
|
from cybertools.stateful.interfaces import IStatesDefinition, ITransitionEvent
|
||||||
from loops.interfaces import ILoopsObject
|
from loops.interfaces import ILoopsObject, IResource
|
||||||
|
from loops import util
|
||||||
|
|
||||||
|
|
||||||
class Stateful(BaseStateful):
|
class Stateful(BaseStateful):
|
||||||
|
@ -46,3 +49,21 @@ class SimplePublishable(StatefulLoopsObject):
|
||||||
|
|
||||||
statesDefinition = 'loops.simple_publishing'
|
statesDefinition = 'loops.simple_publishing'
|
||||||
|
|
||||||
|
|
||||||
|
class StatefulResourceIndexInfo(IndexInfo):
|
||||||
|
|
||||||
|
adapts(IResource)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def availableStatesDefinitions(self):
|
||||||
|
options = IOptions(self.context.getLoopsRoot())
|
||||||
|
return options('organize.stateful.resource', ())
|
||||||
|
|
||||||
|
|
||||||
|
@adapter(IResource, ITransitionEvent)
|
||||||
|
def handleTransition(self, obj, event):
|
||||||
|
previous = event.previousState
|
||||||
|
next = event.transition.targetState
|
||||||
|
if next != previous:
|
||||||
|
cat = getUtility(ICatalog)
|
||||||
|
cat.index_doc(int(util.getUidForObject(obj)), obj)
|
||||||
|
|
|
@ -5,6 +5,13 @@
|
||||||
xmlns:browser="http://namespaces.zope.org/browser"
|
xmlns:browser="http://namespaces.zope.org/browser"
|
||||||
i18n_domain="loops">
|
i18n_domain="loops">
|
||||||
|
|
||||||
|
<zope:adapter
|
||||||
|
factory="loops.organize.stateful.base.StatefulResourceIndexInfo"
|
||||||
|
trusted="True" />
|
||||||
|
<zope:class class="loops.organize.stateful.base.StatefulResourceIndexInfo">
|
||||||
|
<allow interface="cybertools.stateful.interfaces.IStatefulIndexInfo" />
|
||||||
|
</zope:class>
|
||||||
|
|
||||||
<!-- stateful definitions and corresponding adapters -->
|
<!-- stateful definitions and corresponding adapters -->
|
||||||
|
|
||||||
<zope:utility
|
<zope:utility
|
||||||
|
@ -37,6 +44,7 @@
|
||||||
|
|
||||||
<!-- event handlers -->
|
<!-- event handlers -->
|
||||||
|
|
||||||
|
<zope:subscriber handler="loops.organize.stateful.base.handleTransition" />
|
||||||
<zope:subscriber handler="loops.organize.stateful.quality.assign" />
|
<zope:subscriber handler="loops.organize.stateful.quality.assign" />
|
||||||
<zope:subscriber handler="loops.organize.stateful.quality.deassign" />
|
<zope:subscriber handler="loops.organize.stateful.quality.deassign" />
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,7 @@ from cybertools.stateful.interfaces import IStatesDefinition, IStateful
|
||||||
from loops.interfaces import IAssignmentEvent, IDeassignmentEvent
|
from loops.interfaces import IAssignmentEvent, IDeassignmentEvent
|
||||||
from loops.interfaces import ILoopsObject, IResource
|
from loops.interfaces import ILoopsObject, IResource
|
||||||
from loops.organize.stateful.base import StatefulLoopsObject
|
from loops.organize.stateful.base import StatefulLoopsObject
|
||||||
|
from loops.versioning.interfaces import IVersionable
|
||||||
|
|
||||||
|
|
||||||
@implementer(IStatesDefinition)
|
@implementer(IStatesDefinition)
|
||||||
|
@ -70,20 +71,35 @@ class ClassificationQualityCheckable(StatefulLoopsObject):
|
||||||
def assign(self, relation):
|
def assign(self, relation):
|
||||||
if not self.isRelevant(relation):
|
if not self.isRelevant(relation):
|
||||||
return
|
return
|
||||||
|
versionable = IVersionable(self.context, None)
|
||||||
if self.state in ('new', 'unclassified'):
|
if self.state in ('new', 'unclassified'):
|
||||||
self.doTransition('classify')
|
self.doTransitionWithVersions('classify', versionable)
|
||||||
else:
|
else:
|
||||||
self.doTransition('change_classification')
|
self.doTransitionWithVersions('change_classification', versionable)
|
||||||
|
|
||||||
def deassign(self, relation):
|
def deassign(self, relation):
|
||||||
if not self.isRelevant(relation):
|
if not self.isRelevant(relation):
|
||||||
return
|
return
|
||||||
|
versionable = IVersionable(self.context, None)
|
||||||
if self.state in ('new', 'classified', 'verified'):
|
if self.state in ('new', 'classified', 'verified'):
|
||||||
old = self.context.getParentRelations()
|
parents = self.context.getParentRelations()
|
||||||
if len(old) > 2: # the hasType relation always remains
|
if len(parents) > 1: # the hasType relation always remains
|
||||||
self.doTransition('change_classification')
|
self.doTransitionWithVersions('change_classification', versionable)
|
||||||
else:
|
else:
|
||||||
self.doTransition('remove_classification')
|
self.doTransitionWithVersions('remove_classification', versionable)
|
||||||
|
|
||||||
|
def doTransitionWithVersions(self, transition, versionable):
|
||||||
|
self.doTransition(transition)
|
||||||
|
if versionable is None:
|
||||||
|
return
|
||||||
|
for v in versionable.versions.values():
|
||||||
|
if v != self.context:
|
||||||
|
stf = component.getAdapter(v, IStateful, name=self.statesDefinition)
|
||||||
|
available = [t.name for t in stf.getAvailableTransitions()]
|
||||||
|
if transition in available:
|
||||||
|
stf.doTransition(transition)
|
||||||
|
#else:
|
||||||
|
# print '***', v.__name__, stf.state, transition, available
|
||||||
|
|
||||||
def isRelevant(self, relation):
|
def isRelevant(self, relation):
|
||||||
""" Return True if the relation given is relevant for changing
|
""" Return True if the relation given is relevant for changing
|
||||||
|
|
|
@ -28,6 +28,7 @@ from zope.publisher.interfaces.browser import IBrowserRequest, IBrowserView
|
||||||
from zope.security.checker import Checker, defineChecker
|
from zope.security.checker import Checker, defineChecker
|
||||||
|
|
||||||
from cybertools.browser.controller import Controller
|
from cybertools.browser.controller import Controller
|
||||||
|
from cybertools.catalog.keyword import KeywordIndex
|
||||||
from cybertools.composer.schema.factory import SchemaFactory
|
from cybertools.composer.schema.factory import SchemaFactory
|
||||||
from cybertools.composer.schema.field import FieldInstance, NumberFieldInstance
|
from cybertools.composer.schema.field import FieldInstance, NumberFieldInstance
|
||||||
from cybertools.composer.schema.field import DateFieldInstance, BooleanFieldInstance
|
from cybertools.composer.schema.field import DateFieldInstance, BooleanFieldInstance
|
||||||
|
@ -39,6 +40,7 @@ from cybertools.relation.interfaces import IRelation, IRelationRegistry
|
||||||
from cybertools.relation.interfaces import IRelationInvalidatedEvent
|
from cybertools.relation.interfaces import IRelationInvalidatedEvent
|
||||||
from cybertools.relation.registry import IndexableRelationAdapter
|
from cybertools.relation.registry import IndexableRelationAdapter
|
||||||
from cybertools.relation.registry import invalidateRelations, removeRelation
|
from cybertools.relation.registry import invalidateRelations, removeRelation
|
||||||
|
from cybertools.stateful.interfaces import IStatefulIndexInfo
|
||||||
from cybertools.typology.interfaces import IType
|
from cybertools.typology.interfaces import IType
|
||||||
|
|
||||||
from loops.base import Loops
|
from loops.base import Loops
|
||||||
|
@ -51,6 +53,7 @@ from loops.config.base import GlobalOptions, LoopsOptions
|
||||||
from loops.interfaces import ILoopsObject, IIndexAttributes
|
from loops.interfaces import ILoopsObject, IIndexAttributes
|
||||||
from loops.interfaces import IDocument, IFile, ITextDocument
|
from loops.interfaces import IDocument, IFile, ITextDocument
|
||||||
from loops.organize.memberinfo import MemberInfoProvider
|
from loops.organize.memberinfo import MemberInfoProvider
|
||||||
|
from loops.organize.stateful.base import StatefulResourceIndexInfo, handleTransition
|
||||||
from loops.query import QueryConcept
|
from loops.query import QueryConcept
|
||||||
from loops.query import QueryConcept
|
from loops.query import QueryConcept
|
||||||
from loops.resource import Resource, FileAdapter, TextDocumentAdapter
|
from loops.resource import Resource, FileAdapter, TextDocumentAdapter
|
||||||
|
@ -150,8 +153,11 @@ class TestSite(object):
|
||||||
catalog['loops_title'] = TextIndex('title', IIndexAttributes, True)
|
catalog['loops_title'] = TextIndex('title', IIndexAttributes, True)
|
||||||
catalog['loops_text'] = TextIndex('text', IIndexAttributes, True)
|
catalog['loops_text'] = TextIndex('text', IIndexAttributes, True)
|
||||||
catalog['loops_type'] = FieldIndex('tokenForSearch', IType, False)
|
catalog['loops_type'] = FieldIndex('tokenForSearch', IType, False)
|
||||||
|
catalog['loops_state'] = KeywordIndex('tokens', IStatefulIndexInfo, False)
|
||||||
component.provideAdapter(ConceptIndexAttributes)
|
component.provideAdapter(ConceptIndexAttributes)
|
||||||
component.provideAdapter(ResourceIndexAttributes)
|
component.provideAdapter(ResourceIndexAttributes)
|
||||||
|
component.provideAdapter(StatefulResourceIndexInfo)
|
||||||
|
component.provideHandler(handleTransition)
|
||||||
|
|
||||||
loopsRoot = site['loops'] = Loops()
|
loopsRoot = site['loops'] = Loops()
|
||||||
setup = SetupManager(loopsRoot)
|
setup = SetupManager(loopsRoot)
|
||||||
|
|
Loading…
Add table
Reference in a new issue