001 /**
002 * Copyright (C) 2007-2009, Jens Lehmann
003 *
004 * This file is part of DL-Learner.
005 *
006 * DL-Learner is free software; you can redistribute it and/or modify
007 * it under the terms of the GNU General Public License as published by
008 * the Free Software Foundation; either version 3 of the License, or
009 * (at your option) any later version.
010 *
011 * DL-Learner is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
014 * GNU General Public License for more details.
015 *
016 * You should have received a copy of the GNU General Public License
017 * along with this program. If not, see <http://www.gnu.org/licenses/>.
018 *
019 */
020 package org.dllearner.server;
021
022 import java.net.MalformedURLException;
023 import java.net.URL;
024 import java.util.Arrays;
025 import java.util.HashMap;
026 import java.util.Iterator;
027 import java.util.LinkedList;
028 import java.util.List;
029 import java.util.Map;
030 import java.util.Random;
031 import java.util.Set;
032 import java.util.SortedSet;
033 import java.util.TreeMap;
034 import java.util.TreeSet;
035
036 import javax.jws.WebMethod;
037 import javax.jws.WebService;
038 import javax.jws.soap.SOAPBinding;
039
040 import org.apache.log4j.Logger;
041 import org.dllearner.Info;
042 import org.dllearner.cli.ConfMapper;
043 import org.dllearner.core.Component;
044 import org.dllearner.core.ComponentInitException;
045 import org.dllearner.core.ComponentManager;
046 import org.dllearner.core.EvaluatedDescription;
047 import org.dllearner.core.KnowledgeSource;
048 import org.dllearner.core.LearningAlgorithm;
049 import org.dllearner.core.LearningProblem;
050 import org.dllearner.core.LearningProblemUnsupportedException;
051 import org.dllearner.core.ReasonerComponent;
052 import org.dllearner.core.options.ConfigOption;
053 import org.dllearner.core.owl.Description;
054 import org.dllearner.core.owl.Individual;
055 import org.dllearner.core.owl.NamedClass;
056 import org.dllearner.core.owl.ObjectProperty;
057 import org.dllearner.kb.sparql.Cache;
058 import org.dllearner.kb.sparql.NaturalLanguageDescriptionConvertVisitor;
059 import org.dllearner.kb.sparql.SPARQLTasks;
060 import org.dllearner.kb.sparql.SparqlEndpoint;
061 import org.dllearner.kb.sparql.SparqlKnowledgeSource;
062 import org.dllearner.kb.sparql.SparqlQueryDescriptionConvertVisitor;
063 import org.dllearner.kb.sparql.SparqlQueryException;
064 import org.dllearner.parser.KBParser;
065 import org.dllearner.parser.ParseException;
066 import org.dllearner.utilities.datastructures.Datastructures;
067 import org.dllearner.utilities.examples.AutomaticNegativeExampleFinderSPARQL;
068
069 /**
070 * DL-Learner web service interface. The web service makes use of the component
071 * architecture of DL-Learner (see
072 * <a href="http://dl-learner.org/wiki/Architecture">architecture wiki page</a>),
073 * i.e. it allows to create, configure and run components. In addition, it provides
074 * access to some reasoning and querying methods.
075 *
076 * @author Jens Lehmann
077 *
078 */
079 @WebService(name = "DLLearnerWebService")
080 @SOAPBinding(style = SOAPBinding.Style.RPC)
081 public class DLLearnerWS {
082
083 private static Logger logger = Logger.getLogger(DLLearnerWS.class);
084
085 private Map<Integer, ClientState> clients = new TreeMap<Integer,ClientState>();
086 private Random rand=new Random();
087 private static ComponentManager cm = ComponentManager.getInstance();
088 private static ConfMapper confMapper = new ConfMapper();
089
090 /**
091 * Returns the DL-Learner version this web service is based on.
092 * @return DL-Learner-Build.
093 */
094 @WebMethod
095 public String getBuild() {
096 return Info.build;
097 }
098
099 /**
100 * Method to check whether web service is online and how fast it responses.
101 * This method simply returns true.
102 * @return Always returns true.
103 */
104 @WebMethod
105 public boolean ping() {
106 return true;
107 }
108
109 /**
110 * Generates a unique ID for the client and initialises a session.
111 * Using the ID the client can call the other web service methods.
112 * Two calls to this method are guaranteed to return different results.
113 *
114 * @return A session ID.
115 */
116 @WebMethod
117 public int generateID() {
118 int id;
119 do {
120 id = Math.abs(rand.nextInt());
121 } while(clients.containsKey(id));
122 clients.put(id, new ClientState());
123 logger.info("New client " + id + " at DL-Learner web service.");
124 return id;
125 }
126
127 ///////////////////////////////////////
128 // methods for basic component setup //
129 ///////////////////////////////////////
130
131 /**
132 * Gets a list of all DL-Learner components accessible via this web service.
133 * @return All components accessible via this web service.
134 */
135 @WebMethod
136 public String[] getComponents() {
137 Set<String> components = confMapper.getComponents();
138 return components.toArray(new String[components.size()]);
139 }
140
141 /**
142 * Gets a list of all DL-Learner knowledge source components accessible via this web service.
143 * @return All knowledge source components accessible via this web service.
144 */
145 @WebMethod
146 public String[] getKnowledgeSources() {
147 Set<String> knowledgeSources = confMapper.getKnowledgeSources();
148 return knowledgeSources.toArray(new String[knowledgeSources.size()]);
149 }
150
151 /**
152 * Gets a list of all DL-Learner reasoner components accessible via this web service.
153 * @return All reasoner components accessible via this web service.
154 */
155 @WebMethod
156 public String[] getReasoners() {
157 Set<String> reasoners = confMapper.getReasoners();
158 return reasoners.toArray(new String[reasoners.size()]);
159 }
160
161 /**
162 * Gets a list of all DL-Learner learning problem components accessible via this web service.
163 * @return All learning problem components accessible via this web service.
164 */
165 @WebMethod
166 public String[] getLearningProblems() {
167 Set<String> learningProblems = confMapper.getLearningProblems();
168 return learningProblems.toArray(new String[learningProblems.size()]);
169 }
170
171 /**
172 * Gets a list of all DL-Learner learning algorithm components accessible via this web service.
173 * @return All learning algorithm components accessible via this web service.
174 */
175 @WebMethod
176 public String[] getLearningAlgorithms() {
177 Set<String> learningAlgorithms = confMapper.getLearningAlgorithms();
178 return learningAlgorithms.toArray(new String[learningAlgorithms.size()]);
179 }
180
181 /**
182 * Gets the configuration options supported by the component. This allows e.g. to
183 * automatically build user interfaces for configuring components.
184 * @param component Name of the component.
185 * @param allInfo Whether or not complete information is desired (including option description, allowed values, default value).
186 * @return A list of configuration options supported by the component.
187 * @throws UnknownComponentException Thrown if component is not known (see {@link #getComponents()}).
188 */
189 @WebMethod
190 public String[] getConfigOptions(String component, boolean allInfo) throws UnknownComponentException {
191 Class<? extends Component> componentClass = confMapper.getComponentClass(component);
192 List<ConfigOption<?>> options = ComponentManager.getConfigOptions(componentClass);
193 String[] optionsString = new String[options.size()];
194 for(int i=0; i<options.size(); i++) {
195 ConfigOption<?> option = options.get(i);
196 optionsString[i] = option.getName();
197 if(allInfo) {
198 optionsString[i] += "#" + option.getDescription();
199 optionsString[i] += "#" + option.getAllowedValuesDescription();
200 optionsString[i] += "#" + option.getDefaultValue();
201 }
202 }
203 return optionsString;
204 }
205
206 /**
207 * Adds a knowledge source.
208 *
209 * @param id The session ID.
210 * @param component The name of the component.
211 * @param url The URL of the knowledge source.
212 * @return An identifier for the component.
213 * @throws ClientNotKnownException Thrown if client (session ID) is not known.
214 * @throws UnknownComponentException Thrown if component is not known (see {@link #getComponents()}).
215 * @throws MalformedURLException Thrown if passed URL is malformed.
216 */
217 @WebMethod
218 public int addKnowledgeSource(int id, String component, String url) throws ClientNotKnownException, UnknownComponentException, MalformedURLException {
219 ClientState state = getState(id);
220 Class<? extends KnowledgeSource> ksClass = confMapper.getKnowledgeSourceClass(component);
221 if(ksClass == null)
222 throw new UnknownComponentException(component);
223 KnowledgeSource ks = cm.knowledgeSource(ksClass);
224 cm.applyConfigEntry(ks, "url", new URL(url));
225 return state.addKnowledgeSource(ks);
226 }
227
228 /**
229 * Removes a knowledge source.
230 *
231 * @param id The session ID.
232 * @param componentID ID of knowledge source to remove.
233 * @throws ClientNotKnownException Thrown if client (session ID) is not known.
234 */
235 @WebMethod
236 public void removeKnowledgeSource(int id, int componentID) throws ClientNotKnownException {
237 getState(id).removeKnowledgeSource(componentID);
238 }
239
240 /**
241 * Sets the reasoner to use.
242 *
243 * @param id The session ID.
244 * @param component The name of the component.
245 * @return An identifier for the component.
246 * @throws ClientNotKnownException Thrown if client (session ID) is not known.
247 * @throws UnknownComponentException Thrown if component is not known (see {@link #getComponents()}).
248 */
249 @WebMethod
250 public int setReasoner(int id, String component) throws ClientNotKnownException, UnknownComponentException {
251 ClientState state = getState(id);
252 Class<? extends ReasonerComponent> rcClass = confMapper.getReasonerComponentClass(component);
253 if(rcClass == null)
254 throw new UnknownComponentException(component);
255
256 ReasonerComponent rc = cm.reasoner(rcClass, state.getKnowledgeSources());
257 return state.setReasonerComponent(rc);
258 }
259
260 /**
261 * Sets the learning problem to use.
262 *
263 * @param id The session ID.
264 * @param component The name of the component.
265 * @return An identifier for the component.
266 * @throws ClientNotKnownException Thrown if client (session ID) is not known.
267 * @throws UnknownComponentException Thrown if component is not known (see {@link #getComponents()}).
268 */
269 @WebMethod
270 public int setLearningProblem(int id, String component) throws ClientNotKnownException, UnknownComponentException {
271 ClientState state = getState(id);
272 Class<? extends LearningProblem> lpClass = confMapper.getLearningProblemClass(component);
273 if(lpClass == null)
274 throw new UnknownComponentException(component);
275
276 LearningProblem lp = cm.learningProblem(lpClass, state.getReasonerComponent());
277 return state.setLearningProblem(lp);
278 }
279
280 /**
281 * Sets the learning algorithm to use.
282 *
283 * @param id The session ID.
284 * @param component The name of the component.
285 * @return An identifier for the component.
286 * @throws ClientNotKnownException Thrown if client (session ID) is not known.
287 * @throws UnknownComponentException Thrown if component is not known (see {@link #getComponents()}).
288 * @throws LearningProblemUnsupportedException Thrown if the learning problem is not supported by the specified learning algorithm.
289 */
290 @WebMethod
291 public int setLearningAlgorithm(int id, String component) throws ClientNotKnownException, UnknownComponentException, LearningProblemUnsupportedException {
292 ClientState state = getState(id);
293 Class<? extends LearningAlgorithm> laClass = confMapper.getLearningAlgorithmClass(component);
294 if(laClass == null)
295 throw new UnknownComponentException(component);
296
297 LearningAlgorithm la = cm.learningAlgorithm(laClass, state.getLearningProblem(), state.getReasonerComponent());
298 return state.setLearningAlgorithm(la);
299 }
300
301 /**
302 * Initialise all components.
303 * @param id Session ID.
304 * @throws ComponentInitException Thrown if an error occurs during component initialisation.
305 */
306 @WebMethod
307 public void initAll(int id) throws ClientNotKnownException, ComponentInitException {
308 ClientState state = getState(id);
309 for(KnowledgeSource ks : state.getKnowledgeSources())
310 ks.init();
311 state.getReasonerComponent().init();
312 state.getLearningProblem().init();
313 state.getLearningAlgorithm().init();
314 }
315
316 /**
317 * Initialise the specified component.
318 * @param id Session-ID.
319 * @param componentID Component-ID.
320 * @throws ClientNotKnownException Thrown if client (session ID) is not known.
321 * @throws UnknownComponentException Thrown if the component is unknown.
322 * @throws ComponentInitException
323 */
324 @WebMethod
325 public void init(int id, int componentID) throws ClientNotKnownException, UnknownComponentException, ComponentInitException {
326 ClientState state = getState(id);
327 Component component = state.getComponent(componentID);
328 component.init();
329 }
330
331 /**
332 * Starts the learning algorithm and returns the best concept found. This
333 * method will block until learning is completed.
334 *
335 * @param id Session ID.
336 * @param format The format of the result string: "manchester", "kb", "dl".
337 * @return The best solution found.
338 * @throws ClientNotKnownException Thrown if client (session ID) is not known.
339 */
340 @WebMethod
341 public String learn(int id, String format) throws ClientNotKnownException {
342 ClientState state = getState(id);
343 state.getLearningAlgorithm().start();
344 Description solution = state.getLearningAlgorithm().getCurrentlyBestDescription();
345 if(format.equals("manchester"))
346 return solution.toManchesterSyntaxString(state.getReasonerComponent().getBaseURI(), new HashMap<String,String>());
347 else if(format.equals("kb"))
348 return solution.toKBSyntaxString();
349 else
350 return solution.toString();
351 }
352
353 /**
354 * Returns a list of JSON encoded description including extra information
355 * (which partially depends on the learning problem) such as the accuracy
356 * of the learned description.
357 *
358 * @param id The session ID.
359 * @param limit Maximum number of results desired.
360 * @return A JSON string encoding learned descriptions.
361 * @throws ClientNotKnownException Thrown if client (session ID) is not known.
362 */
363 @WebMethod
364 public String learnDescriptionsEvaluated(int id, int limit) throws ClientNotKnownException {
365 ClientState state = getState(id);
366 state.getLearningAlgorithm().start();
367 List<? extends EvaluatedDescription> descriptions = state.getLearningAlgorithm().getCurrentlyBestEvaluatedDescriptions(limit);
368 String json = "{";
369 int count = 1;
370 for(EvaluatedDescription description : descriptions) {
371 if (count>1) json += ",\"solution" + count + "\" : " + description.asJSON();
372 else json += "\"solution" + count + "\" : " + description.asJSON();
373 count++;
374 }
375 json+="}";
376 return json;
377 }
378
379 /**
380 * Starts the learning algorithm and returns immediately. The learning
381 * algorithm is executed in its own thread and can be queried and
382 * controlled using other Web Service methods.
383 *
384 * @param id Session ID.
385 * @throws ClientNotKnownException Thrown if client (session ID) is not known.
386 */
387 @WebMethod
388 public void learnThreaded(int id) throws ClientNotKnownException {
389 final ClientState state = getState(id);
390 Thread learningThread = new Thread() {
391 @Override
392 public void run() {
393 // state.setAlgorithmRunning(true);
394 state.getLearningAlgorithm().start();
395 // state.setAlgorithmRunning(false);
396 }
397 };
398 learningThread.start();
399 }
400
401 /**
402 *
403 * @param id The session ID.
404 * @return
405 * @throws ClientNotKnownException Thrown if client (session ID) is not known.
406 */
407 @WebMethod
408 public String getCurrentlyBestConcept(int id) throws ClientNotKnownException {
409 ClientState state = getState(id);
410 return state.getLearningAlgorithm().getCurrentlyBestEvaluatedDescription().toString();
411 }
412
413 /**
414 *
415 * @param id The session ID.
416 * @param nrOfConcepts
417 * @param format
418 * @return
419 * @throws ClientNotKnownException Thrown if client (session ID) is not known.
420 */
421 @WebMethod
422 public String[] getCurrentlyBestConcepts(int id, int nrOfConcepts, String format) throws ClientNotKnownException {
423 ClientState state = getState(id);
424 List<Description> bestConcepts = state.getLearningAlgorithm().getCurrentlyBestDescriptions(nrOfConcepts);
425 List<String> conc=new LinkedList<String>();
426 Iterator<Description> iter=bestConcepts.iterator();
427 while (iter.hasNext())
428 if (format.equals("manchester"))
429 conc.add(iter.next().toManchesterSyntaxString(state.getReasonerComponent().getBaseURI(), new HashMap<String,String>()));
430 else if(format.equals("kb"))
431 conc.add(iter.next().toKBSyntaxString());
432 else
433 conc.add(iter.next().toString());
434 return conc.toArray(new String[conc.size()]);
435 }
436
437 /**
438 *
439 * @param id The session ID.
440 * @param limit
441 * @return
442 * @throws ClientNotKnownException Thrown if client (session ID) is not known.
443 */
444 @WebMethod
445 public String getCurrentlyBestEvaluatedDescriptions(int id, int limit) throws ClientNotKnownException{
446 return currentlyBestEvaluatedDescriptions(id,limit,-1,false);
447 }
448
449 /**
450 *
451 * @param id The session ID.
452 * @param nrOfDescriptions
453 * @param accuracyThreshold
454 * @param filterNonMinimalDescriptions
455 * @return
456 * @throws ClientNotKnownException Thrown if client (session ID) is not known.
457 */
458 @WebMethod
459 public String getCurrentlyBestEvaluatedDescriptionsFiltered(int id,int nrOfDescriptions, double accuracyThreshold, boolean filterNonMinimalDescriptions) throws ClientNotKnownException
460 {
461 return currentlyBestEvaluatedDescriptions(id,nrOfDescriptions,accuracyThreshold,filterNonMinimalDescriptions);
462 }
463
464 /**
465 *
466 * @param id The session ID.
467 * @param nrOfDescriptions
468 * @param accuracyThreshold
469 * @param filterNonMinimalDescriptions
470 * @return
471 * @throws ClientNotKnownException Thrown if client (session ID) is not known.
472 */
473 private String currentlyBestEvaluatedDescriptions(int id,int nrOfDescriptions, double accuracyThreshold, boolean filterNonMinimalDescriptions) throws ClientNotKnownException
474 {
475 ClientState state = getState(id);
476 List<? extends EvaluatedDescription> descriptions;
477 if (accuracyThreshold!=-1) descriptions = state.getLearningAlgorithm().getCurrentlyBestEvaluatedDescriptions(nrOfDescriptions, accuracyThreshold, filterNonMinimalDescriptions);
478 else descriptions = state.getLearningAlgorithm().getCurrentlyBestEvaluatedDescriptions(nrOfDescriptions);
479 String json = "{";
480 int count = 1;
481 for(EvaluatedDescription description : descriptions) {
482 if (count>1) json += ",\"solution" + count + "\" : " + description.asJSON();
483 else json += "\"solution" + count + "\" : " + description.asJSON();
484 count++;
485 }
486 json+="}";
487 return json;
488 }
489
490 /**
491 *
492 * @param id The session ID.
493 * @return
494 * @throws ClientNotKnownException Thrown if client (session ID) is not known.
495 */
496 @WebMethod
497 public boolean isAlgorithmRunning(int id) throws ClientNotKnownException {
498 return getState(id).getLearningAlgorithm().isRunning();
499 }
500
501 /**
502 * Stops the learning algorithm smoothly.
503 * @param id The session ID.
504 * @throws ClientNotKnownException Thrown if client (session ID) is not known.
505 */
506 @WebMethod
507 public void stop(int id) throws ClientNotKnownException {
508 getState(id).getLearningAlgorithm().stop();
509 }
510
511 /////////////////////////////////////////
512 // methods for component configuration //
513 /////////////////////////////////////////
514
515 /**
516 *
517 * @param id The session ID.
518 * @param positiveExamples
519 * @throws ClientNotKnownException Thrown if client (session ID) is not known.
520 */
521 @WebMethod
522 public void setPositiveExamples(int id, String[] positiveExamples) throws ClientNotKnownException {
523 ClientState state = getState(id);
524 Set<String> posExamples = new TreeSet<String>(Arrays.asList(positiveExamples));
525 cm.applyConfigEntry(state.getLearningProblem(), "positiveExamples", posExamples);
526 }
527
528
529 /**
530 *
531 * @param id The session ID.
532 * @param negativeExamples
533 * @throws ClientNotKnownException Thrown if client (session ID) is not known.
534 */
535 @WebMethod
536 public void setNegativeExamples(int id, String[] negativeExamples) throws ClientNotKnownException {
537 ClientState state = getState(id);
538 Set<String> negExamples = new TreeSet<String>(Arrays.asList(negativeExamples));
539 cm.applyConfigEntry(state.getLearningProblem(), "negativeExamples", negExamples);
540 }
541
542 /**
543 *
544 * @param sessionID The session ID.
545 * @param componentID The componentID.
546 * @param optionName The name of the configuration option.
547 * @param value
548 * @throws ClientNotKnownException Thrown if client (session ID) is not known.
549 * @throws UnknownComponentException
550 */
551 @WebMethod
552 public void applyConfigEntryInt(int sessionID, int componentID, String optionName, Integer value) throws ClientNotKnownException, UnknownComponentException {
553 applyConfigEntry(sessionID, componentID,optionName,value);
554 }
555
556 /**
557 *
558 * @param sessionID The session ID.
559 * @param componentID The componentID.
560 * @param optionName The name of the configuration option.
561 * @param value
562 * @throws ClientNotKnownException Thrown if client (session ID) is not known.
563 * @throws UnknownComponentException
564 */
565 @WebMethod
566 public void applyConfigEntryString(int sessionID, int componentID, String optionName, String value) throws ClientNotKnownException, UnknownComponentException {
567 applyConfigEntry(sessionID, componentID,optionName,value);
568 }
569
570 /**
571 *
572 * @param sessionID The session ID.
573 * @param componentID The componentID.
574 * @param optionName The name of the configuration option.
575 * @param value
576 * @throws ClientNotKnownException Thrown if client (session ID) is not known.
577 * @throws UnknownComponentException
578 * @throws MalformedURLException
579 */
580 @WebMethod
581 public void applyConfigEntryURL(int sessionID, int componentID, String optionName, String value) throws ClientNotKnownException, UnknownComponentException, MalformedURLException {
582 // URLs are passed as String and then converted
583 URL url = new URL(value);
584 applyConfigEntry(sessionID, componentID,optionName,url);
585 }
586
587 /**
588 *
589 * @param sessionID The session ID.
590 * @param componentID The componentID.
591 * @param optionName The name of the configuration option.
592 * @param value
593 * @throws ClientNotKnownException Thrown if client (session ID) is not known.
594 * @throws UnknownComponentException
595 */
596 @WebMethod
597 public void applyConfigEntryStringArray(int sessionID, int componentID, String optionName, String[] value) throws ClientNotKnownException, UnknownComponentException {
598 Set<String> stringSet = new TreeSet<String>(Arrays.asList(value));
599 applyConfigEntry(sessionID, componentID,optionName,stringSet);
600 }
601
602 /**
603 *
604 * @param sessionID The session ID.
605 * @param componentID The componentID.
606 * @param optionName The name of the configuration option.
607 * @param value
608 * @throws ClientNotKnownException Thrown if client (session ID) is not known.
609 * @throws UnknownComponentException
610 */
611 @WebMethod
612 public void applyConfigEntryBoolean(int sessionID, int componentID, String optionName, Boolean value) throws ClientNotKnownException, UnknownComponentException {
613 applyConfigEntry(sessionID, componentID,optionName,value);
614 }
615
616 /**
617 *
618 * @param sessionID The session ID.
619 * @param componentID The componentID.
620 * @param optionName The name of the configuration option.
621 * @param value
622 * @throws ClientNotKnownException Thrown if client (session ID) is not known.
623 * @throws UnknownComponentException
624 */
625 private void applyConfigEntry(int sessionID, int componentID, String optionName, Object value) throws ClientNotKnownException, UnknownComponentException {
626 ClientState state = getState(sessionID);
627 Component component = state.getComponent(componentID);
628 cm.applyConfigEntry(component, optionName, value);
629 }
630
631 /**
632 *
633 * @param sessionID The session ID.
634 * @param componentID The componentID.
635 * @param optionName The name of the configuration option.
636 * @return
637 * @throws ClientNotKnownException Thrown if client (session ID) is not known.
638 * @throws UnknownComponentException
639 * @throws ConfigOptionTypeException
640 */
641 @WebMethod
642 public String[] getConfigOptionValueStringArray(int sessionID, int componentID, String optionName) throws ClientNotKnownException, UnknownComponentException, ConfigOptionTypeException {
643 return getConfigOptionValue(sessionID, componentID, optionName, String[].class);
644 }
645
646 /**
647 *
648 * @param sessionID The session ID.
649 * @param componentID The componentID.
650 * @param optionName The name of the configuration option.
651 * @return
652 * @throws ClientNotKnownException Thrown if client (session ID) is not known.
653 * @throws UnknownComponentException
654 * @throws ConfigOptionTypeException
655 */
656 @WebMethod
657 public String getConfigOptionValueString(int sessionID, int componentID, String optionName) throws ClientNotKnownException, UnknownComponentException, ConfigOptionTypeException {
658 return getConfigOptionValue(sessionID, componentID, optionName, String.class);
659 }
660
661 /**
662 *
663 * @param sessionID The session ID.
664 * @param componentID The componentID.
665 * @param optionName The name of the configuration option.
666 * @return
667 * @throws ClientNotKnownException Thrown if client (session ID) is not known.
668 * @throws UnknownComponentException
669 * @throws ConfigOptionTypeException
670 */
671 @WebMethod
672 public String getConfigOptionValueURL(int sessionID, int componentID, String optionName) throws ClientNotKnownException, UnknownComponentException, ConfigOptionTypeException {
673 URL url = getConfigOptionValue(sessionID, componentID, optionName, URL.class);
674 return url.toString();
675 }
676
677 /**
678 *
679 * @param sessionID The session ID.
680 * @param componentID The componentID.
681 * @param optionName The name of the configuration option.
682 * @return
683 * @throws ClientNotKnownException Thrown if client (session ID) is not known.
684 * @throws UnknownComponentException
685 * @throws ConfigOptionTypeException
686 */
687 @WebMethod
688 public Double getConfigOptionValueDouble(int sessionID, int componentID, String optionName) throws ClientNotKnownException, UnknownComponentException, ConfigOptionTypeException {
689 return getConfigOptionValue(sessionID, componentID, optionName, Double.class);
690 }
691
692 /**
693 *
694 * @param sessionID The session ID.
695 * @param componentID The componentID.
696 * @param optionName The name of the configuration option.
697 * @return
698 * @throws ClientNotKnownException Thrown if client (session ID) is not known.
699 * @throws UnknownComponentException
700 * @throws ConfigOptionTypeException
701 */
702 @WebMethod
703 public Boolean getConfigOptionValueBoolean(int sessionID, int componentID, String optionName) throws ClientNotKnownException, UnknownComponentException, ConfigOptionTypeException {
704 return getConfigOptionValue(sessionID, componentID, optionName, Boolean.class);
705 }
706
707 /**
708 *
709 * @param sessionID The session ID.
710 * @param componentID The componentID.
711 * @param optionName The name of the configuration option.
712 * @return
713 * @throws ClientNotKnownException Thrown if client (session ID) is not known.
714 * @throws UnknownComponentException
715 * @throws ConfigOptionTypeException
716 */
717 @WebMethod
718 public Integer getConfigOptionValueInt(int sessionID, int componentID, String optionName) throws ClientNotKnownException, UnknownComponentException, ConfigOptionTypeException {
719 return getConfigOptionValue(sessionID, componentID, optionName, Integer.class);
720 }
721
722 ////////////////////////////////////
723 // reasoning and querying methods //
724 ////////////////////////////////////
725
726 @WebMethod
727 public String[] getAtomicConcepts(int id) throws ClientNotKnownException {
728 Set<NamedClass> atomicConcepts = getState(id).getReasonerComponent().getNamedClasses();
729 return Datastructures.sortedSet2StringListConcepts(atomicConcepts);
730 }
731
732 @WebMethod
733 public String getSubsumptionHierarchy(int id) throws ClientNotKnownException {
734 return getState(id).getReasonerComponent().toString();
735 }
736
737 @WebMethod
738 public String[] retrieval(int id, String conceptString) throws ClientNotKnownException, ParseException {
739 ClientState state = getState(id);
740 // call parser to parse concept
741 Description concept = null;
742 concept = KBParser.parseConcept(conceptString);
743 Set<Individual> individuals = state.getReasonerComponent().getIndividuals(concept);
744 return Datastructures.sortedSet2StringListIndividuals(individuals);
745 }
746
747 @WebMethod
748 public int getConceptLength(String conceptString) throws ParseException {
749 // call parser to parse concept
750 return KBParser.parseConcept(conceptString).getLength();
751 }
752
753 @WebMethod
754 public String[] getAtomicRoles(int id) throws ClientNotKnownException {
755 ClientState state = getState(id);
756 Set<ObjectProperty> roles = state.getReasonerComponent().getObjectProperties();
757 return Datastructures.sortedSet2StringListRoles(roles);
758 }
759
760 @WebMethod
761 public String[] getInstances(int id) throws ClientNotKnownException {
762 ClientState state = getState(id);
763 Set<Individual> individuals = state.getReasonerComponent().getIndividuals();
764 return Datastructures.sortedSet2StringListIndividuals(individuals);
765 }
766
767 @WebMethod
768 public String[] getIndividualsForARole(int id, String role) throws ClientNotKnownException {
769 ClientState state = getState(id);
770 Map<Individual,SortedSet<Individual>> m = state.getReasonerComponent().getPropertyMembers(new ObjectProperty(role));
771 Set<Individual> individuals = m.keySet();
772 return Datastructures.sortedSet2StringListIndividuals(individuals);
773 }
774
775 ////////////////////////////////////////
776 // SPARQL component methods //
777 ////////////////////////////////////////
778
779
780 @WebMethod
781 public String getAsJSON(int sessionID, int queryID) throws ClientNotKnownException, SparqlQueryException
782 {
783 ClientState state = getState(sessionID);
784 //ResultSet resultSet=null;
785 String json = null;
786 try {
787 json = state.getQuery(queryID).getJson();
788 }catch (Exception e) {
789 e.printStackTrace();
790 throw new SparqlQueryException("SparqlQuery failed"+e.toString());
791 }
792
793 if(json == null) { throw new SparqlQueryException("Sparql Query failed. Please try again later.");}
794 return json;
795 //if ((json=state.getQuery(queryID).getJson())!=null) return json;
796 //else if ((resultSet=state.getQuery(queryID).getResultSet())!=null) return SparqlQuery.getAsJSON(resultSet);
797 //else return SparqlQuery.getAsJSON(state.getQuery(queryID).send());
798 }
799
800 @WebMethod
801 public String getAsXMLString(int sessionID, int queryID) throws ClientNotKnownException, SparqlQueryException
802 {
803 ClientState state = getState(sessionID);
804
805 String xml = null;
806 try{
807 xml = state.getQuery(queryID).getXMLString();
808 }catch (Exception e) {
809 e.printStackTrace();
810 throw new SparqlQueryException("SparqlQuery failed"+e.toString());
811 }
812
813 if(xml == null) throw new SparqlQueryException("SparqlQuery failed xml was null");
814 return xml;
815 //if ((resultSet=state.getQuery(queryID).getResultSet())!=null) return SparqlQuery.getAsXMLString(resultSet);
816 //if ((json=state.getQuery(queryID).getJson())!=null) return SparqlQuery.getAsXMLString(SparqlQuery.JSONtoResultSet(json));
817 //else return SparqlQuery.getAsXMLString(state.getQuery(queryID).send());
818 }
819
820 @WebMethod
821 public int sparqlQueryThreaded(int sessionID, int componentID, String query) throws ClientNotKnownException
822 {
823 final ClientState state = getState(sessionID);
824 Component component = state.getComponent(componentID);
825 final SparqlKnowledgeSource ks=(SparqlKnowledgeSource)component;
826 final int id=state.addQuery(ks.sparqlQuery(query));
827 Thread sparqlThread = new Thread() {
828 @Override
829 public void run() {
830 if (ks.isUseCache()){
831 state.getQuery(id).setRunning(true);
832 Cache cache=new Cache(ks.getCacheDir());
833 cache.executeSparqlQuery(state.getQuery(id));
834 state.getQuery(id).setRunning(false);
835 }
836 else{
837 state.getQuery(id).setRunning(true);
838 state.getQuery(id).send();
839 state.getQuery(id).setRunning(false);
840 }
841 }
842 };
843 sparqlThread.start();
844 return id;
845 }
846
847 @WebMethod
848 public String sparqlQuery(int sessionID, int componentID, String query) throws ClientNotKnownException
849 {
850 ClientState state = getState(sessionID);
851 Component component = state.getComponent(componentID);
852 SparqlKnowledgeSource ks=(SparqlKnowledgeSource)component;
853 return ks.getSPARQLTasks().query(query);
854 /*SparqlQuery sparql=ks.sparqlQuery(query);
855 if (ks.isUseCache()){
856 Cache cache=new Cache(ks.getCacheDir());
857 return cache.executeSparqlQuery(sparql);
858 }
859 else return sparql.getJson();*/
860 }
861
862 /**
863 * Queries one of the standard endpoints defined in DL-Learner.
864 * @param predefinedEndpoint A string describing the endpoint e.g. DBpedia.
865 * @param query The SPARQL query.
866 * @param useCache Specify whether to use a cache for queries.
867 * @return The result of the SPARQL query in JSON format or null if the endpoint does not exist.
868 * @see SPARQLEndpoint#getEndpointByName;
869 */
870 @WebMethod
871 public String sparqlQueryPredefinedEndpoint(String predefinedEndpoint, String query, boolean useCache) {
872 SparqlEndpoint endpoint = SparqlEndpoint.getEndpointByName(predefinedEndpoint);
873 SPARQLTasks st;
874 if(useCache) {
875 st = new SPARQLTasks(endpoint);
876 } else {
877 st = new SPARQLTasks(Cache.getDefaultCache(), endpoint);
878 }
879 return st.query(query);
880 }
881
882 @WebMethod
883 public boolean isSparqlQueryRunning(int sessionID, int queryID) throws ClientNotKnownException
884 {
885 ClientState state = getState(sessionID);
886 return state.getQuery(queryID).isRunning();
887 }
888
889 @WebMethod
890 public void stopSparqlThread(int sessionID, int queryID) throws ClientNotKnownException
891 {
892 ClientState state = getState(sessionID);
893 state.getQuery(queryID).stop();
894 }
895
896 @WebMethod
897 public int[] getConceptDepth(int id, int nrOfConcepts) throws ClientNotKnownException {
898 ClientState state = getState(id);
899 List<Description> bestConcepts = state.getLearningAlgorithm().getCurrentlyBestDescriptions(nrOfConcepts);
900 Iterator<Description> iter=bestConcepts.iterator();
901 int[] length=new int[bestConcepts.size()];
902 int i=0;
903 while (iter.hasNext()){
904 length[i]=iter.next().getDepth();
905 i++;
906 }
907 return length;
908 }
909
910 @WebMethod
911 public int[] getConceptArity(int id, int nrOfConcepts) throws ClientNotKnownException {
912 ClientState state = getState(id);
913 List<Description> bestConcepts = state.getLearningAlgorithm().getCurrentlyBestDescriptions(nrOfConcepts);
914 Iterator<Description> iter=bestConcepts.iterator();
915 int[] arity=new int[bestConcepts.size()];
916 int i=0;
917 while (iter.hasNext()){
918 arity[i]=iter.next().getArity();
919 i++;
920 }
921 return arity;
922 }
923
924 @WebMethod
925 public String SparqlRetrieval(String conceptString,int limit) throws ParseException {
926 // call parser to parse concept
927 return SparqlQueryDescriptionConvertVisitor.getSparqlQuery(conceptString,limit);
928 }
929
930 @WebMethod
931 public String getNaturalDescription(int id, String conceptString, String endpoint) throws ParseException, ClientNotKnownException {
932 // call parser to parse concept
933 ClientState state = getState(id);
934 ReasonerComponent service = state.getReasonerComponent();
935 return NaturalLanguageDescriptionConvertVisitor.getNaturalLanguageDescription(conceptString, service);
936 }
937
938 @WebMethod
939 public String[] getNegativeExamples(int sessionID, int componentID,String[] positives, int results, String namespace, String[] filterClasses) throws ClientNotKnownException
940 {
941 int sparqlResultSetLimit = 500;
942 SortedSet<String> positiveSet = new TreeSet<String>(Arrays.asList(positives));
943 SortedSet<String> filterSet = new TreeSet<String>(Arrays.asList(filterClasses));
944 ClientState state = getState(sessionID);
945 Component component = state.getComponent(componentID);
946 SparqlKnowledgeSource ks=(SparqlKnowledgeSource)component;
947 SPARQLTasks task=ks.getSPARQLTasks();
948 AutomaticNegativeExampleFinderSPARQL finder=new AutomaticNegativeExampleFinderSPARQL(positiveSet,task,filterSet);
949
950 /*finder.makeNegativeExamplesFromNearbyClasses(positiveSet, sparqlResultSetLimit);
951 SortedSet<String> negExamples=finder.getNegativeExamples(results);
952 if (negExamples.isEmpty()){*/
953 finder.makeNegativeExamplesFromParallelClasses(positiveSet, sparqlResultSetLimit);
954 SortedSet<String> negExamples=finder.getNegativeExamples(results);
955 if(negExamples.isEmpty()){
956 finder.makeNegativeExamplesFromRelatedInstances(positiveSet, namespace);
957 negExamples = finder.getNegativeExamples(results);
958 if(negExamples.isEmpty()){
959 finder.makeNegativeExamplesFromSuperClassesOfInstances(positiveSet, sparqlResultSetLimit);
960 negExamples = finder.getNegativeExamples(results);
961 if(negExamples.isEmpty()) {
962 finder.makeNegativeExamplesFromRandomInstances();
963 negExamples = finder.getNegativeExamples(results);
964 }
965 }
966 }
967 //}
968
969 return negExamples.toArray(new String[negExamples.size()]);
970 }
971
972 /////////////////////////////
973 // private utility methods //
974 /////////////////////////////
975
976 // returns session state or throws client not known exception
977 private ClientState getState(int id) throws ClientNotKnownException {
978 ClientState state = clients.get(id);
979 if(state==null)
980 throw new ClientNotKnownException(id);
981 return state;
982 }
983
984 @SuppressWarnings({"unchecked"})
985 private <T> T getConfigOptionValue(int sessionID, int componentID, String optionName, Class<T> clazz) throws ClientNotKnownException, UnknownComponentException, ConfigOptionTypeException {
986 Object value = getConfigOptionValue(sessionID, componentID, optionName);
987 if(clazz.isInstance(value))
988 return (T) value;
989 else
990 throw new ConfigOptionTypeException(optionName, clazz, value.getClass());
991 }
992
993 private Object getConfigOptionValue(int sessionID, int componentID, String optionName) throws ClientNotKnownException, UnknownComponentException {
994 ClientState state = getState(sessionID);
995 Component component = state.getComponent(componentID);
996 return cm.getConfigOptionValue(component, optionName);
997 }
998
999 }