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.core.runtime.Assert; 23 import org.eclipse.core.runtime.CoreException; 24 25 import org.eclipse.jface.resource.ImageDescriptor; 26 27 import org.eclipse.jface.text.IRegion; 28 import org.eclipse.jface.text.Region; 29 30 import org.eclipse.ltk.ui.refactoring.LanguageElementNode; 31 import org.eclipse.ltk.ui.refactoring.TextEditChangeNode; 32 33 import org.eclipse.ltk.core.refactoring.TextEditBasedChange; 34 import org.eclipse.ltk.core.refactoring.TextEditBasedChangeGroup; 35 36 import org.eclipse.jdt.core.ICompilationUnit; 37 import org.eclipse.jdt.core.IJavaElement; 38 import org.eclipse.jdt.core.ISourceRange; 39 import org.eclipse.jdt.core.ISourceReference; 40 import org.eclipse.jdt.core.JavaModelException; 41 42 import org.eclipse.jdt.ui.JavaElementLabels; 43 44 import org.eclipse.jdt.internal.ui.viewsupport.JavaElementImageProvider; 45 46 public class CompilationUnitChangeNode extends TextEditChangeNode { 47 48 static final ChildNode[] EMPTY_CHILDREN= new ChildNode[0]; 49 50 private static class JavaLanguageNode extends LanguageElementNode { 51 52 private IJavaElement fJavaElement; 53 private static JavaElementImageProvider fgImageProvider= new JavaElementImageProvider(); 54 55 public JavaLanguageNode(TextEditChangeNode parent, IJavaElement element) { 56 super(parent); 57 fJavaElement= element; 58 Assert.isNotNull(fJavaElement); 59 } 60 61 public JavaLanguageNode(ChildNode parent, IJavaElement element) { 62 super(parent); 63 fJavaElement= element; 64 Assert.isNotNull(fJavaElement); 65 } 66 67 public String getText() { 68 return JavaElementLabels.getElementLabel(fJavaElement, JavaElementLabels.ALL_DEFAULT); 69 } 70 71 public ImageDescriptor getImageDescriptor() { 72 return fgImageProvider.getJavaImageDescriptor( 73 fJavaElement, 74 JavaElementImageProvider.OVERLAY_ICONS | JavaElementImageProvider.SMALL_ICONS); 75 } 76 77 public IRegion getTextRange() throws CoreException { 78 ISourceRange range= ((ISourceReference)fJavaElement).getSourceRange(); 79 return new Region(range.getOffset(), range.getLength()); 80 } 81 } 82 83 public CompilationUnitChangeNode(TextEditBasedChange change) { 84 super(change); 85 } 86 87 protected ChildNode[] createChildNodes() { 88 final TextEditBasedChange change= getTextEditBasedChange(); 89 ICompilationUnit cunit= (ICompilationUnit) change.getAdapter(ICompilationUnit.class); 90 if (cunit != null) { 91 List children= new ArrayList (5); 92 Map map= new HashMap (20); 93 TextEditBasedChangeGroup[] changes= getSortedChangeGroups(change); 94 for (int i= 0; i < changes.length; i++) { 95 TextEditBasedChangeGroup tec= changes[i]; 96 try { 97 IJavaElement element= getModifiedJavaElement(tec, cunit); 98 if (element.equals(cunit)) { 99 children.add(createTextEditGroupNode(this, tec)); 100 } else { 101 JavaLanguageNode pjce= getChangeElement(map, element, children, this); 102 pjce.addChild(createTextEditGroupNode(pjce, tec)); 103 } 104 } catch (JavaModelException e) { 105 children.add(createTextEditGroupNode(this, tec)); 106 } 107 } 108 return (ChildNode[]) children.toArray(new ChildNode[children.size()]); 109 } else { 110 return EMPTY_CHILDREN; 111 } 112 } 113 114 private static class OffsetComparator implements Comparator { 115 public int compare(Object o1, Object o2) { 116 TextEditBasedChangeGroup c1= (TextEditBasedChangeGroup)o1; 117 TextEditBasedChangeGroup c2= (TextEditBasedChangeGroup)o2; 118 int p1= getOffset(c1); 119 int p2= getOffset(c2); 120 if (p1 < p2) 121 return -1; 122 if (p1 > p2) 123 return 1; 124 return 0; 126 } 127 private int getOffset(TextEditBasedChangeGroup edit) { 128 return edit.getRegion().getOffset(); 129 } 130 } 131 132 private TextEditBasedChangeGroup[] getSortedChangeGroups(TextEditBasedChange change) { 133 TextEditBasedChangeGroup[] edits= change.getChangeGroups(); 134 List result= new ArrayList (edits.length); 135 for (int i= 0; i < edits.length; i++) { 136 if (!edits[i].getTextEditGroup().isEmpty()) 137 result.add(edits[i]); 138 } 139 Comparator comparator= new OffsetComparator(); 140 Collections.sort(result, comparator); 141 return (TextEditBasedChangeGroup[])result.toArray(new TextEditBasedChangeGroup[result.size()]); 142 } 143 144 private IJavaElement getModifiedJavaElement(TextEditBasedChangeGroup edit, ICompilationUnit cunit) throws JavaModelException { 145 IRegion range= edit.getRegion(); 146 if (range.getOffset() == 0 && range.getLength() == 0) 147 return cunit; 148 IJavaElement result= cunit.getElementAt(range.getOffset()); 149 if (result == null) 150 return cunit; 151 152 try { 153 while(true) { 154 ISourceReference ref= (ISourceReference)result; 155 IRegion sRange= new Region(ref.getSourceRange().getOffset(), ref.getSourceRange().getLength()); 156 if (result.getElementType() == IJavaElement.COMPILATION_UNIT || result.getParent() == null || coveredBy(edit, sRange)) 157 break; 158 result= result.getParent(); 159 } 160 } catch(JavaModelException e) { 161 } catch(ClassCastException e) { 163 } 165 return result; 166 } 167 168 private JavaLanguageNode getChangeElement(Map map, IJavaElement element, List children, TextEditChangeNode cunitChange) { 169 JavaLanguageNode result= (JavaLanguageNode)map.get(element); 170 if (result != null) 171 return result; 172 IJavaElement parent= element.getParent(); 173 if (parent instanceof ICompilationUnit) { 174 result= new JavaLanguageNode(cunitChange, element); 175 children.add(result); 176 map.put(element, result); 177 } else { 178 JavaLanguageNode parentChange= getChangeElement(map, parent, children, cunitChange); 179 result= new JavaLanguageNode(parentChange, element); 180 parentChange.addChild(result); 181 map.put(element, result); 182 } 183 return result; 184 } 185 186 private boolean coveredBy(TextEditBasedChangeGroup group, IRegion sourceRegion) { 187 int sLength= sourceRegion.getLength(); 188 if (sLength == 0) 189 return false; 190 int sOffset= sourceRegion.getOffset(); 191 int sEnd= sOffset + sLength - 1; 192 TextEdit[] edits= group.getTextEdits(); 193 for (int i= 0; i < edits.length; i++) { 194 TextEdit edit= edits[i]; 195 if (edit.isDeleted()) 196 return false; 197 int rOffset= edit.getOffset(); 198 int rLength= edit.getLength(); 199 int rEnd= rOffset + rLength - 1; 200 if (rLength == 0) { 201 if (!(sOffset < rOffset && rOffset <= sEnd)) 202 return false; 203 } else { 204 if (!(sOffset <= rOffset && rEnd <= sEnd)) 205 return false; 206 } 207 } 208 return true; 209 } 210 } 211 | Popular Tags |