summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter A. Bigot <pabigot@users.sourceforge.net>2010-05-29 14:11:25 -0500
committerPeter A. Bigot <pabigot@users.sourceforge.net>2010-05-29 14:11:25 -0500
commit346b270e95c928c8cfea75b2223613b3a29500ff (patch)
treed632772df0f6463cf6126f9e6fbfa35489ad6819
parent962748aabcc9afbcd13ff349d4b419cc525f3c72 (diff)
First pass at choice
-rw-r--r--pyxb/binding/content.py67
1 files changed, 59 insertions, 8 deletions
diff --git a/pyxb/binding/content.py b/pyxb/binding/content.py
index 75d9157..081a12e 100644
--- a/pyxb/binding/content.py
+++ b/pyxb/binding/content.py
@@ -106,9 +106,7 @@ class ContentState_mixin (pyxb.cscRoot):
No-op for non-aggregate state. For aggregate state, all contained
particles should be checked to see whether the overall model can be
- satisfied if no additional elements are provided. Where appropriate,
- in this situation the count of the parent particle state should be
- trivially adjusted to meet its minimum.
+ satisfied if no additional elements are provided.
This method does not have a meaningful return value; violations of the
content model should produce the corresponding exception (generally,
@@ -653,6 +651,54 @@ class SequenceState (ContentState_mixin):
self.__parentParticleState.incrementCount()
#print 'SS.NF %s: %d %s %s' % (self, self.__index, particle_ok, self.__particleState)
+class ChoiceState (ContentState_mixin):
+ def __init__ (self, group, parent_particle_state):
+ super(ChoiceState, self).__init__(group)
+ self.__choices = set([ ParticleState(_p, self) for _p in group.particles() ])
+ self.__activeChoice = None
+ #print 'CS.CTOR %s: %d choices' % (self, len(self.__choices))
+
+ def accepts (self, particle_state, instance, value, element_use):
+ #print 'CS.ACC %s: %s %s %s' % (self, instance, value, element_use)
+ if self.__activeChoice is None:
+ for choice in self.__choices:
+ #print 'CS.ACC %s candidate %s' % (self, choice)
+ try:
+ (consume, underflow_exc) = choice.step(instance, value, element_use)
+ except Exception, e:
+ #print 'CS.ACC %s: EXCEPTION %s' % (self, type(e))
+ raise
+ #print 'CS.ACC %s: candidate %s : %s' % (self, choice, consume)
+ if consume:
+ self.__activeChoice = choice
+ self.__choices = None
+ return True
+ return False
+ (consume, underflow_exc) = self.__activeChoice.step(instance, value, element_use)
+ if consume:
+ return True
+ if underflow_exc is not None:
+ self.__failed = True
+ raise underflow_exc
+ return False
+
+ def _verifyComplete (self, parent_particle_state):
+ rv = True
+ if self.__activeChoice is None:
+ for choice in self.__choices:
+ try:
+ choice.verifyComplete()
+ return
+ except Exception, e:
+ pass
+ raise MissingContentError('choice')
+ self.__activeChoice.verifyComplete()
+ parent_particle_state.incrementCount()
+
+ def notifyFailure (self, sub_state, particle_ok):
+ #print 'CS.NF %s' % (self,)
+ pass
+
class ParticleState (pyxb.cscRoot):
def __init__ (self, particle, parent_state=None):
self.__particle = particle
@@ -661,6 +707,8 @@ class ParticleState (pyxb.cscRoot):
#print 'PS.CTOR %s: particle %s' % (self, particle)
self.incrementCount()
+ def particle (self): return self.__particle
+
def incrementCount (self):
#print 'PS.IC %s' % (self,)
self.__count += 1
@@ -797,17 +845,20 @@ class _Group (ContentModel_mixin):
self.__particles = particles
class GroupChoice (_Group):
- def __init__ (self, *args, **kw):
- super(GroupChoice, self).__init__(*args, **kw)
+ def newState (self, parent_particle_state):
+ return ChoiceState(self, parent_particle_state)
+
+ def _validate (self, symbol_set, output_sequence):
+ for p in self.particles():
+ if p._validate(symbol_set, output_sequence):
+ return True
+ return False
class GroupAll (_Group):
def __init__ (self, *args, **kw):
super(GroupAll, self).__init__(*args, **kw)
class GroupSequence (_Group):
- def __init__ (self, *args, **kw):
- super(GroupSequence, self).__init__(*args, **kw)
-
def newState (self, parent_particle_state):
return SequenceState(self, parent_particle_state)