/******************************************************************************* * Copyright (c) 2005 - 2007 committers of openArchitectureWare and others. * All rights reserved. This program and the accompanying materials * are 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: * committers of openArchitectureWare - initial API and implementation *******************************************************************************/ package org.eclipse.emf.mwe.internal.core.debug.mwe; import java.util.ArrayList; import java.util.List; import org.eclipse.emf.mwe.core.WorkflowComponent; import org.eclipse.emf.mwe.core.WorkflowContext; import org.eclipse.emf.mwe.core.container.CompositeComponent; import org.eclipse.emf.mwe.core.debug.model.NameValuePair; import org.eclipse.emf.mwe.core.debug.model.SyntaxElement; import org.eclipse.emf.mwe.core.debug.processing.ElementAdapter; import org.eclipse.emf.mwe.internal.core.ast.parser.Location; import org.eclipse.emf.mwe.internal.core.ast.parser.XmlLocationAnalyser; import org.eclipse.emf.mwe.internal.core.util.ComponentPrinter; /** * The IElementAdapter implementation for WorkflowComponents. */ public class WorkflowElementAdapter implements ElementAdapter { public static final String TYPE = "workflow"; private Object context; private CompositeComponent root; private final XmlLocationAnalyser locationAnalyser; // ------------------------------------------------------------------------- public WorkflowElementAdapter() { this.locationAnalyser = new XmlLocationAnalyser(); } // ------------------------------------------------------------------------- public Object getContext() { return context; } public void setContext(Object context) { this.context = context; } public String getAdapterType() { return TYPE; } // ------------------------------------------------------------------------- public boolean canHandle(Object element) { if (element instanceof WorkflowComponent) { if (root == null) { root = ((WorkflowComponent) element).getContainer(); } return true; } if (element instanceof SyntaxElement) { SyntaxElement se = (SyntaxElement) element; return se.resource.endsWith(".oaw"); } return false; } public boolean shallHandle(Object element) { // no special treatment for workflow components return true; } public boolean shallSuspend(Object element, int flag) { // no special treatment for workflow components return true; } public boolean shallAddToCallStack(Object element) { return true; } public boolean isSurroundingElement(Object element) { return CompositeComponent.class.isAssignableFrom(element.getClass()); } public SyntaxElement createElement(Object element) { WorkflowComponent comp = (WorkflowComponent) element; SyntaxElement se = new SyntaxElement(); Location loc = comp.getLocation(); loc = initialize(loc); se.containerName = ComponentPrinter.getContainerName(comp); se.elementName = ComponentPrinter.getElementName(comp); se.resource = loc.getResource(); se.start = loc.getNameStart(); se.end = loc.getNameEnd(); se.line = loc.getLineNumber(); return se; } public SyntaxElement createEndElementTO(Object element) { CompositeComponent comp = (CompositeComponent) element; SyntaxElement se = new SyntaxElement(); Location loc = comp.getOwnLocation(); if (loc == null) { // for root loc = comp.getLocation(); } loc = initializeEndLocation(loc); se.containerName = ComponentPrinter.getElementName(comp); se.elementName = "end of cartridge"; if (loc != null) { se.resource = loc.getResource(); se.start = loc.getNameStart(); se.end = loc.getNameEnd(); se.line = loc.getLineNumber(); } return se; } public List<NameValuePair> getVariables(Object element) { List<NameValuePair> list = new ArrayList<NameValuePair>(); if (element instanceof WorkflowComponent) { // TODO: ER: show Variables, that are workflow properties // Note: only the available slot variables are shown // internal variables of the WfComponent are neither visible before // start nor after end of invocation // that's why we don't check the element itself WorkflowContext ctx = (WorkflowContext) context; for (String name : ctx.getSlotNames()) { list.add(new NameValuePair(name, ctx.get(name))); } } else { int i = 0; for (String name : ReflectionUtil.getFieldNames(element)) { Object childElement; // ReflectionUtil returns a name format "[" + i + "]" for // arrays, therefore we can't use name here if (element instanceof Object[]) { childElement = ((Object[]) element)[i++]; } else { childElement = ReflectionUtil.getFieldValue(element, name); } list.add(new NameValuePair(name, childElement)); } } return list; } public String getVariableDetailRep(Object element) { return ReflectionUtil.getNameToString(element); } public String getVariableSimpleRep(Object element) { return ReflectionUtil.getSimpleName(element); } public boolean checkVariableHasMembers(Object element) { return ReflectionUtil.checkFields(element); } public Object findElement(SyntaxElement se, Object actual, int flag) { if (root == null) return null; return findComponent(root, se.resource, se.line); } private Object findComponent(CompositeComponent parent, String resource, int lineNo) { Location loc = parent.getOwnLocation(); if (loc == null) { loc = parent.getLocation(); } if (resource.endsWith(loc.getResource())) { for (WorkflowComponent comp : parent.getComponents()) if (comp.getLocation().getLineNumber() == lineNo) return comp; } for (WorkflowComponent comp : parent.getComponents()) if (comp instanceof CompositeComponent) { CompositeComponent child = (CompositeComponent) comp; Object found = findComponent(child, resource, lineNo); if (found != null) return found; } return null; } private Location initialize(Location loc) { if (loc.getResource() == null) return null; return locationAnalyser.adapt(loc); } private Location initializeEndLocation(Location loc) { if (loc.getResource() == null) return null; return locationAnalyser.adaptEnd(loc); } }