# ClientParameters.java

    /*
    ** Module   : ClientParameters.java
    ** Abstract : Container of various client-side parameters which need to be exposed to the server.
    **
    ** Copyright (c) 2013-2024, Golden Code Development Corporation.
    **
    ** -#- -I- --Date-- ----------------------------------Description---------------------------------
    ** 001 CA  20131004 Created initial version.
    ** 002 GES 20141228 Added some equivalents to 4GL command line options.
    ** 003 GES 20150108 Added OS userid, OS PID and terminal name.
    ** 004 IAS 20160328 Client log support.
    ** 005 OM  20160927 Added batchMode property.
    ** 006 IAS 20200908 Rework (de)serialization.
    ** 007 CA  20220208 Added -errorstack command-line option (client:cmd-line-option:error-stack).
    **     CA  20220918 Added socket trust store filename and password to the ClientParameters.
    ** 008 GBB 20230313 Adding client params logentrytypes, logginglevel, logthreshold and numlogfiles.
    ** 009 TT  20230328 Added the -T command-line option (client:cmd-line-option:temp-directory).
    ** 010 TT  20230808 Removed cmd-line-options.
    ** 011 GBB 20231121 Adding web and embedded. Adding driverClass, webPort, browserWebSocket.
    ** 012 TT  20231129 Added the propath client parameter.
    ** 013 GBB 20231130 driverClass replaced by driverName.
    ** 014 GBB 20240214 Added osDeviceId.
    ** 015 GBB 20240301 Added several browser-derived values.
    ** 016 HC  20240513 Moved SPREADSHEET backend (Keikai web application and the related FWD
    **                  integration) from client to server.
    ** 017 SBI 20240821 Added the webRoot serializable field.
    ** 018 GBB 20240826 Adding storageId.
    */
    /*
    ** This program is free software: you can redistribute it and/or modify
    ** it under the terms of the GNU Affero General Public License as
    ** published by the Free Software Foundation, either version 3 of the
    ** License, or (at your option) any later version.
    **
    ** This program is distributed in the hope that it will be useful,
    ** but WITHOUT ANY WARRANTY; without even the implied warranty of
    ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    ** GNU Affero General Public License for more details.
    **
    ** You may find a copy of the GNU Affero GPL version 3 at the following
    ** location: https://www.gnu.org/licenses/agpl-3.0.en.html
    **
    ** Additional terms under GNU Affero GPL version 3 section 7:
    **
    **   Under Section 7 of the GNU Affero GPL version 3, the following additional
    **   terms apply to the works covered under the License.  These additional terms
    **   are non-permissive additional terms allowed under Section 7 of the GNU
    **   Affero GPL version 3 and may not be removed by you.
    **
    **   0. Attribution Requirement.
    **
    **     You must preserve all legal notices or author attributions in the covered
    **     work or Appropriate Legal Notices displayed by works containing the covered
    **     work.  You may not remove from the covered work any author or developer
    **     credit already included within the covered work.
    **
    **   1. No License To Use Trademarks.
    **
    **     This license does not grant any license or rights to use the trademarks
    **     Golden Code, FWD, any Golden Code or FWD logo, or any other trademarks
    **     of Golden Code Development Corporation. You are not authorized to use the
    **     name Golden Code, FWD, or the names of any author or contributor, for
    **     publicity purposes without written authorization.
    **
    **   2. No Misrepresentation of Affiliation.
    **
    **     You may not represent yourself as Golden Code Development Corporation or FWD.
    **
    **     You may not represent yourself for publicity purposes as associated with
    **     Golden Code Development Corporation, FWD, or any author or contributor to
    **     the covered work, without written authorization.
    **
    **   3. No Misrepresentation of Source or Origin.
    **
    **     You may not represent the covered work as solely your work.  All modified
    **     versions of the covered work must be marked in a reasonable way to make it
    **     clear that the modified work is not originating from Golden Code Development
    **     Corporation or FWD.  All modified versions must contain the notices of
    **     attribution required in this license.
    */

    package com.goldencode.p2j.main;

    import java.io.*;

    import static com.goldencode.util.NativeTypeSerializer.*;

    /**
     * Container of client-side parameters which need to be exposed to the server-side application
     * code.
     * <p>
     * This can be used for values that are effectively constants (set or queried at the time the
     * client starts and then unchangable for the remainer of the client's lifetime). It is suitable
     * for values that correspond to:
     * <p>
     * <ul>
     *    <li> Read-only environmental state that is exposed by the 4GL (e.g.
     *         <code>SESSION:WINDOW-SYSTEM</code>).
     *    <li> 4GL command line option equivalents (e.g. <code>-param</code>).
     *    <li> Operating system PID and userid.
     * </ul>
     */
    public class ClientParameters
    implements Externalizable
    {
       /** Constant for the "TTY" window-system (CHUI driver default). */
       public static final String WINDOW_SYSTEM_TTY = "TTY";

       /** Constant for the "MS-WINDOWS" window-system (GUI driver default). */
       public static final String WINDOW_SYSTEM_MS_WINDOWS = "MS-WINDOWS";

       /** Constant identifying the "MS-WIN95" window-system. */
       public static final String WINDOW_SYSTEM_MS_WIN95 = "MS-WIN95";

       /** Constant identifying the "MS-WINXP" window-system. */
       public static final String WINDOW_SYSTEM_MS_WINXP = "MS-WINXP";

       /** Identify the SESSION:WINDOW-SYSTEM attribute used by this client. */
       public String windowSystem = null;

       /** User name as reported by the operating system. */
       public String osUserName = null;

       /** Terminal name as specified on the client command line. */
       public String terminalName = null;

       /** Process ID (PID) of the client process as reported by the operating system. */
       public long pid = -1;

       /** The client web server port. */
       public int webPort;

       /** Driver class name. */
       public String driverName;

       /** The device ID from the OS in the client process */
       public String osDeviceId;

       /** The storage ID for the end-user (available with SSO) */
       public String storageId;

       /** <code>true</code> if this client is ChUI, <code>false</code> for GUI. */
       public boolean chui = true;

       /** <code>true</code> if this client is web (embedded, gui, chui), <code>false</code> otherwise. */
       public boolean web = false;

       /** <code>true</code> if this client is web embedded, <code>false</code> otherwise. */
       public boolean embedded = false;

       /** <code>true</code> if this client is headless, <code>false</code> otherwise. */
       public boolean isHeadless = false;

       /** The batch mode. 0 = none, 1 = batch on, 2/3 = batch forced (client:mode:batch=true) */
       public int batchMode = 0;

       /**
        * Filename of client-side SSL certificate store. Default is {@code trusted-cert.store} from current
        * directory.
        */
       public String socketTrustStoreFilename = null;

       /** The password for access to client-side SSL certificate store. Default is blank. */
       public String socketTrustStorePassword = null;

       /** The propath parameter. */
       public String propath;

       /** The offset in minutes from UTC for the client timezone. */
       public Integer clientTimezone;

       /** The browser WebSocket address. */
       public String browserWebSocket;

       /** The offset in minutes from UTC for the browser timezone. Available with web sessions only. */
       public Integer browserTimezone;

       /**
        * The UTC timestamp of the capture time for {@link #browserWebSocket}.
        * Available with web sessions only.
        */
       public Long ipCaptureTimestamp;

       /**
        * The client screen color depth. Currently implemented only for web sessions and represents the value
        * accessible from the browser.
        */
       public Integer screenColorDepth;

       /**
        * The client screen height. Currently implemented only for web sessions and represents the value
        * accessible from the browser.
        */
       public Integer screenHeight;

       /**
        * The client screen scaling factor. Currently implemented only for web sessions and represents the
        * value accessible from the browser.
        */
       public Float screenScalingFactor;

       /**
        * The client screen width. Currently implemented only for web sessions and represents the value
        * accessible from the browser.
        */
       public Integer screenWidth;

       /** The user agent info of the browser where the js client runs. Available with web sessions only. */
       public String userAgent;

       /** The server base URL as given to spawn the web client. The URL may differ depending on
        *  how the client is spawned, it could be behind a proxy, direct, etc. */
       public String serverBaseUrl;

       /** The client web root path depending on how the client is spawned, it could be behind a proxy, direct, etc. */
       public String webRoot;
       /**
        * Replacement for the default object writing method. The latest state is written to the output
        * destination.
        *
        * @param    out
        *           The output destination to which parameters will be saved.
        *
        * @throws   IOException
        *           In case of I/O errors.
        */
       @Override
       public void writeExternal(ObjectOutput out)
       throws IOException
       {
          writeString(out, windowSystem);
          writeString(out, osUserName);
          writeString(out, terminalName);
          out.writeLong(pid);
          writeString(out, driverName);
          writeString(out, osDeviceId);
          writeString(out, storageId);
          out.writeBoolean(chui);
          out.writeBoolean(web);
          out.writeBoolean(embedded);
          out.writeBoolean(isHeadless);
          out.writeInt(batchMode);
          writeString(out, socketTrustStoreFilename);
          writeString(out, socketTrustStorePassword);
          out.writeInt(webPort);
          writeInteger(out, clientTimezone);
          writeString(out, browserWebSocket);
          writeString(out, propath);
          writeInteger(out, browserTimezone);
          writeLong(out, ipCaptureTimestamp);
          writeInteger(out, screenColorDepth);
          writeInteger(out, screenHeight);
          writeFloat(out, screenScalingFactor);
          writeInteger(out, screenWidth);
          writeString(out, userAgent);
          writeString(out, serverBaseUrl);
          writeString(out, webRoot);
       }

       /**
        * Replacement for the default object reading method. The latest state is read from the input
        * source.
        *
        * @param    in
        *           The input source from which parameters will be restored.
        *
        * @throws   IOException
        *           In case of I/O errors.
        * @throws   ClassNotFoundException
        *           If a parameter can't be instantiated.
        */
       @Override
       public void readExternal(ObjectInput in)
       throws IOException,
              ClassNotFoundException
       {
          windowSystem  = readString(in);
          osUserName    = readString(in);
          terminalName  = readString(in);
          pid           = in.readLong();
          driverName    = readString(in);
          osDeviceId    = readString(in);
          storageId     = readString(in);
          chui          = in.readBoolean();
          web           = in.readBoolean();
          embedded      = in.readBoolean();
          isHeadless    = in.readBoolean();
          batchMode     = in.readInt();
          socketTrustStoreFilename = readString(in);
          socketTrustStorePassword = readString(in);
          webPort       = in.readInt();
          clientTimezone = readInteger(in);
          browserWebSocket = readString(in);
          propath       = readString(in);
          browserTimezone = readInteger(in);
          ipCaptureTimestamp = readLong(in);
          screenColorDepth = readInteger(in);
          screenHeight  = readInteger(in);
          screenScalingFactor = readFloat(in);
          screenWidth   = readInteger(in);
          userAgent     = readString(in);
          serverBaseUrl = readString(in);
          webRoot = readString(in);
       }
    }