/******************************************************************************* * Copyright (c) 2012 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.modeling.typicals.rules; import java.util.Set; import gnu.trove.set.hash.THashSet; import org.simantics.db.Resource; import org.simantics.db.WriteGraph; import org.simantics.db.common.utils.NameUtils; import org.simantics.db.exception.DatabaseException; import org.simantics.diagram.flag.FlagUtil; import org.simantics.diagram.stubs.DiagramResource; import org.simantics.modeling.typicals.ITypicalSynchronizationRule; import org.simantics.modeling.typicals.TypicalInfo; import org.simantics.utils.ui.ErrorLogger; /** * Synchronizes: * * joins * * flag type * * external tag * * IO table binding * * IO table row index * * @author Tuukka Lehtonen */ public enum FlagRule implements ITypicalSynchronizationRule { INSTANCE; public static FlagRule getInstance() { return INSTANCE; } @Override public boolean synchronize(WriteGraph graph, Resource template, Resource instance, TypicalInfo info) throws DatabaseException { DiagramResource DIA = DiagramResource.getInstance(graph); boolean changed = false; boolean result = Properties.synchronizeEnumerationPropertyValue(graph, template, instance, DIA.HasFlagType); if(result) info.messageLog.add("\t\t\tflag type"); changed |= result; result = Properties.synchronizeTag(graph, template, instance, DIA.ExternalFlag); if(result) info.messageLog.add("\t\t\texternal status"); changed |= result; result = Properties.synchronizePrimitivePropertyValue(graph, template, instance, DIA.Flag_HasIOTableBinding); if(result) info.messageLog.add("\t\t\tIO table binding"); changed |= result; result = Properties.synchronizePrimitivePropertyValue(graph, template, instance, DIA.Flag_HasIOTableRowIndex); if(result) info.messageLog.add("\t\t\tIO table row"); changed |= result; changed |= synchronizeJoins(graph, template, instance, info); return changed; } public boolean synchronizeJoins(WriteGraph graph, Resource template, Resource instance, TypicalInfo info) throws DatabaseException { boolean changed = false; Set tCounterparts = FlagUtil.getCounterparts(graph, template, new THashSet(2)); Set iCounterparts = FlagUtil.getCounterparts(graph, instance, new THashSet(2)); if (tCounterparts.isEmpty() && iCounterparts.isEmpty()) return false; for (Resource tCounterpart : tCounterparts) { if (!info.bean.templateElements.contains(tCounterpart)) { // Ignore external flag reference in synchronization. // The user should not be able to create these at all. ErrorLogger.defaultLogWarning("Encountered flag " + NameUtils.getSafeName(graph, template, true) + " in a typical template diagram with an invalid flag reference to correspondence " + NameUtils.getSafeName(graph, tCounterpart, true), new Exception("trace")); continue; } Resource i = info.bean.templateToInstance.get(tCounterpart); if (i == null) { ErrorLogger.defaultLogError( "Encountered flag " + NameUtils.getSafeName(graph, template, true) + " in a typical template diagram while the instance diagram flag " + NameUtils.getSafeName(graph, instance, true) + " does not contain an element mapped to template flag correspondence " + NameUtils.getSafeName(graph, tCounterpart, true), new Exception("trace")); continue; } if (iCounterparts.remove(i)) // instance has the similar counterpart as the template continue; // Instance does not have the same counterpart as the template. // Create a new join. FlagUtil.join(graph, instance, i); info.messageLog.add("\t\t\tsynchronized join " + NameUtils.getSafeName(graph, i)); changed = true; } // iCounterparts contains the set of joins that should be severed for // the instance flag. for (Resource iCounterpart : iCounterparts) { FlagUtil.disconnectFlag(graph, instance, iCounterpart); info.messageLog.add("\t\t\tdisconnected flag " + NameUtils.getSafeName(graph, iCounterpart)); changed = true; } return changed; } }