Jena Ontology API 예제소스 (1)
- Study/OWL,RDF
- 2014. 2. 11. 22:11
일단 소스코드는 소스포지에서 다운받습니다.
http://sourceforge.net/projects/jena/files/Jena/
소스코드라기보다는 Jena API를 통채로 받습니다. 그 안에 예제 온톨로지와 소스코드가 들어있습니다.
최신버전을 받고 압축을 푼다음 src-examples/jena/examples/ontology에 가면 3가지 예제가 있습니다. 하나씩 파보면서 jena API에 사용법을 몸에 적응시켜 보겠습니다. ㅎㅎ
첫번째로 볼 소스는 ClassHierarchy입니다. 실행을 한번 시켜봤는데 온톨로지를 읽어들여서 클래스로 나열시켜주는 간단한 기능인것 같습니다. 두개의 java파일로 만들어져 있는데 일단 Main.java를 보도록 하겠습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | /***************************************************************************** * Source code information * ----------------------- * Original author Ian Dickinson, HP Labs Bristol * Author email ian_dickinson@users.sourceforge.net * Package Jena 2 * Web http://sourceforge.net/projects/jena/ * Created 22-Aug-2003 * Filename $RCSfile: Main.java,v $ * Revision $Revision: 1.3 $ * Release status $State: Exp $ * * Last modified on $Date: 2009/10/06 13:04:43 $ * by $Author: ian_dickinson $ * * (c) Copyright 2002, 2003, 2004, 2005 Hewlett-Packard Development Company, LP * (see footer for full conditions) *****************************************************************************/ // Package /////////////// // Imports /////////////// import com.hp.hpl.jena.ontology.*; import com.hp.hpl.jena.rdf.model.ModelFactory; /** * <p> * Execution wrapper for class hierarchy example * </p> * * @author Ian Dickinson, HP Labs * (<a href="mailto:ian_dickinson@users.sourceforge.net" >email</a>) * @version CVS $Id: Main.java,v 1.3 2009/10/06 13:04:43 ian_dickinson Exp $ */ public class Main { // Constants ////////////////////////////////// // Static variables ////////////////////////////////// // Instance variables ////////////////////////////////// // Constructors ////////////////////////////////// // External signature methods ////////////////////////////////// public static void main( String[] args ) { OntModel m = ModelFactory.createOntologyModel( OntModelSpec.OWL_MEM, null ); // we have a local copy of the wine ontology m.getDocumentManager().addAltEntry( "http://www.w3.org/2001/sw/WebOnt/guide-src/wine", "file:c:/testing/reasoners/bugs/wine.owl" ); m.getDocumentManager().addAltEntry( "http://www.w3.org/2001/sw/WebOnt/guide-src/wine.owl", "file:c:/testing/reasoners/bugs/wine.owl" ); m.getDocumentManager().addAltEntry( "http://www.w3.org/2001/sw/WebOnt/guide-src/food", "file:c:/testing/reasoners/bugs/food.owl" ); m.getDocumentManager().addAltEntry( "http://www.w3.org/2001/sw/WebOnt/guide-src/food.owl", "file:c:/testing/reasoners/bugs/food.owl" ); m.read( "http://www.w3.org/2001/sw/WebOnt/guide-src/wine" ); new ClassHierarchy().showHierarchy( System.out, m ); } // Internal implementation methods ////////////////////////////////// //============================================================================== // Inner class definitions //============================================================================== } /* (c) Copyright 2002, 2003, 2004, 2005 Hewlett-Packard Development Company, LP All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ |
기본적으로 영어주석이 달려있어서 코드가 길어졌네요 ^^; 실제적인 코드는 10~20줄 밖에 안됩니다. Main 부분에서는 단지 모델을 생성한다음 온톨로지를 읽어오는 부분만 있습니다.
OntModel m = ModelFactory.createOntologyModel( OntModelSpec.OWL_MEM, null ); |
모델 생성부분은 RDF와 동일합니다. 단지 OntModle로 선언하는 부분만 다릅니다. ModelFactory의 createOntologyModel 메소드를 사용해서 온톨로지 모델을 생성하는데 사용하는 초기 세팅은 OntModelSpec.OWL_MEM입니다. OWL_MEM에 대해서는 지난 포스팅 표를 참조하시면 됩니다. 제 기억에는 OWL FULL버전을 사용하고 in-memory 저장 구조를 가지고 있던 셋팅인 것 같습니다.
그 다음엔 온톨로지를 읽어들여올 URI와 로컬 폴더를 지정하는 메소드입니다. m.getDocumentManager().addAltEntry()를 통해 URI와 로컬주소를 매칭시키는 코드입니다.
m.read( "http://www.w3.org/2001/sw/WebOnt/guide-src/wine" ); |
다음은 read함수를 통해 온톨로지를 읽어오는 부분입니다. 인자값으로 웹 URI를 적었지만 이전에 URI와 로컬주소를 매칭시켰기때문에 구지 웹에 접속하지않고 로컬에서 파일을 읽어드립니다. 이 때 파일읽기를 실패 할 수 있는데, 여러분이 압축푼 폴더의 경로로 바꿔주셔야 됩니다. 저는 경로를 c드라이브로 사용해서 위와같이 설정했습니다.
new ClassHierarchy().showHierarchy( System.out, m ); |
메인의 마지막 코드입니다. ClassHierarchy()클래스의 showHierarchy메소드를 실행시킵니다. 인자값으로는 첫번째로 output, 두번째로는 모델이 들어가는 것 같습니다. 여기서는 System.out과 모델 m을 사용했습니다.
메인의 코드를 보면 일단 모델을 만든다음 읽을 온톨로지의 경로설정, read 메소드를 통한 읽기, 마지막으로 전체적인 클래스를 나열하는 ClassHierarchy()함수 사용 순으로 되어있습니다. ClassHierarchy()함수만 보지 않는다면 참 간단한 코드입니다. ClassHierarchy() 함수를 보기전에 코드를 실행해 봅니다. 다음과 같은 결과가 나옵니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | Class :Winery Class :Region Class :DryRedWine Class :WineDescriptor Class :WineColor Class :WineTaste Class :WineBody Class :WineFlavor Class :WineSugar Class :FullBodiedWine Class :Bordeaux Class :Sauterne Class :RedTableWine Class :RedWine Class :Port Class :Gamay Class :WhiteTableWine Class :WhiteNonSweetWine Class :TableWine Class :CaliforniaWine Class :RoseWine Class :AmericanWine Class :DryWine Class :GermanWine Class :SweetWine Class :TexasWine Class :AlsatianWine Class :SauvignonBlanc Class :VintageYear Class :Loire Class :DryWhiteWine Class :Semillon Class :FrenchWine Class :ItalianWine Class :Chianti Class :WhiteWine Class food:ConsumableThing Class food:Meal Class food:MealCourse Class food:PotableLiquid Class :Wine Class :LateHarvest Class :Sauterne Class :EarlyHarvest Class :DessertWine Class :SweetRiesling Class food:Juice Class food:EdibleThing Class food:OtherTomatoBasedFood Class food:Fowl Class food:DarkMeatFowl Class food:LightMeatFowl Class food:NonSweetFruit Class food:Meat Class food:RedMeat Class food:SpicyRedMeat Class food:NonSpicyRedMeat Class food:NonRedMeat Class food:Seafood Class food:Shellfish Class food:NonOysterShellfish Class food:OysterShellfish Class food:Fish Class food:BlandFish Class food:NonBlandFish Class food:SweetFruit Class food:Grape Class :WineGrape Class food:EatingGrape Class food:Pasta Class food:PastaWithRedSauce Class food:PastaWithNonSpicyRedSauce Class food:PastaWithSpicyRedSauce Class food:PastaWithWhiteSauce Class food:PastaWithHeavyCreamSauce Class food:PastaWithLightCreamSauce Class food:Dessert Class food:CheeseNutsDessert Class food:SweetDessert Class food:Wine Class food:NonConsumableThing Class food:Fruit |
클래스가 쭈르륵 나열되어있습니다. 여기서 한가지 궁금한점은 우리가 read한 파일은 wine온톨로지인데 아래쪽에 food라는 클래스가 출력된 것을 볼 수 있습니다. 이것은 wine온톨로지에서 food 온톨로지를 import했기 때문에 출력되는 것으로 알 수있습니다. base 온톨로지가 wine이고 import 온톨로지가 food라고 생각하시면 됩니다.
이제 Classhierarchy 코드를 살펴보겠습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 | /***************************************************************************** * Source code information * ----------------------- * Original author Ian Dickinson, HP Labs Bristol * Author email ian_dickinson@users.sourceforge.net * Package Jena 2 * Web http://sourceforge.net/projects/jena/ * Created 27-Mar-2003 * Filename $RCSfile: ClassHierarchy.java,v $ * Revision $Revision: 1.5 $ * Release status $State: Exp $ * * Last modified on $Date: 2009/10/06 13:04:43 $ * by $Author: ian_dickinson $ * * (c) Copyright 2002, 2003, 2004, 2005 Hewlett-Packard Development Company, LP * (see footer for full conditions) *****************************************************************************/ // Package /////////////// // Imports /////////////// import com.hp.hpl.jena.ontology.*; import com.hp.hpl.jena.rdf.model.*; import com.hp.hpl.jena.shared.PrefixMapping; import com.hp.hpl.jena.util.iterator.Filter; import java.io.PrintStream; import java.util.*; /** * <p> * Simple demonstration program to show how to list a hierarchy of classes. This * is not a complete solution to the problem (sub-classes of restrictions, for example, * are not shown). It is intended only to be illustrative of the general approach. * </p> * * @author Ian Dickinson, HP Labs * (<a href="mailto:ian_dickinson@users.sourceforge.net" >email</a>) * @version CVS $Id: ClassHierarchy.java,v 1.5 2009/10/06 13:04:43 ian_dickinson Exp $ */ public class ClassHierarchy { // Constants ////////////////////////////////// // Static variables ////////////////////////////////// // Instance variables ////////////////////////////////// protected OntModel m_model; private Map<AnonId,String> m_anonIDs = new HashMap<AnonId, String>(); private int m_anonCount = 0; // Constructors ////////////////////////////////// // External signature methods ////////////////////////////////// /** Show the sub-class hierarchy encoded by the given model */ public void showHierarchy( PrintStream out, OntModel m ) { // create an iterator over the root classes that are not anonymous class expressions Iterator<OntClass> i = m.listHierarchyRootClasses() .filterDrop( new Filter<OntClass>() { @Override public boolean accept( OntClass r ) { return r.isAnon(); }} ); while (i.hasNext()) { showClass( out, i.next(), new ArrayList<OntClass>(), 0 ); } } // Internal implementation methods ////////////////////////////////// /** Present a class, then recurse down to the sub-classes. * Use occurs check to prevent getting stuck in a loop */ protected void showClass( PrintStream out, OntClass cls, List<OntClass> occurs, int depth ) { renderClassDescription( out, cls, depth ); out.println(); // recurse to the next level down if (cls.canAs( OntClass.class ) && !occurs.contains( cls )) { for (Iterator<OntClass> i = cls.listSubClasses( true ); i.hasNext(); ) { OntClass sub = i.next(); // we push this expression on the occurs list before we recurse occurs.add( cls ); showClass( out, sub, occurs, depth + 1 ); occurs.remove( cls ); } } } /** * <p>Render a description of the given class to the given output stream.</p> * @param out A print stream to write to * @param c The class to render */ public void renderClassDescription( PrintStream out, OntClass c, int depth ) { indent( out, depth ); if (c.isRestriction()) { renderRestriction( out, c.as( Restriction.class ) ); } else { if (!c.isAnon()) { out.print( "Class " ); renderURI( out, c.getModel(), c.getURI() ); out.print( ' ' ); } else { renderAnonymous( out, c, "class" ); } } } /** * <p>Handle the case of rendering a restriction.</p> * @param out The print stream to write to * @param r The restriction to render */ protected void renderRestriction( PrintStream out, Restriction r ) { if (!r.isAnon()) { out.print( "Restriction " ); renderURI( out, r.getModel(), r.getURI() ); } else { renderAnonymous( out, r, "restriction" ); } out.print( " on property " ); renderURI( out, r.getModel(), r.getOnProperty().getURI() ); } /** Render a URI */ protected void renderURI( PrintStream out, PrefixMapping prefixes, String uri ) { out.print( prefixes.shortForm( uri ) ); } /** Render an anonymous class or restriction */ protected void renderAnonymous( PrintStream out, Resource anon, String name ) { String anonID = m_anonIDs.get( anon.getId() ); if (anonID == null) { anonID = "a-" + m_anonCount++; m_anonIDs.put( anon.getId(), anonID ); } out.print( "Anonymous "); out.print( name ); out.print( " with ID " ); out.print( anonID ); } /** Generate the indentation */ protected void indent( PrintStream out, int depth ) { for (int i = 0; i < depth; i++) { out.print( " " ); } } //============================================================================== // Inner class definitions //============================================================================== } /* (c) Copyright 2002, 2003, 2004, 2005 Hewlett-Packard Development Company, LP All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ |
역시 주석을 제외하면 코드는 상당히 짧습니다. 하지만 아쉽게도 공홈에 설명이 없군요..
제 나름대로 분석해 보자면 일단 결과값을 보여주는 클래스는 renderClassDescription입니다. 제일 위에 showHierarchy는 메인에서 실행된 메소드로 루트클래스로부터 서브클래스들을 탐색하게 됩니다. 탐색을 하면서 각각에 클래스에서 showClass라는 메소드를 실행합니다. showClass는 원할한 탐색을위해 중복을 제거하는 메소드입니다. (탐색하던도중 루프에 빠지지않도록) showClass 역시 클래스마다 renderClassDescription 메소드를 실행시킵니다. 마지막으로 renderClassDescription에서 클래스들을 출력하게 됩니다. showClass에서 계산된 깊이를 기반으로 서브클래스를 표시하기위해 앞에 공백을 두어 계층적으로 출력하게 됩니다.
일단 사용되는 코드는 대부분 Iterator 코드입니다. 이는 RDF API 포스팅에서 다루었기때문에 생략하겠습니다. 나머지는 출력하는 부분이라 기본적인 java메소드를 사용한 것 같습니다.
이렇게 첫번째 예제 코드를 해보았는데 아직 잘 모르겠습니다.
다음 포스팅에서 나머지 코드를 해보고 좀더 연구해봐서 실질적인 사용법을 익혀보도록 하겠습니다.
'Study > OWL,RDF' 카테고리의 다른 글
Jena Ontology API (2) (0) | 2014.02.14 |
---|---|
Jena Ontology API 예제소스 (2) (1) | 2014.02.12 |
Jena Ontology API (0) | 2014.02.10 |
Jena RDF api 활용하기 (3) (0) | 2014.02.05 |
Jena RDF api 활용하기 (2) (1) | 2014.02.05 |