/***** BEGIN LICENSE BLOCK ***** * Version: CPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Common 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/legal/cpl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2006 Lukas Felber <lfelber@hsr.ch> * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the CPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the CPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.rubypeople.rdt.refactoring.core; import java.util.ArrayList; import java.util.Collection; import java.util.Map; import org.eclipse.core.resources.IFile; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.OperationCanceledException; import org.eclipse.jface.wizard.IWizardPage; 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.ui.IFileEditorInput; import org.eclipse.ui.PlatformUI; import org.rubypeople.rdt.core.IRubyScript; import org.rubypeople.rdt.core.RubyCore; import org.rubypeople.rdt.internal.corext.refactoring.changes.RenameResourceChange; import org.rubypeople.rdt.internal.corext.refactoring.changes.RubyScriptChange; import org.rubypeople.rdt.internal.ui.RubyPlugin; import org.rubypeople.rdt.internal.ui.rubyeditor.RubyEditor; import org.rubypeople.rdt.refactoring.documentprovider.DocumentProvider; import org.rubypeople.rdt.refactoring.documentprovider.WorkspaceDocumentProvider; import org.rubypeople.rdt.refactoring.editprovider.FileMultiEditProvider; import org.rubypeople.rdt.refactoring.editprovider.FileNameChangeProvider; import org.rubypeople.rdt.refactoring.editprovider.IEditProvider; import org.rubypeople.rdt.refactoring.editprovider.IMultiFileEditProvider; public abstract class RubyRefactoring extends Refactoring { protected RefactoringStatus initialStatus; protected RefactoringStatus finalStatus; private String name; protected Collection<IWizardPage> pages; private IEditProvider editProvider; private IMultiFileEditProvider multiFileEditProvider; private IRefactoringConditionChecker conditionChecker; private IFile file; private FileNameChangeProvider fileNameChangeProvider; public RubyRefactoring(String name) { this(name, null); } public RubyRefactoring(String name, IRefactoringContext selectionProvider) { this.name = name; initialStatus = new RefactoringStatus(); finalStatus = new RefactoringStatus(); pages = new ArrayList<IWizardPage>(); if (selectionProvider != null) { this.file = selectionProvider.getActiveFile(); } else { RubyEditor editor = (RubyEditor) PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor(); this.file = ((IFileEditorInput) editor.getEditorInput()).getFile(); } } protected IFile getActiveFile() { return file; } protected void setEditProvider(IEditProvider editProvider) { this.editProvider = editProvider; } protected void setEditProvider(IMultiFileEditProvider multiFileEditProvider) { this.multiFileEditProvider = multiFileEditProvider; } protected void setFileNameChangeProvider(FileNameChangeProvider fileNameChangeProvider) { this.fileNameChangeProvider = fileNameChangeProvider; } @Override public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public RefactoringStatus checkInitialConditions(IProgressMonitor pm) { if (conditionChecker != null) { Map<String, Collection<String>> messages = conditionChecker.getInitialMessages(); Collection<String> errors = messages.get(IRefactoringConditionChecker.ERRORS); for (String errMessage : errors) { initialStatus.addFatalError(errMessage); } Collection<String> warnings = messages.get(IRefactoringConditionChecker.ERRORS); for (String warningMessage : warnings) { initialStatus.addWarning(warningMessage); } } return initialStatus; } @Override public RefactoringStatus checkFinalConditions(IProgressMonitor pm) throws CoreException, OperationCanceledException { finalStatus = new RefactoringStatus(); if (conditionChecker != null) { Map<String, Collection<String>> messages = conditionChecker.getFinalMessages(); Collection<String> errors = messages.get(IRefactoringConditionChecker.ERRORS); for (String errMessage : errors) { finalStatus.addFatalError(errMessage); } Collection<String> warnings = messages.get(IRefactoringConditionChecker.WARNING); for (String warningMessage : warnings) { finalStatus.addWarning(warningMessage); } } return finalStatus; } @Override public Change createChange(IProgressMonitor pm) throws CoreException, OperationCanceledException { Change change = createEditChanges(); Map<String, String> filesToRename = getFileNameChangeProvider().getFilesToRename(getAllAffectedFiles(change)); if(filesToRename.isEmpty()) { return change; } CompositeChange compositeChange = new CompositeChange(getName(), new Change[]{change}); compositeChange.markAsSynthetic(); for (Map.Entry<String, String> entry : filesToRename.entrySet()) { RenameResourceChange renameResourceChange = new RenameResourceChange(null, RubyPlugin.getWorkspace().getRoot().findMember(entry.getKey()), entry.getValue(), "comment"); compositeChange.add(new DynamicValidationStateChange(renameResourceChange)); } return compositeChange; } private Collection<IFile> getAllAffectedFiles(Change change) { Collection<IFile> affectedFiles = new ArrayList<IFile>(); for (Object object : change.getAffectedObjects()) { if (object instanceof IFile) { affectedFiles.add((IFile) object); } } return affectedFiles; } private Change createEditChanges() { DocumentProvider docProvider = new WorkspaceDocumentProvider(getActiveFile()); if(multiFileEditProvider != null) { return createMultiFileChange(docProvider); } return createActiveFileChange(docProvider); } private Change createActiveFileChange(DocumentProvider docProvider) { return getChange(getActiveFile(), editProvider, docProvider); } private Change createMultiFileChange(DocumentProvider docProvider) { CompositeChange change = new CompositeChange(name); for (FileMultiEditProvider currentProvider : multiFileEditProvider.getFileEditProviders()) { IFile currentIFile = getDocumentProvider().getIFile(currentProvider.getFileName()); change.add(getChange(currentIFile, currentProvider, docProvider)); } return change; } private Change getChange(IFile file, IEditProvider editProvider, DocumentProvider docProvider) { String fileName = file.getFullPath().toOSString(); IRubyScript script = RubyCore.create(file); RubyScriptChange change = new RubyScriptChange(fileName, script); String document = docProvider.getFileContent(fileName); change.setEdit(editProvider.getEdit(document)); return change; } public Collection<IWizardPage> getPages() { return pages; } public WorkspaceDocumentProvider getDocumentProvider() { return new WorkspaceDocumentProvider(getActiveFile()); } protected void setRefactoringConditionChecker(IRefactoringConditionChecker conditionChecker) { this.conditionChecker = conditionChecker; } public IRefactoringConditionChecker getConditionChecker() { return conditionChecker; } public IEditProvider getEditProvider() { return editProvider; } public IMultiFileEditProvider getMultiFileEditProvider() { return multiFileEditProvider; } public FileNameChangeProvider getFileNameChangeProvider() { return fileNameChangeProvider != null ? fileNameChangeProvider : new FileNameChangeProvider(); } }