ExtractStringRefactoringpublic class ExtractStringRefactoring extends org.eclipse.ltk.core.refactoring.Refactoring This refactoring extracts a string from a file and replaces it by an Android resource ID
such as R.string.foo.
There are a number of scenarios, which are not all supported yet. The workflow works as
such:
- User selects a string in a Java (TODO: or XML file) and invokes
the {@link ExtractStringAction}.
- The action finds the {@link ICompilationUnit} being edited as well as the current
{@link ITextSelection}. The action creates a new instance of this refactoring as
well as an {@link ExtractStringWizard} and runs the operation.
- TODO: to support refactoring from an XML file, the action should give the {@link IFile}
and then here we would have to determine whether it's a suitable Android XML file or a
suitable Java file.
TODO: enumerate the exact valid contexts in Android XML files, e.g. attributes in layout
files or text elements (e.g. foo) for values, etc.
- Step 1 of the refactoring is to check the preliminary conditions. Right now we check
that the java source is not read-only and is in sync. We also try to find a string under
the selection. If this fails, the refactoring is aborted.
- TODO: Find the string in an XML file based on selection.
- On success, the wizard is shown, which let the user input the new ID to use.
- The wizard sets the user input values into this refactoring instance, e.g. the new string
ID, the XML file to update, etc. The wizard does use the utility method
{@link XmlStringFileHelper#isResIdDuplicate(IProject, String, String)} to check whether
the new ID is already defined in the target XML file.
- Once Preview or Finish is selected in the wizard, the
{@link #checkFinalConditions(IProgressMonitor)} is called to double-check the user input
and compute the actual changes.
- When all changes are computed, {@link #createChange(IProgressMonitor)} is invoked.
The list of changes are:
- If the target XML does not exist, create it with the new string ID.
- If the target XML exists, find the node and add the new string ID right after.
If the node is , it needs to be opened.
- Create an AST rewriter to edit the source Java file and replace all occurences by the
new computed R.string.foo. Also need to rewrite imports to import R as needed.
If there's already a conflicting R included, we need to insert the FQCN instead.
- TODO: If the source is an XML file, determine if we need to change an attribute or a
a text element.
- TODO: Have a pref in the wizard: [x] Change other XML Files
- TODO: Have a pref in the wizard: [x] Change other Java Files
|
Fields Summary |
---|
private final Mode | mModeThe {@link Mode} of operation of the refactoring. | private final org.eclipse.core.resources.IFile | mFileThe file model being manipulated.
Value is null when not on {@link Mode#EDIT_SOURCE} mode. | private final org.eclipse.core.resources.IProject | mProjectThe project that contains {@link #mFile} and that contains the target XML file to modify. | private final int | mSelectionStartThe start of the selection in {@link #mFile}.
Value is -1 when not on {@link Mode#EDIT_SOURCE} mode. | private final int | mSelectionEndThe end of the selection in {@link #mFile}.
Value is -1 when not on {@link Mode#EDIT_SOURCE} mode. | private org.eclipse.jdt.core.ICompilationUnit | mUnitThe compilation unit, only defined if {@link #mFile} points to a usable Java source file. | private String | mTokenStringThe actual string selected, after UTF characters have been escaped, good for display.
Value is null when not on {@link Mode#EDIT_SOURCE} mode. | private String | mXmlStringIdThe XML string ID selected by the user in the wizard. | private String | mXmlStringValueThe XML string value. Might be different than the initial selected string. | private String | mTargetXmlFileWsPathThe path of the XML file that will define {@link #mXmlStringId}, selected by the user
in the wizard. | private ArrayList | mChangesThe list of changes computed by {@link #checkFinalConditions(IProgressMonitor)} and
used by {@link #createChange(IProgressMonitor)}. | private XmlStringFileHelper | mXmlHelper | private static final String | KEY_MODE | private static final String | KEY_FILE | private static final String | KEY_PROJECT | private static final String | KEY_SEL_START | private static final String | KEY_SEL_END | private static final String | KEY_TOK_ESC |
Constructors Summary |
---|
public ExtractStringRefactoring(Map arguments) //$NON-NLS-1$
mMode = Mode.valueOf(arguments.get(KEY_MODE));
IPath path = Path.fromPortableString(arguments.get(KEY_PROJECT));
mProject = (IProject) ResourcesPlugin.getWorkspace().getRoot().findMember(path);
if (mMode == Mode.EDIT_SOURCE) {
path = Path.fromPortableString(arguments.get(KEY_FILE));
mFile = (IFile) ResourcesPlugin.getWorkspace().getRoot().findMember(path);
mSelectionStart = Integer.parseInt(arguments.get(KEY_SEL_START));
mSelectionEnd = Integer.parseInt(arguments.get(KEY_SEL_END));
mTokenString = arguments.get(KEY_TOK_ESC);
} else {
mFile = null;
mSelectionStart = mSelectionEnd = -1;
mTokenString = null;
}
| public ExtractStringRefactoring(org.eclipse.core.resources.IFile file, org.eclipse.jface.text.ITextSelection selection)Constructor to use when the Extract String refactoring is called on an
*existing* source file. Its purpose is then to get the selected string of
the source and propose to change it by an XML id. The XML id may be a new one
or an existing one.
mMode = Mode.EDIT_SOURCE;
mFile = file;
mProject = file.getProject();
mSelectionStart = selection.getOffset();
mSelectionEnd = mSelectionStart + Math.max(0, selection.getLength() - 1);
| public ExtractStringRefactoring(org.eclipse.core.resources.IProject project, boolean enforceNew)Constructor to use when the Extract String refactoring is called without
any source file. Its purpose is then to create a new XML string ID.
mMode = enforceNew ? Mode.SELECT_NEW_ID : Mode.SELECT_ID;
mFile = null;
mProject = project;
mSelectionStart = mSelectionEnd = -1;
|
Methods Summary |
---|
public org.eclipse.ltk.core.refactoring.RefactoringStatus | checkFinalConditions(org.eclipse.core.runtime.IProgressMonitor monitor)Step 2 of 3 of the refactoring:
Check the conditions once the user filled values in the refactoring wizard,
then prepare the changes to be applied.
In this case, most of the sanity checks are done by the wizard so essentially this
should only be called if the wizard positively validated the user input.
Here we do check that the target resource XML file either does not exists or
is not read-only.
RefactoringStatus status = new RefactoringStatus();
try {
monitor.beginTask("Checking post-conditions...", 3);
if (mXmlStringId == null || mXmlStringId.length() <= 0) {
// this is not supposed to happen
status.addFatalError("Missing replacement string ID");
} else if (mTargetXmlFileWsPath == null || mTargetXmlFileWsPath.length() <= 0) {
// this is not supposed to happen
status.addFatalError("Missing target xml file path");
}
monitor.worked(1);
// Either that resource must not exist or it must be a writeable file.
IResource targetXml = getTargetXmlResource(mTargetXmlFileWsPath);
if (targetXml != null) {
if (targetXml.getType() != IResource.FILE) {
status.addFatalError(
String.format("XML file '%1$s' is not a file.", mTargetXmlFileWsPath));
} else {
ResourceAttributes attr = targetXml.getResourceAttributes();
if (attr != null && attr.isReadOnly()) {
status.addFatalError(
String.format("XML file '%1$s' is read-only.",
mTargetXmlFileWsPath));
}
}
}
monitor.worked(1);
if (status.hasError()) {
return status;
}
mChanges = new ArrayList<Change>();
// Prepare the change for the XML file.
if (!mXmlHelper.isResIdDuplicate(mProject, mTargetXmlFileWsPath, mXmlStringId)) {
// We actually change it only if the ID doesn't exist yet
Change change = createXmlChange((IFile) targetXml, mXmlStringId, mXmlStringValue,
status, SubMonitor.convert(monitor, 1));
if (change != null) {
mChanges.add(change);
}
}
if (status.hasError()) {
return status;
}
if (mMode == Mode.EDIT_SOURCE) {
// Prepare the change to the Java compilation unit
List<Change> changes = computeJavaChanges(mUnit, mXmlStringId, mTokenString,
status, SubMonitor.convert(monitor, 1));
if (changes != null) {
mChanges.addAll(changes);
}
}
monitor.worked(1);
} finally {
monitor.done();
}
return status;
| public org.eclipse.ltk.core.refactoring.RefactoringStatus | checkInitialConditions(org.eclipse.core.runtime.IProgressMonitor monitor)Step 1 of 3 of the refactoring:
Checks that the current selection meets the initial condition before the ExtractString
wizard is shown. The check is supposed to be lightweight and quick. Note that at that
point the wizard has not been created yet.
Here we scan the source buffer to find the token matching the selection.
The check is successful is a Java string literal is selected, the source is in sync
and is not read-only.
This is also used to extract the string to be modified, so that we can display it in
the refactoring wizard.
mUnit = null;
mTokenString = null;
RefactoringStatus status = new RefactoringStatus();
try {
monitor.beginTask("Checking preconditions...", 5);
if (mMode != Mode.EDIT_SOURCE) {
monitor.worked(5);
return status;
}
if (!checkSourceFile(mFile, status, monitor)) {
return status;
}
// Try to get a compilation unit from this file. If it fails, mUnit is null.
try {
mUnit = JavaCore.createCompilationUnitFrom(mFile);
// Make sure the unit is not read-only, e.g. it's not a class file or inside a Jar
if (mUnit.isReadOnly()) {
status.addFatalError("The file is read-only, please make it writeable first.");
return status;
}
// This is a Java file. Check if it contains the selection we want.
if (!findSelectionInJavaUnit(mUnit, status, monitor)) {
return status;
}
} catch (Exception e) {
// That was not a Java file. Ignore.
}
if (mUnit == null) {
// Check this an XML file and get the selection and its context.
// TODO
status.addFatalError("Selection must be inside a Java source file.");
}
} finally {
monitor.done();
}
return status;
| private boolean | checkSourceFile(org.eclipse.core.resources.IFile file, org.eclipse.ltk.core.refactoring.RefactoringStatus status, org.eclipse.core.runtime.IProgressMonitor monitor)Tests from org.eclipse.jdt.internal.corext.refactoringChecks#validateEdit()
Might not be useful.
On success, advance the monitor by 2.
// check whether the source file is in sync
if (!file.isSynchronized(IResource.DEPTH_ZERO)) {
status.addFatalError("The file is not synchronized. Please save it first.");
return false;
}
monitor.worked(1);
// make sure we can write to it.
ResourceAttributes resAttr = file.getResourceAttributes();
if (resAttr == null || resAttr.isReadOnly()) {
status.addFatalError("The file is read-only, please make it writeable first.");
return false;
}
monitor.worked(1);
return true;
| private java.util.List | computeJavaChanges(org.eclipse.jdt.core.ICompilationUnit unit, java.lang.String xmlStringId, java.lang.String tokenString, org.eclipse.ltk.core.refactoring.RefactoringStatus status, org.eclipse.core.runtime.SubMonitor subMonitor)Computes the changes to be made to Java file(s) and returns a list of {@link Change}.
// Get the Android package name from the Android Manifest. We need it to create
// the FQCN of the R class.
String packageName = null;
String error = null;
IResource manifestFile = mProject.findMember(AndroidConstants.FN_ANDROID_MANIFEST);
if (manifestFile == null || manifestFile.getType() != IResource.FILE) {
error = "File not found";
} else {
try {
AndroidManifestParser manifest = AndroidManifestParser.parseForData(
(IFile) manifestFile);
if (manifest == null) {
error = "Invalid content";
} else {
packageName = manifest.getPackage();
if (packageName == null) {
error = "Missing package definition";
}
}
} catch (CoreException e) {
error = e.getLocalizedMessage();
}
}
if (error != null) {
status.addFatalError(
String.format("Failed to parse file %1$s: %2$s.",
manifestFile.getFullPath(), error));
return null;
}
// TODO in a future version we might want to collect various Java files that
// need to be updated in the same project and process them all together.
// To do that we need to use an ASTRequestor and parser.createASTs, kind of
// like this:
//
// ASTRequestor requestor = new ASTRequestor() {
// @Override
// public void acceptAST(ICompilationUnit sourceUnit, CompilationUnit astNode) {
// super.acceptAST(sourceUnit, astNode);
// // TODO process astNode
// }
// };
// ...
// parser.createASTs(compilationUnits, bindingKeys, requestor, monitor)
//
// and then add multiple TextFileChange to the changes arraylist.
// Right now the changes array will contain one TextFileChange at most.
ArrayList<Change> changes = new ArrayList<Change>();
// This is the unit that will be modified.
TextFileChange change = new TextFileChange(getName(), (IFile) unit.getResource());
change.setTextType("java"); //$NON-NLS-1$
// Create an AST for this compilation unit
ASTParser parser = ASTParser.newParser(AST.JLS3);
parser.setProject(unit.getJavaProject());
parser.setSource(unit);
parser.setResolveBindings(true);
ASTNode node = parser.createAST(subMonitor.newChild(1));
// The ASTNode must be a CompilationUnit, by design
if (!(node instanceof CompilationUnit)) {
status.addFatalError(String.format("Internal error: ASTNode class %s", //$NON-NLS-1$
node.getClass()));
return null;
}
// ImportRewrite will allow us to add the new type to the imports and will resolve
// what the Java source must reference, e.g. the FQCN or just the simple name.
ImportRewrite importRewrite = ImportRewrite.create((CompilationUnit) node, true);
String Rqualifier = packageName + ".R"; //$NON-NLS-1$
Rqualifier = importRewrite.addImport(Rqualifier);
// Rewrite the AST itself via an ASTVisitor
AST ast = node.getAST();
ASTRewrite astRewrite = ASTRewrite.create(ast);
ArrayList<TextEditGroup> astEditGroups = new ArrayList<TextEditGroup>();
ReplaceStringsVisitor visitor = new ReplaceStringsVisitor(
ast, astRewrite, astEditGroups,
tokenString, Rqualifier, xmlStringId);
node.accept(visitor);
// Finally prepare the change set
try {
MultiTextEdit edit = new MultiTextEdit();
// Create the edit to change the imports, only if anything changed
TextEdit subEdit = importRewrite.rewriteImports(subMonitor.newChild(1));
if (subEdit.hasChildren()) {
edit.addChild(subEdit);
}
// Create the edit to change the Java source, only if anything changed
subEdit = astRewrite.rewriteAST();
if (subEdit.hasChildren()) {
edit.addChild(subEdit);
}
// Only create a change set if any edit was collected
if (edit.hasChildren()) {
change.setEdit(edit);
// Create TextEditChangeGroups which let the user turn changes on or off
// individually. This must be done after the change.setEdit() call above.
for (TextEditGroup editGroup : astEditGroups) {
change.addTextEditChangeGroup(new TextEditChangeGroup(change, editGroup));
}
changes.add(change);
}
// TODO to modify another Java source, loop back to the creation of the
// TextFileChange and accumulate in changes. Right now only one source is
// modified.
if (changes.size() > 0) {
return changes;
}
subMonitor.worked(1);
} catch (CoreException e) {
// ImportRewrite.rewriteImports failed.
status.addFatalError(e.getMessage());
}
return null;
| private java.util.Map | createArgumentMap()
HashMap<String, String> args = new HashMap<String, String>();
args.put(KEY_MODE, mMode.name());
args.put(KEY_PROJECT, mProject.getFullPath().toPortableString());
if (mMode == Mode.EDIT_SOURCE) {
args.put(KEY_FILE, mFile.getFullPath().toPortableString());
args.put(KEY_SEL_START, Integer.toString(mSelectionStart));
args.put(KEY_SEL_END, Integer.toString(mSelectionEnd));
args.put(KEY_TOK_ESC, mTokenString);
}
return args;
| public org.eclipse.ltk.core.refactoring.Change | createChange(org.eclipse.core.runtime.IProgressMonitor monitor)Step 3 of 3 of the refactoring: returns the {@link Change} that will be able to do the
work and creates a descriptor that can be used to replay that refactoring later.
try {
monitor.beginTask("Applying changes...", 1);
CompositeChange change = new CompositeChange(
getName(),
mChanges.toArray(new Change[mChanges.size()])) {
@Override
public ChangeDescriptor getDescriptor() {
String comment = String.format(
"Extracts string '%1$s' into R.string.%2$s",
mTokenString,
mXmlStringId);
ExtractStringDescriptor desc = new ExtractStringDescriptor(
mProject.getName(), //project
comment, //description
comment, //comment
createArgumentMap());
return new RefactoringChangeDescriptor(desc);
}
};
monitor.worked(1);
return change;
} finally {
monitor.done();
}
| private org.eclipse.ltk.core.refactoring.Change | createXmlChange(org.eclipse.core.resources.IFile targetXml, java.lang.String xmlStringId, java.lang.String tokenString, org.eclipse.ltk.core.refactoring.RefactoringStatus status, org.eclipse.core.runtime.SubMonitor subMonitor)Internal helper that actually prepares the {@link Change} that adds the given
ID to the given XML File.
This does not actually modify the file.
TextFileChange xmlChange = new TextFileChange(getName(), targetXml);
xmlChange.setTextType("xml"); //$NON-NLS-1$
TextEdit edit = null;
TextEditGroup editGroup = null;
if (!targetXml.exists()) {
// The XML file does not exist. Simply create it.
StringBuilder content = new StringBuilder();
content.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"); //$NON-NLS-1$
content.append("<resources>\n"); //$NON-NLS-1$
content.append(" <string name=\""). //$NON-NLS-1$
append(xmlStringId).
append("\">"). //$NON-NLS-1$
append(tokenString).
append("</string>\n"); //$NON-NLS-1$
content.append("<resources>\n"); //$NON-NLS-1$
edit = new InsertEdit(0, content.toString());
editGroup = new TextEditGroup("Create <string> in new XML file", edit);
} else {
// The file exist. Attempt to parse it as a valid XML document.
try {
int[] indices = new int[2];
// TODO case where we replace the value of an existing XML String ID
if (findXmlOpeningTagPos(targetXml.getContents(), "resources", indices)) { //$NON-NLS-1$
// Indices[1] indicates whether we found > or />. It can only be 1 or 2.
// Indices[0] is the position of the first character of either > or />.
//
// Note: we don't even try to adapt our formatting to the existing structure (we
// could by capturing whatever whitespace is after the closing bracket and
// applying it here before our tag, unless we were dealing with an empty
// resource tag.)
int offset = indices[0];
int len = indices[1];
StringBuilder content = new StringBuilder();
content.append(">\n"); //$NON-NLS-1$
content.append(" <string name=\""). //$NON-NLS-1$
append(xmlStringId).
append("\">"). //$NON-NLS-1$
append(tokenString).
append("</string>"); //$NON-NLS-1$
if (len == 2) {
content.append("\n</resources>"); //$NON-NLS-1$
}
edit = new ReplaceEdit(offset, len, content.toString());
editGroup = new TextEditGroup("Insert <string> in XML file", edit);
}
} catch (CoreException e) {
// Failed to read file. Ignore. Will return null below.
}
}
if (edit == null) {
status.addFatalError(String.format("Failed to modify file %1$s",
mTargetXmlFileWsPath));
return null;
}
xmlChange.setEdit(edit);
// The TextEditChangeGroup let the user toggle this change on and off later.
xmlChange.addTextEditChangeGroup(new TextEditChangeGroup(xmlChange, editGroup));
subMonitor.worked(1);
return xmlChange;
| private boolean | findSelectionInJavaUnit(org.eclipse.jdt.core.ICompilationUnit unit, org.eclipse.ltk.core.refactoring.RefactoringStatus status, org.eclipse.core.runtime.IProgressMonitor monitor)Try to find the selected Java element in the compilation unit.
If selection matches a string literal, capture it, otherwise add a fatal error
to the status.
On success, advance the monitor by 3.
try {
IBuffer buffer = unit.getBuffer();
IScanner scanner = ToolFactory.createScanner(
false, //tokenizeComments
false, //tokenizeWhiteSpace
false, //assertMode
false //recordLineSeparator
);
scanner.setSource(buffer.getCharacters());
monitor.worked(1);
for(int token = scanner.getNextToken();
token != ITerminalSymbols.TokenNameEOF;
token = scanner.getNextToken()) {
if (scanner.getCurrentTokenStartPosition() <= mSelectionStart &&
scanner.getCurrentTokenEndPosition() >= mSelectionEnd) {
// found the token, but only keep of the right type
if (token == ITerminalSymbols.TokenNameStringLiteral) {
mTokenString = new String(scanner.getCurrentTokenSource());
}
break;
} else if (scanner.getCurrentTokenStartPosition() > mSelectionEnd) {
// scanner is past the selection, abort.
break;
}
}
} catch (JavaModelException e1) {
// Error in unit.getBuffer. Ignore.
} catch (InvalidInputException e2) {
// Error in scanner.getNextToken. Ignore.
} finally {
monitor.worked(1);
}
if (mTokenString != null) {
// As a literal string, the token should have surrounding quotes. Remove them.
int len = mTokenString.length();
if (len > 0 &&
mTokenString.charAt(0) == '"" &&
mTokenString.charAt(len - 1) == '"") {
mTokenString = mTokenString.substring(1, len - 1);
}
// We need a non-empty string literal
if (mTokenString.length() == 0) {
mTokenString = null;
}
}
if (mTokenString == null) {
status.addFatalError("Please select a Java string literal.");
}
monitor.worked(1);
return status.isOK();
| private boolean | findXmlOpeningTagPos(java.io.InputStream contents, java.lang.String tag, int[] indices)Parse an XML input stream, looking for an opening tag.
If found, returns the character offest in the buffer of the closing bracket of that
tag, e.g. the position of > in "". The first character is at offset 0.
The implementation here relies on a simple character-based parser. No DOM nor SAX
parsing is used, due to the simplified nature of the task: we just want the first
opening tag, which in our case should be the document root. We deal however with
with the tag being commented out, so comments are skipped. We assume the XML doc
is sane, e.g. we don't expect the tag to appear in the middle of a string. But
again since in fact we want the root element, that's unlikely to happen.
We need to deal with the case where the element is written as , in
which case the caller will want to replace /> by ">...". To do that we return
two values: the first offset of the closing tag (e.g. / or >) and the length, which
can only be 1 or 2. If it's 2, the caller have to deal with /> instead of just >.
BufferedReader br = new BufferedReader(new InputStreamReader(contents));
StringBuilder sb = new StringBuilder(); // scratch area
tag = "<" + tag;
int tagLen = tag.length();
int maxLen = tagLen < 3 ? 3 : tagLen;
try {
int offset = 0;
int i = 0;
char searching = '<"; // we want opening tags
boolean capture = false;
boolean inComment = false;
boolean inTag = false;
while ((i = br.read()) != -1) {
char c = (char) i;
if (c == searching) {
capture = true;
}
if (capture) {
sb.append(c);
int len = sb.length();
if (inComment && c == '>") {
// is the comment being closed?
if (len >= 3 && sb.substring(len-3).equals("-->")) { //$NON-NLS-1$
// yes, comment is closing, stop capturing
capture = false;
inComment = false;
sb.setLength(0);
}
} else if (inTag && c == '>") {
// we're capturing in our tag, waiting for the closing >, we just got it
// so we're totally done here. Simply detect whether it's /> or >.
indices[0] = offset;
indices[1] = 1;
if (sb.charAt(len - 2) == '/") {
indices[0]--;
indices[1]++;
}
return true;
} else if (!inComment && !inTag) {
// not a comment and not our tag yet, so we're capturing because a
// tag is being opened but we don't know which one yet.
// look for either the opening or a comment or
// the opening of our tag.
if (len == 3 && sb.equals("<--")) { //$NON-NLS-1$
inComment = true;
} else if (len == tagLen && sb.toString().equals(tag)) {
inTag = true;
}
// if we're not interested in this tag yet, deal with when to stop
// capturing: the opening tag ends with either any kind of whitespace
// or with a > or maybe there's a PI that starts with <?
if (!inComment && !inTag) {
if (c == '>" || c == '?" || c == ' " || c == '\n" || c == '\r") {
// stop capturing
capture = false;
sb.setLength(0);
}
}
}
if (capture && len > maxLen) {
// in any case we don't need to capture more than the size of our tag
// or the comment opening tag
sb.deleteCharAt(0);
}
}
offset++;
}
} catch (IOException e) {
// Ignore.
} finally {
try {
br.close();
} catch (IOException e) {
// oh come on...
}
}
return false;
| public com.android.ide.eclipse.adt.refactorings.extractstring.ExtractStringRefactoring$Mode | getMode()
return mMode;
| public java.lang.String | getName()
if (mMode == Mode.SELECT_ID) {
return "Create or USe Android String";
} else if (mMode == Mode.SELECT_NEW_ID) {
return "Create New Android String";
}
return "Extract Android String";
| private org.eclipse.core.resources.IResource | getTargetXmlResource(java.lang.String xmlFileWsPath)Given a file project path, returns its resource in the same project than the
compilation unit. The resource may not exist.
IResource resource = mProject.getFile(xmlFileWsPath);
return resource;
| public java.lang.String | getTokenString()Gets the actual string selected, after UTF characters have been escaped,
good for display.
return mTokenString;
| public java.lang.String | getXmlStringId()
return mXmlStringId;
| public void | setNewStringId(java.lang.String newStringId)Sets the replacement string ID. Used by the wizard to set the user input.
mXmlStringId = newStringId;
| public void | setNewStringValue(java.lang.String newStringValue)Sets the replacement string ID. Used by the wizard to set the user input.
mXmlStringValue = newStringValue;
| public void | setTargetFile(java.lang.String targetXmlFileWsPath)Sets the target file. This is a project path, e.g. "/res/values/strings.xml".
Used by the wizard to set the user input.
mTargetXmlFileWsPath = targetXmlFileWsPath;
|
|