1717package  io .appium .java_client .remote ;
1818
1919import  static  com .google .common .base .Preconditions .checkNotNull ;
20- import  static  com .google .common .base .Throwables .getRootCause ;
2120import  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+ 
3026import  org .openqa .selenium .WebDriverException ;
3127import  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 ;
3529import  org .openqa .selenium .remote .DriverCommand ;
36- import  org .openqa .selenium .remote .HttpSessionId ;
30+ import  org .openqa .selenium .remote .HttpCommandExecutor ;
3731import  org .openqa .selenium .remote .Response ;
38- import  org .openqa .selenium .remote .ResponseCodec ;
3932import  org .openqa .selenium .remote .http .HttpClient ;
40- import  org .openqa .selenium .remote .http .HttpRequest ;
41- import  org .openqa .selenium .remote .http .HttpResponse ;
4233import  org .openqa .selenium .remote .internal .ApacheHttpClient ;
4334import  org .openqa .selenium .remote .service .DriverService ;
4435
4536import  java .io .IOException ;
4637import  java .net .ConnectException ;
4738import  java .net .URL ;
4839import  java .util .Map ;
40+ import  java .util .Optional ;
4941
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  {
7343
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 ;
7945
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 );
8354    }
8455
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 );
8859    }
8960
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 );
9264    }
9365
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-         }
12466
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+     }
12971
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 ());
15475    }
15576
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+             });
15986        }
16087
16188        try  {
162-             return  doExecute (command );
89+             return  super . execute (command );
16390        } catch  (Throwable  t ) {
164-             Throwable  rootCause  = getRootCause (t );
91+             Throwable  rootCause  = Throwables . getRootCause (t );
16592            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 )); 
175102            }
176103            throwIfUnchecked (t );
177104            throw  new  WebDriverException (t );
178105        } 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 );
181108            }
182109        }
183110    }
184- 
185- }
111+ }
0 commit comments