1 11 package org.eclipse.jdt.internal.ui.refactoring; 12 13 import java.util.ArrayList ; 14 import java.util.Collections ; 15 import java.util.Comparator ; 16 import java.util.HashMap ; 17 import java.util.List ; 18 import java.util.Map ; 19 20 import org.eclipse.text.edits.TextEdit; 21 22 import org.eclipse.jface.text.IRegion; 23 import org.eclipse.jface.text.Region; 24 25 import org.eclipse.ltk.core.refactoring.TextChange; 26 import org.eclipse.ltk.core.refactoring.TextEditChangeGroup; 27 import org.eclipse.ltk.internal.ui.refactoring.ChangeElement; 28 import org.eclipse.ltk.internal.ui.refactoring.DefaultChangeElement; 29 import org.eclipse.ltk.internal.ui.refactoring.IChangeElementChildrenCreator; 30 import org.eclipse.ltk.internal.ui.refactoring.TextEditChangeElement; 31 32 import org.eclipse.jdt.core.ICompilationUnit; 33 import org.eclipse.jdt.core.IJavaElement; 34 import org.eclipse.jdt.core.ISourceReference; 35 import org.eclipse.jdt.core.JavaModelException; 36 37 import org.eclipse.jdt.internal.corext.refactoring.changes.CompilationUnitChange; 38 39 public class CompilationUnitChangeChildrenCreator implements IChangeElementChildrenCreator { 40 41 private static class OffsetComparator implements Comparator { 42 public int compare(Object o1, Object o2) { 43 TextEditChangeGroup c1= (TextEditChangeGroup)o1; 44 TextEditChangeGroup c2= (TextEditChangeGroup)o2; 45 int p1= getOffset(c1); 46 int p2= getOffset(c2); 47 if (p1 < p2) 48 return -1; 49 if (p1 > p2) 50 return 1; 51 return 0; 53 } 54 private int getOffset(TextEditChangeGroup edit) { 55 return edit.getRegion().getOffset(); 56 } 57 } 58 59 public void createChildren(DefaultChangeElement changeElement) { 60 CompilationUnitChange change= (CompilationUnitChange)changeElement.getChange(); 61 ICompilationUnit cunit= change.getCompilationUnit(); 62 List children= new ArrayList (5); 63 Map map= new HashMap (20); 64 TextEditChangeGroup[] changes= getSortedTextEditChanges(change); 65 for (int i= 0; i < changes.length; i++) { 66 TextEditChangeGroup tec= changes[i]; 67 try { 68 IJavaElement element= getModifiedJavaElement(tec, cunit); 69 if (element.equals(cunit)) { 70 children.add(new TextEditChangeElement(changeElement, tec)); 71 } else { 72 PseudoJavaChangeElement pjce= getChangeElement(map, element, children, changeElement); 73 pjce.addChild(new TextEditChangeElement(pjce, tec)); 74 } 75 } catch (JavaModelException e) { 76 children.add(new TextEditChangeElement(changeElement, tec)); 77 } 78 } 79 changeElement.setChildren((ChangeElement[]) children.toArray(new ChangeElement[children.size()])); 80 } 81 82 private TextEditChangeGroup[] getSortedTextEditChanges(TextChange change) { 83 TextEditChangeGroup[] edits= change.getTextEditChangeGroups(); 84 List result= new ArrayList (edits.length); 85 for (int i= 0; i < edits.length; i++) { 86 if (!edits[i].getTextEditGroup().isEmpty()) 87 result.add(edits[i]); 88 } 89 Comparator comparator= new OffsetComparator(); 90 Collections.sort(result, comparator); 91 return (TextEditChangeGroup[])result.toArray(new TextEditChangeGroup[result.size()]); 92 } 93 94 private IJavaElement getModifiedJavaElement(TextEditChangeGroup edit, ICompilationUnit cunit) throws JavaModelException { 95 IRegion range= edit.getRegion(); 96 if (range.getOffset() == 0 && range.getLength() == 0) 97 return cunit; 98 IJavaElement result= cunit.getElementAt(range.getOffset()); 99 if (result == null) 100 return cunit; 101 102 try { 103 while(true) { 104 ISourceReference ref= (ISourceReference)result; 105 IRegion sRange= new Region(ref.getSourceRange().getOffset(), ref.getSourceRange().getLength()); 106 if (result.getElementType() == IJavaElement.COMPILATION_UNIT || result.getParent() == null || coveredBy(edit, sRange)) 107 break; 108 result= result.getParent(); 109 } 110 } catch(JavaModelException e) { 111 } catch(ClassCastException e) { 113 } 115 return result; 116 } 117 118 private PseudoJavaChangeElement getChangeElement(Map map, IJavaElement element, List children, ChangeElement cunitChange) { 119 PseudoJavaChangeElement result= (PseudoJavaChangeElement)map.get(element); 120 if (result != null) 121 return result; 122 IJavaElement parent= element.getParent(); 123 if (parent instanceof ICompilationUnit) { 124 result= new PseudoJavaChangeElement(cunitChange, element); 125 children.add(result); 126 map.put(element, result); 127 } else { 128 PseudoJavaChangeElement parentChange= getChangeElement(map, parent, children, cunitChange); 129 result= new PseudoJavaChangeElement(parentChange, element); 130 parentChange.addChild(result); 131 map.put(element, result); 132 } 133 return result; 134 } 135 136 private boolean coveredBy(TextEditChangeGroup group, IRegion sourceRegion) { 137 int sLength= sourceRegion.getLength(); 138 if (sLength == 0) 139 return false; 140 int sOffset= sourceRegion.getOffset(); 141 int sEnd= sOffset + sLength - 1; 142 TextEdit[] edits= group.getTextEdits(); 143 for (int i= 0; i < edits.length; i++) { 144 TextEdit edit= edits[i]; 145 if (edit.isDeleted()) 146 return false; 147 int rOffset= edit.getOffset(); 148 int rLength= edit.getLength(); 149 int rEnd= rOffset + rLength - 1; 150 if (rLength == 0) { 151 if (!(sOffset < rOffset && rOffset <= sEnd)) 152 return false; 153 } else { 154 if (!(sOffset <= rOffset && rEnd <= sEnd)) 155 return false; 156 } 157 } 158 return true; 159 } 160 } | Popular Tags |