diff options
Diffstat (limited to 'eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/renamepackage/ApplicationPackageNameRefactoring.java')
-rw-r--r-- | eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/renamepackage/ApplicationPackageNameRefactoring.java | 586 |
1 files changed, 0 insertions, 586 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/renamepackage/ApplicationPackageNameRefactoring.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/renamepackage/ApplicationPackageNameRefactoring.java deleted file mode 100644 index 406cebca4..000000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/renamepackage/ApplicationPackageNameRefactoring.java +++ /dev/null @@ -1,586 +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.renamepackage; - -import static com.android.SdkConstants.FN_BUILD_CONFIG_BASE; -import static com.android.SdkConstants.FN_MANIFEST_BASE; -import static com.android.SdkConstants.FN_RESOURCE_BASE; - -import com.android.SdkConstants; -import com.android.ide.eclipse.adt.AdtConstants; -import com.android.ide.eclipse.adt.AdtPlugin; -import com.android.xml.AndroidManifest; - -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IFolder; -import org.eclipse.core.resources.IMarker; -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.IPath; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.OperationCanceledException; -import org.eclipse.core.runtime.Status; -import org.eclipse.jdt.core.ICompilationUnit; -import org.eclipse.jdt.core.JavaCore; -import org.eclipse.jdt.core.JavaModelException; -import org.eclipse.jdt.core.dom.AST; -import org.eclipse.jdt.core.dom.ASTParser; -import org.eclipse.jdt.core.dom.ASTVisitor; -import org.eclipse.jdt.core.dom.CompilationUnit; -import org.eclipse.jdt.core.dom.ImportDeclaration; -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.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.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.wst.sse.core.StructuredModelManager; -import org.eclipse.wst.sse.core.internal.provisional.IModelManager; -import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument; -import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion; -import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion; -import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionList; -import org.eclipse.wst.xml.core.internal.regions.DOMRegionContext; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -/** - * Wrapper class defining the stages of the refactoring process - */ -@SuppressWarnings("restriction") -class ApplicationPackageNameRefactoring extends Refactoring { - private final IProject mProject; - private final Name mOldPackageName; - private final Name mNewPackageName; - - List<String> MAIN_COMPONENT_TYPES_LIST = Arrays.asList(MAIN_COMPONENT_TYPES); - - ApplicationPackageNameRefactoring( - IProject project, - Name oldPackageName, - Name newPackageName) { - mProject = project; - mOldPackageName = oldPackageName; - mNewPackageName = newPackageName; - } - - @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 RefactoringStatus checkFinalConditions(IProgressMonitor pm) - throws OperationCanceledException { - - 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 fileVisitor = new JavaFileVisitor(); - mProject.accept(fileVisitor); - return fileVisitor.getChange(); - } - - @Override - public String getName() { - return "AndroidPackageNameRefactoring"; //$NON-NLS-1$ - } - - public final static String[] MAIN_COMPONENT_TYPES = { - AndroidManifest.NODE_ACTIVITY, AndroidManifest.NODE_SERVICE, - AndroidManifest.NODE_RECEIVER, AndroidManifest.NODE_PROVIDER, - AndroidManifest.NODE_APPLICATION - }; - - - TextEdit updateJavaFileImports(CompilationUnit cu) { - - 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 (rewrittenImports != null && cu.getPackage().getName().getFullyQualifiedName() - .equals(mOldPackageName.getFullyQualifiedName())) { - - UsageVisitor usageVisitor = new UsageVisitor(); - cu.accept(usageVisitor); - - if (usageVisitor.seenAny()) { - ImportRewrite irw = ImportRewrite.create(cu, true); - if (usageVisitor.hasSeenR()) { - irw.addImport(mNewPackageName.getFullyQualifiedName() + '.' - + FN_RESOURCE_BASE); - } - if (usageVisitor.hasSeenBuildConfig()) { - irw.addImport(mNewPackageName.getFullyQualifiedName() + '.' - + FN_BUILD_CONFIG_BASE); - } - if (usageVisitor.hasSeenManifest()) { - irw.addImport(mNewPackageName.getFullyQualifiedName() + '.' - + FN_MANIFEST_BASE); - } - - try { - 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); - } catch (CoreException e) { - Status s = new Status(Status.ERROR, AdtPlugin.PLUGIN_ID, e.getMessage(), e); - AdtPlugin.getDefault().getLog().log(s); - } - } - } - - return rewrittenImports; - } - - // XML utility functions - private String stripQuotes(String text) { - int len = text.length(); - if (len >= 2 && text.charAt(0) == '"' && text.charAt(len - 1) == '"') { - return text.substring(1, len - 1); - } else if (len >= 2 && text.charAt(0) == '\'' && text.charAt(len - 1) == '\'') { - return text.substring(1, len - 1); - } - return text; - } - - private String addQuotes(String text) { - return '"' + text + '"'; - } - - /* - * Make the appropriate package name changes to a resource file, - * e.g. .xml files in res/layout. This entails updating the namespace - * declarations for custom styleable attributes. The namespace prefix - * is user-defined and may be declared in any element where or parent - * element of where the prefix is used. - */ - TextFileChange editXmlResourceFile(IFile file) { - - IModelManager modelManager = StructuredModelManager.getModelManager(); - IStructuredDocument sdoc = null; - try { - sdoc = modelManager.createStructuredDocumentFor(file); - } catch (IOException e) { - Status s = new Status(Status.ERROR, AdtPlugin.PLUGIN_ID, e.getMessage(), e); - AdtPlugin.getDefault().getLog().log(s); - } catch (CoreException e) { - Status s = new Status(Status.ERROR, AdtPlugin.PLUGIN_ID, e.getMessage(), e); - AdtPlugin.getDefault().getLog().log(s); - } - - if (sdoc == null) { - return null; - } - - TextFileChange xmlChange = new TextFileChange("XML resource file edit", file); - xmlChange.setTextType(SdkConstants.EXT_XML); - - MultiTextEdit multiEdit = new MultiTextEdit(); - ArrayList<TextEditGroup> editGroups = new ArrayList<TextEditGroup>(); - - final String oldAppNamespaceString = String.format(AdtConstants.NS_CUSTOM_RESOURCES, - mOldPackageName.getFullyQualifiedName()); - final String newAppNamespaceString = String.format(AdtConstants.NS_CUSTOM_RESOURCES, - mNewPackageName.getFullyQualifiedName()); - - // Prepare the change set - for (IStructuredDocumentRegion region : sdoc.getStructuredDocumentRegions()) { - - if (!DOMRegionContext.XML_TAG_NAME.equals(region.getType())) { - continue; - } - - int nb = region.getNumberOfRegions(); - ITextRegionList list = region.getRegions(); - String lastAttrName = null; - - for (int i = 0; i < nb; i++) { - ITextRegion subRegion = list.get(i); - String type = subRegion.getType(); - - if (DOMRegionContext.XML_TAG_ATTRIBUTE_NAME.equals(type)) { - // Memorize the last attribute name seen - lastAttrName = region.getText(subRegion); - - } else if (DOMRegionContext.XML_TAG_ATTRIBUTE_VALUE.equals(type)) { - // Check this is the attribute and the original string - - if (lastAttrName != null && - lastAttrName.startsWith(SdkConstants.XMLNS_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(), - addQuotes(newAppNamespaceString)); - TextEditGroup editGroup = new TextEditGroup( - "Replace package name in custom namespace prefix", edit); - - multiEdit.addChild(edit); - editGroups.add(editGroup); - } - } - } - } - } - - if (multiEdit.hasChildren()) { - xmlChange.setEdit(multiEdit); - for (TextEditGroup group : editGroups) { - xmlChange.addTextEditChangeGroup(new TextEditChangeGroup(xmlChange, group)); - } - - return xmlChange; - } - return null; - } - - /* - * Replace all instances of the package name in AndroidManifest.xml. - * This includes expanding shorthand paths for each Component (Activity, - * Service, etc.) and of course updating the application package name. - * The namespace prefix might not be "android", so we resolve it - * dynamically. - */ - TextFileChange editAndroidManifest(IFile file) { - - IModelManager modelManager = StructuredModelManager.getModelManager(); - IStructuredDocument sdoc = null; - try { - sdoc = modelManager.createStructuredDocumentFor(file); - } catch (IOException e) { - Status s = new Status(Status.ERROR, AdtPlugin.PLUGIN_ID, e.getMessage(), e); - AdtPlugin.getDefault().getLog().log(s); - } catch (CoreException e) { - Status s = new Status(Status.ERROR, AdtPlugin.PLUGIN_ID, e.getMessage(), e); - AdtPlugin.getDefault().getLog().log(s); - } - - if (sdoc == null) { - return null; - } - - TextFileChange xmlChange = new TextFileChange("Make Manifest edits", file); - xmlChange.setTextType(SdkConstants.EXT_XML); - - MultiTextEdit multiEdit = new MultiTextEdit(); - ArrayList<TextEditGroup> editGroups = new ArrayList<TextEditGroup>(); - - // The namespace prefix is guaranteed to be resolved before - // the first use of this attribute - String android_name_attribute = null; - - // Prepare the change set - for (IStructuredDocumentRegion region : sdoc.getStructuredDocumentRegions()) { - - // Only look at XML "top regions" - if (!DOMRegionContext.XML_TAG_NAME.equals(region.getType())) { - continue; - } - - int nb = region.getNumberOfRegions(); - ITextRegionList list = region.getRegions(); - String lastTagName = null, lastAttrName = null; - - for (int i = 0; i < nb; i++) { - ITextRegion subRegion = list.get(i); - String type = subRegion.getType(); - - if (DOMRegionContext.XML_TAG_NAME.equals(type)) { - // Memorize the last tag name seen - lastTagName = region.getText(subRegion); - - } else if (DOMRegionContext.XML_TAG_ATTRIBUTE_NAME.equals(type)) { - // Memorize the last attribute name seen - lastAttrName = region.getText(subRegion); - - } else if (DOMRegionContext.XML_TAG_ATTRIBUTE_VALUE.equals(type)) { - - String lastAttrValue = region.getText(subRegion); - if (lastAttrName != null && - lastAttrName.startsWith(SdkConstants.XMLNS_PREFIX)) { - - // Resolves the android namespace prefix for this file - if (SdkConstants.ANDROID_URI.equals(stripQuotes(lastAttrValue))) { - String android_namespace_prefix = lastAttrName - .substring(SdkConstants.XMLNS_PREFIX.length()); - android_name_attribute = android_namespace_prefix + ':' - + AndroidManifest.ATTRIBUTE_NAME; - } - } else if (AndroidManifest.NODE_MANIFEST.equals(lastTagName) - && AndroidManifest.ATTRIBUTE_PACKAGE.equals(lastAttrName)) { - - // Found an occurrence. Create a change for it. - TextEdit edit = new ReplaceEdit(region.getStartOffset() - + subRegion.getStart(), subRegion.getTextLength(), - addQuotes(mNewPackageName.getFullyQualifiedName())); - - multiEdit.addChild(edit); - 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); - String old_package_name_string = mOldPackageName.getFullyQualifiedName(); - - String absolute_path = AndroidManifest.combinePackageAndClassName( - old_package_name_string, package_path); - - TextEdit edit = new ReplaceEdit(region.getStartOffset() - + subRegion.getStart(), subRegion.getTextLength(), - addQuotes(absolute_path)); - - multiEdit.addChild(edit); - - editGroups.add(new TextEditGroup("Update component path", edit)); - } - } - } - } - - if (multiEdit.hasChildren()) { - xmlChange.setEdit(multiEdit); - for (TextEditGroup group : editGroups) { - xmlChange.addTextEditChangeGroup(new TextEditChangeGroup(xmlChange, group)); - } - - return xmlChange; - } - return null; - } - - - /* - * Iterates through all project files, taking distinct actions based on - * whether the file is: - * 1) a .java file (replaces or inserts the "import" statements) - * 2) a .xml layout file (updates namespace declarations) - * 3) the AndroidManifest.xml - */ - class JavaFileVisitor implements IResourceVisitor { - - final List<TextFileChange> mChanges = new ArrayList<TextFileChange>(); - - final ASTParser mParser = ASTParser.newParser(AST.JLS3); - - public CompositeChange getChange() { - - Collections.reverse(mChanges); - CompositeChange change = new CompositeChange("Refactoring Application package name", - mChanges.toArray(new Change[mChanges.size()])); - change.markAsSynthetic(); - return change; - } - - @Override - public boolean visit(IResource resource) throws CoreException { - if (resource instanceof IFile) { - IFile file = (IFile) resource; - if (SdkConstants.EXT_JAVA.equals(file.getFileExtension())) { - - ICompilationUnit icu = JavaCore.createCompilationUnitFrom(file); - - mParser.setSource(icu); - CompilationUnit cu = (CompilationUnit) mParser.createAST(null); - - TextEdit textEdit = updateJavaFileImports(cu); - if (textEdit != null && textEdit.hasChildren()) { - MultiTextEdit edit = new MultiTextEdit(); - edit.addChild(textEdit); - - TextFileChange text_file_change = new TextFileChange(file.getName(), file); - text_file_change.setTextType(SdkConstants.EXT_JAVA); - text_file_change.setEdit(edit); - mChanges.add(text_file_change); - } - - // XXX Partially taken from ExtractStringRefactoring.java - // Check this a Layout XML file and get the selection and - // its context. - } else if (SdkConstants.EXT_XML.equals(file.getFileExtension())) { - - if (SdkConstants.FN_ANDROID_MANIFEST_XML.equals(file.getName())) { - // Ensure that this is the root manifest, not some other copy - // (such as the one in bin/) - IPath path = file.getFullPath(); - if (path.segmentCount() == 2) { - TextFileChange manifest_change = editAndroidManifest(file); - mChanges.add(manifest_change); - } - } 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. - // 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. - IPath path = file.getFullPath(); - // check if we are inside the project/res/* folder. - if (path.segmentCount() == 4) { - if (path.segment(1).equalsIgnoreCase(SdkConstants.FD_RESOURCES)) { - - - TextFileChange xmlChange = editXmlResourceFile(file); - if (xmlChange != null) { - mChanges.add(xmlChange); - } - } - } - } - } - - return false; - - } else if (resource instanceof IFolder) { - return !SdkConstants.FD_GEN_SOURCES.equals(resource.getName()); - } - - return true; - } - } - - private static class UsageVisitor extends ASTVisitor { - private boolean mSeenManifest; - private boolean mSeenR; - private boolean mSeenBuildConfig; - - @Override - public boolean visit(QualifiedName node) { - Name qualifier = node.getQualifier(); - if (qualifier.isSimpleName()) { - String name = qualifier.toString(); - if (name.equals(FN_RESOURCE_BASE)) { - mSeenR = true; - } else if (name.equals(FN_BUILD_CONFIG_BASE)) { - mSeenBuildConfig = true; - } else if (name.equals(FN_MANIFEST_BASE)) { - mSeenManifest = true; - } - } - return super.visit(node); - }; - - public boolean seenAny() { - return mSeenR || mSeenBuildConfig || mSeenManifest; - } - - public boolean hasSeenBuildConfig() { - return mSeenBuildConfig; - } - public boolean hasSeenManifest() { - return mSeenManifest; - } - public boolean hasSeenR() { - return mSeenR; - } - } - - private class ImportVisitor extends ASTVisitor { - - final AST mAst; - final ASTRewrite mRewriter; - - ImportVisitor(AST ast) { - mAst = ast; - mRewriter = ASTRewrite.create(ast); - } - - public TextEdit getTextEdit() { - try { - return this.mRewriter.rewriteAST(); - } catch (JavaModelException e) { - Status s = new Status(Status.ERROR, AdtPlugin.PLUGIN_ID, e.getMessage(), e); - AdtPlugin.getDefault().getLog().log(s); - } catch (IllegalArgumentException e) { - Status s = new Status(Status.ERROR, AdtPlugin.PLUGIN_ID, e.getMessage(), e); - AdtPlugin.getDefault().getLog().log(s); - } - return null; - } - - @Override - public boolean visit(ImportDeclaration id) { - - Name importName = id.getName(); - if (importName.isQualifiedName()) { - QualifiedName qualifiedImportName = (QualifiedName) importName; - - String identifier = qualifiedImportName.getName().getIdentifier(); - if (identifier.equals(FN_RESOURCE_BASE)) { - mRewriter.replace(qualifiedImportName.getQualifier(), mNewPackageName, - null); - } else if (identifier.equals(FN_BUILD_CONFIG_BASE) - && mOldPackageName.toString().equals( - qualifiedImportName.getQualifier().toString())) { - mRewriter.replace(qualifiedImportName.getQualifier(), mNewPackageName, - null); - - } else if (identifier.equals(FN_MANIFEST_BASE) - && mOldPackageName.toString().equals( - qualifiedImportName.getQualifier().toString())) { - mRewriter.replace(qualifiedImportName.getQualifier(), mNewPackageName, - null); - } - } - - return true; - } - } -} |