波斯马BOSSMA Information Technology

基于RFC1960的属性过滤器 – C#版LDAPFilter

发布时间:2014年2月8日 / 分类:DOTNET / 9,122 次浏览 / 评论

这里说的属性是指某一个事物所具有的属性,但是其表现形式并不一定是高级语言中类的属性,比如一个人具有的属性:国家-中国;性别-男;年龄-28,这些属性可以对应类中的一个个属性,也可能是一个键值对集合,还可能只是一个字符串。

在JAVA的OSGI框架中实现了一个基于RFC1960的过滤器,使用特定的语法可以过滤对象、过滤服务,很是方便。

其语法比较简单,规则如下:

     <filter> ::= '(' <filtercomp> ')'
     <filtercomp> ::= <and> | <or> | <not> | <item>
     <and> ::= '&' <filterlist>
     <or> ::= '|' <filterlist>
     <not> ::= '!' <filter>
     <filterlist> ::= <filter> | <filter> <filterlist>
     <item> ::= <simple> | <present> | <substring>
     <simple> ::= <attr> <filtertype> <value>
     <filtertype> ::= <equal> | <approx> | <greater> | <less>
     <equal> ::= '='
     <approx> ::= '~='
     <greater> ::= '>='
     <less> ::= '<='
     <present> ::= <attr> '=*'
     <substring> ::= <attr> '=' <initial> <any> <final>
     <initial> ::= NULL | <value>
     <any> ::= '*' <starval>
     <starval> ::= NULL | <value> '*' <starval>
     <final> ::= NULL | <value>

示例:

     (cn=Babs Jensen)
     (!(cn=Tim Howes))
     (&(objectClass=Person)(|(sn=Jensen)(cn=Babs J*)))
     (o=univ*of*mich*)

 

在.net的开源源码中没有找到这个的实现,还好java语法和csharp相差不大,于是找到改造之。

OSGI中的实现:https://svn.apache.org/repos/asf/tuscany/sca-java-2.x/trunk/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/impl/LDAPFilter.java

C#版LDAPFilter:点此下载

使用例子:

Dictionary<string, object> dic = new Dictionary<string, object>();
dic.Add("country","china");
dic.Add("name", "bossma");
dic.Add("gender", "F");
dic.Add("student", true);
dic.Add("homepage", "http://bossma.cn");

LDAPFilter filter = LDAPFilter.Create("(country=china)");
bool result = filter.Match(dic);
Console.WriteLine(result);

LDAPFilter filter2 = LDAPFilter.Create("(country=american)");
bool result2 = filter2.Match(dic);
Console.WriteLine(result2);

bool result3 = LDAPFilter.Matches(dic, "(&(country=chin*)(student=true))");
Console.WriteLine(result3);

bool result4 = LDAPFilter.Matches(dic, "(&(&(country=chin*)(student=true))(!(name=li*)))");
Console.WriteLine(result4);

bool result5 = LDAPFilter.Matches(dic, "(&(&(country=chin*)(student=true))(name=boss*))");
Console.WriteLine(result5);

两种使用方法:调用实例对象的方法;直接调用静态方法。用起来还是挺方便的,只是过滤的语法需要好好学习一下。

看一下这两种方法的实现。

1、直接调用静态方法

/// <summary>
/// 返回dictionary是否匹配指定的过滤字符串
/// </summary>
/// <param name="dictionary"></param>
/// <param name="filterString"></param>
/// <returns></returns>
public static bool Matches(Dictionary<string, object> dictionary, string filterString)
{

if (string.IsNullOrWhiteSpace(filterString))
{
return true;
}

LDAPFilter filterImpl = Create(filterString);
return filterImpl.Match(dictionary);
}

2、调用实例对象的方法

/// <summary>
/// 根据过滤语句创建LDAPFilter的实例
/// </summary>
/// <param name="filterString"></param>
/// <returns></returns>
public static LDAPFilter Create(string filterString)
{
return new Parser(filterString).Parse();
}

/// <summary>
/// 返回dictionary是否匹配当前LDAPFilter
/// </summary>
/// <param name="dictionary"></param>
/// <returns></returns>
public bool Match(Dictionary<string, object> dictionary)
{
return InnerMatch(ConvertToCaseInsensitiveDictionary(dictionary));
}

可以发现直接调用静态方法其实是封装了调用实例对象的方法,用起来更简单些。

这个LDAPFilter要求要过滤的属性格式为Dictionary,如果你使用的场景属性不是Dictionary的形式,需要先转换成这个格式(可以硬编码,也可以通过反射进行转换),处理起来就没问题了。

这个LDAPFilter是一个基础类,可以在他的基础上继续扩展封装,比如OSGI中用于过滤服务:

public boolean match(ServiceReference?reference)
本博客所有文章如无特别注明均为原创。
复制或转载请以超链接形式注明转自波斯马,原文地址《基于RFC1960的属性过滤器 – C#版LDAPFilter

关键字:

建议订阅本站,及时阅读最新文章!
【上一篇】 【下一篇】

发表评论