Jena Ontology API 예제소스 (2)
- Study/OWL,RDF
- 2014. 2. 12. 13:47
이번에는 더 복잡한 예제소스입니다.
jena 폴더안에 src-examples\jena\examples\ontology\describeClass 안에 두개의 java파일이 있습니다. main부터 살펴보도록 하겠습니다.
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 | /***************************************************************************** * 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:44 $ * by $Author: ian_dickinson $ * * (c) Copyright 2002, 2003, 2004, 2005 Hewlett-Packard Development Company, LP * (see footer for full conditions) *****************************************************************************/ // Package /////////////// // Imports /////////////// import java.util.Iterator; import com.hp.hpl.jena.ontology.*; import com.hp.hpl.jena.rdf.model.ModelFactory; /** * <p> * Execution wrapper for describe-class 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:44 ian_dickinson Exp $ */ public class Main { // Constants ////////////////////////////////// // Static variables ////////////////////////////////// // Instance variables ////////////////////////////////// // Constructors ////////////////////////////////// // External signature methods ////////////////////////////////// public static void main( String[] args ) { // read the argument file, or the default String source = (args.length == 0) ? "http://www.w3.org/2001/sw/WebOnt/guide-src/wine" : args[0]; OntModel m = ModelFactory.createOntologyModel( OntModelSpec.OWL_MEM, null ); // we have a local copy of the wine ontology addFoodWineAltPaths( m.getDocumentManager() ); // read the source document m.read( "file:c:/test.owl" ); DescribeClass dc = new DescribeClass(); if (args.length >= 2) { // we have a named class to describe OntClass c = m.getOntClass( args[1] ); dc.describeClass( System.out, c ); } else { for (Iterator<OntClass> i = m.listClasses(); i.hasNext(); ) { // now list the classes dc.describeClass( System.out, i.next() ); } } } // Internal implementation methods ////////////////////////////////// /** * Add alternate paths to save downloading the default ontologies from the Web */ protected static void addFoodWineAltPaths( OntDocumentManager odm ) { odm.addAltEntry( "http://www.w3.org/2001/sw/WebOnt/guide-src/wine", "file:c:/testing/reasoners/bugs/wine.owl" ); odm.addAltEntry( "http://www.w3.org/2001/sw/WebOnt/guide-src/wine.owl", "file:c:/testing/reasoners/bugs/wine.owl" ); odm.addAltEntry( "http://www.w3.org/2001/sw/WebOnt/guide-src/food", "file:c:/testing/reasoners/bugs/food.owl" ); odm.addAltEntry( "http://www.w3.org/2001/sw/WebOnt/guide-src/food.owl", "file:c:/testing/reasoners/bugs/food.owl" ); } //============================================================================== // 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. */ |
역시 주석때문에 상당히 길어보입니다. 이 예제소스는 온톨로지파일을 읽어와서 클래스에 대한 정보를 전부 표시해줍니다. 메인에서는 딱히 새로운 코드는 없는데요, 온톨로지를 불러드리고 읽어오는 과정은 지난 포스팅에서도 했기때문에 생략하겠습니다. 클래스를 분석한 결과를 출력하는 메소드는 DescribeClass라는 java파일에서 선언된 메소드를 사용합니다. 메인에서는 단지 온톨로지 모델을 만들고 제일 상위클래스에서 탐색하여 만나는 클래스마다 describeClass 메소드를 호출하기만 합니다.
저는 제가 만든 온톨로지 파일을 테스트해보기위해 read함수의 인자값 경로를 바꿧는데 기본 예제를 실행하실 때에는 자신이 설치한 jena폴더 경로를 설정해 주시기 바랍니다.
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 | Class :OS Class :Spec is a super-class of Class :Storage is a super-class of Class :Motion_recognition is a super-class of Class :Display is a super-class of Class :Camera is a super-class of Class :CPU is a super-class of Class :Bettery Class :Company Class :Motion_recognition is a sub-class of Class :Spec Class :Storage is a sub-class of Class :Spec Class :Display is a sub-class of Class :Spec Class :Bettery is a sub-class of Class :Spec Class :CPU is a sub-class of Class :Spec Class :Camera is a sub-class of Class :Spec Class :Phone is a sub-class of Anonymous restriction with ID a-0 on property :hasCompany is a sub-class of Anonymous restriction with ID a-1 on property :hasCamera some values from Class :Camera is a sub-class of Anonymous restriction with ID a-2 on property :hasDisplay is a sub-class of Anonymous restriction with ID a-3 on property :hasTelecommunication is a sub-class of Anonymous restriction with ID a-4 on property :hasBetterycapacity some values from Class xsd:integer is a sub-class of Anonymous restriction with ID a-5 on property :hasOS is a sub-class of Anonymous restriction with ID a-6 on property :hasDisplaysize some values from Class xsd:float Class :Telecommunication Anonymous restriction with ID a-0 on property :hasCompany is a super-class of Class :Phone Anonymous restriction with ID a-1 on property :hasCamera some values from Class :Camera is a super-class of Class :Phone Anonymous restriction with ID a-2 on property :hasDisplay is a super-class of Class :Phone Anonymous restriction with ID a-3 on property :hasTelecommunication is a super-class of Class :Phone Anonymous restriction with ID a-4 on property :hasBetterycapacity some values from Class xsd:integer is a super-class of Class :Phone Anonymous restriction with ID a-5 on property :hasOS is a super-class of Class :Phone Anonymous restriction with ID a-6 on property :hasDisplaysize some values from Class xsd:float is a super-class of Class :Phone |
제가 간단히 만든 온톨로지를 넣고 실행해 본 결과 위와같은 결과가 나왔습니다. 아마 예제에 있는 wine 온톨로지를 사용하면 더 길게 나오게 될 겁니다. 결과값을 보면 클래스 하나하나 분석하여 이 클래스는 어떤 클래스의 서브클래스인지, 혹은 슈퍼클래스인지가 나오게 됩니다. 또 여러가지 가지고있는 속성들도 나오게 됩니다.
어떻게해서 이렇게 분석되어 나오는지 describeClass 자바파일을 살펴 보도록 하겠습니다.
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 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 | /***************************************************************************** * 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 25-Jul-2003 * Filename $RCSfile: DescribeClass.java,v $ * Revision $Revision: 1.4 $ * Release status $State: Exp $ * * Last modified on $Date: 2009/10/06 13:04:44 $ * by $Author: ian_dickinson $ * * (c) Copyright 2002, 2003, 2004, 2005 Hewlett-Packard Development Company, LP * (see footer for full conditions) *****************************************************************************/ // Package /////////////// // Imports /////////////// import java.io.PrintStream; import java.util.*; import com.hp.hpl.jena.ontology.*; import com.hp.hpl.jena.rdf.model.*; import com.hp.hpl.jena.shared.PrefixMapping; /** * <p> * Simple example of describing the basic attributes of a OWL, DAML or RDFS class * using the ontology API. This is not meant as a definitive solution to the problem, * but as an illustration of one approach to solving the problem. This example should * be adapted as necessary to provide a given application with the means to render * a class description in a readable form. * </p> * * @author Ian Dickinson, HP Labs * (<a href="mailto:ian_dickinson@users.sourceforge.net" >email</a>) * @version CVS $Id: DescribeClass.java,v 1.4 2009/10/06 13:04:44 ian_dickinson Exp $ */ public class DescribeClass { // Constants ////////////////////////////////// // Static variables ////////////////////////////////// // Instance variables ////////////////////////////////// private Map<AnonId,String> m_anonIDs = new HashMap<AnonId,String>(); private int m_anonCount = 0; // Constructors ////////////////////////////////// // External signature methods ////////////////////////////////// /** * <p>Describe the given ontology class in texttual form. The description * produced has the following form (approximately): * <pre> * Class foo:Bar * is a sub-class of foo:A, ex:B * is a super-class of ex:C * </pre> * </p> * * @param out The print stream to write the description to * @param cls The ontology class to describe */ public void describeClass( PrintStream out, OntClass cls ) { renderClassDescription( out, cls ); // sub-classes for (Iterator<OntClass> i = cls.listSuperClasses( true ); i.hasNext(); ) { out.print( " is a sub-class of " ); renderClassDescription( out, i.next() ); out.println(); } // super-classes for (Iterator<OntClass> i = cls.listSubClasses( true ); i.hasNext(); ) { out.print( " is a super-class of " ); renderClassDescription( out, i.next() ); out.println(); } } /** * <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 ) { if (c.isUnionClass()) { renderBooleanClass( out, "union", c.asUnionClass() ); } else if (c.isIntersectionClass()) { renderBooleanClass( out, "intersection", c.asIntersectionClass() ); } else if (c.isComplementClass()) { renderBooleanClass( out, "complement", c.asComplementClass() ); } else if (c.isRestriction()) { renderRestriction( out, c.asRestriction() ); } else { if (!c.isAnon()) { out.print( "Class " ); renderURI( out, prefixesFor( c ), c.getURI() ); out.print( ' ' ); } else { renderAnonymous( out, c, "class" ); } } } // Internal implementation methods ////////////////////////////////// /** * <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, prefixesFor( r ), r.getURI() ); } else { renderAnonymous( out, r, "restriction" ); } out.println(); renderRestrictionElem( out, " on property", r.getOnProperty() ); out.println(); if (r.isAllValuesFromRestriction()) { renderRestrictionElem( out, " all values from", r.asAllValuesFromRestriction().getAllValuesFrom() ); } if (r.isSomeValuesFromRestriction()) { renderRestrictionElem( out, " some values from", r.asSomeValuesFromRestriction().getSomeValuesFrom() ); } if (r.isHasValueRestriction()) { renderRestrictionElem( out, " has value", r.asHasValueRestriction().getHasValue() ); } } protected void renderRestrictionElem( PrintStream out, String desc, RDFNode value ) { out.print( desc ); out.print( " " ); renderValue( out, value ); } protected void renderValue( PrintStream out, RDFNode value ) { if (value.canAs( OntClass.class )) { renderClassDescription( out, value.as( OntClass.class ) ); } else if (value instanceof Resource) { Resource r = (Resource) value; if (r.isAnon()) { renderAnonymous( out, r, "resource" ); } else { renderURI( out, r.getModel(), r.getURI() ); } } else if (value instanceof Literal) { out.print( ((Literal) value).getLexicalForm() ); } else { out.print( value ); } } protected void renderURI( PrintStream out, PrefixMapping prefixes, String uri ) { out.print( prefixes.shortForm( uri ) ); } protected PrefixMapping prefixesFor( Resource n ) { return n.getModel().getGraph().getPrefixMapping(); } 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 ); } protected void renderBooleanClass( PrintStream out, String op, BooleanClassDescription boolClass ) { out.print( op ); out.println( " of {" ); for (Iterator<? extends OntClass> i = boolClass.listOperands(); i.hasNext(); ) { out.print( " " ); renderClassDescription( out, i.next() ); out.println(); } 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. */ |
이코드는 주석을 제외하고도 상당히 길군요 ^^....
전체적인 구조는 일단 클래스에대한 정의를 하고 sub-class와 super-class를 구분합니다. 그리고 각각의 속성들을 나열하죠. 즉 제일위에 describeClass메소드가 실행되고 그안에서 renderClassDescription 메소드, 그안에서 또 다른 메소드인 식으로 계단식 구조로 되어있습니다. 결국에는 전체적인 클래스 설명이 나오게 되지요.
이런 단순한 출력이 어떻게 도움이 되는지 생각해보면, 일단 이 프로그래밍에선 system.out이라는 출력을 사용하여 단순히 콘솔창에 띄우는 정도이지만, 출력 방법을 수정해서 파일로 만든다거나 원하는 출력만을 따로 뽑아서 새로운 온톨로지를 만들때 사용 될 것 같습니다. 출력을 원하는 대로 할 수 있으니 자신이 원하는 form으로 온톨로지를 재구성 할 수 있습니다. 이거 말고는 다른기능(검색이나 추론)으로 사용하기에는 이 코드만으로 문제가 있네요.
jena의 총 3가지 예제중에 두가지를 실행해 봤는데 남은 한가지는 DB를 가지고 실행하는 예제입니다. 현재 DB설계가 안되있으니 마지막 코드는 생략 하도록 할께요.
예제를 해보았는데 현재 바로 도움이 되는 것은 없는 것 같습니다. 기본적으로 웹에서 제공하는 메뉴얼에 포함된 내용도 아닐뿐더러 단순한 출력만 알려주는 예제였습니다. 메뉴얼에 제시된 코드에 대해서는 일일이 만들어보고 시행착오를 겪어가면서 익혀야 할 것 같습니다.
'Study > OWL,RDF' 카테고리의 다른 글
Reasoners and rule engines: Jena, 온톨로지 추론기능 구현 (2) | 2014.02.17 |
---|---|
Jena Ontology API (2) (0) | 2014.02.14 |
Jena Ontology API 예제소스 (1) (0) | 2014.02.11 |
Jena Ontology API (0) | 2014.02.10 |
Jena RDF api 활용하기 (3) (0) | 2014.02.05 |