UndoableFactory.java

/*
** Module   : UndoableFactory.java
** Abstract : defines APIs to create 4GL-compatible undoable instances and initialize parameters.
**
** Copyright (c) 2016-2025, Golden Code Development Corporation.
**
** -#- -I- --Date-- ---------------------------------------Description----------------------------------------
** 001 CA  20160721 Created initial version.  Added APIs to create 4GL-compatible instances, with
**                  or without initializers, with or without extent clauses.  Also, there are
**                  APIs to initialize function/procedure parameters.  All APIs here (except 
**                  memptr related) will register the instances as undoables.
** 002 OM  20170807 Added missing methods related to comhandles.
** 003 GES 20181211 Added object methods.
**     OM  20181218 Improved generics.
** 004 CA  20190122 Removed deprecated object APIs - all objects must specify their underlying 
**                  type.
** 005 CA  20190927 Added support for direct Java access from 4GL code.
** 006 CA  20210609 Reworked INPUT/INPUT-OUTPUT parameters to a new approach, where they are explicitly 
**                  initialized at the method's execution, and not at the caller's arguments.
** 007 CA  20230712 Added support for 'jobject' extent variables, emitted for Java-style arrays used in 4GL
**                  code.
** 008 SB  20250522 Fix INPUT base data type reference being used as the input variable and not its clone.
*/

/*
** 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.oo.lang.*;

/**
 * Provides APIs to create or initialize an undoable instance and register for undoable support.
 */
public class UndoableFactory
{
   /**
    * Initialize an <code>INPUT</code> parameter by creating a deep copy of the specified instance.
    * <p>
    * The instance will be registered as undoable in the next scope.
    * 
    * @param    var
    *           The original instance receive as an argument.
    *           
    * @return   A copy of the given variable.
    * 
    * @see BaseDataType#deepCopy()
    */
   public static <T extends BaseDataType> T initInput(T var)
   {
      T newVar = TypeFactory.initInput(var);
      
      if (var.getClass() != memptr.class)
      {
         TransactionManager.registerNext(newVar);
      }

      return newVar;
   }

   /**
    * Initialize an <code>INPUT</code> extent parameter by creating a deep copy of the specified 
    * array.
    * <p>
    * The instances will be registered as undoable in the next scope.
    * 
    * @param    var
    *           The original array instance receive as an argument.
    *           
    * @return   A copy of the given array.
    * 
    * @see ArrayAssigner#copyOf(BaseDataType[])
    */
   public static <T extends BaseDataType> T[] initInput(T[] var)
   {
      T[] newVar = TypeFactory.initInput(var);
      
      if (newVar.getClass().getComponentType() != memptr.class)
      {
         TransactionManager.registerNext(newVar);
      }
      
      return newVar;
   }
   
   /**
    * Initialize an <code>OUTPUT</code> parameter by setting it to its default value.
    * <p>
    * The instance will be registered as undoable in the current scope.
    * 
    * @param    var
    *           The original instance receive as an argument.
    * 
    * @return   The instance to be used at the method's execution.
    */
   public static <T extends BaseDataType> T initOutput(T var)
   {
      T newVar = TypeFactory.initOutput(var);
      
      if (!(newVar instanceof memptr))
      {
         TransactionManager.registerNext(newVar);
      }
      
      return newVar;
   }
   
   /**
    * Initialize an <code>OUTPUT</code> parameter by setting it to the specified init value.
    * <p>
    * The instance will be registered as undoable in the current scope.
    * 
    * @param    var
    *           The original instance receive as an argument.
    * @param    init
    *           The init instance.
    * 
    * @return   The instance to be used at the method's execution.
    */
   public static <T extends BaseDataType> T initOutput(T var, T init)
   {
      T newVar = TypeFactory.initOutput(var, init);
      
      if (!(newVar instanceof memptr))
      {
         TransactionManager.registerNext(newVar);
      }
      
      return newVar;
   }

   /**
    * Initialize an <code>OUTPUT</code> extent parameter.
    * <p>
    * The instances will be registered as undoable in the next scope.
    * 
    * @param    var
    *           The original instance receive as an argument.
    *           
    * @return   The associated array.
    * 
    * @see OutputExtentParameter#initParameter()
    */
   public static <T extends BaseDataType> T[] initOutput(OutputExtentParameter<T> var)
   {
      T[] newVar = TypeFactory.initOutput(var);
      
      if (newVar.getClass().getComponentType() != memptr.class)
      {
         TransactionManager.registerNext(newVar);
      }
      
      return newVar;
   }

   /**
    * Initialize an <code>OUTPUT</code> extent parameter using the specified initializer and
    * extent value.
    * <p>
    * The instances will be registered as undoable in the next scope.
    * 
    * @param    var
    *           The original instance receive as an argument.
    * @param    extent
    *           The array length.
    * @param    init
    *           The initializer array.
    *           
    * @return   The associated array.
    */
   public static <T extends BaseDataType> T[] initOutput(OutputExtentParameter<T> var, 
                                                         int                      extent, 
                                                         T...                     init)
   {
      T[] newVar = TypeFactory.initOutput(var, extent, init);
      
      if (newVar.getClass().getComponentType() != memptr.class)
      {
         TransactionManager.registerNext(newVar);
      }
      
      return newVar;
   }
   
   /**
    * Initialize an <code>INPUT-OUTPUT</code> parameter by registering it as undoable in the
    * current scope.
    * <p>
    * The instance will be registered as undoable in the current scope.
    * 
    * @param    var
    *           The original instance receive as an argument.
    * 
    * @return   The instance to be used at the method's execution.
    */
   public static <T extends BaseDataType> T initInputOutput(T var)
   {
      T newVar = TypeFactory.initInputOutput(var);
      
      // in case of INPUT-OUTPUT parameters, we are using the direct reference passed as argument
      // (which was already wrapped by the runtime).
      // for this reason, there is no associated TypeFactory API, as there is no new variable to
      // create - only undoable registration is needed.
      
      if (!(newVar instanceof memptr))
      {
         TransactionManager.registerNext(newVar);
      }
      
      return newVar;
   }
   
   /**
    * Initialize an <code>INPUT-OUTPUT</code> extent parameter.
    * <p>
    * The instances will be registered as undoable in the next scope.
    * 
    * @param    var
    *           The original instance receive as an argument.
    *           
    * @return   The associated array.
    * 
    * @see InputOutputExtentParameter#initParameter()
    */
   public static <T extends BaseDataType> T[] initInputOutput(InputOutputExtentParameter<T> var)
   {
      T[] newVar = TypeFactory.initInputOutput(var);
      
      if (newVar.getClass().getComponentType() != memptr.class)
      {
         TransactionManager.registerNext(newVar);
      }
      
      return newVar;
   }
   
   /**
    * Initialize an <code>INPUT-OUTPUT</code> extent parameter.
    * <p>
    * The instances will be registered as undoable in the next scope.
    * 
    * @param    var
    *           The original instance receive as an argument.
    * @param    extent
    *           The array length.
    *           
    * @return   The associated array.
    * 
    * @see InputOutputExtentParameter#initParameter(int)
    */
   public static <T extends BaseDataType> T[] initInputOutput(InputOutputExtentParameter<T> var, 
                                                              int                           extent)
   {
      T[] newVar = TypeFactory.initInputOutput(var, extent);
      
      if (newVar.getClass().getComponentType() != memptr.class)
      {
         TransactionManager.registerNext(newVar);
      }
      
      return newVar;
   }

   /**
    * Create a {@link memptr} instance initialized to the default value.
    * <p>
    * The created instance will be registered as undoable in the next scope.
    * 
    * @return   See above.
    */
   public static memptr memptr()
   {
      memptr res = TypeFactory.memptr();
      
      // never undoable
      
      return res;
   }
   
   /**
    * Create a {@link memptr} array of the given extent and initialize it with the default value.
    * <p>
    * The created instances will be registered as undoable in the next scope.
    * 
    * @param    extent
    *           The array length.
    * 
    * @return   See above.
    */
   public static memptr[] memptrExtent(int extent)
   {
      memptr[] res = TypeFactory.memptrExtent(extent);
      
      // never undoable
      
      return res;
   }
   
   /**
    * Create a 0-length {@link memptr} array.
    * <p>
    * The created instances will be registered as undoable in the next scope.
    * 
    * @return   See above.
    */
   public static memptr[] memptrExtent()
   {
      memptr[] res = TypeFactory.memptrExtent(0);
      
      // never undoable
      
      return res;
   }

   /**
    * Create a {@link raw} instance initialized to the default value.
    * <p>
    * The created instance will be registered as undoable in the next scope.
    * 
    * @return   See above.
    */
   public static raw raw()
   {
      raw res = TypeFactory.raw();
      
      TransactionManager.registerNext(res);
      
      return res;
   }

   /**
    * Create a {@link raw} array of the given extent and initialize it with the default value.
    * <p>
    * The created instances will be registered as undoable in the next scope.
    * 
    * @param    extent
    *           The array length.
    * 
    * @return   See above.
    */
   public static raw[] rawExtent(int extent)
   {
      raw[] res = TypeFactory.rawExtent(extent);
      
      TransactionManager.registerNext(res);
      
      return res;
   }

   /**
    * Create a 0-length {@link raw} array.
    * <p>
    * The created instances will be registered as undoable in the next scope.
    * 
    * @return   See above.
    */
   public static raw[] rawExtent()
   {
      raw[] res = TypeFactory.rawExtent(0);
      
      TransactionManager.registerNext(res);
      
      return res;
   }

   /**
    * Create a {@link date} instance initialized to the default value.
    * <p>
    * The created instance will be registered as undoable in the next scope.
    * 
    * @return   See above.
    */
   public static date date()
   {
      date res = TypeFactory.date();
      
      TransactionManager.registerNext(res);
      
      return res;
   }

   /**
    * Create a {@link date} array of the given extent.  If there is data in the 
    * <code>init</code> array for a specified index, that will be used to initialize it.  
    * Otherwise, if the init array is empty, default initializer will be used; if the init array 
    * is not empty, all indices which don't have a counterpart will use the last entry in 
    * this array.
    * <p>
    * The created instances will be registered as undoable in the next scope.
    * 
    * @param    extent
    *           The array length.
    * @param    init
    *           The initializer array.
    * 
    * @return   See above.
    */
   public static date[] dateExtent(int extent, date... init)
   {
      date[] res = TypeFactory.dateExtent(extent, init);
      
      TransactionManager.registerNext(res);
      
      return res;
   }

   /**
    * Create a {@link date} extent using as initial values the data in the <code>init</code> 
    * array.  If the init array is empty, a non-initialized (0-extent) array will be returned.
    * <p>
    * The created instances will be registered as undoable in the next scope.
    * 
    * @param    init
    *           The initializer array.
    * 
    * @return   See above.
    */
   public static date[] dateExtent(date... init)
   {
      date[] res = TypeFactory.dateExtent(init);
      
      TransactionManager.registerNext(res);
      
      return res;
   }

   /**
    * Create a {@link date} instance initialized to the init value.
    * <p>
    * The created instance will be registered as undoable in the next scope.
    * 
    * @param    init
    *           The init value.
    *           
    * @return   See above.
    */
   public static date date(date init)
   {
      date res = TypeFactory.date(init);
      
      TransactionManager.registerNext(res);
      
      return res;
   }
   
   /**
    * Create a {@link datetime} instance initialized to the default value.
    * <p>
    * The created instance will be registered as undoable in the next scope.
    * 
    * @return   See above.
    */
   public static datetime datetime()
   {
      datetime res = TypeFactory.datetime();
      
      TransactionManager.registerNext(res);
      
      return res;
   }
   
   /**
    * Create a {@link datetime} array of the given extent.  If there is data in the 
    * <code>init</code> array for a specified index, that will be used to initialize it.  
    * Otherwise, if the init array is empty, default initializer will be used; if the init array 
    * is not empty, all indices which don't have a counterpart will use the last entry in 
    * this array.
    * <p>
    * The created instances will be registered as undoable in the next scope.
    * 
    * @param    extent
    *           The array length.
    * @param    init
    *           The initializer array.
    * 
    * @return   See above.
    */
   public static datetime[] datetimeExtent(int extent, datetime... init)
   {
      datetime[] res = TypeFactory.datetimeExtent(extent, init);
      
      TransactionManager.registerNext(res);
      
      return res;
   }
   
   /**
    * Create a {@link datetime} extent using as initial values the data in the <code>init</code> 
    * array.  If the init array is empty, a non-initialized (0-extent) array will be returned.
    * <p>
    * The created instances will be registered as undoable in the next scope.
    * 
    * @param    init
    *           The initializer array.
    * 
    * @return   See above.
    */
   public static datetime[] datetimeExtent(datetime... init)
   {
      datetime[] res = TypeFactory.datetimeExtent(init);
      
      TransactionManager.registerNext(res);
      
      return res;
   }
   
   /**
    * Create a {@link datetime} instance initialized to the init value.
    * <p>
    * The created instance will be registered as undoable in the next scope.
    * 
    * @param    init
    *           The init value.
    *           
    * @return   See above.
    */
   public static datetime datetime(datetime init)
   {
      datetime res = TypeFactory.datetime(init);
      
      TransactionManager.registerNext(res);
      
      return res;
   }

   /**
    * Create a {@link datetimetz} instance initialized to the default value.
    * <p>
    * The created instance will be registered as undoable in the next scope.
    * 
    * @return   See above.
    */
   public static datetimetz datetimetz()
   {
      datetimetz res = TypeFactory.datetimetz();
      
      TransactionManager.registerNext(res);
      
      return res;
   }
   
   /**
    * Create a {@link datetimetz} array of the given extent.  If there is data in the 
    * <code>init</code> array for a specified index, that will be used to initialize it.  
    * Otherwise, if the init array is empty, default initializer will be used; if the init array 
    * is not empty, all indices which don't have a counterpart will use the last entry in 
    * this array.
    * <p>
    * The created instance will be registered as undoable in the next scope.
    * 
    * @param    extent
    *           The array length.
    * @param    init
    *           The initializer array.
    * 
    * @return   See above.
    */
   public static datetimetz[] datetimetzExtent(int extent, datetimetz... init)
   {
      datetimetz[] res = TypeFactory.datetimetzExtent(extent, init);
      
      TransactionManager.registerNext(res);
      
      return res;
   }
   
   /**
    * Create a {@link datetimetz} extent using as initial values the data in the <code>init</code> 
    * array.  If the init array is empty, a non-initialized (0-extent) array will be returned.
    * <p>
    * The created instances will be registered as undoable in the next scope.
    * 
    * @param    init
    *           The initializer array.
    * 
    * @return   See above.
    */
   public static datetimetz[] datetimetzExtent(datetimetz... init)
   {
      datetimetz[] res = TypeFactory.datetimetzExtent(init);
      
      TransactionManager.registerNext(res);
      
      return res;
   }
   
   /**
    * Create a {@link datetimetz} instance initialized to the init value.
    * <p>
    * The created instance will be registered as undoable in the next scope.
    * 
    * @param    init
    *           The init value.
    *           
    * @return   See above.
    */
   public static datetimetz datetimetz(datetimetz init)
   {
      datetimetz res = TypeFactory.datetimetz(init);
      
      TransactionManager.registerNext(res);
      
      return res;
   }
   
   /**
    * Create an {@link jobject} instance initialized to the default value.
    * <p>
    * The created instance will be registered as undoable in the next scope.
    * 
    * @param   cls
    *          The class that will be wrapped by this object.
    * 
    * @return   See above.
    */
   public static <V extends Object> jobject<V> jobject(Class<V> cls)
   {
      jobject<V> res = TypeFactory.jobject(cls);
      
      TransactionManager.registerNext(res);
      
      return res;
   }
   
   /**
    * Create an empty {@link jobject} array. 
    *
    * @param   cls
    *          The class that will be wrapped by the objects in this array.
    *
    * @return  See above.
    */
   public static <V extends Object> jobject<V>[] jobjectExtent(Class<V> cls)
   {
      jobject<V>[] res = TypeFactory.jobjectExtent(cls);

      TransactionManager.registerNext(res);
      
      return res;
   }
   
   /**
    * Create an {@link jobject} array of the given extent and initialize it with the default value.
    *
    * @param    extent
    *           The array length.
    * @param   cls
    *          The class that will be wrapped by the objects in this array.
    *
    * @return  See above.
    */
   public static <V extends Object> jobject<V>[] jobjectExtent(int extent, Class<V> cls)
   {
      jobject<V>[] res = TypeFactory.jobjectExtent(extent, cls);

      TransactionManager.registerNext(res);
      
      return res;
   }
   
   /**
    * Create an {@link object} instance initialized to the default value.
    * <p>
    * The created instance will be registered as undoable in the next scope.
    * 
    * @param   cls
    *          The class that will be wrapped by this object.
    * 
    * @return   See above.
    */
   public static <V extends _BaseObject_> object<V> object(Class<V> cls)
   {
      object<V> res = TypeFactory.object(cls);
      
      TransactionManager.registerNext(res);
      
      return res;
   }

   /**
    * Create an {@link object} array of the given extent and initialize it with the default value.
    * <p>
    * The created instances will be registered as undoable in the next scope.
    * 
    * @param   extent
    *          The array length.
    * @param   cls
    *          The class that will be wrapped by this object.
    * 
    * @return   See above.
    */
   public static <V extends _BaseObject_> object<V>[] objectExtent(int extent, Class<V> cls)
   {
      object<V>[] res = TypeFactory.objectExtent(extent, cls);
      
      TransactionManager.registerNext(res);
      
      return res;
   }
   
   /**
    * Create a 0-length {@link object} array (indeterminate EXTENT).
    * <p>
    * The created instances will be registered as undoable in the next scope.
    * 
    * @param   cls
    *          The class that will be wrapped by this object.
    * 
    * @return   See above.
    */
   public static <V extends _BaseObject_> object<V>[] objectExtent(Class<V> cls)
   {
      object<V>[] res = TypeFactory.objectExtent(0, cls);
      
      TransactionManager.registerNext(res);
      
      return res;
   }
   
   /**
    * Create a {@link handle} instance initialized to the default value.
    * <p>
    * The created instance will be registered as undoable in the next scope.
    * 
    * @return   See above.
    */
   public static handle handle()
   {
      handle res = TypeFactory.handle();
      
      TransactionManager.registerNext(res);
      
      return res;
   }
   
   /**
    * Create a {@link handle} array of the given extent and initialize it with the default value.
    * <p>
    * The created instances will be registered as undoable in the next scope.
    * 
    * @param    extent
    *           The array length.
    * 
    * @return   See above.
    */
   public static handle[] handleExtent(int extent)
   {
      handle[] res = TypeFactory.handleExtent(extent);
      
      TransactionManager.registerNext(res);
      
      return res;
   }
   
   /**
    * Create a 0-length {@link handle} array.
    * <p>
    * The created instances will be registered as undoable in the next scope.
    * 
    * @return   See above.
    */
   public static handle[] handleExtent()
   {
      handle[] res = TypeFactory.handleExtent(0);
      
      TransactionManager.registerNext(res);
      
      return res;
   }
   
   /**
    * Create a {@link comhandle} instance initialized to the default value.
    * <p>
    * The created instance will be registered as undoable in the next scope.
    * 
    * @return   See above.
    */
   public static comhandle comhandle()
   {
      comhandle res = TypeFactory.comhandle();
      
      TransactionManager.registerNext(res);
      
      return res;
   }
   
   /**
    * Create a {@link comhandle} array of the given extent and initialize it with the default value.
    * <p>
    * The created instances will be registered as undoable in the next scope.
    * 
    * @param    extent
    *           The array length.
    * 
    * @return   See above.
    */
   public static comhandle[] comhandleExtent(int extent)
   {
      comhandle[] res = TypeFactory.comhandleExtent(extent);
      
      TransactionManager.registerNext(res);
      
      return res;
   }
   
   /**
    * Create a 0-length {@link comhandle} array.
    * <p>
    * The created instances will be registered as undoable in the next scope.
    * 
    * @return   See above.
    */
   public static comhandle[] comhandleExtent()
   {
      comhandle[] res = TypeFactory.comhandleExtent(0);
      
      TransactionManager.registerNext(res);
      
      return res;
   }
   
   /**
    * Create a {@link logical} instance initialized to the default value.
    * <p>
    * The created instance will be registered as undoable in the next scope.
    * 
    * @return   See above.
    */
   public static logical logical()
   {
      logical res = TypeFactory.logical();
      
      TransactionManager.registerNext(res);
      
      return res;
   }
   
   /**
    * Create a {@link logical} array of the given extent.  If there is data in the 
    * <code>init</code> array for a specified index, that will be used to initialize it.  
    * Otherwise, if the init array is empty, default initializer will be used; if the init array 
    * is not empty, all indices which don't have a counterpart will use the last entry in 
    * this array.
    * <p>
    * The created instances will be registered as undoable in the next scope.
    * 
    * @param    extent
    *           The array length.
    * @param    init
    *           The initializer array.
    * 
    * @return   See above.
    */
   public static logical[] logicalExtent(int extent, Boolean... init)
   {
      logical[] res = TypeFactory.logicalExtent(extent, init);
      
      TransactionManager.registerNext(res);
      
      return res;
   }
   
   /**
    * Create a {@link logical} extent using as initial values the data in the <code>init</code> 
    * array.  If the init array is empty, a non-initialized (0-extent) array will be returned.
    * <p>
    * The created instances will be registered as undoable in the next scope.
    * 
    * @param    init
    *           The initializer array.
    * 
    * @return   See above.
    */
   public static logical[] logicalExtent(Boolean... init)
   {
      logical[] res = TypeFactory.logicalExtent(init);
      
      TransactionManager.registerNext(res);
      
      return res;
   }
   
   /**
    * Create a {@link logical} instance.  If the <code>init</code> is null, initialize it to
    * <code>unknown</code>.  Otherwise, initialize it to the init value.
    * <p>
    * The created instance will be registered as undoable in the next scope.
    * 
    * @param    init
    *           The init value.
    *           
    * @return   See above.
    */
   public static logical logical(Boolean init)
   {
      logical res = TypeFactory.logical(init);
      
      TransactionManager.registerNext(res);
      
      return res;
   }
   
   /**
    * Create a {@link decimal} instance initialized to the default value.
    * <p>
    * The created instance will be registered as undoable in the next scope.
    * 
    * @return   See above.
    */
   public static decimal decimal()
   {
      decimal res = TypeFactory.decimal();
      
      TransactionManager.registerNext(res);
      
      return res;
   }
   
   /**
    * Create a {@link decimal} array of the given extent.  If there is data in the 
    * <code>init</code> array for a specified index, that will be used to initialize it.  
    * Otherwise, if the init array is empty, default initializer will be used; if the init array 
    * is not empty, all indices which don't have a counterpart will use the last entry in 
    * this array.
    * <p>
    * The created instances will be registered as undoable in the next scope.
    * 
    * @param    extent
    *           The array length.
    * @param    init
    *           The initializer array.
    * 
    * @return   See above.
    */
   public static decimal[] decimalExtent(int extent, decimal... init)
   {
      decimal[] res = TypeFactory.decimalExtent(extent, init);
      
      TransactionManager.registerNext(res);
      
      return res;
   }
   
   /**
    * Create a {@link decimal} extent using as initial values the data in the <code>init</code> 
    * array.  If the init array is empty, a non-initialized (0-extent) array will be returned.
    * <p>
    * The created instances will be registered as undoable in the next scope.
    * 
    * @param    init
    *           The initializer array.
    * 
    * @return   See above.
    */
   public static decimal[] decimalExtent(decimal... init)
   {
      decimal[] res = TypeFactory.decimalExtent(init);
      
      TransactionManager.registerNext(res);
      
      return res;
   }
   
   /**
    * Create a {@link decimal} instance initialized to the init value.
    * <p>
    * The created instance will be registered as undoable in the next scope.
    * 
    * @param    init
    *           The init value.
    *           
    * @return   See above.
    */
   public static decimal decimal(decimal init)
   {
      decimal res = TypeFactory.decimal(init);
      
      TransactionManager.registerNext(res);
      
      return res;
   }
   
   /**
    * Create a {@link integer} instance initialized to the default value.
    * <p>
    * The created instance will be registered as undoable in the next scope.
    * 
    * @return   See above.
    */
   public static integer integer()
   {
      integer res = TypeFactory.integer();
      
      TransactionManager.registerNext(res);
      
      return res;
   }
   
   /**
    * Create a {@link integer} array of the given extent.  If there is data in the 
    * <code>init</code> array for a specified index, that will be used to initialize it.  
    * Otherwise, if the init array is empty, default initializer will be used; if the init array 
    * is not empty, all indices which don't have a counterpart will use the last entry in 
    * this array.
    * <p>
    * The created instances will be registered as undoable in the next scope.
    * 
    * @param    extent
    *           The array length.
    * @param    init
    *           The initializer array.
    * 
    * @return   See above.
    */
   public static integer[] integerExtent(int extent, Long... init)
   {
      integer[] res = TypeFactory.integerExtent(extent, init);
      
      TransactionManager.registerNext(res);
      
      return res;
   }
   
   /**
    * Create a {@link integer} extent using as initial values the data in the <code>init</code> 
    * array.  If the init array is empty, a non-initialized (0-extent) array will be returned.
    * <p>
    * The created instances will be registered as undoable in the next scope.
    * 
    * @param    init
    *           The initializer array.
    * 
    * @return   See above.
    */
   public static integer[] integerExtent(Long... init)
   {
      integer[] res = TypeFactory.integerExtent(init);
      
      TransactionManager.registerNext(res);
      
      return res;
   }

   /**
    * Create a {@link integer} instance.  If the <code>init</code> is null, initialize it to
    * <code>unknown</code>.  Otherwise, initialize it to the init value.
    * <p>
    * The created instance will be registered as undoable in the next scope.
    * 
    * @param    init
    *           The init value.
    *           
    * @return   See above.
    */
   public static integer integer(Long init)
   {
      integer res = TypeFactory.integer(init);
      
      TransactionManager.registerNext(res);
      
      return res;
   }
   
   /**
    * Create a {@link int64} instance initialized to the default value.
    * <p>
    * The created instance will be registered as undoable in the next scope.
    * 
    * @return   See above.
    */
   public static int64 int64()
   {
      int64 res = TypeFactory.int64();
      
      TransactionManager.registerNext(res);
      
      return res;
   }
   
   /**
    * Create a {@link int64} array of the given extent.  If there is data in the 
    * <code>init</code> array for a specified index, that will be used to initialize it.  
    * Otherwise, if the init array is empty, default initializer will be used; if the init array 
    * is not empty, all indices which don't have a counterpart will use the last entry in 
    * this array.
    * <p>
    * The created instances will be registered as undoable in the next scope.
    * 
    * @param    extent
    *           The array length.
    * @param    init
    *           The initializer array.
    * 
    * @return   See above.
    */
   public static int64[] int64Extent(int extent, Long... init)
   {
      int64[] res = TypeFactory.int64Extent(extent, init);
      
      TransactionManager.registerNext(res);
      
      return res;
   }

   /**
    * Create a {@link int64} extent using as initial values the data in the <code>init</code> 
    * array.  If the init array is empty, a non-initialized (0-extent) array will be returned.
    * <p>
    * The created instances will be registered as undoable in the next scope.
    * 
    * @param    init
    *           The initializer array.
    * 
    * @return   See above.
    */
   public static int64[] int64Extent(Long... init)
   {
      int64[] res = TypeFactory.int64Extent(init);
      
      TransactionManager.registerNext(res);
      
      return res;
   }
   
   /**
    * Create a {@link int64} instance.  If the <code>init</code> is null, initialize it to
    * <code>unknown</code>.  Otherwise, initialize it to the init value.
    * <p>
    * The created instance will be registered as undoable in the next scope.
    * 
    * @param    init
    *           The init value.
    *           
    * @return   See above.
    */
   public static int64 int64(Long init)
   {
      int64 res = TypeFactory.int64(init);
      
      TransactionManager.registerNext(res);
      
      return res;
   }
   
   /**
    * Create a {@link rowid} instance initialized to the default value.
    * <p>
    * The created instance will be registered as undoable in the next scope.
    * 
    * @return   See above.
    */
   public static rowid rowid()
   {
      rowid res = TypeFactory.rowid();
      
      TransactionManager.registerNext(res);
      
      return res;
   }
   
   /**
    * Create a {@link rowid} array of the given extent and initialize it with the default value.
    * <p>
    * The created instances will be registered as undoable in the next scope.
    * 
    * @param    extent
    *           The array length.
    * 
    * @return   See above.
    */
   public static rowid[] rowidExtent(int extent)
   {
      rowid[] res = TypeFactory.rowidExtent(extent);
      
      TransactionManager.registerNext(res);
      
      return res;
   }
   
   /**
    * Create a 0-length {@link rowid} array.
    * <p>
    * The created instances will be registered as undoable in the next scope.
    * 
    * @return   See above.
    */
   public static rowid[] rowidExtent()
   {
      rowid[] res = TypeFactory.rowidExtent(0);
      
      TransactionManager.registerNext(res);
      
      return res;
   }
   
   /**
    * Create a {@link recid} instance initialized to the default value.
    * <p>
    * The created instance will be registered as undoable in the next scope.
    * 
    * @return   See above.
    */
   public static recid recid()
   {
      recid res = TypeFactory.recid();
      
      TransactionManager.registerNext(res);
      
      return res;
   }
   
   /**
    * Create a {@link recid} array of the given extent.  If there is data in the 
    * <code>init</code> array for a specified index, that will be used to initialize it.  
    * Otherwise, if the init array is empty, default initializer will be used; if the init array 
    * is not empty, all indices which don't have a counterpart will use the last entry in 
    * this array.
    * <p>
    * The created instances will be registered as undoable in the next scope.
    * 
    * @param    extent
    *           The array length.
    * @param    init
    *           The initializer array.
    * 
    * @return   See above.
    */
   public static recid[] recidExtent(int extent, Long... init)
   {
      recid[] res = TypeFactory.recidExtent(extent, init);
      
      TransactionManager.registerNext(res);
      
      return res;
   }
   
   /**
    * Create a {@link recid} extent using as initial values the data in the <code>init</code> 
    * array.  If the init array is empty, a non-initialized (0-extent) array will be returned.
    * <p>
    * The created instances will be registered as undoable in the next scope.
    * 
    * @param    init
    *           The initializer array.
    * 
    * @return   See above.
    */
   public static recid[] recidExtent(Long... init)
   {
      recid[] res = TypeFactory.recidExtent(init);
      
      TransactionManager.registerNext(res);
      
      return res;
   }
   
   /**
    * Create a {@link recid} instance.  If the <code>init</code> is null, initialize it to
    * <code>unknown</code>.  Otherwise, initialize it to the init value.
    * <p>
    * The created instance will be registered as undoable in the next scope.
    * 
    * @param    init
    *           The init value.
    *           
    * @return   See above.
    */
   public static recid recid(Long init)
   {
      recid res = TypeFactory.recid(init);
      
      TransactionManager.registerNext(res);
      
      return res;
   }

   /**
    * Create a {@link character} instance initialized to the default value.
    * <p>
    * The created instance will be registered as undoable in the next scope.
    * 
    * @return   See above.
    */
   public static character character()
   {
      character res = TypeFactory.character();
      
      TransactionManager.registerNext(res);
      
      return res;
   }

   /**
    * Create a {@link character} array of the given extent.  If there is data in the 
    * <code>init</code> array for a specified index, that will be used to initialize it.  
    * Otherwise, if the init array is empty, default initializer will be used; if the init array 
    * is not empty, all indices which don't have a counterpart will use the last entry in 
    * this array.
    * <p>
    * The created instances will be registered as undoable in the next scope.
    * 
    * @param    extent
    *           The array length.
    * @param    init
    *           The initializer array.
    * 
    * @return   See above.
    */
   public static character[] characterExtent(int extent, String... init)
   {
      character[] res = TypeFactory.characterExtent(extent, init);
      
      TransactionManager.registerNext(res);
      
      return res;
   }

   /**
    * Create a {@link character} extent using as initial values the data in the <code>init</code> 
    * array.  If the init array is empty, a non-initialized (0-extent) array will be returned.
    * <p>
    * The created instances will be registered as undoable in the next scope.
    * 
    * @param    init
    *           The initializer array.
    * 
    * @return   See above.
    */
   public static character[] characterExtent(String... init)
   {
      character[] res = TypeFactory.characterExtent(init);
      
      TransactionManager.registerNext(res);
      
      return res;
   }

   /**
    * Create a {@link character} instance.  If the <code>init</code> is null, initialize it to
    * <code>unknown</code>.  Otherwise, initialize it to the init value.
    * <p>
    * The created instance will be registered as undoable in the next scope.
    * 
    * @param    init
    *           The init value.
    *           
    * @return   See above.
    */
   public static character character(String init)
   {
      character res = TypeFactory.character(init);
      
      TransactionManager.registerNext(res);
      
      return res;
   }
   
   /**
    * Create a {@link longchar} instance initialized to the default value.
    * <p>
    * The created instance will be registered as undoable in the next scope.
    * 
    * @return   See above.
    */
   public static longchar longchar()
   {
      longchar res = TypeFactory.longchar();
      
      TransactionManager.registerNext(res);
      
      return res;
   }
   
   /**
    * Create a {@link longchar} array of the given extent.  If there is data in the 
    * <code>init</code> array for a specified index, that will be used to initialize it.  
    * Otherwise, if the init array is empty, default initializer will be used; if the init array 
    * is not empty, all indices which don't have a counterpart will use the last entry in 
    * this array.
    * <p>
    * The created instances will be registered as undoable in the next scope.
    * 
    * @param    extent
    *           The array length.
    * @param    init
    *           The initializer array.
    * 
    * @return   See above.
    */
   public static longchar[] longcharExtent(int extent, String... init)
   {
      longchar[] res = TypeFactory.longcharExtent(extent, init);
      
      TransactionManager.registerNext(res);
      
      return res;
   }
   
   
   /**
    * Create a {@link longchar} extent using as initial values the data in the <code>init</code> 
    * array.  If the init array is empty, a non-initialized (0-extent) array will be returned.
    * <p>
    * The created instances will be registered as undoable in the next scope.
    * 
    * @param    init
    *           The initializer array.
    * 
    * @return   See above.
    */
   public static longchar[] longcharExtent(String... init)
   {
      longchar[] res = TypeFactory.longcharExtent(init);
      
      TransactionManager.registerNext(res);
      
      return res;
   }
   
   /**
    * Create a {@link longchar} instance.  If the <code>init</code> is null, initialize it to
    * <code>unknown</code>.  Otherwise, initialize it to the init value.
    * <p>
    * The created instance will be registered as undoable in the next scope.
    * 
    * @param    init
    *           The init value.
    *           
    * @return   See above.
    */
   public static longchar longchar(String init)
   {
      longchar res = TypeFactory.longchar(init);
      
      TransactionManager.registerNext(res);
      
      return res;
   }
}