/*
 * Copyright (C) 2012 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_PREFIX;
import static com.android.SdkConstants.ANDROID_URI;
import static com.android.SdkConstants.ATTR_ID;
import static com.android.SdkConstants.ATTR_NAME;
import static com.android.SdkConstants.ATTR_TYPE;
import static com.android.SdkConstants.DOT_XML;
import static com.android.SdkConstants.EXT_XML;
import static com.android.SdkConstants.FD_RES;
import static com.android.SdkConstants.FN_RESOURCE_CLASS;
import static com.android.SdkConstants.NEW_ID_PREFIX;
import static com.android.SdkConstants.PREFIX_RESOURCE_REF;
import static com.android.SdkConstants.PREFIX_THEME_REF;
import static com.android.SdkConstants.R_CLASS;
import static com.android.SdkConstants.TAG_ITEM;
import static com.android.SdkConstants.TOOLS_URI;

import com.android.SdkConstants;
import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.AdtUtils;
import com.android.ide.eclipse.adt.internal.editors.manifest.ManifestInfo;
import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper;
import com.android.ide.eclipse.adt.internal.resources.ResourceNameValidator;
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.resources.ResourceType;
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.IField;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.internal.corext.refactoring.rename.RenameFieldProcessor;
import org.eclipse.ltk.core.refactoring.Change;
import org.eclipse.ltk.core.refactoring.CompositeChange;
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
import org.eclipse.ltk.core.refactoring.TextChange;
import org.eclipse.ltk.core.refactoring.TextFileChange;
import org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext;
import org.eclipse.ltk.core.refactoring.participants.RenameParticipant;
import org.eclipse.ltk.core.refactoring.participants.RenameRefactoring;
import org.eclipse.ltk.core.refactoring.resource.RenameResourceChange;
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.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.List;

/**
 * A rename participant handling renames of resources (such as R.id.foo and R.layout.bar).
 * This reacts to refactorings of fields in the R inner classes (such as R.id), and updates
 * the XML files as appropriate; renaming .xml files, updating XML attributes, resource
 * references in style declarations, and so on.
 */
@SuppressWarnings("restriction") // WTP API
public class RenameResourceParticipant extends RenameParticipant {
    /** The project we're refactoring in */
    private @NonNull IProject mProject;

    /** The type of the resource we're refactoring, such as {@link ResourceType#ID} */
    private @NonNull ResourceType mType;
    /**
     * The type of the resource folder we're refactoring in, such as
     * {@link ResourceFolderType#VALUES}. When refactoring non value files, we need to
     * rename the files as well.
     */
    private @NonNull ResourceFolderType mFolderType;

    /** The previous name of the resource */
    private @NonNull String mOldName;

    /** The new name of the resource */
    private @NonNull String mNewName;

    /** Whether references to the resource should be updated */
    private boolean mUpdateReferences;

    /** A match pattern to look for in XML, such as {@code @attr/foo} */
    private @NonNull String mXmlMatch1;

    /** A match pattern to look for in XML, such as {@code ?attr/foo} */
    private @Nullable String mXmlMatch2;

    /** A match pattern to look for in XML, such as {@code ?foo} */
    private @Nullable String mXmlMatch3;

    /** The value to replace a reference to {@link #mXmlMatch1} with, such as {@code @attr/bar} */
    private @NonNull String mXmlNewValue1;

    /** The value to replace a reference to {@link #mXmlMatch2} with, such as {@code ?attr/bar} */
    private @Nullable String mXmlNewValue2;

    /** The value to replace a reference to {@link #mXmlMatch3} with, such as {@code ?bar} */
    private @Nullable String mXmlNewValue3;

    /**
     * If non null, this refactoring was initiated as a file rename of an XML file (and if
     * null, we are just reacting to a Java field rename)
     */
    private IFile mRenamedFile;

    /**
     * If renaming a field, we need to create an embedded field refactoring to update the
     * Java sources referring to the corresponding R class field. This is stored as an
     * instance such that we can have it participate in both the condition check methods
     * as well as the {@link #createChange(IProgressMonitor)} refactoring operation.
     */
    private RenameRefactoring mFieldRefactoring;

    /**
     * Set while we are creating an embedded Java refactoring. This could cause a recursive
     * invocation of the XML renaming refactoring to react to the field, so this is flag
     * during the call to the Java processor, and is used to ignore requests for adding in
     * field reactions during that time.
     */
    private static boolean sIgnore;

    /**
     * Creates a new {@linkplain RenameResourceParticipant}
     */
    public RenameResourceParticipant() {
    }

    @Override
    public String getName() {
        return "Android Rename Field Participant";
    }

    @Override
    protected boolean initialize(Object element) {
        if (sIgnore) {
            return false;
        }

        if (element instanceof IField) {
            IField field = (IField) element;
            IType declaringType = field.getDeclaringType();
            if (declaringType != null) {
                if (R_CLASS.equals(declaringType.getParent().getElementName())) {
                    String typeName = declaringType.getElementName();
                    mType = ResourceType.getEnum(typeName);
                    if (mType != null) {
                        mUpdateReferences = getArguments().getUpdateReferences();
                        mFolderType = AdtUtils.getFolderTypeFor(mType);
                        IJavaProject javaProject = (IJavaProject) field.getAncestor(
                                IJavaElement.JAVA_PROJECT);
                        mProject = javaProject.getProject();
                        mOldName = field.getElementName();
                        mNewName = getArguments().getNewName();
                        mFieldRefactoring = null;
                        mRenamedFile = null;
                        createXmlSearchPatterns();
                        return true;
                    }
                }
            }

            return false;
        } else if (element instanceof IFile) {
            IFile file = (IFile) element;
            mProject = file.getProject();
            if (BaseProjectHelper.isAndroidProject(mProject)) {
                IPath path = file.getFullPath();
                int segments = path.segmentCount();
                if (segments == 4 && path.segment(1).equals(FD_RES)) {
                    String parentName = file.getParent().getName();
                    mFolderType = ResourceFolderType.getFolderType(parentName);
                    if (mFolderType != null && mFolderType != ResourceFolderType.VALUES) {
                        mType = AdtUtils.getResourceTypeFor(mFolderType);
                        if (mType != null) {
                            mUpdateReferences = getArguments().getUpdateReferences();
                            mProject = file.getProject();
                            mOldName = AdtUtils.stripAllExtensions(file.getName());
                            mNewName = AdtUtils.stripAllExtensions(getArguments().getNewName());
                            mRenamedFile = file;
                            createXmlSearchPatterns();

                            mFieldRefactoring = null;
                            IField field = getResourceField(mProject, mType, mOldName);
                            if (field != null) {
                                mFieldRefactoring = createFieldRefactoring(field);
                            } else {
                                // no corresponding field; aapt has not run yet. Perhaps user has
                                // turned off auto build.
                                mFieldRefactoring = null;
                            }

                            return true;
                        }
                    }
                }
            }
        } else if (element instanceof String) {
            String uri = (String) element;
            if (uri.startsWith(PREFIX_RESOURCE_REF) && !uri.startsWith(ANDROID_PREFIX)) {
                RenameResourceProcessor processor = (RenameResourceProcessor) getProcessor();
                mProject = processor.getProject();
                mType = processor.getType();
                mFolderType = AdtUtils.getFolderTypeFor(mType);
                mOldName = processor.getCurrentName();
                mNewName = processor.getNewName();
                assert uri.endsWith(mOldName) && uri.contains(mType.getName()) : uri;
                mUpdateReferences = getArguments().getUpdateReferences();
                if (mNewName.isEmpty()) {
                    mUpdateReferences = false;
                }
                mRenamedFile = null;
                createXmlSearchPatterns();
                mFieldRefactoring = null;
                if (!mNewName.isEmpty()) {
                    IField field = getResourceField(mProject, mType, mOldName);
                    if (field != null) {
                        mFieldRefactoring = createFieldRefactoring(field);
                    }
                }

                return true;
            }
        }

        return false;
    }

    /** Create nested Java refactoring which updates the R field references, if applicable */
    private RenameRefactoring createFieldRefactoring(IField field) {
        return createFieldRefactoring(field, mNewName, mUpdateReferences);
    }

    /**
     * Create nested Java refactoring which updates the R field references, if
     * applicable
     *
     * @param field the field to be refactored
     * @param newName the new name
     * @param updateReferences whether references should be updated
     * @return a new rename refactoring
     */
    public static RenameRefactoring createFieldRefactoring(
            @NonNull IField field,
            @NonNull String newName,
            boolean updateReferences) {
        RenameFieldProcessor processor = new RenameFieldProcessor(field);
        processor.setRenameGetter(false);
        processor.setRenameSetter(false);
        RenameRefactoring refactoring = new RenameRefactoring(processor);
        processor.setUpdateReferences(updateReferences);
        processor.setUpdateTextualMatches(false);
        processor.setNewElementName(newName);
        try {
            if (refactoring.isApplicable()) {
                return refactoring;
            }
        } catch (CoreException e) {
            AdtPlugin.log(e, null);
        }

        return null;
    }

    private void createXmlSearchPatterns() {
        // Set up search strings for the attribute iterator. This will
        // identify string matches for mXmlMatch1, 2 and 3, and when matched,
        // will add a replacement edit for mXmlNewValue1, 2, or 3.
        mXmlMatch2 = null;
        mXmlNewValue2 = null;
        mXmlMatch3 = null;
        mXmlNewValue3 = null;

        String typeName = mType.getName();
        if (mUpdateReferences) {
            mXmlMatch1 = PREFIX_RESOURCE_REF + typeName + '/' + mOldName;
            mXmlNewValue1 = PREFIX_RESOURCE_REF + typeName + '/' + mNewName;
            if (mType == ResourceType.ID) {
                mXmlMatch2 = NEW_ID_PREFIX + mOldName;
                mXmlNewValue2 = NEW_ID_PREFIX + mNewName;
            } else if (mType == ResourceType.ATTR) {
                // When renaming @attr/foo, also edit ?attr/foo
                mXmlMatch2 = PREFIX_THEME_REF + typeName + '/' + mOldName;
                mXmlNewValue2 = PREFIX_THEME_REF + typeName + '/' + mNewName;
                // as well as ?foo
                mXmlMatch3 = PREFIX_THEME_REF + mOldName;
                mXmlNewValue3 = PREFIX_THEME_REF + mNewName;
            }
        } else if (mType == ResourceType.ID) {
            mXmlMatch1 = NEW_ID_PREFIX + mOldName;
            mXmlNewValue1 = NEW_ID_PREFIX + mNewName;
        }
    }

    @Override
    public RefactoringStatus checkConditions(IProgressMonitor pm, CheckConditionsContext context)
            throws OperationCanceledException {
        if (mRenamedFile != null && getArguments().getNewName().indexOf('.') == -1
                && mRenamedFile.getName().indexOf('.') != -1) {
            return RefactoringStatus.createErrorStatus(
                    String.format("You must include the file extension (%1$s?)",
                           mRenamedFile.getName().substring(mRenamedFile.getName().indexOf('.'))));
        }

        // Ensure that the new name is valid
        if (mNewName != null && !mNewName.isEmpty()) {
            ResourceNameValidator validator = ResourceNameValidator.create(false, mProject, mType);
            String error = validator.isValid(mNewName);
            if (error != null) {
                return RefactoringStatus.createErrorStatus(error);
            }
        }

        if (mFieldRefactoring != null) {
            try {
                sIgnore = true;
                return mFieldRefactoring.checkAllConditions(pm);
            } catch (CoreException e) {
                AdtPlugin.log(e, null);
            } finally {
                sIgnore = false;
            }
        }

        return new RefactoringStatus();
    }

    @Override
    public Change createChange(IProgressMonitor monitor) throws CoreException,
            OperationCanceledException {
        if (monitor.isCanceled()) {
            return null;
        }

        CompositeChange result = new CompositeChange("Update resource references");

        // Only show the children in the refactoring preview dialog
        result.markAsSynthetic();

        addResourceFileChanges(result, mProject, monitor);

        // If renaming resources in a library project, also offer to rename references
        // in including projects
        if (mUpdateReferences) {
            ProjectState projectState = Sdk.getProjectState(mProject);
            if (projectState != null && projectState.isLibrary()) {
                List<ProjectState> parentProjects = projectState.getParentProjects();
                for (ProjectState state : parentProjects) {
                    IProject project = state.getProject();
                    CompositeChange nested = new CompositeChange(
                            String.format("Update references in %1$s", project.getName()));
                    addResourceFileChanges(nested, project, monitor);
                    if (nested.getChildren().length > 0) {
                        result.add(nested);
                    }
                }
            }
        }

        if (mFieldRefactoring != null) {
            // We have to add in Java field refactoring
            try {
                sIgnore = true;
                addJavaChanges(result, monitor);
            } finally {
                sIgnore = false;
            }
        } else {
            // Disable field refactoring added by the default Java field rename handler
            disableExistingResourceFileChange();
        }

        return (result.getChildren().length == 0) ? null : result;
    }

    /**
     * Adds all changes to resource files (typically XML but also renaming drawable files
     *
     * @param project the Android project
     * @param className the layout classes
     */
    private void addResourceFileChanges(
            CompositeChange change,
            IProject project,
            IProgressMonitor monitor)
            throws OperationCanceledException {
        if (monitor.isCanceled()) {
            return;
        }

        try {
            // Update resource references in the manifest
            IFile manifest = project.getFile(SdkConstants.ANDROID_MANIFEST_XML);
            if (manifest != null) {
                addResourceXmlChanges(manifest, change, null);
            }

            // Update references in XML resource files
            IFolder resFolder = project.getFolder(SdkConstants.FD_RESOURCES);

            IResource[] folders = resFolder.members();
            for (IResource folder : folders) {
                if (!(folder instanceof IFolder)) {
                    continue;
                }
                String folderName = folder.getName();
                ResourceFolderType folderType = ResourceFolderType.getFolderType(folderName);
                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)) {
                            addResourceXmlChanges(file, change, folderType);
                        }

                        if ((mRenamedFile == null || !mRenamedFile.equals(file))
                                && fileName.startsWith(mOldName)
                                && fileName.length() > mOldName.length()
                                && fileName.charAt(mOldName.length()) == '.'
                                && mFolderType != ResourceFolderType.VALUES
                                && mFolderType == folderType) {
                            // Rename this file
                            String newFile = mNewName + fileName.substring(mOldName.length());
                            IPath path = file.getFullPath();
                            change.add(new RenameResourceChange(path, newFile));
                        }
                    }
                }
            }
        } catch (CoreException e) {
            RefactoringUtil.log(e);
        }
    }

    private void addJavaChanges(CompositeChange result, IProgressMonitor monitor)
            throws CoreException, OperationCanceledException {
        if (monitor.isCanceled()) {
            return;
        }

        RefactoringStatus status = mFieldRefactoring.checkAllConditions(monitor);
        if (status != null && !status.hasError()) {
            Change fieldChanges = mFieldRefactoring.createChange(monitor);
            if (fieldChanges != null) {
                result.add(fieldChanges);

                // Look for the field change on the R.java class; it's a derived file
                // and will generate file modified manually warnings. Disable it.
                disableRClassChanges(fieldChanges);
            }
        }
    }

    private boolean addResourceXmlChanges(
            IFile file,
            CompositeChange changes,
            ResourceFolderType folderType) {
        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>();
                        addReplacements(edits, root, document, folderType);
                        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 void addReplacements(
            @NonNull List<TextEdit> edits,
            @NonNull Element element,
            @NonNull IStructuredDocument document,
            @Nullable ResourceFolderType folderType) {
        String tag = element.getTagName();
        if (folderType == ResourceFolderType.VALUES) {
            // Look for
            //   <item name="main_layout" type="layout">...</item>
            //   <item name="myid" type="id"/>
            //   <string name="mystring">...</string>
            // etc
            if (tag.equals(mType.getName())
                    || (tag.equals(TAG_ITEM)
                            && (mType == ResourceType.ID
                                || mType.getName().equals(element.getAttribute(ATTR_TYPE))))) {
                Attr nameNode = element.getAttributeNode(ATTR_NAME);
                if (nameNode != null && nameNode.getValue().equals(mOldName)) {
                    int start = RefactoringUtil.getAttributeValueRangeStart(nameNode, document);
                    if (start != -1) {
                        int end = start + mOldName.length();
                        edits.add(new ReplaceEdit(start, end - start, mNewName));
                    }
                }
            }
        }

        NamedNodeMap attributes = element.getAttributes();
        for (int i = 0, n = attributes.getLength(); i < n; i++) {
            Attr attr = (Attr) attributes.item(i);
            String value = attr.getValue();

            // If not updating references, only update XML matches that define the id
            if (!mUpdateReferences && (!ATTR_ID.equals(attr.getLocalName()) ||
                    !ANDROID_URI.equals(attr.getNamespaceURI()))) {

                if (TOOLS_URI.equals(attr.getNamespaceURI()) && value.equals(mXmlMatch1)) {
                    int start = RefactoringUtil.getAttributeValueRangeStart(attr, document);
                    if (start != -1) {
                        int end = start + mXmlMatch1.length();
                        edits.add(new ReplaceEdit(start, end - start, mXmlNewValue1));
                    }
                }

                continue;
            }

            // Replace XML attribute reference, such as
            //   android:id="@+id/oldName"   =>   android:id="+id/newName"

            String match = null;
            String matchedValue = null;

            if (value.equals(mXmlMatch1)) {
                match = mXmlMatch1;
                matchedValue = mXmlNewValue1;
            } else if (value.equals(mXmlMatch2)) {
                match = mXmlMatch2;
                matchedValue = mXmlNewValue2;
            } else if (value.equals(mXmlMatch3)) {
                match = mXmlMatch3;
                matchedValue = mXmlNewValue3;
            } else {
                continue;
            }

            if (match != null) {
                if (mNewName.isEmpty() && ATTR_ID.equals(attr.getLocalName()) &&
                        ANDROID_URI.equals(attr.getNamespaceURI())) {
                    // Delete attribute
                    IndexedRegion region = (IndexedRegion) attr;
                    int start = region.getStartOffset();
                    int end = region.getEndOffset();
                    edits.add(new ReplaceEdit(start, end - start, ""));
                } else {
                    int start = RefactoringUtil.getAttributeValueRangeStart(attr, document);
                    if (start != -1) {
                        int end = start + match.length();
                        edits.add(new ReplaceEdit(start, end - start, matchedValue));
                    }
                }
            }
        }

        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) {
                addReplacements(edits, (Element) child, document, folderType);
            } else if (child.getNodeType() == Node.TEXT_NODE && mUpdateReferences) {
                // Replace XML text, such as @color/custom_theme_color in
                //    <item name="android:windowBackground">@color/custom_theme_color</item>
                //
                String text = child.getNodeValue();
                int index = getFirstNonBlankIndex(text);
                if (index != -1) {
                    String match = null;
                    String matchedValue = null;
                    if (mXmlMatch1 != null
                            && text.startsWith(mXmlMatch1) && text.trim().equals(mXmlMatch1)) {
                        match = mXmlMatch1;
                        matchedValue = mXmlNewValue1;
                    } else if (mXmlMatch2 != null
                            && text.startsWith(mXmlMatch2) && text.trim().equals(mXmlMatch2)) {
                        match = mXmlMatch2;
                        matchedValue = mXmlNewValue2;
                    } else if (mXmlMatch3 != null
                            && text.startsWith(mXmlMatch3) && text.trim().equals(mXmlMatch3)) {
                        match = mXmlMatch3;
                        matchedValue = mXmlNewValue3;
                    }
                    if (match != null) {
                        IndexedRegion region = (IndexedRegion) child;
                        int start = region.getStartOffset() + index;
                        int end = start + match.length();
                        edits.add(new ReplaceEdit(start, end - start, matchedValue));
                    }
                }
            }
        }
    }

    /**
     * Returns the index of the first non-space character in the string, or -1
     * if the string is empty or has only whitespace
     *
     * @param s the string to check
     * @return the index of the first non whitespace character
     */
    private int getFirstNonBlankIndex(String s) {
        for (int i = 0, n = s.length(); i < n; i++) {
            if (!Character.isWhitespace(s.charAt(i))) {
                return i;
            }
        }

        return -1;
    }

    /**
     * Initiates a renaming of a resource item
     *
     * @param project the project containing the resource references
     * @param type the type of resource
     * @param name the name of the resource
     * @return false if initiating the rename failed
     */
    @Nullable
    private static IField getResourceField(
            @NonNull IProject project,
            @NonNull ResourceType type,
            @NonNull String name) {
        try {
            IJavaProject javaProject = BaseProjectHelper.getJavaProject(project);
            if (javaProject == null) {
                return null;
            }

            String pkg = ManifestInfo.get(project).getPackage();
            // TODO: Rename in all libraries too?
            IType t = javaProject.findType(pkg + '.' + R_CLASS + '.' + type.getName());
            if (t == null) {
                return null;
            }

            return t.getField(name);
        } catch (CoreException e) {
            AdtPlugin.log(e, null);
        }

        return null;
    }

    /**
     * Searches for existing changes in the refactoring which modifies the R
     * field to rename it. it's derived so performing this change will generate
     * a "generated code was modified manually" warning
     */
    private void disableExistingResourceFileChange() {
        IFolder genFolder = mProject.getFolder(SdkConstants.FD_GEN_SOURCES);
        if (genFolder != null && genFolder.exists()) {
            ManifestInfo manifestInfo = ManifestInfo.get(mProject);
            String pkg = manifestInfo.getPackage();
            if (pkg != null) {
                IFile rFile = genFolder.getFile(pkg.replace('.', '/') + '/' + FN_RESOURCE_CLASS);
                TextChange change = getTextChange(rFile);
                if (change != null) {
                    change.setEnabled(false);
                }
            }
        }
    }

    /**
     * Searches for existing changes in the refactoring which modifies the R
     * field to rename it. it's derived so performing this change will generate
     * a "generated code was modified manually" warning
     *
     * @param change the change to disable R file changes in
     */
    public static void disableRClassChanges(Change change) {
        if (change.getName().equals(FN_RESOURCE_CLASS)) {
            change.setEnabled(false);
        }
        // Look for the field change on the R.java class; it's a derived file
        // and will generate file modified manually warnings. Disable it.
        if (change instanceof CompositeChange) {
            for (Change outer : ((CompositeChange) change).getChildren()) {
                disableRClassChanges(outer);
            }
        }
    }
}
