KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 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.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 JavaDoc 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 JavaDoc children= new ArrayList JavaDoc(5);
92             Map JavaDoc map= new HashMap JavaDoc(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 JavaDoc {
115         public int compare(Object JavaDoc o1, Object JavaDoc 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             // same offset
125
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 JavaDoc result= new ArrayList JavaDoc(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 JavaDoc 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             // Do nothing, use old value.
162
} catch(ClassCastException JavaDoc e) {
163             // Do nothing, use old value.
164
}
165         return result;
166     }
167     
168     private JavaLanguageNode getChangeElement(Map JavaDoc map, IJavaElement element, List JavaDoc 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