aboutsummaryrefslogtreecommitdiffstats
path: root/eclipse/plugins
diff options
context:
space:
mode:
authorTor Norbye <tnorbye@google.com>2012-12-03 11:09:09 -0800
committerGerrit Code Review <noreply-gerritcodereview@google.com>2012-12-03 11:09:09 -0800
commitc3b3bb82b50c5fcc81aeca72ea9043aa756cc69c (patch)
tree2d5290e42a015be93bbb20a0ebc567db1262def5 /eclipse/plugins
parentbb36284a03dc87d35aff13f66c6f49bd3d050ddf (diff)
parent32654dfbd134559fbf6bec4542d6a4a8105897c9 (diff)
downloadsdk-c3b3bb82b50c5fcc81aeca72ea9043aa756cc69c.zip
sdk-c3b3bb82b50c5fcc81aeca72ea9043aa756cc69c.tar.gz
sdk-c3b3bb82b50c5fcc81aeca72ea9043aa756cc69c.tar.bz2
Merge "Fix rename type, rename package and move type refactorings"
Diffstat (limited to 'eclipse/plugins')
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/META-INF/MANIFEST.MF1
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/LayoutMetadata.java6
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/changes/AndroidDocumentChange.java309
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/changes/AndroidLayoutChange.java297
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/changes/AndroidLayoutChangeDescription.java122
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/changes/AndroidLayoutFileChanges.java61
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/changes/AndroidPackageRenameChange.java135
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/changes/AndroidTypeMoveChange.java45
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/changes/AndroidTypeRenameChange.java120
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/core/AndroidPackageRenameParticipant.java666
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/core/AndroidRenameParticipant.java86
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/core/AndroidTypeMoveParticipant.java483
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/core/AndroidTypeRenameParticipant.java503
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/core/RefactoringUtil.java133
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/core/RenameResourceParticipant.java34
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/refactorings/core/AndroidPackageRenameParticipantTest.java31
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/refactorings/core/RefactoringTestBase.java70
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/refactorings/core/RenameResourceParticipantTest.java19
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/refactorings/core/AndroidTypeMoveParticipantTest.java35
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/refactorings/core/AndroidTypeRenameParticipantTest.java72
20 files changed, 1028 insertions, 2200 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/META-INF/MANIFEST.MF b/eclipse/plugins/com.android.ide.eclipse.adt/META-INF/MANIFEST.MF
index 3745613..67bd705 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/META-INF/MANIFEST.MF
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/META-INF/MANIFEST.MF
@@ -104,7 +104,6 @@ Export-Package: com.android.assetstudiolib;x-friends:="com.android.ide.eclipse.t
com.android.ide.eclipse.adt.internal.preferences;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.adt.internal.project;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.adt.internal.properties;x-friends:="com.android.ide.eclipse.tests",
- com.android.ide.eclipse.adt.internal.refactorings.changes;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.adt.internal.refactorings.core;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.adt.internal.refactorings.extractstring;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.adt.internal.refactorings.renamepackage;x-friends:="com.android.ide.eclipse.tests",
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/LayoutMetadata.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/LayoutMetadata.java
index 94bd058..b79e3b0 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/LayoutMetadata.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/LayoutMetadata.java
@@ -56,7 +56,6 @@ import java.util.Map;
/**
* Design-time metadata lookup for layouts, such as fragment and AdapterView bindings.
*/
-@SuppressWarnings("restriction") // XML DOM model
public class LayoutMetadata {
/** The default layout to use for list items in expandable list views */
public static final String DEFAULT_EXPANDABLE_LIST_ITEM = "simple_expandable_list_item_2"; //$NON-NLS-1$
@@ -75,6 +74,8 @@ public class LayoutMetadata {
public static final String KEY_LV_FOOTER = "listfooter"; //$NON-NLS-1$
/** The property key, included in comments, which references a fragment layout to show */
public static final String KEY_FRAGMENT_LAYOUT = "layout"; //$NON-NLS-1$
+ // NOTE: If you add additional keys related to resources, make sure you update the
+ // ResourceRenameParticipant
/** Utility class, do not create instances */
private LayoutMetadata() {
@@ -191,9 +192,6 @@ public class LayoutMetadata {
return;
}
Display display = AdtPlugin.getDisplay();
- if (display == null) {
- return;
- }
WorkbenchJob job = new WorkbenchJob(display, "Update alternate views") {
@Override
public IStatus runInUIThread(IProgressMonitor monitor) {
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/changes/AndroidDocumentChange.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/changes/AndroidDocumentChange.java
deleted file mode 100644
index eb8ccc7..0000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/changes/AndroidDocumentChange.java
+++ /dev/null
@@ -1,309 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.refactorings.changes;
-
-import com.android.SdkConstants;
-import com.android.ide.eclipse.adt.internal.project.AndroidManifestHelper;
-import com.android.ide.eclipse.adt.internal.project.XmlErrorHandler.BasicXmlErrorListener;
-import com.android.ide.eclipse.adt.internal.refactorings.core.RefactoringUtil;
-import com.android.xml.AndroidManifest;
-
-import org.eclipse.core.filebuffers.ITextFileBufferManager;
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.OperationCanceledException;
-import org.eclipse.jface.text.IDocument;
-import org.eclipse.ltk.core.refactoring.DocumentChange;
-import org.eclipse.ltk.core.refactoring.RefactoringStatus;
-import org.eclipse.text.edits.ReplaceEdit;
-import org.eclipse.text.edits.TextEdit;
-import org.eclipse.wst.sse.core.StructuredModelManager;
-import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
-import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
-import org.eclipse.wst.xml.core.internal.provisional.document.IDOMAttr;
-import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;
-import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
-import org.w3c.dom.Attr;
-import org.w3c.dom.NamedNodeMap;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-
-import java.util.Map;
-
-/**
- * A text change that operates on android manifest using WTP SSE model.
- * It is base class for Rename Package and Rename Type changes
-*/
-@SuppressWarnings("restriction")
-public class AndroidDocumentChange extends DocumentChange {
-
- protected IFile mAndroidManifest;
-
- protected String mAppPackage;
-
- protected IStructuredModel mModel;
-
- protected IDocument mDocument;
-
- protected Map<String, String> mElements;
-
- protected String mNewName;
-
- protected String mOldName;
-
- protected ITextFileBufferManager mManager;
-
- /**
- * Creates a new <code>AndroidDocumentChange</code> for the given
- * {@link IDocument}.
- *
- * @param document the document this change is working on
- */
- public AndroidDocumentChange(IDocument document) {
- super(SdkConstants.FN_ANDROID_MANIFEST_XML, document);
- }
-
- /**
- * Returns the manifest file
- *
- * @return the manifest
- */
- public IFile getManifest() {
- return mAndroidManifest;
- }
-
- @Override
- public RefactoringStatus isValid(IProgressMonitor pm) throws CoreException,
- OperationCanceledException {
- RefactoringStatus status = super.isValid(pm);
- if (mModel == null) {
- status.addFatalError("File " + SdkConstants.FN_ANDROID_MANIFEST_XML + " is invalid.");
- } else {
- mAppPackage = getAppPackage();
- if (mAppPackage == null) {
- status.addFatalError("Invalid package in the "
- + SdkConstants.FN_ANDROID_MANIFEST_XML + " file.");
- }
- }
- BasicXmlErrorListener errorListener = new BasicXmlErrorListener();
- AndroidManifestHelper.parseForError(mAndroidManifest, errorListener);
-
- if (errorListener.mHasXmlError == true) {
- status.addFatalError("File " + SdkConstants.FN_ANDROID_MANIFEST_XML + " is invalid.");
- }
- return status;
- }
-
- /**
- * Finds the attribute with values oldName
- *
- * @param xmlDoc the document
- * @param element the element
- * @param attributeName the attribute
- * @param oldName the value
- *
- * @return the attribute
- */
- private Attr findAttribute(IDOMDocument xmlDoc, String element, String attributeName,
- String oldName) {
- NodeList nodes = xmlDoc.getElementsByTagName(element);
- for (int i = 0; i < nodes.getLength(); i++) {
- Node node = nodes.item(i);
- NamedNodeMap attributes = node.getAttributes();
- if (attributes != null) {
- Attr attribute = RefactoringUtil.findAndroidAttributes(attributes, attributeName);
- if (attribute != null) {
- String value = attribute.getValue();
- if (value != null) {
- String fullName = AndroidManifest.combinePackageAndClassName(
- getAppPackage(), value);
- if (fullName != null && fullName.equals(oldName)) {
- return attribute;
- }
- }
- }
- }
- }
- return null;
- }
-
- /**
- * Returns the attribute value
- *
- * @param xmlDoc the document
- * @param element the element
- * @param attributeName the attribute
- *
- * @return the attribute value
- */
- protected String getElementAttribute(IDOMDocument xmlDoc, String element,
- String attributeName, boolean useNamespace) {
- NodeList nodes = xmlDoc.getElementsByTagName(element);
- for (int i = 0; i < nodes.getLength(); i++) {
- Node node = nodes.item(i);
- NamedNodeMap attributes = node.getAttributes();
- if (attributes != null) {
- Attr attribute;
- if (useNamespace) {
- attribute = RefactoringUtil.findAndroidAttributes(attributes, attributeName);
- } else {
- attribute = (Attr) attributes.getNamedItem(attributeName);
- }
- if (attribute != null) {
- return attribute.getValue();
- }
- }
- }
- return null;
- }
-
- /**
- * Returns the SSE model for a document
- *
- * @param document the document
- * @return the model
- *
- */
- protected IStructuredModel getModel(IDocument document) {
- if (mModel != null) {
- return mModel;
- }
- IStructuredModel model;
- model = StructuredModelManager.getModelManager().getExistingModelForRead(document);
- if (model == null) {
- if (document instanceof IStructuredDocument) {
- IStructuredDocument structuredDocument = (IStructuredDocument) document;
- model = StructuredModelManager.getModelManager()
- .getModelForRead(structuredDocument);
- }
- }
- return model;
- }
-
- @Override
- public void setTextType(String type) {
- super.setTextType(mAndroidManifest.getFileExtension());
- }
-
- /**
- * Returns the SSE DOM document
- *
- * @return the attribute value
- */
- protected IDOMDocument getDOMDocument() {
- IDOMModel xmlModel = (IDOMModel) mModel;
- IDOMDocument xmlDoc = xmlModel.getDocument();
- return xmlDoc;
- }
-
- /**
- * Returns the application package
- *
- * @return the package name
- */
- protected String getAppPackage() {
- if (mAppPackage == null) {
- IDOMDocument xmlDoc = getDOMDocument();
- mAppPackage = getElementAttribute(xmlDoc, AndroidManifest.NODE_MANIFEST,
- AndroidManifest.ATTRIBUTE_PACKAGE, false);
- }
- return mAppPackage;
- }
-
- /**
- * Returns the text change that set new value of attribute
- *
- * @param attribute the attribute
- * @param newValue the new value
- *
- * @return the text change
- */
- protected TextEdit createTextEdit(Attr attribute, String newValue) {
- if (attribute == null)
- return null;
-
- if (attribute instanceof IDOMAttr) {
- IDOMAttr domAttr = (IDOMAttr) attribute;
- // Get the current "region" (the current attribute, including its quotes.)
- String region = domAttr.getValueRegionText();
- int offset = domAttr.getValueRegionStartOffset();
- if (region != null && region.length() >= 2) {
- // Skip the quotes when replacing.
- ReplaceEdit edit = new ReplaceEdit(offset + 1, region.length() - 2, newValue);
- return edit;
- }
- }
- return null;
- }
-
- /**
- * Returns the text change that change the value of attribute from oldValue to newValue
- * and combine package
- *
- * @param elementName the element name
- * @param attributeName the attribute name
- * @param oldValue the old value
- * @param newValue the new value
- *
- * @return the text change
- */
- protected TextEdit createTextEdit(String elementName, String attributeName, String oldValue,
- String newValue) {
- return createTextEdit(elementName, attributeName, oldValue, newValue, true);
- }
-
- /**
- * Returns the text change that change the value of attribute from oldValue to newValue
- *
- * @param elementName the element name
- * @param attributeName the attribute name
- * @param oldName the old value
- * @param newName the new value
- * @param combinePackage combine package ?
- *
- * @return the text change
- */
- protected TextEdit createTextEdit(String elementName, String attributeName, String oldName,
- String newName, boolean combinePackage) {
- IDOMDocument xmlDoc = getDOMDocument();
- String name = null;
- Attr attr = findAttribute(xmlDoc, elementName, attributeName, oldName);
- if (attr != null) {
- name = attr.getValue();
- }
- if (name != null) {
- String newValue = newName;
- if (combinePackage) {
- String pkg = getAppPackage();
- if (oldName.startsWith(pkg) && newName.startsWith(pkg)) {
- // Heuristic: if the old value is a fully qualified name, then
- // assume that's how the user wants it in the manifest and
- // do *not* shorten the new value. Keep it fully qualified too.
- } else {
- newValue = AndroidManifest.extractActivityName(newName, pkg);
- }
- }
- if (newValue != null) {
- TextEdit edit = createTextEdit(attr, newValue);
- return edit;
- }
- }
- return null;
- }
-
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/changes/AndroidLayoutChange.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/changes/AndroidLayoutChange.java
deleted file mode 100644
index 7bac6d7..0000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/changes/AndroidLayoutChange.java
+++ /dev/null
@@ -1,297 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.refactorings.changes;
-
-import com.android.SdkConstants;
-import com.android.ide.eclipse.adt.internal.refactorings.core.RefactoringUtil;
-
-import org.eclipse.core.filebuffers.ITextFileBufferManager;
-import org.eclipse.core.filebuffers.LocationKind;
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.core.runtime.OperationCanceledException;
-import org.eclipse.jface.text.IDocument;
-import org.eclipse.ltk.core.refactoring.DocumentChange;
-import org.eclipse.ltk.core.refactoring.RefactoringStatus;
-import org.eclipse.text.edits.MultiTextEdit;
-import org.eclipse.text.edits.ReplaceEdit;
-import org.eclipse.text.edits.TextEdit;
-import org.eclipse.wst.sse.core.StructuredModelManager;
-import org.eclipse.wst.sse.core.internal.provisional.IModelManager;
-import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
-import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
-import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;
-import org.eclipse.wst.xml.core.internal.provisional.document.IDOMAttr;
-import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;
-import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
-import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
-import org.w3c.dom.Attr;
-import org.w3c.dom.NamedNodeMap;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Set;
-
-/**
- * A text change that operates on android layout using WTP SSE model.
- * It is base class for Rename Package and Rename Type changes
-*/
-@SuppressWarnings("restriction")
-public class AndroidLayoutChange extends DocumentChange {
-
- private IDocument mDocument;
-
- private ITextFileBufferManager mManager;
-
- private IFile mFile;
-
- private IStructuredModel mModel;
-
- private Set<AndroidLayoutChangeDescription> mChanges;
-
- /**
- * Creates a new <code>AndroidLayoutChange</code>
- *
- * @param file the layout file
- * @param document the document
- * @param manager the buffer manager
- * @param changes the list of changes
- */
- public AndroidLayoutChange(IFile file, IDocument document, ITextFileBufferManager manager,
- Set<AndroidLayoutChangeDescription> changes) {
- super("", document); //$NON-NLS-1$
- mFile = file;
- mDocument = document;
- mManager = manager;
- mChanges = changes;
- try {
- this.mModel = getModel(document);
- } catch (Exception ignore) {
- }
- if (mModel != null) {
- addEdits();
- }
- }
-
- public IFile getFile() {
- return mFile;
- }
-
- @Override
- public String getName() {
- return mFile.getName();
- }
-
- @Override
- public RefactoringStatus isValid(IProgressMonitor pm) throws CoreException,
- OperationCanceledException {
- RefactoringStatus status = super.isValid(pm);
- if (mModel == null) {
- status.addFatalError("Invalid the " + getName() + " file.");
- }
- return status;
- }
-
- @Override
- public void setTextType(String type) {
- super.setTextType(mFile.getFileExtension());
- }
-
- @Override
- public void dispose() {
- super.dispose();
- RefactoringUtil.fixModel(mModel, mDocument);
-
- if (mManager != null) {
- try {
- mManager.disconnect(mFile.getFullPath(), LocationKind.NORMALIZE,
- new NullProgressMonitor());
- } catch (CoreException e) {
- RefactoringUtil.log(e);
- }
- }
- }
-
- // ----
-
- /**
- * Adds text edits for this change
- */
- private void addEdits() {
- MultiTextEdit multiEdit = new MultiTextEdit();
- for (AndroidLayoutChangeDescription change : mChanges) {
- if (!change.isStandalone()) {
- TextEdit edit = createTextEdit(SdkConstants.VIEW,
- SdkConstants.ATTR_CLASS,
- change.getClassName(),
- change.getNewName());
- if (edit != null) {
- multiEdit.addChild(edit);
- }
- } else {
- List<TextEdit> edits = createElementTextEdit(change.getClassName(),
- change.getNewName());
- for (TextEdit edit : edits) {
- multiEdit.addChild(edit);
- }
- }
- }
- setEdit(multiEdit);
- }
-
- /**
- * Returns the text changes which change class (custom layout viewer) in layout file
- *
- * @param className the class name
- * @param newName the new class name
- *
- * @return list of text changes
- */
- private List<TextEdit> createElementTextEdit(String className, String newName) {
- IDOMDocument xmlDoc = getDOMDocument();
- List<TextEdit> edits = new ArrayList<TextEdit>();
- NodeList nodes = xmlDoc.getElementsByTagName(className);
- for (int i = 0; i < nodes.getLength(); i++) {
- Node node = nodes.item(i);
- if (node instanceof IDOMElement) {
- IDOMElement domNode = (IDOMElement) node;
- IStructuredDocumentRegion firstRegion = domNode.getFirstStructuredDocumentRegion();
- if (firstRegion != null) {
- int offset = firstRegion.getStartOffset();
- edits.add(new ReplaceEdit(offset + 1, className.length(), newName));
- }
- IStructuredDocumentRegion endRegion = domNode.getEndStructuredDocumentRegion();
- if (endRegion != null) {
- int offset = endRegion.getStartOffset();
- edits.add(new ReplaceEdit(offset + 2, className.length(), newName));
- }
- }
-
- }
- return edits;
- }
-
- /**
- * Returns the SSE DOM document
- *
- * @return the attribute value
- */
- private IDOMDocument getDOMDocument() {
- IDOMModel xmlModel = (IDOMModel) mModel;
- IDOMDocument xmlDoc = xmlModel.getDocument();
- return xmlDoc;
- }
-
- /**
- * Returns the text change that set new value of attribute
- *
- * @param attribute the attribute
- * @param newValue the new value
- *
- * @return the text change
- */
- private TextEdit createTextEdit(Attr attribute, String newValue) {
- if (attribute == null)
- return null;
-
- if (attribute instanceof IDOMAttr) {
- IDOMAttr domAttr = (IDOMAttr) attribute;
- String region = domAttr.getValueRegionText();
- int offset = domAttr.getValueRegionStartOffset();
- if (region != null && region.length() >= 2) {
- return new ReplaceEdit(offset + 1, region.length() - 2, newValue);
- }
- }
- return null;
- }
-
-
- /**
- * Returns the text change that change the value of attribute from oldValue to newValue
- *
- * @param elementName the element name
- * @param argumentName the attribute name
- * @param oldName the old value
- * @param newName the new value
- *
- * @return the text change
- */
- private TextEdit createTextEdit(String elementName, String argumentName, String oldName,
- String newName) {
- IDOMDocument xmlDoc = getDOMDocument();
- String name = null;
- Attr attr = findAttribute(xmlDoc, elementName, argumentName, oldName);
- if (attr != null) {
- name = attr.getValue();
- }
- if (name != null && newName != null) {
- TextEdit edit = createTextEdit(attr, newName);
- return edit;
- }
- return null;
- }
-
- /**
- * Finds the attribute with values oldName
- *
- * @param xmlDoc the document
- * @param element the element
- * @param attributeName the attribute
- * @param oldValue the value
- *
- * @return the attribute
- */
- private Attr findAttribute(IDOMDocument xmlDoc, String element, String attributeName,
- String oldValue) {
- NodeList nodes = xmlDoc.getElementsByTagName(element);
- for (int i = 0; i < nodes.getLength(); i++) {
- Node node = nodes.item(i);
- NamedNodeMap attributes = node.getAttributes();
- if (attributes != null) {
- Attr attribute = RefactoringUtil.findAndroidAttributes(attributes, attributeName);
- if (attribute != null) {
- String value = attribute.getValue();
- if (value != null && value.equals(oldValue)) {
- return attribute;
- }
- }
- }
- }
- return null;
- }
-
- /**
- * Returns the SSE model for a document
- *
- * @param document the document
- * @return the model
- */
- private IStructuredModel getModel(IDocument document) {
-
- IModelManager manager = StructuredModelManager.getModelManager();
- IStructuredModel model = manager.getExistingModelForRead(document);
- if (model == null && document instanceof IStructuredDocument) {
- model = manager.getModelForRead((IStructuredDocument) document);
- }
-
- return model;
- }
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/changes/AndroidLayoutChangeDescription.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/changes/AndroidLayoutChangeDescription.java
deleted file mode 100644
index 2ddaac0..0000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/changes/AndroidLayoutChangeDescription.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.refactorings.changes;
-
-/**
- * This class describes the text changes of android layout files
- *
- */
-public class AndroidLayoutChangeDescription {
-
- private String mClassName;
-
- private String mNewName;
-
- private int mType;
-
- /**
- * the view layout
- */
- public static final int VIEW_TYPE = 0;
-
- /**
- * the standalone layout
- */
- public static final int STANDALONE_TYPE = 1;
-
- /**
- * Creates a new <code>AndroidDocumentChange</code>
- *
- * @param className the old layout class name
- * @param newName the new layout class name
- * @param type the layout type; valid value are VIEW_TYPE and STANDALONE_TYPE
- */
- public AndroidLayoutChangeDescription(String className, String newName, int type) {
- this.mClassName = className;
- this.mNewName = newName;
- this.mType = type;
- }
-
- /**
- * @return the old class name
- */
- public String getClassName() {
- return mClassName;
- }
-
- /**
- * @return the new class name
- */
- public String getNewName() {
- return mNewName;
- }
-
- /**
- * @return the layout type
- */
- public int getType() {
- return mType;
- }
-
- /**
- * @return true if the layout is standalone
- */
- public boolean isStandalone() {
- return mType == STANDALONE_TYPE;
- }
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + ((mClassName == null) ? 0 : mClassName.hashCode());
- result = prime * result + ((mNewName == null) ? 0 : mNewName.hashCode());
- result = prime * result + mType;
- return result;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- AndroidLayoutChangeDescription other = (AndroidLayoutChangeDescription) obj;
- if (mClassName == null) {
- if (other.mClassName != null)
- return false;
- } else if (!mClassName.equals(other.mClassName))
- return false;
- if (mNewName == null) {
- if (other.mNewName != null)
- return false;
- } else if (!mNewName.equals(other.mNewName))
- return false;
- if (mType != other.mType)
- return false;
- return true;
- }
-
- @Override
- public String toString() {
- return "AndroidLayoutChangeDescription [className=" + mClassName + ", newName=" + mNewName
- + ", type=" + mType + "]";
- }
-
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/changes/AndroidLayoutFileChanges.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/changes/AndroidLayoutFileChanges.java
deleted file mode 100644
index 1d4a741..0000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/changes/AndroidLayoutFileChanges.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.refactorings.changes;
-
-import org.eclipse.core.resources.IFile;
-
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * Set of layout files with required text changes
- *
- */
-public class AndroidLayoutFileChanges {
- private IFile mFile;
-
- private Set<AndroidLayoutChangeDescription> mChanges =
- new HashSet<AndroidLayoutChangeDescription>();
-
- /**
- * Creates a new <code>AndroidLayoutFileChanges</code>
- *
- * @param file the layout file
- */
- public AndroidLayoutFileChanges(IFile file) {
- this.mFile = file;
- }
-
- /**
- * Return the layout file
- *
- * @return the file
- */
- public IFile getFile() {
- return mFile;
- }
-
- /**
- * Return the text changes
- *
- * @return the set of changes
- */
- public Set<AndroidLayoutChangeDescription> getChanges() {
- return mChanges;
- }
-
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/changes/AndroidPackageRenameChange.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/changes/AndroidPackageRenameChange.java
deleted file mode 100644
index 08e4f01..0000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/changes/AndroidPackageRenameChange.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.refactorings.changes;
-
-import com.android.ide.eclipse.adt.internal.refactorings.core.FixImportsJob;
-import com.android.ide.eclipse.adt.internal.refactorings.core.RefactoringUtil;
-import com.android.xml.AndroidManifest;
-
-import org.eclipse.core.filebuffers.ITextFileBufferManager;
-import org.eclipse.core.filebuffers.LocationKind;
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.jface.text.IDocument;
-import org.eclipse.ltk.core.refactoring.Change;
-import org.eclipse.text.edits.MultiTextEdit;
-import org.eclipse.text.edits.TextEdit;
-
-import java.util.Map;
-import java.util.Set;
-
-/**
- * A text change that operates on android manifest when execute Java Rename package refactoring
-*/
-public class AndroidPackageRenameChange extends AndroidDocumentChange {
-
- private boolean mIsPackage;
-
- /**
- * Creates a new <code>AndroidPackageRenameChange</code>
- *
- * @param androidManifest the android manifest file
- * @param manager the text buffer manager
- * @param document the document
- * @param elements the elements
- * @param newName the new name
- * @param oldName the old name
- * @param isPackage is the application package
- */
- public AndroidPackageRenameChange(IFile androidManifest, ITextFileBufferManager manager,
- IDocument document, Map<String, String> elements, String oldName, String newName,
- boolean isPackage) {
- super(document);
- this.mDocument = document;
- this.mIsPackage = isPackage;
- this.mElements = elements;
- this.mNewName = newName;
- this.mOldName = oldName;
- this.mManager = manager;
- this.mAndroidManifest = androidManifest;
- try {
- this.mModel = getModel(document);
- } catch (Exception ignore) {
- }
- if (mModel != null) {
- this.mAppPackage = getAppPackage();
- addEdits();
- }
- }
-
- /**
- * Adds text edits for this change
- */
- private void addEdits() {
- MultiTextEdit multiEdit = new MultiTextEdit();
-
- if (mIsPackage) {
- TextEdit edit = createTextEdit(AndroidManifest.NODE_MANIFEST,
- AndroidManifest.ATTRIBUTE_PACKAGE, mOldName, mNewName, false);
- if (edit != null) {
- multiEdit.addChild(edit);
- }
- }
- Set<String> keys = mElements.keySet();
- for (String key : keys) {
- String value = mElements.get(key);
- String oldValue = AndroidManifest.combinePackageAndClassName(mAppPackage, value);
- String newValue = oldValue.replaceFirst(mOldName, mNewName);
- TextEdit edit = createTextEdit(key, AndroidManifest.ATTRIBUTE_NAME, oldValue,
- newValue);
- if (edit != null) {
- multiEdit.addChild(edit);
- }
- if (AndroidManifest.NODE_ACTIVITY.equals(key)) {
- TextEdit alias = createTextEdit(AndroidManifest.NODE_ACTIVITY_ALIAS,
- AndroidManifest.ATTRIBUTE_TARGET_ACTIVITY, oldValue, newValue);
- if (alias != null) {
- multiEdit.addChild(alias);
- }
- }
- }
- setEdit(multiEdit);
- }
-
- @Override
- public Change perform(IProgressMonitor pm) throws CoreException {
- super.perform(pm);
- return new AndroidPackageRenameChange(mAndroidManifest, mManager, mDocument, mElements,
- mOldName, mNewName, mIsPackage);
- }
-
- @Override
- public void dispose() {
- super.dispose();
- RefactoringUtil.fixModel(mModel, mDocument);
-
- if (mManager != null) {
- try {
- mManager.disconnect(mAndroidManifest.getFullPath(), LocationKind.NORMALIZE,
- new NullProgressMonitor());
- } catch (CoreException e) {
- RefactoringUtil.log(e);
- }
- }
- if (mIsPackage) {
- new FixImportsJob("Fix Rename Package", mAndroidManifest, mNewName).schedule(500);
- }
- }
-
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/changes/AndroidTypeMoveChange.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/changes/AndroidTypeMoveChange.java
deleted file mode 100644
index 618500d..0000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/changes/AndroidTypeMoveChange.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.refactorings.changes;
-
-import org.eclipse.core.filebuffers.ITextFileBufferManager;
-import org.eclipse.core.resources.IFile;
-import org.eclipse.jface.text.IDocument;
-
-import java.util.Map;
-
-/**
- * A text change that operates on android manifest when execute Java Move type refactoring
-*/
-public class AndroidTypeMoveChange extends AndroidTypeRenameChange {
-
- /**
- * Creates a new <code>AndroidTypeMoveChange</code>
- *
- * @param androidManifest the android manifest file
- * @param manager the text buffer manager
- * @param document the document
- * @param elements the elements
- * @param newName the new name
- * @param oldName the old name
- */
- public AndroidTypeMoveChange(IFile androidManifest, ITextFileBufferManager manager,
- IDocument document, Map<String, String> elements, String oldName, String newName) {
- super(androidManifest, manager, document, elements, oldName, newName);
- }
-
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/changes/AndroidTypeRenameChange.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/changes/AndroidTypeRenameChange.java
deleted file mode 100644
index 275d412..0000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/changes/AndroidTypeRenameChange.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.refactorings.changes;
-
-import com.android.ide.eclipse.adt.internal.refactorings.core.RefactoringUtil;
-import com.android.xml.AndroidManifest;
-
-import org.eclipse.core.filebuffers.ITextFileBufferManager;
-import org.eclipse.core.filebuffers.LocationKind;
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.jface.text.IDocument;
-import org.eclipse.ltk.core.refactoring.Change;
-import org.eclipse.text.edits.MultiTextEdit;
-import org.eclipse.text.edits.TextEdit;
-
-import java.util.Map;
-import java.util.Set;
-
-/**
- * A text change that operates on android manifest when execute Java Rename type refactoring
-*/
-public class AndroidTypeRenameChange extends AndroidDocumentChange {
-
- /**
- * * Creates a new <code>AndroidTypeRenameChange</code>
- *
- * @param androidManifest the android manifest file
- * @param manager the text buffer manager
- * @param document the document
- * @param elements the elements
- * @param newName the new name
- * @param oldName the old name
- */
- public AndroidTypeRenameChange(IFile androidManifest, ITextFileBufferManager manager,
- IDocument document, Map<String, String> elements, String oldName, String newName) {
- super(document);
- this.mDocument = document;
- this.mElements = elements;
- this.mOldName = oldName;
- this.mNewName = newName;
- this.mManager = manager;
- this.mAndroidManifest = androidManifest;
- try {
- this.mModel = getModel(document);
- } catch (Exception ignore) {
- }
- if (mModel != null) {
- addEdits();
- }
- }
-
- /**
- * Adds text edits for this change
- */
- private void addEdits() {
- MultiTextEdit multiEdit = new MultiTextEdit();
- Set<String> keys = mElements.keySet();
- for (String key : keys) {
- TextEdit edit = createTextEdit(key, AndroidManifest.ATTRIBUTE_NAME, mOldName,
- mNewName);
- if (edit != null) {
- multiEdit.addChild(edit);
- }
- if (AndroidManifest.NODE_ACTIVITY.equals(key)) {
- TextEdit alias = createTextEdit(AndroidManifest.NODE_ACTIVITY_ALIAS,
- AndroidManifest.ATTRIBUTE_TARGET_ACTIVITY, mOldName, mNewName);
- if (alias != null) {
- multiEdit.addChild(alias);
- }
- TextEdit manageSpaceActivity = createTextEdit(
- AndroidManifest.NODE_APPLICATION,
- AndroidManifest.ATTRIBUTE_MANAGE_SPACE_ACTIVITY, mOldName, mNewName);
- if (manageSpaceActivity != null) {
- multiEdit.addChild(manageSpaceActivity);
- }
- }
- }
- setEdit(multiEdit);
- }
-
- @Override
- public Change perform(IProgressMonitor pm) throws CoreException {
- super.perform(pm);
- return new AndroidTypeRenameChange(mAndroidManifest, mManager, mDocument, mElements,
- mOldName, mNewName);
- }
-
- @Override
- public void dispose() {
- super.dispose();
- RefactoringUtil.fixModel(mModel, mDocument);
-
- if (mManager != null) {
- try {
- mManager.disconnect(mAndroidManifest.getFullPath(), LocationKind.NORMALIZE,
- new NullProgressMonitor());
- } catch (CoreException e) {
- RefactoringUtil.log(e);
- }
- }
- }
-
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/core/AndroidPackageRenameParticipant.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/core/AndroidPackageRenameParticipant.java
index bd3224d..67f7d44 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/core/AndroidPackageRenameParticipant.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/core/AndroidPackageRenameParticipant.java
@@ -16,20 +16,26 @@
package com.android.ide.eclipse.adt.internal.refactorings.core;
+import static com.android.SdkConstants.ANDROID_URI;
+import static com.android.SdkConstants.ATTR_CLASS;
+import static com.android.SdkConstants.ATTR_CONTEXT;
+import static com.android.SdkConstants.ATTR_NAME;
+import static com.android.SdkConstants.ATTR_PACKAGE;
+import static com.android.SdkConstants.DOT_XML;
+import static com.android.SdkConstants.EXT_XML;
+import static com.android.SdkConstants.TOOLS_URI;
+import static com.android.SdkConstants.VIEW_FRAGMENT;
+import static com.android.SdkConstants.VIEW_TAG;
+
import com.android.SdkConstants;
+import com.android.annotations.NonNull;
import com.android.ide.common.xml.ManifestData;
import com.android.ide.eclipse.adt.AdtConstants;
+import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.internal.project.AndroidManifestHelper;
-import com.android.ide.eclipse.adt.internal.refactorings.changes.AndroidLayoutChange;
-import com.android.ide.eclipse.adt.internal.refactorings.changes.AndroidLayoutChangeDescription;
-import com.android.ide.eclipse.adt.internal.refactorings.changes.AndroidLayoutFileChanges;
-import com.android.ide.eclipse.adt.internal.refactorings.changes.AndroidPackageRenameChange;
-import com.android.xml.AndroidManifest;
-
-import org.eclipse.core.filebuffers.FileBuffers;
-import org.eclipse.core.filebuffers.ITextFileBuffer;
-import org.eclipse.core.filebuffers.ITextFileBufferManager;
-import org.eclipse.core.filebuffers.LocationKind;
+import com.android.resources.ResourceFolderType;
+import com.android.utils.SdkUtils;
+
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
@@ -37,34 +43,39 @@ import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragment;
-import org.eclipse.jdt.core.IType;
-import org.eclipse.jdt.core.ITypeHierarchy;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.internal.corext.refactoring.changes.RenamePackageChange;
-import org.eclipse.jface.text.IDocument;
+import org.eclipse.jdt.internal.corext.refactoring.rename.RenameCompilationUnitProcessor;
+import org.eclipse.jdt.internal.corext.refactoring.rename.RenameTypeProcessor;
import org.eclipse.ltk.core.refactoring.Change;
import org.eclipse.ltk.core.refactoring.CompositeChange;
+import org.eclipse.ltk.core.refactoring.NullChange;
+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.RefactoringProcessor;
+import org.eclipse.ltk.core.refactoring.participants.RenameParticipant;
+import org.eclipse.text.edits.MultiTextEdit;
+import org.eclipse.text.edits.ReplaceEdit;
+import org.eclipse.text.edits.TextEdit;
import org.eclipse.wst.sse.core.StructuredModelManager;
+import org.eclipse.wst.sse.core.internal.provisional.IModelManager;
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
-import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
import org.w3c.dom.Attr;
+import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
+import java.io.IOException;
import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
import java.util.List;
-import java.util.Map;
-import java.util.Set;
/**
* A participant to participate in refactorings that rename a package in an Android project.
@@ -78,13 +89,81 @@ import java.util.Set;
* </p>
*/
@SuppressWarnings("restriction")
-public class AndroidPackageRenameParticipant extends AndroidRenameParticipant {
+public class AndroidPackageRenameParticipant extends RenameParticipant {
+ private IProject mProject;
+ private IFile mManifestFile;
private IPackageFragment mPackageFragment;
+ private String mOldPackage;
+ private String mNewPackage;
+ private String mAppPackage;
+ private boolean mRefactoringAppPackage;
- private boolean mIsPackage;
+ @Override
+ public String getName() {
+ return "Android Package Rename";
+ }
+
+ @Override
+ public RefactoringStatus checkConditions(IProgressMonitor pm, CheckConditionsContext context)
+ throws OperationCanceledException {
+ return new RefactoringStatus();
+ }
+
+ @Override
+ protected boolean initialize(final Object element) {
+ mRefactoringAppPackage = false;
+ try {
+ // Only propose this refactoring if the "Update References" checkbox is set.
+ if (!getArguments().getUpdateReferences()) {
+ return false;
+ }
+
+ if (element instanceof IPackageFragment) {
+ mPackageFragment = (IPackageFragment) element;
+ if (!mPackageFragment.containsJavaResources()) {
+ return false;
+ }
+ IJavaProject javaProject = (IJavaProject) mPackageFragment
+ .getAncestor(IJavaElement.JAVA_PROJECT);
+ mProject = javaProject.getProject();
+ IResource manifestResource = mProject.findMember(AdtConstants.WS_SEP
+ + SdkConstants.FN_ANDROID_MANIFEST_XML);
+
+ if (manifestResource == null || !manifestResource.exists()
+ || !(manifestResource instanceof IFile)) {
+ RefactoringUtil.logInfo("Invalid or missing the "
+ + SdkConstants.FN_ANDROID_MANIFEST_XML + " in the "
+ + mProject.getName() + " project.");
+ return false;
+ }
+ mManifestFile = (IFile) manifestResource;
+ String packageName = mPackageFragment.getElementName();
+ ManifestData manifestData;
+ manifestData = AndroidManifestHelper.parseForData(mManifestFile);
+ if (manifestData == null) {
+ return false;
+ }
+ mAppPackage = manifestData.getPackage();
+ mOldPackage = packageName;
+ mNewPackage = getArguments().getNewName();
+ if (mOldPackage == null || mNewPackage == null) {
+ return false;
+ }
+
+ if (RefactoringUtil.isRefactorAppPackage()
+ && mAppPackage != null
+ && mAppPackage.equals(packageName)) {
+ mRefactoringAppPackage = true;
+ }
+
+ return true;
+ }
+ } catch (JavaModelException ignore) {
+ }
+ return false;
+ }
- private Set<AndroidLayoutFileChanges> mFileChanges = new HashSet<AndroidLayoutFileChanges>();
@Override
public Change createChange(IProgressMonitor pm) throws CoreException,
@@ -92,50 +171,61 @@ public class AndroidPackageRenameParticipant extends AndroidRenameParticipant {
if (pm.isCanceled()) {
return null;
}
- if (!getArguments().getUpdateReferences())
+ if (!getArguments().getUpdateReferences()) {
return null;
+ }
+
+ RefactoringProcessor p = getProcessor();
+ if (p instanceof RenameCompilationUnitProcessor) {
+ RenameTypeProcessor rtp =
+ ((RenameCompilationUnitProcessor) p).getRenameTypeProcessor();
+ if (rtp != null) {
+ String pattern = rtp.getFilePatterns();
+ boolean updQualf = rtp.getUpdateQualifiedNames();
+ if (updQualf && pattern != null && pattern.contains("xml")) { //$NON-NLS-1$
+ // Do not propose this refactoring if the
+ // "Update fully qualified names in non-Java files" option is
+ // checked and the file patterns mention XML. [c.f. SDK bug 21589]
+ return null;
+ }
+ }
+ }
+
IPath pkgPath = mPackageFragment.getPath();
- IJavaProject javaProject = (IJavaProject) mPackageFragment
- .getAncestor(IJavaElement.JAVA_PROJECT);
- IProject project = javaProject.getProject();
- IPath genPath = project.getFullPath().append(SdkConstants.FD_GEN_SOURCES);
+ IPath genPath = mProject.getFullPath().append(SdkConstants.FD_GEN_SOURCES);
if (genPath.isPrefixOf(pkgPath)) {
RefactoringUtil.logInfo(getName() + ": Cannot rename generated package.");
return null;
}
CompositeChange result = new CompositeChange(getName());
result.markAsSynthetic();
- if (mAndroidManifest.exists()) {
- if (mAndroidElements.size() > 0 || mIsPackage) {
- getManifestDocument();
- Change change = new AndroidPackageRenameChange(mAndroidManifest, mManager,
- mDocument, mAndroidElements, mOldName, mNewName, mIsPackage);
- if (change != null) {
- result.add(change);
- }
- }
- if (mIsPackage) {
- Change genChange = getGenPackageChange(pm);
- if (genChange != null) {
- result.add(genChange);
- }
+
+ addManifestFileChanges(result);
+
+ // Update layout files; we don't just need to react to custom view
+ // changes, we need to update fragment references and even tool:context activity
+ // references
+ addLayoutFileChanges(result);
+
+ if (mRefactoringAppPackage) {
+ Change genChange = getGenPackageChange(pm);
+ if (genChange != null) {
+ result.add(genChange);
}
- // add layoutChange
- for (AndroidLayoutFileChanges fileChange : mFileChanges) {
- IFile file = fileChange.getFile();
- ITextFileBufferManager lManager = FileBuffers.getTextFileBufferManager();
- lManager.connect(file.getFullPath(), LocationKind.NORMALIZE,
- new NullProgressMonitor());
- ITextFileBuffer buffer = lManager.getTextFileBuffer(file.getFullPath(),
- LocationKind.NORMALIZE);
- IDocument lDocument = buffer.getDocument();
- Change layoutChange = new AndroidLayoutChange(file, lDocument, lManager,
- fileChange.getChanges());
- if (layoutChange != null) {
- result.add(layoutChange);
+
+ return new NullChange("Update Imports") {
+ @Override
+ public Change perform(IProgressMonitor monitor) throws CoreException {
+ FixImportsJob job = new FixImportsJob("Fix Rename Package",
+ mManifestFile, mNewPackage);
+ job.schedule(500);
+
+ // Not undoable: just return null instead of an undo-change.
+ return null;
}
- }
+ };
}
+
return (result.getChildren().length == 0) ? null : result;
}
@@ -145,15 +235,15 @@ public class AndroidPackageRenameParticipant extends AndroidRenameParticipant {
* @param pm the progress monitor
*
* @return Android gen package text change
- * @throws CoreException
- * @throws OperationCanceledException
+ * @throws CoreException if an error happens
+ * @throws OperationCanceledException if the operation is canceled
*/
public Change getGenPackageChange(IProgressMonitor pm) throws CoreException,
OperationCanceledException {
- if (mIsPackage) {
+ if (mRefactoringAppPackage) {
IPackageFragment genJavaPackageFragment = getGenPackageFragment();
if (genJavaPackageFragment != null && genJavaPackageFragment.exists()) {
- return new RenamePackageChange(genJavaPackageFragment, mNewName, true);
+ return new RenamePackageChange(genJavaPackageFragment, mNewPackage, true);
}
}
return null;
@@ -161,7 +251,6 @@ public class AndroidPackageRenameParticipant extends AndroidRenameParticipant {
/**
* Return the gen package fragment
- *
*/
private IPackageFragment getGenPackageFragment() throws JavaModelException {
IJavaProject javaProject = (IJavaProject) mPackageFragment
@@ -170,7 +259,7 @@ public class AndroidPackageRenameParticipant extends AndroidRenameParticipant {
IProject project = javaProject.getProject();
IFolder genFolder = project.getFolder(SdkConstants.FD_GEN_SOURCES);
if (genFolder.exists()) {
- String javaPackagePath = mAppPackage.replace(".", "/");
+ String javaPackagePath = mAppPackage.replace('.', '/');
IPath genJavaPackagePath = genFolder.getFullPath().append(javaPackagePath);
IPackageFragment genPackageFragment = javaProject
.findPackageFragment(genJavaPackagePath);
@@ -180,123 +269,53 @@ public class AndroidPackageRenameParticipant extends AndroidRenameParticipant {
return null;
}
- @Override
- public String getName() {
- return "Android Package Rename";
+ /**
+ * Returns the new class name
+ *
+ * @param fqcn the fully qualified class name in the renamed package
+ * @return the new class name
+ */
+ private String getNewClassName(String fqcn) {
+ assert isInRenamedPackage(fqcn) : fqcn;
+ int lastDot = fqcn.lastIndexOf('.');
+ if (lastDot < 0) {
+ return mNewPackage;
+ }
+ String name = fqcn.substring(lastDot, fqcn.length());
+ String newClassName = mNewPackage + name;
+ return newClassName;
}
- @Override
- protected boolean initialize(final Object element) {
- mIsPackage = false;
+ private void addManifestFileChanges(CompositeChange result) {
+ addXmlFileChanges(mManifestFile, result, true);
+ }
+
+ private void addLayoutFileChanges(CompositeChange result) {
try {
- if (element instanceof IPackageFragment) {
- mPackageFragment = (IPackageFragment) element;
- if (!mPackageFragment.containsJavaResources())
- return false;
- IJavaProject javaProject = (IJavaProject) mPackageFragment
- .getAncestor(IJavaElement.JAVA_PROJECT);
- IProject project = javaProject.getProject();
- IResource manifestResource = project.findMember(AdtConstants.WS_SEP
- + SdkConstants.FN_ANDROID_MANIFEST_XML);
+ // Update references in XML resource files
+ IFolder resFolder = mProject.getFolder(SdkConstants.FD_RESOURCES);
- if (manifestResource == null || !manifestResource.exists()
- || !(manifestResource instanceof IFile)) {
- RefactoringUtil.logInfo("Invalid or missing the "
- + SdkConstants.FN_ANDROID_MANIFEST_XML + " in the " + project.getName()
- + " project.");
- return false;
+ IResource[] folders = resFolder.members();
+ for (IResource folder : folders) {
+ String folderName = folder.getName();
+ ResourceFolderType folderType = ResourceFolderType.getFolderType(folderName);
+ if (folderType != ResourceFolderType.LAYOUT) {
+ continue;
}
- mAndroidManifest = (IFile) manifestResource;
- String packageName = mPackageFragment.getElementName();
- ManifestData manifestData;
- manifestData = AndroidManifestHelper.parseForData(mAndroidManifest);
- if (manifestData == null) {
- return false;
- }
- mAppPackage = manifestData.getPackage();
- mOldName = packageName;
- mNewName = getArguments().getNewName();
- if (mOldName == null || mNewName == null) {
- return false;
+ if (!(folder instanceof IFolder)) {
+ continue;
}
+ IResource[] files = ((IFolder) folder).members();
+ for (int i = 0; i < files.length; i++) {
+ IResource member = files[i];
+ if ((member instanceof IFile) && member.exists()) {
+ IFile file = (IFile) member;
+ String fileName = member.getName();
- if (RefactoringUtil.isRefactorAppPackage()
- && mAppPackage != null
- && mAppPackage.equals(packageName)) {
- mIsPackage = true;
- }
- mAndroidElements = addAndroidElements();
-
- try {
- final IType type = javaProject.findType(SdkConstants.CLASS_VIEW);
- final HashSet<IType> elements = new HashSet<IType>();
- if (type != null) {
- ITypeHierarchy hierarchy = type.newTypeHierarchy(
- new NullProgressMonitor());
- IType[] allSubtypes = hierarchy.getAllSubtypes(type);
- for (IType subType : allSubtypes) {
- IResource resource = subType.getResource();
- // TODO: Handle library project downstream dependencies!
- if (resource != null && project.equals(resource.getProject())) {
- if (subType.getPackageFragment().equals(mPackageFragment)) {
- elements.add(subType);
- }
- }
+ if (SdkUtils.endsWith(fileName, DOT_XML)) {
+ addXmlFileChanges(file, result, false);
}
}
-
- List<String> views = new ArrayList<String>();
- for (IType elem : elements) {
- views.add(elem.getFullyQualifiedName());
- }
- if (views.size() > 0) {
- String[] classNames = views.toArray(new String[0]);
- addLayoutChanges(project, classNames);
- }
- } catch (CoreException e) {
- RefactoringUtil.log(e);
- }
-
- return mIsPackage || mAndroidElements.size() > 0 || mFileChanges.size() > 0;
- }
- } catch (JavaModelException ignore) {
- }
- return false;
- }
-
- /**
- * Adds layout changes for project
- *
- * @param project the Android project
- * @param classNames the layout classes
- */
- private void addLayoutChanges(IProject project, String[] classNames) {
- try {
- IFolder resFolder = project.getFolder(SdkConstants.FD_RESOURCES);
- IResource[] layoutMembers = resFolder.members();
- for (int j = 0; j < layoutMembers.length; j++) {
- IResource resource = layoutMembers[j];
- if (resource instanceof IFolder
- && resource.exists()
- && resource.getName().startsWith(SdkConstants.FD_RES_LAYOUT)) {
- IFolder layoutFolder = (IFolder) resource;
- IResource[] members = layoutFolder.members();
- for (int i = 0; i < members.length; i++) {
- IResource member = members[i];
- if ((member instanceof IFile)
- && member.exists()
- && member.getName().endsWith(".xml")) { //$NON-NLS-1$
- IFile file = (IFile) member;
- Set<AndroidLayoutChangeDescription> changes =
- parse(file, classNames);
- if (changes.size() > 0) {
- AndroidLayoutFileChanges fileChange =
- new AndroidLayoutFileChanges(file);
- fileChange.getChanges().addAll(changes);
- mFileChanges.add(fileChange);
- }
- }
- }
}
}
} catch (CoreException e) {
@@ -304,211 +323,164 @@ public class AndroidPackageRenameParticipant extends AndroidRenameParticipant {
}
}
- /**
- * Searches the layout file for classes
- *
- * @param file the Android layout file
- * @param classNames the layout classes
- */
- private Set<AndroidLayoutChangeDescription> parse(IFile file, String[] classNames) {
- Set<AndroidLayoutChangeDescription> changes =
- new HashSet<AndroidLayoutChangeDescription>();
- ITextFileBufferManager lManager = null;
+ private boolean addXmlFileChanges(IFile file, CompositeChange changes, boolean isManifest) {
+ IModelManager modelManager = StructuredModelManager.getModelManager();
+ IStructuredModel model = null;
try {
- lManager = FileBuffers.getTextFileBufferManager();
- lManager.connect(file.getFullPath(),
- LocationKind.NORMALIZE, new NullProgressMonitor());
- ITextFileBuffer buffer = lManager.getTextFileBuffer(file.getFullPath(),
- LocationKind.NORMALIZE);
- IDocument lDocument = buffer.getDocument();
- IStructuredModel model = null;
- try {
- model = StructuredModelManager.getModelManager().
- getExistingModelForRead(lDocument);
- if (model == null) {
- if (lDocument instanceof IStructuredDocument) {
- IStructuredDocument structuredDocument = (IStructuredDocument) lDocument;
- model = StructuredModelManager.getModelManager().getModelForRead(
- structuredDocument);
- }
- }
- if (model != null) {
- IDOMModel xmlModel = (IDOMModel) model;
- IDOMDocument xmlDoc = xmlModel.getDocument();
- NodeList nodes = xmlDoc.getElementsByTagName(SdkConstants.VIEW);
- for (int i = 0; i < nodes.getLength(); i++) {
- Node node = nodes.item(i);
- NamedNodeMap attributes = node.getAttributes();
- if (attributes != null) {
- Node attributeNode = attributes
- .getNamedItem(SdkConstants.ATTR_CLASS);
- if (attributeNode instanceof Attr) {
- Attr attribute = (Attr) attributeNode;
- String value = attribute.getValue();
- if (value != null) {
- for (int j = 0; j < classNames.length; j++) {
- String className = classNames[j];
- if (value.equals(className)) {
- String newClassName = getNewClassName(className);
- AndroidLayoutChangeDescription layoutChange =
- new AndroidLayoutChangeDescription(
- className, newClassName,
- AndroidLayoutChangeDescription.VIEW_TYPE);
- changes.add(layoutChange);
- }
- }
- }
- }
+ model = modelManager.getExistingModelForRead(file);
+ if (model == null) {
+ model = modelManager.getModelForRead(file);
+ }
+ if (model != null) {
+ IStructuredDocument document = model.getStructuredDocument();
+ if (model instanceof IDOMModel) {
+ IDOMModel domModel = (IDOMModel) model;
+ Element root = domModel.getDocument().getDocumentElement();
+ if (root != null) {
+ List<TextEdit> edits = new ArrayList<TextEdit>();
+ if (isManifest) {
+ addManifestReplacements(edits, root, document);
+ } else {
+ addLayoutReplacements(edits, root, document);
}
- }
- for (int j = 0; j < classNames.length; j++) {
- String className = classNames[j];
- nodes = xmlDoc.getElementsByTagName(className);
- for (int i = 0; i < nodes.getLength(); i++) {
- String newClassName = getNewClassName(className);
- AndroidLayoutChangeDescription layoutChange =
- new AndroidLayoutChangeDescription(
- className, newClassName,
- AndroidLayoutChangeDescription.STANDALONE_TYPE);
- changes.add(layoutChange);
+ if (!edits.isEmpty()) {
+ MultiTextEdit rootEdit = new MultiTextEdit();
+ rootEdit.addChildren(edits.toArray(new TextEdit[edits.size()]));
+ TextFileChange change = new TextFileChange(file.getName(), file);
+ change.setTextType(EXT_XML);
+ change.setEdit(rootEdit);
+ changes.add(change);
}
}
- }
- } finally {
- if (model != null) {
- model.releaseFromRead();
+ } else {
+ return false;
}
}
- } catch (CoreException ignore) {
+ return true;
+ } catch (IOException e) {
+ AdtPlugin.log(e, null);
+ } catch (CoreException e) {
+ AdtPlugin.log(e, null);
} finally {
- if (lManager != null) {
- try {
- lManager.disconnect(file.getFullPath(), LocationKind.NORMALIZE,
- new NullProgressMonitor());
- } catch (CoreException ignore) {
- }
+ if (model != null) {
+ model.releaseFromRead();
}
}
- return changes;
- }
- /**
- * Returns the new class name
- *
- * @param className the class name
- * @return the new class name
- */
- private String getNewClassName(String className) {
- int lastDot = className.lastIndexOf("."); //$NON-NLS-1$
- if (lastDot < 0) {
- return mNewName;
- }
- String name = className.substring(lastDot, className.length());
- String newClassName = mNewName + name;
- return newClassName;
+ return false;
}
- /**
- * Returns the elements (activity, receiver, service ...)
- * which have to be renamed
- *
- * @return the android elements
- */
- private Map<String, String> addAndroidElements() {
- Map<String, String> androidElements = new HashMap<String, String>();
+ private boolean isInRenamedPackage(String fqcn) {
+ return fqcn.startsWith(mOldPackage)
+ && fqcn.length() > mOldPackage.length()
+ && fqcn.indexOf('.', mOldPackage.length() + 1) == -1;
+ }
- IDocument document;
- try {
- document = getManifestDocument();
- } catch (CoreException e) {
- RefactoringUtil.log(e);
- if (mManager != null) {
- try {
- mManager.disconnect(mAndroidManifest.getFullPath(), LocationKind.NORMALIZE,
- new NullProgressMonitor());
- } catch (CoreException e1) {
- RefactoringUtil.log(e1);
+ private void addLayoutReplacements(
+ @NonNull List<TextEdit> edits,
+ @NonNull Element element,
+ @NonNull IStructuredDocument document) {
+ String tag = element.getTagName();
+ if (isInRenamedPackage(tag)) {
+ int start = RefactoringUtil.getTagNameRangeStart(element, document);
+ if (start != -1) {
+ int end = start + tag.length();
+ edits.add(new ReplaceEdit(start, end - start, getNewClassName(tag)));
+ }
+ } else {
+ Attr classNode = null;
+ if (tag.equals(VIEW_TAG)) {
+ classNode = element.getAttributeNode(ATTR_CLASS);
+ } else if (tag.equals(VIEW_FRAGMENT)) {
+ classNode = element.getAttributeNodeNS(ANDROID_URI, ATTR_NAME);
+ } else if (element.hasAttributeNS(TOOLS_URI, ATTR_CONTEXT)) {
+ classNode = element.getAttributeNodeNS(TOOLS_URI, ATTR_CONTEXT);
+ if (classNode != null && classNode.getValue().startsWith(".")) { //$NON-NLS-1$
+ classNode = null;
}
}
- document = null;
- return androidElements;
- }
-
- IStructuredModel model = null;
- try {
- model = StructuredModelManager.getModelManager().getExistingModelForRead(document);
- if (model == null) {
- if (document instanceof IStructuredDocument) {
- IStructuredDocument structuredDocument = (IStructuredDocument) document;
- model = StructuredModelManager.getModelManager().getModelForRead(
- structuredDocument);
+ if (classNode != null) {
+ String fqcn = classNode.getValue();
+ if (isInRenamedPackage(fqcn)) {
+ int start = RefactoringUtil.getAttributeValueRangeStart(classNode, document);
+ if (start != -1) {
+ int end = start + fqcn.length();
+ edits.add(new ReplaceEdit(start, end - start, getNewClassName(fqcn)));
+ }
}
}
- if (model != null) {
- IDOMModel xmlModel = (IDOMModel) model;
- IDOMDocument xmlDoc = xmlModel.getDocument();
- add(xmlDoc, androidElements, AndroidManifest.NODE_ACTIVITY,
- AndroidManifest.ATTRIBUTE_NAME);
- add(xmlDoc, androidElements, AndroidManifest.NODE_APPLICATION,
- AndroidManifest.ATTRIBUTE_NAME);
- add(xmlDoc, androidElements, AndroidManifest.NODE_PROVIDER,
- AndroidManifest.ATTRIBUTE_NAME);
- add(xmlDoc, androidElements, AndroidManifest.NODE_RECEIVER,
- AndroidManifest.ATTRIBUTE_NAME);
- add(xmlDoc, androidElements, AndroidManifest.NODE_SERVICE,
- AndroidManifest.ATTRIBUTE_NAME);
+ }
+
+ NodeList children = element.getChildNodes();
+ for (int i = 0, n = children.getLength(); i < n; i++) {
+ Node child = children.item(i);
+ if (child.getNodeType() == Node.ELEMENT_NODE) {
+ addLayoutReplacements(edits, (Element) child, document);
}
- } finally {
- if (model != null) {
- model.releaseFromRead();
+ }
+ }
+
+ private void addManifestReplacements(
+ @NonNull List<TextEdit> edits,
+ @NonNull Element element,
+ @NonNull IStructuredDocument document) {
+ if (mRefactoringAppPackage &&
+ element == element.getOwnerDocument().getDocumentElement()) {
+ // Update the app package declaration
+ Attr pkg = element.getAttributeNode(ATTR_PACKAGE);
+ if (pkg != null && pkg.getValue().equals(mOldPackage)) {
+ int start = RefactoringUtil.getAttributeValueRangeStart(pkg, document);
+ if (start != -1) {
+ int end = start + mOldPackage.length();
+ edits.add(new ReplaceEdit(start, end - start, mNewPackage));
+ }
}
}
- return androidElements;
- }
+ NamedNodeMap attributes = element.getAttributes();
+ for (int i = 0, n = attributes.getLength(); i < n; i++) {
+ Attr attr = (Attr) attributes.item(i);
+ if (!RefactoringUtil.isManifestClassAttribute(attr)) {
+ continue;
+ }
- /**
- * Adds the element (activity, receiver, service ...) to the map
- *
- * @param xmlDoc the document
- * @param androidElements the map
- * @param element the element
- */
- private void add(IDOMDocument xmlDoc, Map<String, String> androidElements, String element,
- String argument) {
- NodeList nodes = xmlDoc.getElementsByTagName(element);
- for (int i = 0; i < nodes.getLength(); i++) {
- Node node = nodes.item(i);
- NamedNodeMap attributes = node.getAttributes();
- if (attributes != null) {
- Attr attribute = RefactoringUtil.findAndroidAttributes(attributes, argument);
- if (attribute != null) {
- String value = attribute.getValue();
- if (value != null) {
- String fullName = AndroidManifest.combinePackageAndClassName(mAppPackage,
- value);
- if (RefactoringUtil.isRefactorAppPackage()) {
- if (fullName != null && fullName.startsWith(mAppPackage)) {
- boolean startWithDot = (value.charAt(0) == '.');
- boolean hasDot = (value.indexOf('.') != -1);
- if (!startWithDot && hasDot) {
- androidElements.put(element, value);
- }
- }
- } else {
- if (fullName != null) {
- String currentPackage = mPackageFragment.getElementName();
- if (fullName.lastIndexOf('.') == currentPackage.length()
- && fullName.startsWith(currentPackage)) {
- androidElements.put(element, value);
- }
- }
+ String value = attr.getValue();
+ if (isInRenamedPackage(value)) {
+ int start = RefactoringUtil.getAttributeValueRangeStart(attr, document);
+ if (start != -1) {
+ int end = start + value.length();
+ edits.add(new ReplaceEdit(start, end - start, getNewClassName(value)));
+ }
+ } else if (value.startsWith(".")) {
+ // If we're renaming the app package
+ String fqcn = mAppPackage + value;
+ if (isInRenamedPackage(fqcn)) {
+ int start = RefactoringUtil.getAttributeValueRangeStart(attr, document);
+ if (start != -1) {
+ int end = start + value.length();
+ String newClassName = getNewClassName(fqcn);
+ if (mRefactoringAppPackage) {
+ newClassName = newClassName.substring(mNewPackage.length());
+ } else if (newClassName.startsWith(mOldPackage)
+ && newClassName.charAt(mOldPackage.length()) == '.') {
+ newClassName = newClassName.substring(mOldPackage.length());
+ }
+
+ if (!newClassName.equals(value)) {
+ edits.add(new ReplaceEdit(start, end - start, newClassName));
}
}
}
}
}
- }
+ NodeList children = element.getChildNodes();
+ for (int i = 0, n = children.getLength(); i < n; i++) {
+ Node child = children.item(i);
+ if (child.getNodeType() == Node.ELEMENT_NODE) {
+ addManifestReplacements(edits, (Element) child, document);
+ }
+ }
+ }
}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/core/AndroidRenameParticipant.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/core/AndroidRenameParticipant.java
deleted file mode 100644
index dca43a1..0000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/core/AndroidRenameParticipant.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.refactorings.core;
-
-import org.eclipse.core.filebuffers.FileBuffers;
-import org.eclipse.core.filebuffers.ITextFileBuffer;
-import org.eclipse.core.filebuffers.ITextFileBufferManager;
-import org.eclipse.core.filebuffers.LocationKind;
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.core.runtime.OperationCanceledException;
-import org.eclipse.jface.text.IDocument;
-import org.eclipse.ltk.core.refactoring.RefactoringStatus;
-import org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext;
-import org.eclipse.ltk.core.refactoring.participants.RenameParticipant;
-
-import java.util.Map;
-
-/**
- * The abstract class for Rename Package and Rename type participants
- *
- */
-public abstract class AndroidRenameParticipant extends RenameParticipant {
-
- protected IFile mAndroidManifest;
-
- protected ITextFileBufferManager mManager;
-
- protected String mOldName;
-
- protected String mNewName;
-
- protected IDocument mDocument;
-
- protected String mAppPackage;
-
- protected Map<String, String> mAndroidElements;
-
- @Override
- public RefactoringStatus checkConditions(IProgressMonitor pm, CheckConditionsContext context)
- throws OperationCanceledException {
- return new RefactoringStatus();
- }
-
- /**
- * @return the document for the {@link #mAndroidManifest}
- * @throws CoreException
- */
- public IDocument getManifestDocument() throws CoreException {
- if (mDocument == null) {
- mManager = FileBuffers.getTextFileBufferManager();
- mManager.connect(mAndroidManifest.getFullPath(),
- LocationKind.NORMALIZE,
- new NullProgressMonitor());
- ITextFileBuffer buffer = mManager.getTextFileBuffer(
- mAndroidManifest.getFullPath(),
- LocationKind.NORMALIZE);
- mDocument = buffer.getDocument();
- }
- return mDocument;
- }
-
- /**
- * @return the android manifest file
- */
- public IFile getAndroidManifest() {
- return mAndroidManifest;
- }
-
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/core/AndroidTypeMoveParticipant.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/core/AndroidTypeMoveParticipant.java
index 287139a..26ae8d0 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/core/AndroidTypeMoveParticipant.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/core/AndroidTypeMoveParticipant.java
@@ -16,55 +16,60 @@
package com.android.ide.eclipse.adt.internal.refactorings.core;
+import static com.android.SdkConstants.ANDROID_URI;
+import static com.android.SdkConstants.ATTR_CLASS;
+import static com.android.SdkConstants.ATTR_CONTEXT;
+import static com.android.SdkConstants.ATTR_NAME;
+import static com.android.SdkConstants.DOT_XML;
+import static com.android.SdkConstants.EXT_XML;
+import static com.android.SdkConstants.TOOLS_URI;
+import static com.android.SdkConstants.VIEW_FRAGMENT;
+import static com.android.SdkConstants.VIEW_TAG;
+
import com.android.SdkConstants;
+import com.android.annotations.NonNull;
import com.android.ide.common.xml.ManifestData;
import com.android.ide.eclipse.adt.AdtConstants;
+import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.internal.project.AndroidManifestHelper;
-import com.android.ide.eclipse.adt.internal.refactorings.changes.AndroidLayoutChange;
-import com.android.ide.eclipse.adt.internal.refactorings.changes.AndroidLayoutChangeDescription;
-import com.android.ide.eclipse.adt.internal.refactorings.changes.AndroidLayoutFileChanges;
-import com.android.ide.eclipse.adt.internal.refactorings.changes.AndroidTypeMoveChange;
import com.android.resources.ResourceFolderType;
-import com.android.xml.AndroidManifest;
+import com.android.utils.SdkUtils;
-import org.eclipse.core.filebuffers.FileBuffers;
-import org.eclipse.core.filebuffers.ITextFileBuffer;
-import org.eclipse.core.filebuffers.ITextFileBufferManager;
-import org.eclipse.core.filebuffers.LocationKind;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IType;
-import org.eclipse.jdt.core.ITypeHierarchy;
import org.eclipse.jdt.core.JavaModelException;
-import org.eclipse.jface.text.IDocument;
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.MoveParticipant;
+import org.eclipse.text.edits.MultiTextEdit;
+import org.eclipse.text.edits.ReplaceEdit;
+import org.eclipse.text.edits.TextEdit;
import org.eclipse.wst.sse.core.StructuredModelManager;
+import org.eclipse.wst.sse.core.internal.provisional.IModelManager;
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
-import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
import org.w3c.dom.Attr;
+import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
/**
* A participant to participate in refactorings that move a type in an Android project.
@@ -79,21 +84,16 @@ import java.util.Set;
@SuppressWarnings("restriction")
public class AndroidTypeMoveParticipant extends MoveParticipant {
- protected IFile mAndroidManifest;
-
- protected ITextFileBufferManager mManager;
-
- protected String mOldName;
-
- protected String mNewName;
-
- protected IDocument mDocument;
-
- protected String mJavaPackage;
-
- protected Map<String, String> mAndroidElements;
+ private IProject mProject;
+ protected IFile mManifestFile;
+ protected String mOldFqcn;
+ protected String mNewFqcn;
+ protected String mAppPackage;
- private Set<AndroidLayoutFileChanges> mFileChanges = new HashSet<AndroidLayoutFileChanges>();
+ @Override
+ public String getName() {
+ return "Android Type Move";
+ }
@Override
public RefactoringStatus checkConditions(IProgressMonitor pm, CheckConditionsContext context)
@@ -102,107 +102,40 @@ public class AndroidTypeMoveParticipant extends MoveParticipant {
}
@Override
- public Change createChange(IProgressMonitor pm) throws CoreException,
- OperationCanceledException {
- if (pm.isCanceled()) {
- return null;
- }
- if (!getArguments().getUpdateReferences())
- return null;
- CompositeChange result = new CompositeChange(getName());
- if (mAndroidManifest.exists()) {
- if (mAndroidElements.size() > 0) {
- getDocument();
- Change change = new AndroidTypeMoveChange(mAndroidManifest, mManager, mDocument,
- mAndroidElements, mNewName, mOldName);
- if (change != null) {
- result.add(change);
- }
- }
-
- for (AndroidLayoutFileChanges fileChange : mFileChanges) {
- IFile file = fileChange.getFile();
- ITextFileBufferManager lManager = FileBuffers.getTextFileBufferManager();
- lManager.connect(file.getFullPath(), LocationKind.NORMALIZE,
- new NullProgressMonitor());
- ITextFileBuffer buffer = lManager.getTextFileBuffer(file.getFullPath(),
- LocationKind.NORMALIZE);
- IDocument lDocument = buffer.getDocument();
- Change layoutChange = new AndroidLayoutChange(file, lDocument, lManager,
- fileChange.getChanges());
- if (layoutChange != null) {
- result.add(layoutChange);
- }
- }
- }
- return (result.getChildren().length == 0) ? null : result;
-
- }
-
- /**
- * @return the document
- * @throws CoreException
- */
- public IDocument getDocument() throws CoreException {
- if (mDocument == null) {
- mManager = FileBuffers.getTextFileBufferManager();
- mManager.connect(mAndroidManifest.getFullPath(), LocationKind.NORMALIZE,
- new NullProgressMonitor());
- ITextFileBuffer buffer = mManager.getTextFileBuffer(mAndroidManifest.getFullPath(),
- LocationKind.NORMALIZE);
- mDocument = buffer.getDocument();
- }
- return mDocument;
- }
-
- /**
- * @return the android manifest file
- */
- public IFile getAndroidManifest() {
- return mAndroidManifest;
- }
-
- @Override
- public String getName() {
- return "Android Type Move";
- }
-
- @Override
protected boolean initialize(Object element) {
-
if (element instanceof IType) {
IType type = (IType) element;
IJavaProject javaProject = (IJavaProject) type.getAncestor(IJavaElement.JAVA_PROJECT);
- IProject project = javaProject.getProject();
- IResource manifestResource = project.findMember(AdtConstants.WS_SEP
+ mProject = javaProject.getProject();
+ IResource manifestResource = mProject.findMember(AdtConstants.WS_SEP
+ SdkConstants.FN_ANDROID_MANIFEST_XML);
if (manifestResource == null || !manifestResource.exists()
|| !(manifestResource instanceof IFile)) {
RefactoringUtil.logInfo("Invalid or missing the "
- + SdkConstants.FN_ANDROID_MANIFEST_XML + " in the " + project.getName()
+ + SdkConstants.FN_ANDROID_MANIFEST_XML + " in the " + mProject.getName()
+ " project.");
return false;
}
- mAndroidManifest = (IFile) manifestResource;
+ mManifestFile = (IFile) manifestResource;
ManifestData manifestData;
- manifestData = AndroidManifestHelper.parseForData(mAndroidManifest);
+ manifestData = AndroidManifestHelper.parseForData(mManifestFile);
if (manifestData == null) {
return false;
}
- mJavaPackage = manifestData.getPackage();
- mOldName = type.getFullyQualifiedName();
+ mAppPackage = manifestData.getPackage();
+ mOldFqcn = type.getFullyQualifiedName();
Object destination = getArguments().getDestination();
if (destination instanceof IPackageFragment) {
IPackageFragment packageFragment = (IPackageFragment) destination;
- mNewName = packageFragment.getElementName() + "." + type.getElementName();
+ mNewFqcn = packageFragment.getElementName() + "." + type.getElementName();
} else if (destination instanceof IResource) {
try {
IPackageFragment[] fragments = javaProject.getPackageFragments();
for (IPackageFragment fragment : fragments) {
IResource resource = fragment.getResource();
if (resource.equals(destination)) {
- mNewName = fragment.getElementName() + "." + type.getElementName();
+ mNewFqcn = fragment.getElementName() + '.' + type.getElementName();
break;
}
}
@@ -210,60 +143,62 @@ public class AndroidTypeMoveParticipant extends MoveParticipant {
// pass
}
}
- if (mOldName == null || mNewName == null) {
- return false;
- }
- mAndroidElements = addAndroidElements();
- try {
- ITypeHierarchy typeHierarchy = type.newSupertypeHierarchy(null);
- if (typeHierarchy == null) {
- return false;
- }
- IType[] superTypes = typeHierarchy.getAllSuperclasses(type);
- for (int i = 0; i < superTypes.length; i++) {
- IType superType = superTypes[i];
- String className = superType.getFullyQualifiedName();
- if (className.equals(SdkConstants.CLASS_VIEW)) {
- addLayoutChanges(project, type.getFullyQualifiedName());
- break;
- }
- }
- } catch (JavaModelException ignore) {
- }
- return mAndroidElements.size() > 0 || mFileChanges.size() > 0;
+ return mOldFqcn != null && mNewFqcn != null;
}
+
return false;
}
- /**
- * Adds layout changes for project
- *
- * @param project the Android project
- * @param className the layout classes
- *
- */
- private void addLayoutChanges(IProject project, String className) {
+ @Override
+ public Change createChange(IProgressMonitor pm) throws CoreException,
+ OperationCanceledException {
+ if (pm.isCanceled()) {
+ return null;
+ }
+ if (!getArguments().getUpdateReferences()) {
+ return null;
+ }
+ CompositeChange result = new CompositeChange(getName());
+ result.markAsSynthetic();
+
+ addManifestFileChanges(result);
+
+ // Update layout files; we don't just need to react to custom view
+ // changes, we need to update fragment references and even tool:context activity
+ // references
+ addLayoutFileChanges(result);
+
+ return (result.getChildren().length == 0) ? null : result;
+ }
+
+ private void addManifestFileChanges(CompositeChange result) {
+ addXmlFileChanges(mManifestFile, result, true);
+ }
+
+ private void addLayoutFileChanges(CompositeChange result) {
try {
- IFolder resFolder = project.getFolder(SdkConstants.FD_RESOURCES);
- for (IResource folder : resFolder.members()) {
- if (!(folder instanceof IFolder)) {
+ // Update references in XML resource files
+ IFolder resFolder = mProject.getFolder(SdkConstants.FD_RESOURCES);
+
+ IResource[] folders = resFolder.members();
+ for (IResource folder : folders) {
+ String folderName = folder.getName();
+ ResourceFolderType folderType = ResourceFolderType.getFolderType(folderName);
+ if (folderType != ResourceFolderType.LAYOUT) {
continue;
}
- ResourceFolderType type = ResourceFolderType.getFolderType(folder.getName());
- if (type != ResourceFolderType.LAYOUT) {
+ if (!(folder instanceof IFolder)) {
continue;
}
- IFolder layoutFolder = (IFolder) folder;
- IResource[] members = layoutFolder.members();
- for (int i = 0; i < members.length; i++) {
- IResource member = members[i];
+ IResource[] files = ((IFolder) folder).members();
+ for (int i = 0; i < files.length; i++) {
+ IResource member = files[i];
if ((member instanceof IFile) && member.exists()) {
IFile file = (IFile) member;
- Set<AndroidLayoutChangeDescription> changes = parse(file, className);
- if (changes.size() > 0) {
- AndroidLayoutFileChanges fileChange = new AndroidLayoutFileChanges(file);
- fileChange.getChanges().addAll(changes);
- mFileChanges.add(fileChange);
+ String fileName = member.getName();
+
+ if (SdkUtils.endsWith(fileName, DOT_XML)) {
+ addXmlFileChanges(file, result, false);
}
}
}
@@ -273,167 +208,139 @@ public class AndroidTypeMoveParticipant extends MoveParticipant {
}
}
- /**
- * Searches the layout file for classes
- *
- * @param file the Android layout file
- * @param className the layout classes
- *
- */
- private Set<AndroidLayoutChangeDescription> parse(IFile file, String className) {
- Set<AndroidLayoutChangeDescription> changes = new HashSet<AndroidLayoutChangeDescription>();
- ITextFileBufferManager lManager = null;
+ private boolean addXmlFileChanges(IFile file, CompositeChange changes, boolean isManifest) {
+ IModelManager modelManager = StructuredModelManager.getModelManager();
+ IStructuredModel model = null;
try {
- lManager = FileBuffers.getTextFileBufferManager();
- lManager.connect(file.getFullPath(), LocationKind.NORMALIZE, new NullProgressMonitor());
- ITextFileBuffer buffer = lManager.getTextFileBuffer(file.getFullPath(),
- LocationKind.NORMALIZE);
- IDocument lDocument = buffer.getDocument();
- IStructuredModel model = null;
- try {
- model = StructuredModelManager.getModelManager().getExistingModelForRead(lDocument);
- if (model == null) {
- if (lDocument instanceof IStructuredDocument) {
- IStructuredDocument structuredDocument = (IStructuredDocument) lDocument;
- model = StructuredModelManager.getModelManager().getModelForRead(
- structuredDocument);
- }
- }
- if (model != null) {
- IDOMModel xmlModel = (IDOMModel) model;
- IDOMDocument xmlDoc = xmlModel.getDocument();
- NodeList nodes = xmlDoc.getElementsByTagName(SdkConstants.VIEW);
- for (int i = 0; i < nodes.getLength(); i++) {
- Node node = nodes.item(i);
- NamedNodeMap attributes = node.getAttributes();
- if (attributes != null) {
- Node attributeNode =
- attributes.getNamedItem(SdkConstants.ATTR_CLASS);
- if (attributeNode instanceof Attr) {
- Attr attribute = (Attr) attributeNode;
- String value = attribute.getValue();
- if (value != null && value.equals(className)) {
- AndroidLayoutChangeDescription layoutChange =
- new AndroidLayoutChangeDescription(className, mNewName,
- AndroidLayoutChangeDescription.VIEW_TYPE);
- changes.add(layoutChange);
- }
- }
+ model = modelManager.getExistingModelForRead(file);
+ if (model == null) {
+ model = modelManager.getModelForRead(file);
+ }
+ if (model != null) {
+ IStructuredDocument document = model.getStructuredDocument();
+ if (model instanceof IDOMModel) {
+ IDOMModel domModel = (IDOMModel) model;
+ Element root = domModel.getDocument().getDocumentElement();
+ if (root != null) {
+ List<TextEdit> edits = new ArrayList<TextEdit>();
+ if (isManifest) {
+ addManifestReplacements(edits, root, document);
+ } else {
+ addLayoutReplacements(edits, root, document);
+ }
+ if (!edits.isEmpty()) {
+ MultiTextEdit rootEdit = new MultiTextEdit();
+ rootEdit.addChildren(edits.toArray(new TextEdit[edits.size()]));
+ TextFileChange change = new TextFileChange(file.getName(), file);
+ change.setTextType(EXT_XML);
+ change.setEdit(rootEdit);
+ changes.add(change);
}
}
- nodes = xmlDoc.getElementsByTagName(className);
- for (int i = 0; i < nodes.getLength(); i++) {
- AndroidLayoutChangeDescription layoutChange =
- new AndroidLayoutChangeDescription(className, mNewName,
- AndroidLayoutChangeDescription.STANDALONE_TYPE);
- changes.add(layoutChange);
- }
- }
- } finally {
- if (model != null) {
- model.releaseFromRead();
+ } else {
+ return false;
}
}
- } catch (CoreException ignore) {
+ return true;
+ } catch (IOException e) {
+ AdtPlugin.log(e, null);
+ } catch (CoreException e) {
+ AdtPlugin.log(e, null);
} finally {
- if (lManager != null) {
- try {
- lManager.disconnect(file.getFullPath(), LocationKind.NORMALIZE,
- new NullProgressMonitor());
- } catch (CoreException ignore) {
- }
+ if (model != null) {
+ model.releaseFromRead();
}
}
- return changes;
- }
- /**
- * Returns the elements (activity, receiver, service ...)
- * which have to be renamed
- *
- * @return the android elements
- */
- private Map<String, String> addAndroidElements() {
- Map<String, String> androidElements = new HashMap<String, String>();
+ return false;
+ }
- IDocument document;
- try {
- document = getDocument();
- } catch (CoreException e) {
- RefactoringUtil.log(e);
- if (mManager != null) {
- try {
- mManager.disconnect(mAndroidManifest.getFullPath(), LocationKind.NORMALIZE,
- new NullProgressMonitor());
- } catch (CoreException e1) {
- RefactoringUtil.log(e1);
- }
+ private void addLayoutReplacements(
+ @NonNull List<TextEdit> edits,
+ @NonNull Element element,
+ @NonNull IStructuredDocument document) {
+ String tag = element.getTagName();
+ if (tag.equals(mOldFqcn)) {
+ int start = RefactoringUtil.getTagNameRangeStart(element, document);
+ if (start != -1) {
+ int end = start + mOldFqcn.length();
+ edits.add(new ReplaceEdit(start, end - start, mNewFqcn));
}
- document = null;
- return androidElements;
- }
-
- IStructuredModel model = null;
- try {
- model = StructuredModelManager.getModelManager().getExistingModelForRead(document);
- if (model == null) {
- if (document instanceof IStructuredDocument) {
- IStructuredDocument structuredDocument = (IStructuredDocument) document;
- model = StructuredModelManager.getModelManager().getModelForRead(
- structuredDocument);
+ } else if (tag.equals(VIEW_TAG)) {
+ Attr classNode = element.getAttributeNode(ATTR_CLASS);
+ if (classNode != null && classNode.getValue().equals(mOldFqcn)) {
+ int start = RefactoringUtil.getAttributeValueRangeStart(classNode, document);
+ if (start != -1) {
+ int end = start + mOldFqcn.length();
+ edits.add(new ReplaceEdit(start, end - start, mNewFqcn));
}
}
- if (model != null) {
- IDOMModel xmlModel = (IDOMModel) model;
- IDOMDocument xmlDoc = xmlModel.getDocument();
- add(xmlDoc, androidElements, AndroidManifest.NODE_ACTIVITY,
- AndroidManifest.ATTRIBUTE_NAME);
- add(xmlDoc, androidElements, AndroidManifest.NODE_APPLICATION,
- AndroidManifest.ATTRIBUTE_NAME);
- add(xmlDoc, androidElements, AndroidManifest.NODE_PROVIDER,
- AndroidManifest.ATTRIBUTE_NAME);
- add(xmlDoc, androidElements, AndroidManifest.NODE_RECEIVER,
- AndroidManifest.ATTRIBUTE_NAME);
- add(xmlDoc, androidElements, AndroidManifest.NODE_SERVICE,
- AndroidManifest.ATTRIBUTE_NAME);
+ } else if (tag.equals(VIEW_FRAGMENT)) {
+ Attr classNode = element.getAttributeNodeNS(ANDROID_URI, ATTR_NAME);
+ if (classNode != null && classNode.getValue().equals(mOldFqcn)) {
+ int start = RefactoringUtil.getAttributeValueRangeStart(classNode, document);
+ if (start != -1) {
+ int end = start + mOldFqcn.length();
+ edits.add(new ReplaceEdit(start, end - start, mNewFqcn));
+ }
}
- } finally {
- if (model != null) {
- model.releaseFromRead();
+ } else if (element.hasAttributeNS(TOOLS_URI, ATTR_CONTEXT)) {
+ Attr classNode = element.getAttributeNodeNS(TOOLS_URI, ATTR_CONTEXT);
+ if (classNode != null && classNode.getValue().equals(mOldFqcn)) {
+ int start = RefactoringUtil.getAttributeValueRangeStart(classNode, document);
+ if (start != -1) {
+ int end = start + mOldFqcn.length();
+ edits.add(new ReplaceEdit(start, end - start, mNewFqcn));
+ }
}
}
- return androidElements;
+ NodeList children = element.getChildNodes();
+ for (int i = 0, n = children.getLength(); i < n; i++) {
+ Node child = children.item(i);
+ if (child.getNodeType() == Node.ELEMENT_NODE) {
+ addLayoutReplacements(edits, (Element) child, document);
+ }
+ }
}
- /**
- * Adds the element (activity, receiver, service ...) to the map
- *
- * @param xmlDoc the document
- * @param androidElements the map
- * @param element the element
- */
- private void add(IDOMDocument xmlDoc, Map<String, String> androidElements, String element,
- String argument) {
- NodeList nodes = xmlDoc.getElementsByTagName(element);
- for (int i = 0; i < nodes.getLength(); i++) {
- Node node = nodes.item(i);
- NamedNodeMap attributes = node.getAttributes();
- if (attributes != null) {
- Attr attribute = RefactoringUtil.findAndroidAttributes(attributes, argument);
- if (attribute != null) {
- String value = attribute.getValue();
- if (value != null) {
- String fullName = AndroidManifest.combinePackageAndClassName(mJavaPackage,
- value);
- if (fullName != null && fullName.equals(mOldName)) {
- androidElements.put(element, value);
- }
+ private void addManifestReplacements(
+ @NonNull List<TextEdit> edits,
+ @NonNull Element element,
+ @NonNull IStructuredDocument document) {
+ NamedNodeMap attributes = element.getAttributes();
+ for (int i = 0, n = attributes.getLength(); i < n; i++) {
+ Attr attr = (Attr) attributes.item(i);
+ if (!RefactoringUtil.isManifestClassAttribute(attr)) {
+ continue;
+ }
+
+ String value = attr.getValue();
+ if (value.equals(mOldFqcn)) {
+ int start = RefactoringUtil.getAttributeValueRangeStart(attr, document);
+ if (start != -1) {
+ int end = start + mOldFqcn.length();
+ edits.add(new ReplaceEdit(start, end - start, mNewFqcn));
+ }
+ } else if (value.startsWith(".")) { //$NON-NLS-1$
+ String fqcn = mAppPackage + value;
+ if (fqcn.equals(mOldFqcn)) {
+ int start = RefactoringUtil.getAttributeValueRangeStart(attr, document);
+ if (start != -1) {
+ int end = start + value.length();
+ edits.add(new ReplaceEdit(start, end - start, mNewFqcn));
}
}
}
}
- }
+ NodeList children = element.getChildNodes();
+ for (int i = 0, n = children.getLength(); i < n; i++) {
+ Node child = children.item(i);
+ if (child.getNodeType() == Node.ELEMENT_NODE) {
+ addManifestReplacements(edits, (Element) child, document);
+ }
+ }
+ }
}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/core/AndroidTypeRenameParticipant.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/core/AndroidTypeRenameParticipant.java
index 227266d..f454c68 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/core/AndroidTypeRenameParticipant.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/core/AndroidTypeRenameParticipant.java
@@ -16,54 +16,61 @@
package com.android.ide.eclipse.adt.internal.refactorings.core;
+import static com.android.SdkConstants.ANDROID_URI;
+import static com.android.SdkConstants.ATTR_CLASS;
+import static com.android.SdkConstants.ATTR_CONTEXT;
+import static com.android.SdkConstants.ATTR_NAME;
+import static com.android.SdkConstants.DOT_XML;
+import static com.android.SdkConstants.EXT_XML;
+import static com.android.SdkConstants.TOOLS_URI;
+import static com.android.SdkConstants.VIEW_FRAGMENT;
+import static com.android.SdkConstants.VIEW_TAG;
+
import com.android.SdkConstants;
+import com.android.annotations.NonNull;
import com.android.ide.common.xml.ManifestData;
import com.android.ide.eclipse.adt.AdtConstants;
+import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.internal.project.AndroidManifestHelper;
-import com.android.ide.eclipse.adt.internal.refactorings.changes.AndroidLayoutChange;
-import com.android.ide.eclipse.adt.internal.refactorings.changes.AndroidLayoutChangeDescription;
-import com.android.ide.eclipse.adt.internal.refactorings.changes.AndroidLayoutFileChanges;
-import com.android.ide.eclipse.adt.internal.refactorings.changes.AndroidTypeRenameChange;
import com.android.resources.ResourceFolderType;
-import com.android.xml.AndroidManifest;
+import com.android.utils.SdkUtils;
-import org.eclipse.core.filebuffers.FileBuffers;
-import org.eclipse.core.filebuffers.ITextFileBuffer;
-import org.eclipse.core.filebuffers.ITextFileBufferManager;
-import org.eclipse.core.filebuffers.LocationKind;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IType;
-import org.eclipse.jdt.core.ITypeHierarchy;
-import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.internal.corext.refactoring.rename.RenameCompilationUnitProcessor;
import org.eclipse.jdt.internal.corext.refactoring.rename.RenameTypeProcessor;
-import org.eclipse.jface.text.IDocument;
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.RefactoringProcessor;
+import org.eclipse.ltk.core.refactoring.participants.RenameParticipant;
+import org.eclipse.text.edits.MultiTextEdit;
+import org.eclipse.text.edits.ReplaceEdit;
+import org.eclipse.text.edits.TextEdit;
import org.eclipse.wst.sse.core.StructuredModelManager;
+import org.eclipse.wst.sse.core.internal.provisional.IModelManager;
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
-import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
import org.w3c.dom.Attr;
+import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
/**
* A participant to participate in refactorings that rename a type in an Android project.
@@ -76,81 +83,32 @@ import java.util.Set;
* <code>org.eclipse.ltk.core.refactoring.participants.RenameParticipant</code>.
*/
@SuppressWarnings("restriction")
-public class AndroidTypeRenameParticipant extends AndroidRenameParticipant {
-
- private Set<AndroidLayoutFileChanges> mFileChanges = new HashSet<AndroidLayoutFileChanges>();
-
- private String mLayoutNewName;
+public class AndroidTypeRenameParticipant extends RenameParticipant {
+ private IProject mProject;
+ private IFile mManifestFile;
+ private String mOldFqcn;
+ private String mNewFqcn;
+ private String mOldDottedName;
+ private String mNewDottedName;
@Override
- public Change createChange(IProgressMonitor pm) throws CoreException,
- OperationCanceledException {
- if (pm.isCanceled()) {
- return null;
- }
-
- // Only propose this refactoring if the "Update References" checkbox is set.
- if (!getArguments().getUpdateReferences())
- return null;
-
- RefactoringProcessor p = getProcessor();
- if (p instanceof RenameCompilationUnitProcessor) {
- RenameTypeProcessor rtp = ((RenameCompilationUnitProcessor) p).getRenameTypeProcessor();
- if (rtp != null) {
- String pattern = rtp.getFilePatterns();
- boolean updQualf = rtp.getUpdateQualifiedNames();
- if (updQualf && pattern != null && pattern.contains("xml")) { //$NON-NLS-1$
- // Do not propose this refactoring if the
- // "Update fully qualified names in non-Java files" option is
- // checked and the file patterns mention XML. [c.f. SDK bug 21589]
- return null;
- }
- }
- }
-
- CompositeChange result = new CompositeChange(getName());
- if (mAndroidManifest.exists()) {
- if (mAndroidElements.size() > 0) {
- getManifestDocument();
- Change change = new AndroidTypeRenameChange(mAndroidManifest, mManager, mDocument,
- mAndroidElements, mOldName, mNewName);
- if (change != null) {
- result.add(change);
- }
- }
- // add layoutChange
- for (AndroidLayoutFileChanges fileChange : mFileChanges) {
- IFile file = fileChange.getFile();
- ITextFileBufferManager lManager = FileBuffers.getTextFileBufferManager();
- lManager.connect(file.getFullPath(), LocationKind.NORMALIZE,
- new NullProgressMonitor());
- ITextFileBuffer buffer = lManager.getTextFileBuffer(file.getFullPath(),
- LocationKind.NORMALIZE);
- IDocument lDocument = buffer.getDocument();
- Change layoutChange = new AndroidLayoutChange(file, lDocument, lManager,
- fileChange.getChanges());
- if (layoutChange != null) {
- result.add(layoutChange);
- }
- }
- }
- return (result.getChildren().length == 0) ? null : result;
-
+ public String getName() {
+ return "Android Type Rename";
}
@Override
- public String getName() {
- return "Android Type Rename";
+ public RefactoringStatus checkConditions(IProgressMonitor pm, CheckConditionsContext context)
+ throws OperationCanceledException {
+ return new RefactoringStatus();
}
@Override
protected boolean initialize(Object element) {
-
if (element instanceof IType) {
IType type = (IType) element;
IJavaProject javaProject = (IJavaProject) type.getAncestor(IJavaElement.JAVA_PROJECT);
- IProject project = javaProject.getProject();
- IResource manifestResource = project.findMember(AdtConstants.WS_SEP
+ mProject = javaProject.getProject();
+ IResource manifestResource = mProject.findMember(AdtConstants.WS_SEP
+ SdkConstants.FN_ANDROID_MANIFEST_XML);
if (manifestResource == null || !manifestResource.exists()
@@ -158,82 +116,102 @@ public class AndroidTypeRenameParticipant extends AndroidRenameParticipant {
RefactoringUtil.logInfo(
String.format("Invalid or missing file %1$s in project %2$s",
SdkConstants.FN_ANDROID_MANIFEST_XML,
- project.getName()));
+ mProject.getName()));
return false;
}
- mAndroidManifest = (IFile) manifestResource;
+ mManifestFile = (IFile) manifestResource;
ManifestData manifestData;
- manifestData = AndroidManifestHelper.parseForData(mAndroidManifest);
+ manifestData = AndroidManifestHelper.parseForData(mManifestFile);
if (manifestData == null) {
return false;
}
- mAppPackage = manifestData.getPackage();
- mOldName = type.getFullyQualifiedName();
+ mOldDottedName = '.' + type.getElementName();
+ mOldFqcn = type.getFullyQualifiedName();
String packageName = type.getPackageFragment().getElementName();
- mNewName = getArguments().getNewName();
+ mNewDottedName = '.' + getArguments().getNewName();
if (packageName != null) {
- mLayoutNewName = packageName + "." + getArguments().getNewName(); //$NON-NLS-1$
+ mNewFqcn = packageName + mNewDottedName;
} else {
- mLayoutNewName = getArguments().getNewName();
+ mNewFqcn = getArguments().getNewName();
}
- if (mOldName == null || mNewName == null) {
+ if (mOldFqcn == null || mOldFqcn == null) {
return false;
}
- if (!RefactoringUtil.isRefactorAppPackage() && mNewName.indexOf(".") == -1) { //$NON-NLS-1$
- mNewName = packageName + "." + mNewName; //$NON-NLS-1$
+ if (!RefactoringUtil.isRefactorAppPackage() && mNewFqcn.indexOf('.') == -1) {
+ mNewFqcn = packageName + mNewDottedName;
}
- mAndroidElements = addAndroidElements();
- try {
- ITypeHierarchy typeHierarchy = type.newSupertypeHierarchy(null);
- if (typeHierarchy == null) {
- return false;
- }
- IType[] superTypes = typeHierarchy.getAllSuperclasses(type);
- for (int i = 0; i < superTypes.length; i++) {
- IType superType = superTypes[i];
- String className = superType.getFullyQualifiedName();
- if (className.equals(SdkConstants.CLASS_VIEW)) {
- addLayoutChanges(project, type.getFullyQualifiedName());
- break;
- }
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public Change createChange(IProgressMonitor pm) throws CoreException,
+ OperationCanceledException {
+ if (pm.isCanceled()) {
+ return null;
+ }
+
+ // Only propose this refactoring if the "Update References" checkbox is set.
+ if (!getArguments().getUpdateReferences()) {
+ return null;
+ }
+
+ RefactoringProcessor p = getProcessor();
+ if (p instanceof RenameCompilationUnitProcessor) {
+ RenameTypeProcessor rtp =
+ ((RenameCompilationUnitProcessor) p).getRenameTypeProcessor();
+ if (rtp != null) {
+ String pattern = rtp.getFilePatterns();
+ boolean updQualf = rtp.getUpdateQualifiedNames();
+ if (updQualf && pattern != null && pattern.contains("xml")) { //$NON-NLS-1$
+ // Do not propose this refactoring if the
+ // "Update fully qualified names in non-Java files" option is
+ // checked and the file patterns mention XML. [c.f. SDK bug 21589]
+ return null;
}
- } catch (JavaModelException ignore) {
}
-
- return mAndroidElements.size() > 0 || mFileChanges.size() > 0;
}
- return false;
+
+ CompositeChange result = new CompositeChange(getName());
+
+ // Only show the children in the refactoring preview dialog
+ result.markAsSynthetic();
+
+ addManifestFileChanges(result);
+ addLayoutFileChanges(result);
+
+ return (result.getChildren().length == 0) ? null : result;
+ }
+
+ private void addManifestFileChanges(CompositeChange result) {
+ addXmlFileChanges(mManifestFile, result, true);
}
- /**
- * Adds layout changes for project
- *
- * @param project the Android project
- * @param className the layout classes
- *
- */
- private void addLayoutChanges(IProject project, String className) {
+ private void addLayoutFileChanges(CompositeChange result) {
try {
- IFolder resFolder = project.getFolder(SdkConstants.FD_RESOURCES);
- for (IResource folder : resFolder.members()) {
- if (!(folder instanceof IFolder)) {
+ // Update references in XML resource files
+ IFolder resFolder = mProject.getFolder(SdkConstants.FD_RESOURCES);
+
+ IResource[] folders = resFolder.members();
+ for (IResource folder : folders) {
+ String folderName = folder.getName();
+ ResourceFolderType folderType = ResourceFolderType.getFolderType(folderName);
+ if (folderType != ResourceFolderType.LAYOUT) {
continue;
}
- ResourceFolderType type = ResourceFolderType.getFolderType(folder.getName());
- if (type != ResourceFolderType.LAYOUT) {
+ if (!(folder instanceof IFolder)) {
continue;
}
- IFolder layoutFolder = (IFolder) folder;
- IResource[] members = layoutFolder.members();
- for (int i = 0; i < members.length; i++) {
- IResource member = members[i];
+ IResource[] files = ((IFolder) folder).members();
+ for (int i = 0; i < files.length; i++) {
+ IResource member = files[i];
if ((member instanceof IFile) && member.exists()) {
IFile file = (IFile) member;
- Set<AndroidLayoutChangeDescription> changes = parse(file, className);
- if (changes.size() > 0) {
- AndroidLayoutFileChanges fileChange = new AndroidLayoutFileChanges(file);
- fileChange.getChanges().addAll(changes);
- mFileChanges.add(fileChange);
+ String fileName = member.getName();
+
+ if (SdkUtils.endsWith(fileName, DOT_XML)) {
+ addXmlFileChanges(file, result, false);
}
}
}
@@ -243,172 +221,143 @@ public class AndroidTypeRenameParticipant extends AndroidRenameParticipant {
}
}
- /**
- * Searches the layout file for classes
- *
- * @param file the Android layout file
- * @param className the layout classes
- *
- */
- private Set<AndroidLayoutChangeDescription> parse(IFile file, String className) {
- Set<AndroidLayoutChangeDescription> changes = new HashSet<AndroidLayoutChangeDescription>();
- ITextFileBufferManager lManager = null;
+ private boolean addXmlFileChanges(IFile file, CompositeChange changes, boolean isManifest) {
+ IModelManager modelManager = StructuredModelManager.getModelManager();
+ IStructuredModel model = null;
try {
- lManager = FileBuffers.getTextFileBufferManager();
- lManager.connect(file.getFullPath(), LocationKind.NORMALIZE, new NullProgressMonitor());
- ITextFileBuffer buffer = lManager.getTextFileBuffer(file.getFullPath(),
- LocationKind.NORMALIZE);
- IDocument lDocument = buffer.getDocument();
- IStructuredModel model = null;
- try {
- model = StructuredModelManager.getModelManager().getExistingModelForRead(lDocument);
- if (model == null) {
- if (lDocument instanceof IStructuredDocument) {
- IStructuredDocument structuredDocument = (IStructuredDocument) lDocument;
- model = StructuredModelManager.getModelManager().getModelForRead(
- structuredDocument);
- }
- }
- if (model != null) {
- IDOMModel xmlModel = (IDOMModel) model;
- IDOMDocument xmlDoc = xmlModel.getDocument();
- NodeList nodes = xmlDoc.getElementsByTagName(SdkConstants.VIEW);
- for (int i = 0; i < nodes.getLength(); i++) {
- Node node = nodes.item(i);
- NamedNodeMap attributes = node.getAttributes();
- if (attributes != null) {
- Node attributeNode =
- attributes.getNamedItem(SdkConstants.ATTR_CLASS);
- if (attributeNode instanceof Attr) {
- Attr attribute = (Attr) attributeNode;
- String value = attribute.getValue();
- if (value != null && value.equals(className)) {
- AndroidLayoutChangeDescription layoutChange =
- new AndroidLayoutChangeDescription(className, mLayoutNewName,
- AndroidLayoutChangeDescription.VIEW_TYPE);
- changes.add(layoutChange);
- }
- }
+ model = modelManager.getExistingModelForRead(file);
+ if (model == null) {
+ model = modelManager.getModelForRead(file);
+ }
+ if (model != null) {
+ IStructuredDocument document = model.getStructuredDocument();
+ if (model instanceof IDOMModel) {
+ IDOMModel domModel = (IDOMModel) model;
+ Element root = domModel.getDocument().getDocumentElement();
+ if (root != null) {
+ List<TextEdit> edits = new ArrayList<TextEdit>();
+ if (isManifest) {
+ addManifestReplacements(edits, root, document);
+ } else {
+ addLayoutReplacements(edits, root, document);
+ }
+ if (!edits.isEmpty()) {
+ MultiTextEdit rootEdit = new MultiTextEdit();
+ rootEdit.addChildren(edits.toArray(new TextEdit[edits.size()]));
+ TextFileChange change = new TextFileChange(file.getName(), file);
+ change.setTextType(EXT_XML);
+ change.setEdit(rootEdit);
+ changes.add(change);
}
}
- nodes = xmlDoc.getElementsByTagName(className);
- for (int i = 0; i < nodes.getLength(); i++) {
- AndroidLayoutChangeDescription layoutChange =
- new AndroidLayoutChangeDescription(className, mLayoutNewName,
- AndroidLayoutChangeDescription.STANDALONE_TYPE);
- changes.add(layoutChange);
- }
- }
- } finally {
- if (model != null) {
- model.releaseFromRead();
+ } else {
+ return false;
}
}
- } catch (CoreException ignore) {
+ return true;
+ } catch (IOException e) {
+ AdtPlugin.log(e, null);
+ } catch (CoreException e) {
+ AdtPlugin.log(e, null);
} finally {
- if (lManager != null) {
- try {
- lManager.disconnect(file.getFullPath(),
- LocationKind.NORMALIZE,
- new NullProgressMonitor());
- } catch (CoreException ignore) {
- }
+ if (model != null) {
+ model.releaseFromRead();
}
}
- return changes;
- }
- /**
- * Returns the elements (activity, receiver, service ...)
- * which have to be renamed
- *
- * @return the android elements
- *
- */
- private Map<String, String> addAndroidElements() {
- Map<String, String> androidElements = new HashMap<String, String>();
+ return false;
+ }
- IDocument document;
- try {
- document = getManifestDocument();
- } catch (CoreException e) {
- RefactoringUtil.log(e);
- if (mManager != null) {
- try {
- mManager.disconnect(mAndroidManifest.getFullPath(),
- LocationKind.NORMALIZE,
- new NullProgressMonitor());
- } catch (CoreException e1) {
- RefactoringUtil.log(e1);
- }
+ private void addLayoutReplacements(
+ @NonNull List<TextEdit> edits,
+ @NonNull Element element,
+ @NonNull IStructuredDocument document) {
+ String tag = element.getTagName();
+ if (tag.equals(mOldFqcn)) {
+ int start = RefactoringUtil.getTagNameRangeStart(element, document);
+ if (start != -1) {
+ int end = start + mOldFqcn.length();
+ edits.add(new ReplaceEdit(start, end - start, mNewFqcn));
}
- document = null;
- return androidElements;
- }
-
- IStructuredModel model = null;
- try {
- model = StructuredModelManager.getModelManager().getExistingModelForRead(document);
- if (model == null) {
- if (document instanceof IStructuredDocument) {
- IStructuredDocument structuredDocument = (IStructuredDocument) document;
- model = StructuredModelManager.getModelManager().getModelForRead(
- structuredDocument);
+ } else if (tag.equals(VIEW_TAG)) {
+ // TODO: Handle inner classes ($ vs .) ?
+ Attr classNode = element.getAttributeNode(ATTR_CLASS);
+ if (classNode != null && classNode.getValue().equals(mOldFqcn)) {
+ int start = RefactoringUtil.getAttributeValueRangeStart(classNode, document);
+ if (start != -1) {
+ int end = start + mOldFqcn.length();
+ edits.add(new ReplaceEdit(start, end - start, mNewFqcn));
}
}
- if (model != null) {
- IDOMModel xmlModel = (IDOMModel) model;
- IDOMDocument xmlDoc = xmlModel.getDocument();
- add(xmlDoc, androidElements, AndroidManifest.NODE_ACTIVITY,
- AndroidManifest.ATTRIBUTE_NAME);
- add(xmlDoc, androidElements, AndroidManifest.NODE_APPLICATION,
- AndroidManifest.ATTRIBUTE_NAME);
- add(xmlDoc, androidElements, AndroidManifest.NODE_PROVIDER,
- AndroidManifest.ATTRIBUTE_NAME);
- add(xmlDoc, androidElements, AndroidManifest.NODE_RECEIVER,
- AndroidManifest.ATTRIBUTE_NAME);
- add(xmlDoc, androidElements, AndroidManifest.NODE_SERVICE,
- AndroidManifest.ATTRIBUTE_NAME);
+ } else if (tag.equals(VIEW_FRAGMENT)) {
+ Attr classNode = element.getAttributeNodeNS(ANDROID_URI, ATTR_NAME);
+ if (classNode != null && classNode.getValue().equals(mOldFqcn)) {
+ int start = RefactoringUtil.getAttributeValueRangeStart(classNode, document);
+ if (start != -1) {
+ int end = start + mOldFqcn.length();
+ edits.add(new ReplaceEdit(start, end - start, mNewFqcn));
+ }
}
- } finally {
- if (model != null) {
- model.releaseFromRead();
+ } else if (element.hasAttributeNS(TOOLS_URI, ATTR_CONTEXT)) {
+ Attr classNode = element.getAttributeNodeNS(TOOLS_URI, ATTR_CONTEXT);
+ if (classNode != null && classNode.getValue().equals(mOldFqcn)) {
+ int start = RefactoringUtil.getAttributeValueRangeStart(classNode, document);
+ if (start != -1) {
+ int end = start + mOldFqcn.length();
+ edits.add(new ReplaceEdit(start, end - start, mNewFqcn));
+ }
+ } else if (classNode != null && classNode.getValue().equals(mOldDottedName)) {
+ int start = RefactoringUtil.getAttributeValueRangeStart(classNode, document);
+ if (start != -1) {
+ int end = start + mOldDottedName.length();
+ edits.add(new ReplaceEdit(start, end - start, mNewDottedName));
+ }
}
}
- return androidElements;
- }
-
- /**
- * (non-Javadoc) Adds the element (activity, receiver, service ...) to the map
- *
- * @param xmlDoc the document
- * @param androidElements the map
- * @param element the element
- */
- private void add(IDOMDocument xmlDoc, Map<String, String> androidElements, String element,
- String argument) {
- NodeList nodes = xmlDoc.getElementsByTagName(element);
- for (int i = 0; i < nodes.getLength(); i++) {
- Node node = nodes.item(i);
- NamedNodeMap attributes = node.getAttributes();
- if (attributes != null) {
- Attr attribute = RefactoringUtil.findAndroidAttributes(attributes, argument);
- if (attribute != null) {
- String value = attribute.getValue();
- if (value != null) {
- String fullName = AndroidManifest.combinePackageAndClassName(mAppPackage,
- value);
- if (fullName != null && fullName.equals(mOldName)) {
- androidElements.put(element, value);
- }
- }
- }
+ NodeList children = element.getChildNodes();
+ for (int i = 0, n = children.getLength(); i < n; i++) {
+ Node child = children.item(i);
+ if (child.getNodeType() == Node.ELEMENT_NODE) {
+ addLayoutReplacements(edits, (Element) child, document);
}
}
}
+ private void addManifestReplacements(
+ @NonNull List<TextEdit> edits,
+ @NonNull Element element,
+ @NonNull IStructuredDocument document) {
+ NamedNodeMap attributes = element.getAttributes();
+ for (int i = 0, n = attributes.getLength(); i < n; i++) {
+ Attr attr = (Attr) attributes.item(i);
+ if (!RefactoringUtil.isManifestClassAttribute(attr)) {
+ continue;
+ }
+ String value = attr.getValue();
+ if (value.equals(mOldFqcn)) {
+ int start = RefactoringUtil.getAttributeValueRangeStart(attr, document);
+ if (start != -1) {
+ int end = start + mOldFqcn.length();
+ edits.add(new ReplaceEdit(start, end - start, mNewFqcn));
+ }
+ } else if (value.equals(mOldDottedName)) {
+ int start = RefactoringUtil.getAttributeValueRangeStart(attr, document);
+ if (start != -1) {
+ int end = start + mOldDottedName.length();
+ edits.add(new ReplaceEdit(start, end - start, mNewDottedName));
+ }
+ }
+ }
-}
+ NodeList children = element.getChildNodes();
+ for (int i = 0, n = children.getLength(); i < n; i++) {
+ Node child = children.item(i);
+ if (child.getNodeType() == Node.ELEMENT_NODE) {
+ addManifestReplacements(edits, (Element) child, document);
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/core/RefactoringUtil.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/core/RefactoringUtil.java
index e48a685..41551a4 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/core/RefactoringUtil.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/core/RefactoringUtil.java
@@ -16,17 +16,25 @@
package com.android.ide.eclipse.adt.internal.refactorings.core;
-import com.android.SdkConstants;
+import static com.android.SdkConstants.ANDROID_URI;
+import static com.android.SdkConstants.ATTR_NAME;
+import static com.android.xml.AndroidManifest.ATTRIBUTE_BACKUP_AGENT;
+import static com.android.xml.AndroidManifest.ATTRIBUTE_MANAGE_SPACE_ACTIVITY;
+import static com.android.xml.AndroidManifest.ATTRIBUTE_PARENT_ACTIVITY_NAME;
+import static com.android.xml.AndroidManifest.ATTRIBUTE_TARGET_ACTIVITY;
+
+import com.android.annotations.NonNull;
import com.android.ide.eclipse.adt.AdtPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.wst.sse.core.StructuredModelManager;
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
+import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion;
import org.w3c.dom.Attr;
-import org.w3c.dom.NamedNodeMap;
-import org.w3c.dom.Node;
+import org.w3c.dom.Element;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
@@ -74,43 +82,6 @@ public class RefactoringUtil {
}
/**
- * Finds attribute by name in android namespace
- *
- * @param attributes the attributes collection
- * @param localName the local part of the qualified name
- *
- * @return the first attribute with this name in android namespace
- */
- public static Attr findAndroidAttributes(final NamedNodeMap attributes,
- final String localName) {
- Attr attribute = null;
- for (int j = 0; j < attributes.getLength(); j++) {
- Node attNode = attributes.item(j);
- if (attNode instanceof Attr) {
- Attr attr = (Attr) attNode;
- String name = attr.getLocalName();
- String namespace = attr.getNamespaceURI();
- if (SdkConstants.NS_RESOURCES.equals(namespace)
- && name != null
- && name.equals(localName)) {
- attribute = attr;
- break;
- }
- }
- }
- return attribute;
- }
-
- /**
- * Logs the error message
- *
- * @param message the message
- */
- public static void logError(String message) {
- AdtPlugin.log(IStatus.ERROR, AdtPlugin.PLUGIN_ID, message);
- }
-
- /**
* Logs the info message
*
* @param message the message
@@ -143,4 +114,86 @@ public class RefactoringUtil {
public static void setRefactorAppPackage(boolean refactorAppPackage) {
RefactoringUtil.sRefactorAppPackage = refactorAppPackage;
}
+
+ /**
+ * Returns the range of the attribute value in the given document
+ *
+ * @param attr the attribute to look up
+ * @param document the document containing the attribute
+ * @return the range of the value text, not including quotes, in the document
+ */
+ public static int getAttributeValueRangeStart(
+ @NonNull Attr attr,
+ @NonNull IDocument document) {
+ IndexedRegion region = (IndexedRegion) attr;
+ int potentialStart = attr.getName().length() + 2; // + 2: add ="
+ String text;
+ try {
+ text = document.get(region.getStartOffset(),
+ region.getEndOffset() - region.getStartOffset());
+ } catch (BadLocationException e) {
+ return -1;
+ }
+ String value = attr.getValue();
+ int index = text.indexOf(value, potentialStart);
+ if (index != -1) {
+ return region.getStartOffset() + index;
+ } else {
+ return -1;
+ }
+ }
+
+ /**
+ * Returns the start of the tag name of the given element
+ *
+ * @param element the element to look up
+ * @param document the document containing the attribute
+ * @return the index of the start tag in the document
+ */
+ public static int getTagNameRangeStart(
+ @NonNull Element element,
+ @NonNull IDocument document) {
+ IndexedRegion region = (IndexedRegion) element;
+ int potentialStart = 1; // add '<'
+ String text;
+ try {
+ text = document.get(region.getStartOffset(),
+ region.getEndOffset() - region.getStartOffset());
+ } catch (BadLocationException e) {
+ return -1;
+ }
+ int index = text.indexOf(element.getTagName(), potentialStart);
+ if (index != -1) {
+ return region.getStartOffset() + index;
+ } else {
+ return -1;
+ }
+ }
+
+ /**
+ * Returns whether the given manifest attribute should be considered to describe
+ * a class name. These will be eligible for refactoring when classes are renamed
+ * or moved.
+ * <p>
+ * TODO: Move to {@link RefactoringUtil}
+ *
+ * @param attribute the manifest attribute
+ * @return true if this attribute can describe a class
+ */
+ public static boolean isManifestClassAttribute(@NonNull Attr attribute) {
+ String name = attribute.getLocalName();
+ if (name == null) {
+ return false;
+ }
+
+ if (name.equals(ATTR_NAME)
+ || name.equals(ATTRIBUTE_TARGET_ACTIVITY)
+ || name.equals(ATTRIBUTE_MANAGE_SPACE_ACTIVITY)
+ || name.equals(ATTRIBUTE_BACKUP_AGENT)
+ || name.equals(ATTRIBUTE_PARENT_ACTIVITY_NAME)) {
+ return ANDROID_URI.equals(attribute.getNamespaceURI());
+ }
+
+ return false;
+ }
}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/core/RenameResourceParticipant.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/core/RenameResourceParticipant.java
index 2b0d5d7..8bd0e13 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/core/RenameResourceParticipant.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/core/RenameResourceParticipant.java
@@ -30,6 +30,7 @@ import static com.android.SdkConstants.PREFIX_RESOURCE_REF;
import static com.android.SdkConstants.PREFIX_THEME_REF;
import static com.android.SdkConstants.R_CLASS;
import static com.android.SdkConstants.TAG_ITEM;
+import static com.android.SdkConstants.TOOLS_URI;
import com.android.SdkConstants;
import com.android.annotations.NonNull;
@@ -58,8 +59,6 @@ import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.internal.corext.refactoring.rename.RenameFieldProcessor;
-import org.eclipse.jface.text.BadLocationException;
-import org.eclipse.jface.text.IDocument;
import org.eclipse.ltk.core.refactoring.Change;
import org.eclipse.ltk.core.refactoring.CompositeChange;
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
@@ -522,24 +521,6 @@ public class RenameResourceParticipant extends RenameParticipant {
return false;
}
- private int getAttributeValueRangeStart(Attr attr, IDocument document) {
- IndexedRegion region = (IndexedRegion) attr;
- int potentialStart = attr.getName().length() + 2; // + 2: add ="
- String text;
- try {
- text = document.get(region.getStartOffset(), region.getLength());
- } catch (BadLocationException e) {
- return -1;
- }
- String value = attr.getValue();
- int index = text.indexOf(value, potentialStart);
- if (index != -1) {
- return region.getStartOffset() + index;
- } else {
- return -1;
- }
- }
-
private void addReplacements(
@NonNull List<TextEdit> edits,
@NonNull Element element,
@@ -558,7 +539,7 @@ public class RenameResourceParticipant extends RenameParticipant {
|| mType.getName().equals(element.getAttribute(ATTR_TYPE))))) {
Attr nameNode = element.getAttributeNode(ATTR_NAME);
if (nameNode != null && nameNode.getValue().equals(mOldName)) {
- int start = getAttributeValueRangeStart(nameNode, document);
+ int start = RefactoringUtil.getAttributeValueRangeStart(nameNode, document);
if (start != -1) {
int end = start + mOldName.length();
edits.add(new ReplaceEdit(start, end - start, mNewName));
@@ -575,6 +556,15 @@ public class RenameResourceParticipant extends RenameParticipant {
// If not updating references, only update XML matches that define the id
if (!mUpdateReferences && (!ATTR_ID.equals(attr.getLocalName()) ||
!ANDROID_URI.equals(attr.getNamespaceURI()))) {
+
+ if (TOOLS_URI.equals(attr.getNamespaceURI()) && value.equals(mXmlMatch1)) {
+ int start = RefactoringUtil.getAttributeValueRangeStart(attr, document);
+ if (start != -1) {
+ int end = start + mXmlMatch1.length();
+ edits.add(new ReplaceEdit(start, end - start, mXmlNewValue1));
+ }
+ }
+
continue;
}
@@ -606,7 +596,7 @@ public class RenameResourceParticipant extends RenameParticipant {
int end = region.getEndOffset();
edits.add(new ReplaceEdit(start, end - start, ""));
} else {
- int start = getAttributeValueRangeStart(attr, document);
+ int start = RefactoringUtil.getAttributeValueRangeStart(attr, document);
if (start != -1) {
int end = start + match.length();
edits.add(new ReplaceEdit(start, end - start, matchedValue));
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/refactorings/core/AndroidPackageRenameParticipantTest.java b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/refactorings/core/AndroidPackageRenameParticipantTest.java
index ec9d324..a074146 100644
--- a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/refactorings/core/AndroidPackageRenameParticipantTest.java
+++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/refactorings/core/AndroidPackageRenameParticipantTest.java
@@ -49,10 +49,19 @@ public class AndroidPackageRenameParticipantTest extends RefactoringTestBase {
" +\n" +
"\n" +
"\n" +
+ "* activity_main.xml - /testRefactor1/res/layout/activity_main.xml\n" +
+ " @@ -33 +33\n" +
+ " - <fragment android:name=\"com.example.refactoringtest.MyFragment\"/>\n" +
+ " + <fragment android:name=\"my.pkg.name.MyFragment\"/>\n" +
+ "\n" +
+ "\n" +
"* AndroidManifest.xml - /testRefactor1/AndroidManifest.xml\n" +
" @@ -16 +16\n" +
" - android:name=\"com.example.refactoringtest.MainActivity\"\n" +
- " + android:name=\"my.pkg.name.MainActivity\"");
+ " + android:name=\"my.pkg.name.MainActivity\"\n" +
+ " @@ -25 +25\n" +
+ " - android:name=\".MainActivity2\"\n" +
+ " + android:name=\"my.pkg.name.MainActivity2\"");
}
public void testRefactor1_noreferences() throws Exception {
@@ -91,6 +100,12 @@ public class AndroidPackageRenameParticipantTest extends RefactoringTestBase {
" + <my.pkg.name.CustomView1\n" +
"\n" +
"\n" +
+ "* activity_main.xml - /testRefactor2/res/layout/activity_main.xml\n" +
+ " @@ -33 +33\n" +
+ " - <fragment android:name=\"com.example.refactoringtest.MyFragment\"/>\n" +
+ " + <fragment android:name=\"my.pkg.name.MyFragment\"/>\n" +
+ "\n" +
+ "\n" +
"* customviews.xml - /testRefactor2/res/layout-land/customviews.xml\n" +
" @@ -9 +9\n" +
" - <com.example.refactoringtest.CustomView1\n" +
@@ -100,7 +115,10 @@ public class AndroidPackageRenameParticipantTest extends RefactoringTestBase {
"* AndroidManifest.xml - /testRefactor2/AndroidManifest.xml\n" +
" @@ -16 +16\n" +
" - android:name=\"com.example.refactoringtest.MainActivity\"\n" +
- " + android:name=\"my.pkg.name.MainActivity\"");
+ " + android:name=\"my.pkg.name.MainActivity\"\n" +
+ " @@ -25 +25\n" +
+ " - android:name=\".MainActivity2\"\n" +
+ " + android:name=\"my.pkg.name.MainActivity2\"");
}
public void testRefactor2_renamesub() throws Exception {
@@ -127,6 +145,12 @@ public class AndroidPackageRenameParticipantTest extends RefactoringTestBase {
" + <my.pkg.name.CustomView1\n" +
"\n" +
"\n" +
+ "* activity_main.xml - /testRefactor2_renamesub/res/layout/activity_main.xml\n" +
+ " @@ -33 +33\n" +
+ " - <fragment android:name=\"com.example.refactoringtest.MyFragment\"/>\n" +
+ " + <fragment android:name=\"my.pkg.name.MyFragment\"/>\n" +
+ "\n" +
+ "\n" +
"* customviews.xml - /testRefactor2_renamesub/res/layout-land/customviews.xml\n" +
" @@ -9 +9\n" +
" - <com.example.refactoringtest.CustomView1\n" +
@@ -137,6 +161,9 @@ public class AndroidPackageRenameParticipantTest extends RefactoringTestBase {
" @@ -16 +16\n" +
" - android:name=\"com.example.refactoringtest.MainActivity\"\n" +
" + android:name=\"my.pkg.name.MainActivity\"\n" +
+ " @@ -25 +25\n" +
+ " - android:name=\".MainActivity2\"\n" +
+ " + android:name=\"my.pkg.name.MainActivity2\"\n" +
"\n" +
"\n" +
"* customviews.xml - /testRefactor2_renamesub/res/layout/customviews.xml\n" +
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/refactorings/core/RefactoringTestBase.java b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/refactorings/core/RefactoringTestBase.java
index 93c3489..44fb522 100644
--- a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/refactorings/core/RefactoringTestBase.java
+++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/refactorings/core/RefactoringTestBase.java
@@ -19,10 +19,6 @@ import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.ide.eclipse.adt.AdtUtils;
import com.android.ide.eclipse.adt.internal.editors.layout.refactoring.AdtProjectTest;
-import com.android.ide.eclipse.adt.internal.refactorings.changes.AndroidDocumentChange;
-import com.android.ide.eclipse.adt.internal.refactorings.changes.AndroidLayoutChange;
-import com.android.ide.eclipse.adt.internal.refactorings.changes.AndroidPackageRenameChange;
-import com.android.ide.eclipse.adt.internal.refactorings.changes.AndroidTypeRenameChange;
import com.google.common.base.Charsets;
import com.google.common.base.Splitter;
import com.google.common.io.ByteStreams;
@@ -133,10 +129,7 @@ public abstract class RefactoringTestBase extends AdtProjectTest {
sb.append('\n');
}
- if (change instanceof TextFileChange
- || change instanceof AndroidPackageRenameChange
- || change instanceof AndroidTypeRenameChange
- || change instanceof AndroidLayoutChange) {
+ if (change instanceof TextFileChange) {
assertNotNull(file);
if (file != null) {
TextChange tc = (TextChange) change;
@@ -221,18 +214,6 @@ public abstract class RefactoringTestBase extends AdtProjectTest {
if (change instanceof TextFileChange) {
TextFileChange tfc = (TextFileChange) change;
return tfc.getFile();
- } else if (change instanceof AndroidPackageRenameChange) {
- AndroidPackageRenameChange aprc = (AndroidPackageRenameChange) change;
- return aprc.getManifest();
- } else if (change instanceof AndroidTypeRenameChange) {
- AndroidTypeRenameChange aprc = (AndroidTypeRenameChange) change;
- return aprc.getManifest();
- } else if (change instanceof AndroidLayoutChange) {
- AndroidLayoutChange alc = (AndroidLayoutChange) change;
- return alc.getFile();
- } else if (change instanceof AndroidDocumentChange) {
- AndroidDocumentChange atmc = (AndroidDocumentChange) change;
- return atmc.getManifest();
}
return null;
@@ -293,6 +274,10 @@ public abstract class RefactoringTestBase extends AdtProjectTest {
" <category android:name=\"android.intent.category.LAUNCHER\" />\n" +
" </intent-filter>\n" +
" </activity>\n" +
+ " <activity\n" +
+ " android:name=\".MainActivity2\"\n" +
+ " android:label=\"@string/app_name2\" >\n" +
+ " </activity>\n" +
" </application>\n" +
"\n" +
"</manifest>";
@@ -323,6 +308,31 @@ public abstract class RefactoringTestBase extends AdtProjectTest {
"\n" +
"}\n";
+ protected static final String SAMPLE_MAIN_ACTIVITY2 =
+ "package com.example.refactoringtest;\n" +
+ "\n" +
+ "import android.os.Bundle;\n" +
+ "import android.app.Activity;\n" +
+ "import android.view.Menu;\n" +
+ "import android.view.View;\n" +
+ "\n" +
+ "public class MainActivity2 extends Activity {\n" +
+ "\n" +
+ " @Override\n" +
+ " protected void onCreate(Bundle savedInstanceState) {\n" +
+ " super.onCreate(savedInstanceState);\n" +
+ " }\n" +
+ "\n" +
+ "}\n";
+
+ protected static final String MY_FRAGMENT =
+ "package com.example.refactoringtest;\n" +
+ "import android.support.v4.app.ListFragment;\n" +
+ "\n" +
+ "public class MyFragment extends ListFragment {\n" +
+ "\n" +
+ "}\n";
+
protected static final String SAMPLE_LAYOUT =
"<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n" +
" xmlns:tools=\"http://schemas.android.com/tools\"\n" +
@@ -356,6 +366,8 @@ public abstract class RefactoringTestBase extends AdtProjectTest {
" android:layout_alignParentTop=\"true\"\n" +
" android:text=\"Button\" />\n" +
"\n" +
+ " <fragment android:name=\"com.example.refactoringtest.MyFragment\"/>" +
+ "\n" +
"</RelativeLayout>";
protected static final String SAMPLE_LAYOUT_2 =
@@ -365,6 +377,18 @@ public abstract class RefactoringTestBase extends AdtProjectTest {
" android:layout_height=\"match_parent\"\n" +
" tools:context=\".MainActivity\" >\n" +
"\n" +
+ " <ListView\n" +
+ " android:layout_width=\"match_parent\"\n" +
+ " android:layout_height=\"wrap_content\"\n" +
+ " tools:listitem=\"@layout/preview\" >\n" +
+ " </ListView>\n" +
+ "\n" +
+ " <fragment\n" +
+ " android:name=\"android.support.v4.app.ListFragment\"\n" +
+ " android:layout_width=\"wrap_content\"\n" +
+ " android:layout_height=\"wrap_content\"\n" +
+ " tools:layout=\"@layout/preview\" />\n" +
+ "\n" +
"\n" +
"</RelativeLayout>";
@@ -482,6 +506,9 @@ public abstract class RefactoringTestBase extends AdtProjectTest {
"src/com/example/refactoringtest/MainActivity.java",
SAMPLE_MAIN_ACTIVITY,
+ "src/com/example/refactoringtest/MainActivity2.java",
+ SAMPLE_MAIN_ACTIVITY2,
+
"gen/com/example/refactoringtest/R.java",
SAMPLE_R,
@@ -572,6 +599,9 @@ public abstract class RefactoringTestBase extends AdtProjectTest {
"src/com/example/refactoringtest/subpackage/CustomView2.java",
CUSTOM_VIEW_2,
+ "src/com/example/refactoringtest/MyFragment.java",
+ MY_FRAGMENT,
+
"gen/com/example/refactoringtest/R.java",
SAMPLE_R,
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/refactorings/core/RenameResourceParticipantTest.java b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/refactorings/core/RenameResourceParticipantTest.java
index b783f8d..3a6859c 100644
--- a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/refactorings/core/RenameResourceParticipantTest.java
+++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/refactorings/core/RenameResourceParticipantTest.java
@@ -311,6 +311,25 @@ public class RenameResourceParticipantTest extends RefactoringTestBase {
" + public static final int output=0x7f070000;");
}
+ public void testRefactor10() throws Exception {
+ // Check updating tools: attributes
+ renameResource(
+ TEST_PROJECT,
+ "@layout/preview",
+ true /*updateReferences*/,
+ "newlayout",
+
+ "CHANGES:\n" +
+ "-------\n" +
+ "* activity_main.xml - /testRefactor10/res/layout-land/activity_main.xml\n" +
+ " @@ -10 +10\n" +
+ " - tools:listitem=\"@layout/preview\" >\n" +
+ " + tools:listitem=\"@layout/newlayout\" >\n" +
+ " @@ -17 +17\n" +
+ " - tools:layout=\"@layout/preview\" />\n" +
+ " + tools:layout=\"@layout/newlayout\" />");
+ }
+
// ---- Test infrastructure ----
protected void renameResource(
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/refactorings/core/AndroidTypeMoveParticipantTest.java b/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/refactorings/core/AndroidTypeMoveParticipantTest.java
index aeedf20..0fb8523 100644
--- a/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/refactorings/core/AndroidTypeMoveParticipantTest.java
+++ b/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/refactorings/core/AndroidTypeMoveParticipantTest.java
@@ -50,18 +50,35 @@ public class AndroidTypeMoveParticipantTest extends RefactoringTestBase {
"\n" +
"* Move resource 'testRefactor1/src/com/example/refactoringtest/CustomView1.java' to 'subpackage'\n" +
"\n" +
- "* Android Type Move\n" +
+ "* customviews.xml - /testRefactor1/res/layout/customviews.xml\n" +
+ " @@ -9 +9\n" +
+ " - <com.example.refactoringtest.CustomView1\n" +
+ " + <com.example.refactoringtest.subpackage.CustomView1\n" +
"\n" +
- " * customviews.xml - /testRefactor1/res/layout/customviews.xml\n" +
- " @@ -9 +9\n" +
- " - <com.example.refactoringtest.CustomView1\n" +
- " + <com.example.refactoringtest.subpackage.CustomView1\n" +
"\n" +
+ "* customviews.xml - /testRefactor1/res/layout-land/customviews.xml\n" +
+ " @@ -9 +9\n" +
+ " - <com.example.refactoringtest.CustomView1\n" +
+ " + <com.example.refactoringtest.subpackage.CustomView1");
+ }
+
+ public void testRefactorFragment() throws Exception {
+ moveType(
+ TEST_PROJECT2,
+ "com.example.refactoringtest.MyFragment",
+ "src/com/example/refactoringtest/subpackage",
+ true /*updateReferences*/,
+
+ "CHANGES:\n" +
+ "-------\n" +
+ "* Move resource 'testRefactorFragment/src/com/example/refactoringtest/MyFragment.java' to 'subpackage'\n" +
+ "\n" +
+ "* Move resource 'testRefactorFragment/src/com/example/refactoringtest/MyFragment.java' to 'subpackage'\n" +
"\n" +
- " * customviews.xml - /testRefactor1/res/layout-land/customviews.xml\n" +
- " @@ -9 +9\n" +
- " - <com.example.refactoringtest.CustomView1\n" +
- " + <com.example.refactoringtest.subpackage.CustomView1");
+ "* activity_main.xml - /testRefactorFragment/res/layout/activity_main.xml\n" +
+ " @@ -33 +33\n" +
+ " - <fragment android:name=\"com.example.refactoringtest.MyFragment\"/>\n" +
+ " + <fragment android:name=\"com.example.refactoringtest.subpackage.MyFragment\"/>");
}
public void testRefactor1_norefs() throws Exception {
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/refactorings/core/AndroidTypeRenameParticipantTest.java b/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/refactorings/core/AndroidTypeRenameParticipantTest.java
index 8ab0a11..f54a49a 100644
--- a/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/refactorings/core/AndroidTypeRenameParticipantTest.java
+++ b/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/refactorings/core/AndroidTypeRenameParticipantTest.java
@@ -38,12 +38,39 @@ public class AndroidTypeRenameParticipantTest extends RefactoringTestBase {
"-------\n" +
"* Rename compilation unit 'MainActivity.java' to 'NewActivityName.java'\n" +
"\n" +
- "* Android Type Rename\n" +
+ "* activity_main.xml - /testRefactor1/res/layout/activity_main.xml\n" +
+ " @@ -5 +5\n" +
+ " - tools:context=\".MainActivity\" >\n" +
+ " + tools:context=\".NewActivityName\" >\n" +
"\n" +
- " * AndroidManifest.xml - /testRefactor1/AndroidManifest.xml\n" +
- " @@ -16 +16\n" +
- " - android:name=\"com.example.refactoringtest.MainActivity\"\n" +
- " + android:name=\"com.example.refactoringtest.NewActivityName\"");
+ "\n" +
+ "* activity_main.xml - /testRefactor1/res/layout-land/activity_main.xml\n" +
+ " @@ -5 +5\n" +
+ " - tools:context=\".MainActivity\" >\n" +
+ " + tools:context=\".NewActivityName\" >\n" +
+ "\n" +
+ "\n" +
+ "* AndroidManifest.xml - /testRefactor1/AndroidManifest.xml\n" +
+ " @@ -16 +16\n" +
+ " - android:name=\"com.example.refactoringtest.MainActivity\"\n" +
+ " + android:name=\"com.example.refactoringtest.NewActivityName\"");
+ }
+
+ public void testRefactor1b() throws Exception {
+ renameType(
+ TEST_PROJECT,
+ "com.example.refactoringtest.MainActivity2",
+ true /*updateReferences*/,
+ "NewActivityName",
+
+ "CHANGES:\n" +
+ "-------\n" +
+ "* Rename compilation unit 'MainActivity2.java' to 'NewActivityName.java'\n" +
+ "\n" +
+ "* AndroidManifest.xml - /testRefactor1b/AndroidManifest.xml\n" +
+ " @@ -25 +25\n" +
+ " - android:name=\".MainActivity2\"\n" +
+ " + android:name=\".NewActivityName\"");
}
public void testRefactor1_noreferences() throws Exception {
@@ -69,18 +96,33 @@ public class AndroidTypeRenameParticipantTest extends RefactoringTestBase {
"-------\n" +
"* Rename compilation unit 'CustomView1.java' to 'NewCustomViewName.java'\n" +
"\n" +
- "* Android Type Rename\n" +
- "\n" +
- " * customviews.xml - /testRefactor2/res/layout/customviews.xml\n" +
- " @@ -9 +9\n" +
- " - <com.example.refactoringtest.CustomView1\n" +
- " + <com.example.refactoringtest.NewCustomViewName\n" +
+ "* customviews.xml - /testRefactor2/res/layout/customviews.xml\n" +
+ " @@ -9 +9\n" +
+ " - <com.example.refactoringtest.CustomView1\n" +
+ " + <com.example.refactoringtest.NewCustomViewName\n" +
"\n" +
"\n" +
- " * customviews.xml - /testRefactor2/res/layout-land/customviews.xml\n" +
- " @@ -9 +9\n" +
- " - <com.example.refactoringtest.CustomView1\n" +
- " + <com.example.refactoringtest.NewCustomViewName");
+ "* customviews.xml - /testRefactor2/res/layout-land/customviews.xml\n" +
+ " @@ -9 +9\n" +
+ " - <com.example.refactoringtest.CustomView1\n" +
+ " + <com.example.refactoringtest.NewCustomViewName");
+ }
+
+ public void testRefactorFragment() throws Exception {
+ renameType(
+ TEST_PROJECT2,
+ "com.example.refactoringtest.MyFragment",
+ true /*updateReferences*/,
+ "NewFragmentName",
+
+ "CHANGES:\n" +
+ "-------\n" +
+ "* Rename compilation unit 'MyFragment.java' to 'NewFragmentName.java'\n" +
+ "\n" +
+ "* activity_main.xml - /testRefactorFragment/res/layout/activity_main.xml\n" +
+ " @@ -33 +33\n" +
+ " - <fragment android:name=\"com.example.refactoringtest.MyFragment\"/>\n" +
+ " + <fragment android:name=\"com.example.refactoringtest.NewFragmentName\"/>");
}
// ---- Test infrastructure ----