001package jmri.jmrit.logix; 002 003import java.util.HashMap; 004import java.util.Iterator; 005import java.util.Map; 006import java.util.Map.Entry; 007 008import jmri.InstanceManager; 009import jmri.implementation.AbstractShutDownTask; 010import jmri.jmrit.roster.Roster; 011import jmri.jmrit.roster.RosterEntry; 012import jmri.jmrit.roster.RosterSpeedProfile; 013import org.slf4j.Logger; 014import org.slf4j.LoggerFactory; 015 016/** 017 * 018 * Allows user to decide if (and which) SpeedProfiles to write to the Roster at 019 * the end of a session. Locos running warrants have had their speeds measured 020 * and this new data may or may not be merged into any existing SpeedProfiles in 021 * the Roster. 022 * 023 * @author Pete cressman Copyright (C) 2017 024 */ 025public class WarrantShutdownTask extends AbstractShutDownTask { 026 027 HashMap<String, Boolean> _mergeCandidates; 028 HashMap<String, RosterSpeedProfile> _mergeProfiles; 029 Map<String, Map<Integer, Boolean>> _anomalies; 030 031 /** 032 * Constructor specifies the warning message and action to take 033 * 034 * @param name the name of the task (used in logs) 035 */ 036 public WarrantShutdownTask(String name) { 037 super(name); 038 } 039 040 /** 041 * {@inheritDoc} 042 */ 043 @Override 044 public Boolean call() { 045 WarrantPreferences preferences = WarrantPreferences.getDefault(); 046 switch (preferences.getShutdown()) { 047 case MERGE_ALL: 048 if (makeMergeCandidates()) { 049 if (_anomalies != null && _anomalies.size() > 0) { 050 makeMergeWindow(); 051 } 052 setDoRun(true); 053 } 054 break; 055 case PROMPT: 056 if (makeMergeCandidates()) { 057 makeMergeWindow(); 058 setDoRun(true); 059 } 060 break; 061 case NO_MERGE: 062 // do nothing 063 break; 064 default: 065 log.warn("No choice made for warrant shutdown"); 066 break; 067 } 068 return true; 069 } 070 071 /** 072 * {@inheritDoc} 073 */ 074 @Override 075 public void run() { 076 if (isDoRun()) { 077 merge(); 078 } 079 } 080 081 private boolean makeMergeCandidates() { 082 WarrantManager manager = InstanceManager.getDefault(WarrantManager.class); 083 _mergeProfiles = manager.getMergeProfiles(); 084 if (_mergeProfiles == null || _mergeProfiles.isEmpty()) { 085 return false; 086 } 087 _anomalies = new HashMap<>(); 088 _mergeCandidates = new HashMap<>(); 089 Iterator<java.util.Map.Entry<String, RosterSpeedProfile>> iter = _mergeProfiles.entrySet().iterator(); 090 while (iter.hasNext()) { 091 java.util.Map.Entry<String, RosterSpeedProfile> entry = iter.next(); 092 Map<Integer, Boolean> anomaly = MergePrompt.validateSpeedProfile(entry.getValue()); 093 if (anomaly != null && anomaly.size() > 0) { 094 _anomalies.put(entry.getKey(), anomaly); 095 } 096 String rosterId = entry.getKey(); 097 if (Roster.getDefault().getEntryForId(rosterId) != null) { 098 _mergeCandidates.put(rosterId, true); 099 } 100 } 101 if (_mergeCandidates.isEmpty()) { 102 return false; 103 } 104 return true; 105 } 106 107 private void makeMergeWindow() { 108 new MergePrompt(Bundle.getMessage("MergeTitle"), _mergeCandidates, _anomalies); 109 } 110 111 private void merge() { 112 for (Entry<String, Boolean> entry : _mergeCandidates.entrySet()) { 113 if (entry.getValue()) { 114 String id = entry.getKey(); 115 RosterEntry rosterEntry = Roster.getDefault().entryFromTitle(id); 116 if (rosterEntry != null) { 117 rosterEntry.setSpeedProfile(_mergeProfiles.get(id)); 118 log.debug("Write SpeedProfile to Roster. id= {}", id); 119 } else { 120 log.debug("Unable to Write SpeedProfile to Roster. No RosterEntry for {}", id); 121 } 122 } else { 123 log.debug("SpeedProfile not merged to Roster. id= {}", entry.getKey()); 124 } 125 } 126 Roster.getDefault().writeRoster(); 127 } 128 129 private static final Logger log = LoggerFactory.getLogger(WarrantShutdownTask.class); 130 131}