在Drools中随时随地更新现有枚举常量的值

如何解决在Drools中随时随地更新现有枚举常量的值

我具有以下枚举结构,因此必须更改第二个参数 THREAT 的值。该应用程序几乎是已开发的,并且在很大程度上取决于枚举类型,并且该类型无法更改(由于大量的枚举变量)。重新启动应用程序时,我需要那里的认值。我有什么办法可以即时更改威胁的值?

enum TraceLevel {
   APP_DOS("as",""),APP_DOS1("as",APP_DOS2("as",APP_DOS3("as",APP_DOS4("as","");
   String NAME;
   String THREAT;

   private TraceLevel(String name,String threat) {
      this.NAME = name;
      this.THREAT = threat;
   }
}

更新1
根据评论,我认为我应该再更新一点问题。我基本上是在我有枚举常量的drools规则引擎上工作。那里的声明不是真的像Java。因此,我无法获得该如何做的信息。这是流口水的特定模式。

declare enum AttackCategory
APP_DOS("as","");
value : String
threat: String

end

解决方法

正如很多问题评论所言,您正试图以一种非设计或预期方式使用枚举。与大多数情况下一样,您可能会强迫它工作,但是您将遇到其他问题。正确的答案是,正如他们所说,回到制图板上,并提出一种解决方案,该解决方案不试图强迫枚举具有类行为。


(错误的)枚举方式

要更改枚举的值,请在声明中添加setter。在Java中,这样做是这样的:

enum TraceLevel {
   APP_DOS("as",""),...;
   String NAME;
   String THREAT;

   private TraceLevel(String name,String threat) {
      this.NAME = name;
      this.THREAT = threat;
   }

  public String getThreat() { return this.NAME; }
  public void setThreat(String name) { this.NAME = name; }
}

(还有一些小注释-“名称”和“威胁”的变量不应完全大写。它们应遵循常规变量的命名约定。)

另一方面,如果您正在使用Drools type declarations,则不要在这些结构上创建方法,而是Drools遵循bean约定生成getter和setter。正如您所指出的那样,这些约定不会在枚举中生成此类方法(应该暗示您试图以错误的方式使用它们。)

因此,如果必须使用枚举,则必须使用Java声明它们。


替代方法:类

您的用例似乎只是美化的常量,那么为什么不使用它作为替代方法呢?声明一个带有三个String变量(名称,线程,id)的类,然后在规则中将它们全部插入工作存储器并应用默认值。当确实需要使用它们时,可以根据需要在内存中更新它们。

declare TraceLevel
  id: String
  name: String
  threat: String
end

rule "Prepare default trace levels"
when
  not( TraceLevel() )
then
  insert( new TraceLevel("APP_DOS","as","") ) // equivalent to TraceLevel.APP_DOS
  insert( new TraceLevel("APP_DOS2","") )
  // etc.
end

rule "Example rule which needs to update a Threat value"
when
  $traceLevel: TraceLevel( id == "APP_DOS" )
then
  modify( $traceLevel ) { threat = "new threat value" }
end

第一个规则“准备默认跟踪级别”将默认级别插入到工作内存中。此时,工作存储器包含一组这些对象,这些对象在功能上与您的枚举值相同。由于它们处于工作记忆中,因此现在可用于所有随后评估的规则。

请注意,此规则的条件非常简单,并且可以验证工作内存中没有预先存在的TraceLevel实例-如果由于某种原因触发了完整的重新评估,这将使该规则无法执行多次。

第二个示例规则显示了如何使用modify rule action更新“威胁”值。

在所有情况下,我都添加了一个“ id”字段,以便您可以标识特定的TraceLevel实例。这些是TraceLevel枚举名称的等效项(例如TraceLevel.APP_DOS-> id =“ APP_DOS”)。第二个示例显示了如何利用此ID来获取特定的TraceLevel实例。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?