/******************************************************************************* * 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.diagram.connection; import java.util.ArrayList; import java.util.Arrays; import org.simantics.db.ReadGraph; import org.simantics.db.RequestProcessor; import org.simantics.db.Resource; import org.simantics.db.Session; import org.simantics.db.exception.DatabaseException; import org.simantics.db.request.Read; import org.simantics.diagram.content.ConnectionUtil; import org.simantics.g2d.connection.IConnectionAdvisor; import org.simantics.g2d.diagram.handler.Topology.Terminal; import org.simantics.g2d.element.ElementUtils; import org.simantics.g2d.element.IElement; import org.simantics.g2d.elementclass.FlagHandler; import org.simantics.structural2.modelingRules.CPIgnore; import org.simantics.structural2.modelingRules.ConnectionJudgement; import org.simantics.structural2.modelingRules.ConnectionJudgementType; import org.simantics.structural2.modelingRules.IConnectionPoint; import org.simantics.structural2.modelingRules.IModelingRules; /** * To customize, prefer overriding * {@link #canBeConnected(ReadGraph, IElement, Terminal, IElement, Terminal)} * and {@link #canBeginConnection(ReadGraph, IElement, Terminal)}. * * @author Hannu Niemistö */ public class ModelledConnectionAdvisor implements IConnectionAdvisor { protected IModelingRules modelingRules; protected Session session; /** * @param modelingRules * @param session */ public ModelledConnectionAdvisor(IModelingRules modelingRules, Session session) { this.modelingRules = modelingRules; this.session = session; } protected IConnectionPoint getConnectionPoint(ReadGraph g, IElement element, Terminal term) throws DatabaseException { return getConnectionPoint(g, element, term, false); } protected IConnectionPoint getConnectionPoint(ReadGraph g, IElement element, Terminal term, boolean ignoreUnrecognized) throws DatabaseException { Object obj = null; if (element != null) obj = ElementUtils.getObject(element); if (obj instanceof Resource) { Resource elementResource = (Resource) obj; return ConnectionUtil.toConnectionPoint(g, elementResource, term); } // FIXME: this currently allows connections to begin from flags // but is rather hackish. if (element.getElementClass().containsClass(FlagHandler.class)) { return CPIgnore.NULL_INSTANCE; } if (ignoreUnrecognized) return CPIgnore.NULL_INSTANCE; throw new IllegalArgumentException("Cannot get IConnectionPoint for (element,terminal) pair:\n\t" + element + "\n\t" + term); } @Override public Object canBeConnected(Object backend, final IElement element1, final Terminal term1, final IElement element2, final Terminal term2) { try { if (backend == null) backend = session; return ((RequestProcessor)backend).syncRequest(new Read() { @Override public Object perform(ReadGraph g) throws DatabaseException { return canBeConnected(g, element1, term1, element2, term2); } }); } catch(DatabaseException e) { e.printStackTrace(); return null; } } @Override public boolean canBeginConnection(Object backend, final IElement element, final Terminal term) { try { if (backend == null) backend = session; return ((RequestProcessor)backend).syncRequest(new Read() { @Override public Boolean perform(ReadGraph g) throws DatabaseException { return canBeginConnection(g, element, term); } }); } catch (DatabaseException e) { e.printStackTrace(); return false; } } protected Object canBeConnected(ReadGraph graph, IElement element1, Terminal term1, IElement element2, Terminal term2) throws DatabaseException { ArrayList cps = new ArrayList(2); if (element1 != null) cps.add(getConnectionPoint(graph, element1, term1, true)); if (element2 != null) cps.add(getConnectionPoint(graph, element2, term2, true)); ConnectionJudgement judgement = modelingRules.judgeConnection(graph, cps); if (judgement.type == ConnectionJudgementType.LEGAL) return judgement; return null; } protected boolean canBeginConnection(ReadGraph graph, IElement element, Terminal term) throws DatabaseException { return modelingRules.judgeConnection(graph, Arrays.asList(getConnectionPoint(graph, element, term))) .type != ConnectionJudgementType.ILLEGAL; } }