001package Torello.Browser; 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.Java.Additional.*; 013import Torello.Java.JSON.*; 014 015import static Torello.Java.JSON.JFlag.*; 016 017import Torello.Java.StrCmpr; 018import Torello.JavaDoc.StaticFunctional; 019import Torello.JavaDoc.JDHeaderBackgroundImg; 020import Torello.JavaDoc.Excuse; 021 022/** 023 * <SPAN CLASS=COPIEDJDK><B>The Tethering domain defines methods and events for browser port binding.</B></SPAN> 024 * 025 * <EMBED CLASS='external-html' DATA-FILE-ID=CODE_GEN_NOTE> 026 */ 027@StaticFunctional(Excused={"counter"}, Excuses={Excuse.CONFIGURATION}) 028@JDHeaderBackgroundImg(EmbedTagFileID="WOOD_PLANK_NOTE") 029public class Tethering 030{ 031 // ******************************************************************************************** 032 // ******************************************************************************************** 033 // Class Header Stuff 034 // ******************************************************************************************** 035 // ******************************************************************************************** 036 037 038 // No Pubic Constructors 039 private Tethering () { } 040 041 // These two Vector's are used by all the "Methods" exported by this class. java.lang.reflect 042 // is used to generate the JSON String's. It saves thousands of lines of Auto-Generated Code. 043 private static final Map<String, Vector<String>> parameterNames = new HashMap<>(); 044 private static final Map<String, Vector<Class<?>>> parameterTypes = new HashMap<>(); 045 046 // Some Methods do not take any parameters - for instance all the "enable()" and "disable()" 047 // I simply could not get ride of RAW-TYPES and UNCHECKED warnings... so there are now, 048 // offically, two empty-vectors. One for String's, and the other for Classes. 049 050 private static final Vector<String> EMPTY_VEC_STR = new Vector<>(); 051 private static final Vector<Class<?>> EMPTY_VEC_CLASS = new Vector<>(); 052 053 static 054 { 055 for (Method m : Tethering.class.getMethods()) 056 { 057 // This doesn't work! The parameter names are all "arg0" ... "argN" 058 // It works for java.lang.reflect.Field, BUT NOT java.lang.reflect.Parameter! 059 // 060 // Vector<String> parameterNamesList = new Vector<>(); -- NOPE! 061 062 Vector<Class<?>> parameterTypesList = new Vector<>(); 063 064 for (Parameter p : m.getParameters()) parameterTypesList.add(p.getType()); 065 066 parameterTypes.put( 067 m.getName(), 068 (parameterTypesList.size() > 0) ? parameterTypesList : EMPTY_VEC_CLASS 069 ); 070 } 071 } 072 073 static 074 { 075 Vector<String> v = null; 076 077 v = new Vector<String>(1); 078 parameterNames.put("bind", v); 079 Collections.addAll(v, new String[] 080 { "port", }); 081 082 v = new Vector<String>(1); 083 parameterNames.put("unbind", v); 084 Collections.addAll(v, new String[] 085 { "port", }); 086 } 087 088 089 // ******************************************************************************************** 090 // ******************************************************************************************** 091 // Types - Static Inner Classes 092 // ******************************************************************************************** 093 // ******************************************************************************************** 094 095 /** Informs that port was successfully bound and got a specified connection id. */ 096 public static class accepted 097 extends BrowserEvent 098 implements java.io.Serializable 099 { 100 /** For Object Serialization. java.io.Serializable */ 101 protected static final long serialVersionUID = 1; 102 103 public boolean[] optionals() 104 { return new boolean[] { false, false, }; } 105 106 /** Port number that was successfully bound. */ 107 public final int port; 108 109 /** Connection id to be used. */ 110 public final String connectionId; 111 112 /** 113 * Constructor 114 * 115 * @param port Port number that was successfully bound. 116 * 117 * @param connectionId Connection id to be used. 118 */ 119 public accepted(int port, String connectionId) 120 { 121 super("Tethering", "accepted", 2); 122 123 // Exception-Check(s) to ensure that if any parameters which are not declared as 124 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 125 126 if (connectionId == null) BRDPC.throwNPE("connectionId"); 127 128 this.port = port; 129 this.connectionId = connectionId; 130 } 131 132 /** 133 * JSON Object Constructor 134 * @param jo A Json-Object having data about an instance of {@code 'accepted'}. 135 */ 136 public accepted (JsonObject jo) 137 { 138 super("Tethering", "accepted", 2); 139 140 this.port = ReadPrimJSON.getInt(jo, "port"); 141 this.connectionId = ReadJSON.getString(jo, "connectionId", false, true); 142 } 143 144 145 /** Checks whether {@code 'this'} equals an input Java-{@code Object} */ 146 public boolean equals(Object other) 147 { 148 if (other == null) return false; 149 if (other.getClass() != this.getClass()) return false; 150 151 accepted o = (accepted) other; 152 153 return 154 (this.port == o.port) 155 && Objects.equals(this.connectionId, o.connectionId); 156 } 157 158 /** Generates a Hash-Code for {@code 'this'} instance */ 159 public int hashCode() 160 { 161 return 162 this.port 163 + Objects.hashCode(this.connectionId); 164 } 165 } 166 167 168 // Counter for keeping the WebSocket Request ID's distinct. 169 private static int counter = 1; 170 171 /** 172 * Request browser port binding. 173 * 174 * @param port Port number to bind. 175 * 176 * @return An instance of <CODE>{@link Script}<String, {@link JsonObject}, 177 * {@link Ret0}></CODE> 178 * 179 * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the 180 * browser receives the invocation-request. 181 * 182 * <BR /><BR />This Browser-Function <I>does not have</I> a return-value. You may choose to 183 * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0} 184 * {@code >} to ensure the Browser Function has run to completion. 185 */ 186 public static Script<String, JsonObject, Ret0> bind(int port) 187 { 188 final int webSocketID = 40000000 + counter++; 189 final boolean[] optionals = { false, }; 190 191 // Convert Method Parameters into JSON. Build the JSON Request-Object (as a String) 192 String requestJSON = WriteJSON.get( 193 parameterTypes.get("bind"), 194 parameterNames.get("bind"), 195 optionals, webSocketID, 196 "Tethering.bind", 197 port 198 ); 199 200 // This Remote Command does not have a Return-Value. 201 return new Script<> 202 (BRDPC.defaultSender, webSocketID, requestJSON, BRDPC.NoReturnValues); 203 } 204 205 /** 206 * Request browser port unbinding. 207 * 208 * @param port Port number to unbind. 209 * 210 * @return An instance of <CODE>{@link Script}<String, {@link JsonObject}, 211 * {@link Ret0}></CODE> 212 * 213 * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the 214 * browser receives the invocation-request. 215 * 216 * <BR /><BR />This Browser-Function <I>does not have</I> a return-value. You may choose to 217 * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0} 218 * {@code >} to ensure the Browser Function has run to completion. 219 */ 220 public static Script<String, JsonObject, Ret0> unbind(int port) 221 { 222 final int webSocketID = 40001000 + counter++; 223 final boolean[] optionals = { false, }; 224 225 // Convert Method Parameters into JSON. Build the JSON Request-Object (as a String) 226 String requestJSON = WriteJSON.get( 227 parameterTypes.get("unbind"), 228 parameterNames.get("unbind"), 229 optionals, webSocketID, 230 "Tethering.unbind", 231 port 232 ); 233 234 // This Remote Command does not have a Return-Value. 235 return new Script<> 236 (BRDPC.defaultSender, webSocketID, requestJSON, BRDPC.NoReturnValues); 237 } 238 239}