# StartupParameters.java

    /*
     ** Module   : StartupParameters.java
     ** Abstract : Startup parameters object.
     **
     ** Copyright (c) 2021-2024, Golden Code Development Corporation.
     **
     ** -#- -I- --Date-- --------------------------------------Description---------------------------------------
     ** 001 HC  20210726 Created initial version.
     ** 002 TT  20230621 Added support for the parameters rereadnolock, icfparam and ininame.
     ** 003 TT  20230915 Used StartupParameter subclassess to encapsulate the startup parameter details.
     ** 004 AD  20240125 Added support for trigger path parameter.
     ** 005 VVT 20241202 dateFormat parameter added for SESSION:DATA-FORMAT. See #9398.
     ** 006 ES  20250219 catchStop parameter added.
     */

    /*
     ** 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 com.goldencode.p2j.cfg.*;
    import com.goldencode.p2j.startup.parameters.*;

    import java.io.*;
    import java.lang.reflect.*;
    import java.util.*;
    import java.util.stream.*;

    /**
     * Client startup parameters object.
     */
    public class StartupParameters
    implements Externalizable
    {
       /** A list containing all the startup parameters */
       private final List<StartupParameter<?>> parameters;

       /** -v6Colon startup option */
       private final BooleanStartupParameter v6colon =
          new BooleanStartupParameter("v6colon", "-v6colon");

       /** -rereadnolock startup option */
       private final BooleanStartupParameter rereadnolock =
          new BooleanStartupParameter("rereadnolock", "-rereadnolock");

       /** -icfparam  startup option */
       private final StringStartupParameter dynamicsIcfparam =
          new StringStartupParameter("dynamics-icfparam", "-icfparam");

       /** -ininame  startup option */
       private final StringStartupParameter initializationFile =
          new StringStartupParameter("initialization-file", "-ininame");

       /** -T startup option */
       private final StringStartupParameter temporaryDirectory =
          new StringStartupParameter("temporary-directory", "-T");

       /** -logginglevel startup option */
       private final StringStartupParameter loggingLevel =
          new StringStartupParameter("logginglevel", "-logginglevel");

       /** -logentrytypes startup option */
       private final StringStartupParameter logEntryTypes =
          new StringStartupParameter("logentrytypes", "-logentrytypes");

       /** -logfile startup option */
       private final StringStartupParameter logFileName =
          new StringStartupParameter("log-file-name", "-logfile");

       /** -ubpid startup option */
       private final IntegerStartupParameter unifiedBrokerProcessId =
          new IntegerStartupParameter("unified-broker-process-id", "-ubpid");

       /** -logname startup option */
       private final StringStartupParameter logSourceName =
          new StringStartupParameter("log-source-name", "-logname");

       /** -logthreshold startup option */
       private final IntegerStartupParameter logThreshold =
          new IntegerStartupParameter("logthreshold", "-logthreshold");

       /** -numlogfiles startup option */
       private final IntegerStartupParameter numLogFiles =
          new IntegerStartupParameter("numlogfiles", "-numlogfiles");

       /** -asid startup option */
       private final IntegerStartupParameter applicationServerId =
          new IntegerStartupParameter("application-server-id", "-asid");

       /** -ubprofile startup option */
       private final StringStartupParameter unifiedBrokerPropertiesFile =
          new StringStartupParameter("unified-broker-properties-file", "-ubpropfile");

       /** -p startup option */
       private final StringStartupParameter startupProcedure =
          new StringStartupParameter("startup-procedure", "-p");

       /** -param startup option */
       private final StringStartupParameter parameter =
          new StringStartupParameter("parameter", "-param");

       /** -pf startup option */
       private final StringStartupParameter parameterFile =
          new StringStartupParameter("parameter-file", "-pf");

       /** -H startup option */
       private final StringStartupParameter hostName =
          new StringStartupParameter("host-name", "-H");

       /** -db startup option */
       private final StringStartupParameter physicalDatabaseName =
          new StringStartupParameter("physical-database-name", "-db");

       /** -S startup option */
       private final StringStartupParameter serviceName =
          new StringStartupParameter("service-name", "-S");

       /** -ld startup option */
       private final StringStartupParameter logicalDatabaseName =
          new StringStartupParameter("logical-database-name", "-ld");

       /** -n startup option */
       private final IntegerStartupParameter numberOfUsers =
          new IntegerStartupParameter("number-of-users", "-n");

       /** -clientlog startup option */
       private final StringStartupParameter clientLog =
          new StringStartupParameter("clientlog", "-clientlog");

       /** -debugalert startup option */
       private final BooleanStartupParameter debugAlert =
          new BooleanStartupParameter("debugalert", "-debugalert");

       /** -errorstack startup option */
       private final BooleanStartupParameter errorStack =
          new BooleanStartupParameter("errorstack", "-errorstack");

       /** -inp startup option */
       private final IntegerStartupParameter inputCharacters =
          new IntegerStartupParameter("input-characters", "-inp");

       /** -cpinternal startup option */
       private final StringStartupParameter cpinternal =
          new StringStartupParameter("i18n", "cpinternal", "-cpinternal");

       /** -cpstream startup option */
       private final StringStartupParameter cpStream =
          new StringStartupParameter("i18n", "cpstream", "-cpstream");

       /** -cpcase startup option */
       private final StringStartupParameter cpCase =
          new StringStartupParameter("i18n", "cpcase", "-cpcase");

       /** -cpcoll startup option */
       private final StringStartupParameter cpColl =
          new StringStartupParameter("i18n", "cpcoll", "-cpcoll");

       /** -cplog startup option */
       private final StringStartupParameter cpLog =
          new StringStartupParameter("i18n", "cplog", "-cplog");

       /** -cpprint startup option */
       private final StringStartupParameter cpPrint =
          new StringStartupParameter("i18n", "cpprint", "-cpprint");

       /** -cprcodein startup option */
       private final StringStartupParameter cpRCodeIn =
          new StringStartupParameter("i18n", "cprcodein", "-cprcodein");

       /** -cprcodeout startup option */
       private final StringStartupParameter cpRCodeOut =
          new StringStartupParameter("i18n", "cprcodeout", "-cprcodeout");

       /** -cpterm startup option */
       private final StringStartupParameter cpTerm =
          new StringStartupParameter("i18n", "cpterm", "-cpterm");

       /** -charset startup option */
       private final StringStartupParameter charSet =
          new StringStartupParameter("i18n", "charset", "-charset");

       /** -trig database connection option */
       private final StringStartupParameter triggerLocation =
          new StringStartupParameter("trigger-location", "-trig");

       /** -d Date Format */
       private final StringStartupParameter dateFormat =
          new StringStartupParameter("date-format", "-d");

       /** -catchStop startup option */
       private final IntegerStartupParameter catchStop =
          new IntegerStartupParameter("catch-stop", "-catchStop");

       /**
        * This method initializes the StartupParameters using the bootstrap config
        *
        * @param bc
        *    is the bootstrap config
        */
       public void initFromBootstrap(BootstrapConfig bc)
       {
          parameters.forEach(p -> p.initFromBootstrap(bc));
       }

       /**
        * This method initializes the StartupParameters using the directory service
        */
       public void initFromDirectory()
       {
          parameters.stream().filter(p -> p.getValue() == null).forEach(StartupParameter::initFromDirectory);
       }

       /**
        * Default constructor for serialization needs. Fields of type StartupParameter are added in aan
        * unmodifiable list using reflection. The goal is for easier manipulation and fewer lines of code.
        */
       public StartupParameters()
       {
          List<StartupParameter<?>> list = new ArrayList<>();

          for (Field field : this.getClass().getDeclaredFields())
          {
             Class<?> superclass = field.getType().getSuperclass();
             if (superclass != null && superclass.isAssignableFrom(StartupParameter.class)) try
             {
                list.add((StartupParameter<?>) field.get(this));
             }
             catch (IllegalAccessException e)
             {
                throw new RuntimeException(e);
             }
          }

          parameters = Collections.unmodifiableList(list);
       }

       /**
        * Getter for v6Colon.
        *
        * @return  The parameter value.
        */
       public boolean getV6Colon()
       {
          return v6colon.getValue() != null && v6colon.getValue();
       }

       /**
        * Getter for rereadNoLock.
        *
        * @return  The parameter value.
        */
       public boolean getRereadNoLock()
       {
          return rereadnolock.getValue() != null && rereadnolock.getValue();
       }

       /**
        * Getter for icfParam.
        *
        * @return  The parameter value.
        */
       public String getDynamicsIcfParam()
       {
          return dynamicsIcfparam.getValue();
       }

       /**
        * Getter for the temporary directory.
        *
        * @return  The parameter value.
        */
       public String getTemporaryDirectory()
       {
          return temporaryDirectory.getValue();
       }

       /**
        * Getter for iniName.
        *
        * @return  The parameter value.
        */
       public String getInitializationFile()
       {
          return initializationFile.getValue();
       }

       /**
        * Getter for loggingLevel.
        *
        * @return  The parameter value.
        */
       public String getLoggingLevel()
       {
          return loggingLevel.getValue();
       }

       /**
        * Getter for logEntryTypes.
        *
        * @return  The parameter value.
        */
       public String getLogEntryTypes()
       {
          return logEntryTypes.getValue();
       }

       /**
        * Getter for logFile.
        *
        * @return  The parameter value.
        */
       public String getLogFileName()
       {
          return logFileName.getValue();
       }

       /**
        * Getter for ubpId.
        *
        * @return  The parameter value.
        */
       public Integer getUnifiedBrokerProcessId()
       {
          return unifiedBrokerProcessId.getValue();
       }

       /**
        * Getter for logName.
        *
        * @return  The parameter value.
        */
       public String getLogSourceName()
       {
          return logSourceName.getValue();
       }

       /**
        * Getter for logThreshold.
        *
        * @return  The parameter value.
        */
       public Integer getLogThreshold()
       {
          return logThreshold.getValue();
       }

       /**
        * Getter for numLogFiles.
        *
        * @return The parameter value.
        */
       public Integer getNumLogFiles()
       {
          return numLogFiles.getValue();
       }

       /**
        * Getter for asId.
        *
        * @return  The parameter value.
        */
       public Integer getApplicationServerId()
       {
          return applicationServerId.getValue();
       }

       /**
        * Getter for ubProfile.
        *
        * @return  The parameter value.
        */
       public String getUnifiedBrokerPropertiesFile()
       {
          return unifiedBrokerPropertiesFile.getValue();
       }

       /**
        * Getter for p.
        *
        * @return  The parameter value.
        */
       public String getStartupProcedure()
       {
          return startupProcedure.getValue();
       }

       /**
        * Getter for param.
        *
        * @return  The parameter value.
        */
       public String getParameter()
       {
          return parameter.getValue();
       }

       /**
        * Getter for pf.
        *
        * @return  The parameter value.
        */
       public String getParameterFile()
       {
          return parameterFile.getValue();
       }

       /**
        * Getter for hostName.
        *
        * @return  The parameter value.
        */
       public String getHostName()
       {
          return hostName.getValue();
       }

       /**
        * Getter for databaseName.
        *
        * @return  The parameter value.
        */
       public String getPhysicalDatabaseName()
       {
          return physicalDatabaseName.getValue();
       }

       /**
        * Getter for serviceName.
        *
        * @return  The parameter value.
        */
       public String getServiceName()
       {
          return serviceName.getValue();
       }

       /**
        * Getter for logicalDatabaseName.
        *
        * @return  The parameter value.
        */
       public String getLogicalDatabaseName()
       {
          return logicalDatabaseName.getValue();
       }

       /**
        * Getter for numberOfUsers.
        *
        * @return  The parameter value.
        */
       public Integer getNumberOfUsers()
       {
          return numberOfUsers.getValue();
       }

       /**
        * Getter for cpInternal.
        *
        * @return  The parameter value.
        */
       public String getCpInternal()
       {
          return cpinternal.getValue();
       }

       /**
        * Getter for clientLog.
        *
        * @return  The parameter value.
        */
       public String getClientLog()
       {
          return clientLog.getValue();
       }

       /**
        * Getter for debugAlert.
        *
        * @return  The parameter value.
        */
       public boolean getDebugAlert()
       {
          return debugAlert.getValue() != null && debugAlert.getValue();
       }

       /**
        * Getter for errorStack.
        *
        * @return  The parameter value.
        */
       public boolean getErrorStack()
       {
          return errorStack.getValue() != null && errorStack.getValue();
       }

       /**
        * Getter for inputCharacters.
        *
        * @return  The parameter value.
        */
       public Integer getInputCharacters()
       {
          return inputCharacters.getValue();
       }

       /**
        * Getter for cpStream.
        *
        * @return  The parameter value.
        */
       public String getCpStream()
       {
          return cpStream.getValue();
       }

       /**
        * Getter for cpCase.
        *
        * @return  The parameter value.
        */
       public String getCpCase()
       {
          return cpCase.getValue();
       }

       /**
        * Getter for cpColl.
        *
        * @return  The parameter value.
        */
       public String getCpColl()
       {
          return cpColl.getValue();
       }

       /**
        * Getter for cpLog.
        *
        * @return  The parameter value.
        */
       public String getCpLog()
       {
          return cpLog.getValue();
       }

       /**
        * Getter for cpPrint.
        *
        * @return  The parameter value.
        */
       public String getCpPrint()
       {
          return cpPrint.getValue();
       }

       /**
        * Getter for cpRCodeIn.
        *
        * @return  The parameter value.
        */
       public String getCpRCodeIn()
       {
          return cpRCodeIn.getValue();
       }

       /**
        * Getter for cpRCodeOut.
        *
        * @return  The parameter value.
        */
       public String getCpRCodeOut()
       {
          return cpRCodeOut.getValue();
       }

       /**
        * Getter for cpTerm.
        *
        * @return  The parameter value.
        */
       public String getCpTerm()
       {
          return cpTerm.getValue();
       }

       /**
        * Getter for cpStream.
        *
        * @return  The parameter value.
        */
       public String getCharset()
       {
          return charSet.getValue();
       }

       /**
        * Getter for triggerLocation.
        *
        * @return  The parameter value.
        */
       public String getTriggerLocation()
       {
          return triggerLocation.getValue();
       }

       /**
        * Getter for dateFormat.
        *
        * @return  The parameter value.
        */
       public String getDateFormat()
       {
          return dateFormat.getValue();
       }

       /**
        * Getter for catchStop.
        *
        * @return  The parameter value.
        */
       public Integer getCatchStop()
       {
          return catchStop.getValue();
       }

       /**
        * 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
       {
          for (StartupParameter<?> value : parameters)
          {
             value.writeExternal(out);
          }
       }

       /**
        * 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
       {
          for (StartupParameter<?> value : parameters)
          {
             value.readExternal(in);
          }
       }

       /**
        * Returns a comma-separated String of all startup parameters.
        *
        * @return see above. The returned value is never null.
        */
       @Override
       public String toString()
       {
          List<String> parameterStrings = parameters.stream()
                                                    .map(Object::toString)
                                                    .filter(Objects::nonNull)
                                                    .collect(Collectors.toList());

          return String.join(",", parameterStrings);
       }
    }