package org.archstudio.xadl.bna.logics.mapping; import static org.archstudio.sysutils.SystemUtils.firstOrNull; import java.util.Set; import org.archstudio.bna.IBNAModelListener; import org.archstudio.bna.IBNAWorld; import org.archstudio.bna.IThing; import org.archstudio.bna.keys.IThingKey; import org.archstudio.bna.keys.IThingMetakey; import org.archstudio.bna.keys.IThingRefKey; import org.archstudio.bna.keys.ThingMetakey; import org.archstudio.bna.logics.AbstractKeyCoordinatingThingLogic; import org.archstudio.bna.utils.BNAUtils; import org.archstudio.xadl.bna.facets.IHasXArchID; import com.google.common.collect.Sets; public class SynchronizeThingIDAndXArchIDLogic extends AbstractKeyCoordinatingThingLogic implements IBNAModelListener { private static final String XARCH_ID_NAME = ".xArchID"; private final Set<IThingMetakey<?, IThingRefKey<?>, String>> xArchIDMetakeys = Sets.newHashSet(); public SynchronizeThingIDAndXArchIDLogic(IBNAWorld world) { super(world, true); track(IHasXArchID.XARCH_ID_KEY); } public IThingMetakey<?, IThingRefKey<?>, String> syncXArchIDKeyToThingIDKey(IThingRefKey<?> thingRefKey) { BNAUtils.checkLock(); track(thingRefKey); IThingMetakey<?, IThingRefKey<?>, String> xArchIDMetakey = _syncXArchIDKeyToThingIDKey(thingRefKey); xArchIDMetakeys.add(xArchIDMetakey); track(xArchIDMetakey); return xArchIDMetakey; } private IThingMetakey<?, IThingRefKey<?>, String> _syncXArchIDKeyToThingIDKey(IThingRefKey<?> thingRefKey) { return ThingMetakey.<String, IThingRefKey<?>, String> create(XARCH_ID_NAME, thingRefKey); } @Override protected void update(IThing thing, IThingKey<?> key) { if (IHasXArchID.XARCH_ID_KEY.equals(key)) { String xArchID = thing.get(IHasXArchID.XARCH_ID_KEY); if (xArchID != null) { for (IThingMetakey<?, IThingRefKey<?>, String> xArchIDKey : xArchIDMetakeys) { for (IThing thingWithXArchID : valueLogic.getThings(xArchIDKey, xArchID)) { thingWithXArchID.set(xArchIDKey.getKey(), thing.getID()); } } } } else if (key instanceof IThingMetakey && XARCH_ID_NAME.equals(((IThingMetakey<?, ?, ?>) key).getName())) { @SuppressWarnings("unchecked") IThingMetakey<?, IThingRefKey<?>, String> xArchIDKey = (IThingMetakey<?, IThingRefKey<?>, String>) key; String xArchID = thing.get(xArchIDKey); if (xArchID != null) { thing.set(xArchIDKey.getKey(), firstOrNull(valueLogic.getThingIDs(IHasXArchID.XARCH_ID_KEY, xArchID))); } else { thing.remove(xArchIDKey.getKey()); } } else if (key instanceof IThingRefKey) { IThingRefKey<?> refKey = (IThingRefKey<?>) key; IThingMetakey<?, IThingRefKey<?>, String> xArchIDKey = _syncXArchIDKeyToThingIDKey(refKey); String xArchID = null; if (thing.has(xArchIDKey)) { IThing referencedThing = refKey.get(thing, model); xArchID = referencedThing != null ? referencedThing.get(IHasXArchID.XARCH_ID_KEY) : null; } if (xArchID != null) { thing.set(xArchIDKey, xArchID); } else { thing.remove(xArchIDKey); } } } }