|
/
Zope
/
gocept svn checkins
/
Archive
/
2005
/
2005-06
/
SVN: r3034 - in AlphaFlow/trunk/doc/examples/MusicReview: . Extensions workflows
[
SVN: r2996 - Formulon/tags/Formulon-0_3_6-release ... ]
[
SVN: r3058 - CMFLinkChecker/trunk / Christian ... ]
SVN: r3034 - in AlphaFlow/trunk/doc/examples/MusicReview: . Extensions workflows
Christian Theune <ct(at)gocept.com> |
2005-06-21 09:33:35 |
[ FULL ]
|
Author: ctheune
Date: Tue Jun 21 09:35:09 2005
New Revision: 3034
Added:
AlphaFlow/trunk/doc/examples/MusicReview/interfaces.py
AlphaFlow/trunk/doc/examples/MusicReview/musicreview.py
- copied, changed from r3030,
AlphaFlow/trunk/doc/examples/MusicReview/dummycontent.py
AlphaFlow/trunk/doc/examples/MusicReview/version.txt
AlphaFlow/trunk/doc/examples/MusicReview/workflows/review.alf
- copied, changed from r3030,
AlphaFlow/trunk/doc/examples/MusicReview/workflows/task.alf
Removed:
AlphaFlow/trunk/doc/examples/MusicReview/dummycontent.py
AlphaFlow/trunk/doc/examples/MusicReview/workflows/task.alf
Modified:
AlphaFlow/trunk/doc/examples/MusicReview/Extensions/Install.py
AlphaFlow/trunk/doc/examples/MusicReview/__init__.py
AlphaFlow/trunk/doc/examples/MusicReview/config.py
Log:
- more or less working example for a workflow application
Modified: AlphaFlow/trunk/doc/examples/MusicReview/Extensions/Install.py
==============================================================================
--- AlphaFlow/trunk/doc/examples/MusicReview/Extensions/Install.py (original)
+++ AlphaFlow/trunk/doc/examples/MusicReview/Extensions/Install.py Tue Jun 21
09:35:09 2005
(at)(at) -1,21 +1,5 (at)(at)
-# AlphaFlowDemo - demonstration of using AlphaFlow
-#
-# Copyright 2004-2005 gocept gmbh & co. kg
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#
+# Copyright (c) 2005 gocept gmbh & co. kg
+# See also LICENSE.txt
# $Id$
"""Installer"""
(at)(at) -27,7 +11,7 (at)(at)
from Products.Archetypes.Extensions.utils import installTypes
# Project imports
-from Products.AlphaFlowDemo import config
+from Products.MusicReview import config
(at)(at) -41,9 +25,3 (at)(at)
print >>out, "Successfully installed %s." % config.PROJECTNAME
return out.getvalue()
-
-def uninstall(self):
- out = StringIO()
- print >>out, 'Uninstalling...'
-
- return out.getvalue()
Modified: AlphaFlow/trunk/doc/examples/MusicReview/__init__.py
==============================================================================
--- AlphaFlow/trunk/doc/examples/MusicReview/__init__.py (original)
+++ AlphaFlow/trunk/doc/examples/MusicReview/__init__.py Tue Jun 21 09:35:09
2005
(at)(at) -3,28 +3,20 (at)(at)
# $Id$
"""Zope initialization code"""
-# Plone imports
+from Products.Archetypes.public import listTypes, process_types
from Products.CMFCore.utils import ContentInit
-from Products.Archetypes.public import process_types, listTypes
-from Products.ATContentTypes.interfaces.IATTopic import \
- IATTopic, IATTopicCriterion
-
-# Project imports
-from Products.AlphaFlowDemo.config import \
- PROJECTNAME, ADD_CONTENT_PERMISSION, ADD_TOPIC_PERMISSION
-
-
-
-def initialize_content(context):
- from Products.AlphaFlowDemo import dummycontent
- from Products.ATContentTypes import initialize as initialize_atcontent
- from types import FunctionType
- # Call ATCT initialization with our globals/context, this registers
- # our types just like their types
- init = FunctionType(initialize_atcontent.func_code, globals())
- init(context)
-
+from Products.MusicReview import config, musicreview
def initialize(context):
- initialize_content(context)
+ listOfTypes = listTypes(config.PROJECTNAME)
+ content_types, constructors, ftis = process_types(
+ listOfTypes,
+ config.PROJECTNAME)
+ ContentInit(
+ config.PROJECTNAME + ' Content',
+ content_types = tuple(content_types),
+ permission = config.ADD_CONTENT_PERMISSION,
+ extra_constructors = tuple(constructors),
+ fti = ftis,
+ ).initialize(context)
Modified: AlphaFlow/trunk/doc/examples/MusicReview/config.py
==============================================================================
--- AlphaFlow/trunk/doc/examples/MusicReview/config.py (original)
+++ AlphaFlow/trunk/doc/examples/MusicReview/config.py Tue Jun 21 09:35:09 2005
(at)(at) -2,8 +2,38 (at)(at)
# See also LICENSE.txt
# $Id$
-PROJECTNAME = 'AlphaFlowDemo'
+from Products.CMFCore import CMFCorePermissions
+from Products.Archetypes import public as atapi
+PROJECTNAME = 'MusicReview'
+ADD_CONTENT_PERMISSION = CMFCorePermissions.AddPortalContent
-from Products.ATContentTypes import Permissions
-ADD_CONTENT_PERMISSION = Permissions.ADD_CONTENT_PERMISSION
-ADD_TOPIC_PERMISSION = Permissions.ADD_TOPIC_PERMISSION
+ratingVocabulary = atapi.DisplayList([
+ (1, "1"),
+ (2, "2"),
+ (3, "3"),
+ (4, "4"),
+ (5, "5")
+ ])
+
+
+genreVocabulary = \
+ ["Acid", "Acid Jazz", "Acid Punk", "Alternative",
+ "AlternRock", "Ambient", "Bass", "Blues", "Cabaret",
+ "Christian Rap", "Classical", "Classic Rock", "Comedy",
+ "Country", "Cult", "Dance", "Darkwave", "Death Metal",
+ "Disco", "Dream", "Electronic", "Ethnic", "Eurodance",
+ "Euro-Techno", "Funk", "Fusion", "Game", "Gangsta",
+ "Gospel", "Gothic", "Grunge", "Hard Rock", "Hip-Hop",
+ "House", "Industrial", "Instrumental",
+ "Instrumental Pop", "Instrumental Rock", "Jazz",
+ "Jazz+Funk", "Jungle", "Lo-Fi", "Meditative", "Metal",
+ "Musical", "Native American", "New Age", "New Wave",
+ "Noise", "Oldies", "Other", "Polka", "Pop", "Pop-Folk",
+ "Pop/Funk", "Pranks", "Psychadelic", "Punk", "Rap",
+ "Rave", "R&B", "Reggae", "Retro", "Rock", "Rock & Roll",
+ "Showtunes", "Ska", "Soul", "Sound Clip", "Soundtrack",
+ "Southern Rock", "Space", "Techno", "Techno-Industrial",
+ "Top 40", "Trailer", "Trance", "Tribal", "Trip-Hop",
+ "Vocal", ]
+
+genreVocabulary = atapi.DisplayList(zip(genreVocabulary, genreVocabulary))
Added: AlphaFlow/trunk/doc/examples/MusicReview/interfaces.py
==============================================================================
--- (empty file)
+++ AlphaFlow/trunk/doc/examples/MusicReview/interfaces.py Tue Jun 21 09:35:09
2005
(at)(at) -0,0 +1,22 (at)(at)
+# Copyright (c) 2005 gocept gmbh & co. kg
+# See also LICENSE.txt
+# $Id: dummycontent.py 3030 2005-06-20 11:13:24Z ctheune $
+
+from Products.Archetypes import public as atapi
+
+from Products.MusicReview import config
+
+musicReviewSchema = atapi.BaseSchema + \
+ atapi.Schema((
+ atapi.FloatField("price"),
+ atapi.IntegerField("year"),
+ atapi.StringField("genre",
+ vocabulary=config.genreVocabulary,
+ widget=atapi.SelectionWidget(label="Genre")),
+ atapi.TextField("review",
+ widget=atapi.TextAreaWidget(label="Review")),
+ atapi.IntegerField("rating",
+ vocabulary=config.ratingVocabulary,
+ widget=atapi.SelectionWidget(label="Rating")),
+ ))
+
Copied: AlphaFlow/trunk/doc/examples/MusicReview/musicreview.py (from r3030,
AlphaFlow/trunk/doc/examples/MusicReview/dummycontent.py)
==============================================================================
--- AlphaFlow/trunk/doc/examples/MusicReview/dummycontent.py (original)
+++ AlphaFlow/trunk/doc/examples/MusicReview/musicreview.py Tue Jun 21 09:35:09
2005
(at)(at) -1,7 +1,7 (at)(at)
-# Copyright (c) 2004-2005 gocept gmbh & co. kg
+# Copyright (c) 2005 gocept gmbh & co. kg
# See also LICENSE.txt
# $Id$
-"""Demonstration how to implement a content type with AlphaFlow
+"""Module containing the MusicReview content class.
"""
# Plone imports
(at)(at) -9,26 +9,17 (at)(at)
# Project imports
from Products.AlphaFlow.workflowedobject import AlphaFlowed
-from Products.AlphaFlowDemo import config
+from Products.MusicReview import config, interfaces
+class MusicReview(AlphaFlowed, atapi.BaseContent):
+ """The MusicReview content class."""
-
-class DummyContent(AlphaFlowed, atapi.BaseContent):
+ portal_type = archetype_name = meta_type = 'MusicReview'
- portal_type = archetype_name = meta_type = 'DummyContent'
__implements__ = (atapi.BaseContent.__implements__ +
AlphaFlowed.__implements__)
+ schema = interfaces.musicReviewSchema
-
-class DummyFolder(AlphaFlowed, atapi.BaseFolder):
-
- portal_type = archetype_name = meta_type = 'DummyFolder'
- __implements__ = (atapi.BaseFolder.__implements__ +
- AlphaFlowed.__implements__)
-
-
-
-atapi.registerType(DummyContent, config.PROJECTNAME)
-atapi.registerType(DummyFolder, config.PROJECTNAME)
+atapi.registerType(MusicReview)
Added: AlphaFlow/trunk/doc/examples/MusicReview/version.txt
==============================================================================
--- (empty file)
+++ AlphaFlow/trunk/doc/examples/MusicReview/version.txt Tue Jun 21 09:35:09
2005
(at)(at) -0,0 +1 (at)(at)
+1.0
Copied: AlphaFlow/trunk/doc/examples/MusicReview/workflows/review.alf (from
r3030, AlphaFlow/trunk/doc/examples/MusicReview/workflows/task.alf)
==============================================================================
--- AlphaFlow/trunk/doc/examples/MusicReview/workflows/task.alf (original)
+++ AlphaFlow/trunk/doc/examples/MusicReview/workflows/review.alf Tue Jun 21
09:35:09 2005
(at)(at) -1,39 +1,43 (at)(at)
<?xml version="1.0" encoding="iso-8859-1"?>
-<workflow id="task"
- title="Demo: Assigning a task"
- description="A member is assigned the task of editing the
- content object. This is one of the simplest
- possible AlphaFlow workflows."
- startActivity="give_to_assignee"
- onlyAllowRoles="Manager,Reviewer,Member">
-
- <permission-change id="give_to_assignee"
- title="Make object editable by assignee"
- continue_activity="edit_object">
-
- <permission id="Modify portal content"
- acquire="False"
- roles="Manager,Owner,Assignee" />
-
- </permission-change>
-
- <task id="edit_object"
- title="Edit the content object"
- completion_activity="take_from_assignee">
-
- <assignees kind="possible"
- roles="Member" />
-
- </task>
-
- <permission-change id="take_from_assignee"
- title="Make object read-only for assignee">
-
- <permission id="Modify portal content"
- acquire="True"
- roles="Manager,Owner" />
-
- </permission-change>
+<workflow id="review"
+ title="Create a new music review"
+ description="A new music review is requested and reviewed."
+ startActivity="configure, dc_private"
+ onlyAllowRoles="Manager Reviewer">
+
+ <configuration
+ id="configure"
+ title="Select author"
+ configures="write_review"
+ continue_activity="write_review"
+ >
+ <assignees kind="actual"
expression="python:[object.owner_info()['id']]"/>
+ </configuration>
+
+ <task id="write_review"
+ title="Write a music review"
+ completion_activity="review_review dc_pending"
+ content_roles="Editor"
+ >
+ <assignees kind="possible" roles="Member" />
+ </task>
+
+ <decision id="review_review"
+ decision_notice=""
+ title="Check review for spelling and bad language."
+ accept_activity="dc_public"
+ reject_activity="write_review"
+ decision_modus="all_yes">
+ <assignees kind="actual"
expression="python:[object.owner_info()['id']]"/>
+ </decision>
+
+ <dcworkflow id="dc_private" status="private"
+ title="Label as private"/>
+ <dcworkflow id="dc_pending" status="pending"
+ title="Label as pending"/>
+
+ <dcworkflow id="dc_public" status="public"
+ title="Label as public"/>
</workflow>
|
SVN: r3041 - in AlphaFlow/trunk: . activities adapters tests tests/workflows
Michael Howitz <mh(at)gocept.com> |
2005-06-21 17:34:50 |
[ FULL ]
|
Author: mac
Date: Tue Jun 21 17:35:57 2005
New Revision: 3041
Modified:
AlphaFlow/trunk/activities/gates.py
AlphaFlow/trunk/activities/interfaces.py
AlphaFlow/trunk/activities/review.py
AlphaFlow/trunk/activities/task.py
AlphaFlow/trunk/activity.py
AlphaFlow/trunk/adapters/activitiesadapter.py
AlphaFlow/trunk/interfaces.py
AlphaFlow/trunk/process.py
AlphaFlow/trunk/tests/test_definition.py
AlphaFlow/trunk/tests/test_editor.py
AlphaFlow/trunk/tests/workflows/cachetest.alf
AlphaFlow/trunk/tests/workflows/catalog_security.alf
AlphaFlow/trunk/tests/workflows/condition.alf
AlphaFlow/trunk/tests/workflows/configuration_all.alf
AlphaFlow/trunk/tests/workflows/decision.alf
AlphaFlow/trunk/tests/workflows/email.alf
AlphaFlow/trunk/tests/workflows/expression_assign.alf
AlphaFlow/trunk/tests/workflows/expressionn_assign.alf
AlphaFlow/trunk/tests/workflows/getviewurl.alf
AlphaFlow/trunk/tests/workflows/multi_review.alf
AlphaFlow/trunk/tests/workflows/multi_review_with_config.alf
AlphaFlow/trunk/tests/workflows/routing_example.alf
AlphaFlow/trunk/tests/workflows/task.alf
Log:
zwischenstand xml export fuer roman
Modified: AlphaFlow/trunk/activities/gates.py
==============================================================================
--- AlphaFlow/trunk/activities/gates.py (original)
+++ AlphaFlow/trunk/activities/gates.py Tue Jun 21 17:35:57 2005
(at)(at) -8,12 +8,13 (at)(at)
from Products.AlphaFlow.workitem import registerWorkItem, BaseWorkItem
from Products.AlphaFlow.activity import registerActivity,
BaseAutomaticActivity
from Products.AlphaFlow.exception import ConfigurationError
-from Products.AlphaFlow.interfaces import IDaemonActivity
+from Products.AlphaFlow.interfaces import IDaemonActivity, IGateActivity
class GateActivity(BaseAutomaticActivity):
- __implements__ = BaseAutomaticActivity.__implements__ + (IDaemonActivity,)
+ __implements__ = BaseAutomaticActivity.__implements__ + (IDaemonActivity,
+ IGateActivity)
meta_type = "AlphaFlow Gate Activity"
activity_type = "gate"
Modified: AlphaFlow/trunk/activities/interfaces.py
==============================================================================
--- AlphaFlow/trunk/activities/interfaces.py (original)
+++ AlphaFlow/trunk/activities/interfaces.py Tue Jun 21 17:35:57 2005
(at)(at) -175,6 +175,9 (at)(at)
class IRoutingWorkItem(IWorkItem):
"""a Routing workitem"""
+class IGateActivity(IAutomaticActivity):
+ """Gate to support routing mechanisms."""
+
class IConfigurationActivity(IAssignableActivity):
"""configuration activity
(at)(at) -189,6 +192,7 (at)(at)
"""WorkItem simulating DC Workflow state changes"""
+
### Deprecated stuff
Modified: AlphaFlow/trunk/activities/review.py
==============================================================================
--- AlphaFlow/trunk/activities/review.py (original)
+++ AlphaFlow/trunk/activities/review.py Tue Jun 21 17:35:57 2005
(at)(at) -23,8 +23,12 (at)(at)
from Products.AlphaFlow.action import Action
+ # deprecated, use DecisionActivity instead
class ReviewActivity(BaseAssignableActivity):
- """assignable review / user based"""
+ """assignable review / user based
+
+ DEPRECATED, use DecisionActivity instead
+ """
__implements__ = (IReviewActivity,) +
BaseAssignableActivity.__implements__
(at)(at) -96,7 +100,7 (at)(at)
'label':'on accept'})
return acts
-
+ # deprecated, use DecisionActivity instead
class RolebasedReviewActivity(ReviewActivity):
activity_type = 'rolebased-review'
(at)(at) -104,6 +108,7 (at)(at)
+ # deprecated, use DecisionActivity instead
class ReviewWorkItem(BaseAssignableWorkItem):
__implements__ = (IReviewWorkItem,) +
BaseAssignableWorkItem.__implements__
(at)(at) -231,6 +236,7 (at)(at)
+# deprecated, use DecisionActivity instead
class RolebasedReviewWorkItem(ReviewWorkItem):
activity_type = 'rolebased-review'
(at)(at) -288,4 +294,3 (at)(at)
registerWorkItem(ReviewWorkItem)
registerWorkItem(RolebasedReviewWorkItem)
-
Modified: AlphaFlow/trunk/activities/task.py
==============================================================================
--- AlphaFlow/trunk/activities/task.py (original)
+++ AlphaFlow/trunk/activities/task.py Tue Jun 21 17:35:57 2005
(at)(at) -18,6 +18,7 (at)(at)
registerActivity, BaseAssignableActivity
from Products.AlphaFlow import config, utils
from Products.AlphaFlow.action import Action
+from Products.AlphaFlow.exception import ConfigurationError
class TaskActivity(BaseAssignableActivity):
(at)(at) -61,7 +62,9 (at)(at)
utils.flexSplit(node.getAttribute("completion_activity").encode("ascii"))
)
if node.hasAttribute("assignees"):
- self.assignees = node.getAttribute("assignees")
+ raise ConfigurationError, \
+ "The assignees attribute is deprecated, use assignees tag
instead!"
+# self.assignees = node.getAttribute("assignees")
def graphGetPossibleChildren(self):
"""Return a list of possible following activities. (List of ids)"""
Modified: AlphaFlow/trunk/activity.py
==============================================================================
--- AlphaFlow/trunk/activity.py (original)
+++ AlphaFlow/trunk/activity.py Tue Jun 21 17:35:57 2005
(at)(at) -44,7 +44,7 (at)(at)
has = node.hasAttribute
get = node.getAttribute
if has("title"):
- self.title = get('title').encode("utf-8")
+ self.title = get('title')#.encode("utf-8")
if has("sort"):
pri = get('sort')
try:
(at)(at) -93,10 +93,6 (at)(at)
xml = adapter.getXML()
return xml
- def getProperties(self):
- """returns the properties of the activity"""
- adapter = getActivitiesAdapter(self)
- return adapter.getProperties()
InitializeClass(BaseActivity)
(at)(at) -245,7 +241,7 (at)(at)
security.declarePrivate('_parse_assignee')
def _parse_assignee(self, assignee):
"""helper for configureFromDOMNode
- """
+ """
has = assignee.hasAttribute
get = assignee.getAttribute
Modified: AlphaFlow/trunk/adapters/activitiesadapter.py
==============================================================================
--- AlphaFlow/trunk/adapters/activitiesadapter.py (original)
+++ AlphaFlow/trunk/adapters/activitiesadapter.py Tue Jun 21 17:35:57 2005
(at)(at) -4,173 +4,298 (at)(at)
# python imports
from types import TupleType, StringType
+from xml.dom import minidom
# sibling imports
-from Products.AlphaFlow.interfaces import ITaskActivity,\
- IDecisionActivity, IAlarmActivity, IDCWorkFlowActivity
+from Products.AlphaFlow import interfaces
from Products.AlphaFlow.adapters import adapter
+
+#####################
+# abstract activities
+
class ActivityAdapter(adapter.Adapter):
"""Baseclass for all activity adapters."""
- # properties in activity (source in XML-File/request.form, attribute on
activity)
- _properties = (('id', None), # id is handled separately
- ('title', 'title'), )
+ # properties in activity (attribute name in XML-File,
+ # attribute name on activity,
+ # default if not evaluates to False)
+ _simple_properties = (('id', None, False), # id is handled separately
+ ('title', 'title', False),
+ ('sort', 'sortPriority', False),
+ ('nonEditableFields', 'nonEditableFields', False),
+ ('startActivity', 'startActivity', False),
+ )
+
+ def writeDOM(self, node):
+ """Get the activity as XML-MiniDom.
+
+ node ... node or document
+ Returns the created activity node
+ """
+ if hasattr(node, 'ownerDocument') and node.ownerDocument is not None:
+ doc = node.ownerDocument # node inside
+ else:
+ doc = node # Document itself
+ activity =
node.appendChild(doc.createElement(self.context.activity_type))
+ self._writeSimplePropertiesToDOM(activity)
+ self._writeComplexPropertiesToDOM(activity)
+ return activity
+
+ def getXML(self):
+ """Get the activity as string XML document."""
+ doc = minidom.Document()
+ self.writeDOM(doc)
+ return doc.toxml()
- def changeProperties(self, form):
- """Change the property values of the activity.
+ def _writeComplexPropertiesToDOM(self, node):
+ """Write properties not in self._simple_properties to given dom
node."""
+ pass
- form ... dict {'prop-name': prop-value}
- """
- for src, dest in self._properties:
- if src == 'id':
- continue
- setattr(self.context, dest, form.get(src,
- getattr(self.context, dest)))
-
- def getProperties(self):
- """Get properties of activity as a dict."""
- res = {}
- for dict_key, attr_name in self._properties:
- if dict_key == 'id':
+
+ def _writeSimplePropertiesToDOM(self, node):
+ """Write self._simple_properties to given dom node."""
+ for xml_attr, python_attr, default in self._simple_properties:
+ if xml_attr == 'id':
value = self.context.getId()
else:
- value = getattr(self.context, attr_name)
- if value is not None:
- res[dict_key] = value
- return res
-
+ value = getattr(self.context, python_attr)
+ if (default and value != default) or \
+ (not default and value):
+ node.setAttribute(xml_attr, self._convertToXML(value))
+
+
+ def _convertToXML(self, value):
+ """Convert a value to XML notation."""
+ if isinstance(value, basestring):
+ return value
+ elif isinstance(value, tuple) or isinstance(value, list):
+ return ' '.join(value)
+ elif isinstance(value, int):
+ return str(value)
+ raise ValueError, "Don't know how to handle '%s'." % value
+
class BaseAutomaticActivityAdapter(ActivityAdapter):
- _properties = ActivityAdapter._properties + \
- (('continue_activity', 'continue_activity'),
- )
+ _simple_properties = ActivityAdapter._simple_properties + \
+ (('continue_activity', 'continue_activity', False),
+ )
class BaseAssignableActivityAdapter(ActivityAdapter):
- _properties = ActivityAdapter._properties + \
- (('roles', 'roles'),
- ('kind', 'assigneesKind'),
- ('expression', 'assigneesExpression'),
- )
+ _simple_properties = ActivityAdapter._simple_properties + \
+ (('view_url_expr',
+ 'viewUrlExpression',
+ 'string:${content/absolute_url}/view'),
+ ('content_roles', 'contentRoles', False)
+ )
+
+ def _writeComplexPropertiesToDOM(self, node):
+ """Write properties not in self._simple_properties to given dom
node."""
+ BaseAssignableActivityAdapter.inheritedAttribute(
+ '_writeComplexPropertiesToDOM')(self, node)
+ if self.context.assigneesKind == "possible" and self.context.roles ==
():
+ return # no assignees tag on default behavior
+ el = node.ownerDocument.createElement('assignees')
+ assignees = node.appendChild(el)
+ data = (('kind', 'assigneesKind'),
+ ('roles', 'roles'),
+ ('expression', 'assigneesExpression'),
+ )
+ for xml_attr, python_attr in data:
+ value = getattr(self.context, python_attr)
+ if value is not None:
+ assignees.setAttribute(xml_attr, self._convertToXML(value))
+
+
+class BaseTalesActivityAdapter(BaseAutomaticActivityAdapter):
+
+ _simple_properties = ActivityAdapter._simple_properties + \
+ (('expression', 'expression', False),
+ )
+
+#####################
+# concrete activities
-class BaseTalesActivityAdapter(ActivityAdapter):
- _properties = ActivityAdapter._properties + \
- (('expression', 'expression'),
- )
-class TaskActivityAdapter(ActivityAdapter):
- _properties = ActivityAdapter._properties + \
- (('title', 'title'),
- ('roles', 'roles'),
- ('completion_activity', 'completion_activity'))
+class TaskActivityAdapter(BaseAssignableActivityAdapter):
+
+ _simple_properties = ActivityAdapter._simple_properties + \
+ (('completion_activity', 'completion_activity',
False),
+ )
-class DecisionActivityAdapter(BaseAssignableActivityAdapter):
- _properties = BaseAssignableActivityAdapter._properties + \
- (('roles', 'roles'),
- ('decision_notice', 'decision_notice'),
- ('decision_modus', 'decision_modus'))
-
-
- def changeProperties(self, form):
- """changes properties on activities"""
- DecisionActivityAdapter.inheritedAttribute('changeProperties')(self,
form)
- childs = self.context.acquireProcess().listActivityIds()
- tuples = ['reject_activity', 'accept_activity']
-
- for t in tuples:
- act = form.get(t, getattr(self.context, t))
-
- if type(act) is TupleType:
- for a in act:
- if a not in childs:
- return
-
- if type(act) is StringType and\
- act in childs:
- act = (act,)
-
- setattr(self.context, t, act)
-
-
- def getProperties(self):
- result =
DecisionActivityAdapter.inheritedAttribute('getProperties')(self)
- properties = ['reject_activity',
- 'accept_activity']
- for prop in properties:
- result[prop] = getattr(self.context, prop)
+class RoutingActivityAdapter(ActivityAdapter):
- return result
+ def _writeComplexPropertiesToDOM(self, node):
+ RoutingActivityAdapter.inheritedAttribute(
+ '_writeComplexPropertiesToDOM')(self, node)
+ process = self.context.acquireProcess()
+ for activity_id in self.context.routes + self.context.gates:
+ adapter = getActivitiesAdapter(process[activity_id])
+ adapter.writeDOM(node)
+
+class RecursionActivityAdapter(BaseAutomaticActivityAdapter):
+
+ _simple_properties = BaseAutomaticActivityAdapter._simple_properties + \
+ (('recursion_activity', 'recursion_activity', False),
+ ('break_activities', 'break_activities', False),
+ ('optional_recursion', 'optional_recursion', 1),
+ )
+
+class PermissionActivityAdapter(BaseAutomaticActivityAdapter):
+
+ def _writeComplexPropertiesToDOM(self, node):
+ PermissionActivityAdapter.inheritedAttribute(
+ '_writeComplexPropertiesToDOM')(self, node)
+ doc = node.ownerDocument
+ perm_attrs = (('id', 'permission'),
+ ('roles', 'roles'),
+ ('acquire', 'acquire'),
+ )
+ for permObj in self.context.permissions:
+ perm = node.appendChild(doc.createElement('permission'))
+ for xml_attr, py_attr in perm_attrs:
+ perm.setAttribute(xml_attr,
+ self._convertToXML(getattr(permObj,
+ py_attr)))
+
+class NTaskActivityAdapter(BaseAssignableActivityAdapter):
+
+ def _writeComplexPropertiesToDOM(self, node):
+ NTaskActivityAdapter.inheritedAttribute(
+ '_writeComplexPropertiesToDOM')(self, node)
+ doc = node.ownerDocument
+ exit_attrs = (('id', 'id'),
+ ('title', 'title'),
+ ('activities', 'activities'),
+ )
+ for exitObj in self.context.exits:
+ exit_node = node.appendChild(doc.createElement('exit'))
+ for xml_attr, py_attr in exit_attrs:
+ exit_node.setAttribute(xml_attr,
+ self._convertToXML(getattr(exitObj,
+ py_attr)))
+
+class EMailActivityAdapter(BaseAutomaticActivityAdapter):
+
+ _simple_properties = BaseAutomaticActivityAdapter._simple_properties + \
+ (('template', 'template', False),
+ ('mailSubject',
+ 'mailSubject',
+ 'AlphaFlow notification message'),
+ )
+ def _writeComplexPropertiesToDOM(self, node):
+ EMailActivityAdapter.inheritedAttribute(
+ '_writeComplexPropertiesToDOM')(self, node)
+ doc = node.ownerDocument
+ for recObj in self.context.getRecipientModes():
+ rec_node = node.appendChild(doc.createElement('recipient'))
+ mode_name = recObj.mode_name
+ rec_node.setAttribute('type', mode_name)
+ if mode_name == 'actual_role':
+ rec_node.setAttribute('roles',
+ self._convertToXML(recObj.roles))
- def getXML(self):
- element = "<decision\n"
- assignees_tag = "><assignees\n"
- properties = self.getProperties()
- for key, val in properties.items():
- if key in ['kind', 'roles']:
- assignees_tag += """\t%s="%s"\n""" %(key, val)
- else:
- element += """\t%s="%s"\n""" %(key, val)
+class GateActivityAdapter(BaseAutomaticActivityAdapter):
+
+ _simple_properties = BaseAutomaticActivityAdapter._simple_properties + \
+ (('mode', 'mode', False),
+ )
+
- element += '%s />' % assignees_tag
- element += '</decision>'
- return element
-
-class AlarmActivityAdapter(ActivityAdapter):
- pass
-# XXX untested!
-# def changeProperties(self, form):
-# from Products.PageTemplates.Expressions import getEngine
-# expr = form.get('expression', self.context.expression)
-# engine = getEngine()
-# expr = engine.compile(expr)
-# context = engine.getContext()
-# try:
-# context.evaluate(expr)
-# except KeyError:
-# return
-# self.context.expression = expr
-# self._changePropertiesHelper(form)
-
+class DecisionActivityAdapter(BaseAssignableActivityAdapter):
+ _simple_properties = BaseAssignableActivityAdapter._simple_properties + \
+ (('decision_notice', 'decision_notice', False),
+ ('decision_modus', 'decision_modus', False),
+ ('reject_activity', 'reject_activity', False),
+ ('accept_activity', 'accept_activity', False),
+ )
+
class DCWorkFlowActivityAdapter(BaseAutomaticActivityAdapter):
-# XXX what's that?
-# def changePropertiesHelper(self, form):
-# self._changePropertiesHelper(form)
-# newstatus = form.get('status', self.context.status)
-# if newstatus in self.context.status_options:
-# self.context.status = newstatus
-
- _properties = BaseAutomaticActivityAdapter._properties + \
- (('status', 'status'),
- )
-
+ _simple_properties = BaseAutomaticActivityAdapter._simple_properties + \
+ (('status', 'status', False),
+ )
+
+class ConfigurationActivityAdapter(BaseAssignableActivityAdapter):
+
+ _simple_properties = BaseAssignableActivityAdapter._simple_properties + \
+ (('continue_activity', 'continue_activity', False),
+ )
+
+ def _writeComplexPropertiesToDOM(self, node):
+ ConfigurationActivityAdapter.inheritedAttribute(
+ '_writeComplexPropertiesToDOM')(self, node)
+ if self.context.configures is None: # marker for "all"
+ node.setAttribute('configures_all', 'true')
+ else:
+ node.setAttribute('configures',
+ self._convertToXML(self.context.configures))
+
+class ConditionActivityAdapter(BaseTalesActivityAdapter):
+
+ _simple_properties = BaseTalesActivityAdapter._simple_properties + \
+ (('continue_activity', 'continue_activity', False),
+ )
+
+# deprected
+class ReviewActivityAdapter(BaseAssignableActivityAdapter):
+
+ _simple_properties = BaseAssignableActivityAdapter._simple_properties + \
+ (('review_notice', 'review_notice', False),
+ ('reject_activity', 'reject_activity', False),
+ ('accept_activity', 'accept_activity', False),
+ )
- def getXML(self):
- properties = self.getProperties()
- return """<dcworkflow id="%s" status="%s" />"""\
- %(properties['id'], properties['status'])
def getActivitiesAdapter(context):
- if ITaskActivity.isImplementedBy(context):
- return TaskActivityAdapter(context).__of__(context)
-
- if IDecisionActivity.isImplementedBy(context):
- return DecisionActivityAdapter(context).__of__(context)
-
- if IAlarmActivity.isImplementedBy(context):
- return AlarmActivityAdapter(context).__of__(context)
+ if interfaces.ITaskActivity.isImplementedBy(context):
+ a = TaskActivityAdapter
+ elif interfaces.IRoutingActivity.isImplementedBy(context):
+ a = RoutingActivityAdapter
+ elif interfaces.IPermissionActivity.isImplementedBy(context):
+ a = PermissionActivityAdapter
+ elif interfaces.INTaskActivity.isImplementedBy(context):
+ a = NTaskActivityAdapter
+ elif interfaces.IEMailActivity.isImplementedBy(context):
+ a = EMailActivityAdapter
+ elif interfaces.IGateActivity.isImplementedBy(context):
+ a = GateActivityAdapter
+ elif interfaces.IExpressionActivity.isImplementedBy(context):
+ a = BaseTalesActivityAdapter # ExpressionActivity is alike
BaseTalesActivity
+ elif interfaces.IDecisionActivity.isImplementedBy(context):
+ a = DecisionActivityAdapter
+ elif interfaces.IDCWorkFlowActivity.isImplementedBy(context):
+ a = DCWorkFlowActivityAdapter
+ elif interfaces.IConfigurationActivity.isImplementedBy(context):
+ a = ConfigurationActivityAdapter
+ elif interfaces.IConditionActivity.isImplementedBy(context):
+ a = ConditionActivityAdapter
+ elif interfaces.IAlarmActivity.isImplementedBy(context):
+ a = BaseTalesActivityAdapter # AlarmActivity is alike
BaseTalesActivity
+ elif interfaces.IReviewActivity.isImplementedBy(context):
+ a = ReviewActivityAdapter # deprecated
+ # recursion
+ elif interfaces.IDaemonActivity.isImplementedBy(context):
+ a = RecursionActivityAdapter
+ # versioning
+ elif interfaces.IAutomaticActivity.isImplementedBy(context):
+ a = BaseAutomaticActivityAdapter
+ else:
+ a = None
+
+ if a is not None:
+ return a(context).__of__(context)
+ raise ValueError, "No adapter for %s" % context
- if IDCWorkFlowActivity.isImplementedBy(context):
- return DCWorkFlowActivityAdapter(context).__of__(context)
Modified: AlphaFlow/trunk/interfaces.py
==============================================================================
--- AlphaFlow/trunk/interfaces.py (original)
+++ AlphaFlow/trunk/interfaces.py Tue Jun 21 17:35:57 2005
(at)(at) -252,14 +252,18 (at)(at)
format
REQUEST
"""
+ def changeProcessProperties(REQUEST):
+ """changes the workflow properties"""
+
def getProcessDOM():
"""returns XML for self as dom node"""
def getProcessXML(REQUEST=None):
- """returns XML as a string containing editor information"""
+ """Returns XML as a string containing editor information"""
+
+ def exportAsXML():
+ """Exports process as XML-String."""
- def changeProcessProperties(REQUEST):
- """changes the workflow properties"""
class IActivity(IDOMConfigurable):
"""A workflow activity.
Modified: AlphaFlow/trunk/process.py
==============================================================================
--- AlphaFlow/trunk/process.py (original)
+++ AlphaFlow/trunk/process.py Tue Jun 21 17:35:57 2005
(at)(at) -23,6 +23,7 (at)(at)
from Products.AlphaFlow.activity import \
listActivities, getActivity
from Products.AlphaFlow.adapters.renderableadapter import getRenderableAdapter
+from Products.AlphaFlow.adapters.activitiesadapter import getActivitiesAdapter
manage_addProcessForm=PageTemplateFile('www/addProcess', globals())
def manage_addProcess(self, id, REQUEST=None):
(at)(at) -128,23 +129,40 (at)(at)
activity = self.addActivity(act_id, act_type)
activity.configureFromDOMNode(act_node)
+ security.declareProtected(config.EDIT_WORKFLOW, "getGraph")
+ def renderGraph(self, **kwargs):
+ """returns the rendered Graph
+ pass additional keyword arguments for
+
+ contenttype
+ format
+ REQUEST
+ """
+ adapter = getRenderableAdapter(self)
+ return adapter.renderGraph(**kwargs)
+
+
security.declareProtected(config.MANAGE_WORKFLOW, 'getProcessDOM')
def getProcessDOM(self):
"""returns XML for self as dom node"""
xmlstr = "<workflow></workflow>"
- start_activities = ",".join(self.startActivity)
- roles = ",".join(self.roles)
+ start_activities = " ".join(self.startActivity)
+ roles = " ".join(self.roles)
+
+ attr_map = (('title', self.title),
+ ('startActivity', start_activities),
+ ('description', self.description),
+ ('onlyAllowRoles', roles),
+ )
dom = minidom.parseString(xmlstr)
- dom.documentElement.setAttribute('title', self.title)
- dom.documentElement.setAttribute('startActivity',
- start_activities)
- dom.documentElement.setAttribute('description',
- self.description)
- dom.documentElement.setAttribute('onlyAllowRoles', roles)
+ for attr, value in attr_map:
+ if value:
+ dom.documentElement.setAttribute(attr, value)
return dom
+
security.declareProtected(config.MANAGE_WORKFLOW, 'getProcessXML')
def getProcessXML(self, REQUEST=None):
"""returns XML as a string containing editor information"""
(at)(at) -159,6 +177,27 (at)(at)
return dom.toxml()
+ security.declareProtected(config.MANAGE_WORKFLOW, 'exportAsXML')
+ def exportAsXML(self):
+ """Exports process as XML-String."""
+ doc = self.getProcessDOM()
+ workflow = doc.getElementsByTagName('workflow')[0]
+ for activitiy in self.objectValues():
+ act_adapt = getActivitiesAdapter(activitiy)
+ if act_adapt is None:
+ continue # no adapter found
+ act_dom = act_adapt.writeDOM(workflow)
+ # remove activites which are inside routing activities and outside,
too
+ routes = doc.getElementsByTagName('route')
+ inside_routes = []
+ for route in routes:
+ for child in route.childNodes:
+ inside_routes.append(child.getAttribute('id'))
+ for node in workflow.childNodes[:]:
+ if node.getAttribute('id') in inside_routes:
+ workflow.removeChild(node)
+ return doc.toxml()
+
security.declareProtected(config.MANAGE_WORKFLOW,
'changeProcessProperties')
def changeProcessProperties(self, REQUEST):
(at)(at) -182,17 +221,5 (at)(at)
def _set_allowed_roles_restriction(self, roles):
roles = tuple(roles) # do not acquire
utils.modifyRolesForPermission(self, config.INIT_PROCESS, roles)
-
- security.declareProtected(config.EDIT_WORKFLOW, "getGraph")
- def renderGraph(self, **kwargs):
- """returns the rendered Graph
- pass additional keyword arguments for
-
- contenttype
- format
- REQUEST
- """
- adapter = getRenderableAdapter(self)
- return adapter.renderGraph(**kwargs)
InitializeClass(Process)
Modified: AlphaFlow/trunk/tests/test_definition.py
==============================================================================
--- AlphaFlow/trunk/tests/test_definition.py (original)
+++ AlphaFlow/trunk/tests/test_definition.py Tue Jun 21 17:35:57 2005
(at)(at) -10,6 +10,7 (at)(at)
from random import shuffle
from StringIO import StringIO
from tempfile import mktemp
+from xml.dom import minidom
from Testing import ZopeTestCase
(at)(at) -38,6 +39,7 (at)(at)
from Products.AlphaFlow.action import Action
from Products.AlphaFlow.activities.review import ReviewWorkItem,
ReviewActivity
from Products.AlphaFlow.utils import flexSplit
+from Products.AlphaFlow.exception import ConfigurationError
_chars = 'abcdefghijklmnopqrstuvwxyz'
_ids_used = {}
(at)(at) -67,12 +69,13 (at)(at)
(IWorkItem, BaseWorkItem),
(IAutomaticWorkItem, BaseAutomaticWorkItem),
(IAction, Action),
+ (IProcess, Process),
(IReviewActivity, ReviewActivity),
(IReviewWorkItem, ReviewWorkItem)] + \
- [ (IActivity, getActivity(act_id))
- for act_id in listActivities() ] + \
- [ (IWorkItem, getWorkItemClass(wi_id))
- for wi_id in listWorkItems() ]
+ [(IActivity, getActivity(act_id))
+ for act_id in listActivities() ] + \
+ [(IWorkItem, getWorkItemClass(wi_id))
+ for wi_id in listWorkItems()]
def test_xml_import(self):
(at)(at) -80,6 +83,66 (at)(at)
portal = self.getPortal()
alf = getToolByName(portal, "workflow_manager")
test = alf.getProcess('test')
+
+ def test_xml_export(self):
+ def _find_in_dom(dom, tagname, id):
+ for tag in dom.getElementsByTagName(tagname):
+ if tag.getAttribute('id') == id:
+ return tag
+ portal = self.getPortal()
+ alf = getToolByName(portal, "workflow_manager")
+ wf_dir = os.path.join(os.path.dirname(__file__), "workflows")
+
+ for wf_name in os.listdir(wf_dir):
+ if not wf_name.endswith('.alf'):
+ continue
+ wf_file = file(os.path.join(wf_dir, wf_name))
+ try:
+ alf.importWorkflowFromXML("test", wf_file)
+ except ConfigurationError:
+ alf.deleteProcess('test')
+ continue
+ wf_file.seek(0)
+ test = alf.getProcess('test')
+ print wf_name
+ test.exportAsXML().encode('utf8')
+ got_dom = minidom.parseString(str(test.exportAsXML()))
+ exp_dom = minidom.parseString(wf_file.read())
+ got_elems = got_dom.getElementsByTagName("*")
+ exp_elems = exp_dom.getElementsByTagName("*")
+ self.assertEqual(len(exp_elems),
+ len(got_elems),
+ "%s: exp: %s\ngot: %s" % (wf_name, exp_elems,
got_elems))
+ for got_tag in got_dom.getElementsByTagName("*"):
+ exp_tag = _find_in_dom(exp_dom, got_tag.nodeName,
+ got_tag.getAttribute('id'))
+ if exp_tag is None:
+ import pdb; pdb.set_trace() #############################
+ self.failIf(exp_tag is None)
+ self.assertEqual(exp_tag.parentNode.nodeName,
+ got_tag.parentNode.nodeName)
+ if exp_tag.parentNode.ownerDocument is not None: # no Document
+ self.assertEqual(exp_tag.parentNode.getAttribute('id'),
+ got_tag.parentNode.getAttribute('id'))
+ else:
+ self.failUnless(got_tag.parentNode.ownerDocument is None)
+ self.assertEqual(len(exp_tag.attributes),
+ len(got_tag.attributes),
+ "%s: exp: %s\ngot: %s" % (wf_name,
+
exp_tag.attributes.items(),
+
got_tag.attributes.items())
+ )
+
+ got_attribs_keys = got_tag.attributes.keys()
+ exp_attribs_keys = exp_tag.attributes.keys()
+ got_attribs_keys.sort()
+ exp_attribs_keys.sort()
+ self.assertEqual(exp_attribs_keys, got_attribs_keys)
+ for key in got_attribs_keys:
+ self.assertEqual(exp_tag.getAttribute(key),
+ got_tag.getAttribute(key))
+ alf.deleteProcess('test')
+
def test_definition(self):
# Creates a simple workflow
Modified: AlphaFlow/trunk/tests/test_editor.py
==============================================================================
--- AlphaFlow/trunk/tests/test_editor.py (original)
+++ AlphaFlow/trunk/tests/test_editor.py Tue Jun 21 17:35:57 2005
(at)(at) -27,7 +27,7 (at)(at)
class AlphaFlowEditorTest(AlphaFlowTestCase):
interfaces_to_test = [(IAlphaFlowEditor, AlphaFlowEditor),
- (IProcess, Process)]
+ ]
def _import_wf(self, wfpath):
portal = self.getPortal()
(at)(at) -60,104 +60,6 (at)(at)
# now
self.assert_(gif.startswith('GIF89'))
- def test_editTaskActivity(self):
- prop = {'roles':"Manager",
- 'completion_activity':'notify',
- 'title':'Neu benachrichtigen'}
- self._import_wf("workflows/alarm_review.alf")
- portal = self.getPortal()
- editor = getToolByName(portal, 'workflow_editor')
- task = editor.processes.test.edit_ticket
- adapter = getActivitiesAdapter(task)
- adapter.changeProperties(prop)
-
- self.assert_(task.title == prop['title'])
- self.assert_(prop['completion_activity'] in
- task.completion_activity)
- self.assert_(prop['roles'] in task.roles)
-
- def test_editDecisionActivity(self):
- prop = {'decision_notice':'test decision notice',
- 'reject_activity':'deci_n',
- 'accept_activity':'private',
- 'decision_modus':'all_yes',
- 'title':'My decision'}
- self._import_wf("workflows/decision.alf")
- portal = self.getPortal()
- editor = getToolByName(portal, 'workflow_editor')
- decision = editor.processes.test.deci_1
- adapter = getActivitiesAdapter(decision)
- adapter.changeProperties(prop)
-
- self.assert_(prop['decision_notice'] == decision.decision_notice)
- self.assert_(prop['decision_modus'] in decision.decision_modus)
- self.assert_(prop['reject_activity'] in decision.reject_activity)
- self.assert_(prop['accept_activity'] in decision.accept_activity)
- self.assert_(prop['title'] == decision.title)
- self.assert_(prop['decision_modus'] == decision.decision_modus)
-
- propnew = {'reject_activity':('deci_n', 'private')}
- adapter.changeProperties(propnew)
- self.assert_(prop['decision_notice'] == decision.decision_notice)
- self.assert_(prop['decision_modus'] in decision.decision_modus)
- self.assert_(propnew['reject_activity'] == decision.reject_activity)
- self.assert_(prop['accept_activity'] in decision.accept_activity)
- self.assert_(prop['title'] == decision.title)
- self.assert_(prop['decision_modus'] == decision.decision_modus)
-
- adapter.changeProperties({'reject_activity':('deci_n',
- 'garbage')})
- self.assert_(propnew['reject_activity'] == decision.reject_activity)
-
- def test_getProperties(self):
- """correct activity properties test"""
- self._import_wf("workflows/decision.alf")
- portal = self.getPortal()
- editor = getToolByName(portal, 'workflow_editor')
- activities = editor.processes.test.objectValues()
-
- for act in activities:
- properties = act.getProperties()
- if properties['id'] == 'deci_1':
- expected = {'id':'deci_1',
- 'title':'',
- 'decision_notice':'first yes counts',
- 'accept_activity':('deci_n',),
- 'reject_activity':('private',),
- 'decision_modus':'first_yes',
- 'kind':'actual',
- 'roles': ('Reviewer',)}
- self.assertEqual(len(expected), len(properties),
- "properties has not the expected length!")
- self.assert_(expected == properties)
-
- if properties['id'] == 'deci_n':
- expected = {'id':'deci_n',
- 'title':'',
- 'decision_notice':'all yes counting',
- 'accept_activity':('public',),
- 'reject_activity':('private',),
- 'decision_modus':'all_yes',
- 'kind':'actual',
- 'roles': ('Editor','Reviewer')}
- self.assertEqual(len(expected), len(properties),
- "properties has not the expected length!")
- self.assert_(expected == properties)
-
- if properties['id'] == 'private':
- self.assert_({'id':'private',
- 'title':'',
- 'continue_activity': (),
- 'status':'private'} ==
- properties)
-
- if properties['id'] == 'public':
- self.assert_({'id':'public',
- 'title':'',
- 'continue_activity':(),
- 'status':'public'} ==
- properties)
-
# XML export tests
def test_decision_getXML(self):
(at)(at) -166,8 +68,8 (at)(at)
editor = getToolByName(portal, 'workflow_editor')
decision_expected = {'id':'deci_n',
'decision_notice':'all yes counting',
- 'accept_activity':"('public',)",
- 'reject_activity':"('private',)",
+ 'accept_activity':"public",
+ 'reject_activity':"private",
'decision_modus':'all_yes',
'title': '',
}
(at)(at) -175,6 +77,7 (at)(at)
xml = minidom.parseString(xml)
el = xml.getElementsByTagName('decision')[0]
+
self.assertEqual(len(el.attributes), len(decision_expected),
"The 'decision' element has not the amount of"\
" expected attributes.")
(at)(at) -183,7 +86,7 (at)(at)
"expected property %s not an xml attribute!" %prop)
assignees_expected = {'kind':'actual',
- 'roles':"('Editor', 'Reviewer')"}
+ 'roles':"Editor Reviewer"}
el = xml.getElementsByTagName('assignees')[0]
self.assertEqual(len(el.attributes.values()), len(assignees_expected),
"The 'assignees' element has not the amount of"\
Modified: AlphaFlow/trunk/tests/workflows/cachetest.alf
==============================================================================
--- AlphaFlow/trunk/tests/workflows/cachetest.alf (original)
+++ AlphaFlow/trunk/tests/workflows/cachetest.alf Tue Jun 21 17:35:57 2005
(at)(at) -1,9 +1,8 (at)(at)
<?xml version="1.0" encoding="iso-8859-1"?>
-<workflow title=""
+<workflow
startActivity="write_document"
- description=""
- onlyAllowRoles="Manager,Reviewer">
+ onlyAllowRoles="Manager Reviewer">
<!-- Write the document -->
<task id="write_document" title="Dokument schreiben" sort="1"
Modified: AlphaFlow/trunk/tests/workflows/catalog_security.alf
==============================================================================
--- AlphaFlow/trunk/tests/workflows/catalog_security.alf (original)
+++ AlphaFlow/trunk/tests/workflows/catalog_security.alf Tue Jun 21 17:35:57
2005
(at)(at) -1,4 +1,4 (at)(at)
-<?xml version="1.0" encoding="iso-8859-1"?>
+<?xml version="1.0" encoding="utf-8"?>
<workflow title=""
startActivity="recursion,make_private"
Modified: AlphaFlow/trunk/tests/workflows/condition.alf
==============================================================================
--- AlphaFlow/trunk/tests/workflows/condition.alf (original)
+++ AlphaFlow/trunk/tests/workflows/condition.alf Tue Jun 21 17:35:57 2005
(at)(at) -1,8 +1,7 (at)(at)
<?xml version="1.0" encoding="iso-8859-1"?>
-<workflow title=""
+<workflow
startActivity="cond_ac_1"
- description=""
onlyAllowRoles="Manager,Reviewer,Member">
<condition id="cond_ac_1"
Modified: AlphaFlow/trunk/tests/workflows/configuration_all.alf
==============================================================================
--- AlphaFlow/trunk/tests/workflows/configuration_all.alf (original)
+++ AlphaFlow/trunk/tests/workflows/configuration_all.alf Tue Jun 21 17:35:57
2005
(at)(at) -1,6 +1,6 (at)(at)
<?xml version="1.0" encoding="iso-8859-1"?>
- <workflow title=""
+ <workflow
startActivity="assign_task"
description="Test of configuration activity"
onlyAllowRoles="Manager,Reviewer,Member">
Modified: AlphaFlow/trunk/tests/workflows/decision.alf
==============================================================================
--- AlphaFlow/trunk/tests/workflows/decision.alf (original)
+++ AlphaFlow/trunk/tests/workflows/decision.alf Tue Jun 21 17:35:57 2005
(at)(at) -1,8 +1,7 (at)(at)
<?xml version="1.0" encoding="iso-8859-1"?>
-<workflow title=""
+<workflow
startActivity="deci_1"
- description=""
onlyAllowRoles="Manager,Reviewer,Member">
<decision id="deci_1"
Modified: AlphaFlow/trunk/tests/workflows/email.alf
==============================================================================
--- AlphaFlow/trunk/tests/workflows/email.alf (original)
+++ AlphaFlow/trunk/tests/workflows/email.alf Tue Jun 21 17:35:57 2005
(at)(at) -1,8 +1,7 (at)(at)
<?xml version="1.0" encoding="iso-8859-1"?>
-<workflow title=""
- startActivity="email1"
- description="">
+<workflow
+ startActivity="email1">
<email id="email1" title="Email versenden" sort="1"
template="default_email"
Modified: AlphaFlow/trunk/tests/workflows/expression_assign.alf
==============================================================================
--- AlphaFlow/trunk/tests/workflows/expression_assign.alf (original)
+++ AlphaFlow/trunk/tests/workflows/expression_assign.alf Tue Jun 21 17:35:57
2005
(at)(at) -3,7 +3,7 (at)(at)
<workflow title=""
startActivity="write_document"
description=""
- onlyAllowRoles="Manager,Reviewer">
+ onlyAllowRoles="Manager Reviewer">
<!-- Write the document -->
<task id="write_document" title="Dokument schreiben" sort="1"
Modified: AlphaFlow/trunk/tests/workflows/expressionn_assign.alf
==============================================================================
--- AlphaFlow/trunk/tests/workflows/expressionn_assign.alf (original)
+++ AlphaFlow/trunk/tests/workflows/expressionn_assign.alf Tue Jun 21 17:35:57
2005
(at)(at) -12,7 +12,7 (at)(at)
expression="object/test_assignees" />
</task>
- <dcworkflow id="dc_publish" title="" status="published"/>
+ <dcworkflow id="dc_publish" title="Publish" status="published"/>
</workflow>
Modified: AlphaFlow/trunk/tests/workflows/getviewurl.alf
==============================================================================
--- AlphaFlow/trunk/tests/workflows/getviewurl.alf (original)
+++ AlphaFlow/trunk/tests/workflows/getviewurl.alf Tue Jun 21 17:35:57 2005
(at)(at) -1,8 +1,7 (at)(at)
<?xml version="1.0" encoding="iso-8859-1"?>
-<workflow title=""
- startActivity="do_this do_that"
- description="">
+<workflow
+ startActivity="do_this do_that">
<task id="do_this"
view_url_expr="string:${content/absolute_url}/edit"
Modified: AlphaFlow/trunk/tests/workflows/multi_review.alf
==============================================================================
--- AlphaFlow/trunk/tests/workflows/multi_review.alf (original)
+++ AlphaFlow/trunk/tests/workflows/multi_review.alf Tue Jun 21 17:35:57 2005
(at)(at) -1,4 +1,4 (at)(at)
-<?xml version="1.0" encoding="iso-8859-1"?>
+<?xml version="1.0" encoding="utf-8"?>
<workflow id="multi_review"
title=""
Modified: AlphaFlow/trunk/tests/workflows/multi_review_with_config.alf
==============================================================================
--- AlphaFlow/trunk/tests/workflows/multi_review_with_config.alf (original)
+++ AlphaFlow/trunk/tests/workflows/multi_review_with_config.alf Tue Jun 21
17:35:57 2005
(at)(at) -77,7 +77,7 (at)(at)
<!-- reviewer -->
<review id="review_document1"
- title="Dokument prüfen"
+ title="Dokument prüfen"
sort="2"
review_notice="Bitte auf inhaltliche Ausgestaltung achten."
reject_activity="make_private"
(at)(at) -90,7 +90,7 (at)(at)
<!-- chief editor -->
<rolebased-review id="review_document2"
- title="Dokument prüfen (verantwortlicher Redakteur)"
+ title="Dokument prüfen (verantwortlicher Redakteur)"
sort="3"
review_notice="Bitte auf formelle Kriterien achten."
reject_activity="make_private"
(at)(at) -103,7 +103,7 (at)(at)
<!-- Publish the document -->
<permission-change id="publish"
- title="Öffentliche Rechte setzen"
+ title="Öffentliche Rechte setzen"
continue_activity="dc_publish">
<permission id="Access contents information"
Modified: AlphaFlow/trunk/tests/workflows/routing_example.alf
==============================================================================
--- AlphaFlow/trunk/tests/workflows/routing_example.alf (original)
+++ AlphaFlow/trunk/tests/workflows/routing_example.alf Tue Jun 21 17:35:57
2005
(at)(at) -1,7 +1,7 (at)(at)
<?xml version="1.0" encoding="iso-8859-1"?>
-<workflow id="routing_example"
- title=""
+<workflow
+ title="routing_example"
description=""
startActivity="review"
onlyAllowRoles="Manager,Reviewer">
Modified: AlphaFlow/trunk/tests/workflows/task.alf
==============================================================================
--- AlphaFlow/trunk/tests/workflows/task.alf (original)
+++ AlphaFlow/trunk/tests/workflows/task.alf Tue Jun 21 17:35:57 2005
(at)(at) -3,7 +3,7 (at)(at)
<workflow title="Testworkflow"
startActivity="edit"
description="Blubb"
- onlyAllowRoles="Manager,Reviewer,Member">
+ onlyAllowRoles="Manager Reviewer Member">
<task id="edit"
title="Dokument bearbeiten" sort="1"
|
SVN: r3043 - in AlphaFlow/trunk/editor/views: ecmascript panels
Roman Joost <rj(at)gocept.com> |
2005-06-22 08:37:36 |
[ FULL ]
|
Author: roman
Date: Wed Jun 22 08:39:10 2005
New Revision: 3043
Modified:
AlphaFlow/trunk/editor/views/ecmascript/base.js.dtml
AlphaFlow/trunk/editor/views/ecmascript/editor.js.dtml
AlphaFlow/trunk/editor/views/ecmascript/helper.js.dtml
AlphaFlow/trunk/editor/views/ecmascript/message_dialog.js.dtml
AlphaFlow/trunk/editor/views/panels/attributes.pt
AlphaFlow/trunk/editor/views/panels/messages.pt
AlphaFlow/trunk/editor/views/panels/toolbox.pt
Log:
- Changed behaviour of the editor a bit: Only the toolbox is now
unfolded, other panels are folded. A panel is automatically unfolded
if eg. an item needs to be displayed in the panel.
Modified: AlphaFlow/trunk/editor/views/ecmascript/base.js.dtml
==============================================================================
--- AlphaFlow/trunk/editor/views/ecmascript/base.js.dtml (original)
+++ AlphaFlow/trunk/editor/views/ecmascript/base.js.dtml Wed Jun 22 08:39:10
2005
(at)(at) -22,6 +22,20 (at)(at)
this.init = function() {
this.base_url = this.getBaseURI()
+ var panelbox = document.getElementById('Panels')
+ var buttons = panelbox.getElementsByTagName('a')
+
+ for ( i=0; i<buttons.length; i++ ) {
+ if (buttons[i].hasAttributes('class')) {
+ var cssclass = buttons[i].getAttribute('class')
+ if (cssclass == 'foldbutton')
+ addEventHandler(buttons[i],
+ 'click',
+ this.foldingHandler,
+ this)
+ }
+ }
+
this.initialize_events()
}
(at)(at) -62,6 +76,25 (at)(at)
request.send(null);
}
+ // (un-) folds a panel element after the user clicked on the button
+ this.foldingHandler = function(ev) {
+ var button = ev.target
+ this.foldSwitch(button)
+ }
+
+ this.foldSwitch = function(button) {
+ var element = button.parentNode.parentNode
+ if (!element.hasAttributes('class'))
+ return
+
+ var attribute = element.getAttribute('class')
+ if (attribute == 'panel folded')
+ element.setAttribute('class', 'panel unfolded')
+ else
+ element.setAttribute('class', 'panel folded')
+
+ }
+
// methods which handling onreadystatechange events
this._handleXML = function(object) {
if (this.readyState == 4) {
Modified: AlphaFlow/trunk/editor/views/ecmascript/editor.js.dtml
==============================================================================
--- AlphaFlow/trunk/editor/views/ecmascript/editor.js.dtml (original)
+++ AlphaFlow/trunk/editor/views/ecmascript/editor.js.dtml Wed Jun 22 08:39:10
2005
(at)(at) -26,4 +26,5 (at)(at)
this.document.location.href=url
}
}
+
// Editor
Modified: AlphaFlow/trunk/editor/views/ecmascript/helper.js.dtml
==============================================================================
--- AlphaFlow/trunk/editor/views/ecmascript/helper.js.dtml (original)
+++ AlphaFlow/trunk/editor/views/ecmascript/helper.js.dtml Wed Jun 22 08:39:10
2005
(at)(at) -52,18 +52,6 (at)(at)
}
}
-
-// (un-) folds a panel element
-function unfold(id){
- var element = document.getElementById(id)
- var attribute = element.getAttribute('class')
-
- if (attribute == 'panel folded')
- element.setAttribute('class', 'panel unfolded')
- else
- element.setAttribute('class', 'panel folded')
-}
-
function debug(where, what) {
where.appendChild(document.createTextNode(what))
}
Modified: AlphaFlow/trunk/editor/views/ecmascript/message_dialog.js.dtml
==============================================================================
--- AlphaFlow/trunk/editor/views/ecmascript/message_dialog.js.dtml (original)
+++ AlphaFlow/trunk/editor/views/ecmascript/message_dialog.js.dtml Wed Jun 22
08:39:10 2005
(at)(at) -1,9 +1,11 (at)(at)
-function MessageDialog()
+function MessageDialog(ed)
{
this.activity_id = "";
this.handledTips = new List();
this.xslt = "renderHTMLTooltip.xsl"
this.document = document
+ // lets use true for 'folded' and false for 'unfolded'
+ this.fold_status = true
this.init()
}
MessageDialog.prototype = new BaseWindow();
(at)(at) -74,6 +76,20 (at)(at)
this.displayToolTip()
}
+MessageDialog.prototype.unfoldPanel = function() {
+ if (!this.fold_status)
+ return
+
+ var panel = this.document.getElementById('Messages')
+ var links = panel.getElementsByTagName('a')
+ for ( i=0; i<links.length; i++ ) {
+ if ( links[i].hasAttributes('class') ) {
+ if ( links[i].getAttribute('class') == 'foldbutton' )
+ this.foldSwitch(links[i])
+ }
+ }
+}
+
// displays the HTMLTooltip in the footer
MessageDialog.prototype.displayToolTip = function () {
//var footer = document.getElementById('Footer')
(at)(at) -96,6 +112,9 (at)(at)
display_element.removeChild(old)
this.handledTips.array.pop()
}
+ // check if the message box is folded and unfold it if it is
+ this.unfoldPanel()
+
// if the message box don't have any messages displayed, append
// a message, otherwise insert before the first message
var node = this.html.firstChild
Modified: AlphaFlow/trunk/editor/views/panels/attributes.pt
==============================================================================
--- AlphaFlow/trunk/editor/views/panels/attributes.pt (original)
+++ AlphaFlow/trunk/editor/views/panels/attributes.pt Wed Jun 22 08:39:10 2005
(at)(at) -1,25 +1,12 (at)(at)
-<div class="panel folded"
+<div id="Properties"
+ class="panel folded"
metal:define-macro="main">
<h4>
- <!-- currently disabled
- <a title="unfold" href="javascript:unfold();">
- <img tal:attributes="src here/images/arrow-unfold.png/absolute_url"
- alt="unfold" />
- </a> -->
+ <a title="unfold" href="#" class="foldbutton">
+ </a>
Properties
</h4>
-
+ <hr />
<span>
- <div tal:condition="act">
-
- <h4>Attributes for <span tal:replace="act/title_or_id"
/></h4>
- <form action="changeProperties"
- method="POST">
-
- <span metal:define-slot="attributes" />
-
- <input type="submit" value="Modify" />
- </form>
- </div>
</span>
</div>
Modified: AlphaFlow/trunk/editor/views/panels/messages.pt
==============================================================================
--- AlphaFlow/trunk/editor/views/panels/messages.pt (original)
+++ AlphaFlow/trunk/editor/views/panels/messages.pt Wed Jun 22 08:39:10 2005
(at)(at) -1,8 +1,8 (at)(at)
<div id="Messages"
- class="panel unfolded"
+ class="panel folded"
metal:define-macro="main">
<h4>
- <a title="fold" href="javascript:unfold('Messages');"
class="foldbutton"> </a>
+ <a title="fold" href="#" class="foldbutton"> </a>
Messages
</h4>
<hr />
Modified: AlphaFlow/trunk/editor/views/panels/toolbox.pt
==============================================================================
--- AlphaFlow/trunk/editor/views/panels/toolbox.pt (original)
+++ AlphaFlow/trunk/editor/views/panels/toolbox.pt Wed Jun 22 08:39:10 2005
(at)(at) -2,7 +2,7 (at)(at)
id="Toolbox"
metal:define-macro="main">
<h4>
- <a title="unfold" href="javascript:unfold('Toolbox');"
+ <a title="unfold" href="#"
class="foldbutton">
</a>
Toolbox
|
SVN: r3044 - AlphaFlow/trunk/tests/workflows
Michael Howitz <mh(at)gocept.com> |
2005-06-22 10:09:05 |
[ FULL ]
|
Author: mac
Date: Wed Jun 22 10:10:35 2005
New Revision: 3044
Modified:
AlphaFlow/trunk/tests/workflows/actual_assignees.alf
AlphaFlow/trunk/tests/workflows/alarm_review.alf
AlphaFlow/trunk/tests/workflows/before_start.alf
AlphaFlow/trunk/tests/workflows/cachetest_multi.alf
AlphaFlow/trunk/tests/workflows/catalog_security.alf
AlphaFlow/trunk/tests/workflows/condition.alf
AlphaFlow/trunk/tests/workflows/configuration.alf
AlphaFlow/trunk/tests/workflows/configuration_all.alf
AlphaFlow/trunk/tests/workflows/decision.alf
AlphaFlow/trunk/tests/workflows/expression_assign.alf
AlphaFlow/trunk/tests/workflows/expressionn_assign.alf
AlphaFlow/trunk/tests/workflows/instance_transaction.alf
AlphaFlow/trunk/tests/workflows/multi_review.alf
AlphaFlow/trunk/tests/workflows/multi_review_with_config.alf
AlphaFlow/trunk/tests/workflows/ntask.alf
AlphaFlow/trunk/tests/workflows/routing_example.alf
AlphaFlow/trunk/tests/workflows/security_fullProcess.alf
AlphaFlow/trunk/tests/workflows/task.alf
AlphaFlow/trunk/tests/workflows/task_no_edit.alf
Log:
made workflows sane
Modified: AlphaFlow/trunk/tests/workflows/actual_assignees.alf
==============================================================================
--- AlphaFlow/trunk/tests/workflows/actual_assignees.alf (original)
+++ AlphaFlow/trunk/tests/workflows/actual_assignees.alf Wed Jun 22 10:10:35
2005
(at)(at) -1,9 +1,8 (at)(at)
<?xml version="1.0" encoding="iso-8859-1"?>
-<workflow title=""
+<workflow
startActivity="write_document"
- description=""
- onlyAllowRoles="Manager,Reviewer">
+ onlyAllowRoles="Manager Reviewer">
<!-- Write the document -->
<task id="write_document" title="Dokument schreiben" sort="1"
(at)(at) -13,7 +12,7 (at)(at)
</task>
- <dcworkflow id="dc_publish" title="" status="published"/>
+ <dcworkflow id="dc_publish" status="published"/>
</workflow>
Modified: AlphaFlow/trunk/tests/workflows/alarm_review.alf
==============================================================================
--- AlphaFlow/trunk/tests/workflows/alarm_review.alf (original)
+++ AlphaFlow/trunk/tests/workflows/alarm_review.alf Wed Jun 22 10:10:35 2005
(at)(at) -1,10 +1,7 (at)(at)
<?xml version="1.0" encoding="iso-8859-1"?>
-<workflow id="alarm_review"
- title=""
- description=""
- startActivity="edit_ticket,deadline"
- onlyAllowRoles="Manager,Reviewer,Member">
+<workflow startActivity="edit_ticket deadline"
+ onlyAllowRoles="Manager Reviewer Member">
<task id="edit_ticket"
title="Ticket bearbeiten"
(at)(at) -17,15 +14,12 (at)(at)
continue_activity="notify" />
<dcworkflow id="notify"
- title=""
status="pending" />
<dcworkflow id="private"
- title=""
status="private" />
<dcworkflow id="public"
- title=""
status="published" />
</workflow>
Modified: AlphaFlow/trunk/tests/workflows/before_start.alf
==============================================================================
--- AlphaFlow/trunk/tests/workflows/before_start.alf (original)
+++ AlphaFlow/trunk/tests/workflows/before_start.alf Wed Jun 22 10:10:35 2005
(at)(at) -1,6 +1,6 (at)(at)
<?xml version="1.0" encoding="iso-8859-1"?>
- <workflow title=""
+ <workflow
startActivity="some-task expression-test"
description="Test sibilng"
onlyAllowRoles="Manager Reviewer Member">
Modified: AlphaFlow/trunk/tests/workflows/cachetest_multi.alf
==============================================================================
--- AlphaFlow/trunk/tests/workflows/cachetest_multi.alf (original)
+++ AlphaFlow/trunk/tests/workflows/cachetest_multi.alf Wed Jun 22 10:10:35
2005
(at)(at) -1,9 +1,8 (at)(at)
<?xml version="1.0" encoding="iso-8859-1"?>
-<workflow title=""
+<workflow
startActivity="write_document write_document2"
- description=""
- onlyAllowRoles="Manager,Reviewer">
+ onlyAllowRoles="Manager Reviewer">
<!-- Write the document -->
<task id="write_document" title="Dokument schreiben" sort="1"
Modified: AlphaFlow/trunk/tests/workflows/catalog_security.alf
==============================================================================
--- AlphaFlow/trunk/tests/workflows/catalog_security.alf (original)
+++ AlphaFlow/trunk/tests/workflows/catalog_security.alf Wed Jun 22 10:10:35
2005
(at)(at) -1,18 +1,17 (at)(at)
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="iso-8859-1"?>
-<workflow title=""
- startActivity="recursion,make_private"
- description=""
- onlyAllowRoles="Manager,Reviewer">
+<workflow
+ startActivity="recursion make_private"
+ onlyAllowRoles="Manager Reviewer">
<!-- Permissions for "private" state -->
- <permission-change id="make_private" title="Autor-Rechte setzen"
continue_activity="write_document,dc_private">
- <permission id="Access contents information" acquire="False"
roles="Manager,Owner,ProcessUser"/>
- <permission id="Modify portal content" acquire="False"
roles="Manager,Owner,ProcessUser"/>
+ <permission-change id="make_private" title="Autor-Rechte setzen"
continue_activity="write_document dc_private">
+ <permission id="Access contents information" acquire="False"
roles="Manager Owner ProcessUser"/>
+ <permission id="Modify portal content" acquire="False"
roles="Manager Owner ProcessUser"/>
<permission id="View" acquire="False" roles="Manager Owner
ProcessUser"/>
</permission-change>
- <dcworkflow id="dc_private" title="" status="private"/>
+ <dcworkflow id="dc_private" status="private"/>
<!-- Write the document -->
<task id="write_document" title="Dokument schreiben" sort="1"
(at)(at) -26,12 +25,12 (at)(at)
if there are any questions, though he gets no work item yet.
-->
<permission-change id="make_review1" title="Review-Rechte setzen"
- continue_activity="review_document1,dc_pending">
- <permission id="Access contents information" acquire="True"
roles="Manager,Owner,Reviewer,ChiefEditor,ProcessUser"/>
- <permission id="Modify portal content" acquire="False"
roles="Manager,Reviewer,ChiefEditor,ProcessUser"/>
- <permission id="View" acquire="False"
roles="Manager,Owner,Reviewer,ChiefEditor,ProcessUser"/>
+ continue_activity="review_document1 dc_pending">
+ <permission id="Access contents information" acquire="True"
roles="Manager Owner Reviewer ChiefEditor ProcessUser"/>
+ <permission id="Modify portal content" acquire="False"
roles="Manager Reviewer ChiefEditor ProcessUser"/>
+ <permission id="View" acquire="False" roles="Manager Owner Reviewer
ChiefEditor ProcessUser"/>
</permission-change>
- <dcworkflow id="dc_pending" title="" status="pending"/>
+ <dcworkflow id="dc_pending" status="pending"/>
<!-- reviewer -->
<review id="review_document1" title="Dokument prüfen" sort="2"
(at)(at) -53,16 +52,15 (at)(at)
<!-- Publish the document -->
<permission-change id="publish" title="Öffentliche Rechte setzen"
continue_activity="dc_publish">
- <permission id="Access contents information" acquire="True"
roles="Anonymous,Manager"/>
+ <permission id="Access contents information" acquire="True"
roles="Anonymous Manager"/>
<permission id="Modify portal content" acquire="False"
roles="Manager"/>
- <permission id="View" acquire="False"
roles="Anonymous,Manager"/>
+ <permission id="View" acquire="False" roles="Anonymous
Manager"/>
</permission-change>
- <dcworkflow id="dc_publish" title="" status="published"/>
+ <dcworkflow id="dc_publish" status="published"/>
<recursion id="recursion"
- recursion_activity="publish,make_private,make_review1"
- block_activities="write_document,review_document1,review_document2"
- optional_recursion="1"/>
+ recursion_activity="publish make_private make_review1"
+ break_activities="write_document review_document1 review_document2"
/>
</workflow>
Modified: AlphaFlow/trunk/tests/workflows/condition.alf
==============================================================================
--- AlphaFlow/trunk/tests/workflows/condition.alf (original)
+++ AlphaFlow/trunk/tests/workflows/condition.alf Wed Jun 22 10:10:35 2005
(at)(at) -2,7 +2,7 (at)(at)
<workflow
startActivity="cond_ac_1"
- onlyAllowRoles="Manager,Reviewer,Member">
+ onlyAllowRoles="Manager Reviewer Member">
<condition id="cond_ac_1"
expression="python:['cond_ac_2']"
Modified: AlphaFlow/trunk/tests/workflows/configuration.alf
==============================================================================
--- AlphaFlow/trunk/tests/workflows/configuration.alf (original)
+++ AlphaFlow/trunk/tests/workflows/configuration.alf Wed Jun 22 10:10:35 2005
(at)(at) -1,6 +1,6 (at)(at)
<?xml version="1.0" encoding="iso-8859-1"?>
- <workflow title=""
+ <workflow
startActivity="assign_task"
description="Test of configuration activity"
onlyAllowRoles="Manager Reviewer Member">
Modified: AlphaFlow/trunk/tests/workflows/configuration_all.alf
==============================================================================
--- AlphaFlow/trunk/tests/workflows/configuration_all.alf (original)
+++ AlphaFlow/trunk/tests/workflows/configuration_all.alf Wed Jun 22 10:10:35
2005
(at)(at) -3,7 +3,7 (at)(at)
<workflow
startActivity="assign_task"
description="Test of configuration activity"
- onlyAllowRoles="Manager,Reviewer,Member">
+ onlyAllowRoles="Manager Reviewer Member">
<configuration id="assign_task"
configures_all="true"
(at)(at) -24,4 +24,4 (at)(at)
<assignees kind="possible" roles="Reviewer" />
</task>
-</workflow>
+</workflow>
\ No newline at end of file
Modified: AlphaFlow/trunk/tests/workflows/decision.alf
==============================================================================
--- AlphaFlow/trunk/tests/workflows/decision.alf (original)
+++ AlphaFlow/trunk/tests/workflows/decision.alf Wed Jun 22 10:10:35 2005
(at)(at) -2,7 +2,7 (at)(at)
<workflow
startActivity="deci_1"
- onlyAllowRoles="Manager,Reviewer,Member">
+ onlyAllowRoles="Manager Reviewer Member">
<decision id="deci_1"
decision_notice="first yes counts"
Modified: AlphaFlow/trunk/tests/workflows/expression_assign.alf
==============================================================================
--- AlphaFlow/trunk/tests/workflows/expression_assign.alf (original)
+++ AlphaFlow/trunk/tests/workflows/expression_assign.alf Wed Jun 22 10:10:35
2005
(at)(at) -1,8 +1,7 (at)(at)
<?xml version="1.0" encoding="iso-8859-1"?>
-<workflow title=""
+<workflow
startActivity="write_document"
- description=""
onlyAllowRoles="Manager Reviewer">
<!-- Write the document -->
(at)(at) -13,7 +12,7 (at)(at)
</task>
- <dcworkflow id="dc_publish" title="" status="published"/>
+ <dcworkflow id="dc_publish" status="published"/>
</workflow>
Modified: AlphaFlow/trunk/tests/workflows/expressionn_assign.alf
==============================================================================
--- AlphaFlow/trunk/tests/workflows/expressionn_assign.alf (original)
+++ AlphaFlow/trunk/tests/workflows/expressionn_assign.alf Wed Jun 22 10:10:35
2005
(at)(at) -1,9 +1,8 (at)(at)
<?xml version="1.0" encoding="iso-8859-1"?>
-<workflow title=""
+<workflow
startActivity="write_document"
- description=""
- onlyAllowRoles="Manager,Reviewer">
+ onlyAllowRoles="Manager Reviewer">
<!-- Write the document -->
<task id="write_document" title="Dokument schreiben" sort="1"
Modified: AlphaFlow/trunk/tests/workflows/instance_transaction.alf
==============================================================================
--- AlphaFlow/trunk/tests/workflows/instance_transaction.alf (original)
+++ AlphaFlow/trunk/tests/workflows/instance_transaction.alf Wed Jun 22
10:10:35 2005
(at)(at) -1,9 +1,8 (at)(at)
<?xml version="1.0" encoding="iso-8859-1"?>
-<workflow title=""
+<workflow
startActivity="write_document"
- description=""
- onlyAllowRoles="Manager,Reviewer">
+ onlyAllowRoles="Manager Reviewer">
<!-- Write the document -->
<task id="write_document" title="Dokument schreiben" sort="1"
(at)(at) -13,7 +12,7 (at)(at)
</task>
- <dcworkflow id="dc_publish" title="" status="published"/>
+ <dcworkflow id="dc_publish" status="published"/>
</workflow>
Modified: AlphaFlow/trunk/tests/workflows/multi_review.alf
==============================================================================
--- AlphaFlow/trunk/tests/workflows/multi_review.alf (original)
+++ AlphaFlow/trunk/tests/workflows/multi_review.alf Wed Jun 22 10:10:35 2005
(at)(at) -1,32 +1,29 (at)(at)
<?xml version="1.0" encoding="utf-8"?>
-<workflow id="multi_review"
- title=""
- description=""
- startActivity="recursion,make_private"
- onlyAllowRoles="Manager,Reviewer">
+<workflow title="multi_review"
+ startActivity="recursion make_private"
+ onlyAllowRoles="Manager Reviewer">
<!-- Permissions for "private" state -->
<permission-change id="make_private"
title="Autor-Rechte setzen"
- continue_activity="write_document,dc_private">
+ continue_activity="write_document dc_private">
<permission id="Access contents information"
acquire="False"
- roles="Manager,Owner" />
+ roles="Manager Owner" />
<permission id="Modify portal content"
acquire="False"
- roles="Manager,Owner" />
+ roles="Manager Owner" />
<permission id="View"
acquire="False"
- roles="Manager,Owner" />
+ roles="Manager Owner" />
</permission-change>
<dcworkflow id="dc_private"
- title=""
status="private" />
<!-- Write the document -->
(at)(at) -48,24 +45,23 (at)(at)
-->
<permission-change id="make_review1"
title="Review-Rechte setzen"
- continue_activity="review_document1,dc_pending">
+ continue_activity="review_document1 dc_pending">
<permission id="Access contents information"
acquire="True"
- roles="Manager,Owner,Reviewer,ChiefEditor" />
+ roles="Manager Owner Reviewer ChiefEditor" />
<permission id="Modify portal content"
acquire="False"
- roles="Manager,Reviewer,ChiefEditor" />
+ roles="Manager Reviewer ChiefEditor" />
<permission id="View"
acquire="False"
- roles="Manager,Owner,Reviewer,ChiefEditor" />
+ roles="Manager Owner Reviewer ChiefEditor" />
</permission-change>
<dcworkflow id="dc_pending"
- title=""
status="pending" />
<!-- reviewer -->
(at)(at) -101,7 +97,7 (at)(at)
<permission id="Access contents information"
acquire="True"
- roles="Anonymous,Manager" />
+ roles="Anonymous Manager" />
<permission id="Modify portal content"
acquire="False"
(at)(at) -109,17 +105,15 (at)(at)
<permission id="View"
acquire="False"
- roles="Anonymous,Manager" />
+ roles="Anonymous Manager" />
</permission-change>
<dcworkflow id="dc_publish"
- title=""
status="published" />
<recursion id="recursion"
- recursion_activity="publish,make_private,make_review1"
-
block_activities="write_document,review_document1,review_document2"
- optional_recursion="1" />
+ recursion_activity="publish make_private make_review1"
+ break_activities="write_document review_document1
review_document2" />
</workflow>
Modified: AlphaFlow/trunk/tests/workflows/multi_review_with_config.alf
==============================================================================
--- AlphaFlow/trunk/tests/workflows/multi_review_with_config.alf (original)
+++ AlphaFlow/trunk/tests/workflows/multi_review_with_config.alf Wed Jun 22
10:10:35 2005
(at)(at) -1,10 +1,8 (at)(at)
<?xml version="1.0" encoding="iso-8859-1"?>
-<workflow id="multi_review"
- title=""
- description=""
+<workflow title="multi_review"
startActivity="config_at_start"
- onlyAllowRoles="Manager,Reviewer">
+ onlyAllowRoles="Manager Reviewer">
<configuration id="config_at_start"
(at)(at) -17,24 +15,23 (at)(at)
<!-- Permissions for "private" state -->
<permission-change id="make_private"
title="Autor-Rechte setzen"
- continue_activity="write_document,dc_private">
+ continue_activity="write_document dc_private">
<permission id="Access contents information"
acquire="False"
- roles="Manager,Owner" />
+ roles="Manager Owner" />
<permission id="Modify portal content"
acquire="False"
- roles="Manager,Owner" />
+ roles="Manager Owner" />
<permission id="View"
acquire="False"
- roles="Manager,Owner" />
+ roles="Manager Owner" />
</permission-change>
<dcworkflow id="dc_private"
- title=""
status="private" />
<!-- Write the document -->
(at)(at) -55,24 +52,23 (at)(at)
-->
<permission-change id="make_review1"
title="Review-Rechte setzen"
- continue_activity="review_document1,dc_pending">
+ continue_activity="review_document1 dc_pending">
<permission id="Access contents information"
acquire="True"
- roles="Manager,Owner,Reviewer,ChiefEditor" />
+ roles="Manager Owner Reviewer ChiefEditor" />
<permission id="Modify portal content"
acquire="False"
- roles="Manager,Reviewer,ChiefEditor" />
+ roles="Manager Reviewer ChiefEditor" />
<permission id="View"
acquire="False"
- roles="Manager,Owner,Reviewer,ChiefEditor" />
+ roles="Manager Owner Reviewer ChiefEditor" />
</permission-change>
<dcworkflow id="dc_pending"
- title=""
status="pending" />
<!-- reviewer -->
(at)(at) -108,7 +104,7 (at)(at)
<permission id="Access contents information"
acquire="True"
- roles="Anonymous,Manager" />
+ roles="Anonymous Manager" />
<permission id="Modify portal content"
acquire="False"
(at)(at) -116,17 +112,15 (at)(at)
<permission id="View"
acquire="False"
- roles="Anonymous,Manager" />
+ roles="Anonymous Manager" />
</permission-change>
<dcworkflow id="dc_publish"
- title=""
status="published" />
<recursion id="recursion"
- recursion_activity="publish,make_private,make_review1"
-
block_activities="write_document,review_document1,review_document2"
- optional_recursion="1" />
+ recursion_activity="publish make_private make_review1"
+ break_activities="write_document review_document1
review_document2" />
</workflow>
Modified: AlphaFlow/trunk/tests/workflows/ntask.alf
==============================================================================
--- AlphaFlow/trunk/tests/workflows/ntask.alf (original)
+++ AlphaFlow/trunk/tests/workflows/ntask.alf Wed Jun 22 10:10:35 2005
(at)(at) -3,7 +3,7 (at)(at)
<workflow title="Testworkflow"
startActivity="edit"
description="Blubb"
- onlyAllowRoles="Manager,Reviewer,Member">
+ onlyAllowRoles="Manager Reviewer Member">
<ntask id="edit"
title="Dokument bearbeiten" sort="1">
Modified: AlphaFlow/trunk/tests/workflows/routing_example.alf
==============================================================================
--- AlphaFlow/trunk/tests/workflows/routing_example.alf (original)
+++ AlphaFlow/trunk/tests/workflows/routing_example.alf Wed Jun 22 10:10:35
2005
(at)(at) -2,9 +2,8 (at)(at)
<workflow
title="routing_example"
- description=""
startActivity="review"
- onlyAllowRoles="Manager,Reviewer">
+ onlyAllowRoles="Manager Reviewer">
<route id="review"
title="Decisions by Marketing, Medical and Legal Departments">
(at)(at) -22,7 +21,6 (at)(at)
accept_activity="accept" />
<dcworkflow id="visible"
- title=""
status="visible"
continue_activity="review_medical"/>
(at)(at) -44,11 +42,9 (at)(at)
reject_activity="reject"
accept_activity="accept" />
<dcworkflow id="private"
- title=""
status="private" />
<dcworkflow id="public"
- title=""
status="published" />
</workflow>
Modified: AlphaFlow/trunk/tests/workflows/security_fullProcess.alf
==============================================================================
--- AlphaFlow/trunk/tests/workflows/security_fullProcess.alf (original)
+++ AlphaFlow/trunk/tests/workflows/security_fullProcess.alf Wed Jun 22
10:10:35 2005
(at)(at) -1,8 +1,6 (at)(at)
-<?xml version="1.0" encoding="iso-8859-1"?>
+<?xml version="1.0" encoding="utf-8"?>
-<workflow id="multi_review"
- title=""
- description=""
+<workflow title="multi_review"
startActivity="config_wf"
onlyAllowRoles="Manager Reviewer">
(at)(at) -15,24 +13,23 (at)(at)
<!-- Permissions for "private" state -->
<permission-change id="make_private"
title="Autor-Rechte setzen"
- continue_activity="write_document,dc_private">
+ continue_activity="write_document dc_private">
<permission id="Access contents information"
acquire="False"
- roles="Manager,Owner" />
+ roles="Manager Owner" />
<permission id="Modify portal content"
acquire="False"
- roles="Manager,Owner" />
+ roles="Manager Owner" />
<permission id="View"
acquire="False"
- roles="Manager,Owner" />
+ roles="Manager Owner" />
</permission-change>
<dcworkflow id="dc_private"
- title=""
status="private" />
<!-- Write the document -->
(at)(at) -53,24 +50,23 (at)(at)
-->
<permission-change id="make_review1"
title="Review-Rechte setzen"
- continue_activity="review_document1,dc_pending">
+ continue_activity="review_document1 dc_pending">
<permission id="Access contents information"
acquire="True"
- roles="Manager,Owner,Reviewer,ChiefEditor" />
+ roles="Manager Owner Reviewer ChiefEditor" />
<permission id="Modify portal content"
acquire="False"
- roles="Manager,Reviewer,ChiefEditor" />
+ roles="Manager Reviewer ChiefEditor" />
<permission id="View"
acquire="False"
- roles="Manager,Owner,Reviewer,ChiefEditor" />
+ roles="Manager Owner Reviewer ChiefEditor" />
</permission-change>
<dcworkflow id="dc_pending"
- title=""
status="pending" />
<!-- reviewer -->
(at)(at) -106,7 +102,7 (at)(at)
<permission id="Access contents information"
acquire="True"
- roles="Anonymous,Manager" />
+ roles="Anonymous Manager" />
<permission id="Modify portal content"
acquire="False"
(at)(at) -114,17 +110,15 (at)(at)
<permission id="View"
acquire="False"
- roles="Anonymous,Manager" />
+ roles="Anonymous Manager" />
</permission-change>
<dcworkflow id="dc_publish"
- title=""
status="published" />
<recursion id="recursion"
- recursion_activity="publish,make_private,make_review1"
-
block_activities="write_document,review_document1,review_document2"
- optional_recursion="1" />
+ recursion_activity="publish make_private make_review1"
+ break_activities="write_document review_document1
review_document2" />
</workflow>
Modified: AlphaFlow/trunk/tests/workflows/task.alf
==============================================================================
--- AlphaFlow/trunk/tests/workflows/task.alf (original)
+++ AlphaFlow/trunk/tests/workflows/task.alf Wed Jun 22 10:10:35 2005
(at)(at) -7,7 +7,7 (at)(at)
<task id="edit"
title="Dokument bearbeiten" sort="1"
- continue_activity="public">
+ completion_activity="public">
<assignees kind="actual" expression="object/Creator" />
</task>
Modified: AlphaFlow/trunk/tests/workflows/task_no_edit.alf
==============================================================================
--- AlphaFlow/trunk/tests/workflows/task_no_edit.alf (original)
+++ AlphaFlow/trunk/tests/workflows/task_no_edit.alf Wed Jun 22 10:10:35 2005
(at)(at) -3,12 +3,12 (at)(at)
<workflow title="Testworkflow"
startActivity="edit"
description="Blubb"
- onlyAllowRoles="Manager,Reviewer,Member">
+ onlyAllowRoles="Manager Reviewer Member">
<task id="edit"
title="Dokument bearbeiten" sort="1"
nonEditableFields="task"
- continue_activity="public">
+ completion_activity="public">
<assignees kind="actual" expression="object/Creator" />
</task>
|
SVN: r3051 - in AlphaFlow/trunk/editor/views: . ecmascript
Roman Joost <rj(at)gocept.com> |
2005-06-22 10:54:06 |
[ FULL ]
|
Author: roman
Date: Wed Jun 22 10:55:44 2005
New Revision: 3051
Added:
AlphaFlow/trunk/editor/views/renderPropertiesForm.xsl
Modified:
AlphaFlow/trunk/editor/views/ecmascript/base.js.dtml
AlphaFlow/trunk/editor/views/ecmascript/editor.js.dtml
AlphaFlow/trunk/editor/views/ecmascript/message_dialog.js.dtml
Log:
- new XSLT for rendering activity properties form
- minor fixes in ecmascripts
Modified: AlphaFlow/trunk/editor/views/ecmascript/base.js.dtml
==============================================================================
--- AlphaFlow/trunk/editor/views/ecmascript/base.js.dtml (original)
+++ AlphaFlow/trunk/editor/views/ecmascript/base.js.dtml Wed Jun 22 10:55:44
2005
(at)(at) -104,7 +104,7 (at)(at)
// first check for parsing errors
if (xml.parseError == 0) {
- object.responseXML = xml
+ object.responseXML = xml
// call render Tooltip for XML-> HTML transformation
object.renderXML2HTML()
}
Modified: AlphaFlow/trunk/editor/views/ecmascript/editor.js.dtml
==============================================================================
--- AlphaFlow/trunk/editor/views/ecmascript/editor.js.dtml (original)
+++ AlphaFlow/trunk/editor/views/ecmascript/editor.js.dtml Wed Jun 22 10:55:44
2005
(at)(at) -14,7 +14,7 (at)(at)
// initalize the event handlers
Editor.prototype.initialize_events = function() {
- addEventHandler(this.canvas, 'click', this.backToHome, this)
+ //addEventHandler(this.canvas, 'click', this.backToHome, this)
}
// if the user clicks on our canvas during editing of the activities
Modified: AlphaFlow/trunk/editor/views/ecmascript/message_dialog.js.dtml
==============================================================================
--- AlphaFlow/trunk/editor/views/ecmascript/message_dialog.js.dtml (original)
+++ AlphaFlow/trunk/editor/views/ecmascript/message_dialog.js.dtml Wed Jun 22
10:55:44 2005
(at)(at) -86,6 +86,7 (at)(at)
if ( links[i].hasAttributes('class') ) {
if ( links[i].getAttribute('class') == 'foldbutton' )
this.foldSwitch(links[i])
+ this.fold_status = false
}
}
}
Added: AlphaFlow/trunk/editor/views/renderPropertiesForm.xsl
==============================================================================
--- (empty file)
+++ AlphaFlow/trunk/editor/views/renderPropertiesForm.xsl Wed Jun 22 10:55:44
2005
(at)(at) -0,0 +1,172 (at)(at)
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<xsl:stylesheet version="1.0"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:editor="http://www.gocept.com/alf/editor"
+ xmlns="http://www.w3.org/1999/xhtml">
+ <xsl:output method="xml"
+ version="1.0"
+ encoding="UTF-8"
+ indent="yes" />
+
+ <xsl:attribute-set name="inputs">
+ <xsl:attribute name="type">text</xsl:attribute>
+ <xsl:attribute name="value">
+ <xsl:value-of select="$value" />
+ </xsl:attribute>
+ <xsl:attribute name="name">
+ <xsl:value-of select="$name" />
+ </xsl:attribute>
+ </xsl:attribute-set>
+
+ <xsl:template match="//*">
+ <div id="ActivityProperties">
+ <!-- this approach seems a bit awkward to me, but works at least
+ -->
+ <h1>Properties for
+ <xsl:if test="string-length(//(at)id) > 0">
+ <xsl:value-of select="//(at)id" />
+ </xsl:if>
+ <xsl:if test="string-length(//(at)title) > 0">
+ "<xsl:value-of select="//(at)title" />"
+ </xsl:if>
+ </h1>
+ <xsl:for-each select="/*/descendant-or-self::node()">
+ <xsl:apply-templates select="(at)*" />
+ </xsl:for-each>
+ <a href="#"
+ id="changeProperties"
+ title="change properties">
+ change properties
+ </a>
+ </div>
+ </xsl:template>
+
+ <!-- attribute matches -->
+ <xsl:template match="//(at)decision_notice">
+ <b><xsl:value-of select="name()" />:</b>
+ <xsl:call-template name="textarea">
+ <xsl:with-param name="value" select="//(at)decision_notice" />
+ <xsl:with-param name="name">decision_notice</xsl:with-param>
+ </xsl:call-template>
+ </xsl:template>
+
+ <xsl:template match="//(at)roles">
+ <b><xsl:value-of select="name()" />:</b>
+ <xsl:call-template name="textarea">
+ <xsl:with-param name="value" select="//(at)roles" />
+ <xsl:with-param name="name">roles</xsl:with-param>
+ </xsl:call-template>
+ </xsl:template>
+ <xsl:template match="//(at)accept_activity">
+ <b><xsl:value-of select="name()" />:</b>
+ <p>
+ <select name="accept_activity" size="5">
+ <xsl:call-template name="option">
+ <xsl:with-param name="str"
select="//(at)editor:availableActivities"
+ />
+ <xsl:with-param name="selected" select="//(at)accept_activity"
/>
+ </xsl:call-template>
+ </select>
+ </p>
+ </xsl:template>
+
+ <xsl:template match="//(at)reject_activity">
+ <b><xsl:value-of select="name()" />:</b>
+ <p>
+ <select name="reject_activity" size="5">
+ <xsl:call-template name="option">
+ <xsl:with-param name="str"
select="//(at)editor:availableActivities"
+ />
+ <xsl:with-param name="selected" select="//(at)reject_activity"
/>
+ </xsl:call-template>
+ </select>
+ </p>
+ </xsl:template>
+
+ <xsl:template match="//(at)decision_modus">
+ <b><xsl:value-of select="name()" />:</b>
+ <p>
+ <select name="reject_activity" size="5">
+ <xsl:call-template name="option">
+ <xsl:with-param name="str" select="//(at)editor:availableModi"
+ />
+ <xsl:with-param name="selected" select="//(at)decision_modus"
/>
+ </xsl:call-template>
+ </select>
+ </p>
+ </xsl:template>
+
+ <!-- catches everything else of attributes -->
+ <xsl:template match="(at)*">
+ <b><xsl:value-of select="name()" />:</b>
+ <xsl:call-template name="input">
+ <xsl:with-param name="value" select="." />
+ <xsl:with-param name="name">
+ <xsl:value-of select="name()" />
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:template>
+
+ <!-- don't care about them -->
+ <xsl:template match="//(at)editor:*" />
+
+ <!-- widgets -->
+ <xsl:template name="input">
+ <xsl:param name="value" />
+ <xsl:param name="name" />
+ <p>
+ <xsl:element name="input" use-attribute-sets="inputs" />
+ </p>
+ </xsl:template>
+
+ <xsl:template name="textarea">
+ <xsl:param name="value" />
+ <xsl:param name="name" />
+ <textarea>
+ <xsl:attribute name="name">
+ <xsl:value-of select="$name" />
+ </xsl:attribute>
+ <xsl:value-of select="$value" />
+ </textarea>
+ </xsl:template>
+
+ <!-- split a comma seperated list and render for each item a HTML tag
+ like <option>foo</option> -->
+ <xsl:template name="option">
+ <xsl:param name="str" />
+ <xsl:param name="selected" />
+
+ <xsl:choose>
+ <xsl:when test="contains($str, ',') ">
+ <option>
+ <xsl:if test="substring-before($str, ',') = $selected">
+ <xsl:attribute name="selected">true</xsl:attribute>
+ </xsl:if>
+ <xsl:attribute name="name">
+ <xsl:value-of select="substring-before($str, ',')" />
+ </xsl:attribute>
+ <xsl:value-of select="substring-before($str, ',')" />
+ </option>
+ <xsl:call-template name="option">
+ <xsl:with-param name="str"
+ select="substring-after($str, ',')" />
+ <xsl:with-param name="selected" select="$selected" />
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:if test="string-length($str) > 0">
+ <option>
+ <xsl:if test="$str = $selected">
+ <xsl:attribute name="selected">true</xsl:attribute>
+ </xsl:if>
+ <xsl:attribute name="name">
+ <xsl:value-of select="$str" />
+ </xsl:attribute>
+ <xsl:value-of select="$str" />
+ </option>
+ </xsl:if>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+</xsl:stylesheet>
|
SVN: r3055 - AlphaFlow/trunk/tests/workflows
Michael Howitz <mh(at)gocept.com> |
2005-06-22 11:41:36 |
[ FULL ]
|
Author: mac
Date: Wed Jun 22 11:43:09 2005
New Revision: 3055
Removed:
AlphaFlow/trunk/tests/workflows/expressionn_assign.alf
Log:
removed unused workflow
|
SVN: r3070 - in AlphaFlow/trunk/editor/views: . ecmascript panels
Roman Joost <rj(at)gocept.com> |
2005-06-22 14:05:06 |
[ FULL ]
|
Author: roman
Date: Wed Jun 22 14:06:29 2005
New Revision: 3070
Modified:
AlphaFlow/trunk/editor/views/ecmascript/activity_dialog.js.dtml
AlphaFlow/trunk/editor/views/ecmascript/base.js.dtml
AlphaFlow/trunk/editor/views/ecmascript/editor.js.dtml
AlphaFlow/trunk/editor/views/ecmascript/helper.js.dtml
AlphaFlow/trunk/editor/views/ecmascript/message_dialog.js.dtml
AlphaFlow/trunk/editor/views/ecmascript/test_editor.js.dtml
AlphaFlow/trunk/editor/views/ecmascript/tests.pt
AlphaFlow/trunk/editor/views/panels/attributes.pt
AlphaFlow/trunk/editor/views/renderPropertiesForm.xsl
AlphaFlow/trunk/editor/views/style.css
Log:
- added activity_dialog, which currently shows a form for editing the
activity properties
Modified: AlphaFlow/trunk/editor/views/ecmascript/activity_dialog.js.dtml
==============================================================================
--- AlphaFlow/trunk/editor/views/ecmascript/activity_dialog.js.dtml (original)
+++ AlphaFlow/trunk/editor/views/ecmascript/activity_dialog.js.dtml Wed Jun 22
14:06:29 2005
(at)(at) -1,8 +1,9 (at)(at)
function ActivityDialog()
{
this.activity_id = "";
- this.xslt = "renderHTMLTooltip.xsl"
+ this.xslt = "renderPropertiesForm.xsl"
this.document = document
+ this.displayed_form = new Dictionary()
this.init()
}
ActivityDialog.prototype = new BaseWindow();
(at)(at) -19,6 +20,27 (at)(at)
}
}
+/* XXX duplicated code, should be factored out in future */
+// returns the activity id from the given HTML object which should
+// be the hovered SVG ellipse element
+ActivityDialog.prototype.getActivityId = function(element) {
+ return element.parentNode.getAttribute('id')
+}
+// returns true if the given element is a shape which characterizes
+// our activity
+ActivityDialog.prototype.isNodeShape = function(element) {
+ var g = element.parentNode
+ var type = null
+
+ if (g.hasAttributes('class')) {
+ type = g.getAttribute('class')
+ if (type == 'node')
+ return 1
+ } else {
+ return 0
+ }
+}
+
// produces an activity properties form in the properties panel after
// the user clicked an activity shape
ActivityDialog.prototype.createActivityForm = function(event) {
(at)(at) -34,6 +56,17 (at)(at)
// handler which calls this.displayToolTip after the HTML is
// rendered
ActivityDialog.prototype.afterRenderedHTML = function() {
- alert('hurz')
+ this.createPropertyForm()
+}
+
+ActivityDialog.prototype.createPropertyForm = function() {
+ var panel = this.document.getElementById('Properties')
+ var container = panel.getElementsByTagName('span')[0]
+
+ if (!this.displayed_form.hasKey(this.activity_id) ||
+ this.displayed_form.array.length < 1) {
+ container.appendChild(this.html.documentElement)
+ this.displayed_form.set(this.activity_id, this.html)
+ }
}
// ActivityDialog
Modified: AlphaFlow/trunk/editor/views/ecmascript/base.js.dtml
==============================================================================
--- AlphaFlow/trunk/editor/views/ecmascript/base.js.dtml (original)
+++ AlphaFlow/trunk/editor/views/ecmascript/base.js.dtml Wed Jun 22 14:06:29
2005
(at)(at) -47,7 +47,7 (at)(at)
*/
this.getXMLFromURL = function(url) {
// puzzle the request URL together
- var url = url
+ var url = url
var request = new XMLHttpRequest()
request.open("GET", url, true)
var callback = new ContextFixer(this._handleXML,
(at)(at) -60,7 +60,6 (at)(at)
// method which is called after the rendering of the HTML is
// finished
this.afterRenderedHTML = function() {
- alert('falsch')
}
this.renderXML2HTML = function() {
Modified: AlphaFlow/trunk/editor/views/ecmascript/editor.js.dtml
==============================================================================
--- AlphaFlow/trunk/editor/views/ecmascript/editor.js.dtml (original)
+++ AlphaFlow/trunk/editor/views/ecmascript/editor.js.dtml Wed Jun 22 14:06:29
2005
(at)(at) -2,6 +2,7 (at)(at)
var ed = new Editor()
var ms_dialog = new MessageDialog()
var wp_window = new WorkflowProperties()
+ var activity_dialog = new ActivityDialog()
}
function Editor()
Modified: AlphaFlow/trunk/editor/views/ecmascript/helper.js.dtml
==============================================================================
--- AlphaFlow/trunk/editor/views/ecmascript/helper.js.dtml (original)
+++ AlphaFlow/trunk/editor/views/ecmascript/helper.js.dtml Wed Jun 22 14:06:29
2005
(at)(at) -52,7 +52,53 (at)(at)
}
}
-function debug(where, what) {
- where.appendChild(document.createTextNode(what))
+// simple dictionary like object
+function Dictionary()
+{
+ this.array = new Array()
+
+ this.set = function(key, value) {
+ var key = key
+ var value = value
+
+ // urks - that sucks
+ // create a tuple like array
+ var pair = new Array()
+ pair[0] = key
+ pair[1] = value
+ this.array.push(pair)
+ }
+
+ this.keys = function() {
+ var result = new Array()
+ for ( i=0; i<this.array.length; i++ ) {
+ var pair = this.array[i]
+ result.push(pair[0])
+ }
+ return result
+ }
+
+ this.get = function(key) {
+ var key = key
+
+ for ( i=0; i<this.array.length; i++ ) {
+ if ( key == this.array[i][0] )
+ return this.array[i][1]
+ }
+ }
+
+ this.hasKey = function(key) {
+ var key = key
+
+ for ( i=0; i<this.array.length; i++ ) {
+ if ( key == this.array[i][0] )
+ return 1
+ }
+ return 0
+ }
+
}
+function debug(what) {
+
document.getElementById('Graph').appendChild(document.createTextNode(what))
+}
Modified: AlphaFlow/trunk/editor/views/ecmascript/message_dialog.js.dtml
==============================================================================
--- AlphaFlow/trunk/editor/views/ecmascript/message_dialog.js.dtml (original)
+++ AlphaFlow/trunk/editor/views/ecmascript/message_dialog.js.dtml Wed Jun 22
14:06:29 2005
(at)(at) -17,7 +17,7 (at)(at)
for(i=0; i<groups.length; i++) {
var g = groups[i]
if (g.getAttribute('class') == 'node') {
- addEventHandler(g, 'mouseover', this.createTooltip, this)
+ //addEventHandler(g, 'mouseover', this.createTooltip, this)
}
}
}
(at)(at) -25,13 +25,13 (at)(at)
// returns the activity id from the given HTML object which should
// be the hovered SVG ellipse element
MessageDialog.prototype.getActivityId = function(element) {
- return element.parentNode.parentNode.getAttribute('id')
+ return element.parentNode.getAttribute('id')
}
// returns true if the given element is a shape which characterizes
// our activity
MessageDialog.prototype.isNodeShape = function(element) {
- var g = element.parentNode.parentNode
+ var g = element.parentNode
var type = null
if (g.hasAttributes('class')) {
Modified: AlphaFlow/trunk/editor/views/ecmascript/test_editor.js.dtml
==============================================================================
--- AlphaFlow/trunk/editor/views/ecmascript/test_editor.js.dtml (original)
+++ AlphaFlow/trunk/editor/views/ecmascript/test_editor.js.dtml Wed Jun 22
14:06:29 2005
(at)(at) -3,7 +3,7 (at)(at)
this.setUp = function() {
this.editor = new Editor()
- this.editor.event_initialize()
+ this.editor.initialize_events()
this.debug_el = document.getElementById('debugoutput')
}
(at)(at) -28,5 +28,22 (at)(at)
};
-
EditorTestCase.prototype = new TestCase;
+
+function DictionaryTestCase() {
+ this.name = "DictionaryTestCase"
+
+ this.setUp = function() {
+ this.dict = new Dictionary()
+ }
+
+ this.test_get = function() {
+ this.dict.set(1, 'foo')
+ this.dict.set('name', 'value')
+ this.dict.set('foo', 'bar')
+
+ this.assert_(this.dict.get('foo') == 'bar')
+ }
+
+};
+DictionaryTestCase.prototype = new TestCase;
Modified: AlphaFlow/trunk/editor/views/ecmascript/tests.pt
==============================================================================
--- AlphaFlow/trunk/editor/views/ecmascript/tests.pt (original)
+++ AlphaFlow/trunk/editor/views/ecmascript/tests.pt Wed Jun 22 14:06:29 2005
(at)(at) -5,18 +5,25 (at)(at)
lang="en">
<metal:block fill-slot="ecmascripts">
<script type="text/javascript" src="ecmaunit.js"> </script>
+ <script type="text/javascript" src="helper.js"> </script>
<script type="text/javascript" src="test_editor.js"> </script>
<script type="text/javascript">
//<![CDATA[
- function runTests() {
- var testcase = new EditorTestCase();
+ function runallTests() {
+ /*var testcase = new EditorTestCase();
var placeholder = document.getElementById('placeholder1');
testcase.initialize(new HTMLReporter(placeholder));
- testcase.runTests();
+ testcase.runTests();*/
+
+ var dicttest = new DictionaryTestCase();
+ var placeholder = document.getElementById('placeholder2');
+ dicttest.initialize(new HTMLReporter(placeholder));
+ dicttest.runTests();
placeholder = document.getElementById('result');
var testsuite = new TestSuite(new HTMLReporter(placeholder));
testsuite.registerTest(EditorTestCase);
+ testsuite.registerTest(DictionaryTestCase);
testsuite.runSuite();
};
//]]>
(at)(at) -24,11 +31,14 (at)(at)
</metal:block>
<body>
<div metal:fill-slot="debug">
- <h3>editor test</h3>
<p>Some of them fail, if you don't use a SVG enabled
Mozilla.</p>
+ <h3>editor test</h3>
<div id="placeholder1"> </div>
+
+ <h3>dictionary test</h3>
+ <div id="placeholder2"> </div>
<p>
- <a href="javascript:runTests()" title="run all tests">
+ <a href="javascript:runallTests()" title="run all tests">
run all tests
</a>
</p>
Modified: AlphaFlow/trunk/editor/views/panels/attributes.pt
==============================================================================
--- AlphaFlow/trunk/editor/views/panels/attributes.pt (original)
+++ AlphaFlow/trunk/editor/views/panels/attributes.pt Wed Jun 22 14:06:29 2005
(at)(at) -1,5 +1,5 (at)(at)
<div id="Properties"
- class="panel folded"
+ class="panel unfolded"
metal:define-macro="main">
<h4>
<a title="unfold" href="#" class="foldbutton">
(at)(at) -8,5 +8,6 (at)(at)
</h4>
<hr />
<span>
+
</span>
</div>
Modified: AlphaFlow/trunk/editor/views/renderPropertiesForm.xsl
==============================================================================
--- AlphaFlow/trunk/editor/views/renderPropertiesForm.xsl (original)
+++ AlphaFlow/trunk/editor/views/renderPropertiesForm.xsl Wed Jun 22 14:06:29
2005
(at)(at) -12,10 +12,10 (at)(at)
<xsl:attribute-set name="inputs">
<xsl:attribute name="type">text</xsl:attribute>
<xsl:attribute name="value">
- <xsl:value-of select="$value" />
+ <xsl:value-of select="." />
</xsl:attribute>
<xsl:attribute name="name">
- <xsl:value-of select="$name" />
+ <xsl:value-of select="node()" />
</xsl:attribute>
</xsl:attribute-set>
(at)(at) -101,10 +101,6 (at)(at)
<xsl:template match="(at)*">
<b><xsl:value-of select="name()" />:</b>
<xsl:call-template name="input">
- <xsl:with-param name="value" select="." />
- <xsl:with-param name="name">
- <xsl:value-of select="name()" />
- </xsl:with-param>
</xsl:call-template>
</xsl:template>
(at)(at) -113,8 +109,6 (at)(at)
<!-- widgets -->
<xsl:template name="input">
- <xsl:param name="value" />
- <xsl:param name="name" />
<p>
<xsl:element name="input" use-attribute-sets="inputs" />
</p>
Modified: AlphaFlow/trunk/editor/views/style.css
==============================================================================
--- AlphaFlow/trunk/editor/views/style.css (original)
+++ AlphaFlow/trunk/editor/views/style.css Wed Jun 22 14:06:29 2005
(at)(at) -76,6 +76,7 (at)(at)
color: white;
}
+/* editor itself*/
#Menu {
height: 2.5em;
background-color: #63777f;
(at)(at) -263,6 +264,7 (at)(at)
border-bottom: 1px solid #919fa5;
}
+/* Messages panel */
#Panels #Messages.unfolded {
min-height: 20em;
}
(at)(at) -301,6 +303,29 (at)(at)
visibility: hidden;
}
+/* Properties panel */
+#ActivityProperties {
+ font-size: 0.7em;
+ color: white;
+}
+#ActivityProperties h1 {
+ font-size: 0.8em;
+ color: white;
+ margin: 0;
+}
+
+#ActivityProperties input[type="text"],
+#ActivityProperties textarea,
+#ActivityProperties select {
+ width: 100%;
+ border: 1px inset #455359;
+}
+
+#ActivityProperties p {
+ margin-top: 0;
+ display: block;
+ padding: 0 0.4em;
+}
/* SVG styles */
.nodisplay {
display: none;
|
SVN: r3073 - in AlphaFlow/trunk/tests: . workflows
Michael Howitz <mh(at)gocept.com> |
2005-06-22 15:14:00 |
[ FULL ]
|
Author: mac
Date: Wed Jun 22 15:15:36 2005
New Revision: 3073
Added:
AlphaFlow/trunk/tests/test_expression.py (contents, props changed)
AlphaFlow/trunk/tests/workflows/expression.alf
Log:
added tests for expression activity
Added: AlphaFlow/trunk/tests/test_expression.py
==============================================================================
--- (empty file)
+++ AlphaFlow/trunk/tests/test_expression.py Wed Jun 22 15:15:36 2005
(at)(at) -0,0 +1,70 (at)(at)
+# Copyright (c) 2005 gocept gmbh & co. kg
+# See also LICENSE.txt
+# $Id$
+
+import common
+import unittest
+
+from DateTime import DateTime
+from Testing import ZopeTestCase
+
+from Products.CMFCore.utils import getToolByName
+
+from Products.AlphaFlow.tests.AlphaFlowTestCase import AlphaFlowTestCase
+from Products.AlphaFlow.interfaces import \
+ IExpressionActivity, IExpressionWorkItem
+from Products.AlphaFlow.activities.expression import \
+ ExpressionActivity, ExpressionWorkItem
+
+class ExpressionTest(AlphaFlowTestCase):
+
+ interfaces_to_test = [
+ (IExpressionWorkItem, ExpressionWorkItem),
+ (IExpressionActivity, ExpressionActivity)
+ ]
+
+ def _init_object(self):
+ portal = self.getPortal()
+ self._create_test_users()
+ self.loginAsPortalOwner()
+ self._import_wf('workflows/expression.alf')
+
+ wftool = getToolByName(portal, 'workflow_manager')
+
+ self.login("author")
+ mtool = getToolByName(portal, 'portal_membership')
+ home = mtool.getPersonalFolder("author")
+ # Create object for instanciation of this process
+ home.createObject("testdocument", "DummyContent")
+
+ # Initialize the process
+ doc = home.testdocument
+ doc.assignProcess(doc.getSuitableProcesses()[0].getId())
+ return doc
+
+ def test_definition(self):
+ portal = self.getPortal()
+ wftool = getToolByName(portal, 'workflow_manager')
+ doc = self._init_object()
+
+ # props not existing
+
+ self.assertRaises(AttributeError,
+ getattr, doc, "asdf_asdf_prop_hjkl")
+ instance = doc.getInstance()
+ instance.start("testing")
+ self.assertEquals(instance.state, "active")
+ self.assertEqual(2, doc.asdf_asdf_prop_hjkl)
+ wis = instance.getWorkItems()
+ # only the task is left
+ self.assertEquals(len(wis), 1)
+
+
+def test_suite():
+ suite = unittest.TestSuite()
+ suite.addTest(unittest.makeSuite(ExpressionTest))
+ return suite
+
+if __name__ == '__main__':
+ framework()
+
Added: AlphaFlow/trunk/tests/workflows/expression.alf
==============================================================================
--- (empty file)
+++ AlphaFlow/trunk/tests/workflows/expression.alf Wed Jun 22 15:15:36 2005
(at)(at) -0,0 +1,18 (at)(at)
+<?xml version="1.0" encoding="iso-8859-1"?>
+
+<workflow
+ startActivity="test2"
+ onlyAllowRoles="Manager Member">
+
+ <expression id="test2"
+ expression="python:object.set('asdf_asdf_prop_hjkl', 2)"
+ continue_activity="test3" />
+
+ <!-- check for TALES contexts -->
+ <expression id="test3"
+ expression="python: workitem != object and activity != portal"
+ continue_activity="end" />
+ <task id="end" />
+
+
+</workflow>
|
SVN: r3076 - in AlphaFlow/trunk/editor/views: . ecmascript
Roman Joost <rj(at)gocept.com> |
2005-06-23 08:49:58 |
[ FULL ]
|
Author: roman
Date: Thu Jun 23 08:45:16 2005
New Revision: 3076
Modified:
AlphaFlow/trunk/editor/views/ecmascript/activity_dialog.js.dtml
AlphaFlow/trunk/editor/views/ecmascript/helper.js.dtml
AlphaFlow/trunk/editor/views/renderPropertiesForm.xsl
Log:
- minor changes in renderPropertiesForm, which should create an HTML
structure which I can easily parse and xmlize to the same structure I
received
- added XMLWriter to helper.js.dtml
Modified: AlphaFlow/trunk/editor/views/ecmascript/activity_dialog.js.dtml
==============================================================================
--- AlphaFlow/trunk/editor/views/ecmascript/activity_dialog.js.dtml (original)
+++ AlphaFlow/trunk/editor/views/ecmascript/activity_dialog.js.dtml Thu Jun 23
08:45:16 2005
(at)(at) -69,4 +69,14 (at)(at)
this.displayed_form.set(this.activity_id, this.html)
}
}
+
+// (at)attributes is a dictionary
+ActivityDialog.prototype.serializeActivity = function(name, content,
attributes) {
+ var name = name
+ var content = content
+ var attributes = attributes
+ var xmlwriter = XMLWriter(name, content, attributes)
+
+ return xmlwriter.elementNL()
+}
// ActivityDialog
Modified: AlphaFlow/trunk/editor/views/ecmascript/helper.js.dtml
==============================================================================
--- AlphaFlow/trunk/editor/views/ecmascript/helper.js.dtml (original)
+++ AlphaFlow/trunk/editor/views/ecmascript/helper.js.dtml Thu Jun 23 08:45:16
2005
(at)(at) -56,6 +56,7 (at)(at)
function Dictionary()
{
this.array = new Array()
+ this.length = this.array.length
this.set = function(key, value) {
var key = key
(at)(at) -77,6 +78,15 (at)(at)
}
return result
}
+
+ this.items = function() {
+ var result = new Array()
+ for ( i=0; i<this.array.length; i++ ) {
+ var pair = this.array[i]
+ result.push(pair)
+ }
+ return result
+ }
this.get = function(key) {
var key = key
(at)(at) -99,6 +109,81 (at)(at)
}
+// simple XML writer based on the XML Hack #95 from hacks.oreilly.com
+function XMLWriter(this.name, this.content, this.attributes)
+{
+ this.name = name
+ this.content = content
+ this.attributes = attributes
+
+ // attributes is a dictionary object
+ this.element = function() {
+ var xml
+ var attrstr = ''
+
+ if (this.attributes)
+ attrstr = formatAttributes(this.attributes)
+
+ if (!this.content)
+ xml = '<' + this.name + attrstr + '/>'
+ else
+ xml = '<' + this.name + attrstr + '>' + this.content +
'</' +
+ this.name + '>'
+
+ return xml
+ }
+
+ // creates an element tag with a newline appended
+ this.elementNL = function() {
+ return this.element() + '\n'
+ }
+
+ this.formatAttributes = function(attributes) {
+ var APOS = "'"; QUOTE = '"'
+ var ESCAPED_QUOTE = { }
+ ESCAPED_QUOTE[QUOTE] = '"'
+ ESCAPED_QUOTE[APOS] = '''
+
+ var value
+ var apos_pos, quot_pos
+ var use_quote, escape, quote_to_escape
+ var attr_str
+ var re
+ var result = ''
+
+ for (var attr in attributes) {
+ value = attributes.get(attr)
+
+ // find quote marks
+ apos_pos = value.indexOf(APOS)
+ quot_pos = value.indexOf(QUOTE)
+
+ // determine the quote type
+ if (apos_pos == -1 && quot_pos == -1) {
+ attr_str = ' ' + attr + "='" + value + "'"
+ result += attr_str
+ continue
+ }
+
+ // prefer double quotes
+ if (quot_pos != -1 && quot_pos < apos_pos)
+ use_quote = QUOTE
+ else
+ use_quote = APOS
+
+
+ // figure kind of quotes to escape
+ escape = ESCAPED_QUOTE[use_quote]
+
+ re = new RegExp(use_quote, 'g')
+ attr_str = ' ' + att + '=' + use_quote +
+ value.replace(re, escape) + use_quote
+ result += attr_str
+ }
+ return result
+ }
+}
+
function debug(what) {
document.getElementById('Graph').appendChild(document.createTextNode(what))
}
Modified: AlphaFlow/trunk/editor/views/renderPropertiesForm.xsl
==============================================================================
--- AlphaFlow/trunk/editor/views/renderPropertiesForm.xsl (original)
+++ AlphaFlow/trunk/editor/views/renderPropertiesForm.xsl Thu Jun 23 08:45:16
2005
(at)(at) -32,7 +32,14 (at)(at)
</xsl:if>
</h1>
<xsl:for-each select="/*/descendant-or-self::node()">
- <xsl:apply-templates select="(at)*" />
+ <xsl:if test="string-length(name()) > 0">
+ <span>
+ <xsl:attribute name="class">
+ <xsl:value-of select="name()" />
+ </xsl:attribute>
+ <xsl:apply-templates select="(at)*" />
+ </span>
+ </xsl:if>
</xsl:for-each>
<a href="#"
id="changeProperties"
|
SVN: r3082 - in AlphaFlow/trunk/editor/views: . ecmascript
Roman Joost <rj(at)gocept.com> |
2005-06-23 14:18:29 |
[ FULL ]
|
Author: roman
Date: Thu Jun 23 14:13:51 2005
New Revision: 3082
Modified:
AlphaFlow/trunk/editor/views/ecmascript/activity_dialog.js.dtml
AlphaFlow/trunk/editor/views/ecmascript/helper.js.dtml
AlphaFlow/trunk/editor/views/ecmascript/message_dialog.js.dtml
AlphaFlow/trunk/editor/views/renderPropertiesForm.xsl
Log:
- added PropertiesCollector and XMLWriter on Ecmascript client side
- minor bugfixes for the XSLT
Modified: AlphaFlow/trunk/editor/views/ecmascript/activity_dialog.js.dtml
==============================================================================
--- AlphaFlow/trunk/editor/views/ecmascript/activity_dialog.js.dtml (original)
+++ AlphaFlow/trunk/editor/views/ecmascript/activity_dialog.js.dtml Thu Jun 23
14:13:51 2005
(at)(at) -11,6 +11,7 (at)(at)
// initalize the event handlers
ActivityDialog.prototype.initialize_events = function() {
var groups = this.document.getElementsByTagName('g')
+ var changebutton = this.document.getElementById('changeProperties')
for(i=0; i<groups.length; i++) {
var g = groups[i]
(at)(at) -18,6 +19,7 (at)(at)
addEventHandler(g, 'click', this.createActivityForm, this)
}
}
+ addEventHandler(changebutton, 'click', this.collectProperties, this)
}
/* XXX duplicated code, should be factored out in future */
(at)(at) -70,13 +72,135 (at)(at)
}
}
-// (at)attributes is a dictionary
-ActivityDialog.prototype.serializeActivity = function(name, content,
attributes) {
- var name = name
- var content = content
- var attributes = attributes
- var xmlwriter = XMLWriter(name, content, attributes)
+// parse the properties panel and save all the key value pairs in our
+// dictionary, so we can build the XML out of it
+ActivityDialog.prototype.collectProperties = function() {
+ var panel = this.document.getElementById('Properties')
+ var collector = new PropertiesCollector(panel)
+
+ var xml = this.serializeActivity(collector.properties)
+ debug(xml)
+}
+// (at)attributes is a dictionary
+ActivityDialog.prototype.serializeActivity = function(properties) {
+ var xmlwriter = new XMLWriter(properties)
return xmlwriter.elementNL()
}
// ActivityDialog
+
+
+function PropertiesCollector(panel)
+{
+ this.panel = panel
+ this.properties = new Dictionary()
+
+ // iterate over each form element in the panel and collect the items
+ // XXX maybe we could build something like a treewalker in the
+ // future
+ this.collectProperties = function() {
+ var sections = this.getPanelSections()
+ var elements = new Array()
+
+ elements.push('select')
+ elements.push('input')
+ elements.push('textarea')
+
+ // the following is a quick, ugly hack and will go away in
+ // the future
+ for ( var i in sections ) {
+ var temp = new Array()
+ for ( var j in elements ) {
+ var els = sections[i].getElementsByTagName(elements[j])
+
+ for ( k=0; k<els.length; k++ ) {
+ pair = this.collectItem(els[k])
+ temp.push(pair)
+ }
+ }
+ this.properties.set(sections[i].getAttribute('class'), temp)
+ }
+ }
+
+ // The panel is rendered with span elements. Each span element has a
+ // class attribute, which indicates a tag name in ALF. This is
+ // needed, because we need to create the same XML we first got from
+ // the server to configure the activity. This method returns the
+ // names from each span element as an array
+ this.getPanelSections = function() {
+ var sections = new Array()
+ var spans = this.panel.getElementsByTagName('span')
+
+ for ( i=0; i<spans.length; i++) {
+ if ( spans[i].hasAttributes('class') )
+ sections.unshift(spans[i])
+ }
+ return sections
+ }
+
+ // collects a (key, value) pair from a form element
+ // eg.
+ // <b>decision_notice:</b>
+ // <textarea name="decision_notice">first yes
counts</textarea>
+ // will result in
+ // 'decision_notice':'first yes counts'
+ this.collectItem = function(form_element) {
+ var form_element = form_element
+ var key = ""
+ var value = ""
+ var pair = new Array()
+
+ if (!form_element.hasAttributes('name'))
+ return
+
+ key = form_element.getAttribute('name')
+
+ switch(form_element.nodeName) {
+ case "input":
+ value = this.getValueFromInput(form_element)
+ break;
+ case "textarea":
+ value = this.getValueFromTextarea(form_element)
+ break;
+ case "select":
+ value = this.getValueFromSelect(form_element)
+ break;
+ default:
+ value = ""
+ break;
+ }
+
+ pair[0] = key
+ pair[1] = value
+ return pair
+ }
+
+ this.getValueFromTextarea = function(textarea) {
+ var textnode = textarea.firstChild
+
+ if (textnode.nodeType == 3) {
+ return textnode.nodeValue
+ }
+ }
+
+ this.getValueFromSelect = function(select) {
+ var select = select
+ var values = new Array()
+
+ for ( i=0; i<select.childNodes.length; i++ ) {
+ var child = select.childNodes[i]
+ if (child.nodeType == 1 &&
+ child.nodeName == "option" &&
+ child.selected)
+ values.push(child.getAttribute('name'))
+ }
+
+ return values.join(",")
+ }
+
+ this.getValueFromInput = function(input) {
+ return input.getAttribute('value')
+ }
+
+ this.collectProperties()
+}
Modified: AlphaFlow/trunk/editor/views/ecmascript/helper.js.dtml
==============================================================================
--- AlphaFlow/trunk/editor/views/ecmascript/helper.js.dtml (original)
+++ AlphaFlow/trunk/editor/views/ecmascript/helper.js.dtml Thu Jun 23 14:13:51
2005
(at)(at) -68,6 +68,7 (at)(at)
pair[0] = key
pair[1] = value
this.array.push(pair)
+ this.length = this.array.length
}
this.keys = function() {
(at)(at) -110,49 +111,33 (at)(at)
}
// simple XML writer based on the XML Hack #95 from hacks.oreilly.com
-function XMLWriter(this.name, this.content, this.attributes)
+function XMLWriter(properties)
{
- this.name = name
- this.content = content
- this.attributes = attributes
+ this.properties = properties
+ this.keys = properties.keys()
- // attributes is a dictionary object
- this.element = function() {
- var xml
- var attrstr = ''
-
- if (this.attributes)
- attrstr = formatAttributes(this.attributes)
-
- if (!this.content)
- xml = '<' + this.name + attrstr + '/>'
- else
- xml = '<' + this.name + attrstr + '>' + this.content +
'</' +
- this.name + '>'
-
- return xml
- }
-
- // creates an element tag with a newline appended
- this.elementNL = function() {
- return this.element() + '\n'
- }
-
this.formatAttributes = function(attributes) {
var APOS = "'"; QUOTE = '"'
var ESCAPED_QUOTE = { }
ESCAPED_QUOTE[QUOTE] = '"'
ESCAPED_QUOTE[APOS] = '''
-
- var value
+
+ var value, key, pair
var apos_pos, quot_pos
var use_quote, escape, quote_to_escape
var attr_str
var re
var result = ''
-
- for (var attr in attributes) {
- value = attributes.get(attr)
+
+ for ( i=0; i<attributes.length; i++) {
+ pair = attributes[i]
+ attr = pair[0]
+ value = pair[1]
+
+ // continue if attr is empty, because printing an attribute
+ // with no key doesn't make any sense
+ if (!attr)
+ continue
// find quote marks
apos_pos = value.indexOf(APOS)
(at)(at) -182,6 +167,38 (at)(at)
}
return result
}
+
+
+ // attributes is a dictionary object
+ this.element = function(name, attributes) {
+ var xml
+ var attrstr = ''
+
+ if ( attributes )
+ attrstr = this.formatAttributes( attributes )
+
+ if ( this.keys.length == 0 ) {
+ xml = '<' + name + attrstr + '/>'
+ } else {
+
+ if ( this.keys.length > 0 ) {
+ var nextname = this.keys.pop()
+ var nextattributes = this.properties.get( nextname )
+ var content = this.element( nextname, nextattributes )
+ xml = '<' + name + attrstr + '>' + content + '</' +
name + '>'
+ }
+ }
+
+ return xml
+ }
+
+ // creates an element tag with a newline appended
+ this.elementNL = function() {
+ name = this.keys.pop()
+ attributes = this.properties.get(name)
+ return this.element(name, attributes) + '\n'
+ }
+
}
function debug(what) {
Modified: AlphaFlow/trunk/editor/views/ecmascript/message_dialog.js.dtml
==============================================================================
--- AlphaFlow/trunk/editor/views/ecmascript/message_dialog.js.dtml (original)
+++ AlphaFlow/trunk/editor/views/ecmascript/message_dialog.js.dtml Thu Jun 23
14:13:51 2005
(at)(at) -17,7 +17,7 (at)(at)
for(i=0; i<groups.length; i++) {
var g = groups[i]
if (g.getAttribute('class') == 'node') {
- //addEventHandler(g, 'mouseover', this.createTooltip, this)
+ addEventHandler(g, 'mouseover', this.createTooltip, this)
}
}
}
Modified: AlphaFlow/trunk/editor/views/renderPropertiesForm.xsl
==============================================================================
--- AlphaFlow/trunk/editor/views/renderPropertiesForm.xsl (original)
+++ AlphaFlow/trunk/editor/views/renderPropertiesForm.xsl Thu Jun 23 14:13:51
2005
(at)(at) -15,7 +15,7 (at)(at)
<xsl:value-of select="." />
</xsl:attribute>
<xsl:attribute name="name">
- <xsl:value-of select="node()" />
+ <xsl:value-of select="name()" />
</xsl:attribute>
</xsl:attribute-set>
(at)(at) -71,6 +71,7 (at)(at)
<xsl:call-template name="select">
<xsl:with-param name="key"
select="//(at)editor:availableActivities" />
<xsl:with-param name="selected" select="//(at)accept_activity"
/>
+ <xsl:with-param name="multiple">yes</xsl:with-param>
</xsl:call-template>
</p>
</xsl:template>
(at)(at) -81,6 +82,7 (at)(at)
<xsl:call-template name="select">
<xsl:with-param name="key"
select="//(at)editor:availableActivities" />
<xsl:with-param name="selected" select="//(at)reject_activity"
/>
+ <xsl:with-param name="multiple">yes</xsl:with-param>
</xsl:call-template>
</p>
</xsl:template>
(at)(at) -131,11 +133,15 (at)(at)
<xsl:template name="select">
<xsl:param name="key" />
<xsl:param name="selected" />
+ <xsl:param name="multiple">false</xsl:param>
<p>
<select size="5">
<xsl:attribute name="name">
<xsl:value-of select="name()" />
</xsl:attribute>
+ <xsl:attribute name="multiple">
+ <xsl:value-of select="$multiple" />
+ </xsl:attribute>
<xsl:call-template name="option">
<xsl:with-param name="str" select="$key"
/>
|
SVN: r3099 - in AlphaFlow/trunk: . activities editor tests tests/workflows
Michael Howitz <mh(at)gocept.com> |
2005-06-27 15:30:37 |
[ FULL ]
|
Author: mac
Date: Mon Jun 27 15:24:52 2005
New Revision: 3099
Added:
AlphaFlow/trunk/registry.py (contents, props changed)
AlphaFlow/trunk/tests/test_registry.py (contents, props changed)
AlphaFlow/trunk/tests/workflows/invalid_permission.alf
Modified:
AlphaFlow/trunk/activities/alarm.py
AlphaFlow/trunk/activities/condition.py
AlphaFlow/trunk/activities/configuration.py
AlphaFlow/trunk/activities/dcworkflow.py
AlphaFlow/trunk/activities/decision.py
AlphaFlow/trunk/activities/expression.py
AlphaFlow/trunk/activities/gates.py
AlphaFlow/trunk/activities/interfaces.py
AlphaFlow/trunk/activities/notify.py
AlphaFlow/trunk/activities/ntask.py
AlphaFlow/trunk/activities/permission.py
AlphaFlow/trunk/activities/recursion.py
AlphaFlow/trunk/activities/review.py
AlphaFlow/trunk/activities/routing.py
AlphaFlow/trunk/activities/task.py
AlphaFlow/trunk/activity.py
AlphaFlow/trunk/editor/editor.py
AlphaFlow/trunk/importexport.py
AlphaFlow/trunk/interfaces.py
AlphaFlow/trunk/process.py
AlphaFlow/trunk/processmanager.py
AlphaFlow/trunk/tests/test_definition.py
AlphaFlow/trunk/tests/test_email.py
AlphaFlow/trunk/tests/test_security.py
AlphaFlow/trunk/utils.py
AlphaFlow/trunk/workflowattr.py
Log:
- made registries fully flagged objects as instances of Registry class
- xml-import is done using the WorkflowAttributes and the DOMImporter class
Modified: AlphaFlow/trunk/activities/alarm.py
==============================================================================
--- AlphaFlow/trunk/activities/alarm.py (original)
+++ AlphaFlow/trunk/activities/alarm.py Mon Jun 27 15:24:52 2005
(at)(at) -21,9 +21,6 (at)(at)
activity_type = nodeName = "alarm"
icon = "alarm"
- error_string = "TALES expression required which " \
- "should return a DateTime object, in %r."
-
class AlarmWorkItem(BaseTalesWorkItem):
Modified: AlphaFlow/trunk/activities/condition.py
==============================================================================
--- AlphaFlow/trunk/activities/condition.py (original)
+++ AlphaFlow/trunk/activities/condition.py Mon Jun 27 15:24:52 2005
(at)(at) -16,7 +16,7 (at)(at)
from Products.AlphaFlow.workitem import registerWorkItem, BaseTalesWorkItem
from Products.AlphaFlow.activity import registerActivity, BaseTalesActivity
from Products.AlphaFlow.interfaces import IConditionActivity,
IConditionWorkItem
-from Products.AlphaFlow import utils, config
+from Products.AlphaFlow import config
from Products.AlphaFlow.workflowattr import WorkflowAttribute
(at)(at) -31,18 +31,16 (at)(at)
attributes = BaseTalesActivity.attributes + (
WorkflowAttribute('continue_activity', 'continue_activity', (),
- 'Activities that can follow this automatic
activity.'
- ), # XXX required
+ 'Activities that can follow this automatic
activity.',
+ required=True, encoding='ascii', datatype=tuple,
+ ),
WorkflowAttribute('expression', 'expression', '',
- 'TALES expression which returns list of activities '
- 'for continuation (must be in continue_activity)!',
+ 'TALES expression: Returns list of activities for '
+ 'continuation (which must be in
continue_activity!)',
importHandler=None, # done by BaseTalesActivity
exportHandler=None),
)
- error_string = "TALES expression required which must return a list of " \
- "WorkItem activity_types (in %r)"
-
security.declareProtected(config.MANAGE_WORKFLOW,
"graphGetPossibleChildren")
(at)(at) -53,28 +51,15 (at)(at)
acts.append({'id':act,
'label':'condition'})
return acts
-
- def configureFromDOMNode(self, node):
- """Configures the activity from a given DOM-Node"""
- BaseTalesActivity.configureFromDOMNode(self, node)
-
- if not node.hasAttribute("continue_activity"):
- raise ConfigurationError, self.error_string % self.activity_type
- self.continue_activity =
utils.flexSplit(node.getAttribute("continue_activity").encode('ascii'))
-
-
class ConditionWorkItem(BaseTalesWorkItem):
- activity_type = "condition"
- security = ClassSecurityInfo()
-
-
__implements__ = BaseTalesWorkItem.__implements__ + \
(IConditionWorkItem, )
+ security = ClassSecurityInfo()
-
+ activity_type = "condition"
######################
# ITalesWorkItem
Modified: AlphaFlow/trunk/activities/configuration.py
==============================================================================
--- AlphaFlow/trunk/activities/configuration.py (original)
+++ AlphaFlow/trunk/activities/configuration.py Mon Jun 27 15:24:52 2005
(at)(at) -6,17 +6,13 (at)(at)
# Zope imports
from AccessControl import ClassSecurityInfo
-# Plone/AT imports
-from Products.CMFCore.utils import getToolByName
-from Products.Archetypes import public as atapi
-
# Sibling imports
from Products.AlphaFlow.interfaces import \
IConfigurationActivity, IConfigurationWorkItem
from Products.AlphaFlow.workitem import \
registerWorkItem, BaseAssignableWorkItem, Group
from Products.AlphaFlow.activity import registerActivity,
BaseAssignableActivity
-from Products.AlphaFlow import utils, config
+from Products.AlphaFlow import config
from Products.AlphaFlow.exception import ConfigurationError
from Products.AlphaFlow.action import Action
from Products.AlphaFlow.workflowattr import WorkflowAttribute
(at)(at) -33,39 +29,27 (at)(at)
icon = "configuration"
attributes = BaseAssignableActivity.attributes + (
+ # viewUrlExpression overwrites existing viewUrlExpression
WorkflowAttribute('viewUrlExpression', 'view_url_expr',
'string:${content/absolute_url}/af_edit_workitem?'
'workitem=${workitem/getId}&action=configure',
'(TALES expression) URL to "view" a workitem, '
'e.g. "Edit document" points to the edit-tab'),
WorkflowAttribute('continue_activity', 'continue_activity', (),
- 'Activity to start after completion.'),
- WorkflowAttribute('configures', '', (),
+ 'Activity to start after completion.',
+ encoding='ascii', datatype=tuple),
+ WorkflowAttribute('', 'configures_all', None,
+ 'Set to true to configure all activities.',
+ importHandler=None, # done by _attr_*_configure
+ exportHandler=None),
+ WorkflowAttribute('configures', 'configures', (),
'Other activities which are configured by this '
'activity or None as marker for all activities.',
- importHandler='attrImport_configure',
+ encoding='ascii', datatype=tuple,
+ importHandler='_attr_import_configure',
exportHandler='_attr_export_configure'),
)
-
- def configureFromDOMNode(self, node):
- """Configures the activity from a given DOM-Node"""
- ConfigurationActivity.inheritedAttribute(
- 'configureFromDOMNode')(self, node)
-
- if node.hasAttribute("continue_activity"):
- self.continue_activity = tuple(
- utils.flexSplit(node.getAttribute(
- "continue_activity").encode("ascii")))
-
- if node.hasAttribute('configures_all'):
- self.configures = None # marker for "all"
- elif node.hasAttribute('configures'):
- self.configures = tuple(utils.flexSplit(node.getAttribute(
- "configures").encode("ascii")))
- else:
- raise ConfigurationError, \
- "Attribute configures or configures_all needed."
def graphGetPossibleChildren(self):
"Return a list of possible following activities. (List of ids)"
(at)(at) -87,8 +71,19 (at)(at)
if self.configures is None: # marker for "all"
node.setAttribute('configures_all', convert_to_xml(True))
else:
- node.setAttribute('configures',
- convert_to_xml(self.configures))
+ self._attr_export_simple(attr, node)
+
+
+ def _attr_import_configure(self, attr, node):
+ if node.hasAttribute('configures_all'):
+ setattr(self, attr.classAttr, None) # None is marker for "all"
+ elif node.hasAttribute('configures'):
+ self._attr_import_simple(attr, node)
+ else:
+ raise ConfigurationError, \
+ "%r: Attribute configures or configures_all needed." % (
+ self.nodeName,)
+
class ConfigurationWorkItem(BaseAssignableWorkItem):
Modified: AlphaFlow/trunk/activities/dcworkflow.py
==============================================================================
--- AlphaFlow/trunk/activities/dcworkflow.py (original)
+++ AlphaFlow/trunk/activities/dcworkflow.py Mon Jun 27 15:24:52 2005
(at)(at) -29,22 +29,14 (at)(at)
attributes = BaseAutomaticActivity.attributes + (
WorkflowAttribute('status', 'status', '',
- 'Status which is set as DCWorkFlow status.'),
+ 'Status which is set as DCWorkFlow status.',
+ required=True, encoding='ascii', datatype=str),
)
_properties = BaseAutomaticActivity._properties + \
({'id': 'status', 'type': 'text', 'mode': 'w'},
)
-
- def configureFromDOMNode(self, node):
- """Configures the activity from a given DOM-Node"""
- BaseAutomaticActivity.configureFromDOMNode(self, node)
-
- if not node.hasAttribute("status"):
- raise ConfigurationError, "Status required in %r" % (
- self.activity_type, )
- self.status = node.getAttribute("status").encode("ascii")
-
+
class DCWorkFlowWorkItem(BaseAutomaticWorkItem):
Modified: AlphaFlow/trunk/activities/decision.py
==============================================================================
--- AlphaFlow/trunk/activities/decision.py (original)
+++ AlphaFlow/trunk/activities/decision.py Mon Jun 27 15:24:52 2005
(at)(at) -6,17 +6,15 (at)(at)
# Zope imports
from AccessControl import ClassSecurityInfo, getSecurityManager
-# # Plone/AT imports
-# from Products.CMFCore.utils import getToolByName
+# Plone/AT imports
from Products.Archetypes import public as atapi
-# # Sibling imports
+# Sibling imports
from Products.AlphaFlow.interfaces import IDecisionActivity, IDecisionWorkItem
from Products.AlphaFlow.workitem import BaseAssignableWorkItem,
registerWorkItem
from Products.AlphaFlow.activity import BaseAssignableActivity,
registerActivity
-from Products.AlphaFlow import config, utils
+from Products.AlphaFlow import config
from Products.AlphaFlow.action import Action
-from Products.AlphaFlow.exception import ConfigurationError
from Products.AlphaFlow.workflowattr import WorkflowAttribute
(at)(at) -34,18 +32,23 (at)(at)
activity_type = nodeName = "decision"
icon = "decision"
+ known_decision_modi = ['first_yes', 'all_yes']
+
attributes = BaseAssignableActivity.attributes + (
WorkflowAttribute('decision_notice', 'decision_notice', '',
'Describing the task for the decision.'),
WorkflowAttribute('decision_modus', 'decision_modus', '',
- 'One of ["first_yes", "all_yes"]'),
+ 'One of self.known_decision_modi',
+ required=True,
+ vocabulary=known_decision_modi),
WorkflowAttribute('reject_activity', 'reject_activity', (),
- 'Activity if result is "no".'),
+ 'Activity if result is "no".',
+ encoding='ascii', datatype=tuple),
WorkflowAttribute('accept_activity', 'accept_activity', (),
- 'Activity if result is "yes".'),
+ 'Activity if result is "yes".',
+ encoding='ascii', datatype=tuple),
)
- known_decision_modi = ['first_yes', 'all_yes']
configurationSchema = BaseAssignableActivity.configurationSchema.copy()
# gets modified by __init__!
(at)(at) -75,29 +78,6 (at)(at)
"""Return a list of possible following activities. (List of ids)"""
return self.reject_activity + self.accept_activity
- def configureFromDOMNode(self, node):
- """Configures the activity from a given DOM-Node"""
- DecisionActivity.inheritedAttribute('configureFromDOMNode')(self,
node)
- has = node.hasAttribute
- get = node.getAttribute
- if has("decision_notice"):
- self.decision_notice = get("decision_notice")
- if has("reject_activity"):
- self.reject_activity = tuple(
- utils.flexSplit(get("reject_activity").encode("ascii"))
- )
- if has("accept_activity"):
- self.accept_activity = tuple(
- utils.flexSplit(get("accept_activity").encode("ascii"))
- )
- if not has("decision_modus"):
- raise ConfigurationError, "Attribute decision_modus has to be set"
- self.decision_modus = get("decision_modus")
- if self.decision_modus not in self.known_decision_modi:
- raise ConfigurationError, "Attribute decision_modus value needs
to"\
- " be in %s" % self.known_decision_modi
-
-
def graphGetPossibleChildren(self):
"""Return a list of possible following activities. (List of ids)"""
Modified: AlphaFlow/trunk/activities/expression.py
==============================================================================
--- AlphaFlow/trunk/activities/expression.py (original)
+++ AlphaFlow/trunk/activities/expression.py Mon Jun 27 15:24:52 2005
(at)(at) -40,22 +40,15 (at)(at)
# XXX change this on migration to BaseTalesActivity as base class
attributes = BaseAutomaticActivity.attributes + (
WorkflowAttribute('expression', 'expression', '',
- 'Expression to be called.'),
+ 'Expression to be called.',
+ required=True, encoding='ascii', datatype=str),
)
_properties = BaseAutomaticActivity._properties + \
({'id': 'expression', 'type': 'string', 'mode': 'w'},
)
- def configureFromDOMNode(self, node):
- """Configures the activity from a given DOM-Node"""
- BaseAutomaticActivity.configureFromDOMNode(self, node)
-
- if not node.hasAttribute("expression"):
- raise ConfigurationError, "expression required in %r" % (
- self.activity_type)
- self.expression = node.getAttribute("expression").encode("ascii")
-
+
class ExpressionWorkItem(BaseAutomaticWorkItem):
Modified: AlphaFlow/trunk/activities/gates.py
==============================================================================
--- AlphaFlow/trunk/activities/gates.py (original)
+++ AlphaFlow/trunk/activities/gates.py Mon Jun 27 15:24:52 2005
(at)(at) -20,32 +20,26 (at)(at)
activity_type = nodeName = "gate"
icon = "gate"
+ # Multimerge is like "OR" (trigger on each)
+ # Discriminate is like "XOR" (trigger on first, ignore others)
+ # Synchronize is like "AND" (trigger once when all completed)
+ mode_types = ('multi-merge', 'discriminate', 'synchronizing-merge')
+
+
attributes = BaseAutomaticActivity.attributes + (
WorkflowAttribute('mode', 'mode', '',
- 'Mode the gate works, values see self.mode_types'),
+ 'Mode the gate works, values see self.mode_types',
+ required=True, encoding='ascii', datatype=str,
+ vocabulary=mode_types),
)
- mode_types = ('multi-merge', 'discriminate', 'synchronizing-merge')
+
_properties = BaseAutomaticActivity._properties + \
({'id': 'mode', 'type': 'selection', 'mode': 'w',
'select_variable': 'mode_types'},
)
- # Discriminate is like "XOR" (trigger on first, ignore others)
- # Multimerge is like "OR" (trigger on each)
- # Synchronize is like "AND" (trigger once when all completed)
-
- def configureFromDOMNode(self, node):
- """Configures the activity from a given DOM-Node"""
- GateActivity.inheritedAttribute('configureFromDOMNode')(self, node)
- if not node.hasAttribute("mode"):
- raise ConfigurationError, "Mode required in %r" % (
- self.activity_type, )
- self.mode = node.getAttribute('mode').encode("ascii")
- if self.mode not in self.mode_types:
- raise ConfigurationError, "Mode must be one of %s for %r" % (
- self.mode_types, self.activity_type)
class GateWorkItem(BaseWorkItem):
Modified: AlphaFlow/trunk/activities/interfaces.py
==============================================================================
--- AlphaFlow/trunk/activities/interfaces.py (original)
+++ AlphaFlow/trunk/activities/interfaces.py Mon Jun 27 15:24:52 2005
(at)(at) -94,7 +94,7 (at)(at)
this workflow."""
def getRecipientModes():
- """Return list of IEMailRecipientMode instances."""
+ """Return list of IEMailRecipientMode instances (possible
recipents)."""
class IEMailWorkItem(IAutomaticWorkItem):
Modified: AlphaFlow/trunk/activities/notify.py
==============================================================================
--- AlphaFlow/trunk/activities/notify.py (original)
+++ AlphaFlow/trunk/activities/notify.py Mon Jun 27 15:24:52 2005
(at)(at) -1,6 +1,6 (at)(at)
# Copyright (c) 2004-2005 gocept gmbh & co. kg
# See also LICENSE.txt
-# notify.py,v 1.3 2005/02/23 12:48:50 zagy Exp
+# $Id$
"""Implement the email activities.
"""
(at)(at) -25,10 +25,30 (at)(at)
from Products.AlphaFlow.interfaces import \
IEMailActivity, IEMailWorkItem, IEMailRecipientMode
from Products.AlphaFlow.workflowattr import \
- WorkflowAttribute, InitializeWorkflowAttributes
-from Products.AlphaFlow.importexport import DOMExporter
+ WorkflowAttribute, InitializeWorkflowAttributes, findAttrInAttributes
+from Products.AlphaFlow.importexport import DOMExporter, DOMImporter
+from Products.AlphaFlow.registry import Registry
+class EMailRegistry(Registry):
+ """Registry for email recipents."""
+
+ def getFromDOMNode(self, node):
+ """Get a class object from data given in DOM-Node.
+
+ node.getAttribute('mode_name') is used as key.
+ """
+ if node.nodeName != AbstractRecipent.nodeName:
+ raise KeyError, 'Only recipent modes in this registry'
+ return self.get(node.getAttribute('type'))
+
+
+#################################
+# Registry for all recipent modes
+# Registry keys should be class.mode_name
+notify_registry = EMailRegistry()
+
+
class EMailActivity(BaseAutomaticActivity):
__implements__ = BaseAutomaticActivity.__implements__ + \
(at)(at) -41,57 +61,30 (at)(at)
attributes = BaseAutomaticActivity.attributes + (
WorkflowAttribute('template', 'template', '',
'ID of a DTML-Method-Object being available from '
- 'portal root.'),
+ 'portal root.',
+ required=True, encoding='ascii', datatype=str),
WorkflowAttribute('mailSubject', 'mailSubject',
'AlphaFlow notification message',
- 'Static subject line for the mails sent.'),
+ 'Static subject line for the mails sent.',
+ required=True),
WorkflowAttribute('recipientModes', '', (),
- 'One of ["owner", "next_assignees", "actual_role"] '
- 'who will get the email.',
- importHandler="attrImport_email",
+ 'Who will get the email. (possible values see'
+ 'default of mode_name in subclasses of '
+ 'AbstractRecipent)',
+ required=True, datatype=tuple,
+ importHandler="_attr_import_email",
exportHandler="_attr_export_email"),
)
- # XXX this is error prone because on new recipent_mode this gets forgotten
- # XXX to update. should use getRecipientModes!
- possible_recipients = ['owner', 'next_assignees', 'actual_role']
-
_properties = BaseAutomaticActivity._properties + \
({'id': 'template', 'type': 'string', 'mode': 'w',},
- {'id': 'recipient', 'type': 'selection', 'mode': 'w',
- 'select_variable': 'possible_recipients'},
+ {'id': 'recipient', 'type': 'string', 'mode': 'w',},
{'id': 'mailSubject', 'type': 'ustring', 'mode': 'w'},
)
-
- def configureFromDOMNode(self, node):
- """Configures the activity from a given DOM-Node"""
- global recipient_modes
- BaseAutomaticActivity.configureFromDOMNode(self, node)
-
- if not node.hasAttribute("template"):
- raise ConfigurationError, "template required in %r" % (
- self.activity_type, )
- self.template = node.getAttribute("template").encode("ascii")
-
- if not node.hasAttribute("mailSubject"):
- raise ConfigurationError, "mailSubject required in %r" % (
- self.activity_type, )
- self.mailSubject = node.getAttribute("mailSubject")
-
- modes = []
- for recipient in node.getElementsByTagName("recipient"):
- mode_name = recipient.getAttribute("type").encode("ascii")
- mode = recipient_modes[mode_name]()
- mode.configureFromDOMNode(recipient)
- modes.append(mode)
- if len(modes) == 0:
- raise ConfigurationError, "No recipients specified in %r" % self
-
- self.recipientModes = tuple(modes)
def getRecipientModes(self):
- """Return list of IEMailRecipientMode instances."""
+ "Return list of IEMailRecipientMode instances (possible recipents)."
return self.recipientModes
#########
(at)(at) -100,7 +93,15 (at)(at)
def _attr_export_email(self, attr, node):
for mode in self.recipientModes:
mode.writeDOM(node)
-
+
+ def _attr_import_email(self, attr, node):
+ global notify_registry
+
+ modes = self.createAndConfigureChildNodes(node, notify_registry)
+ if len(modes) == 0:
+ raise ConfigurationError, "No recipients specified in %r" % self
+ self.recipientModes = attr.datatype(modes)
+
class EMailWorkItem(BaseAutomaticWorkItem):
(at)(at) -188,7 +189,9 (at)(at)
email)
-class AbstractRecipent(Persistent, DOMExporter):
+
+
+class AbstractRecipent(Persistent, DOMExporter, DOMImporter):
"""Abstract recipient class."""
__implements__ = (IEMailRecipientMode, )
(at)(at) -196,10 +199,6 (at)(at)
nodeName = "recipient"
attributes = ()
- def configureFromDOMNode(self, node):
- """Configures the activity from the given DOM node."""
- pass
-
class RecipientOwner(AbstractRecipent):
(at)(at) -245,21 +244,14 (at)(at)
class RecipientActualRole(AbstractRecipent):
"""Recipient mode for notifying users with one of the given roles."""
- attributes = (WorkflowAttribute('mode_name', 'type', 'actual_role',
- 'Identifier for a specific mode.',
- importHandler=None),
- WorkflowAttribute('roles', 'roles', (),
- 'Members with this roles get an e-mail.'),
- )
-
- def configureFromDOMNode(self, node):
- """Configures the activity from the given DOM node."""
- roles = node.getAttribute("roles").encode("ascii")
- if len(roles) == 0:
- raise ConfigurationError, "roles attribute of %s is empty" % \
- node.getParentNode().getAttribute("id")
-
- self.roles = tuple(flexSplit(roles))
+ attributes = (
+ WorkflowAttribute('mode_name', 'type', 'actual_role',
+ 'Identifier for a specific mode.',
+ importHandler=None),
+ WorkflowAttribute('roles', 'roles', (),
+ 'Members with this roles get an e-mail.',
+ required=True, encoding="ascii", datatype=tuple),
+ )
def getRecipientsForWorkItem(self, wi):
"""Returns list of users with at least one of the given roles."""
(at)(at) -272,18 +264,19 (at)(at)
return relevant
-recipient_modes = {}
-def registerEMailRecipientMode(mode):
- global recipient_modes
- recipient_modes[mode.mode_name] = mode
+
+def registerRecipentMode(mode):
+ global notify_registry
+ InitializeWorkflowAttributes(mode,
+ findAttrInAttributes(mode,
+ 'mode_name').default,
+ registry=notify_registry)
+
# register the stuff
registerActivity(EMailActivity)
registerWorkItem(EMailWorkItem)
-InitializeWorkflowAttributes(RecipientOwner)
-InitializeWorkflowAttributes(RecipientNextAssignees)
-InitializeWorkflowAttributes(RecipientActualRole)
-registerEMailRecipientMode(RecipientOwner)
-registerEMailRecipientMode(RecipientNextAssignees)
-registerEMailRecipientMode(RecipientActualRole)
+registerRecipentMode(RecipientOwner)
+registerRecipentMode(RecipientNextAssignees)
+registerRecipentMode(RecipientActualRole)
Modified: AlphaFlow/trunk/activities/ntask.py
==============================================================================
--- AlphaFlow/trunk/activities/ntask.py (original)
+++ AlphaFlow/trunk/activities/ntask.py Mon Jun 27 15:24:52 2005
(at)(at) -1,6 +1,6 (at)(at)
# Copyright (c) 2005 gocept gmbh & co. kg
# See also LICENSE.txt
-# ntask.py,v 1.12.2.1 2005/05/02 10:08:51 zagy Exp
+# $Id$
"""NTask activity and work item."""
# Zope imports
(at)(at) -19,28 +19,26 (at)(at)
from Products.AlphaFlow.exception import ConfigurationError
from Products.AlphaFlow.action import Action
from Products.AlphaFlow.workflowattr import \
- WorkflowAttribute, InitializeWorkflowAttributes
-from Products.AlphaFlow.importexport import DOMExporter
+ WorkflowAttribute, InitializeWorkflowAttributes, \
+ workflow_attributes_registry
+from Products.AlphaFlow.importexport import DOMExporter, DOMImporter
-class Exit(Persistent, DOMExporter):
+class Exit(Persistent, DOMExporter, DOMImporter):
__implements__ = (IExit, )
nodeName = "exit"
attributes = (
WorkflowAttribute('id', 'id', None,
- 'Id of the exit.'),
+ 'Id of the exit.',
+ encoding="ascii", datatype=str),
WorkflowAttribute('title', 'title', None,
'Title of the exit.'),
WorkflowAttribute('activities', 'activities', (),
- 'Continue activities if this exit gets chosen.'),
+ 'Continue activities if this exit gets chosen.',
+ encoding='ascii', datatype=tuple),
)
- def __init__(self, id, title, activities):
- self.id = id
- self.title = title
- self.activities = activities
-
(at)(at) -55,7 +53,8 (at)(at)
attributes = BaseAssignableActivity.attributes + (
WorkflowAttribute('exits', '', (),
'Tuple of IExit objects',
- importHandler="attrImport_ntask",
+ datatype=tuple,
+ importHandler="_attr_import_ntask",
exportHandler="_attr_export_ntask"),
)
(at)(at) -70,22 +69,6 (at)(at)
)),
)) + BaseAssignableActivity.configurationSchema
- def configureFromDOMNode(self, node):
- """Configures the activity from a given DOM-Node"""
- NTaskActivity.inheritedAttribute('configureFromDOMNode')(self, node)
-
- exit_ids = []
- exits = []
- for exit in node.getElementsByTagName("exit"):
- id = exit.getAttribute('id').encode('ascii')
- if id in exit_ids:
- raise ConfigurationError, "Double exit id: %s" % id
- title = exit.getAttribute('title')
- activities = utils.flexSplit(
- exit.getAttribute('activities').encode('ascii'))
- exits.append(Exit(id, title, activities))
- exit_ids.append(id)
- self.exits = tuple(exits)
def getPossibleChildren(self):
"""Return a list of possible following activities. (List of ids)"""
(at)(at) -113,6 +96,18 (at)(at)
for exit in getattr(self, attr.classAttr):
exit.writeDOM(node)
+ def _attr_import_ntask(self, attr, node):
+ "Import exits."
+ exits = self.createAndConfigureChildNodes(node,
+
workflow_attributes_registry)
+ exit_ids = [x.id for x in exits]
+ for exit_id in exit_ids[:]:
+ exit_ids.remove(exit_id)
+ if exit_id in exit_ids:
+ raise ConfigurationError, "Double exit id: %s" % exit_id
+ setattr(self, attr.classAttr, attr.datatype(exits))
+
+
class NTaskWorkItem(BaseAssignableWorkItem):
(at)(at) -180,6 +175,6 (at)(at)
# register the stuff
-InitializeWorkflowAttributes(Exit)
+InitializeWorkflowAttributes(Exit, Exit.nodeName)
registerActivity(NTaskActivity)
registerWorkItem(NTaskWorkItem)
Modified: AlphaFlow/trunk/activities/permission.py
==============================================================================
--- AlphaFlow/trunk/activities/permission.py (original)
+++ AlphaFlow/trunk/activities/permission.py Mon Jun 27 15:24:52 2005
(at)(at) -17,43 +17,40 (at)(at)
IPermissionActivity, IPermissionWorkItem, IPermissionSetting
from Products.AlphaFlow.workitem import registerWorkItem,
BaseAutomaticWorkItem
from Products.AlphaFlow.activity import registerActivity,
BaseAutomaticActivity
-from Products.AlphaFlow.utils import \
- modifyRolesForPermission, makeBoolFromUnicode, flexSplit
+from Products.AlphaFlow.utils import modifyRolesForPermission
from Products.AlphaFlow.workflowattr import \
- WorkflowAttribute, InitializeWorkflowAttributes
+ WorkflowAttribute, InitializeWorkflowAttributes, \
+ workflow_attributes_registry
from Products.AlphaFlow.exception import ConfigurationError
from Products.AlphaFlow import config
-from Products.AlphaFlow.importexport import DOMExporter
+from Products.AlphaFlow.importexport import DOMExporter, DOMImporter
-class PermissionSetting(DOMExporter):
+class PermissionSetting(DOMExporter, DOMImporter):
__implements__ = (IPermissionSetting, )
nodeName = "permission"
- attributes = (WorkflowAttribute('permission', 'name', '',
- 'The permission affected.'),
+ attributes = (WorkflowAttribute('permission', 'id', '',
+ 'id is deprecated, use name!',
+ encoding="ascii", datatype=str,
+ importHandler='_attr_import_permid',
+ exportHandler=None),
+ WorkflowAttribute('permission', 'name', '',
+ 'The permission affected.',
+ encoding="ascii", datatype=str),
WorkflowAttribute('roles', 'roles', '',
- 'Sequence of affected roles.'),
+ 'Sequence of affected roles.',
+ encoding="ascii", datatype=tuple),
WorkflowAttribute('acquire', 'acquire', '',
- '(bool) acquire permission or not.'),
+ '(bool) acquire permission or not.',
+ required=True, datatype=bool),
)
- def __init__(self, context, permission, roles, acquire):
- self.permission = permission
- self.roles = roles
- self.acquire = acquire
- self._validate(context)
-
def _validate(self, context):
"""Validate the permission configuration.
- Permissions are required to exist
- - Acquire must be a boolean.
"""
- if not isinstance(self.acquire, bool):
- raise ValueError, "Acquire must be bool"
-
- # assert the permission does exist
app = context.getPhysicalRoot()
permission_valid = False
permission = self.permission
(at)(at) -62,11 +59,18 (at)(at)
if name == permission:
permission_valid = True
break
-
if not permission_valid:
- raise ValueError, "The permission %r is invalid." % permission
+ raise ConfigurationError, \
+ "The permission %r does not exist." % permission
+
+ def _attr_import_permid(self, attr, node):
+ warn('<permission id="..." /> is deprecated, use name="..."
instead. '
+ 'id will get removed in version 1.1.',
+ DeprecationWarning, stacklevel=4)
+ self._attr_import_simple(attr, node)
+
-InitializeWorkflowAttributes(PermissionSetting)
+InitializeWorkflowAttributes(PermissionSetting, PermissionSetting.nodeName)
class PermissionActivity(BaseAutomaticActivity):
(at)(at) -82,43 +86,11 (at)(at)
attributes = BaseAutomaticActivity.attributes + (
WorkflowAttribute('permissions', '', (),
'Tuple of IPermissionSettings',
- importHandler="attrImport_permission",
+ datatype=tuple,
+ importHandler="_attr_import_permission",
exportHandler="_attr_export_permission"),
)
- def configureFromDOMNode(self, node):
- """Configures the activity from a given DOM-Node"""
- BaseAutomaticActivity.configureFromDOMNode(self, node)
- defs = []
- for perm in node.childNodes:
- if perm.nodeType in (perm.TEXT_NODE, perm.COMMENT_NODE):
- # ignore text and comment nodes
- continue
- if perm.nodeType != perm.ELEMENT_NODE:
- raise ConfigurationError, "Invalid node type %r (%r)" % (
- perm.nodeType, perm.nodeName)
- if perm.nodeName != "permission":
- raise ConfigurationError, "Invalid node %r" % (
- node.nodeName, )
-
- get = perm.getAttribute
- has = perm.hasAttribute
- if has('id'):
- warn('<permission id="..." /> is deprecated, use
name="..." instead. '
- 'id will get removed in version 1.1.',
- DeprecationWarning, stacklevel=4)
- perm = get("id").encode("ascii")
- else:
- perm = get("name").encode("ascii")
- roles = flexSplit(get("roles").encode("ascii"))
- acquire = makeBoolFromUnicode(get("acquire"))
- try:
- p = PermissionSetting(self, perm, roles, acquire)
- except ValueError, e:
- raise ConfigurationError, e
- defs.append(p)
- self.permissions = tuple(defs)
-
security.declareProtected(config.MANAGE_WORKFLOW, 'setPermissions')
def setPermissions(self, permission_setting):
permissions = []
(at)(at) -135,6 +107,14 (at)(at)
for permObj in self.permissions:
permObj.writeDOM(node)
+ security.declarePrivate('_attr_import_permission')
+ def _attr_import_permission(self, attr, node):
+ permissions = self.createAndConfigureChildNodes(
+ node, workflow_attributes_registry)
+ self.permissions = attr.datatype(permissions)
+ for perm in self.permissions:
+ perm._validate(self)
+
class PermissionWorkItem(BaseAutomaticWorkItem):
Modified: AlphaFlow/trunk/activities/recursion.py
==============================================================================
--- AlphaFlow/trunk/activities/recursion.py (original)
+++ AlphaFlow/trunk/activities/recursion.py Mon Jun 27 15:24:52 2005
(at)(at) -5,6 +5,7 (at)(at)
# Zope imports
from AccessControl import ClassSecurityInfo
+import zLOG
# Plone/AT imports
from Products.CMFCore.utils import getToolByName
(at)(at) -15,11 +16,11 (at)(at)
from Products.AlphaFlow.workitem import registerWorkItem,
BaseAutomaticWorkItem
from Products.AlphaFlow.activity import \
registerActivity, BaseAutomaticActivity
-from Products.AlphaFlow import config, utils
+from Products.AlphaFlow import config
from Products.AlphaFlow.interfaces import IDaemonActivity
from Products.AlphaFlow.workflowattr import WorkflowAttribute
-import zLOG
+
class RecursionActivity(BaseAutomaticActivity):
(at)(at) -32,13 +33,15 (at)(at)
attributes = BaseAutomaticActivity.attributes + (
WorkflowAttribute('recursion_activity', 'recursion_activity', (),
- 'Activities which will get called recursively.'),
+ 'Activities which will get called recursively.',
+ encoding='ascii', datatype=tuple),
WorkflowAttribute('break_activities', 'break_activities', (),
- 'Activities which stop recursion.'),
+ 'Activities which stop recursion.',
+ encoding='ascii', datatype=tuple),
WorkflowAttribute('optional_recursion', 'optional_recursion', True,
'User can select via UI if recursion should be '
'called.',
- importHandler="_attr_import_bool"),
+ datatype=bool),
)
configurationSchema = Schema((
(at)(at) -62,21 +65,6 (at)(at)
"""Return a list of possible following activities. (List of ids)"""
return self.recursion_activity + self.continue_activity
- def configureFromDOMNode(self, node):
- """Configures the activity from a given DOM-Node"""
- RecursionActivity.inheritedAttribute('configureFromDOMNode')(self,
node)
- if node.hasAttribute("recursion_activity"):
- self.recursion_activity = tuple(
-
utils.flexSplit(node.getAttribute("recursion_activity").encode("ascii"))
- )
- if node.hasAttribute("break_activities"):
- self.break_activities = tuple(
-
utils.flexSplit(node.getAttribute("break_activities").encode("ascii"))
- )
- if node.hasAttribute('optional_recursion'):
- self.optional_recursion = \
- bool(node.getAttribute('optional_recursion'))
-
def graphGetPossibleChildren(self):
"""Return a list of possible following activities. (List of ids)"""
acts = []
Modified: AlphaFlow/trunk/activities/review.py
==============================================================================
--- AlphaFlow/trunk/activities/review.py (original)
+++ AlphaFlow/trunk/activities/review.py Mon Jun 27 15:24:52 2005
(at)(at) -39,9 +39,11 (at)(at)
WorkflowAttribute('review_notice', 'review_notice', '',
'Describing the review role.'),
WorkflowAttribute('reject_activity', 'reject_activity', (),
- 'Activity if one votes "no".'),
+ 'Activity if one votes "no".',
+ encoding='ascii', datatype=tuple),
WorkflowAttribute('accept_activity', 'accept_activity', (),
- 'Activity if all vote "yes".'),
+ 'Activity if all vote "yes".',
+ encoding='ascii', datatype=tuple),
)
configurationSchema = BaseAssignableActivity.configurationSchema.copy()
(at)(at) -77,18 +79,6 (at)(at)
warn('Using ReviewActivity is deprecated, use DecisionActivity
instead.',
DeprecationWarning, stacklevel=2)
ReviewActivity.inheritedAttribute('configureFromDOMNode')(self, node)
- has = node.hasAttribute
- get = node.getAttribute
- if has("review_notice"):
- self.review_notice = get("review_notice")
- if has("reject_activity"):
- self.reject_activity = tuple(
- utils.flexSplit(get("reject_activity").encode("ascii"))
- )
- if has("accept_activity"):
- self.accept_activity = tuple(
- utils.flexSplit(get("accept_activity").encode("ascii"))
- )
def graphGetPossibleChildren(self):
"""Return a list of possible following activities. (List of ids)"""
Modified: AlphaFlow/trunk/activities/routing.py
==============================================================================
--- AlphaFlow/trunk/activities/routing.py (original)
+++ AlphaFlow/trunk/activities/routing.py Mon Jun 27 15:24:52 2005
(at)(at) -9,7 +9,8 (at)(at)
# Sibling imports
from Products.AlphaFlow.workitem import registerWorkItem, BaseWorkItem
-from Products.AlphaFlow.activity import registerActivity, BaseActivity
+from Products.AlphaFlow.activity import \
+ registerActivity, BaseActivity, activity_registry
from Products.AlphaFlow import config
from Products.AlphaFlow.utils import killWorkItemRecursively
from Products.AlphaFlow.interfaces import IRoutingActivity, IRoutingWorkItem
(at)(at) -41,7 +42,7 (at)(at)
attributes = BaseActivity.attributes + (
WorkflowAttribute('gates', '', (),
'Gate activities inside the route.',
- importHandler="attrImport_route",
+ importHandler="_attr_import_route",
exportHandler="_attr_export_route"),
WorkflowAttribute('routes', '', (),
'All activities inside route which are no gates.',
(at)(at) -55,25 +56,7 (at)(at)
{'id': 'routes', 'type': 'multiple selection', 'mode': 'w',
'select_variable': 'listActivityIds'},
)
-
- def configureFromDOMNode(self, node):
- """Configures the activity from a given DOM-Node"""
- BaseActivity.configureFromDOMNode(self, node)
-
- process = self.getParentNode()
- for child in node.childNodes:
- if child.nodeType in (child.TEXT_NODE,
- child.COMMENT_NODE):
- # Ignore whitespace
- continue
- act_id = child.getAttribute('id').encode('ascii')
- act_type = child.nodeName
- activity = process.addActivity(act_id, act_type)
- activity.configureFromDOMNode(child)
- if act_type == "gate":
- self.gates = self.gates + (act_id,)
- else:
- self.routes = self.routes + (act_id,)
+
security.declareProtected(config.MANAGE_WORKFLOW, "getPossibleChildren")
def getPossibleChildren(self):
(at)(at) -99,6 +82,22 (at)(at)
for activity_id in self.routes + self.gates:
activity = process[activity_id]
activity.writeDOM(node)
+
+ security.declarePrivate('_attr_import_route')
+ def _attr_import_route(self, attr, node):
+ process = self.acquireProcess()
+ childs = self.createAndConfigureChildNodes(node, activity_registry)
+ gates = []
+ routes = []
+ for child in childs:
+ act_id = child.getId()
+ process._set_activity(act_id, child)
+ if child.activity_type == "gate":
+ gates.append(act_id)
+ else:
+ routes.append(act_id)
+ self.gates = tuple(gates)
+ self.routes = tuple(routes)
class RoutingWorkItem(BaseWorkItem):
Modified: AlphaFlow/trunk/activities/task.py
==============================================================================
--- AlphaFlow/trunk/activities/task.py (original)
+++ AlphaFlow/trunk/activities/task.py Mon Jun 27 15:24:52 2005
(at)(at) -30,7 +30,8 (at)(at)
attributes = BaseAssignableActivity.attributes + (
WorkflowAttribute('completion_activity', 'completion_activity', (),
- 'Activity to start after completion.'),
+ 'Activity to start after completion.',
+ encoding="ascii", datatype=tuple),
)
configurationSchema = atapi.Schema((
(at)(at) -55,18 +56,6 (at)(at)
"""Return a list of possible following activities. (List of ids)"""
return self.completion_activity
- def configureFromDOMNode(self, node):
- """Configures the activity from a given DOM-Node"""
- TaskActivity.inheritedAttribute('configureFromDOMNode')(self, node)
- if node.hasAttribute("completion_activity"):
- self.completion_activity = tuple(
-
utils.flexSplit(node.getAttribute("completion_activity").encode("ascii"))
- )
- if node.hasAttribute("assignees"):
- raise ConfigurationError, \
- "The assignees attribute is deprecated, use assignees tag
instead!"
-# self.assignees = node.getAttribute("assignees")
-
def graphGetPossibleChildren(self):
"""Return a list of possible following activities. (List of ids)"""
acts = []
Modified: AlphaFlow/trunk/activity.py
==============================================================================
--- AlphaFlow/trunk/activity.py (original)
+++ AlphaFlow/trunk/activity.py Mon Jun 27 15:24:52 2005
(at)(at) -26,9 +26,12 (at)(at)
from Products.AlphaFlow.exception import ConfigurationError
from Products.AlphaFlow.workflowattr import \
WorkflowAttribute, InitializeWorkflowAttributes, findAttrInAttributes
-from Products.AlphaFlow.importexport import DOMExporter, convert_to_xml
+from Products.AlphaFlow.importexport import \
+ DOMExporter, DOMImporter, convert_to_xml
+from Products.AlphaFlow.registry import Registry
-class BaseActivity(PropertyManager, SimpleItem, DOMExporter):
+
+class BaseActivity(PropertyManager, SimpleItem, DOMExporter, DOMImporter):
"""A base class to implement activities"""
__implements__ = SimpleItem.__implements__ + (IActivity,)
(at)(at) -44,16 +47,19 (at)(at)
importHandler=None,
exportHandler="_attr_export_id"),
WorkflowAttribute('title', 'title', '',
- 'Title of the activity.'),
+ 'Title of the activity.',
+ encoding="utf-8", datatype=str),
WorkflowAttribute('sortPriority', 'sort', 0,
'Lower priority activities will be shown first.',
- importHandler="_attr_import_int"),
+ datatype=int),
WorkflowAttribute('nonEditableFields', 'nonEditableFields', (),
'Fields in schema which are not to be edited '
- 'aka configured by user of workflow.'),
+ 'aka configured by user of workflow.',
+ datatype=tuple),
WorkflowAttribute('startActivity', 'startActivity', (),
'Workitems to be spawned just before the '
- 'workitem for this activity is started.'),
+ 'workitem for this activity is started.',
+ datatype=tuple),
WorkflowAttribute('editor:availableActivities',
'editor:availableActivities', None,
'a string which holds all activity ids for '
(at)(at) -62,31 +68,7 (at)(at)
exportHandler="_attr_export_activities_list"),
)
- def __init__(self, id):
- self.id = id
-
- security.declareProtected(config.MANAGE_WORKFLOW, "configureFromDOMNode")
- def configureFromDOMNode(self, node):
- """Configures the activity from a given DOM-Node"""
- has = node.hasAttribute
- get = node.getAttribute
- if has("title"):
- self.title = get('title') # XXX needed? .encode("utf-8") (breaks
WF export)
- if has("sort"):
- pri = get('sort')
- try:
- pri = int(pri)
- except ValueError:
- pass
- else:
- self.sortPriority = pri
- if has("nonEditableFields"):
- non_editable = utils.flexSplit(get("nonEditableFields"))
- self.nonEditableFields = non_editable
- if has('startActivity'):
- start = utils.flexSplit(get('startActivity'))
- self.startActivity = start
-
+
security.declareProtected(config.MANAGE_WORKFLOW, "acquireActivity")
def acquireActivity(self):
"""returns the activity instance from the acquisition chain"""
(at)(at) -119,7 +101,7 (at)(at)
"Return a list of possible successor activities as dictionaries."
return [] # to be overwritten by subclasses
- security.declarePrivate('_attr_export_id')
+ security.declarePrivate('_attr_export_activities_list')
def _attr_export_activities_list(self, attr, node):
"Export for editor specific attributes."
node.setAttribute('xmlns:editor',
(at)(at) -146,7 +128,8 (at)(at)
attributes = BaseActivity.attributes + (
WorkflowAttribute('continue_activity', 'continue_activity', (),
'A list of activities that follow this'
- 'automatic activity. (single exit)'),
+ 'automatic activity. (single exit)',
+ encoding='ascii', datatype=tuple),
)
(at)(at) -160,16 +143,8 (at)(at)
"""Return a list of possible following activities. (List of ids)"""
return self.continue_activity
- security.declareProtected(config.MANAGE_WORKFLOW, "configureFromDOMNode")
- def configureFromDOMNode(self, node):
- """Configures the activity from a given DOM-Node"""
- BaseActivity.configureFromDOMNode(self, node)
- if node.hasAttribute("continue_activity"):
- self.continue_activity = tuple(
-
utils.flexSplit(node.getAttribute("continue_activity").encode("ascii"))
- )
-
- security.declareProtected(config.MANAGE_WORKFLOW,
"graphGetPossibleChildren")
+ security.declareProtected(config.MANAGE_WORKFLOW,
+ "graphGetPossibleChildren")
def graphGetPossibleChildren(self):
"""Return a list of possible following activities. (List of ids)"""
acts = []
(at)(at) -183,7 +158,8 (at)(at)
class BaseAssignableActivity(BaseActivity):
-
+ "Workflow activity instances of which may be assigned to a member."
+
__implements__ = BaseActivity.__implements__ + (IAssignableActivity, )
security = ClassSecurityInfo()
(at)(at) -198,15 +174,18 (at)(at)
'e.g. "Edit document" points to the edit-tab'),
WorkflowAttribute('contentRoles', 'content_roles', None,
'Roles which assigned users get on the '
- 'content object.'),
+ 'content object.',
+ encoding='ascii', datatype=tuple),
WorkflowAttribute('assigneesKind', 'kind', 'possible',
'Defines the user assignment method, either '
'"possible" or "actual".',
+ required=True, vocabulary=['actual', 'possible'],
importHandler="_attr_import_assignees",
exportHandler="_attr_export_assignees"),
WorkflowAttribute('roles', 'roles', (),
'Roles to compute which members are assignees',
- importHandler=None, # done by attr_import_assignees
(see above)
+ encoding='ascii', datatype=tuple,
+ importHandler=None, # done by _attr_import_assignees
exportHandler=None),
WorkflowAttribute('assigneesExpression', 'expression', None,
'Tales Expression returning a list of member ids, '
(at)(at) -227,31 +206,6 (at)(at)
),
))
- security.declareProtected(config.MANAGE_WORKFLOW, "configureFromDOMNode")
- def configureFromDOMNode(self, node):
- BaseAssignableActivity.inheritedAttribute('configureFromDOMNode')(
- self, node)
- if node.hasAttribute('view_url_expr'):
- self.viewUrlExpression = node.getAttribute('view_url_expr')
-
- if node.hasAttribute('roles'):
- raise ConfigurationError, 'The roles attribute is deprecated.'
-
- assignees = node.getElementsByTagName('assignees')
- if len(assignees) == 0:
- # default behaviour
- self.roles = ()
- elif len(assignees) == 1:
- self._parse_assignee(assignees[0])
- else:
- raise ConfigurationError, ('<assignees> is only allowed once
per '
- 'activity.')
-
- if node.hasAttribute("content_roles"):
- self.contentRoles = \
- tuple(utils.flexSplit(node.getAttribute('content_roles').
- encode('ascii')))
-
security.declareProtected(config.WORK_WITH_PROCESS,
"getPossibleAssignees")
def getPossibleAssignees(self):
"""Returns a list of possible users."""
(at)(at) -291,40 +245,8 (at)(at)
schema.delField('assignees')
return schema
- ########
+ #########
# private
-
- security.declarePrivate('_parse_assignee')
- def _parse_assignee(self, assignee):
- """helper for configureFromDOMNode
- """
- has = assignee.hasAttribute
- get = assignee.getAttribute
-
- kind = None
- if has('kind'):
- kind = get('kind')
- else:
- raise ConfigurationError, '<assignees> requires a kind
attribute'
- if kind not in ('possible', 'actual'):
- raise ConfigurationError, ('<assignees kind="..."> must be
either '
- '"possible" or "actual"')
- self.assigneesKind = kind
-
- if has('roles') and has('expression'):
- raise ConfigurationError, ('<assignees> can only have one of
'
- 'roles or expression')
- if not (has('roles') or has('expression')):
- raise ConfigurationError, ('<assignees> must have one of '
- 'roles or expression')
- if has('roles'):
- self.roles = tuple(utils.flexSplit(get("roles").encode("ascii")))
- if has('expression'):
- if kind == 'possible':
- raise NotImplementedError, \
- "possible/expression is not implemented"
- self.assigneesExpression = get('expression')
-
security.declarePrivate('_get_assignees_default')
def _get_assignees_default(self):
return [getSecurityManager().getUser().getUserName()]
(at)(at) -365,12 +287,53 (at)(at)
assignees.setAttribute(curr_attr.domAttr,
convert_to_xml(value))
+ security.declarePrivate('_attr_import_assignees')
+ def _attr_import_assignees(self, attr, node):
+ if node.hasAttribute('roles'):
+ raise ConfigurationError, 'The roles attribute is deprecated.'
+ assignees = node.getElementsByTagName('assignees')
+ if len(assignees) == 0:
+ # default behaviour
+ self.roles = ()
+ elif len(assignees) == 1:
+ self._parse_assignee(assignees[0])
+ else:
+ raise ConfigurationError, \
+ '<assignees> is only allowed once per activity.'
+
+ security.declarePrivate('_parse_assignee')
+ def _parse_assignee(self, assignee):
+ """helper for _attr_import_assignees
+ """
+ has = assignee.hasAttribute
+ get = assignee.getAttribute
+ _import = self._attr_import_simple
+ attr = findAttrInAttributes
+
+ _import(attr(self, 'assigneesKind'), assignee)
+ kind = self.assigneesKind
+
+ if has('roles') and has('expression'):
+ raise ConfigurationError, \
+ '<assignees> can only have one of roles or
expression.'
+ if not (has('roles') or has('expression')):
+ raise ConfigurationError, \
+ '<assignees> must have one of roles or expression.'
+ if has('roles'):
+ _import(attr(self, 'roles'), assignee)
+ if has('expression'):
+ if kind == 'possible':
+ raise NotImplementedError, \
+ "possible/expression is not implemented"
+ _import(attr(self, 'assigneesExpression'), assignee)
+
InitializeClass(BaseAssignableActivity)
class BaseTalesActivity(BaseAutomaticActivity):
-
+ "Activity based on execution of a TALES-expression."
+
__implements__ = BaseAutomaticActivity.__implements__ + \
(ITalesActivity, )
security = ClassSecurityInfo()
(at)(at) -378,44 +341,23 (at)(at)
attributes = BaseAutomaticActivity.attributes + (
WorkflowAttribute('expression', 'expression', '',
- 'TALES expression which is to be executed.'),
+ 'TALES expression which is to be executed.',
+ required=True),
)
- error_string = "Tal expression required which" \
- "should return a DateTime object, in %r."
-
-
-
-
_properties = BaseAutomaticActivity._properties + \
({'id': 'expression', 'type': 'string', 'mode': 'w'},
)
- security.declareProtected(config.MANAGE_WORKFLOW, "configureFromDOMNode")
- def configureFromDOMNode(self, node):
- """Configures the activity from a given DOM-Node"""
- BaseAutomaticActivity.configureFromDOMNode(self, node)
-
- if not node.hasAttribute("expression"):
- raise ConfigurationError, self.error_string % self.activity_type
- self.expression = node.getAttribute("expression")
-
InitializeClass(BaseTalesActivity)
-###################
-# activity registry
-
-activity_registry = {}
+#############################
+# Registry for all activities
+# Registry keys should be class.nodeName
+activity_registry = Registry()
def registerActivity(activity):
InitializeClass(activity)
- InitializeWorkflowAttributes(activity)
- activity_registry[activity.activity_type] = activity
-
-def getActivity(activity_type):
- return activity_registry[activity_type]
-
-def listActivities():
- return activity_registry.keys()
-
+ InitializeWorkflowAttributes(activity, activity.nodeName,
+ registry=activity_registry)
Modified: AlphaFlow/trunk/editor/editor.py
==============================================================================
--- AlphaFlow/trunk/editor/editor.py (original)
+++ AlphaFlow/trunk/editor/editor.py Mon Jun 27 15:24:52 2005
(at)(at) -76,14 +76,16 (at)(at)
security.declareProtected(config.EDIT_WORKFLOW, "getActivityIcons")
def getActivityIcons(self, filter=[]):
"""returns a list of tuples with (activity, icon)"""
+ global activity_registry
+
result = []
- activities = activity_registry.values()
- for activity in activities:
+ activity_ids = activity_registry.keys()
+ for activity_id in activity_ids:
+ activity = activity_registry.get(activity_id)
if activity.activity_type in filter:
continue
name, icon = activity.activity_type, activity.icon
result.append((name, icon))
-
return result
InitializeClass(AlphaFlowEditor)
Modified: AlphaFlow/trunk/importexport.py
==============================================================================
--- AlphaFlow/trunk/importexport.py (original)
+++ AlphaFlow/trunk/importexport.py Mon Jun 27 15:24:52 2005
(at)(at) -12,9 +12,9 (at)(at)
from AccessControl import ClassSecurityInfo
# Sibling imports
-from Products.AlphaFlow.interfaces import IDOMExportable
-from Products.AlphaFlow import config
-#from Products.AlphaFlow.exception import ConfigurationError
+from Products.AlphaFlow.interfaces import IDOMExportable, IDOMConfigurable
+from Products.AlphaFlow import config, utils
+from Products.AlphaFlow.exception import ConfigurationError
class DOMExporter:
"""Mixin class with DOM export capabilities."""
(at)(at) -24,22 +24,22 (at)(at)
security.declarePrivate("writeDOM")
def writeDOM(self, node):
- "Write the activity into dom node."
+ "Write the object into dom node."
if hasattr(node, 'ownerDocument') and node.ownerDocument is not None:
doc = node.ownerDocument # node inside
else:
doc = node # Document itself
- activity = node.appendChild(doc.createElement(self.nodeName))
+ own_node = node.appendChild(doc.createElement(self.nodeName))
for attr in self.attributes:
if attr.exportHandler is None:
continue
exportHandler = getattr(self, attr.exportHandler)
- exportHandler(attr, activity)
+ exportHandler(attr, own_node)
security.declareProtected(config.EDIT_WORKFLOW, "getXML")
def getXML(self, REQUEST=None):
- """returns the AlphaFlow XML for this activity"""
+ """returns the AlphaFlow XML for this object"""
doc = minidom.Document()
self.writeDOM(doc)
xml = doc.toxml()
(at)(at) -54,7 +54,10 (at)(at)
def _attr_export_simple(self, attr, node):
"Export for attributes which need no special handling."
value = getattr(self, attr.classAttr)
- node.setAttribute(attr.domAttr, convert_to_xml(value))
+ value = convert_to_xml(value)
+ if attr.encoding is not None:
+ value = value.decode(attr.encoding)
+ node.setAttribute(attr.domAttr, value)
security.declarePrivate('_attr_export_id')
def _attr_export_id(self, attr, node):
(at)(at) -64,6 +67,110 (at)(at)
InitializeClass(DOMExporter)
+class DOMImporter:
+ """Mixin class with capabilities to import attributes from DOM."""
+
+ __implements__ = (IDOMConfigurable, )
+ security = ClassSecurityInfo()
+
+
+ def __init__(self, id, *args, **kw):
+ "Constructor"
+ self.id = id
+
+
+ security.declareProtected(config.MANAGE_WORKFLOW, 'configureFromDOMNode')
+ def configureFromDOMNode(self, node):
+ "Configures the object from the given DOM node."
+ for attr in self.attributes:
+ if attr.importHandler is None:
+ continue
+ importHandler = getattr(self, attr.importHandler)
+ importHandler(attr, node)
+
+ security.declareProtected(config.MANAGE_WORKFLOW,
+ 'createAndConfigureChildNodes')
+ def createAndConfigureChildNodes(self, node, registry):
+ "Configure all child nodes of node."
+ created = []
+ for obj_node in node.childNodes:
+ if obj_node.nodeType in (obj_node.TEXT_NODE,
+ obj_node.COMMENT_NODE):
+ # Ignore textnodes, whitespace ...
+ continue
+ obj_type = obj_node.nodeName
+ if obj_node.nodeType != obj_node.ELEMENT_NODE:
+ raise ConfigurationError, "Invalid node type %r (%r)" % (
+ obj_node.nodeType, obj_type)
+ obj_id = obj_node.getAttribute('id').encode('ascii')
+ try:
+ klass = registry.getFromDOMNode(obj_node)
+ except KeyError:
+ raise ConfigurationError, \
+ "XMLImporter does not know how to handle %r tag." % (
+ obj_type,)
+ obj = klass(obj_id)
+ # some validation methods need context, so give it now temporary
+ if hasattr(obj, '__of__'):
+ obj_wrapped = obj.__of__(self)
+ else:
+ obj_wrapped = obj
+ obj_wrapped.configureFromDOMNode(obj_node)
+ created.append(obj)
+ return created
+
+
+ ########################
+ # public import handlers
+
+ security.declarePrivate('_attr_import_simple')
+ def _attr_import_simple(self, attr, node):
+ "Import for attributes which need no special handling."
+ dom_attr = attr.domAttr
+ node_name = node.nodeName
+ datatype = attr.datatype
+ value = ''
+ if node.hasAttribute(dom_attr):
+ value = node.getAttribute(dom_attr)
+ if attr.required and value == '': # req but not set
+ raise ConfigurationError, \
+ "%s requires attribute %s!" % (node_name, dom_attr)
+ if attr.encoding is not None:
+ value = value.encode(attr.encoding)
+ if datatype in [list, tuple]:
+ value = datatype(utils.flexSplit(value))
+ if not len(value):
+ value = attr.default
+ elif datatype == bool:
+ if value == '': # not set and not required
+ value = attr.default
+ else:
+ try:
+ value = utils.makeBoolFromUnicode(value)
+ except ValueError:
+ import sys
+ raise ConfigurationError, str(sys.exc_info()[1])
+ else:
+ # do not try to convert strings or empty values
+ if not (isinstance(datatype, basestring) or value == ''):
+ try:
+ value = datatype(value)
+ except ValueError:
+ raise ConfigurationError, \
+ "%s.%s must be of %s" % (node_name, dom_attr,
+ datatype)
+ if value == '': # no attribute or empty value
+ value = attr.default
+ if attr.vocabulary is not None and value not in attr.vocabulary:
+ raise ConfigurationError, \
+ "%s.%s must be one of %s" % (node_name, dom_attr,
+ attr.vocabulary)
+ setattr(self, attr.classAttr, value)
+
+
+InitializeClass(DOMImporter)
+
+
###################
# helper methods
Modified: AlphaFlow/trunk/interfaces.py
==============================================================================
--- AlphaFlow/trunk/interfaces.py (original)
+++ AlphaFlow/trunk/interfaces.py Mon Jun 27 15:24:52 2005
(at)(at) -1,6 +1,6 (at)(at)
# Copyright (c) 2004-2005 gocept gmbh & co. kg
# See also LICENSE.txt
-# interfaces.py,v 1.61.2.3 2005/05/02 09:02:02 zagy Exp
+# $Id$
from Interface import Interface, Attribute
(at)(at) -9,20 +9,34 (at)(at)
class IDOMConfigurable(Interface):
"""Implemented by objects which are configurable by DOM nodes."""
+ def __init__(id, *args, **kw):
+ """Constructor must have this signature.
+
+ id ... id for the object
+ """
+
def configureFromDOMNode(node):
- """Configures the activity from the given DOM node.
+ """Configures the object from the given DOM node.
Returns nothing.
+ May raise ConfigurationError.
+ """
+
+ def createAndConfigureChildNodes(self, node):
+ """Create and configure all child nodes of node.
+
+ Returns list of created activities.
"""
+
class IDOMExportable(Interface):
"""Implemented by objects which can export itself into a DOM."""
def writeDOM(node):
- """Write the activity into dom node.
+ """Write the object into dom node.
node ... dom node or document
- Returns the created activity node
+ Returns the created dom node
"""
def getXML(REQUEST=None):
(at)(at) -259,6 +273,7 (at)(at)
"""Add a new activity to this process definition by type.
Returns the new activity.
+ Raises KeyError if activity_type is unknown.
"""
def acquireProcess():
"""returns the process instance from the acquisition chain"""
(at)(at) -690,9 +705,7 (at)(at)
portal - the portal root object
"""
- error_string = Attribute("String which is shown when the "
- "expression-attribute is missing. (String must"
- "include a %r for the activity_type.)")
+
class ITalesWorkItem(IAutomaticWorkItem):
"""WorkItem which uses TALES-Expression."""
(at)(at) -707,29 +720,67 (at)(at)
class IWorkflowAttribute(Interface):
- """Attribute for an activity ... data used by import and export"""
+ """Attribute on objects in workflow (activity, process, ...)
- classAttr = Attribute("Name of the attribute in the activity class.")
+ data used for import and export
+ """
+
+ classAttr = Attribute("Name of the attribute in the python class.")
domAttr = Attribute("Name of the attribute in the dom.")
default = Attribute("Default value.")
description = Attribute("Description for the attribute.")
+ required = Attribute("Is this Attribute required?")
+ encoding = Attribute("Encode value with this encoding before converting to
"
+ "datatype. May be None if no encoding needed.")
+ datatype = Attribute("Datatype of value as type.")
+ vocabulary = Attribute("List or tuple of allowed values or None.")
importHandler = Attribute("Name of the method which handles the import "
"of this attribute or None for no import. "
"The method must accept exactly two parameters:"
- " - the activity attribute"
+ " - the WorkflowAttribute"
" - the dom node to be read from")
exportHandler = Attribute("Name of the method which handles the export "
"of this attribute or None for no export. "
"The method must accept exactly two parameters:"
- " - the activity attribute"
+ " - the WorkflowAttribute"
" - the dom node to be written to")
def __init__(classAttr, domAttr, default, description,
+ required=False, encoding=None, datatype=unicode,
+ vocabulary=None,
importHandler="_attr_import_simple",
exportHandler="_attr_export_simple"):
"Constructor."
-
+class IRegistry(Interface):
+ """Registry for class objects."""
+
+ def register(key, klass):
+ """Register a class object on the registry.
+
+ If key already exists, its value gets replaced.
+
+ key ... string: search key in registry
+ klass ... class: object behind key
+ Raises ValueError if klass is no class object.
+ """
+
+ def get(key):
+ """Get class object by key.
+
+ Raises KeyError if key not found.
+ """
+
+ def getFromDOMNode(node):
+ """Get a class object from data given in DOM-Node.
+
+ Which parts of DOM node are taken for getting the key depends on
+ implementation.
+
+ Raises KeyError if key not found.
+ """
+ def keys():
+ """Return the keys in the registry as a list."""
# Need the activity interface here after a refactoring for backwards
Modified: AlphaFlow/trunk/process.py
==============================================================================
--- AlphaFlow/trunk/process.py (original)
+++ AlphaFlow/trunk/process.py Mon Jun 27 15:24:52 2005
(at)(at) -20,11 +20,11 (at)(at)
from Products.AlphaFlow.interfaces import IProcess
from Products.AlphaFlow import utils, config
from Products.AlphaFlow.exception import ConfigurationError
-from Products.AlphaFlow.activity import listActivities, getActivity
+from Products.AlphaFlow.activity import activity_registry
from Products.AlphaFlow.adapters.renderableadapter import getRenderableAdapter
from Products.AlphaFlow.workflowattr import \
WorkflowAttribute, InitializeWorkflowAttributes
-from Products.AlphaFlow.importexport import DOMExporter
+from Products.AlphaFlow.importexport import DOMExporter, DOMImporter
manage_addProcessForm=PageTemplateFile('www/addProcess', globals())
(at)(at) -32,7 +32,7 (at)(at)
self.manage_addProcess(id, REQUEST)
-class Process(Folder, DOMExporter):
+class Process(Folder, DOMExporter, DOMImporter):
__implements__ = Folder.__implements__ + (IProcess,)
meta_type = "AlphaFlow Process"
(at)(at) -86,11 +86,11 (at)(at)
"""Add a new activity to this process definition.
Returns the new activity.
+ Raises KeyError if activity_type is unknown.
"""
- act = getActivity(activity_type)(id)
- self._setObject(id, act)
- return getattr(self, id)
-
+ act = activity_registry.get(activity_type)(id)
+ return self._set_activity(id, act)
+
security.declareProtected(config.MANAGE_WORKFLOW, "listActivityIds")
def listActivityIds(self):
"""Returns a list of activity ids from this process."""
(at)(at) -98,7 +98,7 (at)(at)
security.declareProtected(config.MANAGE_WORKFLOW,
"listPossibleActivities")
def listPossibleActivities(self):
- return listActivities()
+ return activity_registry.keys()
security.declareProtected(CMFCorePermissions.View, "getGraphVizGif")
def getGraphVizGif(self, REQUEST):
(at)(at) -128,19 +128,10 (at)(at)
roles = utils.flexSplit(get("onlyAllowRoles").encode('ascii'))
self.roles = roles
- # Extract all nodes
- for act_node in node.childNodes:
- if act_node.nodeType in (act_node.TEXT_NODE,
- act_node.COMMENT_NODE):
- # Ignore textnodes, whitespace ...
- continue
- if act_node.nodeType != act_node.ELEMENT_NODE:
- raise ConfigurationError, "Invalid node type %r (%r)" % (
- act_node.nodeType, act_node.nodeName)
- act_id = act_node.getAttribute('id').encode('ascii')
- act_type = act_node.nodeName
- activity = self.addActivity(act_id, act_type)
- activity.configureFromDOMNode(act_node)
+ # Setup ChildNodes
+ childs = self.createAndConfigureChildNodes(node, activity_registry)
+ for child in childs:
+ self._set_activity(child.id, child)
security.declareProtected(config.EDIT_WORKFLOW, "getGraph")
def renderGraph(self, **kwargs):
(at)(at) -215,9 +206,17 (at)(at)
#########
# private
+ security.declarePrivate('_set_allowed_roles_restriction')
def _set_allowed_roles_restriction(self, roles):
roles = tuple(roles) # do not acquire
utils.modifyRolesForPermission(self, config.INIT_PROCESS, roles)
+ security.declarePrivate('_set_activity')
+ def _set_activity(self, id, activity):
+ "Place the activity inside process."
+ self._setObject(id, activity)
+ return getattr(self, id)
+
+
InitializeClass(Process)
-InitializeWorkflowAttributes(Process)
+InitializeWorkflowAttributes(Process, Process.nodeName)
Modified: AlphaFlow/trunk/processmanager.py
==============================================================================
--- AlphaFlow/trunk/processmanager.py (original)
+++ AlphaFlow/trunk/processmanager.py Mon Jun 27 15:24:52 2005
(at)(at) -433,7 +433,9 (at)(at)
Returns the imported process definition.
"""
if not hasattr(xmlfile, "read"):
- raise ValueError, "Only file uploads are allowed for importing XML
data."
+ raise ValueError, \
+ "Only file uploads or open files are allowed for " \
+ "importing XML data."
wf = parse(xmlfile).documentElement
assert wf.tagName == "workflow", "This is not a workflow definition"
# try to get the id from the process definition if available
Added: AlphaFlow/trunk/registry.py
==============================================================================
--- (empty file)
+++ AlphaFlow/trunk/registry.py Mon Jun 27 15:24:52 2005
(at)(at) -0,0 +1,42 (at)(at)
+# Copyright (c) 2005 gocept gmbh & co. kg
+# See also LICENSE.txt
+# $Id$
+"""Registry for activities etc."""
+
+# Python imports
+from types import ClassType
+
+# Zope imports
+from ExtensionClass import ExtensionClass
+
+# sibling imports
+from Products.AlphaFlow.interfaces import IRegistry
+
+class Registry:
+ """Registry for class objects."""
+
+ __implements__ = (IRegistry, )
+
+ _registry = None
+
+ def __init__(self):
+ self._registry = {}
+
+ def register(self, key, klass):
+ "Register a class object on the registry."
+ t_klass = type(klass)
+ if not (t_klass == ClassType or t_klass == ExtensionClass):
+ raise ValueError, "klass must be a classobj not %s." % t_klass
+ self._registry[key] = klass
+
+ def get(self, key):
+ "Get class object by key."
+ return self._registry[key]
+
+ def getFromDOMNode(self, node):
+ "Get a class object from data given in DOM-Node."
+ return self.get(node.nodeName)
+
+ def keys(self):
+ """Return the keys in the registry as a list."""
+ return self._registry.keys()
Modified: AlphaFlow/trunk/tests/test_definition.py
==============================================================================
--- AlphaFlow/trunk/tests/test_definition.py (original)
+++ AlphaFlow/trunk/tests/test_definition.py Mon Jun 27 15:24:52 2005
(at)(at) -26,15 +26,15 (at)(at)
from Products.AlphaFlow.tests.AlphaFlowTestCase import AlphaFlowTestCase
from Products.AlphaFlow.interfaces import \
- IProcess, IAlphaFlowed, IInstance, IActivity, \
- IWorkItem, IAutomaticWorkItem, IAction, IReviewWorkItem, IReviewActivity,
\
- IWorkflowAttribute, ITalesActivity, IAssignableActivity,
IAutomaticActivity, \
- IExit, IPermissionSetting
+ IProcess, IAlphaFlowed, IInstance, IActivity, IWorkItem, ITalesActivity, \
+ IAutomaticWorkItem, IAction, IReviewWorkItem, IReviewActivity, IExit, \
+ IWorkflowAttribute, IAssignableActivity, IAutomaticActivity, \
+ IPermissionSetting
from Products.AlphaFlow.workflowedobject import AlphaFlowed
from Products.AlphaFlow.instance import Instance
from Products.AlphaFlow.process import Process
from Products.AlphaFlow.activity import \
- listActivities, getActivity, BaseTalesActivity, BaseAssignableActivity, \
+ activity_registry, BaseTalesActivity, BaseAssignableActivity, \
BaseActivity, BaseAutomaticActivity
from Products.AlphaFlow import config
from Products.AlphaFlow.workitem import \
(at)(at) -45,9 +45,10 (at)(at)
from Products.AlphaFlow.utils import flexSplit, unique
from Products.AlphaFlow.exception import ConfigurationError
from Products.AlphaFlow.workflowattr import \
- WorkflowAttribute, InitializeWorkflowAttributes, getWorkflowAttributes, \
- findAttrInAttributes
+ WorkflowAttribute, InitializeWorkflowAttributes, findAttrInAttributes, \
+ workflow_attributes_registry
from Products.AlphaFlow.importexport import convert_to_xml
+from Products.AlphaFlow.activities.notify import notify_registry
_chars = 'abcdefghijklmnopqrstuvwxyz'
(at)(at) -90,8 +91,8 (at)(at)
(IAutomaticActivity, BaseAutomaticActivity),
(IPermissionSetting, PermissionSetting),
(IReviewWorkItem, ReviewWorkItem)] + \
- [(IActivity, getActivity(act_id))
- for act_id in listActivities() ] + \
+ [(IActivity, activity_registry.get(act_id))
+ for act_id in activity_registry.keys() ] + \
[(IWorkItem, getWorkItemClass(wi_id))
for wi_id in listWorkItems()]
(at)(at) -132,18 +133,26 (at)(at)
def _filter_relevant_attrs(self, node):
- """Get a sorted list of the relevant (not empty, not default)
attributes."""
- try:
- act_attrs = getWorkflowAttributes(node.nodeName)
- except KeyError:
+ "Get a sorted list of the relevant (not empty, not default)
attributes."
+ registries = [activity_registry, workflow_attributes_registry,
+ notify_registry]
+ act_attrs = None
+ for registry in registries:
+ try:
+ act_attrs = registry.getFromDOMNode(node).attributes
+ break
+ except KeyError:
+ pass
+ if act_attrs is None:
if node.nodeName == 'assignees':
- task = getActivity('task')
+ task = activity_registry.get('task')
act_attrs = (findAttrInAttributes(task, 'assigneesKind'),
findAttrInAttributes(task, 'roles'),
findAttrInAttributes(task,
'assigneesExpression'),
)
else:
- raise
+ raise AssertionError, '%s: can not get Workflowattributes' % (
+ node.nodeName)
res = []
for attr, value in node.attributes.items():
if value == '':
(at)(at) -283,6 +292,10 (at)(at)
"workflow tool")
process.startActivity = ("write_document",)
+ # check if process.addActivity raises KeyError on unknown activity
type
+ self.assertRaises(KeyError, process.addActivity, "a",
+ "__not%existing%type$__")
+
# "task" is a special kind of activity to ask people to do
# something
write_document = process.addActivity("write_document", "task")
(at)(at) -703,6 +716,12 (at)(at)
self.failUnless(instance.aq_base is doc.getInstance().aq_base)
instance.restart('more testing')
self.failUnless(instance.aq_base is doc.getInstance().aq_base)
+
+ def test_invalid_permission(self):
+ self.loginAsPortalOwner()
+ self.assertRaises(ConfigurationError, self._import_wf,
+ 'workflows/invalid_permission.alf')
+
def test_suite():
suite = unittest.TestSuite()
Modified: AlphaFlow/trunk/tests/test_email.py
==============================================================================
--- AlphaFlow/trunk/tests/test_email.py (original)
+++ AlphaFlow/trunk/tests/test_email.py Mon Jun 27 15:24:52 2005
(at)(at) -65,9 +65,9 (at)(at)
wi = instance.getWorkItems(state="complete")[0]
self.assert_(IEMailWorkItem.isImplementedBy(wi))
- ro = RecipientOwner()
- rna = RecipientNextAssignees()
- rar = RecipientActualRole()
+ ro = RecipientOwner('ro')
+ rna = RecipientNextAssignees('rna')
+ rar = RecipientActualRole('rar')
rar.roles = ('Editor',)
_test_recipients(ro, ['author'], wi)
Added: AlphaFlow/trunk/tests/test_registry.py
==============================================================================
--- (empty file)
+++ AlphaFlow/trunk/tests/test_registry.py Mon Jun 27 15:24:52 2005
(at)(at) -0,0 +1,90 (at)(at)
+# Copyright (c) 2005 gocept gmbh & co. kg
+# See also LICENSE.txt
+# $Id$
+
+import common
+
+
+import unittest
+from xml.dom import minidom
+
+from Testing import ZopeTestCase
+
+# from Products.Archetypes.tests.utils import *
+# from Products.Archetypes.tests.common import *
+
+# from Products.CMFCore.utils import getToolByName
+
+from Products.AlphaFlow.tests.AlphaFlowTestCase import AlphaFlowTestCase
+
+from Products.AlphaFlow.interfaces import IRegistry
+from Products.AlphaFlow.registry import Registry
+from Products.AlphaFlow.activities.notify import notify_registry,
RecipientOwner
+
+class Demo1:
+ pass
+
+class Demo2:
+ pass
+
+
+
+class RegistryTest(AlphaFlowTestCase):
+
+ interfaces_to_test = [(IRegistry, Registry),
+ ]
+
+ def test_registry(self):
+ r = Registry()
+ self.assertRaises(ValueError, r.register, 'asdf', None)
+ self.assertRaises(ValueError, r.register, 'asdf', 'asdf')
+ self.assertRaises(ValueError, r.register, 'asdf', object())
+ self.assertRaises(KeyError, r.get, 'asdf')
+ self.assertEqual([], r.keys())
+ r.register('asdf', Demo1)
+ self.assertEqual(Demo1, r.get('asdf'))
+ self.assertEqual(['asdf'], r.keys())
+ r.register('qwe', Demo2)
+ self.assertEqual(Demo1, r.get('asdf'))
+ self.assertEqual(Demo2, r.get('qwe'))
+ r.register('asdf', Demo2)
+ self.assertEqual(Demo2, r.get('asdf'))
+ self.assertEqual(Demo2, r.get('qwe'))
+ keys = r.keys()
+ keys.sort()
+ self.failUnless(['asdf', 'qwe'], keys)
+ r.register('qwe', Demo1)
+ # test getFromDOMNode
+ dom1 = minidom.parseString('<asdf/>')
+ dom2 = minidom.parseString('<qwe asdf="asdf"/>')
+ dom3 = minidom.parseString('<zui/>')
+ self.assertEqual(Demo2, r.getFromDOMNode(dom1.documentElement))
+ self.assertEqual(Demo1, r.getFromDOMNode(dom2.documentElement))
+ self.assertRaises(KeyError, r.getFromDOMNode, dom3.documentElement)
+
+ def test_notify_registry(self):
+ global notify_registry
+
+ nr = notify_registry
+ self.assertRaises(KeyError, nr.get, 'asdf')
+ self.assertEqual(RecipientOwner, nr.get('owner'))
+ dom1 = minidom.parseString('<owner />')
+ dom2 = minidom.parseString('<owner type="owner" />')
+ dom3 = minidom.parseString('<recipient />')
+ dom4 = minidom.parseString('<recipient type="owner"/>')
+ self.assertRaises(KeyError, nr.getFromDOMNode, dom1.documentElement)
+ self.assertRaises(KeyError, nr.getFromDOMNode, dom2.documentElement)
+ self.assertRaises(KeyError, nr.getFromDOMNode, dom3.documentElement)
+ self.assertEqual(RecipientOwner,
+ nr.getFromDOMNode(dom4.documentElement))
+
+
+
+def test_suite():
+ suite = unittest.TestSuite()
+ suite.addTest(unittest.makeSuite(RegistryTest))
+ return suite
+
+if __name__ == '__main__':
+ framework()
+
Modified: AlphaFlow/trunk/tests/test_security.py
==============================================================================
--- AlphaFlow/trunk/tests/test_security.py (original)
+++ AlphaFlow/trunk/tests/test_security.py Mon Jun 27 15:24:52 2005
(at)(at) -25,7 +25,6 (at)(at)
from Products.AlphaFlow.instance import Instance
from Products.AlphaFlow.process import Process
from Products.AlphaFlow.processmanager import ProcessManager
-from Products.AlphaFlow.activity import listActivities, getActivity
from Products.AlphaFlow import config, utils
from Products.AlphaFlow.exception import ConfigurationError
from Products.AlphaFlow.eventchannel import EventChannelIndex
Added: AlphaFlow/trunk/tests/workflows/invalid_permission.alf
==============================================================================
--- (empty file)
+++ AlphaFlow/trunk/tests/workflows/invalid_permission.alf Mon Jun 27 15:24:52
2005
(at)(at) -0,0 +1,24 (at)(at)
+<?xml version="1.0" encoding="iso-8859-1"?>
+
+<workflow
+ startActivity="make_private"
+ onlyAllowRoles="Manager Reviewer">
+
+ <permission-change id="make_private"
+ title="Autor-Rechte setzen"
+ continue_activity="dc_private">
+ <permission name="Access contents information"
+ acquire="false"
+ roles="Manager Owner ProcessUser"/>
+ <!-- invalid permission-->
+ <permission name="Modipfui portool contains"
+ acquire="false"
+ roles="Manager Owner ProcessUser"/>
+ <permission name="View"
+ acquire="false"
+ roles="Manager Owner ProcessUser"/>
+ </permission-change>
+
+ <dcworkflow id="dc_private" status="private"/>
+
+</workflow>
Modified: AlphaFlow/trunk/utils.py
==============================================================================
--- AlphaFlow/trunk/utils.py (original)
+++ AlphaFlow/trunk/utils.py Mon Jun 27 15:24:52 2005
(at)(at) -359,7 +359,7 (at)(at)
def flexSplit(string):
string = string.replace(',', ' ')
result = string.split(' ')
- result = [ x for x in result if x ] # filter empty
+ result = [ x for x in result if x ] # filter out empty
return result
Modified: AlphaFlow/trunk/workflowattr.py
==============================================================================
--- AlphaFlow/trunk/workflowattr.py (original)
+++ AlphaFlow/trunk/workflowattr.py Mon Jun 27 15:24:52 2005
(at)(at) -4,8 +4,8 (at)(at)
"""WorkflowAttribute definitions and helpers"""
# Sibling imports
-from Products.AlphaFlow.interfaces import IWorkflowAttribute
-
+from Products.AlphaFlow.interfaces import IWorkflowAttribute, IActivity
+from Products.AlphaFlow.registry import Registry
class WorkflowAttribute:
"""Attribute on objects in workflow (activity, process, ...)
(at)(at) -19,10 +19,16 (at)(at)
domAttr = None
default = ""
description = ""
+ required=False
+ encoding=None
+ datatype=unicode
+ vocabulary=None
importHandler = "_attr_import_simple"
exportHandler = "_attr_export_simple"
def __init__(self, classAttr, domAttr, default, description,
+ required=False, encoding=None, datatype=unicode,
+ vocabulary=None,
importHandler="_attr_import_simple",
exportHandler="_attr_export_simple"):
if not isinstance(classAttr, str):
(at)(at) -33,6 +39,23 (at)(at)
self.domAttr = domAttr
self.default = default
self.description = description
+ if not isinstance(datatype, type):
+ raise ValueError, "datatype must be a python type."
+ self.datatype = datatype
+ if not (isinstance(encoding, str) or encoding is None):
+ raise ValueError, "encoding must be a string encoding or None."
+ self.encoding = encoding
+ if encoding is not None and datatype == unicode:
+ raise ValueError, \
+ "If encoding is not None, datatype must not be unicode."
+ if not isinstance(required, bool):
+ raise ValueError, "required must be a boolean."
+ self.required = required
+ if not (isinstance(vocabulary, list) or
+ isinstance(vocabulary, tuple) or
+ vocabulary is None):
+ raise ValueError, "vocabulary must be a list or None."
+ self.vocabulary = vocabulary
if not (isinstance(importHandler, str) or importHandler is None):
raise ValueError, "importHandler must be a string or None."
self.importHandler = importHandler
(at)(at) -52,19 +75,24 (at)(at)
return attr
-##########
-# registry
-
-_workflow_attributes_registry = {}
+#######################################################################
+# Registry for classes having WorkflowAttributes which are not in other
+# registries.
+# Registry keys should be class.nodeName
+workflow_attributes_registry = Registry()
+
+def InitializeWorkflowAttributes(klass, registry_key,
+ registry=workflow_attributes_registry):
+ """Write the WorkflowAttribute on the class object klass.
+
+ registry_key: Key under which the entry is stored in registry
+ registry: registry object (IRegistry) to register within
+ None means: do not register class
-def InitializeWorkflowAttributes(klass):
- "Write the WorkflowAttribute on the class object klass."
+ """
for attribute in klass.attributes:
setattr(klass, attribute.classAttr, attribute.default)
- _workflow_attributes_registry[klass.nodeName] = klass
-
-def getWorkflowAttributes(nodeName):
- "Get the WorkflowAttributes for a class' nodeName."
- return _workflow_attributes_registry[nodeName].attributes
+ if registry is not None:
+ registry.register(registry_key, klass)
|
SVN: r3103 - in AlphaFlow/trunk: . adapters editor tests
Michael Howitz <mh(at)gocept.com> |
2005-06-28 09:39:29 |
[ FULL ]
|
Author: mac
Date: Tue Jun 28 09:34:19 2005
New Revision: 3103
Modified:
AlphaFlow/trunk/adapters/alphaflowable.py
AlphaFlow/trunk/editor/editor.py
AlphaFlow/trunk/interfaces.py
AlphaFlow/trunk/process.py
AlphaFlow/trunk/processmanager.py
AlphaFlow/trunk/tests/test_definition.py
Log:
- added export of process id
- moved duplicate code of importWorkflowFromXML to adapters/alphaflowable
- moved validateALF to adapters/alphaflowable
- Process now uses configureFromDOMNode from DOMImporter
- exportAsXML exports string UTF-8 encoded
Modified: AlphaFlow/trunk/adapters/alphaflowable.py
==============================================================================
--- AlphaFlow/trunk/adapters/alphaflowable.py (original)
+++ AlphaFlow/trunk/adapters/alphaflowable.py Tue Jun 28 09:34:19 2005
(at)(at) -1,6 +1,25 (at)(at)
+# Copyright (c) 2005 gocept gmbh & co. kg
+# See also LICENSE.txt
+# $Id$
+
+# Python imports
+from xml.dom import minidom
+try:
+ import libxml2
+ have_libxml2 = True
+except ImportError:
+ have_libxml2 = False
+
+
+# sibling imports
from Products.AlphaFlow.interfaces import IProcessManager, IAlphaFlowEditor
from Products.AlphaFlow.adapters import adapter
from Products.AlphaFlow.process import Process
+from Products.AlphaFlow import config
+from Products.AlphaFlow.activity import activity_registry
+
+validate_wf_defs = have_libxml2 and config.validate_wf_defs
+
class ProcessManagerAdapter(adapter.Adapter):
(at)(at) -10,6 +29,57 (at)(at)
self.context.processes._setObject(process_id, process)
return getattr(self.context.processes, process_id)
+ def importWorkflowFromXML(self, id, xmlfile):
+ if not hasattr(xmlfile, "read"):
+ raise ValueError, \
+ "Only file uploads or open files are allowed for " \
+ "importing XML data."
+ wf = minidom.parse(xmlfile).documentElement
+ assert wf.tagName == "workflow", "This is not a workflow definition"
+ # try to get the id from the process definition if available
+ if not id:
+ id = wf.getAttribute('id').encode('ascii')
+ p = self.addProcess(id)
+ p.configureFromDOMNode(wf)
+ childs = p.createAndConfigureChildNodes(wf, activity_registry)
+ for child in childs:
+ p._set_activity(child.id, child)
+ if validate_wf_defs:
+ self.validateALF(p, xmlfile)
+ return p
+
+
+ def validateALF(self, process, xmlfile):
+ """Validate the process definition against a RelaxNG schema.
+
+ xmlfile: file, filename or fileupload instance
+ """
+ errors = []
+ def ALFValidationError(localcontext, unused):
+ e = libxml2.lastError()
+ errors.append((e.message(), e.level()))
+
+ libxml2.registerErrorHandler(ALFValidationError, 'Schema Syntax')
+ rngp = libxml2.relaxNGNewMemParserCtxt(self.schema, len(self.schema))
+ rngs = rngp.relaxNGParse()
+ ctxt = rngs.relaxNGNewValidCtxt()
+
+ if isinstance(xmlfile, file) or hasattr(xmlfile, 'read'):
+ # seek to 0, because the file was already parsed
+ xmlfile.seek(0)
+ elif isinstance(xmlfile, str):
+ xmlfile = file(xmlfile)
+ else:
+ raise TypeError, "xmlfile must be str or file."
+
+ buff = xmlfile.read()
+ doc = libxml2.parseMemory(buff, len(buff))
+ doc.relaxNGValidateDoc(ctxt)
+ process.validation_errors = errors
+
+
+
+
def getAlphaFlowableAdapter(context):
if IProcessManager.isImplementedBy(context) or\
IAlphaFlowEditor.isImplementedBy(context):
Modified: AlphaFlow/trunk/editor/editor.py
==============================================================================
--- AlphaFlow/trunk/editor/editor.py (original)
+++ AlphaFlow/trunk/editor/editor.py Tue Jun 28 09:34:19 2005
(at)(at) -1,8 +1,8 (at)(at)
+# Copyright (c) 2005 gocept gmbh & co. kg
+# See also LICENSE.txt
+# $Id$
"""The workflow editor"""
-# Python imports
-from xml.dom import minidom
-
# Zope imports
from Globals import InitializeClass
from AccessControl import ClassSecurityInfo
(at)(at) -55,23 +55,9 (at)(at)
security.declareProtected(config.MANAGE_WORKFLOW, 'importWorkflowFromXML')
def importWorkflowFromXML(self, id, xmlfile):
- """Import a process definition from an xml file.
-
- xmlfile: file, filename, fileupload instance
-
- Returns the imported process definition.
- """
- # XXX duplicated code, this code is moved from process_manager
- # to this location, but still in process_manager for backwards
- # compatibility
- wf = minidom.parse(xmlfile).documentElement
- assert wf.tagName == "workflow", "This is not a workflow definition"
- # try to get the id from the process definition if available
- if not id:
- id = wf.getAttribute('id').encode('ascii')
- p = self.manage_addProcess(id)
- p.configureFromDOMNode(wf)
- return p
+ "Import a process definition from an xml file."
+ adapter = getAlphaFlowableAdapter(self)
+ return adapter.importWorkflowFromXML(id, xmlfile)
security.declareProtected(config.EDIT_WORKFLOW, "getActivityIcons")
def getActivityIcons(self, filter=[]):
Modified: AlphaFlow/trunk/interfaces.py
==============================================================================
--- AlphaFlow/trunk/interfaces.py (original)
+++ AlphaFlow/trunk/interfaces.py Tue Jun 28 09:34:19 2005
(at)(at) -205,12 +205,10 (at)(at)
def importWorkflowFromXML(process_id, xmlfile):
"""Import a process definition from a xml file.
- xmlfile: file, file name or fileupload instance
+ xmlfile: file or fileupload instance
Returns the imported process definition.
"""
- def validateALF(xmlfile):
- """validates the process definition against a RelaxNG schema"""
def pingCronItems():
"""Trigger all due alarmworkitems.
(at)(at) -305,7 +303,7 (at)(at)
"""Returns XML as a string containing editor information"""
def exportAsXML():
- """Exports process as XML-String."""
+ """Exports process as UTF-8 encoded XML-String."""
class IActivity(IWorkflowAttributeAware, IDOMConfigurable, IDOMExportable):
Modified: AlphaFlow/trunk/process.py
==============================================================================
--- AlphaFlow/trunk/process.py (original)
+++ AlphaFlow/trunk/process.py Tue Jun 28 09:34:19 2005
(at)(at) -40,15 +40,22 (at)(at)
nodeName = "workflow"
attributes = (
+ WorkflowAttribute('id', 'id', None,
+ 'Id of the workflow definition.',
+ encoding='ascii', datatype=str,
+ importHandler=None,
+ exportHandler='_attr_export_id'),
WorkflowAttribute('title', 'title', '',
- 'Title of this process definition.'),
+ 'Title of this process definition.',
+ encoding='utf-8', datatype=str),
WorkflowAttribute('startActivity', 'startActivity', (),
- 'List of activity ids to instantiate at start.'),
+ 'List of activity ids to instantiate at start.',
+ encoding='ascii', datatype=tuple),
WorkflowAttribute('description', 'description', '',
'Description of this process definition.'),
WorkflowAttribute('roles', 'onlyAllowRoles', [],
- 'Only members with this roles my start this
workflow.'
- ),
+ 'Only members with this roles my start this
workflow.',
+ encoding='ascii', datatype=list),
)
(at)(at) -111,27 +118,6 (at)(at)
def acquireProcess(self):
"""returns the process instance from the acquisition chain"""
return self
-
- security.declareProtected(config.MANAGE_WORKFLOW, 'configureFromDOMNode')
- def configureFromDOMNode(self, node):
- """Configures the activity from a given DOM-Node"""
- # Setup my own data
- has = node.hasAttribute
- get = node.getAttribute
- if has("title"):
- self.title = get("title").encode("utf-8")
- if has("startActivity"):
- self.startActivity =
utils.flexSplit(get("startActivity").encode("ascii"))
- if has("description"):
- self.description = get("description")
- if has("onlyAllowRoles"):
- roles = utils.flexSplit(get("onlyAllowRoles").encode('ascii'))
- self.roles = roles
-
- # Setup ChildNodes
- childs = self.createAndConfigureChildNodes(node, activity_registry)
- for child in childs:
- self._set_activity(child.id, child)
security.declareProtected(config.EDIT_WORKFLOW, "getGraph")
def renderGraph(self, **kwargs):
(at)(at) -170,7 +156,7 (at)(at)
security.declareProtected(config.MANAGE_WORKFLOW, 'exportAsXML')
def exportAsXML(self):
- """Exports process as XML-String."""
+ """Exports process as UTF-8 encoded XML-String."""
doc = self.getProcessDOM()
workflow = doc.documentElement
for activitiy in self.objectValues():
(at)(at) -184,7 +170,7 (at)(at)
for node in workflow.childNodes[:]:
if node.getAttribute('id') in inside_routes:
workflow.removeChild(node)
- return doc.toxml()
+ return doc.toxml('utf-8')
security.declareProtected(config.MANAGE_WORKFLOW,
'changeProcessProperties')
Modified: AlphaFlow/trunk/processmanager.py
==============================================================================
--- AlphaFlow/trunk/processmanager.py (original)
+++ AlphaFlow/trunk/processmanager.py Tue Jun 28 09:34:19 2005
(at)(at) -4,7 +4,6 (at)(at)
"""Process manager"""
# Python imports
-from xml.dom.minidom import parse
import sys
try:
(at)(at) -38,7 +37,6 (at)(at)
from Products.AlphaFlow import config, utils
from Products.AlphaFlow.adapters.alphaflowable import getAlphaFlowableAdapter
-validate_wf_defs = have_libxml2 and config.validate_wf_defs
_marker = object()
(at)(at) -426,55 +424,9 (at)(at)
security.declareProtected(config.MANAGE_WORKFLOW, 'importWorkflowFromXML')
def importWorkflowFromXML(self, id, xmlfile):
- """Import a process definition from an xml file.
-
- xmlfile: file, filename, fileupload instance
-
- Returns the imported process definition.
- """
- if not hasattr(xmlfile, "read"):
- raise ValueError, \
- "Only file uploads or open files are allowed for " \
- "importing XML data."
- wf = parse(xmlfile).documentElement
- assert wf.tagName == "workflow", "This is not a workflow definition"
- # try to get the id from the process definition if available
- if not id:
- id = wf.getAttribute('id').encode('ascii')
- p = self.addProcess(id)
- p.configureFromDOMNode(wf)
- if validate_wf_defs:
- self.validateALF(p, xmlfile)
- return p
-
- security.declareProtected(config.MANAGE_WORKFLOW, 'validateALF')
- def validateALF(self, process, xmlfile):
- """Validate the process definition against a RelaxNG schema.
-
- xmlfile: file, filename, fileupload instance
- """
- errors = []
- def ALFValidationError(localcontext, unused):
- e = libxml2.lastError()
- errors.append((e.message(), e.level()))
-
- libxml2.registerErrorHandler(ALFValidationError, 'Schema Syntax')
- rngp = libxml2.relaxNGNewMemParserCtxt(self.schema, len(self.schema))
- rngs = rngp.relaxNGParse()
- ctxt = rngs.relaxNGNewValidCtxt()
-
- if isinstance(xmlfile, file) or hasattr(xmlfile, 'read'):
- # seek to 0, because the file was already parsed
- xmlfile.seek(0)
- elif isinstance(xmlfile, str):
- xmlfile = file(xmlfile)
- else:
- raise TypeError, "xmlfile must be str or file."
-
- buff = xmlfile.read()
- doc = libxml2.parseMemory(buff, len(buff))
- doc.relaxNGValidateDoc(ctxt)
- process.validation_errors = errors
+ "Import a process definition from an xml file."
+ adapter = getAlphaFlowableAdapter(self)
+ return adapter.importWorkflowFromXML(id, xmlfile)
security.declarePublic('translate')
def translateMsg(self, message, translation_domain='alphaflow', **kwargs):
Modified: AlphaFlow/trunk/tests/test_definition.py
==============================================================================
--- AlphaFlow/trunk/tests/test_definition.py (original)
+++ AlphaFlow/trunk/tests/test_definition.py Tue Jun 28 09:34:19 2005
(at)(at) -137,6 +137,7 (at)(at)
registries = [activity_registry, workflow_attributes_registry,
notify_registry]
act_attrs = None
+ nodeName = node.nodeName
for registry in registries:
try:
act_attrs = registry.getFromDOMNode(node).attributes
(at)(at) -144,7 +145,7 (at)(at)
except KeyError:
pass
if act_attrs is None:
- if node.nodeName == 'assignees':
+ if nodeName == 'assignees':
task = activity_registry.get('task')
act_attrs = (findAttrInAttributes(task, 'assigneesKind'),
findAttrInAttributes(task, 'roles'),
(at)(at) -152,13 +153,15 (at)(at)
)
else:
raise AssertionError, '%s: can not get Workflowattributes' % (
- node.nodeName)
+ nodeName)
res = []
for attr, value in node.attributes.items():
if value == '':
continue
if attr.startswith("editor:") or attr.startswith("xmlns"):
continue
+ if nodeName == 'workflow' and attr == 'id':
+ continue # id in workflow tag may be left out or set by hand
breaked = False
for act_attr in act_attrs:
if act_attr.domAttr == attr:
(at)(at) -180,7 +183,8 (at)(at)
continue
if pot_node.parentNode.nodeName != node.parentNode.nodeName:
continue
- if pot_node.parentNode.getAttribute('id') != \
+ if pot_node.parentNode.nodeName != 'workflow' and \
+ pot_node.parentNode.getAttribute('id') != \
node.parentNode.getAttribute('id'):
continue
pot_node_items = self._filter_relevant_attrs(pot_node)
(at)(at) -190,19 +194,24 (at)(at)
return pot_node
- def _compare_DOM_nodes(self, exp_node, got_node, wf_name,
documentElement=False):
+ def _compare_DOM_nodes(self, exp_node, got_node, wf_name,
+ documentElement=False):
# print exp_node.getAttribute('id'),
self.failIf(got_node is None,
- "%s: %s(%s) missing in got DOM" % (wf_name,
- exp_node.nodeName,
-
exp_node.attributes.items()))
- self.assertEqual(exp_node.getAttribute('id'),
- got_node.getAttribute('id'))
+ "%s: %s(%s) missing in got DOM" % (
+ wf_name, exp_node.nodeName, exp_node.attributes.items()))
+ self.assertEqual(exp_node.nodeName, got_node.nodeName)
+ if exp_node.nodeName != 'workflow':
+ # workflow does not have compareable id
+ self.assertEqual(exp_node.getAttribute('id'),
+ got_node.getAttribute('id'))
if not documentElement:
self.assertEqual(exp_node.parentNode.nodeName,
got_node.parentNode.nodeName)
- self.assertEqual(exp_node.parentNode.getAttribute('id'),
- got_node.parentNode.getAttribute('id'))
+ if exp_node.parentNode.nodeName != "workflow":
+ # workflow does not have compareable id
+ self.assertEqual(exp_node.parentNode.getAttribute('id'),
+ got_node.parentNode.getAttribute('id'))
exp_node_items = self._filter_relevant_attrs(exp_node)
got_node_items = self._filter_relevant_attrs(got_node)
(at)(at) -236,9 +245,9 (at)(at)
continue
wf_file.seek(0)
test = alf.getProcess('test')
-# if wf_name == "actual_assignees.alf":
+# if wf_name == "configuration.alf":
# import pdb; pdb.set_trace() #############################
- got_dom = minidom.parseString(test.exportAsXML().encode('utf-8'))
+ got_dom = minidom.parseString(test.exportAsXML())
exp_dom = minidom.parseString(wf_file.read())
self._check_DOM_equality(exp_dom, got_dom, wf_name)
alf.deleteProcess('test')
|
|