ラベル RDF の投稿を表示しています。 すべての投稿を表示
ラベル RDF の投稿を表示しています。 すべての投稿を表示

2013年10月11日金曜日

先のPOST( SADI service の hello )のクライアントをJavaで作ってみる

参考:
先のPOST

Build Path周り:
を,含むプロジェクト全体の図.
  • それぞれのjarは,先のPOSTを実行しているのであれば,$HOME/.m2/repositoryの下に入っています.
  • 面倒なら先のプロジェクトに居候してしまえばパスは通っているので簡単かもしれません.
  • コードをパッと見るとsadi-clientとjenaがあればよさそうですが,依存関係の都合で色々いれなくてはなりませんでした.


("slf4j-api-*.jar"だけでなく, "slf4j-log4j12-*.jar"が必要な場合もあるようです)

コード(Client.java):

package sample;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

import ca.wilkinsonlab.sadi.SADIException;
import ca.wilkinsonlab.sadi.client.ServiceImpl;

import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.ResourceFactory;

public class Client {

 public static void main(String[] args) throws SADIException, IOException {
  Model inputModel = ModelFactory.createDefaultModel();
  if (true) {
   Resource type = ResourceFactory
     .createResource("http://sadiframework.org/examples/hello.owl#NamedIndividual");
   Resource s = inputModel
     .createResource(
       "http://sadiframework.org/examples/hello-input.rdf#1",
       type);
   s.addProperty(
     inputModel.createProperty("http://xmlns.com/foaf/0.1/name"),
     "Guy Incognito");
  } else {
   inputModel.read(new FileInputStream(new File("./hello-input.rdf")),
     "", "RDF/XML");
  }
  inputModel.write(System.out, "RDF/XML");

  String serviceURI = "http://localhost:8080/sadi-services/hello";
  ServiceImpl service = new ServiceImpl(serviceURI);

  Model outputModel = service.invokeServiceUnparsed(inputModel);
  outputModel.write(System.out, "RDF/XML");
 }
}

結果:
当たり前だけど, service側が動いている前提です.

<rdf:RDF
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:j.0="http://xmlns.com/foaf/0.1/"
    xmlns:j.1="http://sadiframework.org/examples/hello.owl#" > 
  <rdf:Description rdf:about="http://sadiframework.org/examples/hello-input.rdf#1">
    <j.0:name>Guy Incognito</j.0:name>
    <rdf:type rdf:resource="http://sadiframework.org/examples/hello.owl#NamedIndividual"/>
  </rdf:Description>
</rdf:RDF>
<rdf:RDF
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:j.0="http://sadiframework.org/examples/hello.owl#" > 
  <rdf:Description rdf:about="http://sadiframework.org/examples/hello-input.rdf#1">
    <j.0:greeting>Hello, Guy Incognito!</j.0:greeting>
    <rdf:type rdf:resource="http://sadiframework.org/examples/hello.owl#GreetedIndividual"/>
  </rdf:Description>
</rdf:RDF>

先のPOST( SADI service の hello )から真似っこだけで,数値2入力の足し算サービスを追加してみる

Owlを用意( ./sample.owl ):
てきとーに書いてみた(後の行程からみて間違ってるかも).

<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#">

  <owl:Ontology rdf:about="">
  </owl:Ontology>

  <owl:Class rdf:ID="inputValues">
    <owl:equivalentClass>
      <owl:Restriction>
        <owl:onProperty rdf:resource="#number1"/>
        <owl:someValuesFrom rdf:resource="http://www.w3.org/2001/XMLSchema#int"/>
      </owl:Restriction>
    </owl:equivalentClass>
    <owl:equivalentClass>
      <owl:Restriction>
        <owl:onProperty rdf:resource="#number2"/>
        <owl:someValuesFrom rdf:resource="http://www.w3.org/2001/XMLSchema#int"/>
      </owl:Restriction>
    </owl:equivalentClass>
  </owl:Class>
  
  <owl:Class rdf:ID="outputValue">
    <owl:equivalentClass>
      <owl:Restriction>
        <owl:onProperty rdf:resource="#result"/>
        <owl:someValuesFrom rdf:resource="http://www.w3.org/2001/XMLSchema#int"/>
      </owl:Restriction>
    </owl:equivalentClass>
  </owl:Class>

</rdf:RDF>



サービスのコードを生成する:
やり方は先のPOST参照のこと.パラメータは以下の通り.

serviceName : add
serviceClass: com.example.AddService
inputClass  : file:./sample.owl#inputValues
outputClass : file:./sample.owl#outputValue
contactEmail: your-email-address (そのままでも実行できる / エンドポイントにて連絡先として公開される)


サービスのコードを修正・実装する:
AddService.java中の'static final class Vocab {'を修正する.
  • 'public static final Resource int ='と変数名が型になってしまったので'int'を'intType'と変更

 static final class Vocab {
  private static Model m_model = ModelFactory.createDefaultModel();

  public static final Property result = m_model
    .createProperty("file:./sample.owl#result");
  public static final Property number1 = m_model
    .createProperty("file:./sample.owl#number1");
  public static final Property number2 = m_model
    .createProperty("file:./sample.owl#number2");
  public static final Resource outputValue = m_model
    .createResource("file:./sample.owl#outputValue");
  public static final Resource intType = m_model
    .createResource("http://www.w3.org/2001/XMLSchema#int");
  public static final Resource inputValues = m_model
    .createResource("file:./sample.owl#inputValues");
 }

AddService.java中の'public void processInput(Resource input, Resource output)'を実装する.

 public void processInput(Resource input, Resource output) 
 {
  int n1 = input.getProperty(Vocab.number1).getInt();
  int n2 = input.getProperty(Vocab.number2).getInt();
  int result = n1 + n2;
  output.addProperty(Vocab.result, result + "");
 }


サービスを起動する:
やり方は先のPOST参照のこと.

Firefoxでアクセスすると( http://localhost:8080/sadi-services/add ):



curlを使ってアクセスしてみる:

$ cat add-input.rdf 
<rdf:RDF
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:sample="file:./sample.owl#">

 <sample:inputValues rdf:about="file:./sample.owl#1">
  <sample:number1>1000000000</sample:number1>
  <sample:number2>20</sample:number2>
 </sample:inputValues>

</rdf:RDF>
$ curl -d '@add-input.rdf' http://localhost:8080/sadi-services/add
<rdf:RDF
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:j.0="file:./sample.owl#">
  <j.0:outputValue rdf:about="file:./sample.owl#1">
    <j.0:result>1000000020</j.0:result>
  </j.0:outputValue>
</rdf:RDF>

SADI (Semantic Automated Discovery and Integration) の service skeleton (Java) を試す(Eclipse+m2e環境で)

参考:
Generating the SADI service code / BuildingServicesInJava / Tutorial: building a SADI service in Java.


環境:
  • Mavenを使えるようにした(m2eプラグインだったと思う)Eclipse(Kepler/4.3)
  • m2eupdate site情報


ダウンロード:


プロジェクトを作る:
  1. メニューから'File > Import'を選択
  2. ダイアログ中から'Existing Projects into Workspace'を選択
  3. ダイアログ中の'Select archive file:'にdownloadした'sadi-service-skeleton-*.zip'を設定
  4. ダイアログ中の'Finish'ボタンを押す.



サービスのコードを生成する:
  1. メニューから'Run > Run Configurations …'を選択
  2. ダイアログ中,左ペインから'Maven Build > generate sadi service'を選択


  3. ダイアログ中,右ペインのパラメタを修正
    
    serviceName : hello
    serviceClass: com.example.HelloWorldService
    inputClass  : http://sadiframework.org/examples/hello.owl#NamedIndividual
    outputClass : http://sadiframework.org/examples/hello.owl#GreetedIndividual
    contactEmail: your-email-address (そのままでも実行はできる / エンドポイントにて連絡先として公開される)
    (コピペ等で最初や最後に空白が入っていると失敗します)
    



  4. ダイアログ中の'Run'ボタンを押す
  5. 生成ファイルを確認するためにメニューから'File > Refresh'を選択
  6. ファイルを確認
    src/main/javaにcom.exampleパッケージのHelloWorldService.javaができている.
    src/main/webapp/WEB-INF/web.xmlが作られ(無い場合),hello Servletの設定が追加されている.
    src/main/webapp/index.jspが作られ(無い場合),“./hello”へのリンク(サービスのエンドポイント)が追加されている.
    



  7. ちなみに http://sadiframework.org/examples/hello.owl の中身はこんなの
    
    <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#">
        
      <owl:Ontology rdf:about="">
      </owl:Ontology>
      
      <owl:DatatypeProperty rdf:about="http://xmlns.com/foaf/0.1/name">
       <rdfs:isDefinedBy rdf:resource="http://xmlns.com/foaf/0.1/index.rdf"/>
      </owl:DatatypeProperty>
      
      <owl:DatatypeProperty rdf:about="#greeting"/>
      
      <owl:Class rdf:ID="NamedIndividual">
        <owl:equivalentClass>
          <owl:Restriction>
            <owl:onProperty rdf:resource="http://xmlns.com/foaf/0.1/name"/>
            <owl:minCardinality rdf:datatype="http://www.w3.org/2001/XMLSchema#int">1</owl:minCardinality>
          </owl:Restriction>
        </owl:equivalentClass>
      </owl:Class>
      
      <owl:Class rdf:ID="GreetedIndividual">
        <owl:equivalentClass>
          <owl:Restriction>
            <owl:onProperty rdf:resource="#greeting"/>
            <owl:someValuesFrom rdf:resource="http://www.w3.org/2001/XMLSchema#string"/>
          </owl:Restriction>
        </owl:equivalentClass>
      </owl:Class>
      
      <owl:DatatypeProperty rdf:about="#lang"/>
      
      <owl:Class rdf:ID="SecondaryParameters">
        <owl:equivalentClass>
          <owl:Restriction>
            <owl:onProperty rdf:resource="#lang"/>
            <owl:minCardinality rdf:datatype="http://www.w3.org/2001/XMLSchema#int">1</owl:minCardinality>
          </owl:Restriction>
        </owl:equivalentClass>
      </owl:Class>
      
    </rdf:RDF>
    


サービスのコードを実装する:
HelloWorldService.java中の'public void processInput(Resource input, Resource output)'を実装する.

 public void processInput(Resource input, Resource output) 
 {
  String name = input.getProperty(Vocab.name).getString(); 
  output.addProperty(Vocab.greeting, String.format("Hello, %s!", name));
 }


サービスを起動する:
  1. メニューから'Run > Run Configurations …'を選択
  2. ダイアログ中,左ペインから'Maven Build > run sadi services in Jetty'を選択


  3. ダイアログ中,'Run'ボタンを押す
これでサービスの開始.

Firefoxでアクセスした場合( http://localhost:8080/sadi-services/hello ):


Safariでアクセスした場合はRDFが返ってくる:

<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="?xsl" ?>
<rdf:RDF
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:mygrid="http://www.mygrid.org.uk/mygrid-moby-service#"
    xmlns:j.0="http://protege.stanford.edu/plugins/owl/dc/protege-dc.owl#"
    xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#">
  <mygrid:serviceDescription rdf:about="">
    <mygrid:hasOperation>
      <mygrid:operation>
        <mygrid:outputParameter>
          <mygrid:parameter>
            <mygrid:objectType rdf:resource="http://sadiframework.org/examples/hello.owl#GreetedIndividual"/>
          </mygrid:parameter>
        </mygrid:outputParameter>
        <mygrid:inputParameter>
          <mygrid:parameter>
            <mygrid:objectType rdf:resource="http://sadiframework.org/examples/hello.owl#NamedIndividual"/>
          </mygrid:parameter>
        </mygrid:inputParameter>
      </mygrid:operation>
    </mygrid:hasOperation>
    <mygrid:providedBy>
      <mygrid:organisation>
        <mygrid:authoritative rdf:datatype="http://www.w3.org/2001/XMLSchema#boolean"
        >false</mygrid:authoritative>
        <j.0:creator rdf:datatype="http://www.w3.org/2001/XMLSchema#string"
        >your-email-address</j.0:creator>
      </mygrid:organisation>
    </mygrid:providedBy>
    <rdfs:label rdf:datatype="http://www.w3.org/2001/XMLSchema#string"
    >hello</rdfs:label>
    <mygrid:hasServiceNameText rdf:datatype="http://www.w3.org/2001/XMLSchema#string"
    >hello</mygrid:hasServiceNameText>
  </mygrid:serviceDescription>
</rdf:RDF>


比較テストがあるのでやってみる:
  1. メニューから'Run > Run Configurations …'を選択
  2. ダイアログ中,左ペインから'Maven Build > test sadi service'を選択


  3. ダイアログ中,右ペインのパラメタを修正
    
    serviceURL: http://localhost:8080/sadi-services/hello
    input     : http://sadiframework.org/test/hello-input.rdf
    expected  : http://sadiframework.org/test/hello-output.rdf (比較対象/予定されている出力(を,
    Modle.write()で書き出し直したモノ)
    



  4. ちなみにhello-input.rdfの中身はこんなの

    
    <rdf:RDF
        xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
        xmlns:foaf="http://xmlns.com/foaf/0.1/"
        xmlns:hello="http://sadiframework.org/examples/hello.owl#">
    
     <hello:NamedIndividual rdf:about="http://sadiframework.org/examples/hello-input.rdf#1">
      <foaf:name>Guy Incognito</foaf:name>
     </hello:NamedIndividual>
    
    </rdf:RDF>
    

    さらにちなむと,これをcom.hp.hpl.jena.rdf.model.Modelのreadメソッド読み込んでwriteメソッドで書き出すと以下のようになる.
    
    <rdf:RDF
        xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
        xmlns:foaf="http://xmlns.com/foaf/0.1/"
        xmlns:hello="http://sadiframework.org/examples/hello.owl#" > 
      <rdf:Description rdf:about="http://sadiframework.org/examples/hello-input.rdf#1">
        <foaf:name>Guy Incognito</foaf:name>
        <rdf:type rdf:resource="http://sadiframework.org/examples/hello.owl#NamedIndividual"/>
      </rdf:Description>
    </rdf:RDF>
    
  5. ちなみにhello-output.rdfの中身はこんなの

    
    <rdf:RDF
        xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
        xmlns:j.0="http://sadiframework.org/examples/hello.owl#" > 
      <rdf:Description rdf:about="http://sadiframework.org/examples/hello-input.rdf#1">
        <j.0:greeting>Hello, Guy Incognito!</j.0:greeting>
        <rdf:type rdf:resource="http://sadiframework.org/examples/hello.owl#GreetedIndividual"/>
      </rdf:Description>
    </rdf:RDF>
    
  6. ダイアログ中,'Run'ボタンを押す
上手く行けばConsoleに'[INFO] BUILD SUCCESS'と出ている.


curlを使ってアクセスしてみる:

$ cat hello-input.rdf
<rdf:RDF
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:foaf="http://xmlns.com/foaf/0.1/"
    xmlns:hello="http://sadiframework.org/examples/hello.owl#">

 <hello:NamedIndividual rdf:about="http://sadiframework.org/examples/hello-input.rdf#1">
  <foaf:name>Guy Incognito</foaf:name>
 </hello:NamedIndividual>

</rdf:RDF>
$ curl -d '@hello-input.rdf' http://localhost:8080/sadi-services/hello
<rdf:RDF
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:j.0="http://sadiframework.org/examples/hello.owl#">
  <j.0:GreetedIndividual rdf:about="http://sadiframework.org/examples/hello-input.rdf#1">
    <j.0:greeting>Hello, Guy Incognito!</j.0:greeting>
  </j.0:GreetedIndividual>
</rdf:RDF>

2回分並べて入力してみる:

$ cat hello-input2.rdf
<rdf:RDF
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:foaf="http://xmlns.com/foaf/0.1/"
    xmlns:hello="http://sadiframework.org/examples/hello.owl#">

 <hello:NamedIndividual rdf:about="http://sadiframework.org/examples/hello-input.rdf#1">
  <foaf:name>Guy Incognito</foaf:name>
 </hello:NamedIndividual>

 <hello:NamedIndividual rdf:about="http://sadiframework.org/examples/hello-input.rdf#2">
  <foaf:name>Gal Incognito</foaf:name>
 </hello:NamedIndividual>

</rdf:RDF>
$ curl -d '@hello-input2.rdf' http://localhost:8080/sadi-services/hello
<rdf:RDF
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:j.0="http://sadiframework.org/examples/hello.owl#">
  <j.0:GreetedIndividual rdf:about="http://sadiframework.org/examples/hello-input.rdf#2">
    <j.0:greeting>Hello, Gal Incognito!</j.0:greeting>
  </j.0:GreetedIndividual>
  <j.0:GreetedIndividual rdf:about="http://sadiframework.org/examples/hello-input.rdf#1">
    <j.0:greeting>Hello, Guy Incognito!</j.0:greeting>
  </j.0:GreetedIndividual>
</rdf:RDF>

2012年10月6日土曜日

'rdf format' to 'png image'

やり方
コード等はtumblrに書きました
結果
$ vi DescribingEricMiller.rdf
<?xml version="1.0"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
             xmlns:contact="http://www.w3.org/2000/10/swap/pim/contact#">

  <contact:Person rdf:about="http://www.w3.org/People/EM/contact#me">
    <contact:fullName>Eric Miller</contact:fullName>
    <contact:mailbox rdf:resource="mailto:em@w3.org"/>
    <contact:personalTitle>Dr.</contact:personalTitle> 
  </contact:Person>

</rdf:RDF>
reference: 'Example 1: RDF/XML Describing Eric Miller' in http://www.w3.org/TR/rdf-primer/#example1
$ ./a.out DescribingEricMiller.rdf Eric.png
  • コード中の"dot"を変えればLayoutが変わります."circo"とか?
  • コード中の"png"を変えれば出力形式が変わります."svg"とか?

2012年10月2日火曜日

“SPARQL query with OPTIONAL to two remote SPARQL endpoints”をやってみる(やっただけ)

参考: 2.2 SPARQL query with OPTIONAL to two remote SPARQL endpoints
参考をopenrdf-sesame 2.6.9 + tomcat (6.0.35 (今回IP:192.168.0.33) / 7.0.30 (今回IP:192.168.0.18) )で行う.
(注意: tomcat-7.0.30 では localhost:8080/openrdf-sesame にアクセスすると404を返すが,localhost:8080/openrdf-workbench へアクセスするとCurrent Selections/Sesame serverの項に表記されるので,応答はしているようである.)
1. 前々回を参考に一台目(今回IP:192.168.0.33)peopleというMemory storeを作成し,下記(参考より)を登録する.
  @prefix foaf:  <http://xmlns.com/foaf/0.1/> .
  @prefix : <http://example.org/> .
  
  :people15  foaf:name     "Alice" .
  :people16  foaf:name     "Bob" .
  :people17  foaf:name     "Charles" .
  :people17  foaf:interest     <http://www.w3.org/2001/sw/rdb2rdf/> .

2. 同じく前々回を参考にニ台目(今回IP:192.168.0.18)people2というMemory storeを作成し,下記(参考より)を登録する.
  @prefix foaf:  <http://xmlns.com/foaf/0.1/> .
  @prefix : <http://example.org/> .
  
  :people15  foaf:knows    :people18 . 
  :people18  foaf:name     "Mike" .
  :people17  foaf:knows    :people19 . 
  :people19  foaf:name     "Daisy" .

3. 一台目もしくは二台目のworkbenchより下記(参考より)のSPARQL Queryを送信する(どちらからでも問題はない).
PREFIX foaf:   <http://xmlns.com/foaf/0.1/>
SELECT ?name ?interest ?known
WHERE
{
  SERVICE <http://192.168.0.33:8080/openrdf-sesame/repositories/people> { 
    ?person foaf:name ?name .  
    OPTIONAL { 
      ?person foaf:interest ?interest .
      SERVICE <http://192.168.0.18:8080/openrdf-sesame/repositories/people2> { 
        ?person foaf:knows ?known . } }
  }    
}

赤字の部分は参考では'people'になっていたが(2012/10/2現在), 参考内のQuery Resultと合わせるには'name'にする必要がある.
4. Query Resultを確認する.

基本は以下のQuery
PREFIX foaf:   <http://xmlns.com/foaf/0.1/>
SELECT ?name
WHERE
{
  SERVICE <http://192.168.0.33:8080/openrdf-sesame/repositories/people> { 
    ?person foaf:name ?name .  
  }    
}

一台目(192.168.0.33)でなら以下でもよい
PREFIX foaf:   <http://xmlns.com/foaf/0.1/>
SELECT ?name
WHERE
{
  ?person foaf:name ?name .      
}


上のQueryの場合の結果

2012年9月28日金曜日

別のRDFS推論を試す(三段論法?) / openrdf-sesame 2.6.9のjar

前々回参考サイトにある別のRDFS推論(3段論法的?)を試す.
RDFS推論 以下のN3ファイルから
@prefix kb:  <http://knowledgebooks.com/ontology#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs:  <http://www.w3.org/2000/01/rdf-schema#> .
@prefix foaf: <http://xmlns.com/foaf/0.1/#> .

foaf:Person rdfs:subClassOf foaf:Agent .
kb:KnowledgeEngineer rdfs:subClassOf foaf:Person .

<http://www.markwatson.com/index.rdf> a kb:KnowledgeEngineer .
次のSPARQL Queryを実行して
PREFIX foaf:  <http://xmlns.com/foaf/0.1/#>
   SELECT ?subject ?predicate WHERE { ?subject ?predicate foaf:Agent . }
foaf:Agentとして以下を得る.
 http://xmlns.com/foaf/0.1/#Person http://www.w3.org/2000/01/rdf-schema#subClassOf
 http://xmlns.com/foaf/0.1/#Agent http://www.w3.org/2000/01/rdf-schema#subClassOf
 http://knowledgebooks.com/ontology#KnowledgeEngineer http://www.w3.org/2000/01/rdf-schema#subClassOf
 http://www.markwatson.com/index.rdf http://www.w3.org/1999/02/22-rdf-syntax-ns#type
下記のような関係を見つけることになる.
コード
ファイル読み込みではなく,途中トリプルを一つ一つ入れて(赤い部分)みた.
import java.io.File;
import java.io.IOException;
import java.util.List;

import org.openrdf.model.Resource;
import org.openrdf.model.URI;
import org.openrdf.model.Value;
import org.openrdf.model.impl.URIImpl;
import org.openrdf.query.BindingSet;
import org.openrdf.query.MalformedQueryException;
import org.openrdf.query.QueryEvaluationException;
import org.openrdf.query.QueryLanguage;
import org.openrdf.query.TupleQuery;
import org.openrdf.query.TupleQueryResult;
import org.openrdf.repository.RepositoryException;
import org.openrdf.repository.sail.SailRepository;
import org.openrdf.repository.sail.SailRepositoryConnection;
import org.openrdf.rio.RDFFormat;
import org.openrdf.rio.RDFParseException;
import org.openrdf.sail.inferencer.fc.ForwardChainingRDFSInferencer;
import org.openrdf.sail.memory.MemoryStore;

public class Sesame_Test {

 /**
  * @param args
  * @throws RepositoryException
  * @throws IOException
  * @throws RDFParseException
  * @throws QueryEvaluationException
  * @throws MalformedQueryException
  */
 public static void main(String[] args) throws RepositoryException,
   RDFParseException, IOException, MalformedQueryException,
   QueryEvaluationException {
  MemoryStore ms = new MemoryStore();
  ForwardChainingRDFSInferencer fci = new ForwardChainingRDFSInferencer(
    ms);
  SailRepository myRepository = new SailRepository(fci);
  myRepository.initialize();
  SailRepositoryConnection con = myRepository.getConnection();
  
  if (true) {
   {
    Resource s = new URIImpl("http://xmlns.com/foaf/0.1/#Person");
    URI p = new URIImpl(
      "http://www.w3.org/2000/01/rdf-schema#subClassOf");
    Value o = new URIImpl("http://xmlns.com/foaf/0.1/#Agent");
    con.add(s, p, o);
   }
   {
    Resource s = new URIImpl(
      "http://knowledgebooks.com/ontology#KnowledgeEngineer");
    URI p = new URIImpl(
      "http://www.w3.org/2000/01/rdf-schema#subClassOf");
    Value o = new URIImpl("http://xmlns.com/foaf/0.1/#Person");
    con.add(s, p, o);
   }
   {
    Resource s = new URIImpl("http://www.markwatson.com/index.rdf");
    URI p = new URIImpl(
      "http://www.w3.org/1999/02/22-rdf-syntax-ns#type");
    // The 'a' in Notation3 format means the
    // 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' in URI;
    Value o = new URIImpl(
      "http://knowledgebooks.com/ontology#KnowledgeEngineer");
    con.add(s, p, o);
   }
  } else {
    File file = new File("rdf_files/class_example.n3");
    con.add(file, null, RDFFormat.N3);
  }
  
  String sparql_query = "PREFIX foaf:  <http://xmlns.com/foaf/0.1/#>";
  sparql_query += " SELECT ?subject ?predicate WHERE { ?subject ?predicate foaf:Agent . }";
  TupleQuery tupleQuery = con.prepareTupleQuery(QueryLanguage.SPARQL,
    sparql_query);
  TupleQueryResult result = tupleQuery.evaluate();

  try {
   List<String> bindingNames = result.getBindingNames();
   while (result.hasNext()) {
    BindingSet bindingSet = result.next();
    int size2 = bindingSet.size();
    for (int i = 0; i < size2; i++) {
     System.out.print('\t' + bindingSet.getValue(
       bindingNames.get(i)).stringValue());
    }
    System.out.print('\n');
   }
  } finally {
   result.close();
  }
 }
}
jarは前々回を参照してもらうか,めんどくさければopenrdf-sesame-2.6.9-sdk.zip展開後のlibフォルダにあるの全部.

openrdf-sesameに付いてくるopenrdf-workbenchからRDFS推論をするまで

前回エントリーの内容を前々回エントリーで作成したopenrdf-sesame serverとworkbenchから試みる.また最後にJavaを用いてSesame ServerへSPARQL Queryで問い合わせることを試みる.
1. とりあえずSesame Serverが動作しているか確認
http://localhost:8080/openrdf-sesame
にアクセスして動作してみる
2. とりあえずWorkbenchにアクセスする
http://localhost:8080/openrdf-workbench
にアクセスして動作してみる
3. Repositoryを作る(とりあえず実行できる程度の内容)
a. 左メニューよりRepositories/New repositoryを選択
b. 作成するRepositoryのTypeを指定(Typeとして'Memory store with RDF Schema inferencing' RDFS推論を行うため!)
c. 'Create'ボタンにてRepositoryを作成
d. できあがったRepository詳細の表示(Current Selectionsに指定されていることを確認)

ちなみにここの'Summary/Repository Location/Location'のURLがSPARQL QueryのEndpointになる
4. ファイルアップロードによりRDF data(news.n3)を追加する
a. 左メニューよりModify/Addを選択
b. 'Base URI:'にある'use base URI as context identifier'のチェックを外す,'RDF Data File:'にある'Select the file containing the RDF data you wish to upload'をセレクト, 'ファイル選択'にてnews.n3(前回エントリー参照)を選択,'Upload'ボタンにてファイルをアップロード
c. 結果画面としてSummaryのページの表示を確認
d. 左メニューの'Explore/Export'にてアップロードされた内容が入っていることを確認(可能)
5. SPARQL Queryを実行する
a. 左メニューより'Explore/Query'を選択
b. 'Query:'にクエリを記述,'Execute'ボタンにて実行('Include inferred statements'のチェックは外さない)
PREFIX kb:   SELECT ?subject ?object WHERE { ?subject kb:containsPlace ?object . }

c. 結果の確認
番外編: JavaでEndpointへQueryを投げてみる
ライブラリは前回エントリーの状態にさらに,lib/commons-httpclient-3.1.jar, lib/commons-codec-1.4.jarを加える.またcommons-logging.jarも加えるのだがこれはopenrdf-sesame-*-sdk.zipに入っていないのでサイトから取得する.
import java.io.IOException;
import java.util.List;

import org.openrdf.query.BindingSet;
import org.openrdf.query.MalformedQueryException;
import org.openrdf.query.QueryEvaluationException;
import org.openrdf.query.QueryLanguage;
import org.openrdf.query.TupleQuery;
import org.openrdf.query.TupleQueryResult;
import org.openrdf.repository.RepositoryConnection;
import org.openrdf.repository.RepositoryException;
import org.openrdf.repository.sparql.SPARQLRepository;
import org.openrdf.rio.RDFParseException;

public class Sesame_Test {

 public static void main(String[] args) throws RepositoryException,
   MalformedQueryException, QueryEvaluationException,
   RDFParseException, IOException {

  String queryEndpointUrl = "http://localhost:8080/openrdf-sesame/repositories/memory-rdfs";
  SPARQLRepository myRepository = new SPARQLRepository(queryEndpointUrl);
  myRepository.initialize();
  RepositoryConnection con = myRepository.getConnection();

  String sparql_query = "PREFIX kb: <http://knowledgebooks.com/ontology#> SELECT ?subject ?object WHERE { ?subject kb:containsPlace ?object . }";

  TupleQuery tupleQuery = con.prepareTupleQuery(QueryLanguage.SPARQL,
    sparql_query);
  //tupleQuery.setIncludeInferred(true); //this property's default value is true.

  TupleQueryResult result = tupleQuery.evaluate();

  try {
   List<String> bindingNames = result.getBindingNames();
   while (result.hasNext()) {
    BindingSet bindingSet = result.next();
    for (int i = 0; i < bindingSet.size(); i++) {
     String val = bindingSet.getValue(bindingNames.get(i))
       .stringValue();
     System.out.print('\t' + val);
    }
    System.out.print('\n');
   }
  } finally {
   result.close();
  }
 }

}

2012年9月27日木曜日

openrdf-sesae 2.6.9のjarを用いてRDFS推論の例を真似してみた(だけ).

参考 Java/JRuby開発者のためのセマンティックWeb入門
参考サイトのRDFS推論の例の実行をopenrdf-sesame 2.6.9のjarで試みる
news.n3を読み込み次のsparql queryによって結果を得る
sparql query
PREFIX kb:  <http://knowlegebooks.com/ontology/#> SELECT ?subject ?object WHERE { ?subject kb:containsPlace ?object . }
news.n3 (参考サイトのサンプルソース内ファイル.以下は参照サイトのリスト5にある同ファイルの最初の数行)
@prefix kb: <http://knowledgebooks.com/ontology#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .

kb:containsCity rdfs:subPropertyOf kb:containsPlace .
kb:containsCountry rdfs:subPropertyOf kb:containsPlace .
kb:containsState rdfs:subPropertyOf kb:containsPlace .

<http://news.yahoo.com/s/nm/20080616/ts_nm/usa_flooding_dc_16 /> kb:containsCity "Burlington" , "Denver" , "St. Paul" , "Chicago" , "Quincy" , "CHICAGO" , "Iowa City" ;
  kb:containsRegion "U.S. Midwest" , "Midwest" ;
  kb:containsCountry "United States" , "Japan" ;
  kb:containsState "Minnesota" , "Illinois" , "Mississippi" , "Iowa" ;
  kb:containsOrganization "National Guard" , "U.S. Department of Agriculture" , "White House" , "Chicago Board of Trade" , "Department of Transportation" ;
  kb:containsPerson "Dena Gray-Fisher" , "Donald Miller" , "Glenn Hollander" , "Rich Feltes" , "George W. Bush" ;
  kb:containsIndustryTerm "food inflation" , "food" , "finance ministers" , "oil" .

上記部分だけではあるが,図示すると以下の2つの図のようになる.
(ただし,
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX kb: <http://knowledgebooks.com/ontology#>
)


( predicateとしてkb:containsPlaceというURIは,このnews.n3ファイルにはない.)

やったこと
1. Eclipse内にJava Project('Sesame_Test')を作成.
2. openrdf-sesame-2.6.9/libをImport.
3. lib/sesame-query*.jar, lib/sesame-repository-*.jar, lib/sesame-rio-*.jar, lib/sesame-sail-*.jar, lib/sesame-util-*.jar, lib/slf4j-api-*.jarをBuild Pathに追加.
4. 参照サイトのサンプルソース内'rdf_files/news.n3'をImport.
5. Sample_Test.javaクラスを作成.
import java.io.File;
import java.io.IOException;
import java.util.List;

import org.openrdf.query.BindingSet;
import org.openrdf.query.MalformedQueryException;
import org.openrdf.query.QueryEvaluationException;
import org.openrdf.query.QueryLanguage;
import org.openrdf.query.TupleQuery;
import org.openrdf.query.TupleQueryResult;
import org.openrdf.repository.RepositoryException;
import org.openrdf.repository.sail.SailRepository;
import org.openrdf.repository.sail.SailRepositoryConnection;
import org.openrdf.rio.RDFFormat;
import org.openrdf.rio.RDFParseException;
import org.openrdf.sail.inferencer.fc.ForwardChainingRDFSInferencer;
import org.openrdf.sail.memory.MemoryStore;

public class Sesame_Test {

 private static SailRepository myRepository;
 private static SailRepositoryConnection con;

 /**
  * @param args
  * @throws RepositoryException
  * @throws IOException
  * @throws RDFParseException
  * @throws QueryEvaluationException
  * @throws MalformedQueryException
  */
 public static void main(String[] args) throws RepositoryException,
   RDFParseException, IOException, MalformedQueryException,
   QueryEvaluationException {
  MemoryStore ms = new MemoryStore();
  ForwardChainingRDFSInferencer fci = new ForwardChainingRDFSInferencer(
    ms);
  myRepository = new SailRepository(fci);
  myRepository.initialize();
  System.out.println(myRepository);
  con = myRepository.getConnection();

  File file = new File("rdf_files/news.n3");
  con.add(file, null, RDFFormat.N3); //the news.n3 file doesn't require the 'baseURI'. (?)

  String sparql_query = "PREFIX kb: <http://knowledgebooks.com/ontology#> SELECT ?subject ?object WHERE { ?subject kb:containsPlace \"Japan\" . }";

  TupleQuery tupleQuery = con.prepareTupleQuery(QueryLanguage.SPARQL,
    sparql_query);
  TupleQueryResult result = tupleQuery.evaluate();
  
  try {
   List<String> bindingNames = result.getBindingNames();
   while (result.hasNext()) {
    BindingSet bindingSet = result.next();
    int size2 = bindingSet.size();
    for (int i = 0; i < size2; i++) {
     String val = bindingSet.getValue(bindingNames.get(i))
       .stringValue();
     System.out.print('\t');
     System.out.print(val);
    }
    System.out.print('\n');
   }
  } finally {
   result.close();
  }
 }

}

ここまでのプロジェクトの状態(Package Explorer)


結果(最初の数行)
 http://news.yahoo.com/s/nm/20080616/ts_nm/usa_flooding_dc_16 / Burlington
 http://news.yahoo.com/s/nm/20080616/ts_nm/usa_flooding_dc_16 / Denver
 http://news.yahoo.com/s/nm/20080616/ts_nm/usa_flooding_dc_16 / St. Paul
 http://news.yahoo.com/s/nm/20080616/ts_nm/usa_flooding_dc_16 / Chicago
 http://news.yahoo.com/s/nm/20080616/ts_nm/usa_flooding_dc_16 / Quincy
…

news.n3でなく,rdfs.ntとnews.ntをそれぞれ読み込んむ場合は上記コードの赤色部分を以下のように変更する.
(rdfs.nt, news.nt内では'knowledgebooks.com/ontology'に関するURI先頭が'http://'でなく'http:://'となっているのでsparql queryも変更)
  File rdfs_file = new File("rdf_files/rdfs.nt");
  con.add(rdfs_file, null, RDFFormat.NTRIPLES); //the rdfs.nt file doesn't require the 'baseURI'. (?)
  File news_file = new File("rdf_files/news.nt"); 
  con.add(news_file, null, RDFFormat.NTRIPLES); //the news.nt file doesn't require the 'baseURI'. (?)

  String sparql_query = "PREFIX kb: <http:://knowledgebooks.com/ontology#> SELECT ?subject ?object WHERE { ?subject kb:containsPlace ?object . }";


openrdf-sesame 2.6.9 's war ( tomcat 6.0.35 / mac os 10.8.2 )

$ unzip openrdf-sesame-2.6.9-sdk.zip
$ unzip apache-tomcat-6.0.35.zip
$ chmod a+x /path/to/apache-tomcat-6.0.35/bin/*.sh
$ cp -p /path/to/openrdf-sesame-2.6.9/war/*.war /path/to/apache-tomcat-6.0.35/webapps/
$ /path/to/apache-tomcat-6.0.35/bin/startup.sh
$ open http://localhost:8080/open-sesame
if you can access the page, you can find following folder.
/Users/[user]/Library/Application Support/Aduna/OpenRDF Sesame/
if you found following folder.
/Users/[user]/Library/Application Support/Aduna/OpenRDF/
you edit the file ( /path/to/apache-tomcat-6.0.35/webapps/open-sesame/WEB-INF/openrdf-http-server-servlet.xml ). the 'applicationId','longName' properties which are in the 'adunaAppConfig' bean element are modified from 'OpenRDF Sesame' to 'OpenRDF_Sesame'. and restart the server.
$ open http://localhost:8080/openrdf-workbench

2012年9月24日月曜日

Rails で Turtle ( .ttl ) を書き出す(単にフォーマットの追加)

参考: Linked Data on Rails
$ rails new turtleTest
$ cd turtleTest
$ rails generate scaffold user username:string
$ vi config/initializers/mime_types.rb //Edit
Mime::Type.register "text/turtle", :ttl
$ vi app/views/users/index.ttl.erb //Create
@prefix ns: <http://example.org/ns> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema> .

<% @users.each_with_index do |user, i| %>
_:a<%= (i+1) %> ns:name "<%= user.username %>"^^xsd:string .
<% end %>
$ vi app/views/users/show.ttl.erb //Create
@prefix ns: <http://example.org/ns> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema> .

_:a ns:username "<%= @user.username %>"^^xsd:string .
$ vi app/controllers/users_controller.rb //Edit
…
  def index
    @users = User.all

    respond_to do |format|
      format.html # index.html.erb
      format.json { render :json => @users }
      format.ttl
    end
  end
…
  def show
    @user = User.find(params[:id])

    respond_to do |format|
      format.html # show.html.erb
      format.json { render :json => @user }
      format.ttl
    end
  end
…
$ rake db:migrate
$ rails server
Result
http://0.0.0.0:3000/users.ttl
@prefix ns: <http://example.org/ns> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema> .

_:a0 ns:name "あいうえお"^^xsd:string .
_:a1 ns:name "かきくけこ"^^xsd:string .
http://0.0.0.0:3000/users/1.ttl
@prefix ns: <http://example.org/ns> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema> .

_:a ns:name "あいうえお"^^xsd:string .

2011年9月14日水曜日

メモ的: Twitterのhome_timelineの情報を無理矢理4storeに入れてみる(いろんな意味でいろいろ間違ってるとは思う)

  • OAuthConsumerフレームワーク('#import <OAuthConsumer/OAuthConsumer.h>')についてはこちら
  • 4storeのクライアントライブラリ(っぽいなにか)('#import "FourStore.h"')についてはこちら

    #import "TwTurtleAppDelegate.h"
    #import <OAuthConsumer/OAuthConsumer.h>
    #import "FourStore.h"

    @implementation TwTurtleAppDelegate

    @synthesize window;

    - (void)applicationDidFinishLaunching:(NSNotification *)aNotification
    {
    OAConsumer *consumer = [[OAConsumer alloc] initWithKey:@"XXXXXXXXXXXXXXXXXXXXXX"
    secret:@"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"];

    OAToken *accessToken= [[OAToken alloc] initWithKey:@"XXXXXXX-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
    secret:@"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"];

    NSURL *url= [NSURL URLWithString:@"http://api.twitter.com/1/statuses/home_timeline.xml"];
    OAMutableURLRequest *requestWithBodyParams = [[[OAMutableURLRequest alloc] initWithURL:url
    consumer:consumer
    token:accessToken
    realm:nil
    signatureProvider:nil] autorelease];

    OADataFetcher *fetcher = [[[OADataFetcher alloc] init] autorelease];

    [fetcher fetchDataWithRequest:requestWithBodyParams
    delegate:self
    didFinishSelector:@selector(apiTicket:didFinishWithData:)
    didFailSelector:@selector(apiTicket:didFailWithError:)];

    }
    - (void)fourstoreWithTurtle:(NSString *)turtle
    {
    FourStore *store= [[FourStore alloc] initWithEndpoint:@"http://localhost:8000/sparql/"];
    [store addPrefix:@"tsp" uri:@"http://example.org/twitter/status/predicate/"];
    [store addPrefix:@"tu" uri:@"http://example.org/twitter/users/"];

    NSString *message0= [store deleteWithGraph:@"http://example.org/twitter/status/"];
    NSLog(@"message0 %@", message0);


    NSString *message1= [store addTurtle:turtle graph:@"http://example.org/twitter/status/"];
    NSLog(@"message1 %@", message1);

    NSString *message2= [store queryWithString:
    @"SELECT ?s ?p ?o \nWHERE {\nGRAPH <http://example.org/twitter/status/> {\n?s ?p ?o .\n}\n}\n"];
    NSLog(@"message2 \n%@", message2);

    }
    - (NSString *)createTurtleWithXMLData:(NSData *)data
    {
    NSMutableString *turtle= [NSMutableString string];

    NSXMLDocument *document = [[[NSXMLDocument alloc] initWithData:data
    options:NSXMLDocumentTidyHTML
    error:NULL] autorelease];
    NSError *error= nil;
    NSArray *nodes = [document nodesForXPath:@"//status" error:&error];
    NSEnumerator *nodesEnum= [nodes objectEnumerator];
    NSXMLNode *node= nil;
    while(node= [nodesEnum nextObject]) {
    NSArray *idnodes= [node nodesForXPath:@"id" error:&error];
    if ([idnodes count]==0) continue;
    NSString *idString= [[idnodes objectAtIndex:0] stringValue];
    NSEnumerator *childrenEnum= [[node children] objectEnumerator];
    NSXMLNode *child=nil;
    while(child= [childrenEnum nextObject]) {
    NSString *name= [child name];
    if ([name isEqualToString:@"id"])
    continue;
    NSString *value= nil;
    if ([name isEqualToString:@"retweeted_status"]){
    NSArray *cidnodes= [child nodesForXPath:@"id" error:&error];
    if ([cidnodes count]==0) continue;
    NSString *cidString= [[cidnodes objectAtIndex:0] stringValue];
    value= [NSString stringWithFormat:@"<%@>", cidString];
    } else if ([name isEqualToString:@"user"]){
    NSArray *cidnodes= [child nodesForXPath:@"id" error:&error];
    if ([cidnodes count]==0) continue;
    NSString *cidString= [[cidnodes objectAtIndex:0] stringValue];
    value= [NSString stringWithFormat:@"<tu:%@>", cidString];
    } else {
    if ([[child stringValue] length]==0) continue;
    value= [child stringValue];
    value= [value stringByReplacingOccurrencesOfString:@"\"" withString:@"\\\""];
    value= [value stringByReplacingOccurrencesOfString:@"\n" withString:@"\\n"];
    value= [NSString stringWithFormat:@"\"%@\"", value];
    }

    [turtle appendFormat:@"<%@> tsp:%@ %@ .\n", idString, name, value];
    }
    }


    return turtle;
    }
    - (void)apiTicket:(OAServiceTicket *)ticket
    didFinishWithData:(NSData *)data
    {

    if (0)
    NSLog(@"didFinish %@", [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease]);

    NSString *turtle= [self createTurtleWithXMLData:data];

    if (0)
    NSLog(@"\n%@", turtle);

    [self fourstoreWithTurtle:turtle];
    }
    - (void)apiTicket:(OAServiceTicket *)ticket
    didFailWithError:(NSError *)error
    {

    NSLog(@"%@", error);
    }
    @end



    やってみてアレコレ悩んだ足跡.
  • 2011年9月12日月曜日

    Cocoa ( Objective-C )での 4store の Client Library (?)

    動機
    4storeを入れてみた.rubyのclient用ライブラリをみて,似たものをcocoaでやってみようと思った(たぶん既にどこかにあるだろうけど).
    入れる際(環境: MacOSX10.7)にハマった点
  • MacPortsでraptorとrasqalを入れたのだがraptorに1.x(www/raptor)と2.x(www/raptor2)があり, rasqal0.9.26がraptor2.xを利用して入っているのにraptor 1.xが入ったままだと4storeのmake時にエラーがでたこと.
  • "git clone https://github.com/garlik/4store.git"でとってきたらconfigureがなかったので(そういうものなのかな?), "sh autogen.sh"から始めたこと.



  • やってみた(rubyにあるload作ってないしsetもマネの途中)
    FourStore.h

    @interface FourStore : NSObject
    {
    NSURL *_urlSPARQL;
    NSURL *_urlDATA;
    NSMutableArray *_prefixs;
    }
    - (id)initWithEndpoint:(NSString *)endpoint;
    - (void)addPrefix:(NSString *)prefix uri:(NSString *)uri;
    - (NSString *)addTurtle:(NSString *)turtle graph:(NSString *)graph;
    //- (NSString *)setTurtle:(NSString *)turtle graph:(NSString *)graph;
    - (NSString *)queryWithString:(NSString *)query;
    - (NSString *)deleteWithGraph:(NSString *)graph;
    @end

    FourStore.m

    #import "FourStore.h"

    @implementation FourStore

    - (id)init
    {
    self = [super init];
    if (self) {
    }
    return self;
    }
    - (id)initWithEndpoint:(NSString *)endpoint
    {
    if (![endpoint hasSuffix:@"/sparql/"]) {
    return nil;
    }
    self = [self init];
    if (self) {
    _urlSPARQL= [[NSURL URLWithString:endpoint] retain];
    NSArray *ary= [endpoint componentsSeparatedByString:@"/sparql/"];
    _urlDATA= [[NSURL URLWithString:[NSString stringWithFormat:@"%@/data/", [ary objectAtIndex:0]]] retain];
    _prefixs= [[NSMutableArray array] retain];
    }
    return self;
    }
    - (void)dealloc
    {
    [_urlSPARQL release];
    [_urlDATA release];
    [super dealloc];
    }
    + (NSString *)sendRequest:(NSURLRequest *)request
    {
    NSURLResponse *response=nil;
    NSError *error= nil;
    NSData *data= [NSURLConnection sendSynchronousRequest:request
    returningResponse:&response
    error:&error];
    if (error) {
    NSLog(@"statusCode %ld", [response statusCode]);
    NSLog(@"error code %ld", [error code]);
    }

    NSString *message= [[NSString alloc] initWithData:data
    encoding:NSUTF8StringEncoding];
    return [message autorelease];
    }
    + (NSString *)send:(NSString *)request url:(NSURL *)url method:(NSString *)method
    {
    NSMutableURLRequest *requestWithBodyParams = [[NSMutableURLRequest alloc] initWithURL:url];
    NSData *requestData = [request dataUsingEncoding:NSASCIIStringEncoding
    allowLossyConversion:YES];
    [requestWithBodyParams setHTTPBody:requestData];
    [requestWithBodyParams setValue:[NSString stringWithFormat:@"%d", [requestData length]]
    forHTTPHeaderField:@"Content-Length"];
    [requestWithBodyParams setValue:@"application/x-www-form-urlencoded"
    forHTTPHeaderField:@"Content-Type"];
    [requestWithBodyParams setHTTPMethod:method];

    NSString *msg= [FourStore sendRequest:requestWithBodyParams];
    [requestWithBodyParams release];

    return msg;
    }

    - (void)addPrefix:(NSString *)prefix uri:(NSString *)uri
    {
    [_prefixs addObject:[NSDictionary dictionaryWithObjectsAndKeys:
    prefix, @"p", uri, @"u", nil]];
    }
    - (NSString *)prefixsOfQuery
    {
    NSMutableString *ret= [NSMutableString string];
    NSEnumerator *prefixsEnum= [_prefixs objectEnumerator];
    NSDictionary *dic;
    while(dic= [prefixsEnum nextObject]) {
    [ret appendFormat:@"PREFIX %@: <%@>\n", [dic objectForKey:@"p"], [dic objectForKey:@"u"]];
    }
    return [[ret retain] autorelease];
    }
    - (NSString *)prefixsOfTurtle
    {
    NSMutableString *ret= [NSMutableString string];
    NSEnumerator *prefixsEnum= [_prefixs objectEnumerator];
    NSDictionary *dic;
    while(dic= [prefixsEnum nextObject]) {
    [ret appendFormat:@"@prefix %@: <%@> .\n", [dic objectForKey:@"p"], [dic objectForKey:@"u"]];
    }
    return [[ret retain] autorelease];
    }
    - (NSString *)queryWithString:(NSString *)query
    {
    NSString *fullquery= [NSString stringWithFormat:@"%@%@", [self prefixsOfQuery], query];

    NSString *request= [NSString stringWithFormat:@"query=%@&soft-limit=%@",
    [fullquery stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding], @""];

    return [FourStore send:request url:_urlSPARQL method:@"POST"];
    }
    - (NSString *)addTurtle:(NSString *)turtle graph:(NSString *)graph
    {
    NSString *fullturtle= [NSString stringWithFormat:@"%@%@", [self prefixsOfTurtle], turtle];

    NSString *request= [NSString stringWithFormat:@"mime-type=%@&data=%@&graph=%@",
    [@"application/x-turtle" stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding],
    [fullturtle stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding],
    [graph stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];

    return [FourStore send:request url:_urlDATA method:@"POST"];
    }
    //- (NSString *)setTurtle:(NSString *)turtle graph:(NSString *)graph
    //{
    // NSString *fullturtle= [NSString stringWithFormat:@"%@%@", [self prefixsOfTurtle], turtle];
    //
    // NSString *request= [fullturtle stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    //
    // NSURL *url= [NSURL URLWithString:[NSString stringWithFormat:@"%@%@", [_urlDATA absoluteString], graph]];
    //
    // return [FourStore send:request url:url method:@"PUT"];
    //}
    - (NSString *)deleteWithGraph:(NSString *)graph
    {
    NSURL *url= [NSURL URLWithString:[NSString stringWithFormat:@"%@%@", [_urlDATA absoluteString], graph]];

    return [FourStore send:@"" url:url method:@"DELETE"];
    }
    @end



    使い方(?)

    FourStore *store= [[FourStore alloc] initWithEndpoint:@"http://localhost:8000/sparql/"];
    [store addPrefix:@"dc" uri:@"http://purl.org/dc/elements/1.1/"];

    if (1) {
    NSString *msg= [store addTurtle:@"<http://example.org/book/book1> dc:title \"SPARQL Tutorial\" ."
    graph:@"http://example.org/book"];
    NSLog(@"%@", msg);
    }
    if (1) {
    NSString *msg= [store queryWithString:
    @"SELECT ?title \nWHERE {\nGRAPH <http://example.org/book> {\n<http://example.org/book/book1> <http://purl.org/dc/elements/1.1/title> ?title .\n}\n}\n"];
    NSLog(@"%@", msg);

    }
    if (1) {
    NSString *msg= [store queryWithString:
    @"SELECT ?title \nWHERE {\nGRAPH <http://example.org/book> {\n<http://example.org/book/book1> dc:title ?title .\n}\n}\n"];
    NSLog(@"%@", msg);

    }
    if (1) {
    NSString *msg= [store deleteWithGraph:@"http://example.org/book"];
    NSLog(@"%@", msg);
    }

    [store release];


    結果

    (> 4s-backend-setup [KB])
    > 4s-backend [KB]
    > 4s-httpd -p 8000 -U [KB]


    > 200 added successfully
    This is a 4store SPARQL server v1.1.3-54-gd8008fc

    > <?xml version="1.0"?>
    <sparql xmlns="http://www.w3.org/2005/sparql-results#">
    <head>
    <variable name="title"/>
    </head>
    <results>
    <result>
    <binding name="title"><literal>SPARQL Tutorial</literal></binding>
    </result>
    </results>
    </sparql>

    > <?xml version="1.0"?>
    <sparql xmlns="http://www.w3.org/2005/sparql-results#">
    <head>
    <variable name="title"/>
    </head>
    <results>
    <result>
    <binding name="title"><literal>SPARQL Tutorial</literal></binding>
    </result>
    </results>
    </sparql>

    > 200 deleted successfully
    This is a 4store SPARQL server v1.1.3-54-gd8008fc

    2011年6月19日日曜日

    ARQを使ってSPARQLをやってみた2(FROMとFROM NAMEDの結合)

    これ('RDF用クエリ言語SPARQL/8.2.3 FROMとFROM NAMEDの結合')をやってみた.


    やってみた
    0.環境
    前回環境を参考

    1.データファイル
    data_8.2.1_1.ttl
    # Default graph (stored at http://example.org/dft.ttl)
    @prefix dc: <http://purl.org/dc/elements/1.1/> .

    <http://example.org/bob> dc:publisher "Bob Hacker" .
    <http://example.org/alice> dc:publisher "Alice Hacker" .


    data_8.2.1_2.ttl
    # Named graph: http://example.org/bob
    @prefix foaf: <http://xmlns.com/foaf/0.1/> .

    _:a foaf:name "Bob" .
    _:a foaf:mbox <mailto:bob@oldcorp.example.org> .


    data_8.2.1_3.ttl
    # Named graph: http://example.org/alice
    @prefix foaf: <http://xmlns.com/foaf/0.1/> .

    _:a foaf:name "Alice" .
    _:a foaf:mbox <mailto:alice@work.example.org> .

    各ファイルの'#'行はコメントなのでこれでナニカを定義しているわけではない.

    2.コード
    Test_8_2_3.java
    package sample;

    import org.openjena.atlas.lib.StrUtils;

    import com.hp.hpl.jena.query.DataSource;
    import com.hp.hpl.jena.query.DatasetFactory;
    import com.hp.hpl.jena.query.Query;
    import com.hp.hpl.jena.query.QueryExecution;
    import com.hp.hpl.jena.query.QueryExecutionFactory;
    import com.hp.hpl.jena.query.QueryFactory;
    import com.hp.hpl.jena.query.ResultSetFormatter;
    import com.hp.hpl.jena.rdf.model.Model;
    import com.hp.hpl.jena.rdf.model.ModelFactory;
    import com.hp.hpl.jena.util.FileManager;

    public class Test_8_2_3 {
    public static void main(String[] args) {
    Model model1 = ModelFactory.createDefaultModel();
    FileManager.get().readModel(model1, "data_8.2.3_1.ttl");
    Model model2 = ModelFactory.createDefaultModel();
    FileManager.get().readModel(model2, "data_8.2.3_2.ttl");
    Model model3 = ModelFactory.createDefaultModel();
    FileManager.get().readModel(model3, "data_8.2.3_3.ttl");

    DataSource dataSource= DatasetFactory.create();
    dataSource.setDefaultModel(model1);
    dataSource.addNamedModel("http://example.org/bob", model2);
    dataSource.addNamedModel("http://example.org/alice", model3);
    System.out.println(dataSource.asDatasetGraph().toString());
    System.out.println();


    String queryString = StrUtils.strjoin("\n",
    "PREFIX foaf: <http://xmlns.com/foaf/0.1/>",
    "PREFIX dc: <http://purl.org/dc/elements/1.1/>",
    "",
    "SELECT ?who ?g ?mbox",
    "FROM <http://example.org/dft.ttl>",
    "FROM NAMED <http://example.org/alice>",
    "FROM NAMED <http://example.org/bob>",
    "WHERE",
    "{",
    " ?g dc:publisher ?who .",
    " GRAPH ?g { ?x foaf:mbox ?mbox }",
    "}");
    Query query = QueryFactory.create(queryString);

    QueryExecution qExec = QueryExecutionFactory.create(query, dataSource);
    ResultSetFormatter.out(System.out, qExec.execSelect(), query);
    qExec.close();
    }
    }

    ('addNamedModelの第一引数の値で関連づけている)

    3.実行
    (dataset
    (graph
    (triple <http://example.org/alice> <http://purl.org/dc/elements/1.1/publisher> "Alice Hacker")
    (triple <http://example.org/bob> <http://purl.org/dc/elements/1.1/publisher> "Bob Hacker")
    )
    (graph <http://example.org/bob>
    (triple _:-335a33de:130a7151814:-7fff <http://xmlns.com/foaf/0.1/mbox> <mailto:bob@oldcorp.example.org>)
    (triple _:-335a33de:130a7151814:-7fff <http://xmlns.com/foaf/0.1/name> "Bob")
    )
    (graph <http://example.org/alice>
    (triple _:-335a33de:130a7151814:-7ffe <http://xmlns.com/foaf/0.1/mbox> <mailto:alice@work.example.org>)
    (triple _:-335a33de:130a7151814:-7ffe <http://xmlns.com/foaf/0.1/name> "Alice")
    ))



    ----------------------------------------------------------------------------------
    | who | g | mbox |
    ==================================================================================
    | "Alice Hacker" | <http://example.org/alice> | <mailto:alice@work.example.org> |
    | "Bob Hacker" | <http://example.org/bob> | <mailto:bob@oldcorp.example.org> |
    ----------------------------------------------------------------------------------



    ARQを使ってSPARQLをやってみた

    これ('RDF用クエリ言語SPARQL/2.1 シンプルなクエリの記述')をやってみた.

    やってみた.
    0.ARQ
    ARQはこちらのページから取得(ARQ-2.8.8).

    1.Eclipseプロジェクト
    Eclipseのプロジェクトにまるごと入れてlib中のjar上のコンテクストメニューにてBuild Path/Add to Build Pathにてパスを通す.

    2.コードを書く
    package sample;

    import org.openjena.atlas.lib.StrUtils;

    import com.hp.hpl.jena.query.Query;
    import com.hp.hpl.jena.query.QueryExecution;
    import com.hp.hpl.jena.query.QueryExecutionFactory;
    import com.hp.hpl.jena.query.QueryFactory;
    import com.hp.hpl.jena.query.ResultSetFormatter;
    import com.hp.hpl.jena.rdf.model.Model;
    import com.hp.hpl.jena.rdf.model.ModelFactory;
    import com.hp.hpl.jena.rdf.model.Resource;
    import com.hp.hpl.jena.vocabulary.DC;

    public class Test {
    public static void main(String[] args) {
    Model model = ModelFactory.createDefaultModel() ;
    Resource resource = model.createResource("http://example.org/book/book1");
    resource.addProperty(DC.title, "SPARQL Tutorial");

    String queryString = StrUtils.strjoin("\n",
    "SELECT ?title",
    "WHERE{",
    " <http://example.org/book/book1> <http://purl.org/dc/elements/1.1/title> ?title .",
    "}");
    Query query = QueryFactory.create(queryString);

    QueryExecution qExec = QueryExecutionFactory.create(query, model);
    ResultSetFormatter.out(System.out, qExec.execSelect(), query);
    qExec.close();
    }
    }


    データをファイルで与える場合:
    package sample;

    import org.openjena.atlas.lib.StrUtils;

    import com.hp.hpl.jena.query.Query;
    import com.hp.hpl.jena.query.QueryExecution;
    import com.hp.hpl.jena.query.QueryExecutionFactory;
    import com.hp.hpl.jena.query.QueryFactory;
    import com.hp.hpl.jena.query.ResultSetFormatter;
    import com.hp.hpl.jena.rdf.model.Model;
    import com.hp.hpl.jena.rdf.model.ModelFactory;
    import com.hp.hpl.jena.util.FileManager;

    public class Test {
    public static void main(String[] args) {
    Model model = ModelFactory.createDefaultModel();
    FileManager.get().readModel(model, "data.ttl");


    String queryString = StrUtils.strjoin("\n",
    "SELECT ?title",
    "WHERE{",
    " <http://example.org/book/book1> <http://purl.org/dc/elements/1.1/title> ?title .",
    "}");
    Query query = QueryFactory.create(queryString);

    QueryExecution qExec = QueryExecutionFactory.create(query, model);
    ResultSetFormatter.out(System.out, qExec.execSelect(), query);
    qExec.close();
    }
    }

    'data.ttl'ファイル.拡張子はttlである必要があるみたい(?).
    <http://example.org/book/book1> <http://purl.org/dc/elements/1.1/title> "SPARQL Tutorial" .


    3.実行(画像をクリックで拡大)


    追記
    'RDF用クエリ言語SPARQL/2.2 複数マッチ'の実行(画像をクリックで拡大)


    追記2
    'RDF用クエリ言語SPARQL/2.3 RDFリテラルのマッチング'の実行(画像をクリックで拡大)