diff options
Diffstat (limited to 'eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/core/AndroidPackageRenameParticipant.java')
-rw-r--r-- | eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/core/AndroidPackageRenameParticipant.java | 547 |
1 files changed, 0 insertions, 547 deletions
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 deleted file mode 100644 index b821777a5..000000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/core/AndroidPackageRenameParticipant.java +++ /dev/null @@ -1,547 +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 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.editors.layout.gle2.DomUtilities; -import com.android.ide.eclipse.adt.internal.project.AndroidManifestHelper; -import com.android.ide.eclipse.adt.internal.sdk.ProjectState; -import com.android.ide.eclipse.adt.internal.sdk.Sdk; -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; -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.OperationCanceledException; -import org.eclipse.jdt.core.IJavaElement; -import org.eclipse.jdt.core.IJavaProject; -import org.eclipse.jdt.core.IPackageFragment; -import org.eclipse.jdt.core.JavaModelException; -import org.eclipse.jdt.internal.corext.refactoring.changes.RenamePackageChange; -import org.eclipse.jdt.internal.corext.refactoring.rename.RenameCompilationUnitProcessor; -import org.eclipse.jdt.internal.corext.refactoring.rename.RenameTypeProcessor; -import org.eclipse.jface.text.IRegion; -import org.eclipse.jface.text.Region; -import org.eclipse.ltk.core.refactoring.Change; -import org.eclipse.ltk.core.refactoring.CompositeChange; -import org.eclipse.ltk.core.refactoring.FileStatusContext; -import org.eclipse.ltk.core.refactoring.NullChange; -import org.eclipse.ltk.core.refactoring.RefactoringStatus; -import org.eclipse.ltk.core.refactoring.RefactoringStatusContext; -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.IndexedRegion; -import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument; -import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel; -import org.w3c.dom.Attr; -import org.w3c.dom.Document; -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.Collection; -import java.util.List; - -/** - * A participant to participate in refactorings that rename a package in an Android project. - * The class updates android manifest and the layout file - * The user can suppress refactoring by disabling the "Update references" checkbox - * <p> - * Rename participants are registered via the extension point <code> - * org.eclipse.ltk.core.refactoring.renameParticipants</code>. - * Extensions to this extension point must therefore extend - * <code>org.eclipse.ltk.core.refactoring.participants.RenameParticipant</code>. - * </p> - */ -@SuppressWarnings("restriction") -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; - - @Override - public String getName() { - return "Android Package Rename"; - } - - @Override - public RefactoringStatus checkConditions(IProgressMonitor pm, CheckConditionsContext context) - throws OperationCanceledException { - if (mAppPackage.equals(mOldPackage) && !mRefactoringAppPackage) { - IRegion region = null; - Document document = DomUtilities.getDocument(mManifestFile); - if (document != null && document.getDocumentElement() != null) { - Attr attribute = document.getDocumentElement().getAttributeNode(ATTR_PACKAGE); - if (attribute instanceof IndexedRegion) { - IndexedRegion ir = (IndexedRegion) attribute; - int start = ir.getStartOffset(); - region = new Region(start, ir.getEndOffset() - start); - } - } - if (region == null) { - region = new Region(0, 0); - } - // There's no line wrapping in the error dialog, so split up the message into - // individually digestible pieces of information - RefactoringStatusContext ctx = new FileStatusContext(mManifestFile, region); - RefactoringStatus status = RefactoringStatus.createInfoStatus( - "You are refactoring the same package as your application's " + - "package (specified in the manifest).\n", ctx); - status.addInfo( - "Note that this refactoring does NOT also update your " + - "application package.", ctx); - status.addInfo("The application package defines your application's identity.", ctx); - status.addInfo( - "If you change it, then it is considered to be a different application.", ctx); - status.addInfo("(Users of the previous version cannot update to the new version.)", - ctx); - status.addInfo( - "The application package, and the package containing the code, can differ.", - ctx); - status.addInfo( - "To really change application package, " + - "choose \"Android Tools\" > \"Rename Application Package.\" " + - "from the project context menu.", ctx); - return status; - } - - 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; - } - - - @Override - public Change createChange(IProgressMonitor pm) throws CoreException, - OperationCanceledException { - if (pm.isCanceled()) { - return null; - } - 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(); - 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(); - - 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(mProject, result); - - // Also update in dependent projects - ProjectState projectState = Sdk.getProjectState(mProject); - if (projectState != null) { - Collection<ProjectState> parentProjects = projectState.getFullParentProjects(); - for (ProjectState parentProject : parentProjects) { - IProject project = parentProject.getProject(); - addLayoutFileChanges(project, result); - } - } - - if (mRefactoringAppPackage) { - Change genChange = getGenPackageChange(pm); - if (genChange != null) { - result.add(genChange); - } - - 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; - } - - /** - * Returns Android gen package text change - * - * @param pm the progress monitor - * - * @return Android gen package text change - * @throws CoreException if an error happens - * @throws OperationCanceledException if the operation is canceled - */ - public Change getGenPackageChange(IProgressMonitor pm) throws CoreException, - OperationCanceledException { - if (mRefactoringAppPackage) { - IPackageFragment genJavaPackageFragment = getGenPackageFragment(); - if (genJavaPackageFragment != null && genJavaPackageFragment.exists()) { - return new RenamePackageChange(genJavaPackageFragment, mNewPackage, true); - } - } - return null; - } - - /** - * Return the gen package fragment - */ - private IPackageFragment getGenPackageFragment() throws JavaModelException { - IJavaProject javaProject = (IJavaProject) mPackageFragment - .getAncestor(IJavaElement.JAVA_PROJECT); - if (javaProject != null && javaProject.isOpen()) { - IProject project = javaProject.getProject(); - IFolder genFolder = project.getFolder(SdkConstants.FD_GEN_SOURCES); - if (genFolder.exists()) { - String javaPackagePath = mAppPackage.replace('.', '/'); - IPath genJavaPackagePath = genFolder.getFullPath().append(javaPackagePath); - IPackageFragment genPackageFragment = javaProject - .findPackageFragment(genJavaPackagePath); - return genPackageFragment; - } - } - return null; - } - - /** - * 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; - } - - private void addManifestFileChanges(CompositeChange result) { - addXmlFileChanges(mManifestFile, result, true); - } - - private void addLayoutFileChanges(IProject project, CompositeChange result) { - try { - // Update references in XML resource files - IFolder resFolder = project.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; - } - 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 (SdkUtils.endsWith(fileName, DOT_XML)) { - addXmlFileChanges(file, result, false); - } - } - } - } - } catch (CoreException e) { - RefactoringUtil.log(e); - } - } - - private boolean addXmlFileChanges(IFile file, CompositeChange changes, boolean isManifest) { - IModelManager modelManager = StructuredModelManager.getModelManager(); - IStructuredModel model = null; - try { - 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); - } - } - } else { - return false; - } - } - - return true; - } catch (IOException e) { - AdtPlugin.log(e, null); - } catch (CoreException e) { - AdtPlugin.log(e, null); - } finally { - if (model != null) { - model.releaseFromRead(); - } - } - - return false; - } - - private boolean isInRenamedPackage(String fqcn) { - return fqcn.startsWith(mOldPackage) - && fqcn.length() > mOldPackage.length() - && fqcn.indexOf('.', mOldPackage.length() + 1) == -1; - } - - 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.getAttributeNode(ATTR_CLASS); - if (classNode == null) { - 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; - } - } - 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))); - } - } - } - } - - 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) { - 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)); - } - } - } - - 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 (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); - } - } - } -} |