package gov.nasa.jpl.mbee.mdk.mms.sync.delta; import com.fasterxml.jackson.core.JsonProcessingException; import com.nomagic.magicdraw.core.Project; import com.nomagic.magicdraw.core.project.ProjectEventListenerAdapter; import com.nomagic.magicdraw.openapi.uml.SessionManager; import com.nomagic.uml2.ext.jmi.helpers.StereotypesHelper; import com.nomagic.uml2.ext.magicdraw.classes.mdkernel.Element; import gov.nasa.jpl.mbee.mdk.mms.sync.jms.JMSMessageListener; import gov.nasa.jpl.mbee.mdk.mms.sync.jms.JMSSyncProjectEventListenerAdapter; import gov.nasa.jpl.mbee.mdk.mms.sync.local.LocalSyncProjectEventListenerAdapter; import gov.nasa.jpl.mbee.mdk.mms.sync.local.LocalSyncTransactionCommitListener; import gov.nasa.jpl.mbee.mdk.json.JacksonUtils; import gov.nasa.jpl.mbee.mdk.util.Changelog; import java.util.function.BiFunction; import java.util.function.Function; import gov.nasa.jpl.mbee.mdk.options.MDKOptionsGroup; import java.util.HashMap; import java.util.Map; /* * This class is responsible for taking action when a project is opened. * This class does the following when instantiated: * 1. Create a transaction manager * 2. Create a TransactionCommitListener object * 3. Add the listener to the transaction manager object * 4. Create a MMS topic and connection to that topic * 5. Store that connection so we keep track of the connections to MMS. * */ public class DeltaSyncProjectEventListenerAdapter extends ProjectEventListenerAdapter { private static final Map<SyncElement.Type, Function<Project, Changelog<String, ?>>> CHANGELOG_FUNCTIONS = new HashMap<>(2); static { CHANGELOG_FUNCTIONS.put(SyncElement.Type.LOCAL, project -> { Changelog<String, Void> combinedPersistedChangelog = new Changelog<>(); for (SyncElement syncElement : SyncElements.getAllOfType(project, SyncElement.Type.LOCAL)) { combinedPersistedChangelog = combinedPersistedChangelog.and(SyncElements.buildChangelog(syncElement)); } LocalSyncTransactionCommitListener localSyncTransactionCommitListener = LocalSyncProjectEventListenerAdapter.getProjectMapping(project).getLocalSyncTransactionCommitListener(); if (localSyncTransactionCommitListener == null) { return combinedPersistedChangelog; } return combinedPersistedChangelog.and(localSyncTransactionCommitListener.getInMemoryLocalChangelog(), (key, element) -> null); }); CHANGELOG_FUNCTIONS.put(SyncElement.Type.MMS, project -> { Changelog<String, Void> combinedPersistedChangelog = new Changelog<>(); for (SyncElement syncElement : SyncElements.getAllOfType(project, SyncElement.Type.MMS)) { combinedPersistedChangelog = combinedPersistedChangelog.and(SyncElements.buildChangelog(syncElement)); } JMSMessageListener jmsMessageListener = JMSSyncProjectEventListenerAdapter.getProjectMapping(project).getJmsMessageListener(); if (jmsMessageListener == null) { return combinedPersistedChangelog; } return combinedPersistedChangelog.and(jmsMessageListener.getInMemoryJMSChangelog(), (key, objectNode) -> null); }); } @Override public void projectPreSaved(Project project, boolean savedInServer) { boolean save = MDKOptionsGroup.getMDKOptions().isPersistChangelog(); if (!save) { return; } if (!StereotypesHelper.hasStereotype(project.getModel(), "ModelManagementSystem")) { return; } persistChanges(project); } private static void persistChanges(Project project) { LocalSyncTransactionCommitListener listener = LocalSyncProjectEventListenerAdapter.getProjectMapping(project).getLocalSyncTransactionCommitListener(); if (listener != null) { listener.setDisabled(true); } if (!SessionManager.getInstance().isSessionCreated(project)) { SessionManager.getInstance().createSession(project, "Delta Sync Changelog Persistence #2"); } for (Map.Entry<SyncElement.Type, Function<Project, Changelog<String, ?>>> entry : CHANGELOG_FUNCTIONS.entrySet()) { Changelog<String, ?> changelog = entry.getValue().apply(project); try { SyncElements.setByType(project, entry.getKey(), JacksonUtils.getObjectMapper().writeValueAsString(SyncElements.buildJson(changelog))); } catch (JsonProcessingException e) { e.printStackTrace(); } } if (SessionManager.getInstance().isSessionCreated(project)) { SessionManager.getInstance().closeSession(); } if (listener != null) { listener.setDisabled(false); } } }