Added a new refactoring action: net.sourceforge.phpdt.ltk.ui.actions.RenameLocalVariable
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / ltk / core / RenameLocalVariableDelegate.java
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ltk/core/RenameLocalVariableDelegate.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ltk/core/RenameLocalVariableDelegate.java
new file mode 100644 (file)
index 0000000..11f3fd5
--- /dev/null
@@ -0,0 +1,173 @@
+// Copyright (c) 2005 by Leif Frenzel. All rights reserved.
+// See http://leiffrenzel.de
+// modified for phpeclipse.de project by axelcl
+package net.sourceforge.phpdt.ltk.core;
+
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import net.sourceforge.phpdt.core.ISourceRange;
+import net.sourceforge.phpdt.core.compiler.ITerminalSymbols;
+import net.sourceforge.phpdt.core.compiler.InvalidInputException;
+import net.sourceforge.phpdt.internal.compiler.parser.Scanner;
+import net.sourceforge.phpdt.internal.compiler.parser.SyntaxError;
+import net.sourceforge.phpdt.internal.core.SourceMethod;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.ltk.core.refactoring.Change;
+import org.eclipse.ltk.core.refactoring.CompositeChange;
+import org.eclipse.ltk.core.refactoring.RefactoringStatus;
+import org.eclipse.ltk.core.refactoring.TextFileChange;
+import org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext;
+import org.eclipse.ltk.core.refactoring.participants.IConditionChecker;
+import org.eclipse.ltk.core.refactoring.participants.ValidateEditChecker;
+import org.eclipse.text.edits.MultiTextEdit;
+import org.eclipse.text.edits.ReplaceEdit;
+
+/**
+ * <p>
+ * delegate object that contains the logic used by the processor.
+ * </p>
+ *
+ */
+public class RenameLocalVariableDelegate extends RenameIdentifierDelegate {
+
+       public RenameLocalVariableDelegate(final RenameIdentifierInfo info) {
+               super(info);
+       }
+
+       RefactoringStatus checkInitialConditions() {
+               RefactoringStatus result = new RefactoringStatus();
+               IFile sourceFile = info.getSourceFile();
+               if (sourceFile == null || !sourceFile.exists()) {
+                       result.addFatalError(CoreTexts.renamePropertyDelegate_noSourceFile);
+               } else if (info.getSourceFile().isReadOnly()) {
+                       result.addFatalError(CoreTexts.renamePropertyDelegate_roFile);
+               } else if (isEmpty(info.getOldName())) {
+                       // || !isPropertyKey( info.getSourceFile(), info.getOldName() ) ) {
+                       result.addFatalError(CoreTexts.renamePropertyDelegate_noPHPKey);
+               }
+               return result;
+       }
+
+       RefactoringStatus checkFinalConditions(final IProgressMonitor pm, final CheckConditionsContext ctxt) {
+               RefactoringStatus result = new RefactoringStatus();
+               pm.beginTask(CoreTexts.renamePropertyDelegate_checking, 100);
+               // do something long-running here: traverse the entire project (or even
+               // workspace) to look for all *.p files with the same bundle
+               // base name
+               IFile file = info.getSourceFile();
+               IProject project = file.getProject();
+               try {
+                       SourceMethod method = info.getMethod();
+                       ISourceRange range = method.getSourceRange();
+                       if (project.isNatureEnabled(PHPeclipsePlugin.PHP_NATURE_ID)) {
+                               determineMethodOffsets(file, range.getOffset(), range.getLength(), result);
+                       }
+               } catch (CoreException e) {
+                       String msg = "Project: " + project.getLocation().toOSString() + " CoreException " + e.getMessage();
+                       result.addError(msg);
+               } catch (Exception e) {
+                       String msg = "Project: " + project.getLocation().toOSString() + " Exception " + e.getMessage();
+                       result.addError(msg);
+               }
+
+               pm.worked(50);
+
+               if (ctxt != null) {
+                       IFile[] files = new IFile[phpFiles.size()];
+                       phpFiles.keySet().toArray(files);
+                       IConditionChecker checker = ctxt.getChecker(ValidateEditChecker.class);
+                       ValidateEditChecker editChecker = (ValidateEditChecker) checker;
+                       editChecker.addFiles(files);
+               }
+               pm.done();
+               return result;
+       }
+
+       protected void createChange(final IProgressMonitor pm, final CompositeChange rootChange) {
+               try {
+                       pm.beginTask(CoreTexts.renamePropertyDelegate_collectingChanges, 100);
+                       // all files in the same bundle
+                       rootChange.addAll(createChangesForContainer(pm));
+               } finally {
+                       pm.done();
+               }
+       }
+
+       // finds the offsets of the identifier to rename
+       // usually, this would be the job of a proper parser;
+       // using a primitive brute-force approach here
+       private void determineMethodOffsets(final IFile file, int offset, int length, final RefactoringStatus status) {
+               ArrayList matches = new ArrayList();
+               try {
+                       String content = readFileContent(file, status);
+                       String methodString = content.substring(offset, offset + length);
+                       Scanner scanner = new Scanner(true, false);
+                       scanner.setSource(methodString.toCharArray());
+                       scanner.setPHPMode(true);
+                       char[] word = info.getOldName().toCharArray();
+
+                       int fToken = ITerminalSymbols.TokenNameEOF;
+                       try {
+                               fToken = scanner.getNextToken();
+                               while (fToken != ITerminalSymbols.TokenNameEOF) {
+                                       if (fToken == ITerminalSymbols.TokenNameVariable) {
+                                               if (scanner.equalsCurrentTokenSource(word)) {
+                                                       matches.add(Integer.valueOf(scanner.getCurrentTokenStartPosition() + offset));
+                                               }
+                                       }
+                                       fToken = scanner.getNextToken();
+                               }
+
+                       } catch (InvalidInputException e) {
+                               String msg = "File: " + file.getLocation().toOSString() + " InvalidInputException " + e.getMessage();
+                               status.addError(msg);
+                       } catch (SyntaxError e) {
+                               String msg = "File: " + file.getLocation().toOSString() + " SyntaxError " + e.getMessage();
+                               status.addError(msg);
+                       }
+
+               } catch (Exception e) {
+                       String msg = "File: " + file.getLocation().toOSString() + " Exception " + e.getMessage();
+                       status.addError(msg);
+               }
+               if (matches.size() > 0) {
+                       phpFiles.put(file, matches);
+               }
+       }
+
+       private String readFileContent(final IFile file, final RefactoringStatus refStatus) {
+               String result = null;
+               try {
+                       InputStream is = file.getContents();
+                       byte[] buf = new byte[1024];
+                       ByteArrayOutputStream bos = new ByteArrayOutputStream();
+                       int len = is.read(buf);
+                       while (len > 0) {
+                               bos.write(buf, 0, len);
+                               len = is.read(buf);
+                       }
+                       is.close();
+                       result = new String(bos.toByteArray());
+               } catch (Exception ex) {
+                       String msg = ex.toString();
+                       refStatus.addFatalError(msg);
+                       String pluginId = PHPeclipsePlugin.getPluginId();
+                       IStatus status = new Status(IStatus.ERROR, pluginId, 0, msg, ex);
+                       PHPeclipsePlugin.getDefault().getLog().log(status);
+               }
+               return result;
+       }
+
+}