• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

development


Commit MetaInfo

Revisãob6007ebd5c6f373ab4bc48363b6738b681ef13a3 (tree)
Hora2009-03-25 12:57:57
AutorRaphael Moll <>
CommiterThe Android Open Source Project

Mensagem de Log

Automated import from //branches/donutburger/...@141823,141823

Mudança Sumário

Diff

--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/refactorings/extractstring/ExtractStringAction.java
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/refactorings/extractstring/ExtractStringAction.java
@@ -16,7 +16,11 @@
1616
1717 package com.android.ide.eclipse.adt.refactorings.extractstring;
1818
19+import com.android.ide.eclipse.common.AndroidConstants;
20+
1921 import org.eclipse.core.resources.IFile;
22+import org.eclipse.core.resources.IProject;
23+import org.eclipse.core.runtime.CoreException;
2024 import org.eclipse.jdt.core.ICompilationUnit;
2125 import org.eclipse.jdt.core.ITypeRoot;
2226 import org.eclipse.jdt.core.JavaCore;
@@ -32,6 +36,7 @@ import org.eclipse.ui.IWorkbenchPage;
3236 import org.eclipse.ui.IWorkbenchWindow;
3337 import org.eclipse.ui.IWorkbenchWindowActionDelegate;
3438 import org.eclipse.ui.PlatformUI;
39+import org.eclipse.ui.part.FileEditorInput;
3540
3641 /*
3742 * Quick Reference Link:
@@ -71,7 +76,7 @@ public class ExtractStringAction implements IWorkbenchWindowActionDelegate {
7176 /** Keep track of the current workbench window. */
7277 private IWorkbenchWindow mWindow;
7378 private ITextSelection mSelection;
74- private ICompilationUnit mUnit;
79+ private IFile mFile;
7580
7681 /**
7782 * Keep track of the current workbench window.
@@ -99,30 +104,24 @@ public class ExtractStringAction implements IWorkbenchWindowActionDelegate {
99104 // runs since we don't have access to the AST yet.
100105
101106 mSelection = null;
102- mUnit = null;
107+ mFile = null;
103108
104109 if (selection instanceof ITextSelection) {
105110 mSelection = (ITextSelection) selection;
106111 if (mSelection.getLength() > 0) {
107- mUnit = getCompilationUnit();
112+ mFile = getSelectedFile();
108113 }
109-
110- // Keep for debugging purposes
111- //System.out.println(String.format("-- Selection: %d + %d = %s",
112- // mSelection.getOffset(),
113- // mSelection.getLength(),
114- // mSelection.getText()));
115114 }
116115
117- action.setEnabled(mSelection != null && mUnit != null);
116+ action.setEnabled(mSelection != null && mFile != null);
118117 }
119118
120119 /**
121120 * Create a new instance of our refactoring and a wizard to configure it.
122121 */
123122 public void run(IAction action) {
124- if (mSelection != null && mUnit != null) {
125- ExtractStringRefactoring ref = new ExtractStringRefactoring(mUnit, mSelection);
123+ if (mSelection != null && mFile != null) {
124+ ExtractStringRefactoring ref = new ExtractStringRefactoring(mFile, mSelection);
126125 RefactoringWizard wizard = new ExtractStringWizard(ref, "Extract Android String");
127126 RefactoringWizardOpenOperation op = new RefactoringWizardOpenOperation(wizard);
128127 try {
@@ -134,9 +133,14 @@ public class ExtractStringAction implements IWorkbenchWindowActionDelegate {
134133 }
135134
136135 /**
137- * Returns the active {@link ICompilationUnit} or null.
136+ * Returns the active {@link IFile} (hopefully matching our selection) or null.
137+ * The file is only returned if it's a file from a project with an Android nature.
138+ * <p/>
139+ * At that point we do not try to analyze if the selection nor the file is suitable
140+ * for the refactoring. This check is performed when the refactoring is invoked since
141+ * it can then produce meaningful error messages as needed.
138142 */
139- private ICompilationUnit getCompilationUnit() {
143+ private IFile getSelectedFile() {
140144 IWorkbenchWindow wwin = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
141145 if (wwin != null) {
142146 IWorkbenchPage page = wwin.getActivePage();
@@ -144,12 +148,19 @@ public class ExtractStringAction implements IWorkbenchWindowActionDelegate {
144148 IEditorPart editor = page.getActiveEditor();
145149 if (editor != null) {
146150 IEditorInput input = editor.getEditorInput();
147- if (input != null) {
148- ITypeRoot typeRoot = JavaUI.getEditorInputTypeRoot(input);
149- // The type root can be either a .class or a .java (aka compilation unit).
150- // We want the compilation unit kind.
151- if (typeRoot instanceof ICompilationUnit) {
152- return (ICompilationUnit) typeRoot;
151+
152+ if (input instanceof FileEditorInput) {
153+ FileEditorInput fi = (FileEditorInput) input;
154+ IFile file = fi.getFile();
155+ if (file.exists()) {
156+ IProject proj = file.getProject();
157+ try {
158+ if (proj != null && proj.hasNature(AndroidConstants.NATURE)) {
159+ return file;
160+ }
161+ } catch (CoreException e) {
162+ // ignore
163+ }
153164 }
154165 }
155166 }
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/refactorings/extractstring/ExtractStringRefactoring.java
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/refactorings/extractstring/ExtractStringRefactoring.java
@@ -24,7 +24,9 @@ import org.eclipse.core.resources.IFile;
2424 import org.eclipse.core.resources.IProject;
2525 import org.eclipse.core.resources.IResource;
2626 import org.eclipse.core.resources.ResourceAttributes;
27+import org.eclipse.core.resources.ResourcesPlugin;
2728 import org.eclipse.core.runtime.CoreException;
29+import org.eclipse.core.runtime.IPath;
2830 import org.eclipse.core.runtime.IProgressMonitor;
2931 import org.eclipse.core.runtime.OperationCanceledException;
3032 import org.eclipse.core.runtime.Path;
@@ -126,46 +128,54 @@ import javax.xml.xpath.XPathExpressionException;
126128 */
127129 class ExtractStringRefactoring extends Refactoring {
128130
129- /** The compilation unit, a.k.a. the Java file model. */
130- private final ICompilationUnit mUnit;
131+ /** The file model being manipulated. */
132+ private final IFile mFile;
133+ /** The start of the selection in {@link #mFile}. */
131134 private final int mSelectionStart;
135+ /** The end of the selection in {@link #mFile}. */
132136 private final int mSelectionEnd;
137+
138+ /** The compilation unit, only defined if {@link #mFile} points to a usable Java source file. */
139+ private ICompilationUnit mUnit;
133140 /** The actual string selected, after UTF characters have been escaped, good for display. */
134141 private String mTokenString;
135- /** Start position of the string token in the source buffer. */
136- private int mTokenStart;
137- /** End position of the string token in the source buffer. */
138- private int mTokenEnd;
142+
143+ /** The XML string ID selected by the user in the wizard. */
139144 private String mXmlStringId;
145+ /** The path of the XML file that will define {@link #mXmlStringId}, selected by the user
146+ * in the wizard. */
140147 private String mTargetXmlFileWsPath;
148+
149+ /** A temporary cache of R.string IDs defined by a given xml file. The key is the
150+ * project path of the file, the data is a set of known string Ids for that file. */
141151 private HashMap<String,HashSet<String>> mResIdCache;
152+ /** An instance of XPath, created lazily on demand. */
142153 private XPath mXPath;
154+ /** The list of changes computed by {@link #checkFinalConditions(IProgressMonitor)} and
155+ * used by {@link #createChange(IProgressMonitor)}. */
143156 private ArrayList<Change> mChanges;
144157
145158 public ExtractStringRefactoring(Map<String, String> arguments)
146159 throws NullPointerException {
147- mUnit = (ICompilationUnit) JavaCore.create(arguments.get("CU")); //$NON-NLS-1$
160+
161+ IPath path = Path.fromPortableString(arguments.get("file")); //$NON-NLS-1$
162+ mFile = (IFile) ResourcesPlugin.getWorkspace().getRoot().findMember(path);
148163 mSelectionStart = Integer.parseInt(arguments.get("sel-start")); //$NON-NLS-1$
149164 mSelectionEnd = Integer.parseInt(arguments.get("sel-end")); //$NON-NLS-1$
150- mTokenStart = Integer.parseInt(arguments.get("tok-start")); //$NON-NLS-1$
151- mTokenEnd = Integer.parseInt(arguments.get("tok-end")); //$NON-NLS-1$
152165 mTokenString = arguments.get("tok-esc"); //$NON-NLS-1$
153166 }
154167
155168 private Map<String, String> createArgumentMap() {
156169 HashMap<String, String> args = new HashMap<String, String>();
157- args.put("CU", mUnit.getHandleIdentifier()); //$NON-NLS-1$
170+ args.put("file", mFile.getFullPath().toPortableString()); //$NON-NLS-1$
158171 args.put("sel-start", Integer.toString(mSelectionStart)); //$NON-NLS-1$
159172 args.put("sel-end", Integer.toString(mSelectionEnd)); //$NON-NLS-1$
160- args.put("tok-start", Integer.toString(mTokenStart)); //$NON-NLS-1$
161- args.put("tok-end", Integer.toString(mTokenEnd)); //$NON-NLS-1$
162173 args.put("tok-esc", mTokenString); //$NON-NLS-1$
163174 return args;
164175 }
165176
166- public ExtractStringRefactoring(ICompilationUnit unit, ITextSelection selection) {
167- mUnit = unit;
168-
177+ public ExtractStringRefactoring(IFile file, ITextSelection selection) {
178+ mFile = file;
169179 mSelectionStart = selection.getOffset();
170180 mSelectionEnd = mSelectionStart + selection.getLength();
171181 }
@@ -207,75 +217,42 @@ class ExtractStringRefactoring extends Refactoring {
207217 public RefactoringStatus checkInitialConditions(IProgressMonitor monitor)
208218 throws CoreException, OperationCanceledException {
209219
220+ mUnit = null;
210221 mTokenString = null;
211- mTokenStart = -1;
212- mTokenEnd = -1;
213222
214223 RefactoringStatus status = new RefactoringStatus();
215224
216225 try {
217- monitor.beginTask("Checking preconditions...", 3);
218-
219- if (!extraChecks(monitor, status)) {
226+ monitor.beginTask("Checking preconditions...", 5);
227+
228+ if (!checkSourceFile(mFile, status, monitor)) {
220229 return status;
221230 }
222-
231+
232+ // Try to get a compilation unit from this file. If it fails, mUnit is null.
223233 try {
224- IBuffer buffer = mUnit.getBuffer();
225-
226- IScanner scanner = ToolFactory.createScanner(
227- false, //tokenizeComments
228- false, //tokenizeWhiteSpace
229- false, //assertMode
230- false //recordLineSeparator
231- );
232- scanner.setSource(buffer.getCharacters());
233- monitor.worked(1);
234-
235- for(int token = scanner.getNextToken();
236- token != ITerminalSymbols.TokenNameEOF;
237- token = scanner.getNextToken()) {
238- if (scanner.getCurrentTokenStartPosition() <= mSelectionStart &&
239- scanner.getCurrentTokenEndPosition() >= mSelectionEnd) {
240- // found the token, but only keep of the right type
241- if (token == ITerminalSymbols.TokenNameStringLiteral) {
242- mTokenString = new String(scanner.getCurrentTokenSource());
243- mTokenStart = scanner.getCurrentTokenStartPosition();
244- mTokenEnd = scanner.getCurrentTokenEndPosition();
245- }
246- break;
247- } else if (scanner.getCurrentTokenStartPosition() > mSelectionEnd) {
248- // scanner is past the selection, abort.
249- break;
250- }
251- }
252- } catch (JavaModelException e1) {
253- // Error in mUnit.getBuffer. Ignore.
254- } catch (InvalidInputException e2) {
255- // Error in scanner.getNextToken. Ignore.
256- } finally {
257- monitor.worked(1);
258- }
234+ mUnit = JavaCore.createCompilationUnitFrom(mFile);
259235
260- if (mTokenString != null) {
261- // As a literal string, the token should have surrounding quotes. Remove them.
262- int len = mTokenString.length();
263- if (len > 0 &&
264- mTokenString.charAt(0) == '"' &&
265- mTokenString.charAt(len - 1) == '"') {
266- mTokenString = mTokenString.substring(1, len - 1);
236+ // Make sure the unit is not read-only, e.g. it's not a class file or inside a Jar
237+ if (mUnit.isReadOnly()) {
238+ status.addFatalError("The file is read-only, please make it writeable first.");
239+ return status;
267240 }
268- // We need a non-empty string literal
269- if (mTokenString.length() == 0) {
270- mTokenString = null;
241+
242+ // This is a Java file. Check if it contains the selection we want.
243+ if (!findSelectionInJavaUnit(mUnit, status, monitor)) {
244+ return status;
271245 }
246+
247+ } catch (Exception e) {
248+ // That was not a Java file. Ignore.
272249 }
273250
274- if (mTokenString == null) {
275- status.addFatalError("Please select a Java string literal.");
251+ if (mUnit == null) {
252+ // Check this an XML file and get the selection and its context.
253+ // TODO
254+ status.addFatalError("Selection must be inside a Java source file.");
276255 }
277-
278- monitor.worked(1);
279256 } finally {
280257 monitor.done();
281258 }
@@ -284,30 +261,93 @@ class ExtractStringRefactoring extends Refactoring {
284261 }
285262
286263 /**
287- * Tests from org.eclipse.jdt.internal.corext.refactoringChecks#validateEdit()
288- * Might not be useful.
264+ * Try to find the selected Java element in the compilation unit.
289265 *
290- * @return False if caller should abort, true if caller should continue.
266+ * If selection matches a string literal, capture it, otherwise add a fatal error
267+ * to the status.
268+ *
269+ * On success, advance the monitor by 3.
291270 */
292- private boolean extraChecks(IProgressMonitor monitor, RefactoringStatus status) {
293- //
294- IResource res = mUnit.getPrimary().getResource();
295- if (res == null || res.getType() != IResource.FILE) {
296- status.addFatalError("Cannot access resource; only regular files can be used.");
297- return false;
271+ private boolean findSelectionInJavaUnit(ICompilationUnit unit,
272+ RefactoringStatus status, IProgressMonitor monitor) {
273+ try {
274+ IBuffer buffer = unit.getBuffer();
275+
276+ IScanner scanner = ToolFactory.createScanner(
277+ false, //tokenizeComments
278+ false, //tokenizeWhiteSpace
279+ false, //assertMode
280+ false //recordLineSeparator
281+ );
282+ scanner.setSource(buffer.getCharacters());
283+ monitor.worked(1);
284+
285+ for(int token = scanner.getNextToken();
286+ token != ITerminalSymbols.TokenNameEOF;
287+ token = scanner.getNextToken()) {
288+ if (scanner.getCurrentTokenStartPosition() <= mSelectionStart &&
289+ scanner.getCurrentTokenEndPosition() >= mSelectionEnd) {
290+ // found the token, but only keep of the right type
291+ if (token == ITerminalSymbols.TokenNameStringLiteral) {
292+ mTokenString = new String(scanner.getCurrentTokenSource());
293+ }
294+ break;
295+ } else if (scanner.getCurrentTokenStartPosition() > mSelectionEnd) {
296+ // scanner is past the selection, abort.
297+ break;
298+ }
299+ }
300+ } catch (JavaModelException e1) {
301+ // Error in unit.getBuffer. Ignore.
302+ } catch (InvalidInputException e2) {
303+ // Error in scanner.getNextToken. Ignore.
304+ } finally {
305+ monitor.worked(1);
306+ }
307+
308+ if (mTokenString != null) {
309+ // As a literal string, the token should have surrounding quotes. Remove them.
310+ int len = mTokenString.length();
311+ if (len > 0 &&
312+ mTokenString.charAt(0) == '"' &&
313+ mTokenString.charAt(len - 1) == '"') {
314+ mTokenString = mTokenString.substring(1, len - 1);
315+ }
316+ // We need a non-empty string literal
317+ if (mTokenString.length() == 0) {
318+ mTokenString = null;
319+ }
298320 }
321+
322+ if (mTokenString == null) {
323+ status.addFatalError("Please select a Java string literal.");
324+ }
325+
299326 monitor.worked(1);
327+ return status.isOK();
328+ }
300329
330+ /**
331+ * Tests from org.eclipse.jdt.internal.corext.refactoringChecks#validateEdit()
332+ * Might not be useful.
333+ *
334+ * On success, advance the monitor by 2.
335+ *
336+ * @return False if caller should abort, true if caller should continue.
337+ */
338+ private boolean checkSourceFile(IFile file,
339+ RefactoringStatus status,
340+ IProgressMonitor monitor) {
301341 // check whether the source file is in sync
302- if (!res.isSynchronized(IResource.DEPTH_ZERO)) {
342+ if (!file.isSynchronized(IResource.DEPTH_ZERO)) {
303343 status.addFatalError("The file is not synchronized. Please save it first.");
304344 return false;
305345 }
306346 monitor.worked(1);
307347
308348 // make sure we can write to it.
309- ResourceAttributes resAttr = res.getResourceAttributes();
310- if (mUnit.isReadOnly() || resAttr == null || resAttr.isReadOnly()) {
349+ ResourceAttributes resAttr = file.getResourceAttributes();
350+ if (resAttr == null || resAttr.isReadOnly()) {
311351 status.addFatalError("The file is read-only, please make it writeable first.");
312352 return false;
313353 }