public sealed interface CompileContext
What every compilation of a rule list is given: the imports the engine was built with, from RulesEngineBuilder.imports(String...), the class loader to look classes up with, the type of the output object, this language's options and its own imports, and a way to report warnings. A language uses what it needs and ignores the rest.

Implemented by the engine, which passes it to a language. It's sealed, so a language can't implement it; a language's unit tests create one with io.github.brantunger.unruly.test.LanguageTestContexts, from the unruly-engine-test artifact. Because only the engine implements it, a later release can add methods to it without breaking languages.

  • Method Details

    • packageImports

      Set<String> packageImports()
      Returns the imported packages, whose classes rules can refer to by their simple names.
      Returns:
      Package names such as java.util; unmodifiable
    • classImports

      Set<Class<?>> classImports()
      Returns the classes imported one by one.
      Returns:
      The classes; unmodifiable
    • classLoader

      ClassLoader classLoader()
      Returns the class loader to look up classes in packageImports() with: the context class loader of the thread that called load(), or the engine's own class loader if that thread has none.
      Returns:
      The class loader, never null
    • outputType

      Class<?> outputType()
      Returns the type of the output object, which the engine was built with through RulesEngineBuilder.outputType(Class). A language may use it, for example to check the properties its actions return; the engine doesn't.
      Returns:
      The output type, or Object if the engine wasn't told one
    • declaredFacts

      Map<String,Class<?>> declaredFacts()
      Returns the facts the engine was declared with, through RulesEngineBuilder.fact(String, Class), by fact name. A language may check its expressions against them, for example to reject a misspelled property when the rules load, or ignore them; the engine checks a run's values against them whatever the language does. A fact declared with a primitive type, such as int, is given as its wrapper, Integer.

      A declared type is what the value a language is given is an instance of; for a fact declared with a primitive type, the engine first widens a narrower boxed primitive the run supplied, as RulesEngineBuilder.fact(String, Class) describes. It isn't a promise that the fact is present, unless allFactsDeclared() is true.

      Returns:
      The declared type of each fact, by name, empty if the engine was told none; unmodifiable
    • allFactsDeclared

      boolean allFactsDeclared()
      Returns whether a run may supply only the facts in declaredFacts(), which the engine was told with RulesEngineBuilder.requireDeclaredFacts(). When it's true, every name a rule can legitimately refer to is declared, so a language may reject an expression that refers to anything else. When it's false, a run may supply facts nobody declared, so an undeclared name isn't a mistake.
      Returns:
      true if every fact a run may supply is declared
    • options

      Map<String,String> options()
      Returns this language's options, set with RulesEngineBuilder.option(String, String, String). What an option means is up to the language.
      Returns:
      The values by option name, empty if this language was given none; unmodifiable
    • languageImports

      default List<String> languageImports()
      Returns the imports given for this language only, with RulesEngineBuilder.languageImports(String, String...), as written and in order, duplicates included. The engine doesn't resolve or check them, beyond their length, and the engine's other languages don't see them. What one means, such as a module, a file or a namespace, is up to the language, which can reject one it can't use by throwing from ExpressionLanguage.newCompiler(CompileContext). The engine creates a language's compiler when a rule list given to load() or validate() has a rule in that language, and creates the default language's compiler for a list with no rules too. A throw from newCompiler then fails that rule list: load() throws, and validate() returns, a RuleCompilationException with the throw as its cause. A language no such rule list uses never has its imports checked.

      Unlike packageImports() and classImports(), which hold the engine's Java imports for every language, these suit a language whose imports aren't Java classes or packages.

      Returns:
      The imports, empty if this language was given none; unmodifiable
    • warn

      void warn(Expression source, InvalidExpressionException.Issue issue)
      Reports a problem that doesn't stop an expression compiling, such as use of a deprecated function. The engine logs it at WARN, naming the rule, whether the expression is its condition or its action, and where the problem is, and loading carries on. While the rules are only validated, with RulesEngine.validate(java.util.List), the warning is discarded. To stop the expression compiling, throw an InvalidExpressionException instead.
      Parameters:
      source - The expression the problem is in
      issue - The problem, reported as a warning whatever its severity
      Throws:
      NullPointerException - if source or issue is null