package oclastview.views;
import oclastview.visitors.XMLforOCL;
import oclastview.visitors.arithSimp.OCLArithSimplifier;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.emf.ecore.EAnnotation;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EModelElement;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EOperation;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.ocl.expressions.OCLExpression;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.ui.ISelectionListener;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.DrillDownAdapter;
import org.eclipse.ui.part.ViewPart;
import org.jdom.Element;
import util.JDomContentProvider;
import util.JDomLabelProvider;
public class OCLASTView extends ViewPart implements ISelectionListener {
public static final String oclNsUri = "http://www.eclipse.org/ocl/examples/OCL";
// but the real one is Environment.OCL_NAMESPACE_URI;
private TreeViewer viewer;
private DrillDownAdapter drillDownAdapter;
private Action action1;
private Action action2;
private Action doubleClickAction;
private Element invisibleXml = null;
/**
* The constructor.
*/
public OCLASTView() {
}
/**
* This is a callback that will allow us to create the viewer and initialize
* it.
*/
public void createPartControl(Composite parent) {
viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
drillDownAdapter = new DrillDownAdapter(viewer);
// create the content provider
viewer.setContentProvider(new JDomContentProvider());
// create the label provider
JDomLabelProvider lp = new JDomLabelProvider();
viewer.setLabelProvider(lp);
// set initial content
invisibleXml = new Element("invisible_root");
viewer.setInput(invisibleXml);
// set background and text colors
setColors(parent, viewer);
makeActions();
hookContextMenu();
hookDoubleClickAction();
// add myself as a global selection listener
getSite().getPage().addSelectionListener(this);
// prime the selection
selectionChanged(null, getSite().getPage().getSelection());
}
private void hookContextMenu() {
MenuManager menuMgr = new MenuManager("#PopupMenu");
menuMgr.setRemoveAllWhenShown(true);
menuMgr.addMenuListener(new IMenuListener() {
public void menuAboutToShow(IMenuManager manager) {
OCLASTView.this.fillContextMenu(manager);
}
});
Menu menu = menuMgr.createContextMenu(viewer.getControl());
viewer.getControl().setMenu(menu);
getSite().registerContextMenu(menuMgr, viewer);
}
private void fillContextMenu(IMenuManager manager) {
manager.add(action1);
manager.add(action2);
manager.add(new Separator());
drillDownAdapter.addNavigationActions(manager);
// Other plug-ins can contribute there actions here
manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
}
private void makeActions() {
action1 = new Action() {
public void run() {
showMessage("Action 1 executed");
}
};
action1.setText("Action 1");
action1.setToolTipText("Action 1 tooltip");
action1.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages()
.getImageDescriptor(ISharedImages.IMG_OBJS_INFO_TSK));
action2 = new Action() {
public void run() {
showMessage("Action 2 executed");
}
};
action2.setText("Action 2");
action2.setToolTipText("Action 2 tooltip");
action2.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages()
.getImageDescriptor(ISharedImages.IMG_OBJS_INFO_TSK));
doubleClickAction = new Action() {
public void run() {
ISelection selection = viewer.getSelection();
Object obj = ((IStructuredSelection) selection)
.getFirstElement();
showMessage("Double-click detected on " + obj.toString());
}
};
}
private void hookDoubleClickAction() {
viewer.addDoubleClickListener(new IDoubleClickListener() {
public void doubleClick(DoubleClickEvent event) {
doubleClickAction.run();
}
});
}
private void showMessage(String message) {
MessageDialog.openInformation(viewer.getControl().getShell(),
"OCL AST View", message);
}
/**
* Passing the focus request to the viewer's control.
*/
public void setFocus() {
viewer.getControl().setFocus();
}
static public void setColors(Composite parent, TreeViewer viewer) {
Color back = parent.getDisplay().getSystemColor(
SWT.COLOR_INFO_BACKGROUND);
Color front = parent.getDisplay().getSystemColor(SWT.COLOR_DARK_BLUE);
viewer.getTree().setBackground(back);
viewer.getTree().setForeground(front);
}
public void selectionChanged(IWorkbenchPart part, ISelection selection) {
clearView();
EObject context = null;
if (!(selection instanceof IStructuredSelection)) {
return;
}
IStructuredSelection sel = (IStructuredSelection) selection;
if (sel != null && !sel.isEmpty()) {
Object selected = sel.getFirstElement();
if (selected instanceof EObject) {
context = (EObject) selected;
} else if (selected instanceof IAdaptable) {
context = (EObject) ((IAdaptable) selected)
.getAdapter(EObject.class);
}
}
if (context == null || !(context instanceof EModelElement)) {
return;
}
EModelElement me = (EModelElement) context;
for (Object oea : me.getEAnnotations()) {
EAnnotation ea = (EAnnotation) oea;
if (ea.getSource().toLowerCase().equals(oclNsUri.toLowerCase())) {
Element tree = new Element("tree");
for (Object key : ea.getDetails().keySet()) {
if (key instanceof String) {
String strKey = (String) key;
if (key.equals("invariant")) {
// the EClassifier, not the EOperation
context = context.eContainer();
}
Object val = ea.getDetails().get(key);
Element xmlNode = null;
if (val instanceof String) {
xmlNode = displayOCL((String) val, context, strKey);
tree.addContent(xmlNode);
}
}
}
openViewOn(tree);
}
}
}
private Element displayOCL(String expression, EObject context, String key) {
org.eclipse.ocl.OCL ocl = null;
org.eclipse.ocl.helper.OCLHelper helper = null;
Element res = new Element(key);
res.setAttribute("textualInput", expression);
if (context instanceof org.eclipse.uml2.uml.NamedElement) {
ocl = org.eclipse.ocl.uml.OCL.newInstance();
} else {
ocl = org.eclipse.ocl.ecore.OCL.newInstance();
}
helper = ocl.createOCLHelper();
// set our helper's context object to parse against it
if ((context instanceof org.eclipse.emf.ecore.EClass)
|| (context instanceof org.eclipse.uml2.uml.Classifier)) {
helper.setContext(context);
} else if (context instanceof org.eclipse.emf.ecore.EOperation) {
EOperation eOp = (EOperation) context;
helper.setOperationContext(eOp.getEContainingClass(), eOp);
} else if (context instanceof org.eclipse.uml2.uml.Operation) {
org.eclipse.uml2.uml.Operation op = (org.eclipse.uml2.uml.Operation) context;
helper.setOperationContext(op.getOwner(), op);
} else if (context instanceof org.eclipse.emf.ecore.EStructuralFeature) {
EStructuralFeature sf = (EStructuralFeature) context;
helper.setAttributeContext(sf.getEContainingClass(), sf);
} else if (context instanceof org.eclipse.uml2.uml.Property) {
org.eclipse.uml2.uml.Property p = (org.eclipse.uml2.uml.Property) context;
helper.setAttributeContext(p.getOwner(), p);
}
OCLExpression<EClassifier> oclExp = null;
Element xmlAST = null;
try {
oclExp = helper.createQuery(expression);
} catch (Exception e) {
xmlAST = reportException(e);
res.addContent(xmlAST);
return res;
}
XMLforOCL xfo = null;
// OCLArithSimplifier simplifier = null;
if (context instanceof org.eclipse.uml2.uml.NamedElement) {
xfo = XMLforOCL.getUML2Version();
// simplifier = OCLArithSimplifier.getUML2Version();
} else {
xfo = XMLforOCL.getEcoreVersion();
// simplifier = OCLArithSimplifier.getEcoreVersion();
}
try {
// oclExp = (OCLExpression) oclExp.accept(simplifier);
xmlAST = (Element) oclExp.accept(xfo); //
} catch (Exception e) {
xmlAST = reportException(e);
}
res.addContent(xmlAST);
return res;
}
private Element reportException(Exception e) {
String elemName = e.getClass().getName();
Element xmlAST = new Element(elemName);
String msg = e.getMessage();
if (msg == null) {
msg = "NULL";
}
xmlAST.setAttribute("msg", msg);
int counter = 0;
StackTraceElement[] sttr = e.getStackTrace();
for (StackTraceElement ste : sttr) {
String string = ste.toString();
Element eL = new Element("line_" + counter);
eL.setAttribute("elem", string);
xmlAST.addContent(eL);
counter++;
}
return xmlAST;
}
private void clearView() {
viewer.setInput(invisibleXml);
viewer.refresh();
viewer.expandAll();
}
/**
* Opens this view showing <code>tree</code>
*
* @param elem
*/
public void openViewOn(Element tree) {
Element root = new Element("root");
root.addContent(tree);
viewer.setInput(root);
viewer.refresh();
viewer.expandAll();
}
}
|