diff options
author | Raphael Moll <ralf@android.com> | 2010-11-30 19:55:19 -0800 |
---|---|---|
committer | Android Code Review <code-review@android.com> | 2010-11-30 19:55:19 -0800 |
commit | 5360287631600baa7509b8926b5b4f75d855af53 (patch) | |
tree | b6ad935f202a69329b6461a021b4efcfccb01178 /eclipse | |
parent | 78338176578c649638ccf0cb897bd26f4aad2d9a (diff) | |
parent | 681d85054670b922fcc311246eb1d2b5254b7584 (diff) | |
download | sdk-5360287631600baa7509b8926b5b4f75d855af53.zip sdk-5360287631600baa7509b8926b5b4f75d855af53.tar.gz sdk-5360287631600baa7509b8926b5b4f75d855af53.tar.bz2 |
Merge "ADT: cleanup RenamePackage action."
Diffstat (limited to 'eclipse')
-rw-r--r-- | eclipse/plugins/com.android.ide.eclipse.adt/plugin.xml | 2 | ||||
-rwxr-xr-x[-rw-r--r--] | eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/renamepackage/ApplicationPackageNameRefactoring.java (renamed from eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/actions/RenamePackageAction.java) | 306 | ||||
-rwxr-xr-x | eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/renamepackage/ApplicationPackageNameRefactoringWizard.java | 35 | ||||
-rw-r--r-- | eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/renamepackage/RenamePackageAction.java | 174 |
4 files changed, 291 insertions, 226 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/plugin.xml b/eclipse/plugins/com.android.ide.eclipse.adt/plugin.xml index 6482ffb..d635de8 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/plugin.xml +++ b/eclipse/plugins/com.android.ide.eclipse.adt/plugin.xml @@ -283,7 +283,7 @@ label="Fix Project Properties" menubarPath="com.android.ide.eclipse.adt.AndroidTools/group3"/> <action - class="com.android.ide.eclipse.adt.internal.actions.RenamePackageAction" + class="com.android.ide.eclipse.adt.internal.refactorings.renamepackage.RenamePackageAction" enablesFor="1" id="com.android.ide.eclipse.adt.project.RenamePackageAction" label="Rename Application Package" diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/actions/RenamePackageAction.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/renamepackage/ApplicationPackageNameRefactoring.java index f06e00d..4a9a66e 100644..100755 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/actions/RenamePackageAction.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/renamepackage/ApplicationPackageNameRefactoring.java @@ -14,14 +14,12 @@ * limitations under the License. */ -package com.android.ide.eclipse.adt.internal.actions; +package com.android.ide.eclipse.adt.internal.refactorings.renamepackage; import com.android.ide.eclipse.adt.AdtPlugin; import com.android.ide.eclipse.adt.AndroidConstants; -import com.android.ide.eclipse.adt.internal.project.AndroidManifestHelper; import com.android.sdklib.SdkConstants; import com.android.sdklib.xml.AndroidManifest; -import com.android.sdklib.xml.ManifestData; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; @@ -30,7 +28,6 @@ import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResourceVisitor; import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.OperationCanceledException; @@ -47,29 +44,17 @@ import org.eclipse.jdt.core.dom.Name; import org.eclipse.jdt.core.dom.QualifiedName; import org.eclipse.jdt.core.dom.rewrite.ASTRewrite; import org.eclipse.jdt.core.dom.rewrite.ImportRewrite; -import org.eclipse.jface.action.IAction; -import org.eclipse.jface.dialogs.IInputValidator; -import org.eclipse.jface.dialogs.InputDialog; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.window.Window; import org.eclipse.ltk.core.refactoring.Change; import org.eclipse.ltk.core.refactoring.CompositeChange; import org.eclipse.ltk.core.refactoring.Refactoring; import org.eclipse.ltk.core.refactoring.RefactoringStatus; import org.eclipse.ltk.core.refactoring.TextEditChangeGroup; import org.eclipse.ltk.core.refactoring.TextFileChange; -import org.eclipse.ltk.ui.refactoring.RefactoringWizard; -import org.eclipse.ltk.ui.refactoring.RefactoringWizardOpenOperation; import org.eclipse.text.edits.MalformedTreeException; import org.eclipse.text.edits.MultiTextEdit; import org.eclipse.text.edits.ReplaceEdit; import org.eclipse.text.edits.TextEdit; import org.eclipse.text.edits.TextEditGroup; -import org.eclipse.ui.IObjectActionDelegate; -import org.eclipse.ui.IWorkbenchPart; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.IWorkbenchWindowActionDelegate; import org.eclipse.wst.sse.core.StructuredModelManager; import org.eclipse.wst.sse.core.internal.provisional.IModelManager; import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument; @@ -82,157 +67,84 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; -import java.util.Iterator; import java.util.List; /** - * Refactoring steps: - * <ol> - * <li>Update the "package" attribute of the <manifest> tag with the new - * name.</li> - * <li>Replace all values for the "android:name" attribute in the - * <application> and "component class" (<activity>, <service>, - * <receiver>, and <provider>) tags with the non-shorthand version - * of the class name</li> - * <li>Replace package resource imports (*.R) in .java files</li> - * <li>Update package name in the namespace declarations (e.g. "xmlns:app") - * used for custom styleable attributes in layout resource files</li> - * </ol> - * Caveat: Sometimes it is necessary to perform a project-wide - * "Organize Imports" afterwards. (CTRL+SHIFT+O when a project has active - * selection) + * Wrapper class defining the stages of the refactoring process */ -public class RenamePackageAction implements IObjectActionDelegate { +@SuppressWarnings("restriction") +class ApplicationPackageNameRefactoring extends Refactoring { - private ISelection mSelection; - - private Name mOldPackageName, mNewPackageName; - - public final static String[] MAIN_COMPONENT_TYPES = { - AndroidManifest.NODE_ACTIVITY, AndroidManifest.NODE_SERVICE, - AndroidManifest.NODE_RECEIVER, AndroidManifest.NODE_PROVIDER, - AndroidManifest.NODE_APPLICATION - }; + private final IProject mProject; + private final Name mOldPackageName; + private final Name mNewPackageName; List<String> MAIN_COMPONENT_TYPES_LIST = Arrays.asList(MAIN_COMPONENT_TYPES); public final static String ANDROID_NS_URI = SdkConstants.NS_RESOURCES; - public final static String NAMESPACE_DECLARATION_PREFIX = "xmlns:"; //$NON-NLS-1$ - IWorkbenchPart mTargetPart; - /** - * @see IObjectActionDelegate#setActivePart(IAction, IWorkbenchPart) - */ - public void setActivePart(IAction action, IWorkbenchPart targetPart) { - mTargetPart = targetPart; + ApplicationPackageNameRefactoring( + IProject project, + Name oldPackageName, + Name newPackageName) { + mProject = project; + mOldPackageName = oldPackageName; + mNewPackageName = newPackageName; } - public void selectionChanged(IAction action, ISelection selection) { - mSelection = selection; - } + @Override + public RefactoringStatus checkInitialConditions(IProgressMonitor pm) + throws CoreException, OperationCanceledException { + + // Accurate refactoring of the "shorthand" names in + // AndroidManifest.xml depends on not having compilation errors. + if (mProject.findMaxProblemSeverity( + IMarker.PROBLEM, + true, + IResource.DEPTH_INFINITE) == IMarker.SEVERITY_ERROR) { + return RefactoringStatus + .createFatalErrorStatus("Fix the errors in your project, first."); + } - /** - * @see IWorkbenchWindowActionDelegate#init - */ - public void init(IWorkbenchWindow window) { - // pass + return new RefactoringStatus(); } - public void run(IAction action) { - - // Prompt for refactoring on the selected project - if (mSelection instanceof IStructuredSelection) { - for (Iterator<?> it = ((IStructuredSelection) mSelection).iterator(); it.hasNext();) { - Object element = it.next(); - IProject project = null; - if (element instanceof IProject) { - project = (IProject) element; - } else if (element instanceof IAdaptable) { - project = (IProject) ((IAdaptable) element).getAdapter(IProject.class); - } - if (project != null) { - // TODO/FIXME Uncomment this when support for Eclipse 3.4 is dropped! - /* - // It is advisable that the user saves before proceeding, - // revealing any compilation errors. The following lines - // enforce a save as a convenience. - RefactoringSaveHelper save_helper = new RefactoringSaveHelper( - RefactoringSaveHelper.SAVE_ALL_ALWAYS_ASK); - if (save_helper.saveEditors(AdtPlugin.getDisplay().getActiveShell())) { - promptNewName(project); - } - */ + @Override + public RefactoringStatus checkFinalConditions(IProgressMonitor pm) + throws OperationCanceledException { - promptNewName(project); - } - } - } + return new RefactoringStatus(); } - /* - * Validate the new package name and start the refactoring wizard - */ - private void promptNewName(final IProject project) { - - ManifestData manifestData = AndroidManifestHelper.parseForData(project); - if (manifestData == null) { - return; - } - - final String old_package_name_string = manifestData.getPackage(); - - final AST ast_validator = AST.newAST(AST.JLS3); - mOldPackageName = ast_validator.newName(old_package_name_string); - - IInputValidator validator = new IInputValidator() { - - public String isValid(String newText) { - try { - ast_validator.newName(newText); - } catch (IllegalArgumentException e) { - return "Illegal package name."; - } - - if (newText.equals(old_package_name_string)) - return "No change."; - else - return null; - } - }; + @Override + public Change createChange(IProgressMonitor pm) throws CoreException, + OperationCanceledException { - InputDialog dialog = new InputDialog(AdtPlugin.getDisplay().getActiveShell(), - "Rename Application Package", "Enter new package name:", old_package_name_string, - validator); - - if (dialog.open() == Window.OK) { - mNewPackageName = ast_validator.newName(dialog.getValue()); - initiateAndroidPackageRefactoring(project); - } + // Traverse all files in the project, building up a list of changes + JavaFileVisitor fileVisitor = new JavaFileVisitor(); + mProject.accept(fileVisitor); + return fileVisitor.getChange(); } + @Override + public String getName() { + return "AndroidPackageNameRefactoring"; //$NON-NLS-1$ + } - private void initiateAndroidPackageRefactoring(final IProject project) { - - Refactoring package_name_refactoring = new ApplicationPackageNameRefactoring(project); + public final static String[] MAIN_COMPONENT_TYPES = { + AndroidManifest.NODE_ACTIVITY, AndroidManifest.NODE_SERVICE, + AndroidManifest.NODE_RECEIVER, AndroidManifest.NODE_PROVIDER, + AndroidManifest.NODE_APPLICATION + }; - ApplicationPackageNameRefactoringWizard wizard = - new ApplicationPackageNameRefactoringWizard(package_name_refactoring); - RefactoringWizardOpenOperation op = new RefactoringWizardOpenOperation(wizard); - try { - op.run(AdtPlugin.getDisplay().getActiveShell(), package_name_refactoring.getName()); - } catch (InterruptedException e) { - Status s = new Status(Status.ERROR, AdtPlugin.PLUGIN_ID, e.getMessage(), e); - AdtPlugin.getDefault().getLog().log(s); - } - } TextEdit updateJavaFileImports(CompilationUnit cu) { - ImportVisitor import_visitor = new ImportVisitor(cu.getAST()); - cu.accept(import_visitor); - TextEdit rewritten_imports = import_visitor.getTextEdit(); + ImportVisitor importVisitor = new ImportVisitor(cu.getAST()); + cu.accept(importVisitor); + TextEdit rewrittenImports = importVisitor.getTextEdit(); // If the import of R was potentially implicit, insert an import statement if (cu.getPackage().getName().getFullyQualifiedName() @@ -243,7 +155,7 @@ public class RenamePackageAction implements IObjectActionDelegate { + AndroidConstants.FN_RESOURCE_BASE); try { - rewritten_imports.addChild( irw.rewriteImports(null) ); + rewrittenImports.addChild( irw.rewriteImports(null) ); } catch (MalformedTreeException e) { Status s = new Status(Status.ERROR, AdtPlugin.PLUGIN_ID, e.getMessage(), e); AdtPlugin.getDefault().getLog().log(s); @@ -253,7 +165,7 @@ public class RenamePackageAction implements IObjectActionDelegate { } } - return rewritten_imports; + return rewrittenImports; } // XML utility functions @@ -292,6 +204,10 @@ public class RenamePackageAction implements IObjectActionDelegate { AdtPlugin.getDefault().getLog().log(s); } + if (sdoc == null) { + return null; + } + TextFileChange xmlChange = new TextFileChange("XML resource file edit", file); xmlChange.setTextType(AndroidConstants.EXT_XML); @@ -325,14 +241,16 @@ public class RenamePackageAction implements IObjectActionDelegate { } else if (DOMRegionContext.XML_TAG_ATTRIBUTE_VALUE.equals(type)) { // Check this is the attribute and the original string - if (lastAttrName.startsWith(NAMESPACE_DECLARATION_PREFIX)) { + if (lastAttrName != null && + lastAttrName.startsWith(NAMESPACE_DECLARATION_PREFIX)) { String lastAttrValue = region.getText(subRegion); if (oldAppNamespaceString.equals(stripQuotes(lastAttrValue))) { // Found an occurrence. Create a change for it. - TextEdit edit = new ReplaceEdit(region.getStartOffset() - + subRegion.getStart(), subRegion.getTextLength(), + TextEdit edit = new ReplaceEdit( + region.getStartOffset() + subRegion.getStart(), + subRegion.getTextLength(), addQuotes(newAppNamespaceString)); TextEditGroup editGroup = new TextEditGroup( "Replace package name in custom namespace prefix", edit); @@ -377,6 +295,10 @@ public class RenamePackageAction implements IObjectActionDelegate { AdtPlugin.getDefault().getLog().log(s); } + if (sdoc == null) { + return null; + } + TextFileChange xmlChange = new TextFileChange("Make Manifest edits", file); xmlChange.setTextType(AndroidConstants.EXT_XML); @@ -414,7 +336,8 @@ public class RenamePackageAction implements IObjectActionDelegate { } else if (DOMRegionContext.XML_TAG_ATTRIBUTE_VALUE.equals(type)) { String lastAttrValue = region.getText(subRegion); - if (lastAttrName.startsWith(NAMESPACE_DECLARATION_PREFIX)) { + if (lastAttrName != null && + lastAttrName.startsWith(NAMESPACE_DECLARATION_PREFIX)) { // Resolves the android namespace prefix for this file if (ANDROID_NS_URI.equals(stripQuotes(lastAttrValue))) { @@ -423,9 +346,7 @@ public class RenamePackageAction implements IObjectActionDelegate { android_name_attribute = android_namespace_prefix + ':' + AndroidManifest.ATTRIBUTE_NAME; } - } - - else if (AndroidManifest.NODE_MANIFEST.equals(lastTagName) + } else if (AndroidManifest.NODE_MANIFEST.equals(lastTagName) && AndroidManifest.ATTRIBUTE_PACKAGE.equals(lastAttrName)) { // Found an occurrence. Create a change for it. @@ -437,6 +358,7 @@ public class RenamePackageAction implements IObjectActionDelegate { editGroups.add(new TextEditGroup("Change Android package name", edit)); } else if (MAIN_COMPONENT_TYPES_LIST.contains(lastTagName) + && lastAttrName != null && lastAttrName.equals(android_name_attribute)) { String package_path = stripQuotes(lastAttrValue); @@ -490,6 +412,7 @@ public class RenamePackageAction implements IObjectActionDelegate { return change; } + @SuppressWarnings("unused") public boolean visit(IResource resource) throws CoreException { if (resource instanceof IFile) { IFile file = (IFile) resource; @@ -524,16 +447,12 @@ public class RenamePackageAction implements IObjectActionDelegate { } else { // Currently we only support Android resource XML files, - // so they must have a path - // similar to - // project/res/<type>[-<configuration>]/*.xml - // There is no support for sub folders, so the segment - // count must be 4. + // so they must have a path similar to + // project/res/<type>[-<configuration>]/*.xml + // There is no support for sub folders, so the segment count must be 4. // We don't need to check the type folder name because - // a/ we only accept - // an AndroidXmlEditor source and b/ aapt generates a - // compilation error for - // unknown folders. + // a/ we only accept an AndroidXmlEditor source and + // b/ aapt generates a compilation error for unknown folders. IPath path = file.getFullPath(); // check if we are inside the project/res/* folder. if (path.segmentCount() == 4) { @@ -585,13 +504,13 @@ public class RenamePackageAction implements IObjectActionDelegate { @Override public boolean visit(ImportDeclaration id) { - Name import_name = id.getName(); - if (import_name.isQualifiedName()) { - QualifiedName qualified_import_name = (QualifiedName) import_name; + Name importName = id.getName(); + if (importName.isQualifiedName()) { + QualifiedName qualifiedImportName = (QualifiedName) importName; - if (qualified_import_name.getName().getIdentifier() + if (qualifiedImportName.getName().getIdentifier() .equals(AndroidConstants.FN_RESOURCE_BASE)) { - mRewriter.replace(qualified_import_name.getQualifier(), mNewPackageName, + mRewriter.replace(qualifiedImportName.getQualifier(), mNewPackageName, null); } } @@ -599,67 +518,4 @@ public class RenamePackageAction implements IObjectActionDelegate { return true; } } - - class ApplicationPackageNameRefactoringWizard extends RefactoringWizard { - - public ApplicationPackageNameRefactoringWizard(Refactoring refactoring) { - super(refactoring, 0); - } - - @Override - protected void addUserInputPages() { - } - } - - /* - * Wrapper class defining the stages of the refactoring process - */ - class ApplicationPackageNameRefactoring extends Refactoring { - - IProject mProject; - - ApplicationPackageNameRefactoring(final IProject project) { - mProject = project; - } - - @Override - public RefactoringStatus checkFinalConditions(IProgressMonitor pm) throws CoreException, - OperationCanceledException { - - return new RefactoringStatus(); - } - - @Override - public RefactoringStatus checkInitialConditions(IProgressMonitor pm) throws CoreException, - OperationCanceledException { - - // Accurate refactoring of the "shorthand" names in - // AndroidManifest.xml - // depends on not having compilation errors. - if (mProject.findMaxProblemSeverity( - IMarker.PROBLEM, - true, - IResource.DEPTH_INFINITE) == IMarker.SEVERITY_ERROR) { - return RefactoringStatus - .createFatalErrorStatus("Fix the errors in your project, first."); - } - - return new RefactoringStatus(); - } - - @Override - public Change createChange(IProgressMonitor pm) throws CoreException, - OperationCanceledException { - - // Traverse all files in the project, building up a list of changes - JavaFileVisitor file_visitor = new JavaFileVisitor(); - mProject.accept(file_visitor); - return file_visitor.getChange(); - } - - @Override - public String getName() { - return "AndroidPackageNameRefactoring"; //$NON-NLS-1$ - } - } } diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/renamepackage/ApplicationPackageNameRefactoringWizard.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/renamepackage/ApplicationPackageNameRefactoringWizard.java new file mode 100755 index 0000000..3651855 --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/renamepackage/ApplicationPackageNameRefactoringWizard.java @@ -0,0 +1,35 @@ +/* + * 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.renamepackage; + +import org.eclipse.ltk.core.refactoring.Refactoring; +import org.eclipse.ltk.ui.refactoring.RefactoringWizard; + +/** + * @see RenamePackageAction + */ +class ApplicationPackageNameRefactoringWizard extends RefactoringWizard { + + public ApplicationPackageNameRefactoringWizard(Refactoring refactoring) { + super(refactoring, 0); + } + + @Override + protected void addUserInputPages() { + } +} + diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/renamepackage/RenamePackageAction.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/renamepackage/RenamePackageAction.java new file mode 100644 index 0000000..dfbaf55 --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/renamepackage/RenamePackageAction.java @@ -0,0 +1,174 @@ +/* + * 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.renamepackage; + +import com.android.ide.eclipse.adt.AdtPlugin; +import com.android.ide.eclipse.adt.internal.project.AndroidManifestHelper; +import com.android.sdklib.xml.ManifestData; + +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.Status; +import org.eclipse.jdt.core.dom.AST; +import org.eclipse.jdt.core.dom.Name; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.dialogs.IInputValidator; +import org.eclipse.jface.dialogs.InputDialog; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.window.Window; +import org.eclipse.ltk.core.refactoring.Refactoring; +import org.eclipse.ltk.ui.refactoring.RefactoringWizardOpenOperation; +import org.eclipse.ui.IObjectActionDelegate; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.IWorkbenchWindowActionDelegate; + +import java.util.Iterator; + +/** + * Refactoring steps: + * <ol> + * <li>Update the "package" attribute of the <manifest> tag with the new + * name.</li> + * <li>Replace all values for the "android:name" attribute in the + * <application> and "component class" (<activity>, <service>, + * <receiver>, and <provider>) tags with the non-shorthand version + * of the class name</li> + * <li>Replace package resource imports (*.R) in .java files</li> + * <li>Update package name in the namespace declarations (e.g. "xmlns:app") + * used for custom styleable attributes in layout resource files</li> + * </ol> + * Caveat: Sometimes it is necessary to perform a project-wide + * "Organize Imports" afterwards. (CTRL+SHIFT+O when a project has active + * selection) + */ +public class RenamePackageAction implements IObjectActionDelegate { + + private ISelection mSelection; + @SuppressWarnings("unused") private IWorkbenchPart mTargetPart; // TODO cleanup + + /** + * @see IObjectActionDelegate#setActivePart(IAction, IWorkbenchPart) + */ + public void setActivePart(IAction action, IWorkbenchPart targetPart) { + mTargetPart = targetPart; + } + + public void selectionChanged(IAction action, ISelection selection) { + mSelection = selection; + } + + /** + * @see IWorkbenchWindowActionDelegate#init + */ + public void init(IWorkbenchWindow window) { + // pass + } + + public void run(IAction action) { + + // Prompt for refactoring on the selected project + if (mSelection instanceof IStructuredSelection) { + for (Iterator<?> it = ((IStructuredSelection) mSelection).iterator(); it.hasNext();) { + Object element = it.next(); + IProject project = null; + if (element instanceof IProject) { + project = (IProject) element; + } else if (element instanceof IAdaptable) { + project = (IProject) ((IAdaptable) element).getAdapter(IProject.class); + } + if (project != null) { + // TODO/FIXME Uncomment this when support for Eclipse 3.4 is dropped! + /* + // It is advisable that the user saves before proceeding, + // revealing any compilation errors. The following lines + // enforce a save as a convenience. + RefactoringSaveHelper save_helper = new RefactoringSaveHelper( + RefactoringSaveHelper.SAVE_ALL_ALWAYS_ASK); + if (save_helper.saveEditors(AdtPlugin.getDisplay().getActiveShell())) { + promptNewName(project); + } + */ + + promptNewName(project); + } + } + } + } + + /* + * Validate the new package name and start the refactoring wizard + */ + private void promptNewName(final IProject project) { + + ManifestData manifestData = AndroidManifestHelper.parseForData(project); + if (manifestData == null) { + return; + } + + final String oldPackageNameString = manifestData.getPackage(); + + final AST astValidator = AST.newAST(AST.JLS3); + Name oldPackageName = astValidator.newName(oldPackageNameString); + + IInputValidator validator = new IInputValidator() { + + public String isValid(String newText) { + try { + astValidator.newName(newText); + } catch (IllegalArgumentException e) { + return "Illegal package name."; + } + + if (newText.equals(oldPackageNameString)) + return "No change."; + else + return null; + } + }; + + InputDialog dialog = new InputDialog(AdtPlugin.getDisplay().getActiveShell(), + "Rename Application Package", "Enter new package name:", oldPackageNameString, + validator); + + if (dialog.open() == Window.OK) { + Name newPackageName = astValidator.newName(dialog.getValue()); + initiateAndroidPackageRefactoring(project, oldPackageName, newPackageName); + } + } + + + private void initiateAndroidPackageRefactoring( + final IProject project, + Name oldPackageName, + Name newPackageName) { + + Refactoring package_name_refactoring = + new ApplicationPackageNameRefactoring(project, oldPackageName, newPackageName); + + ApplicationPackageNameRefactoringWizard wizard = + new ApplicationPackageNameRefactoringWizard(package_name_refactoring); + RefactoringWizardOpenOperation op = new RefactoringWizardOpenOperation(wizard); + try { + op.run(AdtPlugin.getDisplay().getActiveShell(), package_name_refactoring.getName()); + } catch (InterruptedException e) { + Status s = new Status(Status.ERROR, AdtPlugin.PLUGIN_ID, e.getMessage(), e); + AdtPlugin.getDefault().getLog().log(s); + } + } +} |