1 // Copyright (c) 2005 by Leif Frenzel. All rights reserved.
2 // See http://leiffrenzel.de
3 // modified for phpeclipse.de project by axelcl
4 package net.sourceforge.phpdt.ltk.core;
6 import java.io.ByteArrayOutputStream;
7 import java.io.InputStream;
8 import java.util.ArrayList;
10 import net.sourceforge.phpdt.core.ISourceRange;
11 import net.sourceforge.phpdt.core.compiler.ITerminalSymbols;
12 import net.sourceforge.phpdt.core.compiler.InvalidInputException;
13 import net.sourceforge.phpdt.internal.compiler.parser.Scanner;
14 import net.sourceforge.phpdt.internal.compiler.parser.SyntaxError;
15 import net.sourceforge.phpdt.internal.core.SourceMethod;
16 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
18 import org.eclipse.core.resources.IFile;
19 import org.eclipse.core.resources.IProject;
20 import org.eclipse.core.runtime.CoreException;
21 import org.eclipse.core.runtime.IProgressMonitor;
22 import org.eclipse.core.runtime.IStatus;
23 import org.eclipse.core.runtime.Status;
24 import org.eclipse.ltk.core.refactoring.CompositeChange;
25 import org.eclipse.ltk.core.refactoring.RefactoringStatus;
26 import org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext;
27 import org.eclipse.ltk.core.refactoring.participants.IConditionChecker;
28 import org.eclipse.ltk.core.refactoring.participants.ValidateEditChecker;
32 * delegate object that contains the logic used by the processor.
36 public class RenameLocalVariableDelegate extends RenameIdentifierDelegate {
38 public RenameLocalVariableDelegate(final RenameIdentifierInfo info) {
42 RefactoringStatus checkInitialConditions() {
43 RefactoringStatus result = new RefactoringStatus();
44 IFile sourceFile = info.getSourceFile();
45 if (sourceFile == null || !sourceFile.exists()) {
46 result.addFatalError(CoreTexts.renamePropertyDelegate_noSourceFile);
47 } else if (info.getSourceFile().isReadOnly()) {
48 result.addFatalError(CoreTexts.renamePropertyDelegate_roFile);
49 } else if (isEmpty(info.getOldName())) {
50 // || !isPropertyKey( info.getSourceFile(), info.getOldName() ) ) {
51 result.addFatalError(CoreTexts.renamePropertyDelegate_noPHPKey);
56 RefactoringStatus checkFinalConditions(final IProgressMonitor pm, final CheckConditionsContext ctxt) {
57 RefactoringStatus result = new RefactoringStatus();
58 pm.beginTask(CoreTexts.renamePropertyDelegate_checking, 100);
59 // do something long-running here: traverse the entire project (or even
60 // workspace) to look for all *.p files with the same bundle
62 IFile file = info.getSourceFile();
63 IProject project = file.getProject();
65 SourceMethod method = info.getMethod();
66 ISourceRange range = method.getSourceRange();
67 if (project.isNatureEnabled(PHPeclipsePlugin.PHP_NATURE_ID)) {
68 determineMethodOffsets(file, range.getOffset(), range.getLength(), result);
70 } catch (CoreException e) {
71 String msg = "Project: " + project.getLocation().toOSString() + " CoreException " + e.getMessage();
73 } catch (Exception e) {
74 String msg = "Project: " + project.getLocation().toOSString() + " Exception " + e.getMessage();
81 IFile[] files = new IFile[phpFiles.size()];
82 phpFiles.keySet().toArray(files);
83 IConditionChecker checker = ctxt.getChecker(ValidateEditChecker.class);
84 ValidateEditChecker editChecker = (ValidateEditChecker) checker;
85 editChecker.addFiles(files);
91 protected void createChange(final IProgressMonitor pm, final CompositeChange rootChange) {
93 pm.beginTask(CoreTexts.renamePropertyDelegate_collectingChanges, 100);
94 // all files in the same bundle
95 rootChange.addAll(createChangesForContainer(pm));
101 // finds the offsets of the identifier to rename
102 // usually, this would be the job of a proper parser;
103 // using a primitive brute-force approach here
104 private void determineMethodOffsets(final IFile file, int offset, int length, final RefactoringStatus status) {
105 ArrayList matches = new ArrayList();
107 String content = readFileContent(file, status);
108 String methodString = content.substring(offset, offset + length);
109 Scanner scanner = new Scanner(true, false);
110 scanner.setSource(methodString.toCharArray());
111 scanner.setPHPMode(true);
112 String wordStr = info.getOldName();
113 char[] word = wordStr.toCharArray();
115 int fToken = ITerminalSymbols.TokenNameEOF;
120 fToken = scanner.getNextToken();
121 while (fToken != ITerminalSymbols.TokenNameEOF) {
122 if (fToken == ITerminalSymbols.TokenNameVariable) {
123 if (scanner.equalsCurrentTokenSource(word)) {
124 // the current variable token is equal to the given word
125 matches.add(Integer.valueOf(scanner.getCurrentTokenStartPosition() + offset));
127 } else if (fToken == ITerminalSymbols.TokenNameStringDoubleQuote) {
128 // determine the word in double quoted strings:
129 dqStr = new String(scanner.getCurrentTokenSource());
130 dqOffset = scanner.getCurrentTokenStartPosition();
132 while ((index = dqStr.indexOf(wordStr, index + 1)) >= 0) {
133 matches.add(Integer.valueOf(offset + dqOffset + index));
136 fToken = scanner.getNextToken();
139 } catch (InvalidInputException e) {
140 String msg = "File: " + file.getLocation().toOSString() + " InvalidInputException " + e.getMessage();
141 status.addError(msg);
142 } catch (SyntaxError e) {
143 String msg = "File: " + file.getLocation().toOSString() + " SyntaxError " + e.getMessage();
144 status.addError(msg);
147 } catch (Exception e) {
148 String msg = "File: " + file.getLocation().toOSString() + " Exception " + e.getMessage();
149 status.addError(msg);
151 if (matches.size() > 0) {
152 phpFiles.put(file, matches);
156 private String readFileContent(final IFile file, final RefactoringStatus refStatus) {
157 String result = null;
159 InputStream is = file.getContents();
160 byte[] buf = new byte[1024];
161 ByteArrayOutputStream bos = new ByteArrayOutputStream();
162 int len = is.read(buf);
164 bos.write(buf, 0, len);
168 result = new String(bos.toByteArray());
169 } catch (Exception ex) {
170 String msg = ex.toString();
171 refStatus.addFatalError(msg);
172 String pluginId = PHPeclipsePlugin.getPluginId();
173 IStatus status = new Status(IStatus.ERROR, pluginId, 0, msg, ex);
174 PHPeclipsePlugin.getDefault().getLog().log(status);