AbstractPatternWorker.java

/*
** Module   : AbstractPatternWorker.java
** Abstract : centralizes the most common init/term logic for pattern workers
**
** Copyright (c) 2005-2022, Golden Code Development Corporation.
**
** -#- -I- --Date-- --JPRM-- ----------------------------------Description-----------------------------------
** 001 GES 20050228   @20069 Created initial version supporting a
**                           resolver member, library registration and
**                           a default implementation of the
**                           PatternWorker interface.
** 002 ECF 20050228   @20090 Added methods to retrieve source and target
**                           ASTs currently being inspected.
** 003 ECF 20050310   @20272 Added default implementation of the
**                           resolveToLiteral method. Simply returns null.
** 004 ECF 20050315   @20345 Added default implementation of the visitAst
**                           method. Does nothing (required by
**                           PatternWorker interface).
** 005 ECF 20050328   @20515 Changed getTarget method to getCopy.
** 006 ECF 20050429   @20964 Changes related to namespace support for user
**                           functions and variables. Changed method
**                           signature for initialize and finish methods
**                           to match changes to PatternWorker interface.
**                           Pass this object as the namespace key when
**                           registering libraries.
** 007 ECF 20050525   @21290 Changes to support new expression engine
**                           implementation. Only a single library per
**                           pattern worker is now supported. Library
**                           registration now occurs in RuleContainer.
** 008 ECF 20080122   @37466 Plugged possible memory leak. Release resolver in finish().
** 009 ECF 20080730   @39263 Fixed possible memory leak. Release library in finish().
** 010 GES 20090518   @42383 Import change.
** 011 ECF 20130806          Added registerTree to register an arbitrary AST with the resolver.
** 012 CA  20200412          Added incremental conversion support.
** 013 CA  20211214          The AST manager plugin must be context-local, for runtime conversion, as the 
**                           InMemoryRegistryPlugin is not thread-safe.
**                           All worker's state must be context-local, for runtime conversion to work in 
**                           multi-context mode, as the pattern workers are singletons.
**     ECF 20220515          Removed no-op methods which are now defined as defaults in the PatternWorker
**                           interface.
*/
/*
** 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.pattern;

import com.goldencode.ast.*;

/**
 * Provides a default implementation of the most common initialization and 
 * termination logic for pattern engine worker classes.  This class is
 * abstract since it cannot do anything useful on its own.  It only exists
 * as an optional parent class for other pattern workers, to allow them to
 * be written without duplicating the most common logic that most (if not
 * all) workers would have to implement.
 * <p>
 * The most important usage note is that it is not possible for sub-classes
 * to pass the <code>libraries</code> array of <code>Object</code> instances 
 * (the list of exported libraries to register) in the constructor of a
 * super class.  For this reason, <b>a separate <code>setLibraries</code>
 * method has been provided which must be called in the sub-class'
 * constructor, after the <code>super</code> constructor has been
 * invoked.</b>
 */
public abstract class AbstractPatternWorker
implements PatternWorker
{
   /** Library object (exports functions/variables to rulesets) to register */
   private Object library = null;
   
   /**
    * Default constructor, which can only be called by a sub-class.
    */
   protected AbstractPatternWorker()
   {
   }
   
   /**
    * Check if the current mode is for runtime-conversion of query/tables.
    * 
    * @return   See above.
    */
   public boolean isRuntimeQueryMode()
   {
      return isConditionalRuleSets() && isFlagActivated("runtime-query");
   }
   
   /**
    * If conditional rule-set is enabled, check if the given flag is activated.
    * 
    * @param    flag
    *           The flag to check.
    *           
    * @return   See above.
    * 
    * @see      PatternEngine#isFlagActivated(String)
    */
   public boolean isFlagActivated(String flag)
   {
      return getResolver().getPatternEngine().isFlagActivated(flag);
   }
   
   /**
    * Check if conditional rule-sets is activated.
    * 
    * @return   See above.
    * 
    * @see      PatternEngine#isConditionalRuleSets
    */
   public boolean isConditionalRuleSets()
   {
      return getResolver().getPatternEngine().isConditionalRuleSets();
   }
   
   /**
    * Register the given tree with the AST resolver. This will register the AST and all its
    * descendants.
    * 
    * @param   ast
    *          Tree to register.
    */
   public void registerTree(Aast ast)
   {
      getResolver().registerTree(ast);
   }
   
   /**
    * Get the user function/property library exposed by this pattern worker.
    * 
    * @see com.goldencode.p2j.pattern.PatternWorker#getLibrary()
    */
   public Object getLibrary()
   {
      return library;
   }
   
   /**
    * This method is called each time the pattern engine needs to resolve
    * a string constant into a numeric, boolean, or string literal value.
    * <p>
    * It must return an object of the following type (or <code>null</code>):
    * <ul>
    * <li>Long
    * <li>Double
    * <li>Boolean
    * <li>String
    * </ul>
    
    * @param   constant
    *          A string representing a constant to be resolved.
    *
    * @return  This default implementation always returns <code>null</code>.
    */
   public Object resolveConstant(String constant)
   {
      return null;
   }
   
   /**
    * Sets the library that <b>must be registered</b>.  This can only be
    * called by a subclass. This <b>must be called from within the 
    * subclass' constructor.</b>
    *
    * @param    library
    *           Instance of exported libraries to be registered with the
    *           <code>resolver</code>.  <b>Must not</b> be <code>null</code>.
    *
    * @throws   IllegalArgumentException
    *           if <code>library</code> is <code>null</code>.
    */
   protected void setLibrary(Object library)
   {
      if (library == null)
      {
         throw new IllegalArgumentException("No library to register");
      }
      
      this.library = library;
   }
   
   /**
    * Get the current source AST. If called while the pattern engine is
    * processing init- or post-rules, this will always be the root of the
    * source AST. If called while the pattern engine is walking the tree,
    * this will be the source node currently being inspected.
    *
    * @return  The AST node from the source tree currently under inspection.
    */
   protected Aast getSource()
   {
      return getResolver().getSourceAst();
   }
   
   /**
    * Get the current copy AST. If called while the pattern engine is
    * processing init- or post-rules, this will always be the root of the
    * copy AST. If called while the pattern engine is walking the tree,
    * this will be the copy of the source node currently being inspected
    * Note that this could be a node which was removed from the tree by
    * some previous action.
    *
    * @return  The writable copy of the source AST node currently under
    *          inspection.
    */
   protected Aast getCopy()
   {
      return getResolver().getCopyAst();
   }
   
   /**
    * Get the {@link AstSymbolResolver} for the current context.
    * 
    * @return   See above.
    * 
    * @see   AstSymbolResolver#getResolver()
    */
   protected AstSymbolResolver getResolver()
   {
      return AstSymbolResolver.getResolver();
   }
}