[Zope3-checkins] SVN: Zope3/trunk/src/zope/wfmc/ Added an initial
xpdl import capability.
Jim Fulton
jim at zope.com
Fri Jan 7 16:04:19 EST 2005
Log message for revision 28768:
Added an initial xpdl import capability.
Changed:
A Zope3/trunk/src/zope/wfmc/publication.xpdl
U Zope3/trunk/src/zope/wfmc/tests.py
A Zope3/trunk/src/zope/wfmc/xpdl.py
A Zope3/trunk/src/zope/wfmc/xpdl.txt
-=-
Added: Zope3/trunk/src/zope/wfmc/publication.xpdl
===================================================================
--- Zope3/trunk/src/zope/wfmc/publication.xpdl 2005-01-07 21:04:16 UTC (rev 28767)
+++ Zope3/trunk/src/zope/wfmc/publication.xpdl 2005-01-07 21:04:18 UTC (rev 28768)
@@ -0,0 +1,465 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Package Id="Publication" xmlns="http://www.wfmc.org/2002/XPDL1.0" xmlns:xpdl="http://www.wfmc.org/2002/XPDL1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.wfmc.org/2002/XPDL1.0 http://wfmc.org/standards/docs/TC-1025_schema_10_xpdl.xsd">
+ <PackageHeader>
+ <XPDLVersion>1.0</XPDLVersion>
+ <Vendor>Together</Vendor>
+ <Created>2005-01-06 16:28:27</Created>
+ </PackageHeader>
+ <RedefinableHeader PublicationStatus="UNDER_TEST"/>
+ <ConformanceClass GraphConformance="NON_BLOCKED"/>
+ <Participants>
+ <Participant Id="System">
+ <ParticipantType Type="SYSTEM"/>
+ </Participant>
+ </Participants>
+ <Applications>
+ <Application Id="prepare">
+ <FormalParameters>
+ <FormalParameter Id="publish" Mode="OUT">
+ <DataType>
+ <BasicType Type="BOOLEAN"/>
+ </DataType>
+ </FormalParameter>
+ </FormalParameters>
+ </Application>
+ <Application Id="publish"/>
+ <Application Id="reject"/>
+ </Applications>
+ <WorkflowProcesses>
+ <WorkflowProcess AccessLevel="PUBLIC" Id="Publication" Name="Publication">
+ <ProcessHeader DurationUnit="D">
+ <Created>2005-01-06 16:29:02</Created>
+ </ProcessHeader>
+ <RedefinableHeader PublicationStatus="UNDER_TEST"/>
+ <FormalParameters>
+ <FormalParameter Id="author" Mode="IN">
+ <DataType>
+ <BasicType Type="STRING"/>
+ </DataType>
+ </FormalParameter>
+ <FormalParameter Id="publish" Mode="OUT">
+ <DataType>
+ <BasicType Type="BOOLEAN"/>
+ </DataType>
+ </FormalParameter>
+ </FormalParameters>
+ <DataFields>
+ <DataField Id="publish" IsArray="FALSE">
+ <DataType>
+ <BasicType Type="BOOLEAN"/>
+ </DataType>
+ </DataField>
+ <DataField Id="tech_changes" IsArray="FALSE">
+ <DataType>
+ <BasicType Type="BOOLEAN"/>
+ </DataType>
+ </DataField>
+ <DataField Id="ed_changes" IsArray="FALSE">
+ <DataType>
+ <BasicType Type="BOOLEAN"/>
+ </DataType>
+ </DataField>
+ <DataField Id="publish1" IsArray="FALSE">
+ <DataType>
+ <BasicType Type="BOOLEAN"/>
+ </DataType>
+ </DataField>
+ <DataField Id="tech_changes1" IsArray="FALSE">
+ <DataType>
+ <BasicType Type="BOOLEAN"/>
+ </DataType>
+ </DataField>
+ <DataField Id="publish2" IsArray="FALSE">
+ <DataType>
+ <BasicType Type="BOOLEAN"/>
+ </DataType>
+ </DataField>
+ <DataField Id="tech_changes2" IsArray="FALSE">
+ <DataType>
+ <BasicType Type="BOOLEAN"/>
+ </DataType>
+ </DataField>
+ </DataFields>
+ <Participants>
+ <Participant Id="author" Name="Author">
+ <ParticipantType Type="ROLE"/>
+ </Participant>
+ <Participant Id="tech1" Name="Technical Reviewer 1">
+ <ParticipantType Type="HUMAN"/>
+ </Participant>
+ <Participant Id="tech2" Name="Technical Reviewer 2">
+ <ParticipantType Type="HUMAN"/>
+ </Participant>
+ <Participant Id="reviewer" Name="Editorial Reviewer">
+ <ParticipantType Type="HUMAN"/>
+ </Participant>
+ </Participants>
+ <Applications>
+ <Application Id="prepare"/>
+ <Application Id="tech_review">
+ <FormalParameters>
+ <FormalParameter Id="publish" Mode="OUT">
+ <DataType>
+ <BasicType Type="BOOLEAN"/>
+ </DataType>
+ </FormalParameter>
+ <FormalParameter Id="tech_changes" Mode="OUT">
+ <DataType>
+ <BasicType Type="BOOLEAN"/>
+ </DataType>
+ </FormalParameter>
+ </FormalParameters>
+ </Application>
+ <Application Id="ed_review">
+ <FormalParameters>
+ <FormalParameter Id="publish1" Mode="IN">
+ <DataType>
+ <BasicType Type="BOOLEAN"/>
+ </DataType>
+ </FormalParameter>
+ <FormalParameter Id="tech_changes1" Mode="IN">
+ <DataType>
+ <BasicType Type="BOOLEAN"/>
+ </DataType>
+ </FormalParameter>
+ <FormalParameter Id="publish2" Mode="IN">
+ <DataType>
+ <BasicType Type="BOOLEAN"/>
+ </DataType>
+ </FormalParameter>
+ <FormalParameter Id="tech_changes2" Mode="IN">
+ <DataType>
+ <BasicType Type="BOOLEAN"/>
+ </DataType>
+ </FormalParameter>
+ <FormalParameter Id="publish" Mode="OUT">
+ <DataType>
+ <BasicType Type="BOOLEAN"/>
+ </DataType>
+ </FormalParameter>
+ <FormalParameter Id="tech_changes" Mode="OUT">
+ <DataType>
+ <BasicType Type="BOOLEAN"/>
+ </DataType>
+ </FormalParameter>
+ <FormalParameter Id="ed_changes" Mode="OUT">
+ <DataType>
+ <BasicType Type="BOOLEAN"/>
+ </DataType>
+ </FormalParameter>
+ </FormalParameters>
+ </Application>
+ <Application Id="final"/>
+ <Application Id="rfinal">
+ <FormalParameters>
+ <FormalParameter Id="ed_changes" Mode="OUT">
+ <DataType>
+ <BasicType Type="BOOLEAN"/>
+ </DataType>
+ </FormalParameter>
+ </FormalParameters>
+ </Application>
+ </Applications>
+ <Activities>
+ <Activity Id="prepare" Name="Prepare">
+ <Implementation>
+ <Tool Id="prepare" Type="APPLICATION"/>
+ </Implementation>
+ <Performer>author</Performer>
+ <StartMode>
+ <Automatic/>
+ </StartMode>
+ <FinishMode>
+ <Automatic/>
+ </FinishMode>
+ <TransitionRestrictions>
+ <TransitionRestriction>
+ <Join Type="XOR"/>
+ <Split Type="AND">
+ <TransitionRefs>
+ <TransitionRef Id="Publication_Tra3"/>
+ <TransitionRef Id="Publication_Tra2"/>
+ </TransitionRefs>
+ </Split>
+ </TransitionRestriction>
+ </TransitionRestrictions>
+ <ExtendedAttributes>
+ <ExtendedAttribute Name="ParticipantID" Value="author"/>
+ <ExtendedAttribute Name="XOffset" Value="110"/>
+ <ExtendedAttribute Name="YOffset" Value="20"/>
+ </ExtendedAttributes>
+ </Activity>
+ <Activity Id="tech1" Name="Technical Review 1">
+ <Implementation>
+ <Tool Id="tech_review" Type="APPLICATION">
+ <ActualParameters>
+ <ActualParameter>publish1</ActualParameter>
+ <ActualParameter>tech_changes1</ActualParameter>
+ </ActualParameters>
+ </Tool>
+ </Implementation>
+ <Performer>tech1</Performer>
+ <StartMode>
+ <Automatic/>
+ </StartMode>
+ <FinishMode>
+ <Automatic/>
+ </FinishMode>
+ <ExtendedAttributes>
+ <ExtendedAttribute Name="ParticipantID" Value="tech1"/>
+ <ExtendedAttribute Name="XOffset" Value="210"/>
+ <ExtendedAttribute Name="YOffset" Value="30"/>
+ </ExtendedAttributes>
+ </Activity>
+ <Activity Id="tech2" Name="Technical Review 2">
+ <Implementation>
+ <Tool Id="tech_review" Type="APPLICATION">
+ <ActualParameters>
+ <ActualParameter>publish2</ActualParameter>
+ <ActualParameter>tech_changes2</ActualParameter>
+ </ActualParameters>
+ </Tool>
+ </Implementation>
+ <Performer>tech2</Performer>
+ <StartMode>
+ <Automatic/>
+ </StartMode>
+ <FinishMode>
+ <Automatic/>
+ </FinishMode>
+ <ExtendedAttributes>
+ <ExtendedAttribute Name="ParticipantID" Value="tech2"/>
+ <ExtendedAttribute Name="XOffset" Value="190"/>
+ <ExtendedAttribute Name="YOffset" Value="20"/>
+ </ExtendedAttributes>
+ </Activity>
+ <Activity Id="review" Name="Editorial Review">
+ <Implementation>
+ <Tool Id="ed_review" Type="APPLICATION">
+ <ActualParameters>
+ <ActualParameter>publish1</ActualParameter>
+ <ActualParameter>tech_changes1</ActualParameter>
+ <ActualParameter>publish2</ActualParameter>
+ <ActualParameter>tech_changes2</ActualParameter>
+ <ActualParameter>publish</ActualParameter>
+ <ActualParameter>tech_changes</ActualParameter>
+ <ActualParameter>ed_changes</ActualParameter>
+ </ActualParameters>
+ </Tool>
+ </Implementation>
+ <Performer>reviewer</Performer>
+ <StartMode>
+ <Automatic/>
+ </StartMode>
+ <FinishMode>
+ <Automatic/>
+ </FinishMode>
+ <TransitionRestrictions>
+ <TransitionRestriction>
+ <Join Type="AND"/>
+ <Split Type="XOR">
+ <TransitionRefs>
+ <TransitionRef Id="Publication_Tra9"/>
+ <TransitionRef Id="Publication_Tra10"/>
+ <TransitionRef Id="Publication_Tra8"/>
+ <TransitionRef Id="Publication_Tra7"/>
+ </TransitionRefs>
+ </Split>
+ </TransitionRestriction>
+ </TransitionRestrictions>
+ <ExtendedAttributes>
+ <ExtendedAttribute Name="ParticipantID" Value="reviewer"/>
+ <ExtendedAttribute Name="XOffset" Value="300"/>
+ <ExtendedAttribute Name="YOffset" Value="20"/>
+ </ExtendedAttributes>
+ </Activity>
+ <Activity Id="final" Name="Final Preparation">
+ <Implementation>
+ <Tool Id="final" Type="APPLICATION"/>
+ </Implementation>
+ <Performer>author</Performer>
+ <StartMode>
+ <Automatic/>
+ </StartMode>
+ <FinishMode>
+ <Automatic/>
+ </FinishMode>
+ <TransitionRestrictions>
+ <TransitionRestriction>
+ <Join Type="XOR"/>
+ </TransitionRestriction>
+ </TransitionRestrictions>
+ <ExtendedAttributes>
+ <ExtendedAttribute Name="ParticipantID" Value="author"/>
+ <ExtendedAttribute Name="XOffset" Value="370"/>
+ <ExtendedAttribute Name="YOffset" Value="30"/>
+ </ExtendedAttributes>
+ </Activity>
+ <Activity Id="rfinal" Name="Review Final">
+ <Implementation>
+ <Tool Id="rfinal" Type="APPLICATION">
+ <ActualParameters>
+ <ActualParameter>ed_changes</ActualParameter>
+ </ActualParameters>
+ </Tool>
+ </Implementation>
+ <Performer>reviewer</Performer>
+ <StartMode>
+ <Automatic/>
+ </StartMode>
+ <FinishMode>
+ <Automatic/>
+ </FinishMode>
+ <TransitionRestrictions>
+ <TransitionRestriction>
+ <Split Type="XOR">
+ <TransitionRefs>
+ <TransitionRef Id="Publication_Tra13"/>
+ <TransitionRef Id="Publication_Tra12"/>
+ </TransitionRefs>
+ </Split>
+ </TransitionRestriction>
+ </TransitionRestrictions>
+ <ExtendedAttributes>
+ <ExtendedAttribute Name="ParticipantID" Value="reviewer"/>
+ <ExtendedAttribute Name="XOffset" Value="440"/>
+ <ExtendedAttribute Name="YOffset" Value="20"/>
+ </ExtendedAttributes>
+ </Activity>
+ <Activity Id="start" Name="Start">
+ <Implementation>
+ <No/>
+ </Implementation>
+ <Performer>System</Performer>
+ <StartMode>
+ <Automatic/>
+ </StartMode>
+ <FinishMode>
+ <Automatic/>
+ </FinishMode>
+ <ExtendedAttributes>
+ <ExtendedAttribute Name="ParticipantID" Value="System"/>
+ <ExtendedAttribute Name="XOffset" Value="60"/>
+ <ExtendedAttribute Name="YOffset" Value="10"/>
+ </ExtendedAttributes>
+ </Activity>
+ <Activity Id="publish" Name="Publish">
+ <Implementation>
+ <Tool Id="publish" Type="APPLICATION"/>
+ </Implementation>
+ <Performer>System</Performer>
+ <StartMode>
+ <Automatic/>
+ </StartMode>
+ <FinishMode>
+ <Automatic/>
+ </FinishMode>
+ <TransitionRestrictions>
+ <TransitionRestriction>
+ <Join Type="XOR"/>
+ </TransitionRestriction>
+ </TransitionRestrictions>
+ <ExtendedAttributes>
+ <ExtendedAttribute Name="ParticipantID" Value="System"/>
+ <ExtendedAttribute Name="XOffset" Value="540"/>
+ <ExtendedAttribute Name="YOffset" Value="20"/>
+ </ExtendedAttributes>
+ </Activity>
+ <Activity Id="reject" Name="Reject">
+ <Implementation>
+ <Tool Id="reject" Type="APPLICATION"/>
+ </Implementation>
+ <Performer>System</Performer>
+ <StartMode>
+ <Automatic/>
+ </StartMode>
+ <FinishMode>
+ <Automatic/>
+ </FinishMode>
+ <ExtendedAttributes>
+ <ExtendedAttribute Name="ParticipantID" Value="System"/>
+ <ExtendedAttribute Name="XOffset" Value="540"/>
+ <ExtendedAttribute Name="YOffset" Value="80"/>
+ </ExtendedAttributes>
+ </Activity>
+ </Activities>
+ <Transitions>
+ <Transition From="prepare" Id="Publication_Tra2" Name="Transition" To="tech1">
+ <ExtendedAttributes>
+ <ExtendedAttribute Name="RoutingType" Value="NOROUTING"/>
+ <ExtendedAttribute Name="BreakPoint" Value="160;160;1"/>
+ </ExtendedAttributes>
+ </Transition>
+ <Transition From="prepare" Id="Publication_Tra3" Name="Transition" To="tech2">
+ <ExtendedAttributes>
+ <ExtendedAttribute Name="RoutingType" Value="NOROUTING"/>
+ <ExtendedAttribute Name="BreakPoint" Value="210;290;1"/>
+ </ExtendedAttributes>
+ </Transition>
+ <Transition From="tech2" Id="Publication_Tra4" Name="Transition" To="review">
+ <ExtendedAttributes>
+ <ExtendedAttribute Name="RoutingType" Value="NOROUTING"/>
+ </ExtendedAttributes>
+ </Transition>
+ <Transition From="tech1" Id="Publication_Tra5" Name="Transition" To="review">
+ <ExtendedAttributes>
+ <ExtendedAttribute Name="RoutingType" Value="NOROUTING"/>
+ </ExtendedAttributes>
+ </Transition>
+ <Transition From="start" Id="Publication_Tra6" Name="Transition" To="prepare">
+ <ExtendedAttributes>
+ <ExtendedAttribute Name="RoutingType" Value="NOROUTING"/>
+ </ExtendedAttributes>
+ </Transition>
+ <Transition From="review" Id="Publication_Tra7" Name="Transition" To="prepare">
+ <Condition Type="CONDITION">tech_changes</Condition>
+ <ExtendedAttributes>
+ <ExtendedAttribute Name="RoutingType" Value="NOROUTING"/>
+ </ExtendedAttributes>
+ </Transition>
+ <Transition From="review" Id="Publication_Tra8" Name="Transition" To="final">
+ <Condition Type="CONDITION">ed_changes</Condition>
+ <ExtendedAttributes>
+ <ExtendedAttribute Name="RoutingType" Value="NOROUTING"/>
+ </ExtendedAttributes>
+ </Transition>
+ <Transition From="review" Id="Publication_Tra9" Name="Transition" To="reject">
+ <Condition Type="CONDITION">not publish</Condition>
+ <ExtendedAttributes>
+ <ExtendedAttribute Name="RoutingType" Value="NOROUTING"/>
+ </ExtendedAttributes>
+ </Transition>
+ <Transition From="review" Id="Publication_Tra10" Name="Transition" To="publish">
+ <ExtendedAttributes>
+ <ExtendedAttribute Name="RoutingType" Value="NOROUTING"/>
+ </ExtendedAttributes>
+ </Transition>
+ <Transition From="final" Id="Publication_Tra11" Name="Transition" To="rfinal">
+ <ExtendedAttributes>
+ <ExtendedAttribute Name="RoutingType" Value="NOROUTING"/>
+ <ExtendedAttribute Name="BreakPoint" Value="490;400;1"/>
+ </ExtendedAttributes>
+ </Transition>
+ <Transition From="rfinal" Id="Publication_Tra12" Name="Transition" To="final">
+ <Condition Type="CONDITION">ed_changes</Condition>
+ <ExtendedAttributes>
+ <ExtendedAttribute Name="RoutingType" Value="NOROUTING"/>
+ <ExtendedAttribute Name="BreakPoint" Value="440;430;1"/>
+ </ExtendedAttributes>
+ </Transition>
+ <Transition From="rfinal" Id="Publication_Tra13" Name="Transition" To="publish">
+ <ExtendedAttributes>
+ <ExtendedAttribute Name="RoutingType" Value="NOROUTING"/>
+ </ExtendedAttributes>
+ </Transition>
+ </Transitions>
+ <ExtendedAttributes>
+ <ExtendedAttribute Name="ParticipantVisualOrder" Value="tech1;tech2;author;reviewer;System;"/>
+ </ExtendedAttributes>
+ </WorkflowProcess>
+ </WorkflowProcesses>
+ <ExtendedAttributes>
+ <ExtendedAttribute Name="MadeBy" Value="JaWE"/>
+ <ExtendedAttribute Name="Version" Value="1.2"/>
+ </ExtendedAttributes>
+</Package>
Property changes on: Zope3/trunk/src/zope/wfmc/publication.xpdl
___________________________________________________________________
Name: svn:eol-style
+ native
Modified: Zope3/trunk/src/zope/wfmc/tests.py
===================================================================
--- Zope3/trunk/src/zope/wfmc/tests.py 2005-01-07 21:04:16 UTC (rev 28767)
+++ Zope3/trunk/src/zope/wfmc/tests.py 2005-01-07 21:04:18 UTC (rev 28768)
@@ -15,6 +15,7 @@
$Id$
"""
+import os
import unittest
import zope.event
from zope.component.tests import placelesssetup
@@ -23,12 +24,19 @@
placelesssetup.tearDown(test)
zope.event.subscribers.pop()
+def setUp(test):
+ test.globs['this_directory'] = os.path.split(__file__)[0]
+ placelesssetup.setUp(test)
+
def test_suite():
from zope.testing import doctest
suite = unittest.TestSuite()
# suite.addTest(doctest.DocTestSuite())
suite.addTest(doctest.DocFileSuite('README.txt', tearDown=tearDown,
setUp=placelesssetup.setUp))
+ suite.addTest(doctest.DocFileSuite(
+ 'xpdl.txt', tearDown=tearDown, setUp=setUp,
+ optionflags=doctest.NORMALIZE_WHITESPACE))
return suite
if __name__ == '__main__':
Added: Zope3/trunk/src/zope/wfmc/xpdl.py
===================================================================
--- Zope3/trunk/src/zope/wfmc/xpdl.py 2005-01-07 21:04:16 UTC (rev 28767)
+++ Zope3/trunk/src/zope/wfmc/xpdl.py 2005-01-07 21:04:18 UTC (rev 28768)
@@ -0,0 +1,287 @@
+##############################################################################
+#
+# Copyright (c) 2004 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""XPDL reader for process definitions
+
+$Id$
+"""
+
+import sys
+import xml.sax
+import xml.sax.xmlreader
+import xml.sax.handler
+
+import zope.wfmc.process
+
+xpdlns = "http://www.wfmc.org/2002/XPDL1.0"
+
+
+class HandlerError(Exception):
+
+ def __init__(self, orig, tag, locator):
+ self.orig = orig
+ self.tag = tag
+ self.xml = locator.getSystemId()
+ self.line = locator.getLineNumber()
+
+ def __repr__(self):
+ return ('%r\nFile "%s", line %s. in %s'
+ % (self.orig, self.xml, self.line, self.tag))
+
+ def __str__(self):
+ return ('%s\nFile "%s", line %s. in %s'
+ % (self.orig, self.xml, self.line, self.tag))
+
+
+class Package(dict):
+
+ def __init__(self):
+ self.applications = {}
+ self.participants = {}
+
+ def defineApplications(self, **applications):
+ for id, application in applications.items():
+ application.id = id
+ self.applications[id] = application
+
+ def defineParticipants(self, **participants):
+ for id, participant in participants.items():
+ participant.id = id
+ self.participants[id] = participant
+
+
+class XPDLHandler(xml.sax.handler.ContentHandler):
+
+ start_handlers = {}
+ end_handlers = {}
+ text = u''
+
+ def __init__(self, package):
+ self.package = package
+ self.stack = []
+
+ def startElementNS(self, name, qname, attrs):
+ handler = self.start_handlers.get(name)
+ if handler:
+ try:
+ result = handler(self, attrs)
+ except:
+ raise HandlerError, (
+ sys.exc_info()[1], name[1], self.locator
+ ), sys.exc_info()[2]
+ else:
+ result = None
+
+ self.stack.append(result)
+ self.text = u''
+
+ def endElementNS(self, name, qname):
+ last = self.stack.pop()
+ handler = self.end_handlers.get(name)
+ if handler:
+ try:
+ handler(self, last)
+ except:
+ raise HandlerError, (
+ sys.exc_info()[1], name[1], self.locator
+ ), sys.exc_info()[2]
+
+ self.text = u''
+
+ def characters(self, text):
+ self.text += text
+
+ def setDocumentLocator(self, locator):
+ self.locator = locator
+
+ def dup(self, attrs):
+ # Just duplicate whatever is on the top of the stack
+ return self.stack[-1]
+
+ ######################################################################
+ # Application handlers
+
+ # Pointless container elements that we want to "ignore" by having them
+ # dup their containers:
+ for tag in (
+ 'FormalParameters', 'Participants', 'Applications', 'Activities',
+ 'Implementation', 'ActualParameters', 'Transitions',
+ 'TransitionRestrictions', 'TransitionRestriction',
+ ):
+ start_handlers[(xpdlns, tag)] = dup
+
+ def Package(self, attrs):
+ package = self.package
+ package.id = attrs[(None, 'Id')]
+ package.__name__ = attrs.get((None, 'Name'))
+ return package
+ start_handlers[(xpdlns, 'Package')] = Package
+
+ def WorkflowProcess(self, attrs):
+ id = attrs[(None, 'Id')]
+ process = zope.wfmc.process.ProcessDefinition(id)
+ process.__name__ = attrs.get((None, 'Name'))
+
+ # Copy package data:
+ process.defineApplications(**self.package.applications)
+ process.defineParticipants(**self.package.participants)
+
+ self.package[id] = process
+ return process
+ start_handlers[(xpdlns, 'WorkflowProcess')] = WorkflowProcess
+
+ paramter_types = {
+ 'IN': zope.wfmc.process.InputParameter,
+ 'OUT': zope.wfmc.process.OutputParameter,
+ 'INOUT': zope.wfmc.process.InputOutputParameter,
+ }
+
+
+ def FormalParameter(self, attrs):
+ mode = attrs.get((None, 'Mode'), 'IN')
+ id = attrs[(None, 'Id')]
+ self.stack[-1].defineParameters(*[self.paramter_types[mode](id)])
+ start_handlers[(xpdlns, 'FormalParameter')] = FormalParameter
+
+ def Participant(self, attrs):
+ id = attrs[(None, 'Id')]
+ name = attrs.get((None, 'Name'))
+ participant = zope.wfmc.process.Participant(name)
+ self.stack[-1].defineParticipants(**{str(id): participant})
+ start_handlers[(xpdlns, 'Participant')] = Participant
+
+ def Application(self, attrs):
+ id = attrs[(None, 'Id')]
+ name = attrs.get((None, 'Name'))
+ app = zope.wfmc.process.Application()
+ app.id = id
+ if name:
+ app.__name__ = name
+ return app
+ start_handlers[(xpdlns, 'Application')] = Application
+
+ def application(self, app):
+ self.stack[-1].defineApplications(**{str(app.id): app})
+ end_handlers[(xpdlns, 'Application')] = application
+
+ ######################################################################
+ # Activity definitions
+
+ def ActivitySet(self, attrs):
+ raise NotImplementedError("ActivitySet")
+ end_handlers[(xpdlns, 'ActivitySet')] = ActivitySet
+
+ def Activity(self, attrs):
+ id = attrs[(None, 'Id')]
+ name = attrs.get((None, 'Name'))
+ activity = zope.wfmc.process.ActivityDefinition(name)
+ activity.id = id
+ self.stack[-1].defineActivities(**{str(id): activity})
+ return activity
+ start_handlers[(xpdlns, 'Activity')] = Activity
+
+ def Tool(self, attrs):
+ return Tool(attrs[(None, 'Id')])
+ start_handlers[(xpdlns, 'Tool')] = Tool
+
+ def tool(self, tool):
+ self.stack[-1].addApplication(tool.id, tool.parameters)
+ end_handlers[(xpdlns, 'Tool')] = tool
+
+ def actualparameter(self, ignored):
+ self.stack[-1].parameters += (self.text, )
+ end_handlers[(xpdlns, 'ActualParameter')] = actualparameter
+
+ def performer(self, ignored):
+ self.stack[-1].definePerformer(self.text.strip())
+ end_handlers[(xpdlns, 'Performer')] = performer
+
+ def Join(self, attrs):
+ Type = attrs.get((None, 'Type'))
+ if Type == u'AND':
+ self.stack[-1].andJoin(True)
+ start_handlers[(xpdlns, 'Join')] = Join
+
+ def Split(self, attrs):
+ Type = attrs.get((None, 'Type'))
+ if Type == u'AND':
+ self.stack[-1].andSplit(True)
+ start_handlers[(xpdlns, 'Split')] = Split
+
+
+ # Activity definitions
+ ######################################################################
+
+ def Transition(self, attrs):
+ id = attrs[(None, 'Id')]
+ name = attrs.get((None, 'Name'))
+ from_ = attrs.get((None, 'From'))
+ to = attrs.get((None, 'To'))
+ transition = zope.wfmc.process.TransitionDefinition(from_, to)
+ transition.id = id
+ return transition
+ start_handlers[(xpdlns, 'Transition')] = Transition
+
+ def transition(self, transition):
+ self.stack[-1].defineTransitions(transition)
+ end_handlers[(xpdlns, 'Transition')] = transition
+
+ def condition(self, ignored):
+ assert isinstance(self.stack[-1],
+ zope.wfmc.process.TransitionDefinition)
+
+ text = self.text
+ self.stack[-1].condition = TextCondition("(%s)" % text)
+ end_handlers[(xpdlns, 'Condition')] = condition
+
+
+class Tool:
+
+ def __init__(self, id):
+ self.id = id
+
+ parameters = ()
+
+class TextCondition:
+
+ def __init__(self, source):
+ self.source = source
+
+ # make sure that we can compile the source
+ compile(source, '<string>', 'eval')
+
+ def __getstate__(self):
+ return {'source': self.source}
+
+ def __call__(self, data):
+ # XXX we *depend* on being able to use the data's dict.
+ # This needs to be part of the contract.
+ try:
+ compiled = self._v_compiled
+ except AttributeError:
+ self._v_compiled = compile(self.source, '<string>', 'eval')
+ compiled = self._v_compiled
+
+ return eval(compiled, {'__builtins__': None}, data.__dict__)
+
+
+def read(file):
+ src = xml.sax.xmlreader.InputSource(getattr(file, 'name', '<string>'))
+ src.setByteStream(file)
+ parser = xml.sax.make_parser()
+ package = Package()
+ parser.setContentHandler(XPDLHandler(package))
+ parser.setFeature(xml.sax.handler.feature_namespaces, True)
+ parser.parse(src)
+ return package
+
Property changes on: Zope3/trunk/src/zope/wfmc/xpdl.py
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Added: Zope3/trunk/src/zope/wfmc/xpdl.txt
===================================================================
--- Zope3/trunk/src/zope/wfmc/xpdl.txt 2005-01-07 21:04:16 UTC (rev 28767)
+++ Zope3/trunk/src/zope/wfmc/xpdl.txt 2005-01-07 21:04:18 UTC (rev 28768)
@@ -0,0 +1,341 @@
+XPDL Import
+===========
+
+We can import process definitions from files in the XML Process
+Definition Language (XPDL) format. An XPDL file contains multiple
+process definitions arranged in a package. When we load the file, we
+get a package containing some numner of process definitions.
+
+Let's look at an example. The file `publication.xpdl`
+contains a definition for the publication example developed in the
+"README.txt" file. We can read it using the xpdl module:
+
+ >>> from zope.wfmc import xpdl
+ >>> package = xpdl.read(open(this_directory+'/publication.xpdl'))
+
+This package contains a single definition:
+
+ >>> package
+ {u'Publication': ProcessDefinition(u'Publication')}
+
+ >>> pd = package[u'Publication']
+
+Now, having read the process definition, we can use it as we did
+before (in "README.txt"). As before, we'll create an event subscriber
+so that we can see what's going on:
+
+ >>> def log_workflow(event):
+ ... print event
+
+ >>> import zope.event
+ >>> zope.event.subscribers.append(log_workflow)
+
+and we'll register the process definition as a utility:
+
+ >>> import zope.component
+ >>> zope.component.provideUtility(pd, name=pd.id)
+
+and we'll define and register participant and application adapters:
+
+ >>> import zope.interface
+ >>> from zope.wfmc import interfaces
+
+ >>> class Participant(object):
+ ... zope.component.adapts(interfaces.IActivity)
+ ... zope.interface.implements(interfaces.IParticipant)
+ ...
+ ... def __init__(self, activity):
+ ... self.activity = activity
+
+ >>> class User:
+ ... def __init__(self):
+ ... self.work_list = []
+
+ >>> authors = {'bob': User(), 'ted': User(), 'sally': User()}
+
+ >>> reviewer = User()
+ >>> tech1 = User()
+ >>> tech2 = User()
+
+ >>> class Author(Participant):
+ ... def __init__(self, activity):
+ ... Participant.__init__(self, activity)
+ ... author_name = activity.process.workflowRelevantData.author
+ ... self.user = authors[author_name]
+
+ >>> zope.component.provideAdapter(Author, name="Publication.author")
+
+ >>> class Reviewer(Participant):
+ ... user = reviewer
+ >>> zope.component.provideAdapter(Reviewer, name="Publication.reviewer")
+
+ >>> class Tech1(Participant):
+ ... user = tech1
+ >>> zope.component.provideAdapter(Tech1, name="Publication.tech1")
+
+ >>> class Tech2(Participant):
+ ... user = tech2
+ >>> zope.component.provideAdapter(Tech2, name="Publication.tech2")
+
+ >>> zope.component.provideAdapter(Participant, name="Publication.System")
+
+ >>> class ApplicationBase(object):
+ ... zope.component.adapts(interfaces.IParticipant)
+ ... zope.interface.implements(interfaces.IWorkItem)
+ ...
+ ... def __init__(self, participant):
+ ... self.participant = participant
+ ... self.activity = participant.activity
+ ... participant.user.work_list.append(self)
+ ...
+ ... def start(self):
+ ... pass
+ ...
+ ... def finish(self):
+ ... self.participant.activity.workItemFinished(self)
+
+ >>> class Prepare(ApplicationBase):
+ ...
+ ... def summary(self):
+ ... process = self.activity.process
+ ... doc = getattr(process.applicationRelevantData, 'doc', '')
+ ... if doc:
+ ... print 'Previous draft:'
+ ... print doc
+ ... print 'Changed we need to make:'
+ ... for change in process.workflowRelevantData.tech_changes:
+ ... print change
+ ... else:
+ ... print 'Please write the initial draft'
+ ...
+ ... def finish(self, doc):
+ ... self.activity.process.applicationRelevantData.doc = doc
+ ... super(Prepare, self).finish()
+
+ >>> zope.component.provideAdapter(Prepare, name="Publication.prepare")
+
+ >>> class TechReview(ApplicationBase):
+ ...
+ ... def getDoc(self):
+ ... return self.activity.process.applicationRelevantData.doc
+ ...
+ ... def finish(self, decision, changes):
+ ... self.activity.workItemFinished(self, decision, changes)
+
+ >>> zope.component.provideAdapter(TechReview,
+ ... name="Publication.tech_review")
+
+ >>> class Review(TechReview):
+ ...
+ ... def start(self, publish1, changes1, publish2, changes2):
+ ... if not (publish1 and publish2):
+ ... # Reject if either tech reviewer rejects
+ ... self.activity.workItemFinished(
+ ... self, False, changes1 + changes2, ())
+ ...
+ ... if changes1 or changes2:
+ ... # we won't do anyting if there are tech changes
+ ... self.activity.workItemFinished(
+ ... self, True, changes1 + changes2, ())
+ ...
+ ... def finish(self, ed_changes):
+ ... self.activity.workItemFinished(self, True, (), ed_changes)
+
+ >>> zope.component.provideAdapter(Review, name="Publication.ed_review")
+
+ >>> class Final(ApplicationBase):
+ ...
+ ... def summary(self):
+ ... process = self.activity.process
+ ... doc = getattr(process.applicationRelevantData, 'doc', '')
+ ... print 'Previous draft:'
+ ... print self.activity.process.applicationRelevantData.doc
+ ... print 'Changed we need to make:'
+ ... for change in process.workflowRelevantData.ed_changes:
+ ... print change
+ ...
+ ... def finish(self, doc):
+ ... self.activity.process.applicationRelevantData.doc = doc
+ ... super(Final, self).finish()
+
+ >>> zope.component.provideAdapter(Final, name="Publication.final")
+
+ >>> class ReviewFinal(TechReview):
+ ...
+ ... def finish(self, ed_changes):
+ ... self.activity.workItemFinished(self, ed_changes)
+
+ >>> zope.component.provideAdapter(ReviewFinal, name="Publication.rfinal")
+
+
+ >>> class Publish:
+ ... zope.component.adapts(interfaces.IParticipant)
+ ... zope.interface.implements(interfaces.IWorkItem)
+ ...
+ ... def __init__(self, participant):
+ ... self.participant = participant
+ ...
+ ... def start(self):
+ ... print "Published"
+ ... self.finish()
+ ...
+ ... def finish(self):
+ ... self.participant.activity.workItemFinished(self)
+
+
+ >>> zope.component.provideAdapter(Publish, name="Publication.publish")
+
+ >>> class Reject(Publish):
+ ... def start(self):
+ ... print "Rejected"
+ ... self.finish()
+
+ >>> zope.component.provideAdapter(Reject, name="Publication.reject")
+
+and a process context, so we can pass parameters:
+
+ >>> class PublicationContext:
+ ... zope.interface.implements(interfaces.IProcessContext)
+ ...
+ ... def processFinished(self, process, decision):
+ ... self.decision = decision
+
+Now, let's try out our process. We'll follow the same steps we did in
+"README.txt", getting the same results:
+
+ >>> context = PublicationContext()
+ >>> proc = pd(context)
+ >>> proc.start('bob')
+ ProcessStarted(Process(u'Publication'))
+ Transition(None, Activity(u'Publication.start'))
+ ActivityStarted(Activity(u'Publication.start'))
+ ActivityFinished(Activity(u'Publication.start'))
+ Transition(Activity(u'Publication.start'),
+ Activity(u'Publication.prepare'))
+ ActivityStarted(Activity(u'Publication.prepare'))
+
+ >>> item = authors['bob'].work_list.pop()
+ >>> item.finish("I give my pledge, as an American\n"
+ ... "to save, and faithfully to defend from waste\n"
+ ... "the natural resources of my Country.")
+ WorkItemFinished(u'prepare')
+ ActivityFinished(Activity(u'Publication.prepare'))
+ Transition(Activity(u'Publication.prepare'),
+ Activity(u'Publication.tech1'))
+ ActivityStarted(Activity(u'Publication.tech1'))
+ Transition(Activity(u'Publication.prepare'),
+ Activity(u'Publication.tech2'))
+ ActivityStarted(Activity(u'Publication.tech2'))
+
+ >>> item = tech1.work_list.pop()
+ >>> print item.getDoc()
+ I give my pledge, as an American
+ to save, and faithfully to defend from waste
+ the natural resources of my Country.
+
+ >>> item.finish(True, ['Change "American" to "human"'])
+ WorkItemFinished(u'tech_review')
+ ActivityFinished(Activity(u'Publication.tech1'))
+ Transition(Activity(u'Publication.tech1'),
+ Activity(u'Publication.review'))
+
+ >>> item = tech2.work_list.pop()
+ >>> item.finish(True, ['Change "Country" to "planet"'])
+ WorkItemFinished(u'tech_review')
+ ActivityFinished(Activity(u'Publication.tech2'))
+ Transition(Activity(u'Publication.tech2'),
+ Activity(u'Publication.review'))
+ ActivityStarted(Activity(u'Publication.review'))
+ WorkItemFinished(u'ed_review')
+ ActivityFinished(Activity(u'Publication.review'))
+ Transition(Activity(u'Publication.review'),
+ Activity(u'Publication.prepare'))
+ ActivityStarted(Activity(u'Publication.prepare'))
+
+ >>> item = authors['bob'].work_list.pop()
+ >>> item.summary()
+ Previous draft:
+ I give my pledge, as an American
+ to save, and faithfully to defend from waste
+ the natural resources of my Country.
+ Changed we need to make:
+ Change "American" to "human"
+ Change "Country" to "planet"
+
+ >>> item.finish("I give my pledge, as an human\n"
+ ... "to save, and faithfully to defend from waste\n"
+ ... "the natural resources of my planet.")
+ WorkItemFinished(u'prepare')
+ ActivityFinished(Activity(u'Publication.prepare'))
+ Transition(Activity(u'Publication.prepare'),
+ Activity(u'Publication.tech1'))
+ ActivityStarted(Activity(u'Publication.tech1'))
+ Transition(Activity(u'Publication.prepare'),
+ Activity(u'Publication.tech2'))
+ ActivityStarted(Activity(u'Publication.tech2'))
+
+ >>> item = tech1.work_list.pop()
+ >>> item.finish(True, [])
+ WorkItemFinished(u'tech_review')
+ ActivityFinished(Activity(u'Publication.tech1'))
+ Transition(Activity(u'Publication.tech1'),
+ Activity(u'Publication.review'))
+
+ >>> item = tech2.work_list.pop()
+ >>> item.finish(True, [])
+ WorkItemFinished(u'tech_review')
+ ActivityFinished(Activity(u'Publication.tech2'))
+ Transition(Activity(u'Publication.tech2'),
+ Activity(u'Publication.review'))
+ ActivityStarted(Activity(u'Publication.review'))
+
+ >>> item = reviewer.work_list.pop()
+ >>> print item.getDoc()
+ I give my pledge, as an human
+ to save, and faithfully to defend from waste
+ the natural resources of my planet.
+
+ >>> item.finish(['change "an" to "a"'])
+ WorkItemFinished(u'ed_review')
+ ActivityFinished(Activity(u'Publication.review'))
+ Transition(Activity(u'Publication.review'),
+ Activity(u'Publication.final'))
+ ActivityStarted(Activity(u'Publication.final'))
+
+ >>> item = authors['bob'].work_list.pop()
+ >>> item.summary()
+ Previous draft:
+ I give my pledge, as an human
+ to save, and faithfully to defend from waste
+ the natural resources of my planet.
+ Changed we need to make:
+ change "an" to "a"
+
+ >>> item.finish("I give my pledge, as a human\n"
+ ... "to save, and faithfully to defend from waste\n"
+ ... "the natural resources of my planet.")
+ WorkItemFinished(u'final')
+ ActivityFinished(Activity(u'Publication.final'))
+ Transition(Activity(u'Publication.final'),
+ Activity(u'Publication.rfinal'))
+ ActivityStarted(Activity(u'Publication.rfinal'))
+
+ >>> item = reviewer.work_list.pop()
+ >>> print item.getDoc()
+ I give my pledge, as a human
+ to save, and faithfully to defend from waste
+ the natural resources of my planet.
+
+ >>> item.finish([])
+ WorkItemFinished(u'rfinal')
+ ActivityFinished(Activity(u'Publication.rfinal'))
+ Transition(Activity(u'Publication.rfinal'),
+ Activity(u'Publication.publish'))
+ ActivityStarted(Activity(u'Publication.publish'))
+ Published
+ WorkItemFinished(u'publish')
+ ActivityFinished(Activity(u'Publication.publish'))
+ ProcessFinished(Process(u'Publication'))
+
+ >>> context.decision
+ True
Property changes on: Zope3/trunk/src/zope/wfmc/xpdl.txt
___________________________________________________________________
Name: svn:eol-style
+ native
More information about the Zope3-Checkins
mailing list