空元素的 LDAP 事件过滤器
LDAP Event Filter For Null Element
我的事件属性中有一个列表,其中的元素可能为空。我想创建一个 LDAP 字符串来匹配空元素。
考虑这个工作示例:
private final BundleContext context = FrameworkUtil.getBundle(LdapTest.class).getBundleContext();
private final EventAdmin eventAdmin = this.context.getService(this.context.getServiceReference(EventAdmin.class));
@Test
public void test() throws Exception {
final String value = "test";
// register a listener
final Dictionary<String, Object> serviceProperties = new Hashtable<>();
serviceProperties.put(EventConstants.EVENT_TOPIC, new String[] { "myTopic" });
serviceProperties.put(EventConstants.EVENT_FILTER, "(myProperty=" + value + ")");
final boolean[] called = { false };
final ServiceRegistration<EventHandler> listener = this.context.
registerService(EventHandler.class, e -> called[0] = true, serviceProperties);
// fire event
Assert.assertFalse(called[0]);
final Map<String, Object> eventProperties = new HashMap<>();
eventProperties.put("myProperty", Arrays.asList(value));
this.eventAdmin.sendEvent(new Event("myTopic", eventProperties));
Assert.assertTrue(called[0]);
listener.unregister();
}
现在,如果我设置 value = null
,EVENT_FILTER
必须是什么样子才能使测试再次工作?
我尝试了“(!myProperty=*)
”和“(!(myProperty=*))
”,但没有用。
如果设置了 属性,则 LDAP 过滤器表达式 (myProperty=*)
的计算结果为真,否则为假。在 LDAP 过滤器表达式中无法测试空值。如果事件具有空值,我建议不要设置事件 属性。
使用类似于以下的过滤器可能会取得一些成功:
(myProperty=[=10=])
“\00”是空的转义序列。
其中一些取决于 "null" 是否是值中唯一的东西。
我们遇到过来自 SQL 数据存储的值将以空值结尾并且能够使用该过滤器的情况。
如果 "null" 在属性值范围内(比如 Tom<"null">Smith),除了以二进制形式读取属性值并解析字符以寻找"nulls".
-吉姆
如果有人有类似的问题,我现在就是这样解决的。
我添加了第二个 属性 来保存 null
值是否存在的信息:
List<String> values = //...
eventProperties.put("myProperty", values);
eventProperties.put("myProperty.hasNull", values.contains(null));
所以我可以使用这个新的 属性:
进行查询
serviceProperties.put(EventConstants.EVENT_FILTER,
value == null ? "(myProperty.hasNull=true)" : "(myProperty=" + value + ")");
它并不完美,但它完成了工作。
我的事件属性中有一个列表,其中的元素可能为空。我想创建一个 LDAP 字符串来匹配空元素。
考虑这个工作示例:
private final BundleContext context = FrameworkUtil.getBundle(LdapTest.class).getBundleContext();
private final EventAdmin eventAdmin = this.context.getService(this.context.getServiceReference(EventAdmin.class));
@Test
public void test() throws Exception {
final String value = "test";
// register a listener
final Dictionary<String, Object> serviceProperties = new Hashtable<>();
serviceProperties.put(EventConstants.EVENT_TOPIC, new String[] { "myTopic" });
serviceProperties.put(EventConstants.EVENT_FILTER, "(myProperty=" + value + ")");
final boolean[] called = { false };
final ServiceRegistration<EventHandler> listener = this.context.
registerService(EventHandler.class, e -> called[0] = true, serviceProperties);
// fire event
Assert.assertFalse(called[0]);
final Map<String, Object> eventProperties = new HashMap<>();
eventProperties.put("myProperty", Arrays.asList(value));
this.eventAdmin.sendEvent(new Event("myTopic", eventProperties));
Assert.assertTrue(called[0]);
listener.unregister();
}
现在,如果我设置 value = null
,EVENT_FILTER
必须是什么样子才能使测试再次工作?
我尝试了“(!myProperty=*)
”和“(!(myProperty=*))
”,但没有用。
如果设置了 属性,则 LDAP 过滤器表达式 (myProperty=*)
的计算结果为真,否则为假。在 LDAP 过滤器表达式中无法测试空值。如果事件具有空值,我建议不要设置事件 属性。
使用类似于以下的过滤器可能会取得一些成功:
(myProperty=[=10=])
“\00”是空的转义序列。 其中一些取决于 "null" 是否是值中唯一的东西。 我们遇到过来自 SQL 数据存储的值将以空值结尾并且能够使用该过滤器的情况。
如果 "null" 在属性值范围内(比如 Tom<"null">Smith),除了以二进制形式读取属性值并解析字符以寻找"nulls".
-吉姆
如果有人有类似的问题,我现在就是这样解决的。
我添加了第二个 属性 来保存 null
值是否存在的信息:
List<String> values = //...
eventProperties.put("myProperty", values);
eventProperties.put("myProperty.hasNull", values.contains(null));
所以我可以使用这个新的 属性:
进行查询serviceProperties.put(EventConstants.EVENT_FILTER,
value == null ? "(myProperty.hasNull=true)" : "(myProperty=" + value + ")");
它并不完美,但它完成了工作。