[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Newsgroup Home]
[news.eclipse.tools.emf] Re: TraversalStrategy's double visits

John,

Comments below.

John J. Franey wrote:
On Thu, 17 Sep 2009 09:33:10 -0400, Christian W. Damus wrote:

  
Hi, John,

Are you certain that the validator is not actually being invoked twice?
The default recursive strategy takes steps to ensure that, if it is
invoked on a collection of objects, it doesn't re-visit elements that
are contained in (and thus traversed recursively from) other elements
also in the selection set from which it starts.

    
I'm quite certain.

It looks like org.eclipse.emf.common.util.AbstractTreeIterator (ATI) 
manages a stack for the recursion, if I am making this out correctly.  
Apparently, its 'data' field is used as a stack. 
Yes.
 When a call to 
getChildren returns an iterator with stuff to iterate, ATI puts the 
iterator on the stack and subsequent calls to next will pull from that 
iterator.  When that iterator is spent, it is popped from the stack and 
ATI will run a next on the earlier iterator.  Do I have that right?
  
Yep.
So, with the input I provided, the first call to ATI.next ought to return 
a 'component' eobject.
Not sure what input you provided.
  On entrance to this first call, the only  element 
on the 'data' stack is ITraversalStrategy$Recursive object.  During this 
call, getChildren on the 'component' eobject returns a EContentsEList
$FeatureIterator object and ATI pushes that on the 'data' stack.  Later 
calls to ATI pulls from that new iterator and that returns four eObjects 
in this sequence: 'implementation', 'service', 'implementation', 
'service'.
  
The direct contained children...

I single step through hasNext and next methods of EContentsElist
$FeatureIterator.
  
Those should yield the direct contained children in order...
Here is the iterator's value of eStructuralFeatures array whose length 
is 4:

org.eclipse.emf.ecore.impl.EAttributeImpl@61328229 (name: mixed) 
(ordered: true, unique: false, lowerBound: 0, upperBound: -1) 
(changeable: true, volatile: false, transient: false, 
defaultValueLiteral: null, unsettable: false, derived: false) (iD: false)

org.eclipse.emf.ecore.impl.EReferenceImpl@26b056fd (name: implementation) 
(ordered: true, unique: true, lowerBound: 1, upperBound: 1) (changeable: 
true, volatile: true, transient: true, defaultValueLiteral: null, 
unsettable: false, derived: false) (containment: true, resolveProxies: 
false)

org.eclipse.emf.ecore.impl.EReferenceImpl@2a8e32b7 (name: service) 
(ordered: true, unique: true, lowerBound: 0, upperBound: 1) (changeable: 
true, volatile: true, transient: true, defaultValueLiteral: null, 
unsettable: false, derived: false) (containment: true, resolveProxies: 
false)

org.eclipse.emf.ecore.impl.EReferenceImpl@3aff8399 (name: reference) 
(ordered: true, unique: true, lowerBound: 0, upperBound: -1) (changeable: 
true, volatile: true, transient: true, defaultValueLiteral: null, 
unsettable: false, derived: false) (containment: true, resolveProxies: 
false)

It looks like the iterator retrieves the first 'implementation' and 
'service' eObjects as result of interpreting the first element in 
eStructuralFeatures.  The second 'implementation' comes from interpreting 
the second element of eStructuralFeatures.  The second 'service' comes 
from interpreting the third element of eStructuralFeatures.  I can give 
details of this debugging session.  Its painstaking.  I hope I don't have 
to do it.
  
I don't think it's possible for an object to be contained by more than one containment feature. But shouldn't all these other references be marked as derived given they are derived from the mixed feature map (I assume).

So the question: is the iterator being initialized incorrectly (incorrect 
content of eStructuralFeatures), or does it interpret eStructuralFeatures 
incorrectly?
  
I think they fact they aren't derived is a problem. How did this model arise?


  
I can't think of a means by which the default traversal strategy would
visit these elements twice.  The containment of your objects is very
simple.

If you put a breakpoint in the DefaultTraversalStrategy (I hope that's
the name) then you should be able to infer from the call stack the
reason for the repeated visit.

HTH,

Christian


On Wed, 2009-09-16 at 19:25 +0000, John J. Franey wrote:

    
I have a situation where the BatchValidator is visiting some eobjects
twice.  I've been in debugging session for a few hours and am not
seeing what factor would lead to this.

Here is the model serialized as xml:

<?xml version="1.0" encoding="UTF-8"?> <scr:component
  xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" enabled="true"
  factory="" immediate="false" name="Command Provider for Dictionary
  Service" activate=""
  deactivate=""
  modified="">
     <implementation class="jjjjjjjjjj"/>
     <service/>
</scr:component>


This is the order the strategy returns:

component -> implementation -> service -> implementation -> service.

If a single constraint is defined for 'implementation', it run twice.
Two IStatus are returned indicating the same constraint failure on the
same eobject. They have the same message, as do the two markers that
are consequently created by BatchValidator.

What can I do so these are visited only once?

      


Thanks for looking at this.
John