这几个星期来一直在学习RDF OWL 以及相关工具。
个人认为RDF将来在RIA中将是传输数据的最佳选择。
然而,这就意味着我们需要在server端建立一个从内存对象graph转换到rdf文档的转换层。
下面就是我这个周末就着这个问题写的一个小工具,它基本可以将对象间复杂的关系转换为RDF 文档,包括集合属性 等等。
接口:
/*
* Created on 2004-12-26
* just for xul/rdf project test
*/
package rdf.convert;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.RDFNode;
/**
* @author Administrator
*
*/
public interface Object2Resource {
public static ThreadLocal REGISTER=new ThreadLocal();;
/**
*
* @param obj
* @param model
* @param baseUri
* @param schema
* @return
*/
public RDFNode convert2Resource(Object obj,Model model,String baseUri,String schemaUri,Model schema);;
/**
*
* @param obj
* @param uri
*/
public void register(Object obj,String uri);;
/**
*
* @param obj
* @return
*/
public boolean isRegistered(Object obj);;
/**
*
* @param obj
* @return
*/
public String getUriFromReg(Object obj);;
/**
*
* @param obj
* @param baseURI
* @return
*/
public String getObjectURI(Object obj,String baseURI);;
}
下面是我的test class:
public void test(); throws Exception{
String baseUri="http://www.wangyuxiang.com/test/";
String schemaUri="http://www.wangyuxiang.com/schemas/models#";
String rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
String rdfs ="http://www.w3.org/2000/01/rdf-schema#";
Model model=ModelFactory.createDefaultModel();;
model.setNsPrefix("test",baseUri);;
model.setNsPrefix("model",schemaUri);;
Model schema=ModelLoader.loadModel("./src/test/schema.rdf");;
Profile prof=new Profile();;
prof.setDesc("test profile");;
prof.setEMail("wangyuxag@sina.com");;
prof.setFirstName("wang");;
prof.setSecondName("yuxiang");;
prof.setId(1);;
User user=new User();;
user.setId(2);;
user.setProfile(prof);;
UserGroup group=new UserGroup();;
User user2=new User();;
user2.setId(3);;
group.setId(4);;
user.setGroup(group);;
group.addUser(user);;
group.addUser(user2);;
[color=red][b] RDFNode res=converter.convert2Resource(user,model,baseUri,schemaUri,schema);;[/b][/color] model.write(System.out);;
model.write(new FileOutputStream("./src/test/test.rdf"););;
Resource userRes=this.containsSubjectWithURI(converter.getObjectURI(user,baseUri);,model);;
Resource groupRes=this.containsSubjectWithURI(converter.getObjectURI(group,baseUri);,model);;
Resource user2Res=this.containsSubjectWithURI(converter.getObjectURI(user2,baseUri);,model);;
Resource profRes=this.containsSubjectWithURI(converter.getObjectURI(prof,baseUri);,model);;
assertNotNull(userRes);;
assertNotNull(group);;
assertNotNull(user2Res);;
assertNotNull(prof);;
Model tmp=ModelFactory.createDefaultModel();;
Property id=tmp.createProperty(schemaUri+"rdf.model.Entity->id");;
Property groupProp=tmp.createProperty(schemaUri+"rdf.model.User->group");;
Statement ids=userRes.getProperty(id);;
assertEquals(((Literal);ids.getObject(););.getLong();,2);;
Statement groups=userRes.getProperty(groupProp);;
assertEquals(groups.getObject();,groupRes);;
Property group_users=tmp.createProperty(schemaUri+"rdf.model.UserGroup->users");;
Statement st_group_users=groupRes.getProperty(group_users);;
Bag usersRes=st_group_users.getBag();;
System.out.println(usersRes);;
assertEquals(usersRes.size();,2);;
assertTrue(usersRes.contains(userRes););;
assertTrue(usersRes.contains(user2Res););;
}
public void testValidateData(); throws Exception{
Model schema = ModelLoader.loadModel("./src/test/schema.rdf");;
Model data = ModelLoader.loadModel("./src/test/test.rdf");;
Reasoner reasoner = ReasonerRegistry.getOWLReasoner();;
reasoner = reasoner.bindSchema(schema);;
InfModel modelInf = ModelFactory.createInfModel(reasoner,
data);;
ValidityReport vrp1 = modelInf.validate();;
if (vrp1.isValid(););{
System.out.println("Valid OWL");;
}else {
System.out.println("Not valid OWL");;
for (Iterator i = vrp1.getReports();; i.hasNext();;);{
System.out.println(" - " + i.next(););;
}
}
}
描述OWL类定义文件:
<?xml version="1.0" encoding='ISO-8859-1'?>
<!DOCTYPE rdf:RDF [
<!ENTITY xsd 'http://www.w3.org/2001/XMLSchema#'>
<!ENTITY rdf 'http://www.w3.org/1999/02/22-rdf-syntax-ns#'>
<!ENTITY rdfs 'http://www.w3.org/2000/01/rdf-schema#'>
]>
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
xmlns:owl ="http://www.w3.org/2002/07/owl#"
xml:base="http://www.wangyuxiang.com/schemas/models">
<owl:Class rdf:ID="rdf.model.Entity"/>
<owl:Class rdf:ID="rdf.model.Profile"/>
<owl:Class rdf:ID="rdf.model.Privilege">
<rdfs:subClassOf rdf:resource="#rdf.model.Entity"/>
</owl:Class>
<owl:Class rdf:ID="rdf.model.Resource">
<rdfs:subClassOf rdf:resource="#rdf.model.Entity"/>
</owl:Class>
<owl:Class rdf:ID="rdf.model.Role">
<rdfs:subClassOf rdf:resource="#rdf.model.Entity"/>
</owl:Class>
<owl:Class rdf:ID="rdf.model.User">
<rdfs:subClassOf rdf:resource="#rdf.model.Entity"/>
</owl:Class>
<owl:Class rdf:ID="rdf.model.UserGroup">
<rdfs:subClassOf rdf:resource="#rdf.model.Entity"/>
</owl:Class>
<owl:DatatypeProperty rdf:ID="rdf.model.Entity->id">
<rdfs:domain rdf:resource="#rdf.model.Entity"/>
<rdfs:range rdf:resource="&long"/>
</owl:DatatypeProperty>
<owl:DatatypeProperty rdf:ID="rdf.model.Profile->id">
<rdfs:domain rdf:resource="#rdf.model.Profile"/>
<rdfs:range rdf:resource="&long"/>
</owl:DatatypeProperty>
<owl:ObjectProperty rdf:ID="rdf.model.Entity->profile">
<rdfs:domain rdf:resource="#rdf.model.Entity"/>
<rdfs:range rdf:resource="#Profile"/>
</owl:ObjectProperty>
<owl:DatatypeProperty rdf:ID="rdf.model.Profile->desc">
<rdfs:domain rdf:resource="#rdf.model.Profile"/>
<rdfs:range rdf:resource="&string"/>
</owl:DatatypeProperty>
<owl:DatatypeProperty rdf:ID="rdf.model.Profile->eMail">
<rdfs:domain rdf:resource="#rdf.model.Profile"/>
<rdfs:range rdf:resource="&string"/>
</owl:DatatypeProperty>
<owl:DatatypeProperty rdf:ID="rdf.model.Profile->firstName">
<rdfs:domain rdf:resource="#rdf.model.Profile"/>
<rdfs:range rdf:resource="&string"/>
</owl:DatatypeProperty>
<owl:DatatypeProperty rdf:ID="rdf.model.Profile->secondName">
<rdfs:domain rdf:resource="#rdf.model.Profile"/>
<rdfs:range rdf:resource="&string"/>
</owl:DatatypeProperty>
<owl:DatatypeProperty rdf:ID="rdf.model.Profile->fullName">
<rdfs:domain rdf:resource="#rdf.model.Profile"/>
<rdfs:range rdf:resource="&string"/>
</owl:DatatypeProperty>
<owl:DatatypeProperty rdf:ID="rdf.model.Profile->passwd">
<rdfs:domain rdf:resource="#rdf.model.Profile"/>
<rdfs:range rdf:resource="&string"/>
</owl:DatatypeProperty>
<owl:DatatypeProperty rdf:ID="rdf.model.Privilege->mark">
<rdfs:domain rdf:resource="#rdf.model.Privilege"/>
<rdfs:range rdf:resource="&string"/>
</owl:DatatypeProperty>
<owl:ObjectProperty rdf:ID="rdf.model.Resource->privilege">
<rdfs:domain rdf:resource="#rdf.model.Resource"/>
<rdfs:range rdf:resource="#Privilege"/>
</owl:ObjectProperty>
<owl:ObjectProperty rdf:ID="rdf.model.Role->privileges">
<rdfs:domain rdf:resource="#rdf.model.Role"/>
<rdfs:range rdf:resource="&Bag"/>
</owl:ObjectProperty>
<owl:ObjectProperty rdf:ID="rdf.model.User->group">
<rdfs:domain rdf:resource="#rdf.model.User"/>
<rdfs:range rdf:resource="#UserGroup"/>
</owl:ObjectProperty>
<owl:ObjectProperty rdf:ID="rdf.model.User->roles">
<rdfs:domain rdf:resource="#rdf.model.User"/>
<rdfs:range rdf:resource="&Bag"/>
</owl:ObjectProperty>
<owl:ObjectProperty rdf:ID="rdf.model.UserGroup->users">
<rdfs:domain rdf:resource="#rdf.model.UserGroup"/>
<rdfs:range rdf:resource="&Bag"/>
</owl:ObjectProperty>
</rdf:RDF>
生成的RDF文档:
<rdf:RDF
xmlns:test="http://www.wangyuxiang.com/test/"
xmlns:j.0="http://www.wangyuxiang.com/schemas/models#rdf.model.Profile-&"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:j.1="http://www.wangyuxiang.com/schemas/models#rdf.model.User-&"
xmlns:j.2="http://www.wangyuxiang.com/schemas/models#rdf.model.Entity-&"
xmlns:model="http://www.wangyuxiang.com/schemas/models#"
xmlns:j.3="http://www.wangyuxiang.com/schemas/models#rdf.model.UserGroup-&" >
<rdf:Description rdf:about="http://www.wangyuxiang.com/test/rdf.model.User_22172629">
<j.2:id rdf:datatype="http://www.w3.org/2001/XMLSchema#long">2</j.2:id>
<j.1:roles rdf:resource="http://www.wangyuxiang.com/test/rdf.model.User_22172629_roles"/>
<j.2:profile rdf:resource="http://www.wangyuxiang.com/test/rdf.model.Profile_30810736"/>
<rdf:type rdf:resource="http://www.wangyuxiang.com/schemas/models#rdf.model.User"/>
<j.1:group rdf:resource="http://www.wangyuxiang.com/test/rdf.model.UserGroup_4815156"/>
</rdf:Description>
<rdf:Description rdf:about="http://www.wangyuxiang.com/test/rdf.model.UserGroup_4815156_users">
<rdf:_1 rdf:resource="http://www.wangyuxiang.com/test/rdf.model.User_22172629"/>
<rdf:type rdf:resource="http://www.w3.org/1999/02/22-rdf-syntax-ns#Bag"/>
<rdf:_2 rdf:resource="http://www.wangyuxiang.com/test/rdf.model.User_33414193"/>
</rdf:Description>
<rdf:Description rdf:about="http://www.wangyuxiang.com/test/rdf.model.Profile_30810736">
<j.0:secondName rdf:datatype="http://www.w3.org/2001/XMLSchema#string">yuxiang</j.0:secondName>
<j.0:desc rdf:datatype="http://www.w3.org/2001/XMLSchema#string">test profile</j.0:desc>
<j.0:firstName rdf:datatype="http://www.w3.org/2001/XMLSchema#string">wang</j.0:firstName>
<rdf:type rdf:resource="http://www.wangyuxiang.com/schemas/models#rdf.model.Profile"/>
<j.0:id rdf:datatype="http://www.w3.org/2001/XMLSchema#long">1</j.0:id>
</rdf:Description>
<rdf:Description rdf:about="http://www.wangyuxiang.com/test/rdf.model.User_22172629_roles">
<rdf:type rdf:resource="http://www.w3.org/1999/02/22-rdf-syntax-ns#Bag"/>
</rdf:Description>
<rdf:Description rdf:about="http://www.wangyuxiang.com/test/rdf.model.User_33414193">
<rdf:type rdf:resource="http://www.wangyuxiang.com/schemas/models#rdf.model.User"/>
<j.2:id rdf:datatype="http://www.w3.org/2001/XMLSchema#long">3</j.2:id>
<j.1:roles rdf:resource="http://www.wangyuxiang.com/test/rdf.model.User_33414193_roles"/>
</rdf:Description>
<rdf:Description rdf:about="http://www.wangyuxiang.com/test/rdf.model.UserGroup_4815156">
<j.3:users rdf:resource="http://www.wangyuxiang.com/test/rdf.model.UserGroup_4815156_users"/>
<j.2:id rdf:datatype="http://www.w3.org/2001/XMLSchema#long">4</j.2:id>
<rdf:type rdf:resource="http://www.wangyuxiang.com/schemas/models#rdf.model.UserGroup"/>
</rdf:Description>
<rdf:Description rdf:about="http://www.wangyuxiang.com/test/rdf.model.User_33414193_roles">
<rdf:type rdf:resource="http://www.w3.org/1999/02/22-rdf-syntax-ns#Bag"/>
</rdf:Description>
</rdf:RDF>
优点:
可以将内存对象关系完全转换到文档
缺陷:
在schema 文档中,需要严格按照一些规范书写ID/URI
类的ID规范: 对应的java类名
属性ID规范:对应的java类名->属性名
todo:
可以映射 类名 属性名 消除命名限制
对集合属性支持lazy loding
附件是源代码