1 /*
2  * Copyright (C) 2012 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 package com.android.ide.eclipse.adt.internal.refactorings.core;
17 
18 import static com.android.SdkConstants.PREFIX_RESOURCE_REF;
19 
20 import com.android.annotations.NonNull;
21 import com.android.annotations.Nullable;
22 import com.android.ide.eclipse.adt.AdtConstants;
23 import com.android.ide.eclipse.adt.internal.resources.ResourceNameValidator;
24 import com.android.resources.ResourceType;
25 
26 import org.eclipse.core.resources.IProject;
27 import org.eclipse.core.runtime.CoreException;
28 import org.eclipse.core.runtime.IProgressMonitor;
29 import org.eclipse.ltk.core.refactoring.Change;
30 import org.eclipse.ltk.core.refactoring.RefactoringStatus;
31 import org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext;
32 import org.eclipse.ltk.core.refactoring.participants.ParticipantManager;
33 import org.eclipse.ltk.core.refactoring.participants.RefactoringParticipant;
34 import org.eclipse.ltk.core.refactoring.participants.RenameArguments;
35 import org.eclipse.ltk.core.refactoring.participants.RenameProcessor;
36 import org.eclipse.ltk.core.refactoring.participants.SharableParticipants;
37 
38 /**
39  * A rename processor for Android resources.
40  */
41 public class RenameResourceProcessor extends RenameProcessor {
42     private IProject mProject;
43     private ResourceType mType;
44     private String mCurrentName;
45     private String mNewName;
46     private boolean mUpdateReferences = true;
47     private ResourceNameValidator mValidator;
48     private RenameArguments mRenameArguments;
49 
50     /**
51      * Creates a new rename resource processor.
52      *
53      * @param project the project containing the renamed resource
54      * @param type the type of the resource
55      * @param currentName the current name of the resource
56      * @param newName the new name of the resource, or null if not known
57      */
RenameResourceProcessor( @onNull IProject project, @NonNull ResourceType type, @NonNull String currentName, @Nullable String newName)58     public RenameResourceProcessor(
59             @NonNull IProject project,
60             @NonNull ResourceType type,
61             @NonNull String currentName,
62             @Nullable String newName) {
63         mProject = project;
64         mType = type;
65         mCurrentName = currentName;
66         mNewName = newName != null ? newName : currentName;
67         mUpdateReferences= true;
68         mValidator = ResourceNameValidator.create(false, mProject, mType);
69     }
70 
71     /**
72      * Returns the project containing the renamed resource
73      *
74      * @return the project containing the renamed resource
75      */
76     @NonNull
getProject()77     public IProject getProject() {
78         return mProject;
79     }
80 
81     /**
82      * Returns the new resource name
83      *
84      * @return the new resource name
85      */
86     @NonNull
getNewName()87     public String getNewName() {
88         return mNewName;
89     }
90 
91     /**
92      * Returns the current name of the resource
93      *
94      * @return the current name of the resource
95      */
getCurrentName()96     public String getCurrentName() {
97         return mCurrentName;
98     }
99 
100     /**
101      * Returns the type of the resource
102      *
103      * @return the type of the resource
104      */
105     @NonNull
getType()106     public ResourceType getType() {
107         return mType;
108     }
109 
110     /**
111      * Sets the new name
112      *
113      * @param newName the new name
114      */
setNewName(@onNull String newName)115     public void setNewName(@NonNull String newName) {
116         mNewName = newName;
117     }
118 
119     /**
120      * Returns {@code true} if the refactoring processor also updates references
121      *
122      * @return {@code true} if the refactoring processor also updates references
123      */
isUpdateReferences()124     public boolean isUpdateReferences() {
125         return mUpdateReferences;
126     }
127 
128     /**
129      * Specifies if the refactoring processor also updates references. The
130      * default behavior is to update references.
131      *
132      * @param updateReferences {@code true} if the refactoring processor should
133      *            also updates references
134      */
setUpdateReferences(boolean updateReferences)135     public void setUpdateReferences(boolean updateReferences) {
136         mUpdateReferences = updateReferences;
137     }
138 
139     /**
140      * Checks the given new potential name and returns a {@link RefactoringStatus} indicating
141      * whether the potential new name is valid
142      *
143      * @param name the name to check
144      * @return a {@link RefactoringStatus} with the validation result
145      */
checkNewName(String name)146     public RefactoringStatus checkNewName(String name) {
147         String error = mValidator.isValid(name);
148         if (error != null) {
149             return RefactoringStatus.createFatalErrorStatus(error);
150         }
151 
152         return new RefactoringStatus();
153     }
154 
155     @Override
checkInitialConditions(IProgressMonitor pm)156     public RefactoringStatus checkInitialConditions(IProgressMonitor pm) throws CoreException {
157         return new RefactoringStatus();
158     }
159 
160     @Override
checkFinalConditions(IProgressMonitor pm, CheckConditionsContext context)161     public RefactoringStatus checkFinalConditions(IProgressMonitor pm,
162             CheckConditionsContext context) throws CoreException {
163         pm.beginTask("", 1);
164         try {
165             mRenameArguments = new RenameArguments(getNewName(), isUpdateReferences());
166             return new RefactoringStatus();
167         } finally {
168             pm.done();
169         }
170     }
171 
172     @Override
createChange(IProgressMonitor pm)173     public Change createChange(IProgressMonitor pm) throws CoreException {
174         pm.beginTask("", 1);
175         try {
176             // Added by {@link RenameResourceParticipant}
177             return null;
178         } finally {
179             pm.done();
180         }
181     }
182 
183     @Override
getElements()184     public Object[] getElements() {
185         return new Object[0];
186     }
187 
188     @Override
getIdentifier()189     public String getIdentifier() {
190         return "com.android.ide.renameResourceProcessor"; //$NON-NLS-1$
191     }
192 
193     @Override
getProcessorName()194     public String getProcessorName() {
195         return "Rename Android Resource";
196     }
197 
198     @Override
isApplicable()199     public boolean isApplicable() {
200         return true;
201     }
202 
203     @Override
loadParticipants(RefactoringStatus status, SharableParticipants shared)204     public RefactoringParticipant[] loadParticipants(RefactoringStatus status,
205             SharableParticipants shared) throws CoreException {
206         String[] affectedNatures = new String[] { AdtConstants.NATURE_DEFAULT };
207         String url = PREFIX_RESOURCE_REF + mType.getName() + '/' + mCurrentName;
208         return ParticipantManager.loadRenameParticipants(status, this, url, mRenameArguments,
209                 null, affectedNatures, shared);
210     }
211 }