001package Torello.Browser.BrowserAPI;
002
003import java.util.*;
004import javax.json.*;
005import javax.json.stream.*;
006import java.io.*;
007
008import java.lang.reflect.Method;
009import java.lang.reflect.Parameter;
010import java.util.function.Function;
011
012import Torello.Browser.BrowserEvent;
013import Torello.Browser.JavaScriptAPI.*;
014import Torello.Browser.helper.*;
015
016import Torello.Java.Additional.*;
017import Torello.Java.JSON.*;
018
019import static Torello.Java.JSON.JFlag.*;
020
021import Torello.Java.StrCmpr;
022import Torello.JavaDoc.StaticFunctional;
023import Torello.JavaDoc.JDHeaderBackgroundImg;
024import Torello.JavaDoc.Excuse;
025
026/**
027 * <SPAN CLASS=COPIEDJDK><B>EventBreakpoints permits setting JavaScript breakpoints on operations and events
028 * occurring in native code invoked from JavaScript. Once breakpoint is hit, it is
029 * reported through Debugger domain, similarly to regular breakpoints being hit.</B></SPAN>
030 * 
031 * <EMBED CLASS='external-html' DATA-FILE-ID=CODE_GEN_NOTE>
032 */
033@StaticFunctional(Excused={"counter"}, Excuses={Excuse.CONFIGURATION})
034@JDHeaderBackgroundImg(EmbedTagFileID="WOOD_PLANK_NOTE")
035public class EventBreakpoints
036{
037    // ********************************************************************************************
038    // ********************************************************************************************
039    // Class Header Stuff
040    // ********************************************************************************************
041    // ********************************************************************************************
042
043
044    // No Pubic Constructors
045    private EventBreakpoints () { }
046
047    // These two Vector's are used by all the "Methods" exported by this class.  java.lang.reflect
048    // is used to generate the JSON String's.  It saves thousands of lines of Auto-Generated Code.
049    private static final Map<String, Vector<String>>    parameterNames = new HashMap<>();
050    private static final Map<String, Vector<Class<?>>>  parameterTypes = new HashMap<>();
051
052    // Some Methods do not take any parameters - for instance all the "enable()" and "disable()"
053    // I simply could not get ride of RAW-TYPES and UNCHECKED warnings... so there are now,
054    // offically, two empty-vectors.  One for String's, and the other for Classes.
055
056    private static final Vector<String>     EMPTY_VEC_STR = new Vector<>();
057    private static final Vector<Class<?>>   EMPTY_VEC_CLASS = new Vector<>();
058
059    static
060    {
061        for (Method m : EventBreakpoints.class.getMethods())
062        {
063            // This doesn't work!  The parameter names are all "arg0" ... "argN"
064            // It works for java.lang.reflect.Field, BUT NOT java.lang.reflect.Parameter!
065            //
066            // Vector<String> parameterNamesList = new Vector<>(); -- NOPE!
067
068            Vector<Class<?>> parameterTypesList = new Vector<>();
069        
070            for (Parameter p : m.getParameters()) parameterTypesList.add(p.getType());
071
072            parameterTypes.put(
073                m.getName(),
074                (parameterTypesList.size() > 0) ? parameterTypesList : EMPTY_VEC_CLASS
075            );
076        }
077    }
078
079    static
080    {
081        Vector<String> v = null;
082
083        v = new Vector<String>(1);
084        parameterNames.put("setInstrumentationBreakpoint", v);
085        Collections.addAll(v, new String[]
086        { "eventName", });
087
088        v = new Vector<String>(1);
089        parameterNames.put("removeInstrumentationBreakpoint", v);
090        Collections.addAll(v, new String[]
091        { "eventName", });
092
093        parameterNames.put("disable", EMPTY_VEC_STR);
094    }
095
096
097    // ********************************************************************************************
098    // ********************************************************************************************
099    // Types - Static Inner Classes
100    // ********************************************************************************************
101    // ********************************************************************************************
102
103    
104    // Counter for keeping the WebSocket Request ID's distinct.
105    private static int counter = 1;
106    
107    /**
108     * Sets breakpoint on particular native event.
109     * 
110     * @param eventName Instrumentation name to stop on.
111     * 
112     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
113     * {@link Ret0}&gt;</CODE>
114     *
115     * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the
116     * browser receives the invocation-request.
117     *
118     * <BR /><BR />This Browser-Function <I>does not have</I> a return-value.  You may choose to
119     * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0}
120     * {@code >} to ensure the Browser Function has run to completion.
121     */
122    public static Script<String, JsonObject, Ret0> setInstrumentationBreakpoint
123        (String eventName)
124    {
125        // Exception-Check(s) to ensure that if any parameters which are not declared as
126        // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
127        
128        if (eventName == null) THROWS.throwNPE("eventName");
129        
130        final int       webSocketID = 19000000 + counter++;
131        final boolean[] optionals   = { false, };
132        
133        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
134        String requestJSON = WriteJSON.get(
135            parameterTypes.get("setInstrumentationBreakpoint"),
136            parameterNames.get("setInstrumentationBreakpoint"),
137            optionals, webSocketID,
138            "EventBreakpoints.setInstrumentationBreakpoint",
139            eventName
140        );
141        
142        // This Remote Command does not have a Return-Value.
143        return new Script<>
144            (webSocketID, requestJSON, VOID_RETURN.NoReturnValues);
145    }
146    
147    /**
148     * Removes breakpoint on particular native event.
149     * 
150     * @param eventName Instrumentation name to stop on.
151     * 
152     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
153     * {@link Ret0}&gt;</CODE>
154     *
155     * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the
156     * browser receives the invocation-request.
157     *
158     * <BR /><BR />This Browser-Function <I>does not have</I> a return-value.  You may choose to
159     * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0}
160     * {@code >} to ensure the Browser Function has run to completion.
161     */
162    public static Script<String, JsonObject, Ret0> removeInstrumentationBreakpoint
163        (String eventName)
164    {
165        // Exception-Check(s) to ensure that if any parameters which are not declared as
166        // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
167        
168        if (eventName == null) THROWS.throwNPE("eventName");
169        
170        final int       webSocketID = 19001000 + counter++;
171        final boolean[] optionals   = { false, };
172        
173        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
174        String requestJSON = WriteJSON.get(
175            parameterTypes.get("removeInstrumentationBreakpoint"),
176            parameterNames.get("removeInstrumentationBreakpoint"),
177            optionals, webSocketID,
178            "EventBreakpoints.removeInstrumentationBreakpoint",
179            eventName
180        );
181        
182        // This Remote Command does not have a Return-Value.
183        return new Script<>
184            (webSocketID, requestJSON, VOID_RETURN.NoReturnValues);
185    }
186    
187    /**
188     * Removes all breakpoints
189     * 
190     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
191     * {@link Ret0}&gt;</CODE>
192     *
193     * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the
194     * browser receives the invocation-request.
195     *
196     * <BR /><BR />This Browser-Function <I>does not have</I> a return-value.  You may choose to
197     * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0}
198     * {@code >} to ensure the Browser Function has run to completion.
199     */
200    public static Script<String, JsonObject, Ret0> disable()
201    {
202        final int          webSocketID = 19002000 + counter++;
203        final boolean[]    optionals   = new boolean[0];
204        
205        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
206        String requestJSON = WriteJSON.get(
207            parameterTypes.get("disable"),
208            parameterNames.get("disable"),
209            optionals, webSocketID,
210            "EventBreakpoints.disable"
211        );
212        
213        // This Remote Command does not have a Return-Value.
214        return new Script<>
215            (webSocketID, requestJSON, VOID_RETURN.NoReturnValues);
216    }
217    
218}