ad6a6f78022fe80bb0db5dd82f49336005eac1eb
[smartapi.git] / Common / Java / SmartAPI / src / smartapi / agents / OntologyAgent.java
1 package smartapi.agents;
2
3 import java.io.File;
4 import java.util.Map;
5 import java.util.Properties;
6
7 import org.apache.jena.rdf.model.Literal;
8 import org.apache.jena.rdf.model.Model;
9 import org.apache.jena.rdf.model.Resource;
10 import org.apache.jena.rdf.model.Statement;
11 import org.apache.jena.rdf.model.StmtIterator;
12
13 import com.google.gson.JsonObject;
14
15 import smartapi.common.ConceptValidator;
16 import smartapi.common.PROPERTY;
17 import smartapi.common.SERIALIZATION;
18 import smartapi.common.SmartAPI;
19 import smartapi.common.Tools;
20 import smartapi.common.URLs;
21 import smartapi.model.Grading;
22 import smartapi.model.Obj;
23
24 public class OntologyAgent {
25
26         public static String ontologyFolderPath = "ontologies/";
27         
28         private static String ontologyDownloadUriPrefix = "http://talk.smart-api.io/ontology/";
29         
30         private static String checksumFilePath = "checksum.properties";
31         
32         private static Properties checksumProperties = null;
33
34         public OntologyAgent()
35         {
36         }
37
38         public static Grading quickValidate(Obj obj)
39         {
40                 return ConceptValidator.validate(obj);
41         }
42         
43         public static Grading quickValidate(Obj obj, int validationMode)
44         {
45                 return ConceptValidator.validate(obj, validationMode);
46         }
47         
48         public static Grading validate(Obj obj)
49         {
50                 return OntologyAgent.fullValidate(obj);
51         }
52         
53         public static Grading fullValidate(Obj obj)
54         {
55                 //TODO contact validation service
56                 return null;
57         }
58         
59         /**
60          * Download ontology files from Ontology server if needed or forced
61          */
62         public static void updateOntologies(boolean force)
63         {
64                 String checksumOnServer = OntologyAgent.getServerChecksum();
65                 boolean folderExists = (new File(ontologyFolderPath)).exists();
66                 // update if force or never updated or different checksums
67                 if ( force || OntologyAgent.getLocalChecksum() == null || 
68                                 !OntologyAgent.getLocalChecksum().equals(checksumOnServer) ||
69                                 !folderExists ) {
70                         OntologyAgent.downloadOntologyfiles();
71                         OntologyAgent.setLocalChecksum(checksumOnServer);
72                 }
73         }
74         
75         /**
76          * You probably want to use updateOntologies()
77          * method instead of this.
78          * @return
79          */
80         public static boolean areOntologiesUpToDate()
81         {
82                 // if ontologies are never updated, then false
83                 if ( OntologyAgent.getLocalChecksum() == null ) {
84                         return false;
85                 } else {
86                         String serverChecksum = getServerChecksum();
87                         if ( serverChecksum == null ) {
88                                 // unable to fetch checksum, ontologies are as up-to-date as they can get
89                                 return true;
90                         } else {
91                                 if ( OntologyAgent.getLocalChecksum().equals(serverChecksum) ) {
92                                         // same checksum
93                                         return true;
94                                 } else {
95                                         // different checksums
96                                         return false;
97                                 }
98                         }
99                 }
100         }
101         
102         private static String getLocalChecksum()
103         {
104                 // if file not loaded, try loading it
105                 if ( OntologyAgent.checksumProperties == null ) {
106                         OntologyAgent.checksumProperties = Tools.readProperties(checksumFilePath);
107                 }
108                 // if loading was successful, get checksum
109                 if ( OntologyAgent.checksumProperties != null ) {
110                         return OntologyAgent.checksumProperties.getProperty("checksum");
111                 }
112                 return null;
113         }
114
115         private static void setLocalChecksum(String checksum)
116         {
117                 // create properties file if does not exist yet
118                 if ( OntologyAgent.checksumProperties == null ) {
119                         OntologyAgent.checksumProperties = new Properties();
120                 }
121                 // set new value in properties
122                 OntologyAgent.checksumProperties.setProperty("checksum", checksum);
123                 // save to file
124                 Tools.writeProperties(OntologyAgent.checksumProperties, checksumFilePath);
125         }
126                 
127         private static void downloadOntologyfiles()
128         {
129                 try{
130                         for (Map.Entry<String,String> entry : Tools.prefixes.entrySet()) {
131                                 Tools.downloadFile(OntologyAgent.getOntologyDownloadUri(entry.getValue()), OntologyAgent.ontologyFolderPath, entry.getKey() + ".ttl");                                                          
132                         }
133                         System.out.println("Successfully updated ontologies.");
134                 }catch(Exception e){
135                         System.err.println("Error while downloading ontologies.");
136                         e.printStackTrace();
137                 }               
138         }
139         
140         public static String getOntologyDownloadUri(String ontologyPrefixUri)
141         {
142                 // remove last character of prefixUri if it is #
143                 if ( ontologyPrefixUri.endsWith("#") ) {
144                         ontologyPrefixUri = ontologyPrefixUri.substring(0, ontologyPrefixUri.length()-1);                       
145                 }
146                 return OntologyAgent.ontologyDownloadUriPrefix + Tools.urlEncode(ontologyPrefixUri) + "/";
147         }
148         
149         private static String getServerChecksum()
150         {
151                 JsonObject o = new JsonObject();
152                 o.addProperty("jsonrpc", "2.0");
153                 o.addProperty("id", 123);
154                 o.addProperty("method", "sparql_query");
155                 JsonObject params = new JsonObject();
156                 params.addProperty("ontology_filter", "one");
157                 params.addProperty("query_type", "list_all_resources");
158                 o.add("params", params);
159                 try {
160                         String resp = Tools.httpClient.sendPost(URLs.TALK_TRIPLESTOREMANAGER_URI, o.toString(), "application/json").getLeft();  
161                         JsonObject respObj = Tools.jsonParser.parse(resp).getAsJsonObject();
162                         String checksum = respObj.getAsJsonObject("result").get("checksum").getAsString();
163                         return checksum;
164                 } catch ( Exception e ) {
165                         System.err.println("Unable to check updates for prefixes from the ontology server.");
166                         return null;
167                 }
168         }
169         
170         public static void printSubclasses(String resource)
171         {
172                 OntologyAgent.printSubclasses(resource, "en");
173         }
174
175         public static void printSubclasses(String resource, String lang)
176         {
177                 OntologyAgent.printSubclasses(resource, lang, 999);
178         }
179
180         public static void printSubclasses(String resource, String lang, int depth)
181         {
182                 OntologyAgent.updateOntologies(false);
183                 Model model = Tools.fromFile(OntologyAgent.ontologyFolderPath + "smartapi.ttl", SERIALIZATION.TURTLE);
184                 Resource root = model.getResource(resource);
185                 OntologyAgent.printSubclasses("", root, lang, depth);
186         }
187
188         private static void printSubclasses(String indent, Resource r, String lang, int depth)
189         {
190                 if ( depth == 0 ) {
191                         return;
192                 }
193                 depth--;
194                 String label = null;
195                 StmtIterator labelIterator = r.listProperties(r.getModel().createProperty(PROPERTY.getUri(PROPERTY.RDFS_LABEL)));
196                 while ( labelIterator.hasNext() ) {
197                         Statement s = labelIterator.next();
198                         Literal lit = s.getLiteral();
199                         if ( lit.getLanguage().equals(lang) ) {
200                                 label = lit.getString();
201                         } else {
202                                 if ( label == null ) {
203                                         label = lit.getString() + " -- EN --";
204                                 }
205                         }
206                 }
207                 System.out.println(indent + label);
208                 StmtIterator i = r.getModel().listStatements((Resource)null, r.getModel().createProperty(PROPERTY.getUri(PROPERTY.SUBCLASSOF)), r);
209                 while ( i.hasNext() ) {
210                         Statement s = i.next();
211                         Resource subclass = s.getSubject();
212                         printSubclasses(indent + "    ", subclass, lang, depth);
213                 }
214         }
215 }