Community
Participate
Working Groups
Created attachment 137291 [details] This attachment contains the two versions of the java file for which the incorrect number of lines were reported. Build ID: 3.2 Steps To Reproduce: We are running the following compare routine to compare two versions of a java file: package com.ibm.file.compare; import java.util.LinkedList; import java.util.ResourceBundle; import javax.swing.event.ChangeListener; import org.eclipse.compare.CompareUI; import org.eclipse.compare.ITypedElement; import org.eclipse.compare.ResourceNode; import org.eclipse.compare.internal.CompareUIPlugin; import org.eclipse.compare.internal.DocLineComparator; import org.eclipse.compare.internal.StructureCreatorDescriptor; import org.eclipse.compare.rangedifferencer.IRangeComparator; import org.eclipse.compare.rangedifferencer.RangeDifference; import org.eclipse.compare.rangedifferencer.RangeDifferencer; import org.eclipse.compare.structuremergeviewer.DiffContainer; import org.eclipse.compare.structuremergeviewer.DiffNode; import org.eclipse.compare.structuremergeviewer.Differencer; import org.eclipse.compare.structuremergeviewer.DocumentRangeNode; import org.eclipse.compare.structuremergeviewer.IStructureComparator; import org.eclipse.compare.structuremergeviewer.IStructureCreator; import org.eclipse.core.resources.IFile; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.IRegion; import org.eclipse.jface.text.Position; import org.eclipse.jface.text.Region; public class VersionCompare { private ResourceBundle resourceBundle; private static final String ID = "org.softevo.rose.compare"; /** * The constructor. */ public VersionCompare() { } /** * Returns an structure creator descriptor for the given type. * * @param type the type for which to find a descriptor * @return a descriptor for the given type, or <code>null</code> if no * descriptor has been registered */ public static IStructureCreator getStructureCreator(String type) { if (type == null) return null; if (type.startsWith(".")) type = type.substring(1); CompareUIPlugin ui = CompareUIPlugin.getDefault(); StructureCreatorDescriptor creator = ui.getStructureCreator(type); if (creator == null) return null; return creator.createStructureCreator(); } /** * * @param leftFile * @param rightFile * @return */ public static LinkedList doStructureCompare(IStructureCreator creator, IFile leftFile, IFile rightFile) { return doStructureCompare(creator, new ResourceNode(leftFile), new ResourceNode(rightFile)); } /** * Left and right objects "should" implement IStreamContentAccessor. * E.g.: * <ul> * <li><code>new ResourceNode(leftFile)</code> * <li><code>new HistoryItem(oldFile, IFileState)</code> * </ul> * @param creator * @param left * @param right * @return */ public static LinkedList doStructureCompare(IStructureCreator creator, Object left, Object right) { // Create the structure of the two versions IStructureComparator leftStructure = creator.getStructure(left); IStructureComparator rightStructure = creator.getStructure(right); return doStructureCompare(leftStructure, rightStructure); } /** * @param leftStructure * @param rightStructure * @return */ public static LinkedList doStructureCompare(IStructureComparator leftStructure, IStructureComparator rightStructure) { LinkedList result = new LinkedList(); // Create the differencer Differencer differencer = new Differencer(); // Find the differences // System.out.println("Create differences by findDifferences..."); Object outcome = differencer.findDifferences( false, new NullProgressMonitor(), null, null, leftStructure, rightStructure); // System.out.println(outcome); // Analyze outcome via a DFS if (outcome != null && outcome instanceof DiffNode) { DiffNode dn = (DiffNode) outcome; // Initialize DFS stack LinkedList stack = new LinkedList(); for (int i = 0; i < dn.getChildren().length; i++) { stack.addLast(dn.getChildren()[i]); } // Work off stack while (!stack.isEmpty()) { Object element = stack.removeFirst(); if (element instanceof DiffContainer) { DiffContainer dc = (DiffContainer) element; if (dc.getChildren() == null || dc.getChildren().length==0) { // We have reached a leaf - found a difference if (dc instanceof DiffNode) { // Add difference to list result.addAll(getModificationItems((DiffNode) dc)); } } else { // Push elements on stack (in reverse order) for (int i = dc.getChildren().length-1 ; i > -1; i--) { stack.addFirst(dc.getChildren()[i]); } } } } } //for (Iterator iter = result.iterator(); iter.hasNext();) { // ModificationItem element = (ModificationItem) iter.next(); // if (element != null && element.isDocumentRangeNode()) { // DocumentRangeNode drn = element.getDocumentRangeNode(); // System.out.println(drn.getId()); // } //} return result; } /** * @param dc * @return */ private static LinkedList getModificationItems(DiffNode dn) { int type = ModificationItem.CHANGED; if (dn.getLeft() == null) { type = ModificationItem.ADDED; } else if (dn.getRight() == null) { type = ModificationItem.DELETED; } int changedLines = getChangedLines(dn); // System.out.println(" No of changed line are : " + dn.getId().getName() + " :" + changedLines); return ModificationItem.createModificationItems(dn.getId(), type,changedLines); } private static int getChangedLines(DiffNode dn) { ITypedElement lElement = dn.getLeft(); ITypedElement rElement = dn.getRight(); IDocument lDoc = null; IDocument rDoc = null; Position lRegion= null; Position rRegion= null; int changedLines = 0; if( lElement != null && lElement instanceof DocumentRangeNode ) { lDoc = ((DocumentRangeNode)lElement).getDocument(); lRegion = ((DocumentRangeNode)lElement).getRange(); changedLines =countLines(lDoc,lRegion); } if( rElement != null && rElement instanceof DocumentRangeNode) { rDoc = ((DocumentRangeNode)rElement).getDocument(); rRegion = ((DocumentRangeNode)rElement).getRange(); changedLines = countLines(rDoc,rRegion); } if(lDoc !=null && rDoc !=null) { changedLines = 0; DocLineComparator sright= new DocLineComparator(rDoc, toRegion(rRegion), true); DocLineComparator sleft= new DocLineComparator(lDoc, toRegion(lRegion), true); RangeDifference[] result = RangeDifferencer.findRanges(sleft,sright); if (result == null ) return changedLines; for(int i=0;i<result.length;i++) { if (result[i].kind() == RangeDifference.NOCHANGE ) continue; else ++changedLines; } } return changedLines; } private static int countLines(IDocument document, Position region) { if(region != null) { int length = region.getLength(); int start= region.getOffset(); int offset = 0; try { offset = document.getLineOfOffset(start); } catch (BadLocationException ex) { // silently ignored } if (length == 0) return 0; else { int endLine= document.getNumberOfLines(); try { endLine= document.getLineOfOffset(start + length); } catch (BadLocationException ex) { // silently ignored } int linecount= endLine - offset + 1; return linecount; } } else { return document.getNumberOfLines(); } } private static IRegion toRegion(Position position) { if (position != null) return new Region(position.getOffset(), position.getLength()); return null; } } More information: The Comparator reports only 1 line changed in method "importAndValidate(String file)", although 22 lines have been added in that method. We have also attached the two versions of the java file as an attachment.
Move to JDT/Text. This might be a platform/compare issue.
>We are running the following compare routine to compare two versions of a java >file: How? Can you provide either a JUnit test case or a main method that displays the wrong result. In addition please attach a test file/case that we can actually use i.e. that compiles inside Eclipse SDK. The current one has types which are not available and hence many compile errors.
Please provide the requested information, otherwise we cannot proceed with this bug report.
Please reopen once the requested information has been provided.