001/*
002 * Copyright (c) 2004-2010 The Regents of the University of California.
003 * All rights reserved.
004 *
005 * '$Author: crawl $'
006 * '$Date: 2013-01-17 18:45:04 +0000 (Thu, 17 Jan 2013) $' 
007 * '$Revision: 31345 $'
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.util;
031
032import java.io.File;
033import java.io.IOException;
034import java.net.URI;
035import java.net.URISyntaxException;
036import java.util.ArrayList;
037import java.util.Arrays;
038import java.util.HashMap;
039import java.util.Iterator;
040import java.util.List;
041import java.util.Map;
042import java.util.Vector;
043
044import javax.xml.parsers.DocumentBuilder;
045import javax.xml.parsers.DocumentBuilderFactory;
046import javax.xml.parsers.ParserConfigurationException;
047
048import org.apache.commons.logging.Log;
049import org.apache.commons.logging.LogFactory;
050import org.kepler.sms.Color;
051import org.w3c.dom.Attr;
052import org.w3c.dom.Document;
053import org.w3c.dom.Element;
054import org.w3c.dom.NodeList;
055import org.xml.sax.SAXException;
056
057/**
058 * This class reads in ontology_catalog.xml and returns the set of ontologies.
059 * It also gives those that are suitable as library categorizations.
060 */
061public class OntologyConfiguration {
062
063        /**
064         * This is a singleton class, so the constructor is "hidden"
065         */
066        protected OntologyConfiguration() {
067                defaultColors = new ArrayList<Color>();
068                Color[] colors = new Color[] {new Color("red"), new Color("blue"), new Color("pink"), new Color("orange"), new Color("green"), new Color("magenta"), new Color("cyan"), new Color("gray")};
069                defaultColors.addAll(Arrays.asList(colors));
070        }
071        
072        public void setIndexFile(File indexFile) {
073                _indexFile = indexFile;
074        }
075        
076        public File getIndexFile() {
077                return _indexFile;
078        }
079
080        /**
081         * Initialize the catalog TODO: read from config file
082         */
083        public void initialize() {
084                // load the index file
085                try {
086                        DocumentBuilderFactory factory = DocumentBuilderFactory
087                                        .newInstance();
088                        DocumentBuilder builder = factory.newDocumentBuilder();
089                        initializePaths();
090                        _document = builder.parse(INDEX_FILE);
091                        // System.out.println("Reading ontology file: " + new
092                        // File(INDEX_FILE).getAbsolutePath());
093                } catch (SAXException sxe) {
094                        Exception x = sxe;
095                        if (sxe.getException() != null)
096                                x = sxe.getException();
097                        x.printStackTrace();
098                } catch (ParserConfigurationException pce) {
099                        pce.printStackTrace();
100                } catch (IOException ioe) {
101                        ioe.printStackTrace();
102                }
103        }
104
105        private void initializePaths() {
106                /*
107                File indexFile = ProjectLocator
108                                .getHighestRankedFile("configs/ptolemy/configs/kepler/ontologies/ontology_catalog.xml");
109                */
110                // System.out.println("**** " + indexFile.getAbsolutePath());
111
112                try {
113                        INDEX_FILE = _indexFile.getAbsolutePath();
114                        URI uri = getClass().getClassLoader().getResource("ptolemy/configs/kepler/ontologies").toURI();
115                        
116                        // make sure the directory is on the file system. 
117                        // FIXME allow the directory to be in other locations, e.g., in a jar.
118                        if(!uri.getScheme().equals("file")) {
119                            log.error("Ontology directory is not on file system: " + uri);
120                        } else {
121                            ONTO_PATH = new File(uri).getAbsolutePath() + "/";
122                        }
123                } catch(URISyntaxException ex) {
124                        log.error("Error finding ontology directory.", ex);
125                } catch(IllegalArgumentException ex2) {
126            log.error("Error finding ontology directory.");
127                }
128        }
129
130        /**
131         * This method must be called to create/obtain an instance of the catalog
132         * 
133         * @return The unique instance of this class
134         */
135        public static OntologyConfiguration instance() {
136                if (_config == null)
137                        _config = new OntologyConfiguration();
138                return _config;
139        }
140        
141        public void reset() {
142                _document = null;
143        }
144
145        /**
146         * Get the file path names for the ontologies
147         */
148        public Iterator getFilePathNames() {
149                Vector result = new Vector();
150                if (_document == null)
151                        return result.iterator();
152
153                // get the root
154                Element root = _document.getDocumentElement();
155                if (root == null)
156                        return result.iterator();
157
158                // iterate through root, get each ontology element and its
159                // filename
160                NodeList lst = root.getElementsByTagName("ontology");
161                for (int i = 0; i < lst.getLength(); i++) {
162                        Element elem = (Element) lst.item(i);
163                        Attr att = elem.getAttributeNode("filename");
164                        if (att != null) {
165                                String filename = att.getValue();
166                                if (filename != null)
167                                        result.addElement(getAbsoluteOntologyPath(filename));
168                        }
169                }
170
171                return result.iterator();
172        }
173        
174        
175        /**
176         * FIXME
177         * TODO create test cases for this method
178         * 
179         * @param filename
180         * @return
181         */
182        private String getAbsoluteOntologyPath(String filename) {
183                if (isDebugging) log.debug("getAbsoluteOntologyPath(\"" + filename + "\")");
184                if (new File(filename).isFile()) {
185                        if (isDebugging) log.debug("Path is absolute");
186                        return filename;
187                }
188                if (isDebugging) log.debug("Path is relative: " + new File(ONTO_PATH + filename).getAbsolutePath());
189                return ONTO_PATH + filename;
190        }
191        
192        private List<Color> defaultColors;
193        private Map<String, Color> defaultSetColors = new HashMap<String, Color>();
194        
195        public Color getLibraryColor(String filepath) {
196                if (_document == null || filepath == null)
197                        return null;
198
199                // get the root
200                Element root = _document.getDocumentElement();
201                if (root == null)
202                        return null;
203    
204        filepath = new File(filepath).getAbsolutePath();
205
206                // iterate to find the ontology with filepath
207                NodeList lst = root.getElementsByTagName("ontology");
208                for (int i = 0; i < lst.getLength(); i++) {
209                        Element elem = (Element) lst.item(i);
210                        Attr att = elem.getAttributeNode("filename");
211                        if (att != null) {
212                                String filename = att.getValue();
213                                if (filepath.equals(getAbsoluteOntologyPath(filename))) {
214                                        Attr libatt = elem.getAttributeNode("color");
215                                        if (libatt != null) {
216                                                String colorString = libatt.getValue();
217                                                return new Color(colorString);
218                                        }
219                }
220                        }
221                }
222
223        if (!defaultSetColors.containsKey(filepath)) {
224            if (defaultColors.isEmpty()) {
225                return Color.getDefaultColor();
226            }
227            defaultSetColors.put(filepath, defaultColors.remove(defaultColors.size() - 1));
228        }
229        return defaultSetColors.get(filepath);
230        }
231        
232        public Boolean isLibraryLocal(String filepath) {
233                if (_document == null || filepath == null)
234                        return null;
235
236                // get the root
237                Element root = _document.getDocumentElement();
238                if (root == null)
239                        return null;
240                // iterate to find the ontology with filepath
241                NodeList lst = root.getElementsByTagName("ontology");
242                for (int i = 0; i < lst.getLength(); i++) {
243                        Element elem = (Element) lst.item(i);
244                        Attr att = elem.getAttributeNode("filename");
245                        if (att != null) {
246                                String filename = att.getValue();
247                                if (filepath.equals(getAbsoluteOntologyPath(filename))) {
248                                        Attr libatt = elem.getAttributeNode("local");
249                                        if (libatt != null) {
250                                                String localityString = libatt.getValue();
251                                                return "true".equals(localityString);
252                                        }
253                                        else {
254                                                // Default to not editable
255                                                return false;
256                                        }
257                                }
258                        }
259                }
260                return false;   
261        }
262
263        /**
264         * @return True if the filepath is suitable as a library categorization.
265         */
266        public boolean isLibraryOntology(String filepath) {
267                if (_document == null || filepath == null)
268                        return false;
269
270                // get the root
271                Element root = _document.getDocumentElement();
272                if (root == null)
273                        return false;
274                // iterate to find the ontology with filepath
275                NodeList lst = root.getElementsByTagName("ontology");
276                for (int i = 0; i < lst.getLength(); i++) {
277                        Element elem = (Element) lst.item(i);
278                        Attr att = elem.getAttributeNode("filename");
279                        if (att != null) {
280                                String filename = att.getValue();
281                                if (filepath.equals(getAbsoluteOntologyPath(filename))) {
282                                        Attr libatt = elem.getAttributeNode("library");
283                                        if (libatt != null) {
284                                                String library = libatt.getValue();
285                                                if (library != null && library.equals("true"))
286                                                        return true;
287                                        }
288                                }
289                        }
290                }
291                return false;
292        }
293        
294        public boolean isTagBarOntology(String filepath) {
295                if (_document == null || filepath == null)
296                        return false;
297
298                // get the root
299                Element root = _document.getDocumentElement();
300                if (root == null)
301                        return false;
302                // iterate to find the ontology with filepath
303                NodeList lst = root.getElementsByTagName("ontology");
304                for (int i = 0; i < lst.getLength(); i++) {
305                        Element elem = (Element) lst.item(i);
306                        Attr att = elem.getAttributeNode("filename");
307                        if (att != null) {
308                                String filename = att.getValue();
309                                if (filepath.equals(getAbsoluteOntologyPath(filename))) {
310                                        Attr libatt = elem.getAttributeNode("tagbar");
311                                        if (libatt != null) {
312                                                String library = libatt.getValue();
313                                                if (library != null && library.equals("false")) {
314                                                        return false;
315                                                }
316                                        }
317                                }
318                        }
319                }
320                return true;
321        }
322        
323
324        /* PRIVATE MEMBERS */
325
326        private static OntologyConfiguration _config = null; // singleton instance
327        // private String KEPLER = System.getProperty("KEPLER");
328        // private String KEPLER =
329        private String ONTO_PATH;
330        private String INDEX_FILE;
331        private Document _document; // the ontology document
332        private File _indexFile;
333
334        private static final Log log = LogFactory.getLog(OntologyConfiguration.class);
335        private static final boolean isDebugging = log.isDebugEnabled();
336        
337}