/***************************************************************************** * This file is part of Rinzo * * Author: Claudio Cancinos * WWW: https://sourceforge.net/projects/editorxml * Copyright (C): 2008, Claudio Cancinos * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this program; If not, see <http://www.gnu.org/licenses/> ****************************************************************************/ package ar.com.tadp.xml.rinzo.core.refactors.rename; import java.util.ArrayList; import java.util.List; import org.eclipse.core.resources.IFile; import org.eclipse.core.runtime.IProgressMonitor; 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.TextFileChange; import org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext; import org.eclipse.ltk.core.refactoring.participants.IConditionChecker; import org.eclipse.ltk.core.refactoring.participants.ValidateEditChecker; import org.eclipse.text.edits.MultiTextEdit; import org.eclipse.text.edits.ReplaceEdit; import ar.com.tadp.xml.rinzo.core.RinzoXMLEditor; import ar.com.tadp.xml.rinzo.core.model.XMLNode; import ar.com.tadp.xml.rinzo.core.model.visitor.FindTagsByNameVisitor; import ar.com.tadp.xml.rinzo.core.refactors.RefactoringProcessorDelegate; /** * Delegate object that contains the logic used by the processor to rename a Tag. * * @author ccancinos */ public class RenameTagNameDelegate implements RefactoringProcessorDelegate { private final RenameTagInfo info; private final XMLNode rootNode; private RinzoXMLEditor editor; RenameTagNameDelegate(final RenameTagInfo info, RinzoXMLEditor editor) { this.info = info; this.editor = editor; this.rootNode = this.editor.getModel().getTree().getRootNode(); } public String getName() { return "Rename Tag"; } public RefactoringStatus checkInitialConditions() { RefactoringStatus result = new RefactoringStatus(); IFile sourceFile = info.getSourceFile(); if (sourceFile == null || !sourceFile.exists()) { result.addFatalError("File does not exist"); } else if (info.getSourceFile().isReadOnly()) { result.addFatalError("File is read only"); } XMLNode node = this.editor.getModel().getTree().getActiveNode(this.info.getOffset()); if(!node.isTag() && !node.isEmptyTag()) { result.addFatalError("Cannot rename current selection."); } return result; } public RefactoringStatus checkFinalConditions(final IProgressMonitor pm, final CheckConditionsContext ctxt) { RefactoringStatus result = new RefactoringStatus(); pm.beginTask("Checking", 100); pm.worked(50); if (ctxt != null) { IFile[] arrayFiles = new IFile[] {info.getSourceFile()}; IConditionChecker checker = ctxt.getChecker(ValidateEditChecker.class); ValidateEditChecker editChecker = (ValidateEditChecker) checker; editChecker.addFiles(arrayFiles); } pm.done(); return result; } public void createChange(final IProgressMonitor pm, final CompositeChange rootChange) { try { pm.beginTask("Collecting changes", 100); // the property which was directly selected by the user pm.worked(10); // all files in the same bundle if(info.isUpdateAllInParent()) { rootChange.addAll(createChangesForParent()); } else { if(info.isUpdateAllInFile()) { rootChange.addAll(createChangesForFile()); } else { rootChange.add(createSingleRenameChange()); } } pm.worked(90); } finally { pm.done(); } } private Change createSingleRenameChange() { TextFileChange result = new TextFileChange(info.getSourceFile().getName(), info.getSourceFile()); MultiTextEdit fileChangeRootEdit = new MultiTextEdit(); result.setEdit(fileChangeRootEdit); XMLNode activeNode = this.editor.getModel().getTree().getActiveNode(info.getOffset()); this.addReplaceEdit(activeNode, fileChangeRootEdit); return result; } private Change[] createChangesForFile() { List<TextFileChange> result = new ArrayList<TextFileChange>(); TextFileChange tfc = new TextFileChange(info.getSourceFile().getName(), info.getSourceFile()); MultiTextEdit fileChangeRootEdit = new MultiTextEdit(); tfc.setEdit(fileChangeRootEdit); FindTagsByNameVisitor visitor = new FindTagsByNameVisitor(info.getOldName()); this.rootNode.accept(visitor); for (XMLNode node : visitor.getNodes()) { this.addReplaceEdit(node, fileChangeRootEdit); } result.add(tfc); return result.toArray(new Change[result.size()]); } private Change[] createChangesForParent() { List<TextFileChange> result = new ArrayList<TextFileChange>(); TextFileChange tfc = new TextFileChange(info.getSourceFile().getName(), info.getSourceFile()); MultiTextEdit fileChangeRootEdit = new MultiTextEdit(); tfc.setEdit(fileChangeRootEdit); FindTagsByNameVisitor visitor = new FindTagsByNameVisitor(info.getOldName()); XMLNode activeNode = this.editor.getModel().getTree().getActiveNode(info.getOffset()); activeNode.getParent().accept(visitor); for (XMLNode node : visitor.getNodes()) { this.addReplaceEdit(node, fileChangeRootEdit); } result.add(tfc); return result.toArray(new Change[result.size()]); } private void addReplaceEdit(XMLNode node, MultiTextEdit fileChangeRootEdit) { ReplaceEdit edit = new ReplaceEdit(node.getSelectionOffset(), info.getOldName().length(), info.getNewName()); fileChangeRootEdit.addChild(edit); XMLNode correspondingNode = node.getCorrespondingNode(); if(correspondingNode != null) { int offset = correspondingNode.getSelectionOffset(); edit = new ReplaceEdit(offset, info.getOldName().length(), info.getNewName()); fileChangeRootEdit.addChild(edit); } } }