/******************************************************************************* * Copyright (c) 2007 Exadel, Inc. and Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Exadel, Inc. and Red Hat, Inc. - initial API and implementation ******************************************************************************/ package org.jboss.tools.common.model.refactoring; import java.text.MessageFormat; import java.util.ArrayList; import java.util.List; import org.eclipse.core.resources.IFile; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jdt.internal.corext.refactoring.changes.TextChangeCompatibility; import org.eclipse.ltk.core.refactoring.Change; import org.eclipse.ltk.core.refactoring.TextFileChange; import org.eclipse.text.edits.ReplaceEdit; import org.jboss.tools.common.model.XModelObject; import org.jboss.tools.common.model.filesystems.impl.FileAnyImpl; import org.jboss.tools.common.model.impl.XModelObjectImpl; import org.jboss.tools.common.model.util.EclipseResourceUtil; import org.jboss.tools.common.model.util.PositionSearcher; /** * @author glory * * This change receives an array of objects which reference * to a renamed object, name of attribute by which they * reference to it, and new value. The change implementation * presents and performs the change as a text change. * * Use restrictions: * 1. All objects must belong to the same file object. * 2. If you need process two sets of objects from one file with different * attributes affected, use method addEdits(XModelObject[], String, String) * repeatedly. */ public class RenameModelObjectChange extends TextFileChange { boolean ok = false; private String newName; class ObjectSet { XModelObject[] objects; String attributeName; ObjectSet(XModelObject[] objects, String attributeName) { this.objects = objects; this.attributeName = attributeName; } } List<ObjectSet> list = new ArrayList<ObjectSet>(); public static RenameModelObjectChange createChange(XModelObject[] objects, String newName, String attributeName) { if(objects == null || objects.length == 0) return null; String name = objects[0].getPresentationString(); IFile f = getFile(objects[0]); if(f == null) return null; return new RenameModelObjectChange(name, f, objects, newName, attributeName); } /** * Creates empty change, for which one has to add edits * by calling addEdits(XModelObject[], String, String) * * @param fileObject * @param newName * @return */ public static RenameModelObjectChange createChange(XModelObject fileObject, String newName) { String name = fileObject.getPresentationString(); IFile f = getFile(fileObject); if(f == null) return null; return new RenameModelObjectChange(name, f, newName); } private RenameModelObjectChange(String name, IFile file, String newName) { super(name, file); this.newName = newName; } private RenameModelObjectChange(String name, IFile file, XModelObject[] objects, String newName, String attributeName) { this(name, file, newName); addEdits(objects, attributeName, "Update field reference"); } public void addEdits(XModelObject[] objects, String attributeName, String textEditName) { list.add(new ObjectSet(objects, attributeName)); PositionSearcher searcher = new PositionSearcher(); XModelObject o = ((XModelObjectImpl)objects[0]).getResourceAncestor(); String text = ((FileAnyImpl)o).getAsText(); for (int i = 0; i < objects.length; i++) { searcher.init(text, objects[i], attributeName); searcher.execute(); int bp = searcher.getStartPosition(); int ep = searcher.getEndPosition(); ok = false; if(bp >= 0 && ep >= ep) { ReplaceEdit edit = new ReplaceEdit(bp, ep - bp, newName); TextChangeCompatibility.addTextEdit(this, textEditName, edit); ok = true; } } } protected static IFile getFile(XModelObject object) { XModelObject o = ((XModelObjectImpl)object).getResourceAncestor(); return o == null ? null : (IFile)EclipseResourceUtil.getResource(o); } public Change perform(IProgressMonitor pm) throws CoreException { Change result = null; if(ok) { result = super.perform(pm); } else { for (ObjectSet set: list) { for (int i = 0; i < set.objects.length; i++) { set.objects[i].getModel().changeObjectAttribute(set.objects[i], set.attributeName, newName); } } } return result; } public Object getModifiedElement() { return null; } public String getName() { return MessageFormat.format("Edit {0}", list.get(0).attributeName); } }