【发布时间】:2018-04-16 16:21:26
【问题描述】:
Out 产品与 Drools 集成,用户可以通过在一个简单的长滚动 JTextArea 中加载整个包并直接编辑一些 DRools 函数来从/向包添加/编辑/删除 Drools 函数;或者,更好的是,在使用其他工具(如 Notepad++)编辑后复制并粘贴整个包。 当新包被持久化时,我必须用它之前存储在数据库中的版本来解析它,并审计现有函数中的差异,或者插入/删除的函数。我已经有一个将 Drools 函数拆分为其组件的类,我在其中添加了这个方法来恢复要存储的函数的快照:
public String getFunctionCode() {
StringBuilder strBld = new StringBuilder("function ");
if (this.returnType == null)
strBld.append("void");
else
strBld.append(this.returnType);
strBld.append(" ");
strBld.append(this.name);
strBld.append("(");
if (this.paramNames != null && !this.paramNames.isEmpty()) {
int parametersSize = this.paramTypes.size();
for (int i = 0; i < parametersSize; i++) {
strBld.append(this.paramTypes.get(i).getName());
strBld.append(" ");
strBld.append(this.paramNames.get(i).getName());
if (i < parametersSize - 1)
strBld.append(",");
}
}
strBld.append(") {");
if (this.text == null || this.text.trim().isEmpty())
strBld.append(" ");
else
strBld.append(this.text);
strBld.append("}\r\n");
return strBld.toString();
}
其中paramNames 和paramTypes 只是一个包含函数签名的List<String>,而text 包含签名后两个主要{ } 之间的函数体。
即使用户添加或删除了另一个功能,有时也会检测到包的所有其他功能已编辑。为什么这个?这是因为一些不可打印的字符吗?
如果我将存储在 DB 上的两个快照与文本差异工具进行比较,则没有检测到任何内容。
为了获得改变的功能,我在一个 for 循环中做:
for (FunctionInfo functionInfo : updatedFunctions) {
FunctionInfo oldFunction = oldPackageInfo.getFunction(functionInfo.getName());
String oldFunctionBody = oldFunction.getFunctionCode();
String newFunctionBody = functionInfo.getFunctionCode();
if (!newFunctionBody.equals(oldFunctionBody)) {
/* persist an audit record */
}
}
其中updatedFunctions 是List<FunctionInfo>,它是通过检索旧的持久包和从前端到达的包之间的所有共同函数,在按名称排序后得到的。
可能是什么原因?
更新
我在调试模式下启动了 Wildfly,并在 Eclipse 上在前一个循环的 if 语句中设置了一个断点。然后,使用this online tool 进行文本差异我比较了oldFunctionBody 和newFunctionBody 的一个我没有从前端窗口编辑的函数。
事实证明,来自前端的旧未触及函数添加了一些不可打印的字符,总体上有许多\r。为什么会这样?
旧功能:
function void disableTestOnDevice(SampleBuilder sample,String devices,String[] devTestCode) {\r\n\t\t if(devices == null)\r\n\t\t\t return;\r\n\t if(sample.getListTransc() != null && sample.getListTransc().size() > 0){\t\r\n\t\t\t\tfor(int i = sample.getListTransc().size()-1; i >= 0; i--){\r\n\t\t\t\t\tViewWorklistBuilder j = (ViewWorklistBuilder)sample.getListTransc().get(i);\r\n\t\t\t\t\tif(j.getDeviceId() == null || j.getDeviceTestCode() == null || j.getDeviceSpecimenCode() == null){\r\n\t\t\t\t\t\tcontinue;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif(j.getDeviceId().equals(devices)){\r\n\t\t\t\t\t\tif(devTestCode != null){\r\n\t\t\t\t\t\t\tfor(int k = 0; k < devTestCode.length; k++){\r\n\t\t\t\t\t\t\t\tif(j.getDeviceTestCode().equals(devTestCode[k])){\r\n\t\t\t\t\t\t\t\t\tj.setEnabled(0);\r\n\t\t\t\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t\t\t\r\n\t\t\t\t}\r\n\t }\r\n\t\r\n
新功能:
function void disableTestOnDevice(SampleBuilder sample,String devices,String[] devTestCode) {\n\t\t if(devices == null)\n\t\t\t return;\n\t if(sample.getListTransc() != null && sample.getListTransc().size() > 0){\t\n\t\t\t\tfor(int i = sample.getListTransc().size()-1; i >= 0; i--){\n\t\t\t\t\tViewWorklistBuilder j = (ViewWorklistBuilder)sample.getListTransc().get(i);\n\t\t\t\t\tif(j.getDeviceId() == null || j.getDeviceTestCode() == null || j.getDeviceSpecimenCode() == null){\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif(j.getDeviceId().equals(devices)){\n\t\t\t\t\t\tif(devTestCode != null){\n\t\t\t\t\t\t\tfor(int k = 0; k < devTestCode.length; k++){\n\t\t\t\t\t\t\t\tif(j.getDeviceTestCode().equals(devTestCode[k])){\n\t\t\t\t\t\t\t\t\tj.setEnabled(0);\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t\t\n\t\t\t\t}\n\t }\n\t\r\n
【问题讨论】:
-
当您的代码检测到错误(错误)更改时,您能否尝试调试实例,它实际上比较了哪两个函数?
-
我试过了,功能完全一样。相同的名字和相同的签名。此外,如果我在 DB 表中打开 OLD_SNAPSHOT 和 NEW_FUNCTIONS 字段,它们包含与该函数名称相同的字符串
-
我不知道这是否可能,但如果这种情况有时会像您在问题中提到的那样发生,您可能会尝试找出对函数的哪种类型的更改会对其他人造成错误的更改检测。它可以提示进一步解决您的问题。
-
在比较字符串之前回答类似this的问题可能会有所帮助。
-
@EmreDalkiran :感谢您的建议,我刚刚开始考虑在比较函数体之前删除所有不可打印的字符......我希望它有所帮助。明天早上我会告诉你的
标签: java string drools stringbuilder string-comparison