Project

General

Profile

scopeable_6650_patch_20220901a.patch

Constantin Asofiei, 09/01/2022 09:36 AM

Download (115 KB)

View differences:

new/src/com/goldencode/p2j/main/StandardServer.java 2022-09-01 08:47:05 +0000
196 196
**     CA  20220405          Added authentication and authorization for web requests.  When this is enabled, 
197 197
**                           the target API call will be executed under the authenticated FWD context, and not 
198 198
**                           the agent's context.
199
**     CA  20220901          Refactored scope notification support: ScopeableFactory was removed, and the 
200
**                           registration is now specific to each type of scopeable.  For each case, the block
201
**                           will be registered for scope support (for that particular scopeable) only when
202
**                           the scopeable is 'active' (i.e. unnamed streams or accumulators are used).  This
203
**                           allows a lazy registration of scopeables, to avoid the unnecessary overhead of
204
**                           processing all the scopeables for each and every block.
199 205
*/
200 206

  
201 207
/*
......
1166 1172
   /**
1167 1173
    * Register default services:
1168 1174
    * <ol>
1169
    * <li> {@link SharedVariableManager} </li>
1170
    * <li> {@link UnnamedStreams} </li>
1171
    * <li> {@link LogicalTerminal} </li>
1172 1175
    * <li> {@link Persistence} </li>
1173
    * <li> {@link AccumulatorManager} </li>
1174 1176
    * <li> {@link WebServer} </li>
1175 1177
    * <li> custom account extension plugin </li>
1176 1178
    * </ol>
......
1237 1239
         @Override
1238 1240
         public void initialize()
1239 1241
         {
1240
            SharedVariableManager.initialize();
1241
         }
1242
      });
1243

  
1244
      serverHooks.add(new AbstractInitTermListener()
1245
      {
1246
         @Override
1247
         public void initialize()
1248
         {
1249
            UnnamedStreams.initialize();
1250
         }
1251
      });
1252
      
1253
      serverHooks.add(new AbstractInitTermListener()
1254
      {
1255
         @Override
1256
         public void initialize()
1257
         {
1258
            LogicalTerminal.initialize();
1259
         }
1260
      });
1261
      
1262
      serverHooks.add(new AbstractInitTermListener()
1263
      {
1264
         @Override
1265
         public void initialize()
1266
         {
1267 1242
            ServerKeyStore.initialize();
1268 1243
         }
1269 1244
      });
......
1309 1284
            }
1310 1285
         }
1311 1286
      });
1312
      
1313
      serverHooks.add(new AbstractInitTermListener()
1314
      {
1315
         @Override
1316
         public void initialize()
1317
         {
1318
            AccumulatorManager.initialize();
1319
         }
1320
      });
1321
      
1287

  
1322 1288
      // register controller for method execution tracing
1323 1289
      serverHooks.add(new AbstractInitTermListener()
1324 1290
      {
......
1712 1678
                                   false,
1713 1679
                                   false);
1714 1680
      
1681
      // make sure that the global block gets a special notification - but only for non-appserver sessions.
1682
      if (!AppServerManager.isRemote() && !TransactionManager._isHeadless())
1683
      {
1684
         Finalizable cleaner = new Finalizable()
1685
         {
1686
            @Override
1687
            public void finished()
1688
            {
1689
               LogicalTerminal.getInstance().pauseBeforeEnd(TransactionManager.isProcessingQuit());
1690
            }
1691
            
1692
            @Override
1693
            public void iterate()
1694
            {
1695
               // nothing to do here 
1696
            }
1697
            
1698
            @Override
1699
            public void retry()
1700
            {
1701
               // nothing to do here 
1702
            }
1703
            
1704
            @Override
1705
            public void deleted()
1706
            {
1707
               // nothing to do here
1708
            }
1709
         };
1710
            
1711
         TransactionManager.registerFinalizable(cleaner, true);
1712
      }
1713
      
1715 1714
      Object result = null;
1716 1715
      try
1717 1716
      {
new/src/com/goldencode/p2j/persist/BufferManager.java 2022-09-01 08:47:17 +0000
444 444
**                           were added to the collection during iterating it, resulting in a 
445 445
**                           ConcurrentModificationException (refs #6356). 
446 446
**     CA  20220707          Cache the converted Java names for the dynamic buffers.
447
**     CA  20220901          Refactored scope notification support: ScopeableFactory was removed, and the 
448
**                           registration is now specific to each type of scopeable.  For each case, the block
449
**                           will be registered for scope support (for that particular scopeable) only when
450
**                           the scopeable is 'active' (i.e. unnamed streams or accumulators are used).  This
451
**                           allows a lazy registration of scopeables, to avoid the unnecessary overhead of
452
**                           processing all the scopeables for each and every block.
447 453
*/
448 454

  
449 455
/*
......
517 523
import com.goldencode.p2j.security.*;
518 524
import com.goldencode.p2j.util.*;
519 525
import com.goldencode.p2j.util.LogHelper;
526
import com.goldencode.p2j.util.Scopeable.ScopeId;
520 527
import com.goldencode.p2j.util.ErrorManager;
521 528
import com.goldencode.util.*;
529
import com.goldencode.util.Stack;
522 530

  
523 531
/**
524 532
 * Manages all record buffers within the current user context.  This includes
......
568 576
      @Override protected BufferManager initialValue() { return (new BufferManager()); }
569 577
   };
570 578
   
571
   /** Flag indicating whether class was initialized, i.e. {@link #initialize} was called */
572
   private static boolean initialized = false;
573
   
574 579
   /** A cache of buffer-related fields defined in a specific legacy-converted class. */
575 580
   private static final Map<Class<?>, Set<Field>> classBufferFields = new ConcurrentHashMap<>();
576 581
   
......
637 642
   private final ScopedList<RecordBuffer> openBuffers = new ScopedList<>();
638 643
   
639 644
   /**
640
    * The buffers touched via a Create, Update or Delete operation, in each scope. If the full transaction
645
    * The buffers touched via a Create, Update, Copy or Delete operation, in each scope. If the full transaction
641 646
    * block is not {@link #commit committed} or {@link #rollback rolled back}, then the buffers will be merged 
642 647
    * in the previous scope. 
643 648
    */
......
662 667
   private final ScopedDictionary<OutputTableHandleCopier, Integer> thOutputParameters =
663 668
      new ScopedDictionary<>();
664 669
   
670
   /** Track the external scopes pushed on {@link BufferManager}. */
671
   private final Stack<Boolean> externalScope = new Stack<>();
672
   
665 673
   /** Database to transaction wrapper instance map */
666 674
   private final Map<Database, TxWrapper> txWrapperMap = new HashMap<>();
667 675
   
......
692 700
   /** Transaction helper */
693 701
   private final TransactionManager.TransactionHelper txHelper;
694 702
   
703
   /** Change broker instance. */
704
   private final ChangeBroker changeBroker;
705
   
695 706
   /** Block depth at which full application transaction began, or -1 if not in a transaction */
696 707
   private int transactionDepth = -1;
697 708
   
......
742 753
      txHelper.registerStopVetoHandler(this);
743 754
      txHelper.registerResettable(this);
744 755
      
756
      changeBroker = ChangeBroker.get();
757
      
745 758
      if (LOG.isLoggable(Level.FINE))
746 759
      {
747 760
         LOG.log(Level.FINE, "BufferManager created in context " + Utils.describeContext());
......
749 762
   }
750 763
   
751 764
   /**
752
    * Retrieve the context-local instance of this class, instantiating it
753
    * first if necessary.
765
    * Retrieve the context-local instance of this class, instantiating it first if necessary.
754 766
    *
755 767
    * @return  Context-local instance of this class.
756
    * @throws  IllegalStateException
757
    *            when {@link BufferManager} is not activated, i.e. {@link
758
    *            #initialize()} is not called.
759 768
    */
760 769
   public static BufferManager get()
761 770
   {
762
      if (!BufferManager.initialized)
763
      {
764
         throw new IllegalStateException(
765
            "An attempt to use uninitialized BufferManager. Is persistence activated?");
766
      }
767
      
768 771
      BufferManager bm = context.get();
769 772
      if (bm.connMgr == null)
770 773
      {
......
783 786
   }
784 787
   
785 788
   /**
789
    * Register the {@link BufferManager} instance as for scope notifications at the current block.
790
    * 
791
    * @param    bufferManager
792
    *           The {@link BufferManager} instance.
793
    */
794
   public static void registerScopeable(BufferManager bufferManager)
795
   {
796
      if (bufferManager == null)
797
      {
798
         bufferManager = get();
799
      }
800
      
801
      bufferManager.txHelper.registerBlockScopeable(bufferManager);
802
      bufferManager.txHelper.registerBlockScopeable(bufferManager.changeBroker);
803
   }
804

  
805
   /**
806
    * Register the {@link BufferManager} instance as pending scopeable, to be added to the next block.
807
    * 
808
    * @param    bufferManager
809
    *           The {@link BufferManager} instance.
810
    */
811
   public static void registerPendingScopeable(BufferManager bufferManager)
812
   {
813
      if (bufferManager == null)
814
      {
815
         bufferManager = get();
816
      }
817
      
818
      bufferManager.txHelper.registerPendingScopeable(bufferManager);
819
      bufferManager.txHelper.registerPendingScopeable(bufferManager.changeBroker);
820
   }
821
   
822
   /**
786 823
    * Cleanup of pending resources. This is called when the external procedure constructor failed 
787 824
    * to build a new object because of an exception thrown in a member initialization (shared 
788 825
    * frame/table).
......
796 833
   }
797 834
   
798 835
   /**
799
    * Register with the {@link com.goldencode.p2j.util.TransactionManager
800
    * TransactionManager} a factory object which creates instances of this
801
    * class, so that they can be registered to receive notifications of
802
    * runtime scope start and finish events.
803
    * <p>
804
    * This method should be invoked once during the server bootstrap phase.
805
    */
806
   static void initialize()
807
   {
808
      TransactionManager.registerScopeableFactory(BufferManager::get);
809
      BufferManager.initialized = true;
810
   }
811
   
812
   /**
813 836
    * Register this buffer as 'dirty' in the current scope.
814 837
    * <p>
815 838
    * This registration doesn't mean that at the time of {@link #commit}, {@link #rollback}, or 
......
1045 1068
   }
1046 1069
   
1047 1070
   /**
1071
    * Find the nearest external block (from the bottom of the stack).
1072
    * 
1073
    * @return   See above.
1074
    */
1075
   public int findNearestExternal()
1076
   {
1077
      int idx = externalScope.size() - 1;
1078
      while (idx > 0)
1079
      {
1080
         if (externalScope.get(idx))
1081
         {
1082
            return idx + 1;
1083
         }
1084
         
1085
         idx = idx - 1;
1086
      }
1087
      
1088
      return -1;
1089
   }
1090
   
1091
   /**
1048 1092
    * Check the specified exception and determine whether we want to allow it
1049 1093
    * to be honored by the {@link TransactionManager}, or whether we want to
1050 1094
    * veto the STOP at this scope.
......
1235 1279
      thOutputParameters.addScope(null);
1236 1280
      undoData.addScope(null);
1237 1281
      fieldScopes.scopeStart();
1282
      externalScope.push(txHelper.isExternalBlock());
1238 1283
      
1239 1284
      BatchModeData crtBatchScope = batchModeStack.peek();
1240 1285
      if (crtBatchScope != null && crtBatchScope.batchDepth == BatchModeData.INTERNAL)
......
1455 1500
      fieldScopes.scopeFinished();
1456 1501
      openStaticTempTables.deleteScope();
1457 1502
      thOutputParameters.deleteScope();
1503
      externalScope.pop();
1458 1504
      BatchModeData bmd = batchModeStack.pop();
1459 1505
      if (bmd.batchDepth == BatchModeData.INTERNAL)
1460 1506
      {
......
1536 1582
   }
1537 1583
   
1538 1584
   /**
1585
    * Get the {@link ScopeId} for the instance.
1586
    * 
1587
    * @return   {@link ScopeId#BUFFER_MANAGER}.
1588
    */
1589
   @Override
1590
   public ScopeId getScopeId()
1591
   {
1592
      return ScopeId.BUFFER_MANAGER;
1593
   }
1594
   
1595
   /**
1539 1596
    * Provides a notification that a batch is starting or ending.  Enters or
1540 1597
    * exits batch assignment mode for all record buffers in this context,
1541 1598
    * depending on the value of <code>start</code>.
......
1660 1717
    * 
1661 1718
    * @return  {@code true} if we are in a transaction, else {@code false}.
1662 1719
    */
1720
   @Deprecated
1663 1721
   public boolean isTransactionAt(int level)
1664 1722
   {
1665 1723
      return transactionDepth >= 0 && transactionDepth <= level;
......
1672 1730
    * @return  {@code true} if we are at (and within) a full transaction boundary, else {@code
1673 1731
    *          false}.
1674 1732
    */
1733
   @Deprecated
1675 1734
   public boolean isFullTransaction()
1676 1735
   {
1736
      // TODO: this has dependency on the full app stack 
1677 1737
      return transactionDepth >= 0 && getOpenBufferScopes() - 1 == transactionDepth;
1678 1738
   }
1679 1739
   
......
1684 1744
    * @return  Zero-based block depth of current, full transaction, or -1 if we are not currently
1685 1745
    *          within a transaction.
1686 1746
    */
1747
   @Deprecated
1687 1748
   public int getFullTransactionBlock()
1688 1749
   {
1689 1750
      return transactionDepth;
......
2658 2719
    */
2659 2720
   void openScopeAt(int openScopeDepth, RecordBuffer buffer)
2660 2721
   {
2722
      // TODO: this seems to be called only for 'openScopeDepth == 0'.
2723
      
2661 2724
      if (buffer.isActive())
2662 2725
      {
2663 2726
         if (openScopeDepth == 0)
......
3147 3210
    * @return  {@code true} if the block is considered &quot;important&quot; by the above criteria, else
3148 3211
    *          {@code false}.
3149 3212
    */
3150
   private boolean isImportantBlockTransition()
3213
   public boolean isImportantBlockTransition()
3151 3214
   {
3152 3215
      return !txHelper.isTransaction() ||
3153 3216
             txHelper.currentTransactionLevel() != TransactionManager.NO_TRANSACTION;
......
3158 3221
    * primary key.  One instance of this class holds all such objects for a
3159 3222
    * single buffer in a single scope.
3160 3223
    */
3224
   @Deprecated
3161 3225
   private static class UndoData
3162 3226
   {
3163 3227
      /** Undoable which will set a no-undo buffer to its proper record after a rollback. */
new/src/com/goldencode/p2j/persist/ChangeBroker.java 2022-09-01 08:47:22 +0000
98 98
**                           Use an identity HashSet where possible.
99 99
**     CA  20220309          Added isQueried(), which checks if a temp-table has any listeners registered for
100 100
**                           events which are a P2JQuery.
101
**     CA  20220901          Refactored scope notification support: ScopeableFactory was removed, and the 
102
**                           registration is now specific to each type of scopeable.  For each case, the block
103
**                           will be registered for scope support (for that particular scopeable) only when
104
**                           the scopeable is 'active' (i.e. unnamed streams or accumulators are used).  This
105
**                           allows a lazy registration of scopeables, to avoid the unnecessary overhead of
106
**                           processing all the scopeables for each and every block.
101 107
*/
102 108

  
103 109
/*
......
164 170
import com.goldencode.p2j.persist.orm.*;
165 171
import com.goldencode.p2j.security.*;
166 172
import com.goldencode.p2j.util.*;
173
import com.goldencode.p2j.util.Scopeable.ScopeId;
167 174

  
168 175
/**
169 176
 * A clearing house which notifies interested parties of changes made to
......
253 260
   }
254 261
   
255 262
   /**
256
    * Register with the {@link com.goldencode.p2j.util.TransactionManager
257
    * TransactionManager} a factory object which creates instances of this
258
    * class, so that they can be registered to receive notifications of
259
    * runtime scope start and finish events.
260
    * <p>
261
    * This method should be invoked once during the server bootstrap phase.
262
    */
263
   static void initialize()
264
   {
265
      TransactionManager.registerScopeableFactory(ChangeBroker::get);
266
   }
267
   
268
   /**
269 263
    * Add a scope to the listeners dictionary whenever a new runtime scope
270 264
    * opens.
271 265
    */
......
332 326
   }
333 327
   
334 328
   /**
329
    * Get the {@link ScopeId} for the instance.
330
    * 
331
    * @return   {@link ScopeId#CHANGE_BROKER}.
332
    */
333
   @Override
334
   public ScopeId getScopeId()
335
   {
336
      return ScopeId.CHANGE_BROKER;
337
   }
338
   
339
   /**
335 340
    * Register a listener to receive DMO property change notifications.  The
336 341
    * listener will receive notifications of any changes to DMOs of the types
337 342
    * for which it is registered, as they occur in this scope or in scopes
new/src/com/goldencode/p2j/persist/CompoundQuery.java 2022-09-01 08:48:30 +0000
224 224
**                           its own block and not via a QUERY resource). 
225 225
**     IAS 20220510          Resetting activeIndex before iterating over the components for current(LockType)
226 226
**     IAS 20220707          Resetting nullOuter on new iteration step.
227
**     CA  20220901          Refactored scope notification support: ScopeableFactory was removed, and the 
228
**                           registration is now specific to each type of scopeable.  For each case, the block
229
**                           will be registered for scope support (for that particular scopeable) only when
230
**                           the scopeable is 'active' (i.e. unnamed streams or accumulators are used).  This
231
**                           allows a lazy registration of scopeables, to avoid the unnecessary overhead of
232
**                           processing all the scopeables for each and every block.
227 233
*/
228 234

  
229 235
/*
......
763 769
      activeIndex = -1;
764 770
      preselected = false;
765 771
      
766
      int lowestScope = registerRecordChangeListeners();
772
      boolean globalScope = registerRecordChangeListeners();
767 773
      
768 774
      super.open();
769 775
      
......
772 778
         preselectResults();
773 779
      }
774 780
      
775
      initReferenceRowSupport(lowestScope);
781
      initReferenceRowSupport(globalScope);
776 782
   }
777 783
   
778 784
   /**
......
1880 1886
    * Init structures required to use reference row: create the map of all buffers, register
1881 1887
    * parameter filters for sub-queries and register this query as a record change listener.
1882 1888
    *
1883
    * @param   blockDepth
1884
    *          Depth of the block at which this query is registered as record change listener.
1885
    *          <code>0</code> for global scope.
1889
    * @param   globalScope
1890
    *          Flag indicating if the block at which this query is registered as record change listener is
1891
    *          the global scope.
1886 1892
    */
1887
   protected void initReferenceRowSupport(int blockDepth)
1893
   protected void initReferenceRowSupport(boolean globalScope)
1888 1894
   {
1889 1895
      if (!preselect && buffersMap == null)
1890 1896
      {
......
1909 1915
         }
1910 1916
         
1911 1917
         ChangeBroker.get().addListener(this);
1912
         if (blockDepth == 0)
1918
         if (globalScope)
1913 1919
         {
1914 1920
            unregisterOnCleanup = true;
1915 1921
         }
......
2064 2070
   @SuppressWarnings("unchecked")
2065 2071
   protected Object[] retrieve(int navigation, LockType lockType, boolean iterating, boolean peek)
2066 2072
   {
2067
      initReferenceRowSupport(-1);
2073
      initReferenceRowSupport(false);
2068 2074
      
2069 2075
      Object[] rowData;
2070 2076
      
......
2398 2404
   /**
2399 2405
    * Register the query within each component as a record change listener.
2400 2406
    * 
2401
    * @return  The lowest scope found among all the components' record buffers.
2407
    * @return  <code>true</code> if the global scope is used for registration.
2402 2408
    */
2403
   private int registerRecordChangeListeners()
2409
   private boolean registerRecordChangeListeners()
2404 2410
   {
2405 2411
      // Find for each compound query component the most outer scope among
2406 2412
      // nearest external scope and the outermost scopes of buffers used by
2407 2413
      // this component and register the component into this scope.
2408
      int externalScope = TransactionManager.findNearestExternal();
2414
      int externalScope = BufferManager.get().findNearestExternal();
2409 2415
      int lowestScope = externalScope;
2410 2416
      
2411 2417
      for (CompoundComponent comp : getComponents())
......
2428 2434
         }
2429 2435
      }
2430 2436
      
2431
      return lowestScope;
2437
      return lowestScope == 0;
2432 2438
   }
2433 2439
   
2434 2440
   /**
new/src/com/goldencode/p2j/persist/DataSet.java 2022-09-01 08:48:23 +0000
62 62
**     CA  20220106 Fixed CREATE-LIKE when relations are involved, their active flag was not being copied 
63 63
**                  properly.
64 64
**     OM  20220422 Allow Xml/JsonImport to load records into buffer without exposing package private methods.
65
**     CA  20220901 Refactored scope notification support: ScopeableFactory was removed, and the registration 
66
**                  is now specific to each type of scopeable.  For each case, the block will be registered 
67
**                  for scope support (for that particular scopeable) only when the scopeable is 'active' 
68
**                  (i.e. unnamed streams or accumulators are used).  This allows a lazy registration of 
69
**                  scopeables, to avoid the unnecessary overhead of processing all the scopeables for each
70
**                  and every block.
65 71
*/
66 72

  
67 73
/*
......
403 409
         throw new IllegalStateException("Parameter mode (INPUT/OUTPUT) was not specified!");
404 410
      }
405 411
      
412
      DataSetManager.registerScopeable();
413
      
406 414
      StaticDataSet localDS = (StaticDataSet) dsTarget;
407 415
      if (!dsSrc.isRemoteParameter())
408 416
      {
......
638 646
         throw new IllegalStateException("Parameter mode (INPUT/OUTPUT) was not specified!");
639 647
      }
640 648
      
649
      DataSetManager.registerScopeable();
650
      
641 651
      if (output)
642 652
      {
643 653
         TransactionManager.registerCurrent(dsHandle);
new/src/com/goldencode/p2j/persist/DataSetManager.java 2022-09-01 08:51:46 +0000
2 2
** Module   : DataSetManager.java
3 3
** Abstract : Manages all the DataSets, taking care for matching shared ones. 
4 4
**
5
** Copyright (c) 2019-2020, Golden Code Development Corporation.
5
** Copyright (c) 2019-2022, Golden Code Development Corporation.
6 6
**
7 7
** -#- -I- --Date-- ---------------------------------Description---------------------------------
8 8
** 001 OM  20190403 Created initial version.
......
11 11
**     OM  20190731 Added REFERENCE-ONLY support.
12 12
** 004 CA  20200110 More fixes for DATASET parameters and resource delete.
13 13
** 005 CA  20201003 Allow dictionaries with an identity map.
14
**     CA  20220901 Refactored scope notification support: ScopeableFactory was removed, and the registration 
15
**                  is now specific to each type of scopeable.  For each case, the block will be registered 
16
**                  for scope support (for that particular scopeable) only when the scopeable is 'active' 
17
**                  (i.e. unnamed streams or accumulators are used).  This allows a lazy registration of 
18
**                  scopeables, to avoid the unnecessary overhead of processing all the scopeables for each
19
**                  and every block.
14 20
*/
15 21

  
16 22
/*
......
70 76

  
71 77
import com.goldencode.p2j.security.*;
72 78
import com.goldencode.p2j.util.*;
79
import com.goldencode.p2j.util.Scopeable.ScopeId;
73 80

  
74 81
import java.util.*;
75 82

  
......
116 123
   
117 124
   /** A dictionary of BY-REFERENCE dataset parameters. */
118 125
   private final ScopedDictionary<DataSet, Integer> byReferenceParameters = new ScopedDictionary<>();
126

  
127
   /** The transaction helper. */
128
   private final TransactionManager.TransactionHelper tm;
119 129
   
120 130
   /**
121 131
    * Default c'tor.  Marks dictionaries which can use identity maps.
122 132
    */
123 133
   private DataSetManager()
124 134
   {
135
      tm = TransactionManager.getTransactionHelper();
125 136
      dshOutputParams.setIdentityKeys(true);
126 137
      byReferenceParameters.setIdentityKeys(true);
138
      
139
      // there is a bug with static datasets: instead of registering as 'pending' for next scope, they are
140
      // registering in the callee's scope... so, for now, push an 'implicit' scope here.
141
      scopeStart();
127 142
   }
128 143
   
129 144
   /**
......
152 167
      return instance.get();
153 168
   }
154 169
   
155
   
156 170
   /**
157
    * Register with the {@link com.goldencode.p2j.util.TransactionManager
158
    * TransactionManager} a factory object which creates instances of this
159
    * class, so that they can be registered to receive notifications of
160
    * runtime scope start and finish events.
161
    * <p>
162
    * This method should be invoked once during the server bootstrap phase.
171
    * Register the {@link DataSetManager} for scope notifications at the current block.
163 172
    */
164
   static void initialize()
173
   public static void registerScopeable()
165 174
   {
166
      TransactionManager.registerScopeableFactory(DataSetManager::instance);
175
      DataSetManager mgr = instance();
176
      mgr.tm.registerBlockScopeable(mgr);
167 177
   }
168 178
   
169 179
   /**
......
180 190
    */
181 191
   public void register(DataSet dataSet, String legacyName, boolean isShared, boolean isNew)
182 192
   {
193
      tm.registerPendingScopeable(this);
194
      
183 195
      if (!dataSet._dynamic())
184 196
      {
185 197
         registry.addEntry(false, legacyName.toLowerCase(), dataSet);
......
252 264
   }
253 265
   
254 266
   /**
267
    * Get the {@link ScopeId} for the instance.
268
    * 
269
    * @return   {@link ScopeId#DATA_SET_MANAGER}.
270
    */
271
   @Override
272
   public ScopeId getScopeId()
273
   {
274
      return ScopeId.DATA_SET_MANAGER;
275
   }
276
   
277
   /**
255 278
    * Check if the given dataset is passed as a BY-REFERENCE parameter.
256 279
    * 
257 280
    * @param    ds
new/src/com/goldencode/p2j/persist/Persistence.java 2022-09-01 08:47:44 +0000
569 569
**     IAS 20220608          Provide additional information in reportUDFVersion().
570 570
**     IAS 20220712          Create missing UDFs
571 571
**     IAS 20220816          Do not use 'udf' schema for non-PostgreSQL UDFs
572
**     CA  20220901          Refactored scope notification support: ScopeableFactory was removed, and the 
573
**                           registration is now specific to each type of scopeable.  For each case, the block
574
**                           will be registered for scope support (for that particular scopeable) only when
575
**                           the scopeable is 'active' (i.e. unnamed streams or accumulators are used).  This
576
**                           allows a lazy registration of scopeables, to avoid the unnecessary overhead of
577
**                           processing all the scopeables for each and every block.
572 578
*/
573 579

  
574 580
/*
......
819 825
    * Initialize various infrastructure components of the persistence framework:
820 826
    * <ul>
821 827
    *   <li>{@code DataTypeHelper}, which is used when preprocessing FQL where clauses.
822
    *   <li>{@code BufferManager}, which tracks open buffers and transactions.
823
    *   <li>{@code ChangeBroker}, which dispatches notifications about changes to DMO properties.
824 828
    *   <li>{@code DatabaseManager}, which configures the ORM environment for the databases
825 829
    *       to which the framework connects.
826 830
    *   <li>{@code P2OLookup}, instances of which are used for runtime, on-the-fly query and
......
835 839
    *          if any error is encountered initializing the persistence framework.
836 840
    *
837 841
    * @see     DataTypeHelper#initialize()
838
    * @see     BufferManager#initialize()
839
    * @see     ChangeBroker#initialize()
840 842
    * @see     DatabaseManager#initialize()
841 843
    * @see     TemporaryDatabaseManager#initialize()
842
    * @see     DataSetManager#initialize()
843 844
    * @see     P2OLookup#initialize()
844 845
    */
845 846
   public static void initialize()
846 847
   throws PersistenceException
847 848
   {
848 849
      DataTypeHelper.initialize();
849
      BufferManager.initialize();
850
      ChangeBroker.initialize();
851 850
      TemporaryDatabaseManager.initialize();
852 851
      DatabaseManager.initialize();
853
      DataSetManager.initialize();
854 852
      
855 853
      // if runtime conversion services are required, initialize schema lookup resources
856 854
      if (ConversionPool.isInitialized())
new/src/com/goldencode/p2j/persist/RecordBuffer.java 2022-09-01 08:47:37 +0000
1217 1217
**                           must be used, as the buffer instance may be proxied.  Fixed OM/20220707.
1218 1218
**     OM  20220809          Use a temporary virtual scope while invoking the db triggers to block the 
1219 1219
**                           release() to be recursively invoked at the end of a trigger().
1220
**     CA  20220901          Refactored scope notification support: ScopeableFactory was removed, and the 
1221
**                           registration is now specific to each type of scopeable.  For each case, the block
1222
**                           will be registered for scope support (for that particular scopeable) only when
1223
**                           the scopeable is 'active' (i.e. unnamed streams or accumulators are used).  This
1224
**                           allows a lazy registration of scopeables, to avoid the unnecessary overhead of
1225
**                           processing all the scopeables for each and every block.
1220 1226
*/
1221 1227

  
1222 1228
/*
......
3783 3789
               }
3784 3790
               
3785 3791
               // heuristically convert from SQL name to legacy name
3786
               Iterator<Property> fields = buffer.dmoInfo.getFields(false);
3792
               Iterator<Property> fields = buffer.getDmoInfo().getFields(false);
3787 3793
               while (fields.hasNext())
3788 3794
               {
3789 3795
                  Property prop = fields.next();
......
3940 3946
      BufferReference srcProxy = (BufferReference) srcDmo;
3941 3947
      RecordBuffer srcBuf = srcProxy.buffer();
3942 3948
      RecordBuffer dstBuf = dstProxy.buffer();
3949
      dstBuf.bufferManager.registerDirtyBuffer(dstBuf);
3943 3950
      
3944 3951
      srcBuf.initialize();
3945 3952
      dstBuf.initialize();
......
4231 4238
         return new logical(false);
4232 4239
      }
4233 4240
      
4241
      dstBuf.bufferManager.registerDirtyBuffer(dstBuf);
4242
      
4234 4243
      boolean created = false;
4235 4244
      Record dstRec = dstBuf.getCurrentRecord();
4236 4245
      if (dstRec == null)
......
7549 7558
    */
7550 7559
   protected void openScopeAt(int blockDepth)
7551 7560
   {
7561
      // TODO: blockDepth param is always zero...
7562
      
7552 7563
      // Register this scope with the buffer manager.
7553 7564
      bufferManager.openScopeAt(blockDepth, this);
7554 7565
      
new/src/com/goldencode/p2j/persist/trigger/DatabaseTriggerManager.java 2022-09-01 08:49:05 +0000
55 55
**     TW  20220803          Error-status:error must be set for return error in method, while return error
56 56
**                           in old-style ABL function must remain the same. Refs: #6567.
57 57
**     TW  20220817          Error-status:error must be set for return error in static method.
58
**     CA  20220901          Refactored scope notification support: ScopeableFactory was removed, and the 
59
**                           registration is now specific to each type of scopeable.  For each case, the block
60
**                           will be registered for scope support (for that particular scopeable) only when
61
**                           the scopeable is 'active' (i.e. unnamed streams or accumulators are used).  This
62
**                           allows a lazy registration of scopeables, to avoid the unnecessary overhead of
63
**                           processing all the scopeables for each and every block.
58 64
*/
59 65

  
60 66
/*
......
117 123
import com.goldencode.p2j.security.*;
118 124
import com.goldencode.p2j.util.*;
119 125
import com.goldencode.p2j.util.LogHelper;
126
import com.goldencode.p2j.util.Scopeable.ScopeId;
127

  
120 128
import java.lang.reflect.*;
121 129
import java.util.*;
122 130
import java.util.logging.Level;
......
166 174
    */
167 175
   private DatabaseTriggerManager()
168 176
   {
169
      // I want to receive enter/leave bloc events
170
      tm.registerScopeable(this);
171 177
      if (LOG.isLoggable(Level.FINE))
172 178
      {
173 179
         LOG.log(Level.FINE, "DatabaseTriggerManager registered with TransactionManager.");
......
456 462
                                              boolean hasOldBuffer)
457 463
   {
458 464
      DatabaseTriggerManager manager = get();
465
      manager.tm.registerTopLevelScopeable(manager);
466
      
459 467
      if (manager.stack.isEmpty())
460 468
      {
461 469
         // sanity check failed
......
558 566
         throw new IllegalArgumentException("Use this form of register only for ASSIGN triggers.");
559 567
      }
560 568
      DatabaseTriggerManager manager = get();
569
      manager.tm.registerTopLevelScopeable(manager);
570
      
561 571
      if (manager.stack.isEmpty())
562 572
      {
563 573
         // sanity check failed
......
601 611
      }
602 612
      
603 613
      DatabaseTriggerManager manager = get();
614
      manager.tm.registerTopLevelScopeable(manager);
615
      
604 616
      if (manager.stack.isEmpty())
605 617
      {
606 618
         // sanity check failed
......
633 645
      }
634 646
      
635 647
      DatabaseTriggerManager manager = get();
648
      manager.tm.registerTopLevelScopeable(manager);
649
      
636 650
      if (manager.stack.isEmpty())
637 651
      {
638 652
         // sanity check failed
......
656 670
   public static boolean disableDumpTriggers(Class<? extends Buffer> bufferCls)
657 671
   {
658 672
      DatabaseTriggerManager manager = get();
673
      manager.tm.registerTopLevelScopeable(manager);
674
      
659 675
      if (manager.stack.isEmpty())
660 676
      {
661 677
         return false;
......
697 713
                                             boolean allowReplication)
698 714
   {
699 715
      DatabaseTriggerManager manager = get();
716
      manager.tm.registerTopLevelScopeable(manager);
717
      
700 718
      if (manager.stack.isEmpty())
701 719
      {
702 720
         return false;
......
910 928
   public void scopeStart()
911 929
   {
912 930
      // triggers get notifications at all top level blocks
913
      if (tm.isTopLevelBlock())
914
      {
915
         stack.addFirst(new TriggerBlockLayer()); // push();
916
      }
931
      stack.addFirst(new TriggerBlockLayer()); // push();
917 932
   }
918 933
   
919 934
   /**
......
926 941
   }
927 942
   
928 943
   /**
944
    * Get the {@link ScopeId} for the instance.
945
    * 
946
    * @return   {@link ScopeId#DATABASE_TRIGGER_MANAGER}.
947
    */
948
   @Override
949
   public ScopeId getScopeId()
950
   {
951
      return ScopeId.DATABASE_TRIGGER_MANAGER;
952
   }
953
   
954
   /**
929 955
    * Provides a notification that a scope is about to be exited. The manager only acts on
930 956
    * top-level scope. Each time a scope is exited a the last layer of triggers is removed from
931 957
    * internal stack.
......
934 960
   public void scopeFinished()
935 961
   {
936 962
      // triggers get notifications at all top level blocks
937
      if (tm.isTopLevelBlock())
938
      {
939
         if (stack.isEmpty())
940
         {
941
            LOG.log(Level.WARNING, "Invalid scope finished.");
942
         }
943
         else
944
         {
945
            stack.removeFirst(); // pop();
946
         }
963
      if (stack.isEmpty())
964
      {
965
         LOG.log(Level.WARNING, "Invalid scope finished.");
966
      }
967
      else
968
      {
969
         stack.removeFirst(); // pop();
947 970
      }
948 971
   }
949 972
   
new/src/com/goldencode/p2j/ui/GenericFrame.java 2022-09-01 08:49:01 +0000
955 955
**                           widget is explicitly specified.
956 956
**     EVL 20220809          Fixed the regression from recent HIDDEN attribute reset change.  Only widgets
957 957
**                           defined in DISPLAY statement should be affected.
958
**     CA  20220901          Refactored scope notification support: ScopeableFactory was removed, and the 
959
**                           registration is now specific to each type of scopeable.  For each case, the block
960
**                           will be registered for scope support (for that particular scopeable) only when
961
**                           the scopeable is 'active' (i.e. unnamed streams or accumulators are used).  This
962
**                           allows a lazy registration of scopeables, to avoid the unnecessary overhead of
963
**                           processing all the scopeables for each and every block.
958 964
*/
959 965

  
960 966
/*
......
1849 1855
   public Object invoke(Object proxy, Method method, Object[] args)
1850 1856
   throws Throwable
1851 1857
   {
1858
      // frame is accessed, register scopeable
1859
      TransactionManager.registerBlockScopeable(LogicalTerminal.getInstance());
1860
      
1852 1861
      int    op         = -1;
1853 1862
      String widgetName = null;
1854 1863

  
......
8721 8730
      // push down the screen definition
8722 8731
      if (force)
8723 8732
      {
8733
         TransactionManager.registerBlockScopeable(LogicalTerminal.getInstance());
8734

  
8724 8735
         // synchronous push
8725 8736
         ScreenDefinition[] sd = new ScreenDefinition[] {frameDef};
8726 8737
         LogicalTerminal.pushScreenDefinition(sd);
new/src/com/goldencode/p2j/ui/LogicalTerminal.java 2022-09-01 08:48:53 +0000
995 995
**     TW  20220803          Error-status:error must be set for return error in method, while return error
996 996
**                           in old-style ABL function must remain the same. Refs: #6567.
997 997
**     TW  20220817          Error-status:error must be set for return error in static method.
998
**     CA  20220901          Refactored scope notification support: ScopeableFactory was removed, and the 
999
**                           registration is now specific to each type of scopeable.  For each case, the block
1000
**                           will be registered for scope support (for that particular scopeable) only when
1001
**                           the scopeable is 'active' (i.e. unnamed streams or accumulators are used).  This
1002
**                           allows a lazy registration of scopeables, to avoid the unnecessary overhead of
1003
**                           processing all the scopeables for each and every block.
998 1004
*/
999 1005

  
1000 1006
/*
......
1078 1084
import com.goldencode.p2j.util.*;
1079 1085
import com.goldencode.p2j.util.ErrorManager;
1080 1086
import com.goldencode.p2j.util.ErrorManager.*;
1087
import com.goldencode.p2j.util.Scopeable.ScopeId;
1081 1088
import com.goldencode.p2j.util.LogHelper;
1082 1089
import com.goldencode.p2j.util.SocketImpl;
1083 1090
import com.goldencode.p2j.util.Text;
......
1703 1710
      }
1704 1711
      
1705 1712
      LogicalTerminal lt = locate();
1706
      lt.scopeTrack.forceHiding();
1713
      lt.forceHiding();
1707 1714
      lt.client.hideAll(noPause, targetWindowWorker(hWin, false));
1708 1715
      
1709 1716
      // TODO get frames from target window?
......
9364 9371
      
9365 9372
      LogicalTerminal lt = locate();
9366 9373
      
9367
      lt.scopeTrack.frameViewed(frame);
9374
      lt.frameViewed(frame);
9368 9375
      frame.setHadView();
9369 9376

  
9370 9377
      // refresh editable frames list
......
9405 9412
      
9406 9413
      LogicalTerminal lt = locate();
9407 9414
      
9408
      lt.scopeTrack.frameViewed(frame);
9415
      lt.frameViewed(frame);
9409 9416
      frame.setHadView();
9410 9417

  
9411 9418
      // refresh editable frames list
......
9519 9526
      ScreenBuffer[] frameBuf = (frame == null) ? null : lt.getEditableServerScreenBuffers(frame); 
9520 9527
      int          windowId = (frame == null) ? WindowConfig.RESOLVE_WINDOW : frame.getWindowId();
9521 9528
      
9522
      lt.scopeTrack.frameViewed(frame);
9529
      lt.frameViewed(frame);
9523 9530
      FieldGroup fg;
9524 9531
      if (frame != null)
9525 9532
      {
......
9549 9556
   {
9550 9557
      LogicalTerminal lt = locate();
9551 9558
      
9552
      lt.scopeTrack.frameViewed(frame);
9559
      lt.frameViewed(frame);
9553 9560
      
9554 9561
      view(frame.getFrameId(),
9555 9562
           lt.getEditableServerScreenBuffers(frame),
......
9577 9584
   {
9578 9585
      LogicalTerminal lt = locate();
9579 9586
      
9580
      lt.scopeTrack.frameViewed(frame);
9587
      lt.frameViewed(frame);
9581 9588
      
9582 9589
      view(frame.getFrameId(),
9583 9590
           lt.getEditableServerScreenBuffers(frame),
......
9625 9632
   {
9626 9633
      LogicalTerminal lt = locate();
9627 9634
      
9628
      lt.scopeTrack.frameViewed(frame);
9635
      lt.frameViewed(frame);
9629 9636
      
9630 9637
      WidgetConfig[] wcfgs = lt.client.view(frame.getFrameId(),
9631 9638
                                            lt.getEditableServerScreenBuffers(frame),
......
9669 9676
   {
9670 9677
      LogicalTerminal lt = locate();
9671 9678
      
9672
      lt.scopeTrack.frameViewed(frame);
9679
      lt.frameViewed(frame);
9673 9680
      
9674 9681
      FieldGroup fg = frame.getFieldGroup();
9675 9682
      
......
9724 9731
   {
9725 9732
      LogicalTerminal lt = locate();
9726 9733
      
9727
      lt.scopeTrack.frameViewed(frame);
9734
      lt.frameViewed(frame);
9728 9735
      
9729 9736
      WidgetConfig[] wcfgs = lt.client.view(frame.getFrameId(),
9730 9737
                                            lt.getEditableServerScreenBuffers(frame),
......
9760 9767
   {
9761 9768
      LogicalTerminal lt = locate();
9762 9769
      
9763
      lt.scopeTrack.frameViewed(frame);
9770
      lt.frameViewed(frame);
9764 9771
      
9765 9772
      view(frame.getFrameId(),
9766 9773
           frameBuf,
......
9810 9817
      // call the client
9811 9818
      try
9812 9819
      {
9813
         lt.scopeTrack.frameViewed(frame);
9820
         lt.frameViewed(frame);
9814 9821
         
9815 9822
         int[] tabItemList = frame.updateTabItemsList(widgetIds, UpdatesOp.PROMPT_FOR);
9816 9823
         
......
10155 10162
      // we haven't had the chance to mark the next partition yet because
10156 10163
      // scopeStart() won't be called until the business logic initializer
10157 10164
      // is complete
10158
      locate().level2definitions.add(frameDef);
10165
      LogicalTerminal lt = locate();
10166
      lt.level2definitions.add(frameDef);
10167
      lt.tm.registerPendingScopeable(lt);
10159 10168
   }
10160 10169

  
10161 10170
   /**
......
10171 10180
      // we haven't had the chance to mark the next partition yet because
10172 10181
      // scopeStart() won't be called until the business logic initializer
10173 10182
      // is complete
10174
      locate().level2descriptions.add(menuDescr);
10183
      LogicalTerminal lt = locate();
10184
      lt.level2descriptions.add(menuDescr);
10185
      lt.tm.registerPendingScopeable(lt);
10175 10186
   }
10176 10187
   
10177 10188
   /**
......
10193 10204
   public static void processDeferredPush(boolean fromLevel2)
10194 10205
   {
10195 10206
      LogicalTerminal lt = locate();
10207
      lt.tm.registerBlockScopeable(lt);
10208

  
10196 10209
      if (fromLevel2)
10197 10210
      {
10198 10211
         lt.definitions.markPartition();
......
11372 11385
    */
11373 11386
   static void deregisterFrame(int frameId)
11374 11387
   {
11375
      locate().deregisterFrameInt(frameId);
11388
      LogicalTerminal lt = locate();
11389
      lt.tm.registerBlockScopeable(lt);
11390

  
11391
      lt.deregisterFrameInt(frameId);
11376 11392
   }
11377 11393
   
11378 11394
   /**
......
11815 11831
         return frameRegistry.get(frameId);
11816 11832
      }
11817 11833
   }
11834
   
11835
   /**
11836
    * Notify scope that frame is viewed.
11837
    * <p>
11838
    * This also registeres {@link LogicalTerminal} for scope notifications at the current block.
11839
    *  
11840
    * @param   frame
11841
    *          Frame which is about to be viewed.
11842
    */
11843
   private void frameViewed(GenericFrame frame)
11844
   {
11845
      tm.registerBlockScopeable(this);
11846
      
11847
      scopeTrack.frameViewed(frame);
11848
   }
11818 11849

  
11819 11850
   /**
11851
    * Clear map of viewed frames.
11852
    * <p>
11853
    * This also registeres {@link LogicalTerminal} for scope notifications at the current block.
11854
    */
11855
   private void forceHiding()
11856
   {
11857
      tm.registerBlockScopeable(this);
11858
      
11859
      scopeTrack.forceHiding();
11860
   }
11861
   
11862
   /**
11820 11863
    * Save the {@link UIStatement} running for each registered frame.
11821 11864
    * 
11822 11865
    * @return   A map with each frame's UI statement.
......
13298 13341
   }
13299 13342
   
13300 13343
   /**
13301
    * Register with the {@link com.goldencode.p2j.util.TransactionManager TransactionManager} a
13302
    * factory object which creates instances of this class, so that they can be registered to
13303
    * receive notifications of runtime scope start and finish events.
13304
    * <p>
13305
    * This method should be invoked once during the server bootstrap phase.
13306
    * <p>
13307
    * The registered factory functions conditionally. It uses the {@link 
13308
    * TransactionManager#_isHeadless()} to check whether the context has been declared headless.
13309
    */
13310
   public static void initialize()
13311
   {
13312
      TransactionManager.registerScopeableFactory(
13313
         () -> TransactionManager._isHeadless() ? null : LogicalTerminal.locate() 
13314
      );
13315
   }
13316
   
13317
   /**
13318 13344
    * Process a notification that a new block scope is about to be entered.
13319 13345
    * <p>
13320 13346
    * In the Logical Terminal, a new top level block scope causes creation of
......
13325 13351
   @Override
13326 13352
   public void scopeStart()
13327 13353
   {
13354
      // scopeable registration is done in different places - if changes are made, ensure that scopeable 
13355
      // support is registered properly.
13356
      
13328 13357
      // register at each scope, it is important to instantiate the scope
13329 13358
      // processor BEFORE the state.interactions counter is reset below
13330 13359
      tm.registerFinalizable(new ScopeProcessor(), false);
......
13342 13371
         state.interactions = 0;
13343 13372
      }
13344 13373
      
13345
      // make sure that the global block gets a special notification - but only for non-appserver sessions.
13346
      if (tm.isGlobalBlock() && !tm.isRemote())
13347
      {
13348
         Finalizable cleaner = new Finalizable()
13349
         {
13350
            @Override
13351
            public void finished()
13352
            {
13353
               pauseBeforeEnd(tm.isProcessingQuit());
13354
            }
13355
            
13356
            @Override
13357
            public void iterate()
13358
            {
13359
               // nothing to do here 
13360
            }
13361
            
13362
            @Override
13363
            public void retry()
13364
            {
13365
               // nothing to do here 
13366
            }
13367
            
13368
            @Override
13369
            public void deleted()
13370
            {
13371
               // nothing to do here
13372
            }
13373
         };
13374
         
13375
         tm.registerFinalizable(cleaner, true);
13376
      }
13377

  
13378 13374
      // add a new scope for each top-level block
13379 13375
      if (tm.isTopLevelBlock())
13380 13376
      {
......
13463 13459
   }
13464 13460
   
13465 13461
   /**
13462
    * Get the {@link ScopeId} for the instance.
13463
    * 
13464
    * @return   {@link ScopeId#LOGICAL_TERMINAL}.
13465
    */
13466
   @Override
13467
   public ScopeId getScopeId()
13468
   {
13469
      return ScopeId.LOGICAL_TERMINAL;
13470
   }
13471
   
13472
   /**
13466 13473
    * Called by the protocol driver to obtain the latest state that should
13467 13474
    * be sent to the other side of the connection.  This is called just 
13468 13475
    * before a "real" message is sent and any changes provided will be
......
13589 13596
         
13590 13597
         if (cs.deregister != null)
13591 13598
         {
13599
            tm.registerBlockScopeable(this);
13600

  
13592 13601
            for (int i : cs.deregister)
13593 13602
            {
13594 13603
               deregisterFrameInt(i);
......
13605 13614
         
13606 13615
         if (cs.wrapped != null && scopeTrack != null)
13607 13616
         {
13617
            tm.registerBlockScopeable(this);
13618
            
13608 13619
            for (int id : cs.wrapped)
13609 13620
            {
13610 13621
               scopeTrack.frameWrapped(id);
new/src/com/goldencode/p2j/ui/MenuContainerWidget.java 2022-09-01 08:52:28 +0000
2 2
** Module   : MenuContainerWidget.java
3 3
** Abstract : The base class for MenuWidget and SubMenuWidget.
4 4
**
5
** Copyright (c) 2015-2020, Golden Code Development Corporation.
5
** Copyright (c) 2015-2022, Golden Code Development Corporation.
6 6
**
7 7
** -#- -I- --Date-- ---------------------------------Description----------------------------------
8 8
** 001 VIG 20150115 Created initial version.
......
34 34
**     EVL 20201021 More optimization for getAttr() usage or widget ID getting.
35 35
**     EVL 20201022 Optimized attributes flush implementation.
36 36
**     CA  20201117 Do not use resourceDelete to delete the widget - use the delete() API for this code.
37
**     CA  20220901 Refactored scope notification support: ScopeableFactory was removed, and the registration 
38
**                  is now specific to each type of scopeable.  For each case, the block will be registered 
39
**                  for scope support (for that particular scopeable) only when the scopeable is 'active' 
40
**                  (i.e. unnamed streams or accumulators are used).  This allows a lazy registration of 
41
**                  scopeables, to avoid the unnecessary overhead of processing all the scopeables for each
42
**                  and every block.
37 43
*/
38 44
/*
39 45
** This program is free software: you can redistribute it and/or modify
......
494 500
      // push down the screen definition
495 501
      if (force)
496 502
      {
503
         TransactionManager.registerBlockScopeable(LogicalTerminal.getInstance());
504

  
497 505
         // synchronous push
498 506
         MenuDescription[] sd = new MenuDescription[] {root.menuDef};
499 507
         LogicalTerminal.pushMenuDescription(sd);
new/src/com/goldencode/p2j/ui/TriggerManager.java 2022-09-01 08:48:45 +0000
56 56
**                           the resource gets deleted (including widgets).
57 57
**     CA  20210917          Javadoc fixes.
58 58
**     SBI 20220126          Fixed scopeFinished to add preserved events before all events from the target list.
59
**     CA  20220901          Refactored scope notification support: ScopeableFactory was removed, and the 
60
**                           registration is now specific to each type of scopeable.  For each case, the block
61
**                           will be registered for scope support (for that particular scopeable) only when
62
**                           the scopeable is 'active' (i.e. unnamed streams or accumulators are used).  This
63
**                           allows a lazy registration of scopeables, to avoid the unnecessary overhead of
64
**                           processing all the scopeables for each and every block.
59 65
*/
60 66

  
61 67
/*
......
190 196
                               EventList             events, 
191 197
                               int                   tid)
192 198
   {
199
      TransactionManager.registerBlockScopeable(LogicalTerminal.getInstance());
200

  
193 201
      events.setTriggerId(tid);
194 202

  
195 203
      // insert the latest trigger def at the front of the list. all created triggers are saved,
......
261 269
   @SuppressWarnings("unchecked")
262 270
   public static void deregister(ScopedDictionary<?,?> registry, EventList el)
263 271
   {
272
      TransactionManager.registerBlockScopeable(LogicalTerminal.getInstance());
273

  
264 274
      LinkedList<EventList> registryScope = null;
265 275

  
266 276
      // DEBUG: System.err.printf("DEREGISTER\nBEFORE %s", dumpRegistry(registry));
new/src/com/goldencode/p2j/util/AbstractParameter.java 2022-09-01 08:54:12 +0000
3 3
** Abstract : Common logic for assigns [input-]output parameter values (database fields and normal
4 4
**            variables) upon exit from procedure/function
5 5
**
6
** Copyright (c) 2015-2021, Golden Code Development Corporation.
6
** Copyright (c) 2015-2022, Golden Code Development Corporation.
7 7
**
8 8
** -#- -I- --Date-- ---------------------------------------Description----------------------------------------
9 9
** 001 OM  20150702 First version based on extracted code form AbstractSimpleParameter and
......
18 18
**                  in the parameter instance must be replaced.
19 19
**     CA  20210609 Reworked INPUT/INPUT-OUTPUT parameters to a new approach, where they are explicitly 
20 20
**                  initialized at the method's execution, and not at the caller's arguments.
21
**     CA  20220901 Refactored scope notification support: ScopeableFactory was removed, and the registration 
22
**                  is now specific to each type of scopeable.  For each case, the block will be registered 
23
**                  for scope support (for that particular scopeable) only when the scopeable is 'active' 
24
**                  (i.e. unnamed streams or accumulators are used).  This allows a lazy registration of 
25
**                  scopeables, to avoid the unnecessary overhead of processing all the scopeables for each
26
**                  and every block.
21 27
*/
22 28
/*
23 29
** This program is free software: you can redistribute it and/or modify
......
76 82

  
77 83
import com.goldencode.p2j.persist.*;
78 84
import com.goldencode.p2j.security.*;
85
import com.goldencode.p2j.util.Scopeable.ScopeId;
86

  
79 87
import java.lang.reflect.*;
80 88
import java.util.*;
81 89
import java.util.logging.*;
......
338 346
      }
339 347
      
340 348
      /**
349
       * Get the {@link ScopeId} for the instance.
350
       * 
351
       * @return   <code>null</code>, as the notification is done via {@link BufferManager}.
352
       */
353
      @Override
354
      public ScopeId getScopeId()
355
      {
356
         // no explicit registration is done, this is called via BufferManager
357
         return null;
358
      }
359
      
360
      /**
341 361
       * Get the object which manages field assigners for the current scope.
342 362
       *
343 363
       * @return  Current scope.
new/src/com/goldencode/p2j/util/Accumulator.java 2022-09-01 08:54:09 +0000
2 2
** Module   : Accumulator.java
3 3
** Abstract : Abstract base class for concrete accumulator implementations
4 4
**
5
** Copyright (c) 2004-2019, Golden Code Development Corporation.
5
** Copyright (c) 2004-2022, Golden Code Development Corporation.
6 6
**
7 7
** -#- -I- --Date-- --JPRM-- -----------------------------Description-----------------------------
8 8
** 001 ECF 20051227   @23778 Created initial version. Base class for
......
117 117
**                           when reset() called without accumulate().
118 118
** 028 CA  20190326          Implemented TransactionHelper instead of direct usage of the static   
119 119
**                           API.  This allows the elimination of context local usage in TM.
120
** 029 CA  20220901          Refactored scope notification support: ScopeableFactory was removed, and the 
121
**                           registration is now specific to each type of scopeable.  For each case, the block
122
**                           will be registered for scope support (for that particular scopeable) only when
123
**                           the scopeable is 'active' (i.e. unnamed streams or accumulators are used).  This
124
**                           allows a lazy registration of scopeables, to avoid the unnecessary overhead of
125
**                           processing all the scopeables for each and every block.
120 126
*/
121 127
/*
122 128
** This program is free software: you can redistribute it and/or modify
......
176 182
import java.lang.reflect.*;
177 183
import java.util.*;
178 184

  
185
import com.goldencode.p2j.util.Scopeable.ScopeId;
186

  
179 187
/**
180 188
 * Abstract base class for all accumulators.  An accumulator collects one
181 189
 * piece of data upon each pass through an iterative loop and calculates a
......
1099 1107
   {
1100 1108
      // no-op
1101 1109
   }
1110
   
1111
   /**
1112
    * Get the {@link ScopeId} for the instance.
1113
    * 
1114
    * @return   <code>null</code>, as the scope notification is done via {@link AccumulatorManager}.
1115
    */
1116
   @Override
1117
   public ScopeId getScopeId()
1118
   {
1119
      // no ID necessary, as it does not get registered explicitly, is called via AccumulatorManager
1120
      return null;
1121
   }
1102 1122

  
1103 1123
   /**
1104 1124
    * Process a notification that a new block scope has been entered. Each 
new/src/com/goldencode/p2j/util/AccumulatorManager.java 2022-09-01 08:53:49 +0000
2 2
** Module   : AccumulatorManager.java
3 3
** Abstract : provides block-behavior for the accumulators.
4 4
**
5
** Copyright (c) 2008-2021, Golden Code Development Corporation.
5
** Copyright (c) 2008-2022, Golden Code Development Corporation.
6 6
**
7 7
** -#- -I- --Date-- -T- --JPRM-- ----------------Description-----------------
8 8
** 001 CA  20080129   @37024 Created initial version. Provides context
......
33 33
** 010 CA  20200930          Refactored to remove the singleton scopeable instance (which forced the scope 
34 34
**                           notifications to use context-local state).
35 35
**     CA  20210310          Small performance improvement.
36
**     CA  20220901          Refactored scope notification support: ScopeableFactory was removed, and the 
37
**                           registration is now specific to each type of scopeable.  For each case, the block
38
**                           will be registered for scope support (for that particular scopeable) only when
39
**                           the scopeable is 'active' (i.e. unnamed streams or accumulators are used).  This
40
**                           allows a lazy registration of scopeables, to avoid the unnecessary overhead of
41
**                           processing all the scopeables for each and every block.
36 42
*/
37 43
/*
38 44
** This program is free software: you can redistribute it and/or modify
......
91 97

  
92 98
import java.util.*;
93 99
import com.goldencode.p2j.security.ContextLocal;
100
import com.goldencode.p2j.util.Scopeable.ScopeId;
94 101

  
... This diff was truncated because it exceeds the maximum size that can be displayed.