Package org.pdtextensions.internal.corext.refactoring.rename

Source Code of org.pdtextensions.internal.corext.refactoring.rename.PHPRenameProcessor

/*******************************************************************************
* Copyright (c) 2000, 2009, 2013-2014 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
*     The PDT Extension Group - initial port to the PDT Extension Group Core Plugin
*******************************************************************************/
package org.pdtextensions.internal.corext.refactoring.rename;

import java.util.StringTokenizer;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Status;
import org.eclipse.dltk.core.IField;
import org.eclipse.dltk.core.ILocalVariable;
import org.eclipse.dltk.core.IMember;
import org.eclipse.dltk.core.IModelElement;
import org.eclipse.dltk.core.ISourceModule;
import org.eclipse.dltk.core.ISourceRange;
import org.eclipse.dltk.core.IType;
import org.eclipse.dltk.core.ModelException;
import org.eclipse.dltk.internal.corext.refactoring.ScriptRefactoringArguments;
import org.eclipse.dltk.internal.corext.refactoring.ScriptRefactoringDescriptor;
import org.eclipse.dltk.internal.corext.refactoring.changes.DynamicValidationRefactoringChange;
import org.eclipse.dltk.internal.corext.refactoring.code.ScriptableRefactoring;
import org.eclipse.dltk.internal.corext.refactoring.participants.ScriptProcessors;
import org.eclipse.dltk.internal.corext.refactoring.rename.RenameModifications;
import org.eclipse.dltk.internal.corext.refactoring.rename.ScriptRenameProcessor;
import org.eclipse.dltk.internal.corext.refactoring.tagging.IReferenceUpdating;
import org.eclipse.dltk.internal.corext.refactoring.util.ResourceUtil;
import org.eclipse.dltk.internal.corext.refactoring.util.TextChangeManager;
import org.eclipse.ltk.core.refactoring.Change;
import org.eclipse.ltk.core.refactoring.RefactoringDescriptor;
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
import org.eclipse.ltk.core.refactoring.TextChange;
import org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext;
import org.eclipse.ltk.core.refactoring.participants.RefactoringArguments;
import org.eclipse.ltk.core.refactoring.participants.RenameArguments;
import org.eclipse.text.edits.MalformedTreeException;
import org.eclipse.text.edits.MultiTextEdit;
import org.eclipse.text.edits.ReplaceEdit;
import org.eclipse.text.edits.TextEdit;
import org.eclipse.text.edits.TextEditGroup;
import org.pdtextensions.core.PHPType;
import org.pdtextensions.core.ui.Messages;
import org.pdtextensions.core.ui.PEXUIPlugin;
import org.pdtextensions.core.ui.refactoring.IPHPRefactorings;
import org.pdtextensions.internal.corext.refactoring.Checks;
import org.pdtextensions.internal.corext.refactoring.RefactoringCoreMessages;
import org.pdtextensions.internal.corext.refactoring.RenamePHPElementDescriptor;

/**
* This is the replacement of the {@link org.eclipse.dltk.internal.corext.refactoring.rename.RenameModelElementProcessor}
* class for PHP elements.
*
* @since 0.17.0
*/
public abstract class PHPRenameProcessor extends ScriptRenameProcessor implements IReferenceUpdating {
  protected IModelElement modelElement;
  protected ISourceModule cu;

  //the following fields are set or modified after the construction
  protected boolean updateReferences;

  protected TextChangeManager changeManager = new TextChangeManager(true);

  public PHPRenameProcessor(IModelElement modelElement) {
    this.modelElement = modelElement;
    cu = (ISourceModule) modelElement.getAncestor(IModelElement.SOURCE_MODULE);
  }

  @Override
  public RefactoringStatus initialize(RefactoringArguments arguments) {
    if (!(arguments instanceof ScriptRefactoringArguments))
      return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.InitializableRefactoring_inacceptable_arguments);
    final ScriptRefactoringArguments extended = (ScriptRefactoringArguments) arguments;
    final String handle = extended.getAttribute(ScriptRefactoringDescriptor.ATTRIBUTE_INPUT);
    if (handle != null) {
      final IModelElement element = ScriptRefactoringDescriptor.handleToElement(extended.getProject(), handle, false);
      if (element != null && element.exists()) {
        if (element.getElementType() == IModelElement.SOURCE_MODULE) {
          cu = (ISourceModule) element;
        } else if (element.getElementType() == IModelElement.LOCAL_VARIABLE) {
          modelElement = (ILocalVariable) element;
          cu = (ISourceModule) modelElement.getAncestor(IModelElement.SOURCE_MODULE);
          if (cu == null)
            return ScriptableRefactoring.createInputFatalStatus(element, getProcessorName(), IPHPRefactorings.RENAME_LOCAL_VARIABLE);
        } else
          return ScriptableRefactoring.createInputFatalStatus(element, getProcessorName(), IPHPRefactorings.RENAME_LOCAL_VARIABLE);
      } else
        return ScriptableRefactoring.createInputFatalStatus(element, getProcessorName(), IPHPRefactorings.RENAME_LOCAL_VARIABLE);
    } else {
      return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ScriptRefactoringDescriptor.ATTRIBUTE_INPUT));
    }
    final String name = extended.getAttribute(ScriptRefactoringDescriptor.ATTRIBUTE_NAME);
    if (name != null && !"".equals(name)) //$NON-NLS-1$
      setNewElementName(name);
    else
      return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ScriptRefactoringDescriptor.ATTRIBUTE_NAME));
    if (cu != null && modelElement == null) {
      final String selection = extended.getAttribute(ScriptRefactoringDescriptor.ATTRIBUTE_SELECTION);
      if (selection != null) {
        int offset= -1;
        int length= -1;
        final StringTokenizer tokenizer = new StringTokenizer(selection);
        if (tokenizer.hasMoreTokens())
          offset = Integer.valueOf(tokenizer.nextToken()).intValue();
        if (tokenizer.hasMoreTokens())
          length = Integer.valueOf(tokenizer.nextToken()).intValue();
        if (offset >= 0 && length >= 0) {
          try {
            final IModelElement[] elements = cu.codeSelect(offset, length);
            if (elements != null) {
              for (int index = 0; index < elements.length; index++) {
                final IModelElement element = elements[index];
                if (element instanceof ILocalVariable)
                  modelElement = (ILocalVariable) element;
              }
            }
            if (modelElement == null)
              return ScriptableRefactoring.createInputFatalStatus(null, getProcessorName(), IPHPRefactorings.RENAME_LOCAL_VARIABLE);
          } catch (ModelException exception) {
            PEXUIPlugin.getDefault().getLog().log(new Status(IStatus.ERROR, PEXUIPlugin.PLUGIN_ID, exception.getMessage(), exception));
          }
        } else
          return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_illegal_argument, new Object[] { selection,
              ScriptRefactoringDescriptor.ATTRIBUTE_SELECTION }));
      } else
        return RefactoringStatus
            .createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ScriptRefactoringDescriptor.ATTRIBUTE_SELECTION));
    }
    final String references= extended.getAttribute(ScriptRefactoringDescriptor.ATTRIBUTE_REFERENCES);
    if (references != null) {
      updateReferences= Boolean.valueOf(references).booleanValue();
    } else
      return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ScriptRefactoringDescriptor.ATTRIBUTE_REFERENCES));
    return new RefactoringStatus();
  }

  @Override
  public String getCurrentElementName() {
    return modelElement.getElementName();
  }

  @Override
  public boolean canEnableUpdateReferences() {
    IType enclosingType = (IType) modelElement.getAncestor(IModelElement.TYPE);
    if (enclosingType == null) return false;

    try {
      return new PHPType(enclosingType).inResourceWithSameName();
    } catch (CoreException e) {
      PEXUIPlugin.getDefault().getLog().log(new Status(IStatus.WARNING, PEXUIPlugin.PLUGIN_ID, e.getMessage(), e));

      return false;
    }
  }

  @Override
  public void setUpdateReferences(boolean update) {
    updateReferences = update && canEnableUpdateReferences();
  }

  @Override
  public boolean getUpdateReferences() {
    return updateReferences;
  }

  @Override
  public boolean isApplicable() throws CoreException {
      return Checks.isAvailable(modelElement);
  }

  @Override
  public Change createChange(IProgressMonitor pm) throws CoreException, OperationCanceledException {
    pm.beginTask(RefactoringCoreMessages.RenameRefactoring_checking, 1);

    try {
      Change result = new DynamicValidationRefactoringChange(createRefactoringDescriptor(), getProcessorName(), changeManager.getAllChanges());
      pm.worked(1);

      return result;
    } finally {
      changeManager.clear();
      pm.done();
    }
  }

  @Override
  protected RenameModifications computeRenameModifications()
      throws CoreException {
    RenameModifications result = new RenameModifications();
    if (modelElement instanceof ILocalVariable) {
      result.rename((ILocalVariable)modelElement, new RenameArguments(getNewElementName(), getUpdateReferences()));
    } else if (modelElement instanceof IField) {
      // TODO: add switching method in RenameModifications
      result.rename((IField)modelElement, new RenameArguments(getNewElementName(), getUpdateReferences()));
    }

    return result;
  }

  @Override
  protected IFile[] getChangedFiles() throws CoreException {
    return ResourceUtil.getFiles(changeManager.getAllSourceModules());
  }

  @Override
  protected RefactoringStatus doCheckFinalConditions(IProgressMonitor pm, CheckConditionsContext context) throws CoreException, OperationCanceledException {
    pm.beginTask("", 1); //$NON-NLS-1$

    try {
      RefactoringStatus result;

      result = checkNewElementName(getNewElementName());
      if (result.hasFatalError()) return result;

      result = renameDeclaration(pm);
      if (result.hasFatalError()) return result;

      if (updateReferences) {
        result = updateReferences(pm);
        if (result.hasFatalError()) return result;
      }

      return result;
    } finally {
      pm.done();
    }
  }

  protected RefactoringStatus renameDeclaration(IProgressMonitor pm) throws CoreException {
    return renameDeclaration(pm, modelElement, cu);
  }

  protected RefactoringStatus renameDeclaration(IProgressMonitor pm, IModelElement modelElement, ISourceModule sourceModule) throws CoreException {
    ISourceRange sourceRange = null;
    if (modelElement instanceof IMember) {
      sourceRange = ((IMember) modelElement).getNameRange();
    }
    if (sourceRange != null) {
      addTextEdit(changeManager.get(sourceModule), getProcessorName(), new ReplaceEdit(sourceRange.getOffset(), modelElement.getElementName().length(), getNewElementName()));
    }

    return new RefactoringStatus();
  }

  protected abstract RefactoringStatus updateReferences(IProgressMonitor pm) throws CoreException;

  protected static void addTextEdit(TextChange change, String name, TextEdit edit) throws MalformedTreeException {
    TextEdit root = change.getEdit();
    if (root == null) {
      root = new MultiTextEdit();
      change.setEdit(root);
    }

    root.addChild(edit);
    change.addTextEditGroup(new TextEditGroup(name, edit));
  }

  @Override
  protected String[] getAffectedProjectNatures() throws CoreException {
    return ScriptProcessors.computeAffectedNatures(cu);
  }

  @Override
  public Object[] getElements() {
    return new Object[]{ modelElement };
  }
 
  @Override
  public String getNewElement() {
    return getNewElementName();
  }

  @Override
  public RefactoringStatus checkInitialConditions(IProgressMonitor pm) throws CoreException, OperationCanceledException {
    return new RefactoringStatus();
  }

  protected RefactoringDescriptor createRefactoringDescriptor() {
    RenamePHPElementDescriptor descriptor = new RenamePHPElementDescriptor(getRefactoringId());
    if (cu.getScriptProject() != null) {
      descriptor.setProject(cu.getScriptProject().getElementName());
    }

    descriptor.setFlags(RefactoringDescriptor.NONE);
    descriptor.setModelElement(modelElement);
    descriptor.setNewName(getNewElementName());
    descriptor.setUpdateReferences(updateReferences);

    return descriptor;
  }

  protected abstract String getRefactoringId();
}
TOP

Related Classes of org.pdtextensions.internal.corext.refactoring.rename.PHPRenameProcessor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.