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);
   }
}