-- 作者: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
|