001package jmri.jmrit.operations.automation.actions; 002 003import java.io.File; 004 005import org.slf4j.Logger; 006import org.slf4j.LoggerFactory; 007 008import jmri.InstanceManager; 009import jmri.jmrit.operations.locations.Location; 010import jmri.jmrit.operations.locations.LocationManager; 011import jmri.jmrit.operations.setup.Control; 012import jmri.jmrit.operations.setup.Setup; 013import jmri.jmrit.operations.trains.Train; 014import jmri.jmrit.operations.trains.TrainCsvSwitchLists; 015import jmri.jmrit.operations.trains.TrainManager; 016import jmri.jmrit.operations.trains.TrainSwitchLists; 017import jmri.jmrit.operations.trains.excel.TrainCustomManifest; 018import jmri.jmrit.operations.trains.excel.TrainCustomSwitchList; 019 020public class RunSwitchListChangesAction extends Action { 021 022 private static final int _code = ActionCodes.RUN_SWITCHLIST_CHANGES; 023 protected static final boolean IS_CHANGED = true; 024 025 @Override 026 public int getCode() { 027 return _code; 028 } 029 030 @Override 031 public String getName() { 032 return Bundle.getMessage("RunSwitchListChanges"); 033 } 034 035 @Override 036 public void doAction() { 037 doAction(IS_CHANGED); 038 } 039 040 /** 041 * Creates a custom switch list for each location that is selected and there's 042 * new work for that location. 043 * <p> 044 * common code see RunSwitchListAction.java 045 * 046 * @param isChanged if set true only locations with changes will get a custom 047 * switch list. 048 */ 049 protected void doAction(boolean isChanged) { 050 if (getAutomationItem() != null) { 051 if (!Setup.isGenerateCsvSwitchListEnabled()) { 052 log.warn("Generate CSV Switch List isn't enabled!"); 053 finishAction(false); 054 return; 055 } 056 // we do need one of these! 057 if (!InstanceManager.getDefault(TrainCustomSwitchList.class).excelFileExists()) { 058 log.warn("Manifest creator file not found!, directory name: {}, file name: {}", 059 InstanceManager.getDefault(TrainCustomSwitchList.class).getDirectoryName(), 060 InstanceManager.getDefault(TrainCustomSwitchList.class).getFileName()); 061 finishAction(false); 062 return; 063 } 064 setRunning(true); 065 TrainSwitchLists trainSwitchLists = new TrainSwitchLists(); 066 TrainCsvSwitchLists trainCsvSwitchLists = new TrainCsvSwitchLists(); 067 // check that both the Excel custom manifest and custom switch lists aren't busy 068 // with other work 069 // We've found that on some OS only one copy of Excel can be running at a time 070 // this can wait thread 071 if (!InstanceManager.getDefault(TrainCustomManifest.class).checkProcessReady()) { 072 log.warn( 073 "Timeout waiting for excel manifest program to complete previous operation, timeout value: {} seconds", 074 Control.excelWaitTime); 075 } 076 // this can wait thread 077 if (!InstanceManager.getDefault(TrainCustomSwitchList.class).checkProcessReady()) { 078 log.warn( 079 "Timeout waiting for excel switch list program to complete previous operation, timeout value: {} seconds", 080 Control.excelWaitTime); 081 } 082 if (InstanceManager.getDefault(TrainCustomSwitchList.class).doesCommonFileExist()) { 083 log.warn("Switch List CSV common file exists!"); 084 } 085 for (Location location : InstanceManager.getDefault(LocationManager.class).getUniqueLocationsByNameList()) { 086 if (location.isSwitchListEnabled() && 087 (!isChanged || location.getStatus().equals(Location.MODIFIED))) { 088 File csvFile = trainCsvSwitchLists.buildSwitchList(location); 089 // also build the regular switch lists so they can be used 090 trainSwitchLists.buildSwitchList(location); 091 if (csvFile == null || !csvFile.exists()) { 092 log.error("CSV switch list file was not created for location {}", location.getName()); 093 finishAction(false); 094 return; 095 } 096 location.setStatus(Location.PRINTED); 097 location.setSwitchListState(Location.SW_PRINTED); 098 InstanceManager.getDefault(TrainCustomSwitchList.class).addCsvFile(csvFile); 099 log.info("Queued switch list CSV file location ({}) for custom processing", location.getName()); 100 } 101 } 102 // Processes the CSV Manifest files using an external custom program. 103 boolean status = InstanceManager.getDefault(TrainCustomSwitchList.class).process(); 104 if (status) { 105 try { 106 // wait up to 60 seconds per file 107 status = InstanceManager.getDefault(TrainCustomSwitchList.class).waitForProcessToComplete(); 108 } catch (InterruptedException e) { 109 // TODO Auto-generated catch block 110 log.error("Thread interrupeted while waiting", e); 111 } 112 } else { 113 log.info("No switch list changes found"); 114 } 115 // set trains switch lists printed 116 InstanceManager.getDefault(TrainManager.class).setTrainsSwitchListStatus(Train.PRINTED); 117 finishAction(status); 118 } 119 } 120 121 @Override 122 public void cancelAction() { 123 // no cancel for this action 124 } 125 126 private final static Logger log = LoggerFactory.getLogger(RunSwitchListChangesAction.class); 127 128}