/* * Copyright (c) 2015 EMC Corporation * All Rights Reserved */ package com.emc.storageos.db.common; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import org.springframework.context.support.FileSystemXmlApplicationContext; public class DbMigrationCallbackChecker { private static final String SERVICE_BEAN = "versionedCustomMigrationCallbacks"; private static final String ADD_CALLBACK = "add"; private static final String REMOVE_CALLBACK = "remove"; private Map<String, List<String>> baseVersionedCallbacks = null; private Map<String, List<String>> currentVersionedCallbacks = null; public DbMigrationCallbackChecker(final String baseFile, final String currentFile) { this.baseVersionedCallbacks = getVersionedCallbacks(baseFile); this.currentVersionedCallbacks = getVersionedCallbacks(currentFile); } public DbMigrationCallbackChecker(final Map<String, List<String>> baseCallbacks, final Map<String, List<String>> currentCallbacks) { this.baseVersionedCallbacks = baseCallbacks; this.currentVersionedCallbacks = currentCallbacks; } @SuppressWarnings("unchecked") private Map<String, List<String>> getVersionedCallbacks(final String beanFile) { FileSystemXmlApplicationContext ctx = new FileSystemXmlApplicationContext(beanFile); Map<String, List<Object>> bean = (Map<String, List<Object>>) ctx.getBean(SERVICE_BEAN); Map<String, List<String>> versionedCallbacks = new HashMap<String, List<String>>(); for (Map.Entry<String, List<Object>> versionEntry : bean.entrySet()) { List<String> callbacks = new ArrayList<String>(); for (Object callbackInstance : versionEntry.getValue()) { callbacks.add(callbackInstance.getClass().getCanonicalName()); } versionedCallbacks.put(versionEntry.getKey(), callbacks); } return versionedCallbacks; } public boolean hasDiff() { if (this.baseVersionedCallbacks == null || this.currentVersionedCallbacks == null) { return false; } if (this.baseVersionedCallbacks.size() != this.currentVersionedCallbacks.size()) { return true; } for (Entry<String, List<String>> currentCallbacks : this.currentVersionedCallbacks.entrySet()) { List<String> baseCallbacks = this.baseVersionedCallbacks.get(currentCallbacks.getKey()); List<MigrationCallbackDiff> listDiff = getListDiff(baseCallbacks, currentCallbacks.getValue()); if (listDiff != null && !listDiff.isEmpty()) { return true; } } return false; } public Map<String, List<MigrationCallbackDiff>> getDiff() { Map<String, List<MigrationCallbackDiff>> versionedDiffs = new HashMap<String, List<MigrationCallbackDiff>>(); for (Map.Entry<String, List<String>> versionedCurrentCallbacks : this.currentVersionedCallbacks.entrySet()) { List<String> baseCallbacks = this.baseVersionedCallbacks.get(versionedCurrentCallbacks.getKey()); List<MigrationCallbackDiff> diff = getListDiff(baseCallbacks, versionedCurrentCallbacks.getValue()); if (diff != null && !diff.isEmpty()) { versionedDiffs.put(versionedCurrentCallbacks.getKey(), diff); } } return Collections.unmodifiableMap(versionedDiffs); } private List<MigrationCallbackDiff> getListDiff(final List<String> baseCallbacks, final List<String> list) { if (baseCallbacks == null || baseCallbacks.isEmpty()) { return MigrationCallbackDiff.build(ADD_CALLBACK, list); } if (list == null || list.isEmpty()) { return MigrationCallbackDiff.build(REMOVE_CALLBACK, baseCallbacks); } List<MigrationCallbackDiff> diffs = new ArrayList<MigrationCallbackDiff>(); for (String callback : baseCallbacks) { if (!list.contains(callback)) { diffs.add(MigrationCallbackDiff.build(REMOVE_CALLBACK, callback)); } } for (String callback : list) { if (!baseCallbacks.contains(callback)) { diffs.add(MigrationCallbackDiff.build(ADD_CALLBACK, callback)); } } return diffs; } public void setBaselineVersionedCallbacks( Map<String, List<String>> baselineVersionedCallbacks) { this.baseVersionedCallbacks = baselineVersionedCallbacks; } public void setCurrentVersionedCallbacks( Map<String, List<String>> currentVersionedCallbacks) { this.currentVersionedCallbacks = currentVersionedCallbacks; } public static class MigrationCallbackDiff { private String action; private String callback; public MigrationCallbackDiff(String action, String callback) { super(); this.action = action; this.callback = callback; } public String getAction() { return action; } public void setAction(String action) { this.action = action; } public String getCallback() { return callback; } public void setCallback(String callback) { this.callback = callback; } public static List<MigrationCallbackDiff> build(final String action, final List<String> list) { List<MigrationCallbackDiff> diffs = new ArrayList<MigrationCallbackDiff>(); if (action == null || list == null) { return diffs; } for (String callback : list) { MigrationCallbackDiff diff = new MigrationCallbackDiff(action, callback); diffs.add(diff); } return diffs; } @Override public String toString() { return this.action + " " + this.callback; } public static MigrationCallbackDiff build(final String action, final String callback) { return new MigrationCallbackDiff(action, callback); } } }