001package Torello.Browser; 002 003import static Torello.Java.C.BYELLOW; 004import static Torello.Java.C.RESET; 005 006import Torello.JSON.ReadJSON; 007import Torello.JavaDoc.Annotations.LinkJavaSource; 008import NeoVisionaries.WebSockets.WebSocketException; 009 010import java.util.Objects; 011import java.io.IOException; 012import javax.json.JsonObject; 013 014 015/** 016 * A Connection to a Browser, rather than an individual Page within the Browser. 017 * 018 * <BR /><BR /> 019 * Represents a snapshot of metadata returned from Chrome’s 020 * <B STYLE='color:red;'>{@code /json/version}</B> End-Point. This 021 * includes protocol versioning, V8 details, and the root 022 * {@link NeoVisionaries.WebSockets.WebSocket WebSocket} {@code URL} for establishing DevTools 023 * sessions. 024 * 025 * <BR /><BR /> 026 * Although this class offers a public constructor, the recommended way to build an instance is via 027 * the {@code static} method: <B>{@link #getBrowserConn getBrowserConn}</B>. This instance 028 * contains a few informational fields that were scraped from the Json-Response to the above 029 * mentioned Chrome response object. 030 * 031 * <BR /><BR /><B CLASS=JDDescLabel2>A {@link WebSocketSender} Instance:</B> 032 * 033 * <BR /> 034 * To begin sending CDP commands, it is mandatory to obtain an instance of the 035 * <B>{@link WebSocketSender}</B> class which has been connected to a Web Browser. This instance 036 * should be passed as the sender to any of the available API methods offered by the Domain Classes 037 * in the packages 038 * <B><CODE><A HREF='BrowserAPI/package-summary.html'>BrowserAPI</A></CODE></B> 039 * and or the classes in 040 * <B><CODE><A HREF='JavaScriptAPI/package-summary.html'>JavaScriptAPI</A></CODE></B>. 041 * You should review the methods exported by each of the domains and classes within those packages, 042 * and note that the <B>{@link Script}</B> objects returned by them expose an 043 * <B>{@link Script#exec(WebSocketSender)}</B> method. 044 * 045 * <BR /><BR /> 046 * Obtaining the <B>{@link WebSocketSender}</B> instance can be achieved by invoking 047 * <B>{@link BrowserConn#createSender(ConnRecord) BrowserConn.createSender}</B>, 048 * a method offered by this class. This method initializes a <B>{@link WebSocketSender}</B> which 049 * is connected to the associated <B>{@link #webSocketDebuggerUrl}</B>. That sender can be used to 050 * make invocations into all CDP Domains. 051 * 052 * <BR /><BR /> 053 * The individual fields exported by this class are documented below, and within their respective 054 * documentation. This class, itself, is largely a structured data holder with minimal logic. 055 * Mostly, it parses the Json which is returned by the Web-Browser endpoint 056 * <B STYLE='color:red;'>{@code /json/version}</B>. 057 * 058 * <EMBED CLASS='external-html' DATA-FILE-ID=PCBC_CHECKLIST> 059 */ 060@Torello.JavaDoc.Annotations.CSSLinks(FileNames="BrowserAndPageConn.css") 061public class BrowserConn implements java.io.Serializable, Comparable<BrowserConn>, Cloneable 062{ 063 /** <EMBED CLASS=external-html DATA-FILE-ID=SVUID> */ 064 protected static final long serialVersionUID = 1; 065 066 067 // ******************************************************************************************** 068 // ******************************************************************************************** 069 // PUBLIC FIELDS 070 // ******************************************************************************************** 071 // ******************************************************************************************** 072 073 074 /** <EMBED CLASS='external-html' DATA-FILE-ID=BC_BROWSER> */ 075 public final String browser; 076 077 /** <EMBED CLASS='external-html' DATA-FILE-ID=BC_PROT_VER> */ 078 public final String protocolVersion; 079 080 /** <EMBED CLASS='external-html' DATA-FILE-ID=BC_USER_AGENT> */ 081 public final String userAgent; 082 083 /** <EMBED CLASS='external-html' DATA-FILE-ID=BC_V8_VERSION> */ 084 public final String v8Version; 085 086 /** <EMBED CLASS='external-html' DATA-FILE-ID=BC_WEBKIT_VER> */ 087 public final String webkitVersion; 088 089 /** <EMBED CLASS='external-html' DATA-FILE-ID=BC_WS_DEBUG_URL> */ 090 public final String webSocketDebuggerUrl; 091 092 093 // ******************************************************************************************** 094 // ******************************************************************************************** 095 // Constructors 096 // ******************************************************************************************** 097 // ******************************************************************************************** 098 099 100 /** 101 * Constructs an instance of this type. 102 * @throws NullPointerException if {@code 'webSocketDebuggerUrl'} is passed null. 103 */ 104 public BrowserConn( 105 final String browser, 106 final String protocolVersion, 107 final String userAgent, 108 final String v8Version, 109 final String webkitVersion, 110 final String webSocketDebuggerUrl 111 ) 112 { 113 Objects.requireNonNull(webSocketDebuggerUrl, "webSocketDebuggerUrl is null"); 114 115 this.browser = browser; 116 this.protocolVersion = protocolVersion; 117 this.userAgent = userAgent; 118 this.v8Version = v8Version; 119 this.webkitVersion = webkitVersion; 120 this.webSocketDebuggerUrl = webSocketDebuggerUrl; 121 } 122 123 /** 124 * <EMBED CLASS='external-html' DATA-FILE-ID=PAGE_CONN> 125 * 126 * @param jo The exact {@link JsonObject} that was generated by querying the HTTP End-Point 127 * <B STYLE='color:red;'>{@code /json/version}</B>. 128 * 129 * @see ReadJSON#getString(JsonObject, String, boolean, boolean) 130 */ 131 public BrowserConn(final JsonObject jo) 132 { 133 this.browser = ReadJSON.getString(jo, "Browser", false, true); 134 this.protocolVersion = ReadJSON.getString(jo, "Protocol-Version", false, true); 135 this.userAgent = ReadJSON.getString(jo, "User-Agent", false, true); 136 this.v8Version = ReadJSON.getString(jo, "V8-Version", true, false); 137 this.webkitVersion = ReadJSON.getString(jo, "WebKit-Version", true, false); 138 139 this.webSocketDebuggerUrl = 140 ReadJSON.getString(jo, "webSocketDebuggerUrl", false, true); 141 } 142 143 144 // ******************************************************************************************** 145 // ******************************************************************************************** 146 // Build Methods 147 // ******************************************************************************************** 148 // ******************************************************************************************** 149 150 151 /** 152 * Creates a {@link WebSocketSender} connected to the {@link #webSocketDebuggerUrl} for this 153 * tab. This URL is the endpoint that speaks the Chrome DevTools Protocol (CDP). 154 * 155 * @param connRec Messaging settings for this connection 156 */ 157 public WebSocketSender createSender(final ConnRecord connRec) 158 throws IOException, WebSocketException 159 { return new WebSocketSender(this.webSocketDebuggerUrl, connRec); } 160 161 /** 162 * Retrieves the WebSocketDebugger URL for the main browser instance. 163 * This queries {@code /json/version} and parses the result into an instance. 164 * 165 * @param port The DevTools port Chrome is listening on (default is 9222 if {@code null}). 166 * @param quiet If {@code false}, debug output is printed to the console. 167 * @return A {@code BrowserConn} instance representing the browser-level connection. 168 */ 169 @LinkJavaSource(handle="BCBuilder") 170 public static BrowserConn getBrowserConn(Integer port, boolean quiet) 171 { return BCBuilder.getBrowserConn(port, quiet); } 172 173 174 // ******************************************************************************************** 175 // ******************************************************************************************** 176 // java.lang.Object Methods 177 // ******************************************************************************************** 178 // ******************************************************************************************** 179 180 181 @LinkJavaSource(handle="BCHelper", name="toString") 182 public String toString() { return BCHelper.toString(this); } 183 184 @LinkJavaSource(handle="BCHelper", name="hashCode") 185 public int hashCode() { return BCHelper.hashCode(this); } 186 187 @LinkJavaSource(handle="BCHelper", name="equals") 188 public boolean equals(Object o) { return BCHelper.equals(this, o); } 189 190 @LinkJavaSource(handle="BCHelper", name="clone") 191 public BrowserConn clone() { return BCHelper.clone(this); } 192 193 public int compareTo(BrowserConn other) 194 { return this.webSocketDebuggerUrl.compareTo(other.webSocketDebuggerUrl); } 195}