以文本方式查看主题

-  计算机科学论坛  (http://bbs.xml.org.cn/index.asp)
--  『 Web Services & Semantic Web Services 』  (http://bbs.xml.org.cn/list.asp?boardid=10)
----  OWL-S API的应用(其余功能)----[经典转贴]  (http://bbs.xml.org.cn/dispbbs.asp?boardid=10&rootid=&id=46208)


--  作者:timothy
--  发布时间:4/28/2007 8:50:00 PM

--  OWL-S API的应用(其余功能)----[经典转贴]
类CreateSequence表明了如何将一系列服务串联起来,并自动产生一个描述新服务的profile,这个类假定每个服务都是单输入单输出的(除了第一个服务和最后一个服务),这样前面的服务的输出将作为后一个服务的输入。第一个服务不需要有输入,最后一个服务不需要有输出。组合服务的名字命名为[Service1 + Service2 + ... + ServiceN]。最后在main函数中进行测试,将BookFinder.owl和BNPrice.owl进行组合,输入"City of Glass",先查通过BookFinder.owl查到书号,然后将书号输入BNPrice.owl,得到输出:
Executing...done
Book Price =
   Price:
     currency: USD
     amount: 14.00


完整代码如下:


import java.net.URI;
import java.util.ArrayList;
import java.util.List;

import org.mindswap.owl.EntityFactory;
import org.mindswap.owl.OWLFactory;
import org.mindswap.owl.OWLIndividual;
import org.mindswap.owl.OWLKnowledgeBase;
import org.mindswap.owl.OWLOntology;
import org.mindswap.owls.OWLSFactory;
import org.mindswap.owls.grounding.Grounding;
import org.mindswap.owls.process.AtomicProcess;
import org.mindswap.owls.process.CompositeProcess;
import org.mindswap.owls.process.Input;
import org.mindswap.owls.process.Output;
import org.mindswap.owls.process.Perform;
import org.mindswap.owls.process.Process;
import org.mindswap.owls.process.ProcessList;
import org.mindswap.owls.process.Result;
import org.mindswap.owls.process.Sequence;
import org.mindswap.owls.process.execution.ProcessExecutionEngine;
import org.mindswap.owls.profile.Profile;
import org.mindswap.owls.service.Service;
import org.mindswap.query.ValueMap;
import org.mindswap.utils.URIUtils;
import org.mindswap.utils.Utils;

/**
* An example to show how service descriptions can be created on the fly, saved and executed.
*
* @author Evren Sirin
*/
public class CreateSequence {
    public static final URI baseURI = URI.create("http://www.example.org/BookPrice.owl#");
    
    OWLOntology ont;

    public CreateSequence() {        
    }
    
/**
  *
  * Create a new Sequence from the processes of the given services and put them in a new
  * Service object with a automatically generated Profile. This function assumes that
  * each service in the list has exactly one input and one output (except the first and
  * last one) such that in the resulting Service the output of each service will be fed
  * as input to the next one. The first service does not have to have an input and the
  * last one does not need to have an output. The resulting service will have an input
  * (or an output) depending on this.
  *
  * @param services List of Service objects
  * @param baseURI The base URI for the generated service
  * @return The Service which is a Sequence of the given services
  */
Service createSequenceService(List services) {
  Service service = ont.createService(URIUtils.createURI(baseURI, "TestService"));
  CompositeProcess process = ont.createCompositeProcess(URIUtils.createURI(baseURI, "TestProcess"));   
  Profile profile = ont.createProfile(URIUtils.createURI(baseURI, "TestProfile"));
  Grounding grounding = ont.createGrounding(URIUtils.createURI(baseURI, "TestGrounding"));
  
  System.out.println(ont.getKB().getServices());
  
  service.setProfile(profile);
  service.setProcess(process);
  service.setGrounding(grounding);
  
  createSequenceProcess(process, services);
  createProfile(profile, process);

  ProcessList list = process.getComposedOf().getAllProcesses();
  for(int i = 0; i < list.size(); i++) {
   Process pc = list.processAt(i);
   if(pc instanceof AtomicProcess) {
    grounding.addGrounding(((AtomicProcess)pc).getGrounding());
   }
  }
  
  
  profile.setLabel(createLabel(services));
  profile.setTextDescription(profile.getLabel());
  
  service.setProfile(profile);
  service.setProcess(process);
  service.setGrounding(grounding);
  return service;
}

/**
  *
  * Create a label for the composite service based on the labels of services. Basically
  * return the string [Service1 + Service2 + ... + ServiceN] as the label
  *
  * @param services List of Servie objects
  * @return
  */
String createLabel(List services) {
  String label = "[";
  
  for(int i = 0; i < services.size(); i++) {
   Service s = (Service) services.get(i);
   
   if(i > 0) label += " + ";      

   label += s.getLabel();
  }
  label += "]";
  
  return label;
}

/**
  *
  * Create a Profile for the composite service. We only set the input and output of the profile
  * based on the process.
  *
  * @param profile
  * @param process
  * @return
  */
Profile createProfile(Profile profile, Process process) {
  for(int i = 0; i < process.getInputs().size(); i++) {
   Input input = process.getInputs().inputAt(i);
   
   profile.addInput(input);
  }
  
  for(int i = 0; i < process.getOutputs().size(); i++) {
   Output output = process.getOutputs().outputAt(i);

   profile.addOutput(output);
  }
  
  return profile;
}

/**
  *
  * Create a Sequence process for the processes of given services. Creates the DataFlow asssuming each
  * service has one output and one intput (except first and last one).
  *
  * @param compositeProcess
  * @param grounding
  * @param services
  * @return
  */
CompositeProcess createSequenceProcess(CompositeProcess compositeProcess, List services) {
  Sequence sequence = ont.createSequence();
  compositeProcess.setComposedOf(sequence);
  
  Perform[] performs = new Perform[services.size()];
  for(int i = 0; i < services.size(); i++) {
   Service s = (Service) services.get(i);
   Process p = s.getProcess();
   
   performs[i] = ont.createPerform();
   performs[i].setProcess(p);
   
   sequence.addComponent(performs[i]);

   if(i > 0) {
    Perform prevPerform = performs[i - 1];
    Input input = p.getInputs().inputAt(0);
    Output output = prevPerform.getProcess().getOutputs().outputAt(0);
    
    // the value of 'input' is the value of 'output' from 'prevPerform'
    performs[i].addBinding(input, prevPerform, output);
   }
  }

  Perform firstPerform = performs[0];
  Perform lastPerform = performs[services.size()-1];
  boolean createInput = firstPerform.getProcess().getInputs().size() > 0;  
  boolean createOutput = lastPerform.getProcess().getOutputs().size() > 0;

  if(createInput) {
   Input input = firstPerform.getProcess().getInputs().inputAt(0);
   Input newInput = ont.createInput(URIUtils.createURI(baseURI, "TestInput"));
   newInput.setLabel(input.getLabel());
   newInput.setParamType(input.getParamType());
   newInput.setProcess(compositeProcess);
   
   // input of the first perform is directly read from the input of the
   // composite process
   performs[0].addBinding(input, Perform.TheParentPerform, newInput);
  }
  
  if(createOutput) {
   Output output = lastPerform.getProcess().getOutputs().outputAt(0);
   Output newOutput = ont.createOutput(URIUtils.createURI(baseURI, "TestOutput"));
   newOutput.setLabel(output.getLabel());
   newOutput.setParamType(output.getParamType());
   newOutput.setProcess(compositeProcess);

   // the output of the composite process is the output pf last process
   Result result = ont.createResult();
   result.addBinding(newOutput, lastPerform, output);
   
   compositeProcess.setResult(result);
  }
  
  return compositeProcess;
}


public void runTest() throws Exception {
  // create an OWL-S knowledge base
  OWLKnowledgeBase kb = OWLFactory.createKB();

  // create an empty ontology in this KB
  ont = kb.createOntology();
  
  // create an execution engine
  ProcessExecutionEngine exec = OWLSFactory.createExecutionEngine();
  
  // load two services
  Service s1 = kb.readService("http://www.mindswap.org/2004/owl-s/1.1/BookFinder.owl#");
  Service s2 = kb.readService("http://www.mindswap.org/2004/owl-s/1.1/BNPrice.owl#");
  
  // put the services in a list
  List services = new ArrayList();
  services.add(s1);
  services.add(s2);
  
  // create a new service as a sequence of the list
  Service s = createSequenceService(services);
  
  // print the description of new service to standard output
  ont.write(System.out, baseURI);
  System.out.println();
  
  // get the process of the new service
  Process process = s.getProcess();
  // initialize the input values to be empty
  ValueMap values = new ValueMap();
  // get the parameter using the local name
  values.setValue(process.getInputs().inputAt(0), EntityFactory.createDataValue("City of Glass"));
  
  // execute the service
  System.out.print("Executing...");
  values = exec.execute(process, values);
  System.out.println("done");
  
  // get the output param using the index  
  OWLIndividual outValue = values.getIndividualValue(process.getOutput());
  
  // display the result
  System.out.println("Book Price = ");
  System.out.println(Utils.formatRDF(outValue.toRDF()));  
  System.out.println();  
}

public static void main(String[] args) throws Exception {  
  CreateSequence test = new CreateSequence();
  test.runTest();  
}
}

ForEachExample类是对多输入值进行操作的例子,例如,分别输入三个邮政编码,然后调用服务得到三个地区的纬度和经度。


完整代码如下:

import impl.owls.process.execution.ProcessExecutionEngineImpl;

import java.net.URI;

import org.mindswap.owl.OWLClass;
import org.mindswap.owl.OWLDataProperty;
import org.mindswap.owl.OWLFactory;
import org.mindswap.owl.OWLIndividual;
import org.mindswap.owl.OWLKnowledgeBase;
import org.mindswap.owl.OWLOntology;
import org.mindswap.owl.list.RDFList;
import org.mindswap.owls.OWLSFactory;
import org.mindswap.owls.process.CompositeProcess;
import org.mindswap.owls.process.ForEach;
import org.mindswap.owls.process.Input;
import org.mindswap.owls.process.Local;
import org.mindswap.owls.process.Perform;
import org.mindswap.owls.process.Process;
import org.mindswap.owls.process.execution.ProcessExecutionEngine;
import org.mindswap.owls.service.Service;
import org.mindswap.owls.vocabulary.OWLS;
import org.mindswap.query.ValueMap;

/**
*
* Example to show how to create and execute a forEach control construct.
*
* @author Evren Sirin
*/
public class ForEachExample {
public void run() throws Exception {
  String ns = "http://www.example.org/test#";  
  
  // print the inputs and outputs during each iteration of the loop
  ProcessExecutionEngineImpl.DEBUG = true;
  ProcessExecutionEngine exec = OWLSFactory.createExecutionEngine();
  
  OWLKnowledgeBase kb = OWLFactory.createKB();  
  
  Service service = kb.readService("http://www.mindswap.org/2004/owl-s/1.1/FindLatLong.owl");
  Process process = service.getProcess();
  
  OWLOntology ont = kb.createOntology();
  CompositeProcess cp = ont.createCompositeProcess();
  Input in = ont.createInput(URI.create( ns + "in" ));
  in.setParamType(OWLS.ObjList.List());
  cp.addInput(in);

  // create a ForEach construct
  ForEach forEach = ont.createForEach();
  Local loopVar = ont.createLocal( URI.create( ns + "loopVar") );
  cp.setComposedOf(forEach);
  forEach.setListValue( Perform.TheParentPerform, in );
  forEach.setLoopVar( loopVar );

  // perform the process by passing the loop variable
  Perform perform = ont.createPerform();
  perform.setProcess(process);
  perform.addBinding(process.getInput(), Perform.TheParentPerform, loopVar);
  
  forEach.setComponent(perform);
  
  // display how the construct looks like in RDF/XML
  ont.write(System.out);
  
  // create some zip code values
     String zipcodeOnt = "http://www.daml.org/2001/10/html/zipcode-ont#";
     OWLClass ZipCode = kb.getClass(URI.create(zipcodeOnt + "ZipCode"));
     OWLDataProperty zip = kb.getDataProperty(URI.create(zipcodeOnt + "zip"));
     
     OWLIndividual zip1 = ont.createInstance(ZipCode);
     zip1.setProperty(zip, "20740");
     OWLIndividual zip2 = ont.createInstance(ZipCode);
     zip2.setProperty(zip, "11430");
     OWLIndividual zip3 = ont.createInstance(ZipCode);
     zip3.setProperty(zip, "94102");
     
     // put them in a list
     RDFList list = ont.createList(zip1).add(zip2).add(zip3);
  
     ValueMap values = new ValueMap();
  values.setValue(cp.getInput("in"), list);
  
  exec.execute( cp , values );
}

public static void main(String[] args) throws Exception {  
  ForEachExample test = new ForEachExample();
  
  test.run();  
}
}


运行后得到输出:

Executing AtomicProcess http://www.mindswap.org/2004/owl-s/1.1/FindLobjectatLong.owl#FindLatLongProcess
Inputs:
(http://www.mindswap.org/2004/owl-s/1.1/FindLobjectatLong.owl#ZipCode=
  <j.0:ZipCode>
    <j.0:zip>20740</j.0:zip>
  </j.0:ZipCode>
)
Invoking http://cheeso.members.winisp.net/zips/ZipService.asmx?WSDL
Result:
(http://www.mindswap.org/2004/owl-s/1.1/FindLobjectatLong.owl#LatLong=
  <j.0:LatLon>
    <j.0:latitude>38.996303</j.0:latitude>
    <j.0:longitude>-76.929891</j.0:longitude>
  </j.0:LatLon>
)

Executing AtomicProcess http://www.mindswap.org/2004/owl-s/1.1/FindLobjectatLong.owl#FindLatLongProcess
Inputs:
(http://www.mindswap.org/2004/owl-s/1.1/FindLobjectatLong.owl#ZipCode=
  <rdf:Description>
    <j.0:zip>11430</j.0:zip>
  </rdf:Description>
)
Invoking http://cheeso.members.winisp.net/zips/ZipService.asmx?WSDL
Result:
(http://www.mindswap.org/2004/owl-s/1.1/FindLobjectatLong.owl#LatLong=
  <j.0:LatLon>
    <j.0:latitude>-0</j.0:latitude>
    <j.0:longitude>-0</j.0:longitude>
  </j.0:LatLon>
)

Executing AtomicProcess http://www.mindswap.org/2004/owl-s/1.1/FindLobjectatLong.owl#FindLatLongProcess
Inputs:
(http://www.mindswap.org/2004/owl-s/1.1/FindLobjectatLong.owl#ZipCode=
  <rdf:Description>
    <j.0:zip>94102</j.0:zip>
  </rdf:Description>
)
Invoking http://cheeso.members.winisp.net/zips/ZipService.asmx?WSDL
Result:
(http://www.mindswap.org/2004/owl-s/1.1/FindLobjectatLong.owl#LatLong=
  <j.0:LatLon>
    <j.0:latitude>-0</j.0:latitude>
    <j.0:longitude>-0</j.0:longitude>
  </j.0:LatLon>
)

Matchmaker这个例子说明了如何对服务进行匹配,实现服务的组合。服务的输出与服务的输入进行匹配,分别运用"EXACT, SUBSUME以及RELAXED"作为匹配标准。这里应用了Pellet推理机。

对以下几个文件进行输入输出皮匹配:
http://www.mindswap.org/2004/owl-s/1.1/BNPrice.owl
http://www.mindswap.org/2004/owl-s/1.1/BookFinder.owl
http://www.mindswap.org/2004/owl-s/1.1/CurrencyConverter.owl
http://www.mindswap.org/2004/owl-s/1.1/Dictionary.owl
http://www.mindswap.org/2004/owl-s/1.1/ZipCodeFinder.owl
http://www.mindswap.org/2004/owl-s/1.1/FindLatLong.owl
http://www.mindswap.org/2004/owl-s/1.1/BabelFishTranslator.owl

得到运行结果:
Reading http://www.mindswap.org/2004/owl-s/1.1/BNPrice.owl
Reading http://www.mindswap.org/2004/owl-s/1.1/BookFinder.owl
Reading


--  作者:yfhbwh
--  发布时间:8/27/2009 9:57:00 AM

--  
这位大哥,你运行这个程序花了多长时间啊?
我选择其中一个BookFinder,读取其中的内容,都花了N长时间,整个程序跑起来半天不出来结果,能不能先把这些文件下载下来,根据路径读取啊?或者有更好的办法?
--  作者:timothy
--  发布时间:8/31/2009 11:03:00 PM

--  
呵呵, 很久之前的事了, 记不大清楚了。

照做应该是没问题的。


--  作者:Humphrey
--  发布时间:9/5/2009 3:35:00 PM

--  
事实上,网址的部分就是URI。改为本地路径应该也是可以的,但必须按照本地路径的标引规范来做。
--  作者:Humphrey
--  发布时间:9/6/2009 11:13:00 AM

--  
“其余功能”是按照什么标准提出的呢?
是除了它的某几种主要功能之外的全部功能了吗?
那么这些主要功能又是什么呢?
W 3 C h i n a ( since 2003 ) 旗 下 站 点
苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
18,187.500ms