/*
* Copyright (c) 2004- michael lawley and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser General Public License version 2.1 as published by the Free Software Foundation
* which accompanies this distribution, and is available by writing to
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* Contributors:
* michael lawley
*
*
*
*/
package tefkat.plugin;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.ETypedElement;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.views.contentoutline.ContentOutlinePage;
import tefkat.model.AndTerm;
import tefkat.model.MofInstance;
import tefkat.model.NamespaceDeclaration;
import tefkat.model.OrTerm;
import tefkat.model.Term;
import tefkat.model.Transformation;
import tefkat.model.Var;
import tefkat.model.VarScope;
import tefkat.model.VarUse;
/**
* @author lawley
*
*/
public class TefkatModelOutlinePage extends ContentOutlinePage {
private String resId;
final private Map<String, Object> objMap = new HashMap<String, Object>();
final private Map<Object, String> idMap = new HashMap<Object, String>();
/**
*
*/
public TefkatModelOutlinePage() {
super();
}
public void setResource(Resource res) {
String id = res.getURI().toString();
boolean reparse = id.equals(resId);
resId = id;
// leaks mem like a sieve without these two lines :-)
idMap.clear();
objMap.clear();
objMap.put(id, res);
idMap.put(res, id);
if (!reparse) {
getTreeViewer().setInput(id);
} else {
getTreeViewer().refresh(id);
}
}
private String getID(Object obj) {
if (null == obj) {
return "";
}
String id = idMap.get(obj);
if (null == id) {
if (obj instanceof Transformation) {
id = ((Transformation) obj).getName();
} else if (obj instanceof VarScope) {
id = "SCOPE" + getID(((EObject) obj).eContainer()) + ((VarScope) obj).getName();
} else if (obj instanceof Var) {
id = "VAR" + getID(((EObject) obj).eContainer()) + ((Var) obj).getName();
} else if (obj instanceof VarUse) {
id = "USE" + getID(((EObject) obj).eContainer()) + getID(((VarUse) obj).getVar());
} else if (obj instanceof AndTerm) {
id = "AND" + getID(((EObject) obj).eContainer());
for (Iterator itr = ((AndTerm) obj).getTerm().iterator(); itr.hasNext(); ) {
id = id + itr.next();
}
} else if (obj instanceof OrTerm) {
id = "OR" + getID(((EObject) obj).eContainer());
for (Iterator itr = ((OrTerm) obj).getTerm().iterator(); itr.hasNext(); ) {
id = id + itr.next();
}
} else if (obj instanceof MofInstance) {
MofInstance inst = ((MofInstance) obj);
id = "INST" + getID(((EObject) obj).eContainer()) + inst.getTypeName() + inst.getInstance();
} else if (obj instanceof EObject) {
id = obj.getClass().getName() + getID(((EObject) obj).eContainer()) + obj.hashCode();
} else if (obj instanceof Resource) {
id = ((Resource) obj).getURI().toString();
} else {
id = obj.getClass().getName() + obj.hashCode();
}
objMap.put(id, obj);
idMap.put(obj, id);
}
return id;
}
private String[] getIDs(Object[] objects) {
String[] strings = new String[objects.length];
for (int i = 0; i < objects.length; i++) {
strings[i] = getID(objects[i]);
}
return strings;
}
/**
* Return the real objects in the selection rather than their internal ID proxies
*
* @see org.eclipse.ui.views.contentoutline.ContentOutlinePage#fireSelectionChanged(org.eclipse.jface.viewers.ISelection)
*/
protected void fireSelectionChanged(ISelection selection) {
Object[] idElts = ((IStructuredSelection) selection).toArray();
Object[] elts = new Object[idElts.length];
for (int i = 0; i < elts.length; i++) {
elts[i] = objMap.get(idElts[i]);
}
super.fireSelectionChanged(new StructuredSelection(elts));
}
/* (non-Javadoc)
* @see org.eclipse.ui.part.IPage#createControl(org.eclipse.swt.widgets.Composite)
*/
public void createControl(Composite parent) {
super.createControl(parent);
getTreeViewer().setLabelProvider(new LabelProvider() {
public String getText(Object element) {
Object obj = objMap.get(element);
if (obj instanceof EClassifier) {
return ((EClassifier) obj).getName();
} else if (obj instanceof ETypedElement) {
return ((ETypedElement) obj).getName() + ": " + ((ETypedElement) obj).getEType().getName();
} else if (obj instanceof EPackage) {
return ((EPackage) obj).getName() + " <" + ((EPackage) obj).getNsURI() + ">";
} else if (obj instanceof Collection) {
return "stratum";
} else if (obj instanceof AndTerm) {
return "AND";
} else if (obj instanceof OrTerm) {
return "OR";
} else {
return String.valueOf(obj);
}
}
});
getTreeViewer().setContentProvider(new ITreeContentProvider() {
public Object[] getChildren(Object elementID) {
Object element = objMap.get(elementID); // map from String id to (E)Object
if (element instanceof EObject) {
Object[] children = filter(((EObject) element).eContents()).toArray();
if (element instanceof Term) {
return getIDs(children);
} else {
return getIDs(children);
}
} else {
// System.out.println("************* Parent element must be an EObject: " + element);
return null;
// throw new Error("Parent element must be an EObject");
}
}
public Object getParent(Object elementID) {
Object element = objMap.get(elementID); // map from String id to (E)Object
if (element instanceof EObject) {
return ((EObject) element).eContainer();
}
return null;
}
public boolean hasChildren(Object elementID) {
Object element = objMap.get(elementID); // map from String id to (E)Object
boolean children = false;
if (element instanceof EObject) {
children = !filter(((EObject) element).eContents()).isEmpty();
}
return children;
}
public Object[] getElements(Object elementID) {
Object element = objMap.get(elementID); // map from String id to Object
if (element instanceof Resource) {
Object[] children = filter(((Resource) element).getContents()).toArray();
return getIDs(children);
} else {
// System.out.println("************* Root element must be a Resource: " + element);
return null;
// throw new Error("Root element must be a Resource");
}
}
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
if (viewer != null && newInput != null && oldInput == null) {
((TreeViewer) viewer).refresh(newInput);
}
}
public void dispose() {
}
});
}
private boolean filter(final Object obj) {
if (obj instanceof Var || obj instanceof NamespaceDeclaration || obj instanceof EPackage) {
return false;
}
return true;
}
private Collection<Object> filter(final Collection objects) {
Collection<Object> result = new ArrayList<Object>();
for (Object o: objects) {
if (filter(o)) {
result.add(o);
}
}
return result;
}
public void dispose() {
resId = null;
objMap.clear();
idMap.clear();
}
}