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