/******************************************************************************* * Copyright (c) 2007, 2010 Association for Decentralized Information Management * in Industry THTH ry. * 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: * VTT Technical Research Centre of Finland - initial API and implementation *******************************************************************************/ package org.simantics.g2d.diagram.participant; import java.lang.reflect.Field; import org.simantics.g2d.canvas.ICanvasContext; import org.simantics.g2d.canvas.impl.AbstractCanvasParticipant; import org.simantics.g2d.canvas.impl.DependencyReflection; import org.simantics.g2d.canvas.impl.DependencyReflection.ReferenceDefinition; import org.simantics.g2d.canvas.impl.DependencyReflection.ReferenceType; import org.simantics.g2d.canvas.impl.HintReflection.HintListener; import org.simantics.g2d.diagram.DiagramClass; import org.simantics.g2d.diagram.DiagramHints; import org.simantics.g2d.diagram.IDiagram; import org.simantics.g2d.diagram.handler.DiagramHandler; import org.simantics.utils.datastructures.hints.IHintObservable; import org.simantics.utils.datastructures.hints.IHintContext.Key; /** * This is a base implementation for all participants that handle * diagram. * * Features: * - Overrideable onDiagramSet() method * - diagram -field points to current diagram * - DiagramHandlers accessible with @Dependency and @Reference annotations * * TODO add Diagram class handler annotations * @author Toni Kalajainen */ public class AbstractDiagramParticipant extends AbstractCanvasParticipant { public IDiagram diagram; public DiagramClass clazz; protected ReferenceDefinition[] handlerDefs; boolean handlerDepsSatisfied = true; public AbstractDiagramParticipant() { super(); handlerDefs = DependencyReflection.getDependencies(this, ReferenceType.DiagramHandler); } @HintListener(Class=DiagramHints.class, Field="KEY_DIAGRAM") public void hintChanged(IHintObservable sender, Key key, Object oldValue, Object newValue) { if (oldValue==newValue) return; _setDiagram( (IDiagram) newValue ); } @HintListener(Class=DiagramHints.class, Field="KEY_DIAGRAM") public void hintRemoved(IHintObservable sender, Key key, Object oldValue) { _setDiagram(null); } @Override public void addedToContext(ICanvasContext ctx) { super.addedToContext(ctx); _setDiagram( (IDiagram) ctx.getHintStack().getHint(DiagramHints.KEY_DIAGRAM) ); } @Override public void removedFromContext(ICanvasContext ctx) { _setDiagram(null); super.removedFromContext(ctx); } @Override public void assertDependencies() { super.assertDependencies(); assert(diagram!=null); } private void _setDiagram(IDiagram d) { IDiagram oldDiagram = this.diagram; this.diagram = d; if (d!=null) clazz = d.getDiagramClass(); else clazz=null; if (clazz!=null) { try { for (DiagramHandler h : clazz.getAll()) { Class c = h.getClass(); for (ReferenceDefinition def : handlerDefs) { Class defClass = def.requirement; if (!defClass.isAssignableFrom(c)) continue; Field f = def.field; //Object value = f.get(this); //assert(value==null); f.set(this, h); } } } catch (Exception e) { throw new RuntimeException(e); } handlerDepsSatisfied = checkHandlerDependencies(); } else { try { for (ReferenceDefinition def : handlerDefs) { Field f = def.field; f.set(this, null); } } catch (Exception e) { throw new RuntimeException(e); } handlerDepsSatisfied = true; } onDiagramSet(this.diagram, oldDiagram); } /** * OVERRIDE THIS to hook diagram modifications * @param newDiagram new diagram or null * @param oldDiagram .. */ protected void onDiagramSet(IDiagram newDiagram, IDiagram oldDiagram) { } private boolean checkHandlerDependencies() { try { for (ReferenceDefinition rd : handlerDefs) { if (!rd.dependency) continue; Field f = rd.field; Object o = f.get(this); if (o == null) return false; } } catch (Exception e) { throw new RuntimeException(e); } return true; } }