001package Torello.Browser;
002
003import static Torello.Java.C.BYELLOW;
004import static Torello.Java.C.RESET;
005
006import Torello.Java.JSON.ReadJSON;
007import Torello.JavaDoc.LinkJavaSource;
008import Torello.Browser.BrowserEvent;
009import Torello.Browser.WebSocketSender;
010import NeoVisionaries.WebSockets.WebSocketException;
011
012import java.util.stream.Stream;
013import java.io.IOException;
014import java.util.Objects;
015import java.util.function.Consumer;
016import java.util.Objects;
017import javax.json.JsonObject;
018
019
020// @AutoFindFieldDocs(location="BRDPC/PageConn/fields/")
021/**
022 * A Connection to a specific page within a browser.
023 * <EMBED CLASS='external-html' DATA-FILE-ID=PAGE_CONN>
024 */
025@Torello.JavaDoc.CSSLinks(FileNames="BrowserAndPageConn.css")
026public class PageConn
027{
028    // ********************************************************************************************
029    // ********************************************************************************************
030    // Public Fields
031    // ********************************************************************************************
032    // ********************************************************************************************
033
034
035    /** <EMBED CLASS='external-html' DATA-FILE-ID=PC_ID> */
036    public final String id;
037
038    /** <EMBED CLASS='external-html' DATA-FILE-ID=PC_TYPE> */
039    public final String type;
040
041    /** <EMBED CLASS='external-html' DATA-FILE-ID=PC_TITLE> */
042    public final String title;
043
044    /** <EMBED CLASS='external-html' DATA-FILE-ID=PC_URL> */
045    public final String url;
046
047    /** <EMBED CLASS='external-html' DATA-FILE-ID=PC_DESCRIPTION> */
048    public final String description;
049
050    /** <EMBED CLASS='external-html' DATA-FILE-ID=PC_WS_DEBUG_URL> */
051    public final String webSocketDebuggerUrl;
052
053    /** <EMBED CLASS='external-html' DATA-FILE-ID=PC_DEVTOOLS_URL> */
054    public final String devtoolsFrontendUrl;
055
056    /** <EMBED CLASS='external-html' DATA-FILE-ID=PC_FAVICON_URL> */
057    public final String faviconUrl;
058
059
060    // ********************************************************************************************
061    // ********************************************************************************************
062    // Package Private Constructors
063    // ********************************************************************************************
064    // ********************************************************************************************
065
066
067    public PageConn(
068            final String id,
069            final String type,
070            final String title,
071            final String url,
072            final String description,
073            final String webSocketDebuggerUrl,
074            final String devtoolsFrontendUrl,
075            final String faviconUrl
076        )
077    {
078        Objects.requireNonNull(webSocketDebuggerUrl, "webSocketDebuggerUrl is null");
079
080        this.id                     = id;
081        this.type                   = type;
082        this.title                  = title;
083        this.url                    = url;
084        this.description            = description;
085        this.webSocketDebuggerUrl   = webSocketDebuggerUrl;
086        this.devtoolsFrontendUrl    = devtoolsFrontendUrl;
087        this.faviconUrl             = faviconUrl;
088    }
089
090    public PageConn(JsonObject jo)
091    {
092        // Boolean #1: 'isOptional'
093        //      FALSE   ==> throws if Missing
094        //      TRUE    ==> Assigns Null if Missing
095        // 
096        // Boolean #2: 'throwOnNull'
097        //      FALSE   ==> returns null if Json-Null has been passed
098        //      TRUE    ==> throws if Json-Null has been passed
099
100        this.id     = ReadJSON.getString(jo, "id",      false, true);
101        this.type   = ReadJSON.getString(jo, "type",    false, true);
102        this.title  = ReadJSON.getString(jo, "title",   true, false);
103        this.url    = ReadJSON.getString(jo, "url",     false, true);
104    
105        this.description =
106            ReadJSON.getString(jo, "description", true, false);
107    
108        this.webSocketDebuggerUrl =
109            ReadJSON.getString(jo, "webSocketDebuggerUrl", false, true);
110    
111        this.devtoolsFrontendUrl =
112            ReadJSON.getString(jo, "devtoolsFrontendUrl", true, false);
113    
114        this.faviconUrl =
115            ReadJSON.getString(jo, "faviconUrl", true, false);
116    }
117
118
119    // ********************************************************************************************
120    // ********************************************************************************************
121    // Builder Methods
122    // ********************************************************************************************
123    // ********************************************************************************************
124
125
126    /**
127     * Creates a {@link WebSocketSender} connected to the {@link #webSocketDebuggerUrl} for this
128     * tab.  This URL is the endpoint that speaks the Chrome DevTools Protocol (CDP).
129     * 
130     * @param eventHandler          <EMBED CLASS='external-html' DATA-FILE-ID=PCBC_EVENT_H>
131     * @param rdpErrorHandler       <EMBED CLASS='external-html' DATA-FILE-ID=PCBC_RDP_ERR_H>
132     * @param browserErrorHandler   <EMBED CLASS='external-html' DATA-FILE-ID=PCBC_BROWSER_ERR_H>
133     */
134    public WebSocketSender createSender(
135            final Consumer<BrowserEvent>    eventHandler,
136            final Consumer<RDPError>        rdpErrorHandler,
137            final Consumer<BrowserError>    browserErrorHandler
138        )
139        throws IOException, WebSocketException
140    {
141        return new WebSocketSender
142            (this.webSocketDebuggerUrl, eventHandler, rdpErrorHandler, browserErrorHandler);
143    }
144
145    /**
146     * Retrieves all pages from the CDP-RDP endpoint currently open on the named port.
147     * This queries {@code /json/list} and returns a Java-{@code Stream} of the instnces of this 
148     * class.
149     *
150     * @param port  The DevTools port Chrome is listening on (default is 9222 if {@code null}).
151     * @param quiet If {@code TRUE}, output is shunted.
152     * @return A list of all Open-Pages, as instances of {@code PageConn}
153     */
154    @LinkJavaSource(handle="PCBuilder")
155    public static Stream<PageConn> getAllPageConn(Integer port, final boolean quiet)
156    { return PCBuilder.getAllPageConn(port, quiet); }
157
158
159    // ********************************************************************************************
160    // ********************************************************************************************
161    // java.lang.Object Methods
162    // ********************************************************************************************
163    // ********************************************************************************************
164
165
166    @LinkJavaSource(handle="PCHelper", name="toString")
167    public String toString() { return PCHelper.toString(this); }
168
169    @LinkJavaSource(handle="PCHelper", name="hashCode")
170    public int hashCode() { return PCHelper.hashCode(this); }
171
172    @LinkJavaSource(handle="PCHelper", name="equals")
173    public boolean equals(Object o) { return PCHelper.equals(this, o); }
174
175    @LinkJavaSource(handle="PCHelper", name="clone")
176    public PageConn clone() { return PCHelper.clone(this); }
177}
178