package org.jboss.tools.seam.pages.xml.model.refactoring;
import java.util.ArrayList;
import java.util.Properties;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Path;
import org.eclipse.ltk.core.refactoring.Change;
import org.eclipse.ltk.core.refactoring.CompositeChange;
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
import org.eclipse.wst.common.componentcore.ComponentCore;
import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
import org.eclipse.wst.common.componentcore.resources.IVirtualFolder;
import org.jboss.tools.common.meta.action.XActionInvoker;
import org.jboss.tools.common.model.XModelException;
import org.jboss.tools.common.model.XModelObject;
import org.jboss.tools.common.model.filesystems.FileSystemsHelper;
import org.jboss.tools.common.model.filesystems.impl.FolderImpl;
import org.jboss.tools.common.model.refactoring.RefactoringHelper;
import org.jboss.tools.common.model.util.EclipseResourceUtil;
import org.jboss.tools.common.model.util.XModelObjectLoaderUtil;
import org.jboss.tools.jst.web.model.ReferenceObject;
import org.jboss.tools.seam.pages.xml.SeamPagesXMLMessages;
import org.jboss.tools.seam.pages.xml.model.SeamPagesConstants;
import org.jboss.tools.seam.pages.xml.model.handlers.RenameViewSupport;
import org.jboss.tools.seam.pages.xml.model.helpers.SeamPagesDiagramHelper;
import org.jboss.tools.seam.pages.xml.model.helpers.SeamPagesDiagramStructureHelper;
public class SeamPagesRenamePageConfigChange extends CompositeChange {
XModelObject object;
String newName;
String oldText;
String newText;
XModelObject[] fs = new XModelObject[0];
Properties replacements = new Properties();
public SeamPagesRenamePageConfigChange(XModelObject object, String newName) {
super(SeamPagesXMLMessages.PAGES_CONFIG_CHANGES);
this.object = object;
this.newName = newName;
replacements.clear();
oldText = XModelObjectLoaderUtil.getResourcePath(object);
if(!EclipseResourceUtil.hasNature(object.getModel(), "org.jboss.tools.jsf.jsfnature")) {
IFile file = (IFile)object.getAdapter(IFile.class);
if(file != null) {
IPath root = getRootPath(file.getProject());
if(root.isPrefixOf(file.getFullPath())) {
oldText = file.getFullPath().removeFirstSegments(root.segmentCount()).toString();
if(!oldText.startsWith("/")) oldText = "/" + oldText;
}
}
}
int i = oldText.lastIndexOf("/");
newText = oldText.substring(0, i + 1) + newName;
replacements.setProperty(oldText, newText);
addChanges();
}
IPath getRootPath(IProject project) {
IVirtualComponent component = ComponentCore.createComponent(project);
if(component == null) return null;
return component.getRootFolder().getWorkspaceRelativePath();
}
private void addChanges() {
if(object == null) return;
XModelObject fso = FileSystemsHelper.getFileSystems(object.getModel());
if(fso == null) return;
ArrayList<XModelObject> list = new ArrayList<XModelObject>();
collectFiles(list, fso);
fs = list.toArray(new XModelObject[0]);
addChanges(fs);
}
private void addChanges(XModelObject[] objects) {
for (int i = 0; i < objects.length; i++) {
int c = getChildren().length;
RefactoringHelper.addChanges(objects[i], replacements, this);
if(c == getChildren().length) {
final XModelObject gs = findGroup(objects[i]);
if(gs != null) {
add(new Change() {
public String getName() {
return SeamPagesXMLMessages.UPDATE_REFERENCE_TO_PAGE + gs.getAttributeValue(SeamPagesConstants.ATTR_PATH);
}
public void initializeValidationData(IProgressMonitor pm) {
}
public RefactoringStatus isValid(IProgressMonitor pm) throws CoreException, OperationCanceledException {
return null;
}
public Change perform(IProgressMonitor pm) throws CoreException {
return null;
}
public Object getModifiedElement() {
return null;
}
});
}
}
}
}
XModelObject findGroup(XModelObject f) {
XModelObject diagram = SeamPagesDiagramStructureHelper.instance.getDiagram(f);
if(diagram == null) return null;
XModelObject[] is = SeamPagesDiagramStructureHelper.instance.getItems(diagram);
for (int i = 0; i < is.length; i++) {
String path = is[i].getAttributeValue(SeamPagesConstants.ATTR_PATH);
if(path != null && path.equals(oldText)) return is[i];
}
return null;
}
private void collectFiles(ArrayList<XModelObject> list, XModelObject object) {
if(object.getFileType() == XModelObject.SYSTEM) {
if(object.getModelEntity().getName().equals("FileSystemJar")) {
return;
}
}
if(object.getFileType() == XModelObject.FILE) {
if(object.getModelEntity().getName().startsWith(SeamPagesConstants.ENT_FILE_SEAM_PAGE)) {
if(!isOverlapped(object)) list.add(object);
}
} else {
if("true".equals(object.get("overlapped"))) return;
XModelObject[] cs = object.getChildren();
for (XModelObject o: cs) {
collectFiles(list, o);
}
}
}
protected boolean isOverlapped(XModelObject object) {
XModelObject p = object.getParent();
while(p != null && !"true".equals(p.get("overlapped"))) p = p.getParent();
return (p != null);
}
public Change perform(IProgressMonitor pm) throws CoreException {
XModelObject parent = object.getParent();
if(parent instanceof FolderImpl) {
((FolderImpl)parent).update();
}
for (int i = 0; i < fs.length; i++) {
performChangeInFile(fs[i]);
}
for (int i = 0; i < fs.length; i++) {
if(fs[i].isModified()) {
XActionInvoker.invoke("SaveActions.Save", fs[i], null);
}
}
return null;
}
private void performChangeInFile(XModelObject f) throws XModelException {
replaceViewIDs(f, oldText, newText);
XModelObject g = findGroup(f);
if(g != null) {
SeamPagesDiagramHelper h = SeamPagesDiagramHelper.getHelper(SeamPagesDiagramStructureHelper.instance.getDiagram(f));
h.addUpdateLock(this);
try {
RenameViewSupport.replace((ReferenceObject)g, oldText, newText);
} finally {
h.removeUpdateLock(this);
h.updateDiagram();
}
}
}
static String[] ATTRIBUTES = {"no conversation view id", "login view id"};
static void replaceViewIDs(XModelObject f, String oldText, String newText) throws XModelException {
if(oldText == null || oldText.length() == 0) return;
for (int i = 0; i < ATTRIBUTES.length; i++) {
if(f.getModelEntity().getAttribute(ATTRIBUTES[i]) != null) {
String v = f.getAttributeValue(ATTRIBUTES[i]);
if(oldText.equals(v)) f.getModel().editObjectAttribute(f, ATTRIBUTES[i], newText);
}
}
if(f.getModelEntity().getName().startsWith(SeamPagesConstants.ENT_FILE_SEAM_PAGES)) {
XModelObject[] cs = f.getChildrenForSave();
for (int i = 0; i < cs.length; i++) replaceViewIDs(cs[i], oldText, newText);
}
}
}