wiki地址:http://protegewiki.stanford.edu/wiki/BuildingSemanticWebApplications
Main article: ProtegeOWL_API_Programmers_Guide
Building Semantic Web Applications--搭建语义网应用程序
可以使用Protege-OWL API 构建独立的应用程序。这些应用程序可以从语义网(Semantic Web)上下载本体,对这些本体进行查询或者编辑,对实例和类进行归纳划分,并且将结果本体写入文件中。语义网应用的一些方法和架构由Holger Knublanch在他的论文中提出。下面的图是从论文中截取的,主要描述了一个应用的典型架构。
上图的架构,将整个应用系统划分为两个部分:语义网层,逻辑层
语义网层:存储大量可用的领域本体,其他用户可以使用web Service获取网络上的本体。
逻辑层:将使用的本体封装成应用中对应的具体java类(针对应用构建模型),底层拥有各种推理机可以进行推理。这里可以这么理解,将语义网理解成一个巨大的数据库,而图中Customer.java和Activity.java可以理解成我们平时的应用中的Model。
其实这里还隐藏了一个与用户的交互层,即View。使用Jsp编写,通过web service或者servlet等方式调用逻辑层提供的服务。
Wiki中给出了下面的例子:
1. 有一个Purchase本体,每个purchase包含了customer和product(这两个概念定义在别的本体中)。
2. 我们需要处理某个customer,则直接调用本体的代码如下。
OWLNamedClass customerClass = owlModel.getOWLNamedClass("Customer"); OWLDatatypeProperty firstNameProperty = owlModel.getOWLDatatypeProperty("firstName"); OWLIndividual myCustomer = owlModel.getOWLIndividual("Customer42"); String firstName = (String) myCustomer.getPropertyValue(firstNameProperty);
这种调用方式容易造成混乱,直接通过字符串处理本体是非常不合理的。
如果我们需要统计用户的个数,则代码如下
private static float getPurchasesSum(RDFIndividual customer) { OWLModel owlModel = customer.getOWLModel(); float sum = 0; RDFProperty purchasesProperty = owlModel.getRDFProperty("purchases"); RDFProperty productProperty = owlModel.getRDFProperty("product"); RDFProperty priceProperty = owlModel.getRDFProperty("price"); Iterator purchases = customer.listPropertyValues(purchasesProperty); while(purchases.hasNext()) { RDFIndividual purchase = (RDFIndividual) purchases.next(); RDFIndividual product = (RDFIndividual) purchase.getPropertyValue(productProperty); Float price = (Float) product.getPropertyValue(priceProperty); sum += price.floatValue(); } return sum; }
3. 封装为应用的model
编写一个接口,完成Customer需要的功能,向外部应用提供这样的接口可以提高程序的安全性,也符合面向对象的原则。
public interface Customer { String getFirstName(); void setFirstName(String value); ... float getPurchasesSum(); }
编写一个默认用户类,实现这些方法。每个用户是本体中的一个实例,所以该类可以从api提供的本体实例类继承。
package com.demo.model.impl; public class DefaultCustomer extends DefaultOWLIndividual implements Customer { public DefaultCustomer(KnowledgeBase kb, FrameID id) { super(kb, id); } public String getFirstName() { RDFProperty property = getOWLModel().getRDFProperty("firstName"); return (String) getPropertyValue(property); } public void setFirstName(String value) { RDFProperty property = getOWLModel().getRDFProperty("firstName"); setPropertyValue(property, value); } }
另外,编写一个工厂类MyFactory用于实现向本体中添加新的数据。
package edu.stanford.smi.protegex.owlx.examples.javaDemo.model; import edu.stanford.smi.protegex.owl.model.OWLModel; import edu.stanford.smi.protegex.owl.model.RDFSNamedClass; /** * Generated by Protégé-OWL (http://protege.stanford.edu/plugins/owl). * * @version generated on Mon Feb 21 10:53:08 EST 2005 */ public class MyFactory { private OWLModel owlModel; public MyFactory(OWLModel owlModel) { this.owlModel = owlModel; } public RDFSNamedClass getCustomerClass() { final String uri = "http://www.owl-ontologies.com/javaDemo.owl#Customer"; final String name = owlModel.getResourceNameForURI(uri); return owlModel.getRDFSNamedClass(name); } public Customer createCustomer(String name) { final RDFSNamedClass cls = getCustomerClass(); return (Customer) cls.createInstance(name).as(Customer.class); } public RDFSNamedClass getPurchaseClass() { final String uri = "http://www.owl-ontologies.com/javaDemo.owl#Purchase"; final String name = owlModel.getResourceNameForURI(uri); return owlModel.getRDFSNamedClass(name); } public Purchase createPurchase(String name) { final RDFSNamedClass cls = getPurchaseClass(); return (Purchase) cls.createInstance(name).as(Purchase.class); } public RDFSNamedClass getProductClass() { final String uri = "http://www.owl-ontologies.com/javaDemo.owl#Product"; final String name = owlModel.getResourceNameForURI(uri); return owlModel.getRDFSNamedClass(name); } public Product createProduct(String name) { final RDFSNamedClass cls = getProductClass(); return (Product) cls.createInstance(name).as(Product.class); } }
4. 改进后
可以直接使用提供的接口对本体中的用户进行操作,整个代码结构非常清晰简洁。
private static Purchase createPurchase(Customer customer, Product product, String date) { OWLModel owlModel = customer.getOWLModel(); Purchase purchase = new MyFactory(owlModel).createPurchase(null); purchase.setCustomer(customer); purchase.setProduct(product); RDFSDatatype xsdDate = owlModel.getRDFSDatatypeByName("xsd:date"); purchase.setDate(owlModel.createRDFSLiteral(date, xsdDate); return purchase; }
这是一个简单应用的基本框架。最近也正好在做本体相关的工作,但是应用中出现的类和实例非常之多,主要涉及的也是推理的工作,真正直接对本体各个数据进行直接改动的工作还是比较少。但是这个思维方式还是非常值得借鉴的,觉得很经典,其实也很像MVC。在后续的工作中或许也会涉及到这样的应用,这里先初步学习记录。