blob: bb475aab1d3472d81599ff420a80762a157b4311 [file] [log] [blame]
/*
* 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.common.xml.ManifestData;
import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.internal.project.AndroidManifestHelper;
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.jdt.ui.refactoring.RefactoringSaveHelper;
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 &lt;manifest&gt; tag with the new
* name.</li>
* <li>Replace all values for the "android:name" attribute in the
* &lt;application&gt; and "component class" (&lt;activity&gt;, &lt;service&gt;,
* &lt;receiver&gt;, and &lt;provider&gt;) 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)
*/
@Override
public void setActivePart(IAction action, IWorkbenchPart targetPart) {
mTargetPart = targetPart;
}
@Override
public void selectionChanged(IAction action, ISelection selection) {
mSelection = selection;
}
/**
* @see IWorkbenchWindowActionDelegate#init
*/
public void init(IWorkbenchWindow window) {
// pass
}
@Override
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) {
// 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.getShell())) {
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() {
@Override
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.getShell(),
"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.getShell(), package_name_refactoring.getName());
} catch (InterruptedException e) {
Status s = new Status(Status.ERROR, AdtPlugin.PLUGIN_ID, e.getMessage(), e);
AdtPlugin.getDefault().getLog().log(s);
}
}
}