1/* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Eclipse Public License, Version 1.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.eclipse.org/org/documents/epl-v10.php 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.ide.eclipse.adt.internal.refactorings.renamepackage; 18 19import com.android.ide.common.xml.ManifestData; 20import com.android.ide.eclipse.adt.AdtPlugin; 21import com.android.ide.eclipse.adt.internal.project.AndroidManifestHelper; 22 23import org.eclipse.core.resources.IProject; 24import org.eclipse.core.runtime.IAdaptable; 25import org.eclipse.core.runtime.Status; 26import org.eclipse.jdt.core.dom.AST; 27import org.eclipse.jdt.core.dom.Name; 28import org.eclipse.jdt.ui.refactoring.RefactoringSaveHelper; 29import org.eclipse.jface.action.IAction; 30import org.eclipse.jface.dialogs.IInputValidator; 31import org.eclipse.jface.dialogs.InputDialog; 32import org.eclipse.jface.viewers.ISelection; 33import org.eclipse.jface.viewers.IStructuredSelection; 34import org.eclipse.jface.window.Window; 35import org.eclipse.ltk.core.refactoring.Refactoring; 36import org.eclipse.ltk.ui.refactoring.RefactoringWizardOpenOperation; 37import org.eclipse.ui.IObjectActionDelegate; 38import org.eclipse.ui.IWorkbenchPart; 39import org.eclipse.ui.IWorkbenchWindow; 40import org.eclipse.ui.IWorkbenchWindowActionDelegate; 41 42import java.util.Iterator; 43 44/** 45 * Refactoring steps: 46 * <ol> 47 * <li>Update the "package" attribute of the <manifest> tag with the new 48 * name.</li> 49 * <li>Replace all values for the "android:name" attribute in the 50 * <application> and "component class" (<activity>, <service>, 51 * <receiver>, and <provider>) tags with the non-shorthand version 52 * of the class name</li> 53 * <li>Replace package resource imports (*.R) in .java files</li> 54 * <li>Update package name in the namespace declarations (e.g. "xmlns:app") 55 * used for custom styleable attributes in layout resource files</li> 56 * </ol> 57 * Caveat: Sometimes it is necessary to perform a project-wide 58 * "Organize Imports" afterwards. (CTRL+SHIFT+O when a project has active 59 * selection) 60 */ 61public class RenamePackageAction implements IObjectActionDelegate { 62 63 private ISelection mSelection; 64 @SuppressWarnings("unused") private IWorkbenchPart mTargetPart; // TODO cleanup 65 66 /** 67 * @see IObjectActionDelegate#setActivePart(IAction, IWorkbenchPart) 68 */ 69 @Override 70 public void setActivePart(IAction action, IWorkbenchPart targetPart) { 71 mTargetPart = targetPart; 72 } 73 74 @Override 75 public void selectionChanged(IAction action, ISelection selection) { 76 mSelection = selection; 77 } 78 79 /** 80 * @see IWorkbenchWindowActionDelegate#init 81 */ 82 public void init(IWorkbenchWindow window) { 83 // pass 84 } 85 86 @Override 87 public void run(IAction action) { 88 89 // Prompt for refactoring on the selected project 90 if (mSelection instanceof IStructuredSelection) { 91 for (Iterator<?> it = ((IStructuredSelection) mSelection).iterator(); it.hasNext();) { 92 Object element = it.next(); 93 IProject project = null; 94 if (element instanceof IProject) { 95 project = (IProject) element; 96 } else if (element instanceof IAdaptable) { 97 project = (IProject) ((IAdaptable) element).getAdapter(IProject.class); 98 } 99 if (project != null) { 100 // It is advisable that the user saves before proceeding, 101 // revealing any compilation errors. The following lines 102 // enforce a save as a convenience. 103 RefactoringSaveHelper save_helper = new RefactoringSaveHelper( 104 RefactoringSaveHelper.SAVE_ALL_ALWAYS_ASK); 105 if (save_helper.saveEditors(AdtPlugin.getDisplay().getActiveShell())) { 106 promptNewName(project); 107 } 108 } 109 } 110 } 111 } 112 113 /* 114 * Validate the new package name and start the refactoring wizard 115 */ 116 private void promptNewName(final IProject project) { 117 118 ManifestData manifestData = AndroidManifestHelper.parseForData(project); 119 if (manifestData == null) { 120 return; 121 } 122 123 final String oldPackageNameString = manifestData.getPackage(); 124 125 final AST astValidator = AST.newAST(AST.JLS3); 126 Name oldPackageName = astValidator.newName(oldPackageNameString); 127 128 IInputValidator validator = new IInputValidator() { 129 130 @Override 131 public String isValid(String newText) { 132 try { 133 astValidator.newName(newText); 134 } catch (IllegalArgumentException e) { 135 return "Illegal package name."; 136 } 137 138 if (newText.equals(oldPackageNameString)) 139 return "No change."; 140 else 141 return null; 142 } 143 }; 144 145 InputDialog dialog = new InputDialog(AdtPlugin.getDisplay().getActiveShell(), 146 "Rename Application Package", "Enter new package name:", oldPackageNameString, 147 validator); 148 149 if (dialog.open() == Window.OK) { 150 Name newPackageName = astValidator.newName(dialog.getValue()); 151 initiateAndroidPackageRefactoring(project, oldPackageName, newPackageName); 152 } 153 } 154 155 156 private void initiateAndroidPackageRefactoring( 157 final IProject project, 158 Name oldPackageName, 159 Name newPackageName) { 160 161 Refactoring package_name_refactoring = 162 new ApplicationPackageNameRefactoring(project, oldPackageName, newPackageName); 163 164 ApplicationPackageNameRefactoringWizard wizard = 165 new ApplicationPackageNameRefactoringWizard(package_name_refactoring); 166 RefactoringWizardOpenOperation op = new RefactoringWizardOpenOperation(wizard); 167 try { 168 op.run(AdtPlugin.getDisplay().getActiveShell(), package_name_refactoring.getName()); 169 } catch (InterruptedException e) { 170 Status s = new Status(Status.ERROR, AdtPlugin.PLUGIN_ID, e.getMessage(), e); 171 AdtPlugin.getDefault().getLog().log(s); 172 } 173 } 174} 175