001/* 002 * Copyright (c) 2004-2010 The Regents of the University of California. 003 * All rights reserved. 004 * 005 * '$Author: welker $' 006 * '$Date: 2010-05-06 05:21:26 +0000 (Thu, 06 May 2010) $' 007 * '$Revision: 24234 $' 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.ecoinformatics.seek.ecogrid; 031 032import java.io.File; 033import java.util.Iterator; 034import java.util.Vector; 035 036import javax.xml.parsers.DocumentBuilder; 037import javax.xml.parsers.DocumentBuilderFactory; 038 039import org.w3c.dom.Document; 040import org.w3c.dom.Element; 041import org.w3c.dom.NodeList; 042 043import com.hp.hpl.jena.ontology.Individual; 044import com.hp.hpl.jena.ontology.OntClass; 045import com.hp.hpl.jena.ontology.OntModel; 046import com.hp.hpl.jena.ontology.OntModelSpec; 047import com.hp.hpl.jena.rdf.model.ModelFactory; 048import com.hp.hpl.jena.rdf.model.Resource; 049import com.hp.hpl.jena.util.iterator.ExtendedIterator; 050 051/** 052 * Description of the Class 053 * 054 *@author berkley 055 *@created February 17, 2005 056 */ 057public class SemRegIndex { 058 059 private String LOCAL_PATH = "tests/test/org/ecoinformatics/seek/sms/"; 060 private String ONTO_FILE = LOCAL_PATH + "test_onto.owl"; 061 private String INDEX_FILE = LOCAL_PATH + "semreg_index.xml"; 062 private Document index; 063 064 /** 065 * Constructor 066 */ 067 public SemRegIndex() { 068 System.out.println(">>> onto_file = " + ONTO_FILE); 069 System.out.println(">>> index_file = " + INDEX_FILE); 070 071 } 072 073 /** 074 * getActiveClassNames Finds the active domain of class names of the index 075 * 076 *@return The activeClassNames value 077 */ 078 public Vector getActiveClassNames() { 079 // run through the index checking for instances ... 080 return new Vector(); 081 } 082 083 /** 084 * search default case. 085 * 086 *@param classname 087 * Description of the Parameter 088 *@return Description of the Return Value 089 */ 090 public Vector search(String classname) { 091 return search(classname, false); 092 } 093 094 /** 095 * search A simple search implementation that finds actors in the index 096 * (identified via their paths) that instantiate the classname. For example, 097 * search("RichnessIndex") finds all actors that instantiate either the 098 * class named "RichnessIndex" or one of its subclasses. 099 * 100 *@param classname 101 * Description of the Parameter 102 *@param approx 103 * Description of the Parameter 104 *@return Description of the Return Value 105 */ 106 public Vector search(String classname, boolean approx) { 107 // load the index into memory for now 108 loadIndex(); 109 110 // check if valid concept name 111 if (!isValidClass(classname, approx)) { 112 System.out.println(">>> didn't find classname"); 113 return new Vector(); 114 } 115 116 // iterate through the index, searching for a matching item 117 return traverseIndex(classname, approx); 118 } 119 120 /** 121 * traverseIndex 122 * 123 *@param classname 124 * Description of the Parameter 125 *@param approx 126 * Description of the Parameter 127 *@return Description of the Return Value 128 */ 129 private Vector traverseIndex(String classname, boolean approx) { 130 Vector result = new Vector(); 131 // get the entry tags 132 NodeList entries = index.getElementsByTagName("entry"); 133 // iterate through each tag, check if there is a match 134 for (int i = 0; i < entries.getLength(); i++) { 135 Element entry = (Element) entries.item(i); 136 checkCondition(classname, entry, result, approx); 137 } 138 return result; 139 } 140 141 /** 142 * checkCondition Determines whether the entry's annotation instantiates 143 * classname, and if so, adds the actor path to result. 144 * 145 *@param classname 146 * Description of the Parameter 147 *@param entry 148 * Description of the Parameter 149 *@param result 150 * Description of the Parameter 151 *@param approx 152 * Description of the Parameter 153 */ 154 private void checkCondition(String classname, Element entry, Vector result, 155 boolean approx) { 156 // get the annotation node 157 Element annotation = (Element) (entry 158 .getElementsByTagName("annotation").item(0)); 159 // get the 'ref' attribute 160 String fname = annotation.getAttribute("ref"); 161 System.out.println(">>> CHECKING CONDITION (" + fname + ")"); 162 163 // load the ontology 164 OntModel onto = ModelFactory.createOntologyModel( 165 OntModelSpec.OWL_MEM_RDFS_INF, null); 166 onto.setDynamicImports(true); 167 168 // read in the annotation 169 onto.read("file:" + LOCAL_PATH + fname); 170 171 boolean foundMatch = false; 172 // get the individuals defined by the annotation 173 ExtendedIterator inds = onto.listIndividuals(); 174 while (inds.hasNext() && !foundMatch) { 175 Individual i = (Individual) inds.next(); 176 // get the direct types of this individual 177 ExtendedIterator types = i.listRDFTypes(false); 178 while (types.hasNext() && !foundMatch) { 179 Resource r = (Resource) types.next(); 180 OntClass c = (OntClass) r.as(OntClass.class); 181 // check if c is a matching class 182 System.out.println(">>>> checking " + c); 183 if (!approx && c.getLocalName().equals(classname)) { 184 foundMatch = true; 185 } 186 if (approx && approxMatch(c.getLocalName(), classname)) { 187 foundMatch = true; 188 } 189 } 190 } 191 if (foundMatch) { 192 System.out.println(">>> FOUND MATCH!"); 193 // found a match: build the path, add it to result, and return 194 Element item = (Element) (entry.getElementsByTagName("item") 195 .item(0)); 196 result.add(buildResult(item)); 197 } 198 } 199 200 /** 201 * buildResult Note that we assume at least one folder and leafs have at 202 * most one actor here. 203 * 204 *@param item 205 * Description of the Parameter 206 *@return Description of the Return Value 207 */ 208 private Vector buildResult(Element item) { 209 Vector result = new Vector(); 210 // get the folders under item 211 NodeList folders = item.getElementsByTagName("folder"); 212 // get each folder and add to result 213 Element folder = item; 214 for (int i = 0; i < folders.getLength(); i++) { 215 folder = (Element) folders.item(i); 216 result.add(folder.getAttribute("name")); 217 } 218 // get the actor and add to result 219 Element actor = (Element) folder.getElementsByTagName("actor").item(0); 220 result.add(actor.getAttribute("name")); 221 // return the path 222 return result; 223 } 224 225 /** 226 * isValidClass Note that we are assuming uniformity in that there is only a 227 * single namespace for the ontology, and so below, we only check the 228 * fragments of the URIs of the classes in the ontology. This operation is 229 * just a simple optimization pre-step. 230 * 231 *@param classname 232 * Description of the Parameter 233 *@param approx 234 * Description of the Parameter 235 *@return The validClass value 236 */ 237 private boolean isValidClass(String classname, boolean approx) { 238 // load the ontology 239 OntModel onto = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM, 240 null); 241 // read in the ontology 242 onto.read("file:" + ONTO_FILE); 243 // get the classes in the onto 244 Iterator iter = onto.listClasses(); 245 while (iter.hasNext()) { 246 OntClass c = (OntClass) iter.next(); 247 if (!approx && c.getLocalName().equals(classname)) { 248 return true; 249 } 250 if (approx && approxMatch(c.getLocalName(), classname)) { 251 return true; 252 } 253 } 254 return false; 255 } 256 257 /** 258 * Description of the Method 259 * 260 *@param val1 261 * Description of the Parameter 262 *@param val2 263 * Description of the Parameter 264 *@return Description of the Return Value 265 */ 266 private boolean approxMatch(String val1, String val2) { 267 val1 = val1.toLowerCase(); 268 val2 = val2.toLowerCase(); 269 if (val1.indexOf(val2) != -1 || val2.indexOf(val1) != -1) { 270 return true; 271 } 272 return false; 273 } 274 275 /** 276 * loadIndex 277 */ 278 private void loadIndex() { 279 // build the factory 280 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 281 // set validating false; no dtd 282 factory.setValidating(false); 283 // construct doc builder and parse it 284 DocumentBuilder builder = null; 285 try { 286 builder = factory.newDocumentBuilder(); 287 index = builder.parse(new File(INDEX_FILE)); 288 } catch (Exception e) { 289 e.printStackTrace(); 290 } 291 } 292 293 // for testing 294 /** 295 * The main program for the SemRegIndex class 296 * 297 *@param args 298 * The command line arguments 299 */ 300 public static void main(String[] args) { 301 SemRegIndex index = new SemRegIndex(); 302 String query = "RichnessIndex"; 303 Vector result = index.search("RichnessIndex"); 304 System.out.println("Query for '" + query + "' returned " + result); 305 } 306 307}