KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > ui > refactoring > CompilationUnitChangeChildrenCreator


1 /*******************************************************************************
2  * Copyright (c) 2000, 2005 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11  package org.eclipse.jdt.internal.ui.refactoring;
12
13 import java.util.ArrayList JavaDoc;
14 import java.util.Collections JavaDoc;
15 import java.util.Comparator JavaDoc;
16 import java.util.HashMap JavaDoc;
17 import java.util.List JavaDoc;
18 import java.util.Map JavaDoc;
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 JavaDoc {
42         public int compare(Object JavaDoc o1, Object JavaDoc 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             // same offset
52
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 JavaDoc children= new ArrayList JavaDoc(5);
63         Map JavaDoc map= new HashMap JavaDoc(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 JavaDoc result= new ArrayList JavaDoc(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 JavaDoc 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             // Do nothing, use old value.
112
} catch(ClassCastException JavaDoc e) {
113             // Do nothing, use old value.
114
}
115         return result;
116     }
117     
118     private PseudoJavaChangeElement getChangeElement(Map JavaDoc map, IJavaElement element, List JavaDoc 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