001package jmri.jmrit.logixng.actions; 002 003import java.io.*; 004import java.util.*; 005 006import jmri.*; 007import jmri.jmrit.logixng.*; 008import jmri.jmrit.logixng.util.*; 009import jmri.jmrit.logixng.util.parser.*; 010import jmri.util.FileUtil; 011 012/** 013 * This action executes a program. 014 * 015 * @author Daniel Bergqvist Copyright 2025 016 */ 017public class ExecuteProgram extends AbstractDigitalAction { 018 019 private final LogixNG_SelectString _selectProgram = 020 new LogixNG_SelectString(this); 021 private final LogixNG_SelectStringList _selectParameters = 022 new LogixNG_SelectStringList(); 023 private final LogixNG_SelectString _selectWorkingDirectory = 024 new LogixNG_SelectString(this, ""); 025 026 027 public ExecuteProgram(String sys, String user) 028 throws BadUserNameException, BadSystemNameException { 029 super(sys, user); 030 } 031 032 @Override 033 public Base getDeepCopy(Map<String, String> systemNames, Map<String, String> userNames) throws ParserException, JmriException { 034 DigitalActionManager manager = InstanceManager.getDefault(DigitalActionManager.class); 035 String sysName = systemNames.get(getSystemName()); 036 String userName = userNames.get(getSystemName()); 037 if (sysName == null) sysName = manager.getAutoSystemName(); 038 ExecuteProgram copy = new ExecuteProgram(sysName, userName); 039 copy.setComment(getComment()); 040 _selectProgram.copy(copy._selectProgram); 041 _selectParameters.copy(copy._selectParameters); 042 _selectWorkingDirectory.copy(copy._selectWorkingDirectory); 043 return manager.registerAction(copy).deepCopyChildren(this, systemNames, userNames); 044 } 045 046 public LogixNG_SelectString getSelectProgram() { 047 return _selectProgram; 048 } 049 050 public LogixNG_SelectStringList getSelectParameters() { 051 return _selectParameters; 052 } 053 054 public LogixNG_SelectString getSelectWorkingDirectory() { 055 return _selectWorkingDirectory; 056 } 057 058 /** {@inheritDoc} */ 059 @Override 060 public Category getCategory() { 061 return Category.OTHER; 062 } 063 064 /** {@inheritDoc} */ 065 @Override 066 public void execute() throws JmriException { 067 final ConditionalNG conditionalNG; 068 069 synchronized(this) { 070 conditionalNG = getConditionalNG(); 071 } 072 073 String program = _selectProgram.evaluateValue(conditionalNG); 074 List<String> parameters = _selectParameters.evaluateValue(conditionalNG); 075 String workingDirectory = _selectWorkingDirectory.evaluateValue(conditionalNG); 076 077 File workingDirectoryFile; 078 if (!workingDirectory.isBlank()) { 079 workingDirectoryFile = new File(workingDirectory); 080 } else { 081 // Ensure the default folder is the preferences folder. 082 workingDirectoryFile = new File(FileUtil.getUserFilesPath()); 083 } 084 085 List<String> programAndParameters = new ArrayList<>(); 086 programAndParameters.add(program); 087 programAndParameters.addAll(parameters); 088 089 try { 090 Runtime.getRuntime().exec( 091 programAndParameters.toArray(String[]::new), 092 null, 093 workingDirectoryFile); 094 } catch (IOException e) { 095 throw new JmriException(e); 096 } 097 } 098 099 @Override 100 public String getShortDescription(Locale locale) { 101 return Bundle.getMessage(locale, "ExecuteProgram_Short"); 102 } 103 104 @Override 105 public String getLongDescription(Locale locale) { 106 String program = _selectProgram.getDescription(locale); 107 return Bundle.getMessage(locale, "ExecuteProgram_Long", program); 108 } 109 110 /** {@inheritDoc} */ 111 @Override 112 public void setup() { 113 // Do nothing 114 } 115 116 /** {@inheritDoc} */ 117 @Override 118 public void disposeMe() { 119 } 120 121 122// private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(ExecuteProgram.class); 123 124}