• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  *
4  * Licensed under the Eclipse Public License, Version 1.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.eclipse.org/org/documents/epl-v10.php
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.ide.eclipse.adt.internal.refactorings.extractstring;
17 
18 import com.android.ide.eclipse.adt.AdtPlugin;
19 import com.android.ide.eclipse.adt.AdtUtils;
20 
21 import org.eclipse.core.resources.IFile;
22 import org.eclipse.jdt.core.IBuffer;
23 import org.eclipse.jdt.core.JavaModelException;
24 import org.eclipse.jdt.core.dom.ASTNode;
25 import org.eclipse.jdt.ui.text.java.IInvocationContext;
26 import org.eclipse.jdt.ui.text.java.IJavaCompletionProposal;
27 import org.eclipse.jface.text.IDocument;
28 import org.eclipse.jface.text.ITextSelection;
29 import org.eclipse.jface.text.TextSelection;
30 import org.eclipse.jface.text.contentassist.IContextInformation;
31 import org.eclipse.ltk.ui.refactoring.RefactoringWizard;
32 import org.eclipse.ltk.ui.refactoring.RefactoringWizardOpenOperation;
33 import org.eclipse.swt.graphics.Image;
34 import org.eclipse.swt.graphics.Point;
35 import org.eclipse.ui.IEditorPart;
36 import org.eclipse.ui.IWorkbenchWindow;
37 import org.eclipse.ui.PlatformUI;
38 
39 /**
40  * Proposal for extracting strings in Java files
41  */
42 public class ExtractStringProposal implements IJavaCompletionProposal {
43     private IInvocationContext mContext;
44 
ExtractStringProposal(IInvocationContext context)45     public ExtractStringProposal(IInvocationContext context) {
46         mContext = context;
47     }
48 
49     @Override
apply(IDocument document)50     public void apply(IDocument document) {
51         IEditorPart editor = AdtUtils.getActiveEditor();
52         IFile file = AdtUtils.getActiveFile();
53         if (editor == null || file == null) {
54             return;
55         }
56 
57         ASTNode coveringNode = mContext.getCoveringNode();
58         int start = coveringNode.getStartPosition();
59         int length = coveringNode.getLength();
60         ITextSelection selection = new TextSelection(start, length);
61 
62         ExtractStringRefactoring refactoring = new ExtractStringRefactoring(file, editor,
63                 selection);
64 
65         RefactoringWizard wizard = new ExtractStringWizard(refactoring, file.getProject());
66         RefactoringWizardOpenOperation op = new RefactoringWizardOpenOperation(wizard);
67         try {
68             IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
69             op.run(window.getShell(), wizard.getDefaultPageTitle());
70         } catch (InterruptedException e) {
71         }
72     }
73 
74     @Override
getSelection(IDocument document)75     public Point getSelection(IDocument document) {
76         return null;
77     }
78 
79     @Override
getAdditionalProposalInfo()80     public String getAdditionalProposalInfo() {
81         try {
82             ASTNode coveringNode = mContext.getCoveringNode();
83             int start = coveringNode.getStartPosition();
84             int length = coveringNode.getLength();
85             IBuffer buffer = mContext.getCompilationUnit().getBuffer();
86             StringBuilder sb = new StringBuilder();
87             String string = buffer.getText(start, length);
88             string = ExtractStringRefactoring.unquoteAttrValue(string);
89             String token = ExtractStringInputPage.guessId(string);
90 
91             // Look up the beginning and the end of the line (outside of the extracted string)
92             // such that we can show a preview of the diff, e.g. if you have
93             // foo.setTitle("Hello"); we want to show foo.setTitle(R.string.hello);
94             // so we need to extract "foo.setTitle(" and ");".
95 
96             // Look backwards to the beginning of the line (and strip whitespace)
97             int i = start - 1;
98             while (i > 0) {
99                 char c = buffer.getChar(i);
100                 if (c == '\r' || (c == '\n')) {
101                     break;
102                 }
103                 i--;
104             }
105             String linePrefix = buffer.getText(i + 1, start - (i + 1)).trim();
106 
107             // Look forwards to the end of the line (and strip whitespace)
108             i = start + length;
109             while (i < buffer.getLength()) {
110                 char c = buffer.getChar(i);
111                 if (c == '\r' || (c == '\n')) {
112                     break;
113                 }
114                 i++;
115             }
116             String lineSuffix = buffer.getText(start + length, i - (start + length));
117 
118             // Should we show the replacement as just R.string.foo or
119             // context.getString(R.string.foo) ?
120             boolean useContext = false;
121             ASTNode parent = coveringNode.getParent();
122             if (parent != null) {
123                 int type = parent.getNodeType();
124                 if (type == ASTNode.ASSIGNMENT
125                         || type == ASTNode.VARIABLE_DECLARATION_STATEMENT
126                         || type == ASTNode.VARIABLE_DECLARATION_FRAGMENT
127                         || type == ASTNode.VARIABLE_DECLARATION_EXPRESSION) {
128                     useContext = true;
129                 }
130             }
131 
132             // Display .java change:
133             sb.append("...<br>");                   //$NON-NLS-1$
134             sb.append(linePrefix);
135             sb.append("<b>");                       //$NON-NLS-1$
136             if (useContext) {
137                 sb.append("context.getString(");    //$NON-NLS-1$
138             }
139             sb.append("R.string.");                 //$NON-NLS-1$
140             sb.append(token);
141             if (useContext) {
142                 sb.append(")");                     //$NON-NLS-1$
143             }
144             sb.append("</b>");                      //$NON-NLS-1$
145             sb.append(lineSuffix);
146             sb.append("<br>...<br>");               //$NON-NLS-1$
147 
148             // Display strings.xml change:
149             sb.append("<br>");                      //$NON-NLS-1$
150             sb.append("&lt;resources&gt;<br>");     //$NON-NLS-1$
151             sb.append("    <b>&lt;string name=\""); //$NON-NLS-1$
152             sb.append(token);
153             sb.append("\"&gt;");                    //$NON-NLS-1$
154             sb.append(string);
155             sb.append("&lt;/string&gt;</b><br>");   //$NON-NLS-1$
156             sb.append("&lt;/resources&gt;");        //$NON-NLS-1$
157 
158             return sb.toString();
159         } catch (JavaModelException e) {
160             AdtPlugin.log(e, null);
161         }
162 
163         return "Initiates the Extract String refactoring operation";
164     }
165 
166     @Override
getDisplayString()167     public String getDisplayString() {
168         return "Extract String";
169     }
170 
171     @Override
getImage()172     public Image getImage() {
173         return AdtPlugin.getAndroidLogo();
174     }
175 
176     @Override
getContextInformation()177     public IContextInformation getContextInformation() {
178         return null;
179     }
180 
181     @Override
getRelevance()182     public int getRelevance() {
183         return 80;
184     }
185 }