001/* 002 * Copyright (c) 2004-2010 The Regents of the University of California. 003 * All rights reserved. 004 * 005 * '$Author: aschultz $' 006 * '$Date: 2011-04-08 23:06:46 +0000 (Fri, 08 Apr 2011) $' 007 * '$Revision: 27484 $' 008 * 009 * Permission is hereby granted, without written agreement and without 010 * license or royalty fees, to use, copy, modify, and distribute this 011 * software and its documentation for any purpose, provided that the above 012 * copyright notice and the following two paragraphs appear in all copies 013 * of this software. 014 * 015 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY 016 * FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 017 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 018 * THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF 019 * SUCH DAMAGE. 020 * 021 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 022 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 023 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE 024 * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 025 * CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 026 * ENHANCEMENTS, OR MODIFICATIONS. 027 * 028 */ 029 030package org.kepler.sms; 031 032import java.io.File; 033import java.net.URI; 034import java.util.ArrayList; 035import java.util.Collections; 036import java.util.HashSet; 037import java.util.Iterator; 038import java.util.List; 039import java.util.Random; 040import java.util.Set; 041import java.util.TreeSet; 042import java.util.Vector; 043import java.util.regex.Matcher; 044import java.util.regex.Pattern; 045 046import org.apache.commons.logging.Log; 047import org.apache.commons.logging.LogFactory; 048import org.semanticweb.owl.model.AddAxiom; 049import org.semanticweb.owl.model.OWLAnnotation; 050import org.semanticweb.owl.model.OWLAnnotationAxiom; 051import org.semanticweb.owl.model.OWLAxiom; 052import org.semanticweb.owl.model.OWLClass; 053import org.semanticweb.owl.model.OWLDataFactory; 054import org.semanticweb.owl.model.OWLDescription; 055import org.semanticweb.owl.model.OWLLabelAnnotation; 056import org.semanticweb.owl.model.OWLOntology; 057import org.semanticweb.owl.model.OWLOntologyChangeException; 058import org.semanticweb.owl.model.OWLOntologyCreationException; 059import org.semanticweb.owl.model.OWLOntologyManager; 060import org.semanticweb.owl.model.OWLOntologyStorageException; 061import org.semanticweb.owl.model.OWLProperty; 062import org.semanticweb.owl.model.RemoveAxiom; 063import org.semanticweb.owl.util.SimpleURIMapper; 064 065/** 066 * This class encapsulates/wraps an ontology model. TODO: still developing the 067 * interface for this class. 068 */ 069public class NamedOntModel implements Comparable { 070 071 private OWLOntology _ontology; // the ontology in the model 072 private String _name; // the name of the ontology, or the namespace 073 private OWLOntologyManager _manager; 074 private Color color; 075 private boolean local; 076 077 private String _filePath; // the name of the OWL file 078 079 /** 080 * Creates a named ont model for the ontology given in filePath 081 * 082 * @param filePath 083 * The path to the file to load. We assume the ontology is 084 * already classified. 085 */ 086 public NamedOntModel(String filePath) throws Exception { 087 _filePath = filePath; 088 } 089 090 public static String parseLabel(OWLAnnotationAxiom axiom) { 091 return parseLabel(axiom.getAnnotation()); 092 } 093 094 public static String parseLabel(OWLAnnotation annot) { 095 Pattern pattern = Pattern.compile("\"(.*)\"\\^\\^string"); 096 if(annot == null || annot.getAnnotationValue() == null) 097 return null; 098 String a = annot.getAnnotationValue().toString(); 099 Matcher matcher = pattern.matcher(a); 100 if (matcher.matches()) { 101 return matcher.group(1); 102 } 103 return a; 104 } 105 106 public String getTopLevelLabel() { 107 Set<OWLAnnotationAxiom> axioms = _ontology.getAnnotationAxioms(); 108 URI labelURI = URI.create("http://www.w3.org/2000/01/rdf-schema#label"); 109 for (OWLAnnotationAxiom axiom : axioms) { 110 if (axiom.getAnnotation().getAnnotationURI().equals(labelURI) && axiom.getSubject() instanceof OWLOntology) { 111 _name = parseLabel(axiom); 112 return _name; 113 } 114 } 115 _name = _ontology.toString(); 116 return _name; 117 } 118 119 public void initializeNew(String label) { 120 Random random = new Random(); 121 int i; 122 do { 123 i = random.nextInt(); 124 } 125 while(i < 0); 126 127 _manager = OntologyCatalog.getManager(); 128 URI logicalUri = URI.create("urn:lsid:localhost:onto:" + random.nextInt() + ":1"); 129 URI physicalUri = new File(_filePath).toURI(); 130 SimpleURIMapper mapper = new SimpleURIMapper(logicalUri, physicalUri); 131 _manager.addURIMapper(mapper); 132 133 try { 134 _ontology = _manager.createOntology(logicalUri); 135 } 136 catch(OWLOntologyCreationException e) { 137 e.printStackTrace(); 138 } 139 140 setTopLevelLabel(label); 141 _name = label; 142 } 143 144 public void removeTopLevelLabel() { 145 if (_ontology == null) { 146 return; 147 } 148 149 Set<OWLAnnotationAxiom> axioms = _ontology.getAnnotationAxioms(); 150 URI labelURI = URI.create("http://www.w3.org/2000/01/rdf-schema#label"); 151 for (OWLAnnotationAxiom axiom : axioms) { 152 if (axiom.getAnnotation().getAnnotationURI().equals(labelURI) && axiom.getSubject() instanceof OWLOntology) { 153 try { 154 _manager.applyChange(new RemoveAxiom(_ontology, axiom)); 155 } 156 catch(OWLOntologyChangeException ex) { 157 ex.printStackTrace(); 158 } 159 return; 160 } 161 } 162 } 163 164 @Override 165 public boolean equals(Object o) { 166 if (this == o) return true; 167 if (o == null || getClass() != o.getClass()) return false; 168 169 NamedOntModel that = (NamedOntModel) o; 170 171 if (_filePath != null ? !_filePath.equals(that._filePath) : that._filePath != null) return false; 172 if (_name != null ? !_name.equals(that._name) : that._name != null) return false; 173 174 return true; 175 } 176 177 @Override 178 public int hashCode() { 179 int result = _name != null ? _name.hashCode() : 0; 180 result = 31 * result + (_filePath != null ? _filePath.hashCode() : 0); 181 return result; 182 } 183 184 185 public void setTopLevelLabel(String label) { 186 if (_ontology == null) { 187 return; 188 } 189 190 OWLDataFactory factory = _manager.getOWLDataFactory(); 191 OWLLabelAnnotation annotation = factory.getOWLLabelAnnotation(label); 192 OWLAxiom axiom = factory.getOWLOntologyAnnotationAxiom(_ontology, annotation); 193 try { 194 _manager.applyChange(new AddAxiom(_ontology, axiom)); 195 } 196 catch(OWLOntologyChangeException ex) { 197 log.error("Error adding ontology label", ex); 198 } 199 } 200 201 public File getFile() { 202 return new File(_filePath); 203 } 204 205 /** 206 * Initializes a named ont model wrapper for the ontology. 207 */ 208 public boolean initialize() { 209 _manager = OntologyCatalog.getManager(); 210 try { 211 _ontology = _manager.loadOntologyFromPhysicalURI(new File(_filePath).toURI()); 212 SimpleURIMapper mapper = new SimpleURIMapper(_ontology.getURI(), new File(_filePath).toURI()); 213 _manager.addURIMapper(mapper); 214 } 215 catch(OWLOntologyCreationException ex) { 216 return false; 217 } 218 _name = getTopLevelLabel(); 219 220 // garbage collect to keep memory usage from spiking 221 System.gc(); 222 223 return true; 224 } 225 226 /** 227 * @return The namespace for the ontology 228 */ 229 public String getNameSpace() { 230 return _ontology.getURI().toString(); 231 } 232 233 public OWLOntology getOntology() { 234 return this._ontology; 235 } 236 237 /** 238 * @return The root classes, i.e., without a named superclass, for this 239 * ontology. 240 */ 241 public Iterator<NamedOntClass> getRootClasses(boolean sorted) { 242 // get all the classesg 243 Vector<OWLClass> classes = new Vector(_ontology.getReferencedClasses()); 244 Vector<NamedOntClass> results = new Vector(); 245 boolean foundResult = true; 246 // check each class to see if a root 247 for (OWLClass c : _ontology.getReferencedClasses()) { // TODO: Is this an appropriate replacement for listNamedClasses()? 248 for (OWLDescription superClassAxiom : c.getSuperClasses(_ontology)) { 249 250 if(!superClassAxiom.isAnonymous()) { 251 OWLClass s = superClassAxiom.asOWLClass(); 252 if (classes.contains(s)) { 253 foundResult = false; 254 break; 255 } 256 } 257 } 258 259 if (foundResult) { 260 results.add(new NamedOntClass(c, _ontology)); 261 } 262 foundResult = true; 263 } 264 if (sorted) 265 Collections.sort(results); 266 return results.iterator(); 267 } 268 269 public void write() { 270 try { 271 _manager.saveOntology(_ontology); 272 } 273 catch(OWLOntologyStorageException ex) { 274 ex.printStackTrace(); 275 } 276 } 277 278 /** 279 * gets a list of the named classes in the ontology 280 * 281 * @param sorted 282 * Return sorted list if true 283 * @return A sorted list of named ontology classes 284 */ 285 public Iterator<NamedOntClass> getNamedClasses() { 286 287 //use TreeSet instead of Vector so contains() is fast. TreeSet also 288 //gives ascending natural ordering sorting for free. fix for bug #4539 289 //Vector<NamedOntClass> results = new Vector<NamedOntClass>(); 290 TreeSet<NamedOntClass> results = new TreeSet<NamedOntClass>(); 291 NamedOntClass noc = null; 292 for (OWLClass c : _ontology.getReferencedClasses()) { 293 noc = new NamedOntClass(c, _ontology); 294 295 if (!results.contains(noc)) 296 results.add(noc); 297 } 298 299 return results.iterator(); 300 } 301 302 public NamedOntClass getNamedClass(String name) { 303 for(OWLClass c : _ontology.getReferencedClasses()) { 304 String uri = c.getURI().toString(); 305 String [] parts = uri.split("#"); 306 if(parts.length != 2) 307 return null; 308 if(parts[1].equals(name)) 309 return new NamedOntClass(c, _ontology); 310 } 311 return null; 312 } 313 314 /** 315 * gets a list of the named properties in the ontology 316 * 317 * @param sorted 318 * Return sorted list if true 319 * @return A sorted list of named ontology classes 320 */ 321 public Iterator<NamedOntProperty> getNamedProperties(boolean sorted) { 322 Set<OWLProperty> owlProperties = new HashSet<OWLProperty>(); 323 owlProperties.addAll(_ontology.getReferencedDataProperties()); 324 owlProperties.addAll(_ontology.getReferencedObjectProperties()); 325 326 List<NamedOntProperty> results = new ArrayList<NamedOntProperty>(); 327 for (OWLProperty owlProperty : owlProperties) { 328 results.add(new NamedOntProperty(owlProperty, _ontology, this)); 329 } 330 331 if (sorted) { 332 Collections.sort(results); 333 } 334 return results.iterator(); 335 } 336 337 /** 338 * 339 */ 340 public String toString() { 341 return getName(); 342 } 343 344 /** 345 * @return The name of the model 346 */ 347 public String getName() { 348 return _name; 349 } 350 351 public int compareTo(Object obj) { 352 String str1 = toString(); 353 String str2 = obj.toString(); 354 return str1.compareTo(str2); 355 } 356 357 private static final Log log = LogFactory.getLog(NamedOntModel.class); 358 359 public Color getColor() { 360 return color; 361 } 362 363 public void setColor(Color color) { 364 this.color = color; 365 } 366 367 public boolean isLocal() { 368 return local; 369 } 370 371 public void setLocal(boolean local) { 372 this.local = local; 373 } 374} // NamedOntModel