17
17
package io .appium .java_client .remote ;
18
18
19
19
import static com .google .common .base .Preconditions .checkNotNull ;
20
- import static com .google .common .base .Throwables .getRootCause ;
21
20
import static com .google .common .base .Throwables .throwIfUnchecked ;
22
- import static org .openqa .selenium .remote .DriverCommand .GET_ALL_SESSIONS ;
23
- import static org .openqa .selenium .remote .DriverCommand .NEW_SESSION ;
24
- import static org .openqa .selenium .remote .DriverCommand .QUIT ;
25
-
26
- import io .appium .java_client .AppiumCommandInfo ;
27
- import org .openqa .selenium .NoSuchSessionException ;
28
- import org .openqa .selenium .SessionNotCreatedException ;
29
- import org .openqa .selenium .UnsupportedCommandException ;
21
+ import static java .util .Optional .ofNullable ;
22
+
23
+ import com .google .common .base .Supplier ;
24
+ import com .google .common .base .Throwables ;
25
+
30
26
import org .openqa .selenium .WebDriverException ;
31
27
import org .openqa .selenium .remote .Command ;
32
- import org .openqa .selenium .remote .CommandCodec ;
33
- import org .openqa .selenium .remote .CommandExecutor ;
34
- import org .openqa .selenium .remote .Dialect ;
28
+ import org .openqa .selenium .remote .CommandInfo ;
35
29
import org .openqa .selenium .remote .DriverCommand ;
36
- import org .openqa .selenium .remote .HttpSessionId ;
30
+ import org .openqa .selenium .remote .HttpCommandExecutor ;
37
31
import org .openqa .selenium .remote .Response ;
38
- import org .openqa .selenium .remote .ResponseCodec ;
39
32
import org .openqa .selenium .remote .http .HttpClient ;
40
- import org .openqa .selenium .remote .http .HttpRequest ;
41
- import org .openqa .selenium .remote .http .HttpResponse ;
42
33
import org .openqa .selenium .remote .internal .ApacheHttpClient ;
43
34
import org .openqa .selenium .remote .service .DriverService ;
44
35
45
36
import java .io .IOException ;
46
37
import java .net .ConnectException ;
47
38
import java .net .URL ;
48
39
import java .util .Map ;
40
+ import java .util .Optional ;
49
41
50
- public class AppiumCommandExecutor implements CommandExecutor {
51
-
52
- private final URL remoteServer ;
53
- private final HttpClient client ;
54
- private final Map <String , AppiumCommandInfo > additionalCommands ;
55
- private CommandCodec <HttpRequest > commandCodec ;
56
- private ResponseCodec <HttpResponse > responseCodec ;
57
- private DriverService service ;
58
-
59
- /**
60
- * Cretes an instance that sends requests and receives responses.
61
- *
62
- * @param additionalCommands is the mapped command repository
63
- * @param addressOfRemoteServer is the url to connect to the Appium remote/local server
64
- * @param httpClientFactory is the http client factory
65
- */
66
- public AppiumCommandExecutor (Map <String , AppiumCommandInfo > additionalCommands ,
67
- URL addressOfRemoteServer , HttpClient .Factory httpClientFactory ) {
68
- checkNotNull (addressOfRemoteServer );
69
- remoteServer = addressOfRemoteServer ;
70
- this .additionalCommands = additionalCommands ;
71
- this .client = httpClientFactory .createClient (remoteServer );
72
- }
42
+ public class AppiumCommandExecutor extends HttpCommandExecutor {
73
43
74
- public AppiumCommandExecutor (Map <String , AppiumCommandInfo > additionalCommands , DriverService service ,
75
- HttpClient .Factory httpClientFactory ) {
76
- this (additionalCommands , service .getUrl (), httpClientFactory );
77
- this .service = service ;
78
- }
44
+ private final Optional <DriverService > serviceOptional ;
79
45
80
- public AppiumCommandExecutor (Map <String , AppiumCommandInfo > additionalCommands ,
81
- URL addressOfRemoteServer ) {
82
- this (additionalCommands , addressOfRemoteServer , new ApacheHttpClient .Factory ());
46
+ private AppiumCommandExecutor (Map <String , CommandInfo > additionalCommands , DriverService service ,
47
+ URL addressOfRemoteServer ,
48
+ HttpClient .Factory httpClientFactory ) {
49
+ super (additionalCommands ,
50
+ ofNullable (service )
51
+ .map (DriverService ::getUrl )
52
+ .orElse (addressOfRemoteServer ), httpClientFactory );
53
+ serviceOptional = ofNullable (service );
83
54
}
84
55
85
- public AppiumCommandExecutor (Map <String , AppiumCommandInfo > additionalCommands ,
86
- DriverService service ) {
87
- this (additionalCommands , service , new ApacheHttpClient . Factory () );
56
+ public AppiumCommandExecutor (Map <String , CommandInfo > additionalCommands , DriverService service ,
57
+ HttpClient . Factory httpClientFactory ) {
58
+ this (additionalCommands , checkNotNull ( service ), null , httpClientFactory );
88
59
}
89
60
90
- public URL getAddressOfRemoteServer () {
91
- return remoteServer ;
61
+ public AppiumCommandExecutor (Map <String , CommandInfo > additionalCommands ,
62
+ URL addressOfRemoteServer , HttpClient .Factory httpClientFactory ) {
63
+ this (additionalCommands , null , checkNotNull (addressOfRemoteServer ), httpClientFactory );
92
64
}
93
65
94
- private Response doExecute (Command command ) throws IOException , WebDriverException {
95
- if (command .getSessionId () == null ) {
96
- if (QUIT .equals (command .getName ())) {
97
- return new Response ();
98
- }
99
- if (!GET_ALL_SESSIONS .equals (command .getName ())
100
- && !NEW_SESSION .equals (command .getName ())) {
101
- throw new NoSuchSessionException (
102
- "Session ID is null. Using WebDriver after calling quit()?" );
103
- }
104
- }
105
-
106
- if (NEW_SESSION .equals (command .getName ())) {
107
- if (commandCodec != null ) {
108
- throw new SessionNotCreatedException ("Session already exists" );
109
- }
110
- AppiumProtocolHandShake handshake = new AppiumProtocolHandShake ();
111
- AppiumProtocolHandShake .Result result = handshake .createSession (client , command );
112
- Dialect dialect = result .getDialect ();
113
- commandCodec = dialect .getCommandCodec ();
114
-
115
- additionalCommands .forEach ((key , value ) -> {
116
- checkNotNull (key );
117
- checkNotNull (value );
118
- commandCodec .defineCommand (key , value .getMethod (), value .getUrl ());
119
- } );
120
-
121
- responseCodec = dialect .getResponseCodec ();
122
- return result .createResponse ();
123
- }
124
66
125
- if ( commandCodec == null || responseCodec == null ) {
126
- throw new WebDriverException (
127
- "No command or response codec has been defined. Unable to proceed" );
128
- }
67
+ public AppiumCommandExecutor ( Map < String , CommandInfo > additionalCommands ,
68
+ URL addressOfRemoteServer ) {
69
+ this ( additionalCommands , addressOfRemoteServer , new ApacheHttpClient . Factory () );
70
+ }
129
71
130
- HttpRequest httpRequest = commandCodec .encode (command );
131
- try {
132
- HttpResponse httpResponse = client .execute (httpRequest , true );
133
-
134
- Response response = responseCodec .decode (httpResponse );
135
- if (response .getSessionId () == null ) {
136
- if (httpResponse .getTargetHost () != null ) {
137
- response .setSessionId (HttpSessionId .getSessionId (httpResponse .getTargetHost ()));
138
- } else {
139
- response .setSessionId (command .getSessionId ().toString ());
140
- }
141
- }
142
- if (QUIT .equals (command .getName ())) {
143
- client .close ();
144
- }
145
- return response ;
146
- } catch (UnsupportedCommandException e ) {
147
- if (e .getMessage () == null || "" .equals (e .getMessage ())) {
148
- throw new UnsupportedOperationException (
149
- "No information from server. Command name was: " + command .getName (),
150
- e .getCause ());
151
- }
152
- throw e ;
153
- }
72
+ public AppiumCommandExecutor (Map <String , CommandInfo > additionalCommands ,
73
+ DriverService service ) {
74
+ this (additionalCommands , service , new ApacheHttpClient .Factory ());
154
75
}
155
76
156
- @ Override public Response execute (Command command ) throws IOException , WebDriverException {
157
- if (DriverCommand .NEW_SESSION .equals (command .getName ()) && service != null ) {
158
- service .start ();
77
+ @ Override public Response execute (Command command ) throws WebDriverException {
78
+ if (DriverCommand .NEW_SESSION .equals (command .getName ())) {
79
+ serviceOptional .ifPresent (driverService -> {
80
+ try {
81
+ driverService .start ();
82
+ } catch (IOException e ) {
83
+ throw new WebDriverException (e .getMessage (), e );
84
+ }
85
+ });
159
86
}
160
87
161
88
try {
162
- return doExecute (command );
89
+ return super . execute (command );
163
90
} catch (Throwable t ) {
164
- Throwable rootCause = getRootCause (t );
91
+ Throwable rootCause = Throwables . getRootCause (t );
165
92
if (rootCause instanceof ConnectException
166
- && rootCause .getMessage ().contains ("Connection refused" )
167
- && service != null ) {
168
- if (service .isRunning ()) {
169
- throw new WebDriverException ("The session is closed!" , t );
170
- }
171
-
172
- if (! service . isRunning ()) {
173
- throw new WebDriverException ( "The appium server has accidentally died!" , t );
174
- }
93
+ && rootCause .getMessage ().contains ("Connection refused" )) {
94
+ throw serviceOptional . map ( service -> {
95
+ if (service .isRunning ()) {
96
+ return new WebDriverException ("The session is closed!" , rootCause );
97
+ }
98
+
99
+ return new WebDriverException ( "The appium server has accidentally died!" , rootCause );
100
+ }). orElseGet (( Supplier < WebDriverException >) () ->
101
+ new WebDriverException ( rootCause . getMessage (), rootCause ));
175
102
}
176
103
throwIfUnchecked (t );
177
104
throw new WebDriverException (t );
178
105
} finally {
179
- if (DriverCommand .QUIT .equals (command .getName ()) && service != null ) {
180
- service . stop ( );
106
+ if (DriverCommand .QUIT .equals (command .getName ())) {
107
+ serviceOptional . ifPresent ( DriverService :: stop );
181
108
}
182
109
}
183
110
}
184
-
185
- }
111
+ }
0 commit comments