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}