001package jmri.jmrit.logixng.actions; 002 003import java.awt.Desktop; 004import java.io.IOException; 005import java.net.*; 006import java.util.Locale; 007import java.util.Map; 008 009import jmri.InstanceManager; 010import jmri.JmriException; 011import jmri.jmrit.logixng.*; 012 013/** 014 * Executes an string action with the result of an string expression. 015 * 016 * @author Daniel Bergqvist Copyright 2019 017 */ 018public class WebBrowser 019 extends AbstractDigitalAction 020 implements FemaleSocketListener { 021 022 private String _urlExpressionSocketSystemName; 023 private final FemaleStringExpressionSocket _urlExpressionSocket; 024 025 public WebBrowser(String sys, String user) { 026 super(sys, user); 027 _urlExpressionSocket = InstanceManager.getDefault(StringExpressionManager.class) 028 .createFemaleSocket(this, this, "E"); 029 } 030 031 @Override 032 public Base getDeepCopy(Map<String, String> systemNames, Map<String, String> userNames) throws JmriException { 033 DigitalActionManager manager = InstanceManager.getDefault(DigitalActionManager.class); 034 String sysName = systemNames.get(getSystemName()); 035 String userName = userNames.get(getSystemName()); 036 if (sysName == null) sysName = manager.getAutoSystemName(); 037 WebBrowser copy = new WebBrowser(sysName, userName); 038 copy.setComment(getComment()); 039 return manager.registerAction(copy).deepCopyChildren(this, systemNames, userNames); 040 } 041 042 /** {@inheritDoc} */ 043 @Override 044 public Category getCategory() { 045 return Category.OTHER; 046 } 047 048 /** {@inheritDoc} */ 049 @Override 050 public void execute() throws JmriException { 051 String url = _urlExpressionSocket.evaluate(); 052 053 try { 054 URI uri = new URI(url); 055 HttpURLConnection request = (HttpURLConnection) uri.toURL().openConnection(); 056 request.setRequestMethod("GET"); 057 request.connect(); 058 if (request.getResponseCode() != 200) { 059 throw new JmriException(String.format( 060 "Failed to connect to web page: %d, %s", 061 request.getResponseCode(), request.getResponseMessage())); 062 } 063 if ( Desktop.getDesktop().isSupported( Desktop.Action.BROWSE) ) { 064 // Open browser to URL with draft report 065 Desktop.getDesktop().browse(uri); 066 } else { 067 throw new JmriException(String.format( 068 "Failed to connect to web page. java.awt.Desktop doesn't suppport Action.BROWSE")); 069 } 070 } catch (IOException | URISyntaxException e) { 071 throw new JmriException(String.format( 072 "Failed to connect to web page. Exception thrown: %s", 073 e.getMessage()), e); 074 } 075 } 076 077 @Override 078 public FemaleSocket getChild(int index) throws IllegalArgumentException, UnsupportedOperationException { 079 switch (index) { 080 case 0: 081 return _urlExpressionSocket; 082 083 default: 084 throw new IllegalArgumentException( 085 String.format("index has invalid value: %d", index)); 086 } 087 } 088 089 @Override 090 public int getChildCount() { 091 return 1; 092 } 093 094 @Override 095 public void connected(FemaleSocket socket) { 096 if (socket == _urlExpressionSocket) { 097 _urlExpressionSocketSystemName = socket.getConnectedSocket().getSystemName(); 098 } else { 099 throw new IllegalArgumentException("unkown socket"); 100 } 101 } 102 103 @Override 104 public void disconnected(FemaleSocket socket) { 105 if (socket == _urlExpressionSocket) { 106 _urlExpressionSocketSystemName = null; 107 } else { 108 throw new IllegalArgumentException("unkown socket"); 109 } 110 } 111 112 @Override 113 public String getShortDescription(Locale locale) { 114 return Bundle.getMessage(locale, "WebBrowser_Short"); 115 } 116 117 @Override 118 public String getLongDescription(Locale locale) { 119 return Bundle.getMessage(locale, "WebBrowser_Long", _urlExpressionSocket.getName()); 120 } 121 122 public FemaleStringExpressionSocket getStringExpressionSocket() { 123 return _urlExpressionSocket; 124 } 125 126 public String getStringExpressionSocketSystemName() { 127 return _urlExpressionSocketSystemName; 128 } 129 130 public void setStringExpressionSocketSystemName(String systemName) { 131 _urlExpressionSocketSystemName = systemName; 132 } 133 134 /** {@inheritDoc} */ 135 @Override 136 public void setup() { 137 try { 138 if (!_urlExpressionSocket.isConnected() 139 || !_urlExpressionSocket.getConnectedSocket().getSystemName() 140 .equals(_urlExpressionSocketSystemName)) { 141 142 String socketSystemName = _urlExpressionSocketSystemName; 143 144 _urlExpressionSocket.disconnect(); 145 146 if (socketSystemName != null) { 147 MaleSocket maleSocket = 148 InstanceManager.getDefault(StringExpressionManager.class) 149 .getBySystemName(socketSystemName); 150 if (maleSocket != null) { 151 _urlExpressionSocket.connect(maleSocket); 152 maleSocket.setup(); 153 } else { 154 log.error("cannot load string expression {}", socketSystemName); 155 } 156 } 157 } else { 158 _urlExpressionSocket.getConnectedSocket().setup(); 159 } 160 } catch (SocketAlreadyConnectedException ex) { 161 // This shouldn't happen and is a runtime error if it does. 162 throw new RuntimeException("socket is already connected"); 163 } 164 } 165 166 /** {@inheritDoc} */ 167 @Override 168 public void registerListenersForThisClass() { 169 } 170 171 /** {@inheritDoc} */ 172 @Override 173 public void unregisterListenersForThisClass() { 174 } 175 176 /** {@inheritDoc} */ 177 @Override 178 public void disposeMe() { 179 } 180 181 private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(WebBrowser.class); 182 183}