1 11 package org.eclipse.ltk.core.refactoring.participants; 12 13 import java.util.ArrayList ; 14 import java.util.Arrays ; 15 import java.util.Collections ; 16 import java.util.HashMap ; 17 import java.util.Iterator ; 18 import java.util.List ; 19 import java.util.Map ; 20 21 import org.eclipse.core.runtime.CoreException; 22 import org.eclipse.core.runtime.IProgressMonitor; 23 import org.eclipse.core.runtime.NullProgressMonitor; 24 import org.eclipse.core.runtime.OperationCanceledException; 25 import org.eclipse.core.runtime.PerformanceStats; 26 import org.eclipse.core.runtime.SubProgressMonitor; 27 28 import org.eclipse.core.resources.IFile; 29 30 import org.eclipse.ltk.core.refactoring.Change; 31 import org.eclipse.ltk.core.refactoring.CompositeChange; 32 import org.eclipse.ltk.core.refactoring.Refactoring; 33 import org.eclipse.ltk.core.refactoring.RefactoringStatus; 34 import org.eclipse.ltk.core.refactoring.TextChange; 35 import org.eclipse.ltk.core.refactoring.TextFileChange; 36 37 import org.eclipse.ltk.internal.core.refactoring.Messages; 38 import org.eclipse.ltk.internal.core.refactoring.ParticipantDescriptor; 39 import org.eclipse.ltk.internal.core.refactoring.RefactoringCoreMessages; 40 import org.eclipse.ltk.internal.core.refactoring.RefactoringCorePlugin; 41 42 51 public abstract class ProcessorBasedRefactoring extends Refactoring { 52 53 private static final String PERF_CHECK_CONDITIONS= "org.eclipse.ltk.core.refactoring/perf/participants/checkConditions"; private static final String PERF_CREATE_CHANGES= "org.eclipse.ltk.core.refactoring/perf/participants/createChanges"; 56 private List fParticipants; 57 58 private Map fTextChangeMap; 59 60 private static final List EMPTY_PARTICIPANTS= Collections.EMPTY_LIST; 61 62 private static class ProcessorChange extends CompositeChange { 63 private Map fParticipantMap; 64 public ProcessorChange(String name) { 65 super(name); 66 markAsSynthetic(); 67 } 68 public void setParticipantMap(Map map) { 69 fParticipantMap= map; 70 } 71 protected void internalHandleException(Change change, Throwable e) { 72 if (e instanceof OperationCanceledException) 73 return; 74 75 RefactoringParticipant participant= (RefactoringParticipant)fParticipantMap.get(change); 76 if (participant != null) { 77 ParticipantDescriptor descriptor= participant.getDescriptor(); 78 descriptor.disable(); 79 RefactoringCorePlugin.logRemovedParticipant(descriptor, e); 80 } 81 } 82 protected boolean internalContinueOnCancel() { 83 return true; 84 } 85 protected boolean internalProcessOnCancel(Change change) { 86 RefactoringParticipant participant= (RefactoringParticipant)fParticipantMap.get(change); 87 if (participant == null) 88 return false; 89 return participant.getDescriptor().processOnCancel(); 90 } 91 } 92 93 98 protected ProcessorBasedRefactoring() { 99 } 100 101 108 protected ProcessorBasedRefactoring(RefactoringProcessor processor) { 109 processor.setRefactoring(this); 110 } 111 112 118 public abstract RefactoringProcessor getProcessor(); 119 120 121 132 public final boolean isApplicable() throws CoreException { 133 return getProcessor().isApplicable(); 134 } 135 136 139 public String getName() { 140 return getProcessor().getProcessorName(); 141 } 142 143 146 public RefactoringStatus checkInitialConditions(IProgressMonitor pm) throws CoreException { 147 if (pm == null) 148 pm= new NullProgressMonitor(); 149 RefactoringStatus result= new RefactoringStatus(); 150 pm.beginTask("", 10); pm.setTaskName(RefactoringCoreMessages.ProcessorBasedRefactoring_initial_conditions); 152 153 result.merge(getProcessor().checkInitialConditions(new SubProgressMonitor(pm, 8))); 154 if (result.hasFatalError()) { 155 pm.done(); 156 return result; 157 } 158 pm.done(); 159 return result; 160 } 161 162 165 public RefactoringStatus checkFinalConditions(IProgressMonitor pm) throws CoreException { 166 if (pm == null) 167 pm= new NullProgressMonitor(); 168 RefactoringStatus result= new RefactoringStatus(); 169 CheckConditionsContext context= createCheckConditionsContext(); 170 171 pm.beginTask("", 9); pm.setTaskName(RefactoringCoreMessages.ProcessorBasedRefactoring_final_conditions); 173 174 result.merge(getProcessor().checkFinalConditions(new SubProgressMonitor(pm, 5), context)); 175 if (result.hasFatalError()) { 176 pm.done(); 177 return result; 178 } 179 if (pm.isCanceled()) 180 throw new OperationCanceledException(); 181 182 SharableParticipants sharableParticipants= new SharableParticipants(); fParticipants= new ArrayList (Arrays.asList(getProcessor().loadParticipants(result, sharableParticipants))); 184 if (fParticipants == null) 185 fParticipants= EMPTY_PARTICIPANTS; 186 if (result.hasFatalError()) { 187 pm.done(); 188 return result; 189 } 190 IProgressMonitor sm= new SubProgressMonitor(pm, 2); 191 192 sm.beginTask("", fParticipants.size()); for (Iterator iter= fParticipants.iterator(); iter.hasNext() && !result.hasFatalError(); ) { 194 195 RefactoringParticipant participant= (RefactoringParticipant) iter.next(); 196 197 final PerformanceStats stats= PerformanceStats.getStats(PERF_CHECK_CONDITIONS, getName() + ", " + participant.getName()); stats.startRun(); 199 200 try { 201 result.merge(participant.checkConditions(new SubProgressMonitor(sm, 1), context)); 202 } catch (RuntimeException e) { 203 RefactoringCorePlugin.log(e); 205 result.merge(RefactoringStatus.createErrorStatus(Messages.format( 206 RefactoringCoreMessages.ProcessorBasedRefactoring_check_condition_participant_failed, 207 participant.getName()))); 208 iter.remove(); 209 } 210 211 stats.endRun(); 212 213 if (sm.isCanceled()) 214 throw new OperationCanceledException(); 215 } 216 sm.done(); 217 if (result.hasFatalError()) { 218 pm.done(); 219 return result; 220 } 221 result.merge(context.check(new SubProgressMonitor(pm, 1))); 222 pm.done(); 223 return result; 224 } 225 226 229 public Change createChange(IProgressMonitor pm) throws CoreException { 230 if (pm == null) 231 pm= new NullProgressMonitor(); 232 pm.beginTask("", fParticipants.size() + 2); pm.setTaskName(RefactoringCoreMessages.ProcessorBasedRefactoring_create_change); 234 Change processorChange= getProcessor().createChange(new SubProgressMonitor(pm, 1)); 235 if (pm.isCanceled()) 236 throw new OperationCanceledException(); 237 238 fTextChangeMap= new HashMap (); 239 addToTextChangeMap(processorChange); 240 241 List changes= new ArrayList (); 242 Map participantMap= new HashMap (); 243 for (Iterator iter= fParticipants.iterator(); iter.hasNext();) { 244 final RefactoringParticipant participant= (RefactoringParticipant) iter.next(); 245 246 try { 247 final PerformanceStats stats= PerformanceStats.getStats(PERF_CREATE_CHANGES, getName() + ", " + participant.getName()); stats.startRun(); 249 250 Change change= participant.createChange(new SubProgressMonitor(pm, 1)); 251 252 stats.endRun(); 253 254 if (change != null) { 255 changes.add(change); 256 participantMap.put(change, participant); 257 addToTextChangeMap(change); 258 } 259 } catch (CoreException e) { 260 disableParticipant(participant, e); 261 throw e; 262 } catch (RuntimeException e) { 263 disableParticipant(participant, e); 264 throw e; 265 } 266 if (pm.isCanceled()) 267 throw new OperationCanceledException(); 268 } 269 270 fTextChangeMap= null; 271 272 Change postChange= getProcessor().postCreateChange( 273 (Change[])changes.toArray(new Change[changes.size()]), 274 new SubProgressMonitor(pm, 1)); 275 276 ProcessorChange result= new ProcessorChange(getName()); 277 result.add(processorChange); 278 result.addAll((Change[]) changes.toArray(new Change[changes.size()])); 279 result.setParticipantMap(participantMap); 280 if (postChange != null) 281 result.add(postChange); 282 return result; 283 } 284 285 299 public TextChange getTextChange(Object element) { 300 if (fTextChangeMap == null) 301 return null; 302 return (TextChange)fTextChangeMap.get(element); 303 } 304 305 321 public Object getAdapter(Class clazz) { 322 if (clazz.isInstance(this)) 323 return this; 324 if (clazz.isInstance(getProcessor())) 325 return getProcessor(); 326 return super.getAdapter(clazz); 327 } 328 329 332 public String toString() { 333 return getName(); 334 } 335 336 338 private CheckConditionsContext createCheckConditionsContext() throws CoreException { 339 CheckConditionsContext result= new CheckConditionsContext(); 340 result.add(new ValidateEditChecker(getValidationContext())); 341 result.add(new ResourceChangeChecker()); 342 return result; 343 } 344 345 346 private void disableParticipant(final RefactoringParticipant participant, Throwable e) { 347 ParticipantDescriptor descriptor= participant.getDescriptor(); 348 descriptor.disable(); 349 RefactoringCorePlugin.logRemovedParticipant(descriptor, e); 350 } 351 352 private void addToTextChangeMap(Change change) { 353 if (change instanceof TextChange) { 354 Object element= ((TextChange)change).getModifiedElement(); 355 if (element != null) { 356 fTextChangeMap.put(element, change); 357 } 358 if (change instanceof TextFileChange && !change.getClass().equals(TextFileChange.class)) { 361 IFile file= ((TextFileChange)change).getFile(); 362 fTextChangeMap.put(file, change); 363 } 364 } else if (change instanceof CompositeChange) { 365 Change[] children= ((CompositeChange)change).getChildren(); 366 for (int i= 0; i < children.length; i++) { 367 addToTextChangeMap(children[i]); 368 } 369 } 370 } 371 } 372 | Popular Tags |