# CentralLoggerClientConfig.java

    /*
    ** Module   : CentralLoggerClientConfigs.java
    ** Abstract : Wrapper class for client logger configs.
    **
    ** Copyright (c) 2023-2024, Golden Code Development Corporation.
    **
    ** -#- -I- --Date-- ----------------------------Description-----------------------------
    ** 001 GBB 20230419 Initial setup.
    ** 002 GBB 20230519 Support for disabling rotation.
    ** 003 GBB 20230619 convertToLevel method moved to LoggingUtil
    ** 004 GBB 20240729 JavaDoc fixes.
    */
    /*
     ** This program is free software: you can redistribute it and/or modify
     ** it under the terms of the GNU Affero General 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 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.util.logging;

    import java.io.*;
    import java.util.*;
    import java.util.logging.*;

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

    /** Wrapper for logger name : level pairs. Used to transfer levels from server to clients. */
    public class CentralLoggerClientConfig
    implements Externalizable
    {
       /** Logger name : level pairs. */
       private final Map<String, Level> loggerNameLevelMap = new HashMap<>();

       /** A flag indicating if writing to log files is server-side. */
       private Boolean isServerSideLogging;

       /** The path to the log file. */
       private String filePath;

       /** The file limit, or the max bytes in a log file before rotation. */
       private int fileLimit;

       /** The file count, or the max number of files before file overwrite starts. */
       private int fileCount;

       /** Default constructor for CentralLoggerLevels. Used for constructing the Externalizable. */
       public CentralLoggerClientConfig()
       {
          this.isServerSideLogging = null;
       }

       /**
        * Public constructor. Used for sending the new logger name : level map to the client to invalidate the
        * logger levels in the tree.
        *
        * @param   loggerLevelMap
        *          Logger name : level pairs.
        */
       public CentralLoggerClientConfig(Map<String, Level> loggerLevelMap)
       {
          this.isServerSideLogging = null;
          this.loggerNameLevelMap.putAll(loggerLevelMap);
       }

       /**
        * Public constructor with takes values for all fields as parameters. Used by the server sending initial
        * configurations.
        *
        * @param   loggerLevelMap
        *          Logger name : level pairs.
        * @param   filePath
        *          The path to the log file.
        * @param   fileLimit
        *          The file limit, or the max bytes in a log file before rotation.
        * @param   fileCount
        *          The file count, or the max number of files before file overwrite starts.
        * @param   isServerSideLogging
        *          A flag indicating if writing to log files is server-side.
        */
       public CentralLoggerClientConfig(Map<String, Level> loggerLevelMap,
                                        String filePath,
                                        int fileLimit,
                                        int fileCount,
                                        boolean isServerSideLogging)
       {
          this.isServerSideLogging = isServerSideLogging;
          this.filePath = filePath;
          this.fileLimit = fileLimit;
          this.fileCount = fileCount;
          this.loggerNameLevelMap.putAll(loggerLevelMap);
       }

       /**
        * Getter for the logger name : level map.
        *
        * @return  The logger name : level map.
        */
       public Map<String, Level> getLoggerLevels()
       {
          return loggerNameLevelMap;
       }

       /**
        * Getter for the flag indicating if writing to log files is server-side.
        *
        * @return  The flag indicating if writing to log files is server-side.
        */
       public Boolean isServerSideLoggingEnabled()
       {
          return isServerSideLogging;
       }

       /**
        * Getter for the path to the log file.
        *
        * @return  The path to the log file.
        */
       public String getFilePath()
       {
          return filePath;
       }

       /**
        * Getter for the file limit, or the max bytes in a log file before rotation.
        *
        * @return  The file limit, or the max bytes in a log file before rotation.
        */
       public int getFileLimit()
       {
          return fileLimit;
       }

       /**
        * Getter for the file count, or the max number of files before file overwrite starts.
        *
        * @return  The file count, or the max number of files before file overwrite starts.
        */
       public int getFileCount()
       {
          return fileCount;
       }

       /**
        * Writes out {@link #loggerNameLevelMap} as Set of strings ans {@link #isServerSideLogging} as Boolean.
        *
        * @param   out
        *          The stream to write the object to
        *
        * @throws  IOException
        *          If any I/O exceptions occur
        */
       @Override
       public void writeExternal(ObjectOutput out)
       throws IOException
       {
          Set<String> pairStrings = new HashSet<>();
          loggerNameLevelMap.forEach((loggerName, level) -> pairStrings.add(loggerName + "," + level.getName()));
          writeStringSet(out, pairStrings);
          writeString(out, filePath);
          writeInteger(out, fileLimit);
          writeInteger(out, fileCount);
          writeBoolean(out, isServerSideLogging);
       }

       /**
        * Reads {@link #loggerNameLevelMap} as Set of strings and {@link #isServerSideLogging} as Boolean.
        *
        * @param   in
        *          The stream to read data from in order to restore the object
        *
        * @throws  IOException
        *          If any I/O exceptions occur
        */
       @Override
       public void readExternal(ObjectInput in)
       throws IOException,
              ClassNotFoundException
       {
          Set<String> pairStrings = readStringSet(in, true);
          if (pairStrings == null)
          {
             return;
          }
          pairStrings.forEach(nameLevelString -> {
             String[] nameLevelArray = nameLevelString.split(",");
             Optional<Level> levelOptional = LoggingUtil.convertToLevel(nameLevelArray[1]);
             levelOptional.ifPresent(level -> loggerNameLevelMap.put(nameLevelArray[0], level));
          });
          filePath = readString(in);
          fileLimit = readInteger(in);
          fileCount = readInteger(in);
          isServerSideLogging = readBoolean(in);
       }
    }