]> git.uio.no Git - ifi-stolz-refaktor.git/blame - case-study/jdt-after/core extension/org/eclipse/jdt/internal/corext/fix/CleanUpRefactoring.java
Case Study: adding data and statistics
[ifi-stolz-refaktor.git] / case-study / jdt-after / core extension / org / eclipse / jdt / internal / corext / fix / CleanUpRefactoring.java
CommitLineData
1b2798f6
EK
1/*******************************************************************************
2 * Copyright (c) 2000, 2011 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 *******************************************************************************/
11package org.eclipse.jdt.internal.corext.fix;
12
13import java.lang.reflect.InvocationTargetException;
14import java.util.ArrayList;
15import java.util.HashSet;
16import java.util.Hashtable;
17import java.util.Iterator;
18import java.util.LinkedList;
19import java.util.List;
20import java.util.Map;
21import java.util.Map.Entry;
22
23import org.eclipse.swt.widgets.Display;
24import org.eclipse.swt.widgets.Shell;
25
26import org.eclipse.core.runtime.CoreException;
27import org.eclipse.core.runtime.IProgressMonitor;
28import org.eclipse.core.runtime.IStatus;
29import org.eclipse.core.runtime.NullProgressMonitor;
30import org.eclipse.core.runtime.OperationCanceledException;
31import org.eclipse.core.runtime.SubProgressMonitor;
32import org.eclipse.core.runtime.jobs.ISchedulingRule;
33
34import org.eclipse.core.resources.IFile;
35import org.eclipse.core.resources.IResource;
36import org.eclipse.core.resources.ProjectScope;
37import org.eclipse.core.resources.ResourcesPlugin;
38
39import org.eclipse.text.edits.MalformedTreeException;
40import org.eclipse.text.edits.TextEdit;
41import org.eclipse.text.edits.TextEditGroup;
42import org.eclipse.text.edits.UndoEdit;
43
44import org.eclipse.jface.operation.IRunnableContext;
45import org.eclipse.jface.operation.IRunnableWithProgress;
46
47import org.eclipse.jface.text.BadLocationException;
48import org.eclipse.jface.text.Document;
49import org.eclipse.jface.text.IDocument;
50import org.eclipse.jface.text.IRegion;
51
52import org.eclipse.ui.PlatformUI;
53
54import org.eclipse.ltk.core.refactoring.CategorizedTextEditGroup;
55import org.eclipse.ltk.core.refactoring.Change;
56import org.eclipse.ltk.core.refactoring.CompositeChange;
57import org.eclipse.ltk.core.refactoring.ContentStamp;
58import org.eclipse.ltk.core.refactoring.GroupCategory;
59import org.eclipse.ltk.core.refactoring.GroupCategorySet;
60import org.eclipse.ltk.core.refactoring.NullChange;
61import org.eclipse.ltk.core.refactoring.PerformChangeOperation;
62import org.eclipse.ltk.core.refactoring.Refactoring;
63import org.eclipse.ltk.core.refactoring.RefactoringCore;
64import org.eclipse.ltk.core.refactoring.RefactoringStatus;
65import org.eclipse.ltk.core.refactoring.RefactoringTickProvider;
66import org.eclipse.ltk.core.refactoring.TextChange;
67import org.eclipse.ltk.core.refactoring.TextEditBasedChangeGroup;
68import org.eclipse.ltk.core.refactoring.TextFileChange;
69import org.eclipse.ltk.ui.refactoring.RefactoringUI;
70
71import org.eclipse.jdt.core.ICompilationUnit;
72import org.eclipse.jdt.core.IJavaProject;
73import org.eclipse.jdt.core.IPackageFragment;
74import org.eclipse.jdt.core.JavaModelException;
75import org.eclipse.jdt.core.WorkingCopyOwner;
76import org.eclipse.jdt.core.dom.ASTParser;
77import org.eclipse.jdt.core.dom.ASTRequestor;
78import org.eclipse.jdt.core.dom.CompilationUnit;
79import org.eclipse.jdt.core.refactoring.CompilationUnitChange;
80
81import org.eclipse.jdt.internal.corext.dom.ASTBatchParser;
82import org.eclipse.jdt.internal.corext.fix.CleanUpRefactoring.CleanUpChange;
83import org.eclipse.jdt.internal.corext.fix.CleanUpRefactoring.MultiFixTarget;
84import org.eclipse.jdt.internal.corext.refactoring.Checks;
85import org.eclipse.jdt.internal.corext.refactoring.changes.DynamicValidationStateChange;
86import org.eclipse.jdt.internal.corext.refactoring.changes.MultiStateCompilationUnitChange;
87import org.eclipse.jdt.internal.corext.refactoring.util.RefactoringASTParser;
88import org.eclipse.jdt.internal.corext.refactoring.util.TextEditUtil;
89import org.eclipse.jdt.internal.corext.util.Messages;
90
91import org.eclipse.jdt.ui.JavaElementLabels;
92import org.eclipse.jdt.ui.cleanup.CleanUpContext;
93import org.eclipse.jdt.ui.cleanup.CleanUpOptions;
94import org.eclipse.jdt.ui.cleanup.ICleanUp;
95import org.eclipse.jdt.ui.cleanup.ICleanUpFix;
96import org.eclipse.jdt.ui.refactoring.RefactoringSaveHelper;
97import org.eclipse.jdt.ui.text.java.IProblemLocation;
98
99import org.eclipse.jdt.internal.ui.JavaPlugin;
100import org.eclipse.jdt.internal.ui.fix.CleanUpRefactoringWizard.CleanUpConfigurationPage;
101import org.eclipse.jdt.internal.ui.fix.IMultiFix.MultiFixContext;
102import org.eclipse.jdt.internal.ui.fix.MapCleanUpOptions;
103import org.eclipse.jdt.internal.ui.fix.MultiFixMessages;
104import org.eclipse.jdt.internal.ui.javaeditor.ASTProvider;
105import org.eclipse.jdt.internal.ui.refactoring.IScheduledRefactoring;
106import org.eclipse.jdt.internal.ui.refactoring.RefactoringExecutionHelper;
107import org.eclipse.jdt.internal.ui.text.correction.proposals.FixCorrectionProposal;
108import org.eclipse.jdt.internal.ui.viewsupport.BasicElementLabels;
109
110public class CleanUpRefactoring extends Refactoring implements IScheduledRefactoring {
111
112 public static class CleanUpTarget {
113
114 private final ICompilationUnit fCompilationUnit;
115
116 public CleanUpTarget(ICompilationUnit unit) {
117 fCompilationUnit= unit;
118 }
119
120 public ICompilationUnit getCompilationUnit() {
121 return fCompilationUnit;
122 }
123
124 public void generated_3512855110069567600(CleanUpRefactoring cleanuprefactoring) {
125 IJavaProject javaProject= getCompilationUnit().getJavaProject();
126 if (!cleanuprefactoring.fProjects.containsKey(javaProject))
127 cleanuprefactoring.fProjects.put(javaProject, new ArrayList<CleanUpTarget>());
128
129 List<CleanUpTarget> targets= cleanuprefactoring.fProjects.get(javaProject);
130 targets.add(this);
131 }
132 }
133
134 public static class MultiFixTarget extends CleanUpTarget {
135
136 private final IProblemLocation[] fProblems;
137
138 public MultiFixTarget(ICompilationUnit unit, IProblemLocation[] problems) {
139 super(unit);
140 fProblems= problems;
141 }
142
143 public IProblemLocation[] getProblems() {
144 return fProblems;
145 }
146 }
147
148 public static class CleanUpChange extends CompilationUnitChange {
149
150 private UndoEdit fUndoEdit;
151
152 public CleanUpChange(String name, ICompilationUnit cunit) {
153 super(name, cunit);
154 }
155
156 /**
157 * {@inheritDoc}
158 */
159 @Override
160 protected Change createUndoChange(UndoEdit edit, ContentStamp stampToRestore) {
161 fUndoEdit= edit;
162 return super.createUndoChange(edit, stampToRestore);
163 }
164
165 public UndoEdit getUndoEdit() {
166 return fUndoEdit;
167 }
168
169 /*
170 * @see org.eclipse.ltk.core.refactoring.TextChange#perform(org.eclipse.core.runtime.IProgressMonitor)
171 */
172 @Override
173 public Change perform(final IProgressMonitor pm) throws CoreException {
174 if (Display.getCurrent() == null) {
175 final Change[] result= new Change[1];
176 final CoreException[] exs= new CoreException[1];
177 Display.getDefault().syncExec(new Runnable() {
178 public void run() {
179 try {
180 result[0]= CleanUpChange.super.perform(pm);
181 } catch (CoreException e) {
182 exs[0]= e;
183 }
184 }
185 });
186
187 if (exs[0] != null)
188 throw exs[0];
189
190 return result[0];
191 } else {
192 return super.perform(pm);
193 }
194 }
195
196 public IRegion[] generated_3577844454337008817(ICompilationUnit unit, IRegion[] changedRegions, IProgressMonitor monitor, ICleanUp[] cleanUps, CompositeChange result, LinkedList<UndoEdit> undoEdits, CleanUpPostSaveListener cleanuppostsavelistener) throws CoreException {
197 result.add(this);
198
199 setSaveMode(TextFileChange.LEAVE_DIRTY);
200 initializeValidationData(new NullProgressMonitor());
201
202 PerformChangeOperation performChangeOperation= RefactoringUI.createUIAwareChangeOperation(this);
203 performChangeOperation.setSchedulingRule(unit.getSchedulingRule());
204
205 if (changedRegions != null && changedRegions.length > 0 && cleanuppostsavelistener.requiresChangedRegions(cleanUps)) {
206 changedRegions= cleanuppostsavelistener.performWithChangedRegionUpdate(performChangeOperation, changedRegions, unit, new SubProgressMonitor(monitor, 5));
207 } else {
208 performChangeOperation.run(new SubProgressMonitor(monitor, 5));
209 }
210
211 performChangeOperation.getUndoChange();
212 undoEdits.addFirst(getUndoEdit());
213 return changedRegions;
214 }
215
216 public TextChange generated_1297851598183582600(CleanUpChange change) {
217 setSaveMode(change.getSaveMode());
218 return this;
219 }
220 }
221
222 public static class FixCalculationException extends RuntimeException {
223
224 private static final long serialVersionUID= 3807273310144726165L;
225
226 private final CoreException fException;
227
228 public FixCalculationException(CoreException exception) {
229 fException= exception;
230 }
231
232 public CoreException getException() {
233 return fException;
234 }
235 }
236
237 static class ParseListElement {
238
239 private final CleanUpTarget fTarget;
240 private final ICleanUp[] fCleanUpsArray;
241
242 public ParseListElement(CleanUpTarget cleanUpTarget, ICleanUp[] cleanUps) {
243 fTarget= cleanUpTarget;
244 fCleanUpsArray= cleanUps;
245 }
246
247 public CleanUpTarget getTarget() {
248 return fTarget;
249 }
250
251 public ICleanUp[] getCleanUps() {
252 return fCleanUpsArray;
253 }
254
255 public void generated_704773225463029839(CleanUpASTRequestor cleanupastrequestor) {
256 cleanupastrequestor.fCompilationUnitParseElementMap.put(getTarget().getCompilationUnit(), this);
257 }
258 }
259
260 final class CleanUpRefactoringProgressMonitor extends SubProgressMonitor {
261
262 private double fRealWork;
263 private int fFlushCount;
264 private final int fSize;
265 private final int fIndex;
266
267 private CleanUpRefactoringProgressMonitor(IProgressMonitor monitor, int ticks, int size, int index) {
268 super(monitor, ticks);
269 fFlushCount= 0;
270 fSize= size;
271 fIndex= index;
272 }
273
274 /**
275 * {@inheritDoc}
276 */
277 @Override
278 public void internalWorked(double work) {
279 fRealWork+= work;
280 }
281
282 public void flush() {
283 super.internalWorked(fRealWork);
284 reset();
285 fFlushCount++;
286 }
287
288 public void reset() {
289 fRealWork= 0.0;
290 }
291
292 @Override
293 public void done() {}
294
295 public int getIndex() {
296 return fIndex + fFlushCount;
297 }
298
299 public String getSubTaskMessage(ICompilationUnit source) {
300 String typeName= BasicElementLabels.getFileName(source);
301 return Messages.format(FixMessages.CleanUpRefactoring_ProcessingCompilationUnit_message, new Object[] {new Integer(getIndex()), new Integer(fSize), typeName});
302 }
303
304 public void generated_2876694169375894621(CleanUpASTRequestor cleanupastrequestor, ICompilationUnit source, CompilationUnit ast) {
305 subTask(getSubTaskMessage(source));
306
307 ICompilationUnit primary= (ICompilationUnit)source.getPrimaryElement();
308 ParseListElement element= cleanupastrequestor.fCompilationUnitParseElementMap.get(primary);
309 CleanUpTarget target= element.getTarget();
310
311 CleanUpContext context;
312 if (target instanceof MultiFixTarget) {
313 context= new MultiFixContext(source, ast, ((MultiFixTarget)target).getProblems());
314 } else {
315 context= new CleanUpContext(source, ast);
316 }
317 ICleanUp[] rejectedCleanUps= cleanupastrequestor.calculateSolutions(context, element.getCleanUps());
318
319 if (rejectedCleanUps.length > 0) {
320 cleanupastrequestor.fUndoneElements.add(new ParseListElement(target, rejectedCleanUps));
321 reset();
322 } else {
323 flush();
324 }
325 }
326
327 public void generated_733833685706273047(IProgressMonitor monitor, List<ICompilationUnit> parseList, List<ICompilationUnit> sourceList, final CleanUpFixpointIterator cleanupfixpointiterator)
328 throws CoreException {
329 CleanUpASTRequestor requestor= new CleanUpASTRequestor(cleanupfixpointiterator.fParseList, cleanupfixpointiterator.fSolutions, this);
330 if (parseList.size() > 0) {
331 ASTBatchParser parser= new ASTBatchParser() {
332 @Override
333 protected ASTParser createParser(IJavaProject project) {
334 ASTParser result= CleanUpFixpointIterator.createCleanUpASTParser();
335 result.setProject(project);
336
337 Map<String, String> options= RefactoringASTParser.getCompilerOptions(project);
338 options.putAll(cleanupfixpointiterator.fCleanUpOptions);
339 result.setCompilerOptions(options);
340 return result;
341 }
342 };
343 try {
344 ICompilationUnit[] units= parseList.toArray(new ICompilationUnit[parseList.size()]);
345 parser.createASTs(units, new String[0], requestor, this);
346 } catch (FixCalculationException e) {
347 throw e.getException();
348 }
349 }
350
351 for (Iterator<ICompilationUnit> iterator= sourceList.iterator(); iterator.hasNext();) {
352 ICompilationUnit cu= iterator.next();
353
354 monitor.worked(1);
355
356 requestor.acceptSource(cu);
357
358 if (monitor.isCanceled())
359 throw new OperationCanceledException();
360 }
361
362 cleanupfixpointiterator.fParseList= requestor.getUndoneElements();
363 cleanupfixpointiterator.fIndex= getIndex();
364 }
365 }
366
367 public static class CleanUpASTRequestor extends ASTRequestor {
368
369 private final List<ParseListElement> fUndoneElements;
370 private final Hashtable<ICompilationUnit, List<CleanUpChange>> fSolutions;
371 private final Hashtable<ICompilationUnit, ParseListElement> fCompilationUnitParseElementMap;
372 private final CleanUpRefactoringProgressMonitor fMonitor;
373
374 public CleanUpASTRequestor(List<ParseListElement> parseList, Hashtable<ICompilationUnit, List<CleanUpChange>> solutions, CleanUpRefactoringProgressMonitor monitor) {
375 fSolutions= solutions;
376 fMonitor= monitor;
377 fUndoneElements= new ArrayList<ParseListElement>();
378 fCompilationUnitParseElementMap= new Hashtable<ICompilationUnit, ParseListElement>(parseList.size());
379 for (Iterator<ParseListElement> iter= parseList.iterator(); iter.hasNext();) {
380 ParseListElement element= iter.next();
381 element.generated_704773225463029839(CleanUpASTRequestor.this);
382 }
383 }
384
385 /**
386 * {@inheritDoc}
387 */
388 @Override
389 public void acceptAST(ICompilationUnit source, CompilationUnit ast) {
390
391 fMonitor.generated_2876694169375894621(this, source, ast);
392 }
393
394 public void acceptSource(ICompilationUnit source) {
395 acceptAST(source, null);
396 }
397
398 public List<ParseListElement> getUndoneElements() {
399 return fUndoneElements;
400 }
401
402 ICleanUp[] calculateSolutions(CleanUpContext context, ICleanUp[] cleanUps) {
403 List<ICleanUp>result= new ArrayList<ICleanUp>();
404 CleanUpChange solution;
405 return context.generated_952798979635111062(CleanUpASTRequestor.this, cleanUps, result, solution);
406 }
407
408 public void integrateSolution(CleanUpChange solution, ICompilationUnit source) {
409 ICompilationUnit primary= source.getPrimary();
410
411 List<CleanUpChange> changes= fSolutions.get(primary);
412 if (changes == null) {
413 changes= new ArrayList<CleanUpChange>();
414 fSolutions.put(primary, changes);
415 }
416 changes.add(solution);
417 }
418 }
419
420 public class CleanUpFixpointIterator {
421
422 private List<ParseListElement> fParseList;
423 private final Hashtable<ICompilationUnit, List<CleanUpChange>> fSolutions;
424 private final Hashtable<ICompilationUnit, ICompilationUnit> fWorkingCopies; // map from primary to working copy
425 private final Map<String, String> fCleanUpOptions;
426 private final int fSize;
427 private int fIndex;
428
429 public CleanUpFixpointIterator(CleanUpTarget[] targets, ICleanUp[] cleanUps) {
430 fSolutions= new Hashtable<ICompilationUnit, List<CleanUpChange>>(targets.length);
431 fWorkingCopies= new Hashtable<ICompilationUnit, ICompilationUnit>();
432
433 fParseList= new ArrayList<ParseListElement>(targets.length);
434 for (int i= 0; i < targets.length; i++) {
435 fParseList.add(new ParseListElement(targets[i], cleanUps));
436 }
437
438 fCleanUpOptions= new Hashtable<String, String>();
439 for (int i= 0; i < cleanUps.length; i++) {
440 ICleanUp cleanUp= cleanUps[i];
441 Map<String, String> currentCleanUpOption= cleanUp.getRequirements().getCompilerOptions();
442 if (currentCleanUpOption != null)
443 fCleanUpOptions.putAll(currentCleanUpOption);
444 }
445
446 fSize= targets.length;
447 fIndex= 1;
448 }
449
450 public boolean hasNext() {
451 return !fParseList.isEmpty();
452 }
453
454 public void next(IProgressMonitor monitor) throws CoreException {
455 List<ICompilationUnit> parseList= new ArrayList<ICompilationUnit>();
456 List<ICompilationUnit> sourceList= new ArrayList<ICompilationUnit>();
457
458 try {
459 for (Iterator<ParseListElement> iter= fParseList.iterator(); iter.hasNext();) {
460 ParseListElement element= iter.next();
461
462 ICompilationUnit compilationUnit= element.getTarget().getCompilationUnit();
463 if (fSolutions.containsKey(compilationUnit)) {
464 if (fWorkingCopies.containsKey(compilationUnit)) {
465 compilationUnit= fWorkingCopies.get(compilationUnit);
466 } else {
467 compilationUnit= compilationUnit.getWorkingCopy(new WorkingCopyOwner() {}, null);
468 fWorkingCopies.put(compilationUnit.getPrimary(), compilationUnit);
469 }
470 applyChange(compilationUnit, fSolutions.get(compilationUnit.getPrimary()));
471 }
472
473 if (requiresAST(element.getCleanUps())) {
474 parseList.add(compilationUnit);
475 } else {
476 sourceList.add(compilationUnit);
477 }
478 }
479
480 CleanUpRefactoringProgressMonitor cuMonitor= new CleanUpRefactoringProgressMonitor(monitor, parseList.size() + sourceList.size(), fSize, fIndex);
481 cuMonitor.generated_733833685706273047(monitor, parseList, sourceList, CleanUpFixpointIterator.this);
482 } finally {
483 }
484 }
485
486 public void dispose() {
487 for (Iterator<ICompilationUnit> iterator= fWorkingCopies.values().iterator(); iterator.hasNext();) {
488 ICompilationUnit cu= iterator.next();
489 try {
490 cu.discardWorkingCopy();
491 } catch (JavaModelException e) {
492 JavaPlugin.log(e);
493 }
494 }
495 fWorkingCopies.clear();
496 }
497
498 private boolean requiresAST(ICleanUp[] cleanUps) {
499 for (int i= 0; i < cleanUps.length; i++) {
500 if (cleanUps[i].getRequirements().requiresAST())
501 return true;
502 }
503 return false;
504 }
505
506 public Change[] getResult() {
507
508 Change[] result= new Change[fSolutions.size()];
509 int i=0;
510 for (Iterator<Entry<ICompilationUnit, List<CleanUpChange>>> iterator= fSolutions.entrySet().iterator(); iterator.hasNext();) {
511 Entry<ICompilationUnit, List<CleanUpChange>> entry= iterator.next();
512
513 List<CleanUpChange> changes= entry.getValue();
514 ICompilationUnit unit= entry.getKey();
515
516 int saveMode;
517 if (fLeaveFilesDirty) {
518 saveMode= TextFileChange.LEAVE_DIRTY;
519 } else {
520 saveMode= TextFileChange.KEEP_SAVE_STATE;
521 }
522
523 if (changes.size() == 1) {
524 CleanUpChange change= changes.get(0);
525 change.setSaveMode(saveMode);
526 result[i]= change;
527 } else {
528 MultiStateCompilationUnitChange mscuc= new MultiStateCompilationUnitChange(getChangeName(unit), unit);
529 mscuc.generated_3684191273689231377(result, i, changes, saveMode, CleanUpFixpointIterator.this);
530 }
531
532 i++;
533 }
534
535 return result;
536 }
537
538 public TextChange createGroupFreeChange(CleanUpChange change) {
539 CleanUpChange result= new CleanUpChange(change.getName(), change.getCompilationUnit());
540 result.setEdit(change.getEdit());
541 return result.generated_1297851598183582600(change);
542 }
543
544 private void applyChange(ICompilationUnit compilationUnit, List<CleanUpChange> changes) throws JavaModelException, CoreException {
545 IDocument document= new Document(changes.get(0).getCurrentContent(new NullProgressMonitor()));
546 for (int i= 0; i < changes.size(); i++) {
547 CleanUpChange change= changes.get(i);
548 TextEdit edit= change.getEdit().copy();
549
550 try {
551 edit.apply(document, TextEdit.UPDATE_REGIONS);
552 } catch (MalformedTreeException e) {
553 JavaPlugin.log(e);
554 } catch (BadLocationException e) {
555 JavaPlugin.log(e);
556 }
557 }
558 compilationUnit.getBuffer().setContents(document.get());
559 }
560
561 public Change[] generated_3192539793063366456(IJavaProject project, SubProgressMonitor subMonitor) throws CoreException {
562 subMonitor.subTask(Messages.format(FixMessages.CleanUpRefactoring_Parser_Startup_message, BasicElementLabels.getResourceName(project.getProject())));
563 try {
564 while (hasNext()) {
565 next(subMonitor);
566 }
567
568 return getResult();
569 } finally {
570 dispose();
571 subMonitor.done();
572 }
573 }
574 }
575
576 private static final RefactoringTickProvider CLEAN_UP_REFACTORING_TICK_PROVIDER= new RefactoringTickProvider(0, 1, 0, 0);
577
578 /**
579 * A clean up is considered slow if its execution lasts longer then the value of
580 * SLOW_CLEAN_UP_THRESHOLD in ms.
581 */
582 private static final int SLOW_CLEAN_UP_THRESHOLD= 2000;
583
584 private final List<ICleanUp> fCleanUps;
585 private final Hashtable<IJavaProject, List<CleanUpTarget>> fProjects;
586 public Change fChange;
587 private boolean fLeaveFilesDirty;
588 private final String fName;
589
590 private boolean fUseOptionsFromProfile;
591
592 public CleanUpRefactoring() {
593 this(FixMessages.CleanUpRefactoring_Refactoring_name);
594 }
595
596 public CleanUpRefactoring(String name) {
597 fName= name;
598 fCleanUps= new ArrayList<ICleanUp>();
599 fProjects= new Hashtable<IJavaProject, List<CleanUpTarget>>();
600 fUseOptionsFromProfile= false;
601 }
602
603 public void setUseOptionsFromProfile(boolean enabled) {
604 fUseOptionsFromProfile= enabled;
605 }
606
607 public void addCompilationUnit(ICompilationUnit unit) {
608 addCleanUpTarget(new CleanUpTarget(unit));
609 }
610
611 public void addCleanUpTarget(CleanUpTarget target) {
612
613 target.generated_3512855110069567600(this);
614 }
615
616 public CleanUpTarget[] getCleanUpTargets() {
617 List<CleanUpTarget> result= new ArrayList<CleanUpTarget>();
618 for (Iterator<List<CleanUpTarget>> iter= fProjects.values().iterator(); iter.hasNext();) {
619 List<CleanUpTarget> projectTargets= iter.next();
620 result.addAll(projectTargets);
621 }
622 return result.toArray(new CleanUpTarget[result.size()]);
623 }
624
625 public int getCleanUpTargetsSize() {
626 int result= 0;
627 for (Iterator<List<CleanUpTarget>> iter= fProjects.values().iterator(); iter.hasNext();) {
628 List<CleanUpTarget> projectTargets= iter.next();
629 result+= projectTargets.size();
630 }
631 return result;
632 }
633
634 public void addCleanUp(ICleanUp fix) {
635 fCleanUps.add(fix);
636 }
637
638 public void clearCleanUps() {
639 fCleanUps.clear();
640 }
641
642 public boolean hasCleanUps() {
643 return !fCleanUps.isEmpty();
644 }
645
646 public ICleanUp[] getCleanUps() {
647 return fCleanUps.toArray(new ICleanUp[fCleanUps.size()]);
648 }
649
650 public IJavaProject[] getProjects() {
651 return fProjects.keySet().toArray(new IJavaProject[fProjects.keySet().size()]);
652 }
653
654 public void setLeaveFilesDirty(boolean leaveFilesDirty) {
655 fLeaveFilesDirty= leaveFilesDirty;
656 }
657
658 /* (non-Javadoc)
659 * @see org.eclipse.ltk.core.refactoring.Refactoring#getName()
660 */
661 @Override
662 public String getName() {
663 return fName;
664 }
665
666 /* (non-Javadoc)
667 * @see org.eclipse.ltk.core.refactoring.Refactoring#checkInitialConditions(org.eclipse.core.runtime.IProgressMonitor)
668 */
669 @Override
670 public RefactoringStatus checkInitialConditions(IProgressMonitor pm) throws CoreException, OperationCanceledException {
671 if (pm != null) {
672 pm.beginTask("", 1); //$NON-NLS-1$
673 pm.worked(1);
674 pm.done();
675 }
676 return new RefactoringStatus();
677 }
678
679 /* (non-Javadoc)
680 * @see org.eclipse.ltk.core.refactoring.Refactoring#createChange(org.eclipse.core.runtime.IProgressMonitor)
681 */
682 @Override
683 public Change createChange(IProgressMonitor pm) throws CoreException, OperationCanceledException {
684 if (pm != null) {
685 pm.beginTask("", 1); //$NON-NLS-1$
686 pm.worked(1);
687 pm.done();
688 }
689 return fChange;
690 }
691
692 /* (non-Javadoc)
693 * @see org.eclipse.ltk.core.refactoring.Refactoring#checkFinalConditions(org.eclipse.core.runtime.IProgressMonitor)
694 */
695 @Override
696 public RefactoringStatus checkFinalConditions(IProgressMonitor pm) throws CoreException, OperationCanceledException {
697
698 if (pm == null)
699 pm= new NullProgressMonitor();
700
701 if (fProjects.size() == 0 || fCleanUps.size() == 0) {
702 pm.beginTask("", 1); //$NON-NLS-1$
703 pm.worked(1);
704 pm.done();
705 fChange= new NullChange();
706
707 return new RefactoringStatus();
708 }
709
710 int cuCount= getCleanUpTargetsSize();
711
712 RefactoringStatus result= new RefactoringStatus();
713
714 ICleanUp[] cleanUps= getCleanUps();
715 pm.beginTask("", cuCount * 2 * fCleanUps.size() + 4 * cleanUps.length); //$NON-NLS-1$
716 try {
717 DynamicValidationStateChange change= new DynamicValidationStateChange(getName());
718 change.setSchedulingRule(getSchedulingRule());
719 for (Iterator<Entry<IJavaProject, List<CleanUpTarget>>> projectIter= fProjects.entrySet().iterator(); projectIter.hasNext();) {
720 Entry<IJavaProject, List<CleanUpTarget>> entry= projectIter.next();
721 IJavaProject project= entry.getKey();
722 List<CleanUpTarget> targetsList= entry.getValue();
723 CleanUpTarget[] targets= targetsList.toArray(new CleanUpTarget[targetsList.size()]);
724
725 if (fUseOptionsFromProfile) {
726 result.merge(setOptionsFromProfile(project, cleanUps));
727 if (result.hasFatalError())
728 return result;
729 }
730
731 result.merge(checkPreConditions(project, targets, new SubProgressMonitor(pm, 3 * cleanUps.length)));
732 if (result.hasFatalError())
733 return result;
734
735 Change[] changes= cleanUpProject(project, targets, cleanUps, pm);
736
737 result.merge(checkPostConditions(new SubProgressMonitor(pm, cleanUps.length)));
738 if (result.hasFatalError())
739 return result;
740
741 for (int i= 0; i < changes.length; i++) {
742 change.add(changes[i]);
743 }
744 }
745 List<IResource> files= change.generated_4320575570476407810(this);
746 result.merge(Checks.validateModifiesFiles(files.toArray(new IFile[files.size()]), getValidationContext()));
747 } finally {
748 pm.done();
749 }
750
751 return result;
752 }
753
754 public void findFilesToBeModified(CompositeChange change, List<IResource> result) throws JavaModelException {
755 Change[] children= change.getChildren();
756 for (int i= 0; i < children.length; i++) {
757 Change child= children[i];
758 if (child instanceof CompositeChange) {
759 findFilesToBeModified((CompositeChange)child, result);
760 } else if (child instanceof MultiStateCompilationUnitChange) {
761 result.add(((MultiStateCompilationUnitChange)child).getCompilationUnit().getCorrespondingResource());
762 } else if (child instanceof CompilationUnitChange) {
763 result.add(((CompilationUnitChange)child).getCompilationUnit().getCorrespondingResource());
764 }
765 }
766 }
767
768 private Change[] cleanUpProject(IJavaProject project, CleanUpTarget[] targets, ICleanUp[] cleanUps, IProgressMonitor monitor) throws CoreException {
769 CleanUpFixpointIterator iter= new CleanUpFixpointIterator(targets, cleanUps);
770
771 SubProgressMonitor subMonitor= new SubProgressMonitor(monitor, 2 * targets.length * cleanUps.length);
772 subMonitor.beginTask("", targets.length); //$NON-NLS-1$
773 return iter.generated_3192539793063366456(project, subMonitor);
774 }
775
776 private RefactoringStatus setOptionsFromProfile(IJavaProject javaProject, ICleanUp[] cleanUps) {
777 Map<String, String> options= CleanUpPreferenceUtil.loadOptions(new ProjectScope(javaProject.getProject()));
778 if (options == null)
779 return RefactoringStatus.createFatalErrorStatus(Messages.format(FixMessages.CleanUpRefactoring_could_not_retrive_profile, BasicElementLabels.getResourceName(javaProject.getProject())));
780
781 CleanUpOptions cleanUpOptions= new MapCleanUpOptions(options);
782 for (int i= 0; i < cleanUps.length; i++)
783 cleanUps[i].setOptions(cleanUpOptions);
784
785 return new RefactoringStatus();
786 }
787
788 private RefactoringStatus checkPreConditions(IJavaProject javaProject, CleanUpTarget[] targets, IProgressMonitor monitor) throws CoreException {
789 RefactoringStatus result= new RefactoringStatus();
790
791 ICompilationUnit[] compilationUnits= new ICompilationUnit[targets.length];
792 for (int i= 0; i < targets.length; i++) {
793 compilationUnits[i]= targets[i].getCompilationUnit();
794 }
795
796 ICleanUp[] cleanUps= getCleanUps();
797 monitor.beginTask("", compilationUnits.length * cleanUps.length); //$NON-NLS-1$
798 monitor.subTask(Messages.format(FixMessages.CleanUpRefactoring_Initialize_message, BasicElementLabels.getResourceName(javaProject.getProject())));
799 try {
800 for (int j= 0; j < cleanUps.length; j++) {
801 result.merge(cleanUps[j].checkPreConditions(javaProject, compilationUnits, new SubProgressMonitor(monitor, compilationUnits.length)));
802 if (result.hasFatalError())
803 return result;
804 }
805 } finally {
806 monitor.done();
807 }
808
809 return result;
810 }
811
812 private RefactoringStatus checkPostConditions(SubProgressMonitor monitor) throws CoreException {
813 RefactoringStatus result= new RefactoringStatus();
814
815 ICleanUp[] cleanUps= getCleanUps();
816 monitor.beginTask("", cleanUps.length); //$NON-NLS-1$
817 monitor.subTask(FixMessages.CleanUpRefactoring_checkingPostConditions_message);
818 try {
819 for (int j= 0; j < cleanUps.length; j++) {
820 result.merge(cleanUps[j].checkPostConditions(new SubProgressMonitor(monitor, 1)));
821 }
822 } finally {
823 monitor.done();
824 }
825 return result;
826 }
827
828 private static String getChangeName(ICompilationUnit compilationUnit) {
829 StringBuffer buf= new StringBuffer();
830 JavaElementLabels.getCompilationUnitLabel(compilationUnit, JavaElementLabels.ALL_DEFAULT, buf);
831 buf.append(JavaElementLabels.CONCAT_STRING);
832
833 StringBuffer buf2= new StringBuffer();
834 JavaElementLabels.getPackageFragmentLabel((IPackageFragment)compilationUnit.getParent(), JavaElementLabels.P_QUALIFIED, buf2);
835 buf.append(buf2.toString().replace('.', '/'));
836
837 return buf.toString();
838 }
839
840 public static CleanUpChange calculateChange(CleanUpContext context, ICleanUp[] cleanUps, List<ICleanUp> undoneCleanUps, HashSet<ICleanUp> slowCleanUps) throws CoreException {
841 if (cleanUps.length == 0)
842 return null;
843
844 CleanUpChange solution= null;
845 int i= 0;
846 do {
847 ICleanUp cleanUp= cleanUps[i];
848 ICleanUpFix fix;
849 if (slowCleanUps != null) {
850 long timeBefore= System.currentTimeMillis();
851 fix= cleanUp.createFix(context);
852 if (System.currentTimeMillis() - timeBefore > SLOW_CLEAN_UP_THRESHOLD)
853 slowCleanUps.add(cleanUp);
854 } else {
855 fix= cleanUp.createFix(context);
856 }
857 if (fix != null) {
858 CompilationUnitChange current= fix.createChange(null);
859 TextEdit currentEdit= current.getEdit();
860
861 if (solution != null) {
862 if (TextEditUtil.overlaps(currentEdit, solution.getEdit())) {
863 undoneCleanUps.add(cleanUp);
864 } else {
865 CleanUpChange merge= new CleanUpChange(FixMessages.CleanUpRefactoring_clean_up_multi_chang_name, context.getCompilationUnit());
866 merge.setEdit(TextEditUtil.merge(currentEdit, solution.getEdit()));
867
868 copyChangeGroups(merge, solution);
869 copyChangeGroups(merge, current);
870
871 solution= merge;
872 }
873 } else {
874 solution= new CleanUpChange(current.getName(), context.getCompilationUnit());
875 solution.setEdit(currentEdit);
876
877 copyChangeGroups(solution, current);
878 }
879 }
880 i++;
881 } while (i < cleanUps.length && (context.getAST() == null || !cleanUps[i].getRequirements().requiresFreshAST()));
882
883 for (; i < cleanUps.length; i++) {
884 undoneCleanUps.add(cleanUps[i]);
885 }
886 return solution;
887 }
888
889 private static void copyChangeGroups(CompilationUnitChange target, CompilationUnitChange source) {
890 TextEditBasedChangeGroup[] changeGroups= source.getChangeGroups();
891 for (int i= 0; i < changeGroups.length; i++) {
892 TextEditGroup textEditGroup= changeGroups[i].getTextEditGroup();
893 TextEditGroup newGroup;
894 if (textEditGroup instanceof CategorizedTextEditGroup) {
895 String label= textEditGroup.getName();
896 newGroup= new CategorizedTextEditGroup(label, new GroupCategorySet(new GroupCategory(label, label, label)));
897 } else {
898 newGroup= new TextEditGroup(textEditGroup.getName());
899 }
900 TextEdit[] textEdits= textEditGroup.getTextEdits();
901 for (int j= 0; j < textEdits.length; j++) {
902 newGroup.addTextEdit(textEdits[j]);
903 }
904 target.addTextEditGroup(newGroup);
905 }
906 }
907
908 /* (non-Javadoc)
909 * @see org.eclipse.ltk.core.refactoring.Refactoring#getRefactoringTickProvider()
910 */
911 @Override
912 protected RefactoringTickProvider doGetRefactoringTickProvider() {
913 return CLEAN_UP_REFACTORING_TICK_PROVIDER;
914 }
915
916 /**
917 * {@inheritDoc}
918 */
919 public ISchedulingRule getSchedulingRule() {
920 return ResourcesPlugin.getWorkspace().getRoot();
921 }
922
923 public void generated_6419108774172304623(CleanUpConfigurationPage cleanupconfigurationpage) {
924 int cleanUpTargetsSize= getCleanUpTargetsSize();
925 IJavaProject[] projects= getProjects();
926 if (cleanUpTargetsSize == 1) {
927 cleanupconfigurationpage.setMessage(MultiFixMessages.CleanUpRefactoringWizard_CleaningUp11_Title);
928 } else if (projects.length == 1) {
929 cleanupconfigurationpage.setMessage(Messages.format(MultiFixMessages.CleanUpRefactoringWizard_CleaningUpN1_Title, new Integer(cleanUpTargetsSize)));
930 } else {
931 cleanupconfigurationpage.setMessage(Messages.format(MultiFixMessages.CleanUpRefactoringWizard_CleaningUpNN_Title, new Object[] {new Integer(cleanUpTargetsSize), new Integer(projects.length)}));
932 }
933 }
934
935 public void generated_680054145197122767(CleanUpConfigurationPage cleanupconfigurationpage) {
936 CleanUpOptions options= null;
937 if (cleanupconfigurationpage.fUseCustomField.isSelected()) {
938 setUseOptionsFromProfile(false);
939 options= new MapCleanUpOptions(cleanupconfigurationpage.fCustomSettings);
940 } else {
941 setUseOptionsFromProfile(true);
942 }
943
944 clearCleanUps();
945 ICleanUp[] cleanups= JavaPlugin.getDefault().getCleanUpRegistry().createCleanUps();
946 for (int i= 0; i < cleanups.length; i++) {
947 if (options != null)
948 cleanups[i].setOptions(options);
949 addCleanUp(cleanups[i]);
950 }
951 }
952
953 public void generated_5919516677790640796(FixCorrectionProposal fixcorrectionproposal) {
954 addCompilationUnit(fixcorrectionproposal.getCompilationUnit());
955 addCleanUp(fixcorrectionproposal.fCleanUp);
956 setLeaveFilesDirty(true);
957
958 int stopSeverity= RefactoringCore.getConditionCheckingFailedSeverity();
959 Shell shell= JavaPlugin.getActiveWorkbenchShell();
960 IRunnableContext context= PlatformUI.getWorkbench().getActiveWorkbenchWindow();
961 RefactoringExecutionHelper executer= new RefactoringExecutionHelper(this, stopSeverity, RefactoringSaveHelper.SAVE_NOTHING, shell, context);
962 try {
963 executer.perform(true, true);
964 } catch (InterruptedException e) {
965 } catch (InvocationTargetException e) {
966 JavaPlugin.log(e);
967 }
968 return;
969 }
970
971 public RefactoringExecutionHelper generated_8947968545019694324(MultiFixTarget[] targets, final IProgressMonitor monitor, FixCorrectionProposal fixcorrectionproposal) {
972 for (int i= 0; i < targets.length; i++) {
973 addCleanUpTarget(targets[i]);
974 }
975
976 addCleanUp(fixcorrectionproposal.fCleanUp);
977
978 IRunnableContext context= new IRunnableContext() {
979 public void run(boolean fork, boolean cancelable, IRunnableWithProgress runnable) throws InvocationTargetException, InterruptedException {
980 runnable.run(monitor == null ? new NullProgressMonitor() : monitor);
981 }
982 };
983
984 Shell shell= PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
985 RefactoringExecutionHelper helper= new RefactoringExecutionHelper(this, IStatus.INFO, RefactoringSaveHelper.SAVE_REFACTORING, shell, context);
986 return helper;
987 }
988
989 public static ASTParser createCleanUpASTParser() {
990 ASTParser result= ASTParser.newParser(ASTProvider.SHARED_AST_LEVEL);
991
992 result.setResolveBindings(true);
993 result.setStatementsRecovery(ASTProvider.SHARED_AST_STATEMENT_RECOVERY);
994 result.setBindingsRecovery(ASTProvider.SHARED_BINDING_RECOVERY);
995
996 return result;
997 }
998
999}