--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.corext.refactoring.util;
+
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.SubProgressMonitor;
+
+import org.eclipse.core.filebuffers.ITextFileBuffer;
+
+import org.eclipse.text.edits.MalformedTreeException;
+import org.eclipse.text.edits.TextEdit;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.Document;
+import org.eclipse.jface.text.IDocument;
+
+import org.eclipse.ltk.core.refactoring.RefactoringStatus;
+import org.eclipse.ltk.core.refactoring.TextChange;
+import org.eclipse.ltk.core.refactoring.TextEditBasedChange;
+
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.dom.ASTParser;
+import org.eclipse.jdt.core.dom.ASTRequestor;
+import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
+import org.eclipse.jdt.core.dom.CompilationUnit;
+import org.eclipse.jdt.core.dom.IBinding;
+import org.eclipse.jdt.core.dom.ITypeBinding;
+import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
+import org.eclipse.jdt.core.refactoring.CompilationUnitChange;
+
+import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages;
+import org.eclipse.jdt.internal.corext.refactoring.changes.MultiStateCompilationUnitChange;
+import org.eclipse.jdt.internal.corext.refactoring.structure.ASTNodeSearchUtil;
+import org.eclipse.jdt.internal.corext.refactoring.structure.CompilationUnitRewrite;
+import org.eclipse.jdt.internal.corext.refactoring.structure.ExtractInterfaceProcessor;
+import org.eclipse.jdt.internal.corext.refactoring.structure.ExtractSupertypeProcessor;
+import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
+
+import org.eclipse.jdt.internal.ui.JavaPlugin;
+import org.eclipse.jdt.internal.ui.javaeditor.ASTProvider;
+
+
+/**
+ * A <code>TextChangeManager</code> manages associations between <code>ICompilationUnit</code>
+ * or <code>IFile</code> and <code>TextEditBasedChange</code> objects.
+ */
+public class TextEditBasedChangeManager {
+
+ private Map<ICompilationUnit, TextEditBasedChange> fMap= new HashMap<ICompilationUnit, TextEditBasedChange>(10);
+
+ private final boolean fKeepExecutedTextEdits;
+
+ public TextEditBasedChangeManager() {
+ this(false);
+ }
+
+ public TextEditBasedChangeManager(boolean keepExecutedTextEdits) {
+ fKeepExecutedTextEdits= keepExecutedTextEdits;
+ }
+
+ /**
+ * Adds an association between the given compilation unit and the passed
+ * change to this manager.
+ *
+ * @param cu the compilation unit (key)
+ * @param change the change associated with the compilation unit
+ */
+ public void manage(ICompilationUnit cu, TextEditBasedChange change) {
+ fMap.put(cu, change);
+ }
+
+ /**
+ * Returns the <code>TextEditBasedChange</code> associated with the given compilation unit.
+ * If the manager does not already manage an association it creates a one.
+ *
+ * @param cu the compilation unit for which the text buffer change is requested
+ * @return the text change associated with the given compilation unit.
+ */
+ public TextEditBasedChange get(ICompilationUnit cu) {
+ TextEditBasedChange result= fMap.get(cu);
+ if (result == null) {
+ result= new CompilationUnitChange(cu.getElementName(), cu);
+ result.setKeepPreviewEdits(fKeepExecutedTextEdits);
+ fMap.put(cu, result);
+ }
+ return result;
+ }
+
+ /**
+ * Removes the <tt>TextEditBasedChange</tt> managed under the given key
+ * <code>unit<code>.
+ *
+ * @param unit the key determining the <tt>TextEditBasedChange</tt> to be removed.
+ * @return the removed <tt>TextEditBasedChange</tt>.
+ */
+ public TextEditBasedChange remove(ICompilationUnit unit) {
+ return fMap.remove(unit);
+ }
+
+ /**
+ * Returns all text changes managed by this instance.
+ *
+ * @return all text changes managed by this instance
+ */
+ public TextEditBasedChange[] getAllChanges(){
+ Set<ICompilationUnit> cuSet= fMap.keySet();
+ ICompilationUnit[] cus= cuSet.toArray(new ICompilationUnit[cuSet.size()]);
+ // sort by cu name:
+ Arrays.sort(cus, new Comparator<ICompilationUnit>() {
+ public int compare(ICompilationUnit o1, ICompilationUnit o2) {
+ String name1= o1.getElementName();
+ String name2= o2.getElementName();
+ return name1.compareTo(name2);
+ }
+ });
+
+ TextEditBasedChange[] textChanges= new TextEditBasedChange[cus.length];
+ for (int i= 0; i < cus.length; i++) {
+ textChanges[i]= fMap.get(cus[i]);
+ }
+ return textChanges;
+ }
+
+ /**
+ * Returns all compilation units managed by this instance.
+ *
+ * @return all compilation units managed by this instance
+ */
+ public ICompilationUnit[] getAllCompilationUnits(){
+ return fMap.keySet().toArray(new ICompilationUnit[fMap.keySet().size()]);
+ }
+
+ /**
+ * Clears all associations between resources and text changes.
+ */
+ public void clear() {
+ fMap.clear();
+ }
+
+ /**
+ * Returns if any text changes are managed for the specified compilation unit.
+ *
+ * @param cu the compilation unit
+ * @return <code>true</code> if any text changes are managed for the specified compilation unit and <code>false</code> otherwise
+ */
+ public boolean containsChangesIn(ICompilationUnit cu){
+ return fMap.containsKey(cu);
+ }
+
+ public void generated_1598636152115507703(ExtractSupertypeProcessor extractsupertypeprocessor, final ICompilationUnit extractedUnit) throws CoreException {
+ ICompilationUnit unit;
+ CompilationUnitRewrite rewrite;
+ for (final Iterator<ICompilationUnit> iterator= extractsupertypeprocessor.fCompilationUnitRewrites.keySet().iterator(); iterator.hasNext();) {
+ unit= iterator.next();
+ if (unit.equals(extractedUnit)) {
+ rewrite= extractsupertypeprocessor.fCompilationUnitRewrites.get(unit);
+ if (rewrite != null) {
+ CompilationUnitChange change= rewrite.createChange(true);
+
+ if (change != null) {
+ final TextEdit edit= ((TextChange) change).getEdit();
+ if (edit != null) {
+ final IDocument document= new Document(extractsupertypeprocessor.fSuperSource);
+ try {
+ edit.apply(document, TextEdit.UPDATE_REGIONS);
+ } catch (MalformedTreeException exception) {
+ JavaPlugin.log(exception);
+ } catch (BadLocationException exception) {
+ JavaPlugin.log(exception);
+ }
+ extractsupertypeprocessor.fSuperSource= document.get();
+ remove(extractedUnit);
+ }
+ }
+ }
+ } else {
+ rewrite= extractsupertypeprocessor.fCompilationUnitRewrites.get(unit);
+ if (rewrite != null) {
+ final CompilationUnitChange layerChange= extractsupertypeprocessor.fLayerChanges.get(unit.getPrimary());
+ final CompilationUnitChange rewriteChange= rewrite.createChange(true);
+ if (rewriteChange != null && layerChange != null) {
+ final MultiStateCompilationUnitChange change= new MultiStateCompilationUnitChange(rewriteChange.getName(), unit);
+ change.addChange(layerChange);
+ change.addChange(rewriteChange);
+ extractsupertypeprocessor.fLayerChanges.remove(unit.getPrimary());
+ manage(unit, change);
+ } else if (layerChange != null) {
+ manage(unit, layerChange);
+ extractsupertypeprocessor.fLayerChanges.remove(unit.getPrimary());
+ } else if (rewriteChange != null) {
+ manage(unit, rewriteChange);
+ }
+ }
+ }
+ }
+ for (Iterator<Entry<ICompilationUnit, CompilationUnitChange>> iterator= extractsupertypeprocessor.fLayerChanges.entrySet().iterator(); iterator.hasNext();) {
+ final Entry<ICompilationUnit, CompilationUnitChange> entry= iterator.next();
+ manage(entry.getKey(), entry.getValue());
+ }
+ ICompilationUnit[] units= getAllCompilationUnits();
+ for (int index= 0; index < units.length; index++) {
+ if (units[index].getPath().equals(extractedUnit.getPath()))
+ remove(units[index]);
+ }
+ }
+
+ public void generated_320977291508916516(final ExtractInterfaceProcessor extractinterfaceprocessor, final CompilationUnitRewrite sourceRewrite, final ICompilationUnit superUnit, final Set<String> replacements, final RefactoringStatus status, final IProgressMonitor monitor, final ICompilationUnit subUnit, final ITextFileBuffer buffer, final ASTRewrite rewrite) throws JavaModelException,
+ CoreException {
+ try {
+ final IDocument document= new Document(buffer.getDocument().get());
+ try {
+ rewrite.rewriteAST(document, extractinterfaceprocessor.fSubType.getJavaProject().getOptions(true)).apply(document, TextEdit.UPDATE_REGIONS);
+ } catch (MalformedTreeException exception) {
+ JavaPlugin.log(exception);
+ } catch (BadLocationException exception) {
+ JavaPlugin.log(exception);
+ }
+ subUnit.getBuffer().setContents(document.get());
+ } finally {
+ RefactoringFileBuffers.release(extractinterfaceprocessor.fSubType.getCompilationUnit());
+ }
+ JavaModelUtil.reconcile(subUnit);
+ final IJavaProject project= subUnit.getJavaProject();
+ final ASTParser parser= ASTParser.newParser(ASTProvider.SHARED_AST_LEVEL);
+ parser.setWorkingCopyOwner(extractinterfaceprocessor.fOwner);
+ parser.setResolveBindings(true);
+ parser.setProject(project);
+ parser.setCompilerOptions(RefactoringASTParser.getCompilerOptions(project));
+ parser.createASTs(new ICompilationUnit[] { subUnit}, new String[0], new ASTRequestor() {
+
+ @Override
+ public final void acceptAST(final ICompilationUnit unit, final CompilationUnit node) {
+ try {
+ final IType subType= (IType) JavaModelUtil.findInCompilationUnit(unit, extractinterfaceprocessor.fSubType);
+ final AbstractTypeDeclaration subDeclaration= ASTNodeSearchUtil.getAbstractTypeDeclarationNode(subType, node);
+ if (subDeclaration != null) {
+ final ITypeBinding subBinding= subDeclaration.resolveBinding();
+ if (subBinding != null) {
+ String name= null;
+ ITypeBinding superBinding= null;
+ final ITypeBinding[] superBindings= subBinding.getInterfaces();
+ for (int index= 0; index < superBindings.length; index++) {
+ name= superBindings[index].getName();
+ if (name.startsWith(extractinterfaceprocessor.fSuperName) && superBindings[index].getTypeArguments().length == subBinding.getTypeParameters().length)
+ superBinding= superBindings[index];
+ }
+ if (superBinding != null) {
+ extractinterfaceprocessor.solveSuperTypeConstraints(unit, node, subType, subBinding, superBinding, new SubProgressMonitor(monitor, 80), status);
+ if (!status.hasFatalError()) {
+ extractinterfaceprocessor.rewriteTypeOccurrences(TextEditBasedChangeManager.this, extractinterfaceprocessor, sourceRewrite, unit, node, replacements, status, new SubProgressMonitor(monitor, 200));
+ if (containsChangesIn(superUnit)) {
+ final TextEditBasedChange change= get(superUnit);
+ if (change instanceof TextChange) {
+ final TextEdit edit= ((TextChange) change).getEdit();
+ if (edit != null) {
+ final IDocument document= new Document(superUnit.getBuffer().getContents());
+ try {
+ edit.apply(document, TextEdit.UPDATE_REGIONS);
+ } catch (MalformedTreeException exception) {
+ JavaPlugin.log(exception);
+ status.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractInterfaceProcessor_internal_error));
+ } catch (BadLocationException exception) {
+ JavaPlugin.log(exception);
+ status.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractInterfaceProcessor_internal_error));
+ }
+ extractinterfaceprocessor.fSuperSource= document.get();
+ remove(superUnit);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ } catch (JavaModelException exception) {
+ JavaPlugin.log(exception);
+ status.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractInterfaceProcessor_internal_error));
+ }
+ }
+
+ @Override
+ public final void acceptBinding(final String key, final IBinding binding) {
+ // Do nothing
+ }
+ }, new NullProgressMonitor());
+ }
+}
+