LegacyLogOps.java

/*
** Module   : LegacyLogOps.java
** Abstract : Factory to create and manage the LOG-MANAGER and DSLOG-MANAGER instances.
**
** Copyright (c) 2014-2025, Golden Code Development Corporation.
**
** -#- -I- --Date-- -----------------------Description------------------------
** 001 GES 20141029 Created initial version.
** 002 GBB 20230313 Separate LegacyLogManagerImpl and DsLegacyLogManagerImpl.
**                  Close LOG-MANAGER on ContextLocal cleanup.
** 003 GBB 20250403 LOG-MANAGER defaults exposed as constants. Method added to access out of context 
**                  LOG-MANAGER instances for system logs.
** 004 AL2 20250522 Overloaded logMgr to allow possibility of not creating a LOG-MANAGER if none exists.
*/
/*
** 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.util;

import com.goldencode.p2j.security.*;
import com.goldencode.p2j.util.logging.*;

import java.util.*;
import java.util.concurrent.*;

/**
 * Factory to create and manage the LOG-MANAGER and DSLOG-MANAGER instances. These instances
 * are created per-context so that each session has its own set, since in the 4GL the logging
 * will be different per client.
 */
public class LegacyLogOps
{
   /** Appserver LOG-MANAGER configs stored to be restored in case of state reset (in State-reset mode). */
   public static final Map<String, LegacyLogManagerConfigs> appserverNameLogConfigPairs = 
      new ConcurrentHashMap<>();

   /** Default logging level. */
   public static final int DEFAULT_LOGGING_LEVEL = 2;

   /** Default number of log files. */
   public static final int DEFAULT_NUM_FILES = 3;

   /** Default threshold. */
   public static final int DEFAULT_THRESHOLD = 0;
   
   /** Default entry types for appserver agents.  */
   public static final String DEFAULT_APPSERVER_TYPES = LoggingEntryType.ASPlumbing.toString() + "," +
      LoggingEntryType.DB_Connects.toString();
   
   /** The default log file name pattern. Used by appservers. */
   public static final String DEFAULT_APPSERVER_LOGFILE_NAME =
      "legacy_client_" + LoggingUtil.SORTABLE_DATETIME_FORMAT + "_%uos_%pid_%as.log";

   /** An instance of the log write executor to be reused by all log manager instances. */
   private static final LegacyLogWriteExecutor writeExecutor = LegacyLogWriteExecutor.get();

   /** Stores this context's log manager instances. */
   private static final ContextLocal<WorkArea> local = new ContextLocal<WorkArea>()
   {
      @Override
      protected WorkArea initialValue()
      {
         return new WorkArea();
      }
      
      @Override
      public WeightFactor getWeight()
      {
         return WeightFactor.LEVEL_10;
      }

      @Override
      protected void cleanup(WorkArea wa)
      {
         if (wa.logMgr != null)
         {
            wa.logMgr.close(false, true);
         }
      }
   };
   
   /**
    * Disables construction of instances of this object.  All access is via static methods.
    */
   private LegacyLogOps()
   {
   }
   
   /**
    * Returns the instance of the current session's <code>LOG-MANAGER</code> resource.
    * 
    * @return   The <code>LOG-MANAGER</code> instance.
    */
   public static LegacyLogManager logMgr()
   {
      return logMgr(true);
   }
   
   /**
    * Returns the instance of the current session's <code>LOG-MANAGER</code> resource.
    * 
    * @param    create
    *           If {@code true} and no log manager was ever created, then it will be created now.
    *           Otherwise, avoid creating one. This is usually used in sensitive places like clean-up.
    * 
    * @return   The <code>LOG-MANAGER</code> instance.
    */
   public static LegacyLogManager logMgr(boolean create)
   {
      WorkArea wa = local.get();
      
      LegacyLogManager lm = null;
      
      synchronized (wa)
      {
         if (wa.logMgr == null && create)
         {
            wa.logMgr = new LegacyLogManagerImpl(writeExecutor);
         }
         
         lm = wa.logMgr;
      }
      
      return lm;
   }

   /**
    * Creates a new instance of <code>LOG-MANAGER</code> that is not context local.
    *
    * @return   The <code>LOG-MANAGER</code> instance.
    */
   public static LegacyLogManager newStaticLogMgr()
   {
      return new LegacyLogManagerImpl(writeExecutor);
   }
   
   /**
    * Returns the instance of the current session's <code>LOG-MANAGER</code> system handle.
    * 
    * @return   The <code>LOG-MANAGER</code> system handle.
    */
   public static handle logMgrHandle()
   {
      return new handle(logMgr());
   }
   
   /**
    * Returns the instance of the current session's <code>DSLOG-MANAGER</code> resource.
    * 
    * @return   The <code>DSLOG-MANAGER</code> instance.
    */
   public static LegacyDsLogManager dsLogMgr()
   {
      WorkArea wa = local.get();

      LegacyDsLogManager lm = null;
      
      synchronized (wa)
      {
         if (wa.dsLogMgr == null)
         {
            wa.dsLogMgr = new LegacyDsLogManagerImpl(writeExecutor);
         }
         
         lm = wa.dsLogMgr;
      }
      
      return lm;
   }
   
   /**
    * Returns the instance of the current session's <code>DSLOG-MANAGER</code> system handle.
    * 
    * @return   The <code>DSLOG-MANAGER</code> system handle.
    */
   public static handle dsLogMgrHandle()
   {
      return new handle(dsLogMgr());
   }
   
   /** 
    * Stores global data relating to the state of the current context.
    */
   private static class WorkArea
   {
      /** Equivalent of the LOG-MANAGER system handle for this session. */
      private LegacyLogManager logMgr = null;
      
      /** Equivalent of the DSLOG-MANAGER system handle for this session. */
      private LegacyDsLogManager dsLogMgr = null;
   }
}