Home | History | Annotate | Download | only in renamepackage
      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 
     17 package com.android.ide.eclipse.adt.internal.refactorings.renamepackage;
     18 
     19 import static com.android.SdkConstants.FN_BUILD_CONFIG_BASE;
     20 import static com.android.SdkConstants.FN_MANIFEST_BASE;
     21 import static com.android.SdkConstants.FN_RESOURCE_BASE;
     22 
     23 import com.android.SdkConstants;
     24 import com.android.ide.eclipse.adt.AdtConstants;
     25 import com.android.ide.eclipse.adt.AdtPlugin;
     26 import com.android.xml.AndroidManifest;
     27 
     28 import org.eclipse.core.resources.IFile;
     29 import org.eclipse.core.resources.IFolder;
     30 import org.eclipse.core.resources.IMarker;
     31 import org.eclipse.core.resources.IProject;
     32 import org.eclipse.core.resources.IResource;
     33 import org.eclipse.core.resources.IResourceVisitor;
     34 import org.eclipse.core.runtime.CoreException;
     35 import org.eclipse.core.runtime.IPath;
     36 import org.eclipse.core.runtime.IProgressMonitor;
     37 import org.eclipse.core.runtime.OperationCanceledException;
     38 import org.eclipse.core.runtime.Status;
     39 import org.eclipse.jdt.core.ICompilationUnit;
     40 import org.eclipse.jdt.core.JavaCore;
     41 import org.eclipse.jdt.core.JavaModelException;
     42 import org.eclipse.jdt.core.dom.AST;
     43 import org.eclipse.jdt.core.dom.ASTParser;
     44 import org.eclipse.jdt.core.dom.ASTVisitor;
     45 import org.eclipse.jdt.core.dom.CompilationUnit;
     46 import org.eclipse.jdt.core.dom.ImportDeclaration;
     47 import org.eclipse.jdt.core.dom.Name;
     48 import org.eclipse.jdt.core.dom.QualifiedName;
     49 import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
     50 import org.eclipse.jdt.core.dom.rewrite.ImportRewrite;
     51 import org.eclipse.ltk.core.refactoring.Change;
     52 import org.eclipse.ltk.core.refactoring.CompositeChange;
     53 import org.eclipse.ltk.core.refactoring.Refactoring;
     54 import org.eclipse.ltk.core.refactoring.RefactoringStatus;
     55 import org.eclipse.ltk.core.refactoring.TextEditChangeGroup;
     56 import org.eclipse.ltk.core.refactoring.TextFileChange;
     57 import org.eclipse.text.edits.MalformedTreeException;
     58 import org.eclipse.text.edits.MultiTextEdit;
     59 import org.eclipse.text.edits.ReplaceEdit;
     60 import org.eclipse.text.edits.TextEdit;
     61 import org.eclipse.text.edits.TextEditGroup;
     62 import org.eclipse.wst.sse.core.StructuredModelManager;
     63 import org.eclipse.wst.sse.core.internal.provisional.IModelManager;
     64 import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
     65 import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;
     66 import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion;
     67 import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionList;
     68 import org.eclipse.wst.xml.core.internal.regions.DOMRegionContext;
     69 
     70 import java.io.IOException;
     71 import java.util.ArrayList;
     72 import java.util.Arrays;
     73 import java.util.Collections;
     74 import java.util.List;
     75 
     76 /**
     77  *  Wrapper class defining the stages of the refactoring process
     78  */
     79 @SuppressWarnings("restriction")
     80 class ApplicationPackageNameRefactoring extends Refactoring {
     81     private final IProject mProject;
     82     private final Name mOldPackageName;
     83     private final Name mNewPackageName;
     84 
     85     List<String> MAIN_COMPONENT_TYPES_LIST = Arrays.asList(MAIN_COMPONENT_TYPES);
     86 
     87     ApplicationPackageNameRefactoring(
     88             IProject project,
     89             Name oldPackageName,
     90             Name newPackageName) {
     91         mProject = project;
     92         mOldPackageName = oldPackageName;
     93         mNewPackageName = newPackageName;
     94     }
     95 
     96     @Override
     97     public RefactoringStatus checkInitialConditions(IProgressMonitor pm)
     98             throws CoreException, OperationCanceledException {
     99 
    100         // Accurate refactoring of the "shorthand" names in
    101         // AndroidManifest.xml depends on not having compilation errors.
    102         if (mProject.findMaxProblemSeverity(
    103                 IMarker.PROBLEM,
    104                 true,
    105                 IResource.DEPTH_INFINITE) == IMarker.SEVERITY_ERROR) {
    106             return
    107                 RefactoringStatus.createFatalErrorStatus("Fix the errors in your project, first.");
    108         }
    109 
    110         return new RefactoringStatus();
    111     }
    112 
    113     @Override
    114     public RefactoringStatus checkFinalConditions(IProgressMonitor pm)
    115             throws OperationCanceledException {
    116 
    117         return new RefactoringStatus();
    118     }
    119 
    120     @Override
    121     public Change createChange(IProgressMonitor pm) throws CoreException,
    122     OperationCanceledException {
    123 
    124         // Traverse all files in the project, building up a list of changes
    125         JavaFileVisitor fileVisitor = new JavaFileVisitor();
    126         mProject.accept(fileVisitor);
    127         return fileVisitor.getChange();
    128     }
    129 
    130     @Override
    131     public String getName() {
    132         return "AndroidPackageNameRefactoring"; //$NON-NLS-1$
    133     }
    134 
    135     public final static String[] MAIN_COMPONENT_TYPES = {
    136         AndroidManifest.NODE_ACTIVITY, AndroidManifest.NODE_SERVICE,
    137         AndroidManifest.NODE_RECEIVER, AndroidManifest.NODE_PROVIDER,
    138         AndroidManifest.NODE_APPLICATION
    139     };
    140 
    141 
    142     TextEdit updateJavaFileImports(CompilationUnit cu) {
    143 
    144         ImportVisitor importVisitor = new ImportVisitor(cu.getAST());
    145         cu.accept(importVisitor);
    146         TextEdit rewrittenImports = importVisitor.getTextEdit();
    147 
    148         // If the import of R was potentially implicit, insert an import statement
    149         if (rewrittenImports != null && cu.getPackage().getName().getFullyQualifiedName()
    150                 .equals(mOldPackageName.getFullyQualifiedName())) {
    151 
    152             UsageVisitor usageVisitor = new UsageVisitor();
    153             cu.accept(usageVisitor);
    154 
    155             if (usageVisitor.seenAny()) {
    156                 ImportRewrite irw = ImportRewrite.create(cu, true);
    157                 if (usageVisitor.hasSeenR()) {
    158                     irw.addImport(mNewPackageName.getFullyQualifiedName() + '.'
    159                             + FN_RESOURCE_BASE);
    160                 }
    161                 if (usageVisitor.hasSeenBuildConfig()) {
    162                     irw.addImport(mNewPackageName.getFullyQualifiedName() + '.'
    163                             + FN_BUILD_CONFIG_BASE);
    164                 }
    165                 if (usageVisitor.hasSeenManifest()) {
    166                     irw.addImport(mNewPackageName.getFullyQualifiedName() + '.'
    167                             + FN_MANIFEST_BASE);
    168                 }
    169 
    170                 try {
    171                     rewrittenImports.addChild( irw.rewriteImports(null) );
    172                 } catch (MalformedTreeException e) {
    173                     Status s = new Status(Status.ERROR, AdtPlugin.PLUGIN_ID, e.getMessage(), e);
    174                     AdtPlugin.getDefault().getLog().log(s);
    175                 } catch (CoreException e) {
    176                     Status s = new Status(Status.ERROR, AdtPlugin.PLUGIN_ID, e.getMessage(), e);
    177                     AdtPlugin.getDefault().getLog().log(s);
    178                 }
    179             }
    180         }
    181 
    182         return rewrittenImports;
    183     }
    184 
    185     // XML utility functions
    186     private String stripQuotes(String text) {
    187         int len = text.length();
    188         if (len >= 2 && text.charAt(0) == '"' && text.charAt(len - 1) == '"') {
    189             return text.substring(1, len - 1);
    190         } else if (len >= 2 && text.charAt(0) == '\'' && text.charAt(len - 1) == '\'') {
    191             return text.substring(1, len - 1);
    192         }
    193         return text;
    194     }
    195 
    196     private String addQuotes(String text) {
    197         return '"' + text + '"';
    198     }
    199 
    200     /*
    201      * Make the appropriate package name changes to a resource file,
    202      * e.g. .xml files in res/layout. This entails updating the namespace
    203      * declarations for custom styleable attributes.  The namespace prefix
    204      * is user-defined and may be declared in any element where or parent
    205      * element of where the prefix is used.
    206      */
    207     TextFileChange editXmlResourceFile(IFile file) {
    208 
    209         IModelManager modelManager = StructuredModelManager.getModelManager();
    210         IStructuredDocument sdoc = null;
    211         try {
    212             sdoc = modelManager.createStructuredDocumentFor(file);
    213         } catch (IOException e) {
    214             Status s = new Status(Status.ERROR, AdtPlugin.PLUGIN_ID, e.getMessage(), e);
    215             AdtPlugin.getDefault().getLog().log(s);
    216         } catch (CoreException e) {
    217             Status s = new Status(Status.ERROR, AdtPlugin.PLUGIN_ID, e.getMessage(), e);
    218             AdtPlugin.getDefault().getLog().log(s);
    219         }
    220 
    221         if (sdoc == null) {
    222             return null;
    223         }
    224 
    225         TextFileChange xmlChange = new TextFileChange("XML resource file edit", file);
    226         xmlChange.setTextType(SdkConstants.EXT_XML);
    227 
    228         MultiTextEdit multiEdit = new MultiTextEdit();
    229         ArrayList<TextEditGroup> editGroups = new ArrayList<TextEditGroup>();
    230 
    231         final String oldAppNamespaceString = String.format(AdtConstants.NS_CUSTOM_RESOURCES,
    232                 mOldPackageName.getFullyQualifiedName());
    233         final String newAppNamespaceString = String.format(AdtConstants.NS_CUSTOM_RESOURCES,
    234                 mNewPackageName.getFullyQualifiedName());
    235 
    236         // Prepare the change set
    237         for (IStructuredDocumentRegion region : sdoc.getStructuredDocumentRegions()) {
    238 
    239             if (!DOMRegionContext.XML_TAG_NAME.equals(region.getType())) {
    240                 continue;
    241             }
    242 
    243             int nb = region.getNumberOfRegions();
    244             ITextRegionList list = region.getRegions();
    245             String lastAttrName = null;
    246 
    247             for (int i = 0; i < nb; i++) {
    248                 ITextRegion subRegion = list.get(i);
    249                 String type = subRegion.getType();
    250 
    251                 if (DOMRegionContext.XML_TAG_ATTRIBUTE_NAME.equals(type)) {
    252                     // Memorize the last attribute name seen
    253                     lastAttrName = region.getText(subRegion);
    254 
    255                 } else if (DOMRegionContext.XML_TAG_ATTRIBUTE_VALUE.equals(type)) {
    256                     // Check this is the attribute and the original string
    257 
    258                     if (lastAttrName != null &&
    259                             lastAttrName.startsWith(SdkConstants.XMLNS_PREFIX)) {
    260 
    261                         String lastAttrValue = region.getText(subRegion);
    262                         if (oldAppNamespaceString.equals(stripQuotes(lastAttrValue))) {
    263 
    264                             // Found an occurrence. Create a change for it.
    265                             TextEdit edit = new ReplaceEdit(
    266                                     region.getStartOffset() + subRegion.getStart(),
    267                                     subRegion.getTextLength(),
    268                                     addQuotes(newAppNamespaceString));
    269                             TextEditGroup editGroup = new TextEditGroup(
    270                                     "Replace package name in custom namespace prefix", edit);
    271 
    272                             multiEdit.addChild(edit);
    273                             editGroups.add(editGroup);
    274                         }
    275                     }
    276                 }
    277             }
    278         }
    279 
    280         if (multiEdit.hasChildren()) {
    281             xmlChange.setEdit(multiEdit);
    282             for (TextEditGroup group : editGroups) {
    283                 xmlChange.addTextEditChangeGroup(new TextEditChangeGroup(xmlChange, group));
    284             }
    285 
    286             return xmlChange;
    287         }
    288         return null;
    289     }
    290 
    291     /*
    292      * Replace all instances of the package name in AndroidManifest.xml.
    293      * This includes expanding shorthand paths for each Component (Activity,
    294      * Service, etc.) and of course updating the application package name.
    295      * The namespace prefix might not be "android", so we resolve it
    296      * dynamically.
    297      */
    298     TextFileChange editAndroidManifest(IFile file) {
    299 
    300         IModelManager modelManager = StructuredModelManager.getModelManager();
    301         IStructuredDocument sdoc = null;
    302         try {
    303             sdoc = modelManager.createStructuredDocumentFor(file);
    304         } catch (IOException e) {
    305             Status s = new Status(Status.ERROR, AdtPlugin.PLUGIN_ID, e.getMessage(), e);
    306             AdtPlugin.getDefault().getLog().log(s);
    307         } catch (CoreException e) {
    308             Status s = new Status(Status.ERROR, AdtPlugin.PLUGIN_ID, e.getMessage(), e);
    309             AdtPlugin.getDefault().getLog().log(s);
    310         }
    311 
    312         if (sdoc == null) {
    313             return null;
    314         }
    315 
    316         TextFileChange xmlChange = new TextFileChange("Make Manifest edits", file);
    317         xmlChange.setTextType(SdkConstants.EXT_XML);
    318 
    319         MultiTextEdit multiEdit = new MultiTextEdit();
    320         ArrayList<TextEditGroup> editGroups = new ArrayList<TextEditGroup>();
    321 
    322         // The namespace prefix is guaranteed to be resolved before
    323         // the first use of this attribute
    324         String android_name_attribute = null;
    325 
    326         // Prepare the change set
    327         for (IStructuredDocumentRegion region : sdoc.getStructuredDocumentRegions()) {
    328 
    329             // Only look at XML "top regions"
    330             if (!DOMRegionContext.XML_TAG_NAME.equals(region.getType())) {
    331                 continue;
    332             }
    333 
    334             int nb = region.getNumberOfRegions();
    335             ITextRegionList list = region.getRegions();
    336             String lastTagName = null, lastAttrName = null;
    337 
    338             for (int i = 0; i < nb; i++) {
    339                 ITextRegion subRegion = list.get(i);
    340                 String type = subRegion.getType();
    341 
    342                 if (DOMRegionContext.XML_TAG_NAME.equals(type)) {
    343                     // Memorize the last tag name seen
    344                     lastTagName = region.getText(subRegion);
    345 
    346                 } else if (DOMRegionContext.XML_TAG_ATTRIBUTE_NAME.equals(type)) {
    347                     // Memorize the last attribute name seen
    348                     lastAttrName = region.getText(subRegion);
    349 
    350                 } else if (DOMRegionContext.XML_TAG_ATTRIBUTE_VALUE.equals(type)) {
    351 
    352                     String lastAttrValue = region.getText(subRegion);
    353                     if (lastAttrName != null &&
    354                             lastAttrName.startsWith(SdkConstants.XMLNS_PREFIX)) {
    355 
    356                         // Resolves the android namespace prefix for this file
    357                         if (SdkConstants.ANDROID_URI.equals(stripQuotes(lastAttrValue))) {
    358                             String android_namespace_prefix = lastAttrName
    359                                 .substring(SdkConstants.XMLNS_PREFIX.length());
    360                             android_name_attribute = android_namespace_prefix + ':'
    361                                 + AndroidManifest.ATTRIBUTE_NAME;
    362                         }
    363                     } else if (AndroidManifest.NODE_MANIFEST.equals(lastTagName)
    364                             && AndroidManifest.ATTRIBUTE_PACKAGE.equals(lastAttrName)) {
    365 
    366                         // Found an occurrence. Create a change for it.
    367                         TextEdit edit = new ReplaceEdit(region.getStartOffset()
    368                                 + subRegion.getStart(), subRegion.getTextLength(),
    369                                 addQuotes(mNewPackageName.getFullyQualifiedName()));
    370 
    371                         multiEdit.addChild(edit);
    372                         editGroups.add(new TextEditGroup("Change Android package name", edit));
    373 
    374                     } else if (MAIN_COMPONENT_TYPES_LIST.contains(lastTagName)
    375                             && lastAttrName != null
    376                             && lastAttrName.equals(android_name_attribute)) {
    377 
    378                         String package_path = stripQuotes(lastAttrValue);
    379                         String old_package_name_string = mOldPackageName.getFullyQualifiedName();
    380 
    381                         String absolute_path = AndroidManifest.combinePackageAndClassName(
    382                                 old_package_name_string, package_path);
    383 
    384                         TextEdit edit = new ReplaceEdit(region.getStartOffset()
    385                                 + subRegion.getStart(), subRegion.getTextLength(),
    386                                 addQuotes(absolute_path));
    387 
    388                         multiEdit.addChild(edit);
    389 
    390                         editGroups.add(new TextEditGroup("Update component path", edit));
    391                     }
    392                 }
    393             }
    394         }
    395 
    396         if (multiEdit.hasChildren()) {
    397             xmlChange.setEdit(multiEdit);
    398             for (TextEditGroup group : editGroups) {
    399                 xmlChange.addTextEditChangeGroup(new TextEditChangeGroup(xmlChange, group));
    400             }
    401 
    402             return xmlChange;
    403         }
    404         return null;
    405     }
    406 
    407 
    408     /*
    409      * Iterates through all project files, taking distinct actions based on
    410      * whether the file is:
    411      * 1) a .java file (replaces or inserts the "import" statements)
    412      * 2) a .xml layout file (updates namespace declarations)
    413      * 3) the AndroidManifest.xml
    414      */
    415     class JavaFileVisitor implements IResourceVisitor {
    416 
    417         final List<TextFileChange> mChanges = new ArrayList<TextFileChange>();
    418 
    419         final ASTParser mParser = ASTParser.newParser(AST.JLS3);
    420 
    421         public CompositeChange getChange() {
    422 
    423             Collections.reverse(mChanges);
    424             CompositeChange change = new CompositeChange("Refactoring Application package name",
    425                     mChanges.toArray(new Change[mChanges.size()]));
    426             change.markAsSynthetic();
    427             return change;
    428         }
    429 
    430         @Override
    431         public boolean visit(IResource resource) throws CoreException {
    432             if (resource instanceof IFile) {
    433                 IFile file = (IFile) resource;
    434                 if (SdkConstants.EXT_JAVA.equals(file.getFileExtension())) {
    435 
    436                     ICompilationUnit icu = JavaCore.createCompilationUnitFrom(file);
    437 
    438                     mParser.setSource(icu);
    439                     CompilationUnit cu = (CompilationUnit) mParser.createAST(null);
    440 
    441                     TextEdit textEdit = updateJavaFileImports(cu);
    442                     if (textEdit != null && textEdit.hasChildren()) {
    443                         MultiTextEdit edit = new MultiTextEdit();
    444                         edit.addChild(textEdit);
    445 
    446                         TextFileChange text_file_change = new TextFileChange(file.getName(), file);
    447                         text_file_change.setTextType(SdkConstants.EXT_JAVA);
    448                         text_file_change.setEdit(edit);
    449                         mChanges.add(text_file_change);
    450                     }
    451 
    452                     // XXX Partially taken from ExtractStringRefactoring.java
    453                     // Check this a Layout XML file and get the selection and
    454                     // its context.
    455                 } else if (SdkConstants.EXT_XML.equals(file.getFileExtension())) {
    456 
    457                     if (SdkConstants.FN_ANDROID_MANIFEST_XML.equals(file.getName())) {
    458                         // Ensure that this is the root manifest, not some other copy
    459                         // (such as the one in bin/)
    460                         IPath path = file.getFullPath();
    461                         if (path.segmentCount() == 2) {
    462                             TextFileChange manifest_change = editAndroidManifest(file);
    463                             mChanges.add(manifest_change);
    464                         }
    465                     } else {
    466 
    467                         // Currently we only support Android resource XML files,
    468                         // so they must have a path similar to
    469                         //   project/res/<type>[-<configuration>]/*.xml
    470                         // There is no support for sub folders, so the segment count must be 4.
    471                         // We don't need to check the type folder name because
    472                         // a/ we only accept an AndroidXmlEditor source and
    473                         // b/ aapt generates a compilation error for unknown folders.
    474                         IPath path = file.getFullPath();
    475                         // check if we are inside the project/res/* folder.
    476                         if (path.segmentCount() == 4) {
    477                             if (path.segment(1).equalsIgnoreCase(SdkConstants.FD_RESOURCES)) {
    478 
    479 
    480                                 TextFileChange xmlChange = editXmlResourceFile(file);
    481                                 if (xmlChange != null) {
    482                                     mChanges.add(xmlChange);
    483                                 }
    484                             }
    485                         }
    486                     }
    487                 }
    488 
    489                 return false;
    490 
    491             } else if (resource instanceof IFolder) {
    492                 return !SdkConstants.FD_GEN_SOURCES.equals(resource.getName());
    493             }
    494 
    495             return true;
    496         }
    497     }
    498 
    499     private static class UsageVisitor extends ASTVisitor {
    500         private boolean mSeenManifest;
    501         private boolean mSeenR;
    502         private boolean mSeenBuildConfig;
    503 
    504         @Override
    505         public boolean visit(QualifiedName node) {
    506             Name qualifier = node.getQualifier();
    507             if (qualifier.isSimpleName()) {
    508                 String name = qualifier.toString();
    509                 if (name.equals(FN_RESOURCE_BASE)) {
    510                     mSeenR = true;
    511                 } else if (name.equals(FN_BUILD_CONFIG_BASE)) {
    512                     mSeenBuildConfig = true;
    513                 } else if (name.equals(FN_MANIFEST_BASE)) {
    514                     mSeenManifest = true;
    515                 }
    516             }
    517             return super.visit(node);
    518         };
    519 
    520         public boolean seenAny() {
    521             return mSeenR || mSeenBuildConfig || mSeenManifest;
    522         }
    523 
    524         public boolean hasSeenBuildConfig() {
    525             return mSeenBuildConfig;
    526         }
    527         public boolean hasSeenManifest() {
    528             return mSeenManifest;
    529         }
    530         public boolean hasSeenR() {
    531             return mSeenR;
    532         }
    533     }
    534 
    535     private class ImportVisitor extends ASTVisitor {
    536 
    537         final AST mAst;
    538         final ASTRewrite mRewriter;
    539 
    540         ImportVisitor(AST ast) {
    541             mAst = ast;
    542             mRewriter = ASTRewrite.create(ast);
    543         }
    544 
    545         public TextEdit getTextEdit() {
    546             try {
    547                 return this.mRewriter.rewriteAST();
    548             } catch (JavaModelException e) {
    549                 Status s = new Status(Status.ERROR, AdtPlugin.PLUGIN_ID, e.getMessage(), e);
    550                 AdtPlugin.getDefault().getLog().log(s);
    551             } catch (IllegalArgumentException e) {
    552                 Status s = new Status(Status.ERROR, AdtPlugin.PLUGIN_ID, e.getMessage(), e);
    553                 AdtPlugin.getDefault().getLog().log(s);
    554             }
    555             return null;
    556         }
    557 
    558         @Override
    559         public boolean visit(ImportDeclaration id) {
    560 
    561             Name importName = id.getName();
    562             if (importName.isQualifiedName()) {
    563                 QualifiedName qualifiedImportName = (QualifiedName) importName;
    564 
    565                 String identifier = qualifiedImportName.getName().getIdentifier();
    566                 if (identifier.equals(FN_RESOURCE_BASE)) {
    567                     mRewriter.replace(qualifiedImportName.getQualifier(), mNewPackageName,
    568                             null);
    569                 } else if (identifier.equals(FN_BUILD_CONFIG_BASE)
    570                         && mOldPackageName.toString().equals(
    571                                 qualifiedImportName.getQualifier().toString())) {
    572                     mRewriter.replace(qualifiedImportName.getQualifier(), mNewPackageName,
    573                             null);
    574 
    575                 } else if (identifier.equals(FN_MANIFEST_BASE)
    576                         && mOldPackageName.toString().equals(
    577                                 qualifiedImportName.getQualifier().toString())) {
    578                     mRewriter.replace(qualifiedImportName.getQualifier(), mNewPackageName,
    579                             null);
    580                 }
    581             }
    582 
    583             return true;
    584         }
    585     }
    586 }
    587