Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 130042 - ToolUtilities.findCommonAncestor throws exception when one edit part contains another
Summary: ToolUtilities.findCommonAncestor throws exception when one edit part contains...
Status: RESOLVED FIXED
Alias: None
Product: GEF
Classification: Tools
Component: GEF-Legacy GEF (MVC) (show other bugs)
Version: 3.2   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: 3.2.0 (Callisto) M6   Edit
Assignee: Steven R. Shaw CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-03-01 17:43 EST by Andrew Eisenberg CLA
Modified: 2006-03-29 17:14 EST (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Andrew Eisenberg CLA 2006-03-01 17:43:51 EST
ToolUtilities.findCommonAncestor should return the containing edit part when one of the edit parts passed to it as an argument contains the other edit part.  Instead, an ArrayIndexOutOfBounds exception is thrown.

Here is the code.  See comment in the code:

public static EditPart findCommonAncestor(EditPart ll, EditPart rr) {
	if (ll == rr)
		return ll;
	ArrayList leftAncestors = new ArrayList();
	ArrayList rightAncestors = new ArrayList();
	EditPart l = ll;
	EditPart r = rr;
	while (l != null) {
		leftAncestors.add(l);
		l = l.getParent();
	}
	while (r != null) {
		rightAncestors.add(r);
		r = r.getParent();
	}

	int il = leftAncestors.size() - 1;
	int ir = rightAncestors.size() - 1;

	/*****   if ((il == 0 || ir == 0) &&  
	         leftAncestors.get(il) == rightAncestors.get(ir)) 
	         should return leftAncestors.get(il) 
	         instead the loop continues and an aioob exception is thrown 
	         *********/

	while (leftAncestors.get(il) == rightAncestors.get(ir)) {

		il--;
		ir--;
	}
	il++;

	return (EditPart)leftAncestors.get(il);
}
Comment 1 Randy Hudson CLA 2006-03-01 23:07:32 EST
This utility method has only ever been tested when the left and right editparts are "leaves" in the editpart tree, as occurs in our text example.

Would you care to submit a patch?
Comment 2 Andrew Eisenberg CLA 2006-03-02 02:07:25 EST
I don't have my workspace set up to create patches, but here is the new version of the method that I am using in my code.  I hope you can use this:


  public static EditPart findCommonAncestor(EditPart ll, EditPart rr) {
    if (ll == rr)
      return ll;
    ArrayList leftAncestors = new ArrayList();
    ArrayList rightAncestors = new ArrayList();
    EditPart l = ll;
    EditPart r = rr;
    while (l != null) {
      leftAncestors.add(l);
      l = l.getParent();
    }
    while (r != null) {
      rightAncestors.add(r);
      r = r.getParent();
    }

    int il = leftAncestors.size() - 1;
    int ir = rightAncestors.size() - 1;
    while (leftAncestors.get(il) == rightAncestors.get(ir)) {
      il--;
      ir--;
      
      // fix bug 130042
      // one of the parts contains the other part
      if ( (il == 0 || ir == 0) && 
          leftAncestors.get(il) == rightAncestors.get(ir)) {
        return leftAncestors.get(il);
      }
      
    }
    il++;

    return (EditPart)leftAncestors.get(il);
  }
Comment 3 Randy Hudson CLA 2006-03-02 15:38:05 EST
My choice:

	do {
		if (leftAncestors.get(il) != rightAncestors.get(ir))
			break;
		il--;
		ir--;		
	} while (il >= 0 && ir >= 0);
	
	return (EditPart) leftAncestors.get(il + 1);
}
Comment 4 Andrew Eisenberg CLA 2006-03-02 16:02:11 EST
Looks good to me.
Comment 5 Steven R. Shaw CLA 2006-03-29 17:14:12 EST
Create JUnit test to verify failure and for happy path in org.eclipse.gef.test.ToolUtilitiesTest.

Fixed for next integration build.