KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > hp > hpl > jena > reasoner > dig > DIGQueryTranslator


1 /*****************************************************************************
2  * Source code information
3  * -----------------------
4  * Original author Ian Dickinson, HP Labs Bristol
5  * Author email Ian.Dickinson@hp.com
6  * Package Jena 2
7  * Web http://sourceforge.net/projects/jena/
8  * Created July 19th 2003
9  * Filename $RCSfile: DIGQueryTranslator.java,v $
10  * Revision $Revision: 1.16 $
11  * Release status $State: Exp $
12  *
13  * Last modified on $Date: 2005/03/16 18:52:27 $
14  * by $Author: ian_dickinson $
15  *
16  * (c) Copyright 2001, 2002, 2003, 2004, 2005 Hewlett-Packard Development Company, LP
17  * [See end of file]
18  * ****************************************************************************/

19
20 // Package
21
///////////////
22
package com.hp.hpl.jena.reasoner.dig;
23
24
25 // Imports
26
///////////////
27
import java.util.*;
28 import java.util.Iterator JavaDoc;
29 import java.util.List JavaDoc;
30
31 import org.apache.commons.logging.LogFactory;
32 import org.w3c.dom.Document JavaDoc;
33 import org.w3c.dom.Element JavaDoc;
34
35 import com.hp.hpl.jena.graph.*;
36 import com.hp.hpl.jena.rdf.model.Model;
37 import com.hp.hpl.jena.reasoner.TriplePattern;
38 import com.hp.hpl.jena.reasoner.rulesys.Node_RuleVariable;
39 import com.hp.hpl.jena.util.iterator.*;
40 import com.hp.hpl.jena.util.xml.SimpleXMLPath;
41 import com.hp.hpl.jena.util.xml.SimpleXMLPathElement;
42
43
44 /**
45  * <p>
46  * Base class for translators that map incoming RDF find patterns to DIG queries.
47  * </p>
48  *
49  * @author Ian Dickinson, HP Labs (<a HREF="mailto:Ian.Dickinson@hp.com">email</a>)
50  * @version Release @release@ ($Id: DIGQueryTranslator.java,v 1.16 2005/03/16 18:52:27 ian_dickinson Exp $)
51  */

52 public abstract class DIGQueryTranslator {
53     // Constants
54
//////////////////////////////////
55

56     public static final String JavaDoc ALL = "*";
57
58
59     // Static variables
60
//////////////////////////////////
61

62
63     // Instance variables
64
//////////////////////////////////
65

66     /** The node that the incoming subject must match */
67     private Node m_subject;
68
69     /** The node that the incoming object must match */
70     private Node m_object;
71
72     /** The node that the incoming predicate must match */
73     private Node m_pred;
74
75
76     // Constructors
77
//////////////////////////////////
78

79     /**
80      * <p>Construct an abstract translator, given the URI's of nodes to match against
81      * or null to represent
82      */

83     public DIGQueryTranslator( String JavaDoc subject, String JavaDoc predicate, String JavaDoc object ) {
84         m_subject = mapNode( subject );
85         m_pred = mapNode( predicate );
86         m_object = mapNode( object );
87     }
88
89
90     // External signature methods
91
//////////////////////////////////
92

93     /**
94      * <p>Translate the given pattern to a DIG query, and pass it on to the DIG
95      * adapter as a query. Translate the results of the query back to a
96      * triple stream via an extended iterator. Assumes this method is called
97      * contingent on a successful {@link #trigger}.</p>
98      * @param pattern The pattern to translate to a DIG query
99      * @param da The DIG adapter through which we communicate with a DIG reasoner
100      */

101     public ExtendedIterator find( TriplePattern pattern, DIGAdapter da ) {
102         DIGConnection dc = da.getConnection();
103
104         // pose the query to the dig reasoner
105
Document JavaDoc query = translatePattern( pattern, da );
106         if (query == null) {
107             LogFactory.getLog( getClass() ).warn( "Could not find pattern translator for nested DIG query " + pattern );
108         }
109         Document JavaDoc response = da.getConnection().sendDigVerb( query, da.getProfile() );
110
111         boolean warn = dc.warningCheck( response );
112         if (warn) {
113             for (Iterator JavaDoc i = dc.getWarnings(); i.hasNext(); ) {
114                 LogFactory.getLog( getClass() ).warn( i.next() );
115             }
116         }
117
118         // translate the response back to triples
119
return translateResponse( response, pattern, da );
120     }
121
122
123     /**
124      * <p>Translate the given pattern (with given premises)
125      * to a DIG query, and pass it on to the DIG
126      * adapter as a query. Translate the results of the query back to a
127      * triple stream via an extended iterator.</p>
128      * @param pattern The pattern to translate to a DIG query
129      * @param da The DIG adapter through which we communicate with a DIG reasoner
130      * @param premises Model conveying additional information about the resources
131      * in the subject or object
132      */

133     public ExtendedIterator find( TriplePattern pattern, DIGAdapter da, Model premises ) {
134         DIGConnection dc = da.getConnection();
135
136         // pose the query to the dig reasoner
137
Document JavaDoc query = translatePattern( pattern, da, premises );
138         if (query == null) {
139             LogFactory.getLog( getClass() ).warn( "Could not find pattern translator for nested DIG query " + pattern );
140             return NullIterator.instance;
141         }
142         else {
143             Document JavaDoc response = da.getConnection().sendDigVerb( query, da.getProfile() );
144
145             boolean warn = dc.warningCheck( response );
146             if (warn) {
147                 for (Iterator JavaDoc i = dc.getWarnings(); i.hasNext(); ) {
148                     LogFactory.getLog( getClass() ).warn( i.next() );
149                 }
150             }
151
152             // translate the response back to triples
153
return translateResponse( response, pattern, da );
154         }
155     }
156
157
158     /**
159      * <p>Answer true if this translator applies to the given triple pattern.</p>
160      * @param pattern An incoming patter to match against
161      * @param da The current dig adapter
162      * @param premises An optional Model that is used to convey the statements in the additional
163      * premises to the query
164      * @return True if this translator applies to the pattern.
165      */

166     public boolean trigger( TriplePattern pattern, DIGAdapter da, Model premises ) {
167         return trigger( m_subject, pattern.getSubject(), premises ) &&
168                trigger( m_object, pattern.getObject(), premises ) &&
169                trigger( m_pred, pattern.getPredicate(), premises ) &&
170                checkTriple( pattern, da, premises );
171     }
172
173
174     /**
175      * <p>An optional post-trigger check on the consituents of the triple pattern. By default,
176      * delegates to a check on each of the subjec, object and predicate. However, this method
177      * may be overridden by sub-classes to provide a more context-sensitive test.</p>
178      * @param pattern The triple pattern
179      * @param da The current dig adapter
180      * @param premises Model denoting premises to the query, or null
181      * @return True if the pattern conforms to the prerequisites for a given translation step
182      */

183     public boolean checkTriple( TriplePattern pattern, DIGAdapter da, Model premises ) {
184         return checkSubject( pattern.getSubject(), da, premises ) &&
185                checkObject( pattern.getObject(), da, premises ) &&
186                checkPredicate( pattern.getPredicate(), da, premises );
187
188     }
189
190
191     /**
192      * <p>Additional test on the subject of the incoming find pattern. Default
193      * is to always match</p>
194      * @param subject The subject resource from the incoming pattern
195      * @param da The current dig adapter
196      * @param premises A model that conveys additional information about the premises
197      * of the query, which might assist the check to suceed or fail. By default it
198      * is ignored.
199      * @return True if this subject matches the trigger condition expressed by this translator instance
200      */

201     public boolean checkSubject( Node subject, DIGAdapter da, Model premises ) {
202         return true;
203     }
204
205
206     /**
207      * <p>Additional test on the object of the incoming find pattern. Default
208      * is to always match</p>
209      * @param object The object resource from the incoming pattern
210      * @param da The current dig adapter
211      * @param premises A model that conveys additional information about the premises
212      * of the query, which might assist the check to suceed or fail. By default it
213      * is ignored.
214      * @return True if this object matches the trigger condition expressed by this translator instance
215      */

216     public boolean checkObject( Node object, DIGAdapter da, Model premises ) {
217         return true;
218     }
219
220
221     /**
222      * <p>Additional test on the predicate of the incoming find pattern. Default
223      * is to always match</p>
224      * @param pred The predicate resource from the incoming pattern
225      * @param da The current dig adapter
226      * @param premises A model that conveys additional information about the premises
227      * of the query, which might assist the check to suceed or fail. By default it
228      * is ignored.
229      * @return True if this predicate matches the trigger condition expressed by this translator instance
230      */

231     public boolean checkPredicate( Node pred, DIGAdapter da, Model premises ) {
232         return true;
233     }
234
235
236     /**
237      * <p>Answer an XML document that presents the translation of the query into DIG query language.</p>
238      */

239     public abstract Document JavaDoc translatePattern( TriplePattern query, DIGAdapter da );
240
241     /**
242      * <p>Answer an XML document that presents the translation of the query into DIG query language,
243      * given that either the subject or object may be expressions defined by the statements
244      * in the premises model.</p>
245      */

246     public abstract Document JavaDoc translatePattern( TriplePattern pattern, DIGAdapter da, Model premises );
247
248     /**
249      * <p>Answer an extended iterator over the triples that result from translatig the given DIG response
250      * to RDF.</p>
251      */

252     public final ExtendedIterator translateResponse( Document JavaDoc response, TriplePattern query, DIGAdapter da ) {
253         ExtendedIterator i = translateResponseHook( response, query, da );
254         Filter f = getResultsTripleFilter( query );
255         return (f == null) ? i : i.filterKeep( f );
256     }
257
258
259     // Internal implementation methods
260
//////////////////////////////////
261

262     /**
263      * <p>Answer an extended iterator over the triples that result from translatig the given DIG response
264      * to RDF.</p>
265      */

266     protected abstract ExtendedIterator translateResponseHook( Document JavaDoc response, TriplePattern query, DIGAdapter da );
267
268
269     /**
270      * <p>Answer a node corresponding to the given URI.</p>
271      * @param uri A node URI, or the special string *, or null.
272      * @return A Jena Node corresponding to the given URI
273      */

274     protected Node mapNode( String JavaDoc uri ) {
275         if (uri == null) {
276             return null;
277         }
278         else {
279             return (uri.equals( ALL )) ? Node_RuleVariable.WILD : Node.createURI( uri );
280         }
281     }
282
283
284     /**
285      * <p>A node matches a trigger (lhs) node if either the lhs is null, or
286      * the nodes are equal. Note: not matching in the same sense as triple patterns.</p>
287      * @param lhs The trigger node to match against
288      * @param rhs The incoming pattern node
289      * @param premises A model that conveys additional information about the premises
290      * of the query, which might assist the trigger to suceed or fail. By default it
291      * is ignored.
292      * @return True if match
293      */

294     protected boolean trigger( Node lhs, Node rhs, Model premises ) {
295         return (lhs == null) || lhs.equals( rhs );
296     }
297
298
299     /**
300      * <p>Answer true if the given document is the response &lt;true&gt; from a DIG reasoner.
301      * @param response The document encoding the response
302      * @return True iff this is the response <code>true</code>.
303      */

304     protected boolean isTrue( Document JavaDoc response ) {
305         return new SimpleXMLPath( true )
306                .appendElementPath( DIGProfile.TRUE )
307                .getAll( response )
308                .hasNext();
309     }
310
311
312     /**
313      * <p>Answer true if the given document is the response &lt;false&gt; from a DIG reasoner.
314      * @param response The document encoding the response
315      * @return True iff this is the response <code>false</code>.
316      */

317     protected boolean isFalse( Document JavaDoc response ) {
318         return new SimpleXMLPath( true )
319                .appendElementPath( DIGProfile.FALSE )
320                .getAll( response )
321                .hasNext();
322     }
323
324
325     /**
326      * <p>Translate a concept set document into an extended iterator
327      * of triples, placing the concept identities into either the subject
328      * or object position in the returned triple.</p>
329      * @param response The response XML document
330      * @param query The original query
331      * @param object Flag to indicate that the concept names should occupy the subject field
332      * of the returned triple, otherwise the object
333      */

334     protected ExtendedIterator translateConceptSetResponse( Document JavaDoc response, TriplePattern query, boolean object, DIGAdapter da ) {
335         return translateNameSetResponse( response, query, object,
336                                          new String JavaDoc[] {DIGProfile.CONCEPT_SET, DIGProfile.SYNONYMS, DIGProfile.CATOM} )
337                .andThen( translateSpecialConcepts( response, da,
338                                                    object ? query.getSubject() : query.getObject(),
339                                                    query.getPredicate(), object ));
340     }
341
342
343     /**
344      * <p>Translate a role set document into an extended iterator
345      * of triples, placing the concept identities into either the subject
346      * or object position in the returned triple.</p>
347      * @param response The response XML document
348      * @param query The original query
349      * @param object Flag to indicate that the role names should occupy the subject field
350      * of the returned triple, or the object
351      */

352     protected ExtendedIterator translateRoleSetResponse( Document JavaDoc response, TriplePattern query, boolean object ) {
353         return translateNameSetResponse( response, query, object,
354                                          new String JavaDoc[] {DIGProfile.ROLE_SET, DIGProfile.SYNONYMS, DIGProfile.RATOM} );
355     }
356
357
358     /**
359      * <p>Translate an instance set document into an extended iterator
360      * of triples, placing the concept identities into either the subject
361      * or object position in the returned triple.</p>
362      * @param response The response XML document
363      * @param query The original query
364      * @param object Flag to indicate that the instance names should occupy the subject field
365      * of the returned triple, or the object
366      */

367     protected ExtendedIterator translateIndividualSetResponse( Document JavaDoc response, TriplePattern query, boolean object ) {
368         return translateNameSetResponse( response, query, object,
369                                          new String JavaDoc[] {DIGProfile.INDIVIDUAL_SET, DIGProfile.INDIVIDUAL} );
370     }
371
372
373     /**
374      * <p>Translate an document encoding a set of named entities into an extended iterator
375      * of triples, placing the concept identities into either the subject
376      * or object position in the returned triple.</p>
377      * @param response The response XML document
378      * @param query The original query
379      * @param object Flag to indicate that the instance names should occupy the subject field
380      * of the returned triple, or the object
381      * @param path The element name path to follow from the root
382      */

383     protected ExtendedIterator translateNameSetResponse( Document JavaDoc response, TriplePattern query, boolean object, String JavaDoc[] path ) {
384         // evaluate a path through the return value to give us an iterator over catom names
385
SimpleXMLPath p = new SimpleXMLPath( true );
386
387         // build the path
388
for (int i = 0; i < path.length; i++) {
389             p.appendElementPath( path[i] );
390         }
391         p.appendAttrPath( DIGProfile.NAME );
392
393         // and evaluate it
394
ExtendedIterator iNodes = p.getAll( response ).mapWith( new DIGValueToNodeMapper() );
395
396         // return the results as triples
397
if (object) {
398             return iNodes.mapWith( new TripleObjectFiller( query.getSubject(), query.getPredicate() ) );
399         }
400         else {
401             return iNodes.mapWith( new TripleSubjectFiller( query.getPredicate(), query.getObject() ) );
402         }
403     }
404
405     /**
406      * <p>Check if a document representing a concept-set response from the DIG reasoner
407      * contains a given node as a value, and, if so, return a singleton iterator over the
408      * given result triple.</p>
409      * @param response The XML document to process
410      * @param da The DIG adapter
411      * @param node The node we are seeking
412      * @param result The triple to return if node occurs in the concept set in response
413      * @return The singeleton iterator over result, or the null iterator if node is not present
414      * in the response.
415      */

416     protected ExtendedIterator conceptSetNameCheck( Document JavaDoc response, DIGAdapter da, Node node, Triple result ) {
417         // evaluate a path through the return value to give us an iterator over catom names
418
ExtendedIterator catoms = new SimpleXMLPath( true )
419                                      .appendElementPath( DIGProfile.CONCEPT_SET )
420                                      .appendElementPath( DIGProfile.SYNONYMS )
421                                      .appendElementPath( SimpleXMLPathElement.ALL_CHILDREN )
422                                      .getAll( response );
423
424         // search for the object name
425
String JavaDoc oName = da.getNodeID( node );
426
427         boolean seekingTop = oName.equals( da.getOntLanguage().THING().getURI() );
428         boolean seekingBottom = oName.equals( da.getOntLanguage().NOTHING().getURI() );
429
430         boolean found = false;
431         while (!found && catoms.hasNext()) {
432             Element JavaDoc name = (Element JavaDoc) catoms.next();
433
434             found = (seekingTop && name.getNodeName().equals( DIGProfile.TOP )) ||
435                     (seekingBottom && name.getNodeName().equals( DIGProfile.BOTTOM )) ||
436                     name.getAttribute( DIGProfile.NAME ).equals( oName );
437         }
438
439         // the resulting iterator is either of length 0 or 1
440
return found ? (ExtendedIterator) new SingletonIterator( result )
441                      : NullIterator.instance;
442     }
443
444
445     /**
446      * <p>Answer an iterator that contains appropriate triples if the given
447      * response contains either top or bottom elements.</p>
448      * @param response The XML document to process
449      * @param da The DIG adapter
450      * @param ref The fixed node in the triple
451      * @param pred The predicate in the triple
452      * @param refSubject True if the reference node is to be the subject of any
453      * created triples
454      * @return An iterator over any subset of Thing and Nothing, if either
455      * or both of top and bottom appear as elements in the response document.
456      */

457     protected ExtendedIterator translateSpecialConcepts( Document JavaDoc response, DIGAdapter da, Node ref, Node pred, boolean refSubject ) {
458         SimpleXMLPath topPath = new SimpleXMLPath( true )
459                                     .appendElementPath( DIGProfile.CONCEPT_SET )
460                                     .appendElementPath( DIGProfile.SYNONYMS )
461                                     .appendElementPath( DIGProfile.TOP );
462         SimpleXMLPath bottomPath = new SimpleXMLPath( true )
463                                     .appendElementPath( DIGProfile.CONCEPT_SET )
464                                     .appendElementPath( DIGProfile.SYNONYMS )
465                                     .appendElementPath( DIGProfile.BOTTOM );
466
467         List JavaDoc specials = new ArrayList();
468
469         if (topPath.getAll( response ).hasNext()) {
470             // the returned concepts include <top/>
471
Node n = da.getOntLanguage().THING().asNode();
472             specials.add( refSubject ? new Triple( ref, pred, n )
473                                      : new Triple( n, pred, ref ) );
474
475         }
476         if (bottomPath.getAll( response ).hasNext()) {
477             // the returned concepts include <bottom/>
478
Node n = da.getOntLanguage().NOTHING().asNode();
479             specials.add( refSubject ? new Triple( ref, pred, n )
480                                      : new Triple( n, pred, ref ) );
481
482         }
483
484         return WrappedIterator.create( specials.iterator() );
485     }
486
487
488     /**
489      * <p>Extension point: translators can add an optional filter stage to
490      * the translated result by providing a non-null filter here. The filter
491      * should accept triples, and return true for those triples that are to
492      * remain in the final result iterator.</p>
493      * @return An optional filter on the results of a DIG query
494      */

495     protected Filter getResultsTripleFilter( TriplePattern query ) {
496         return null;
497     }
498
499
500     //==============================================================================
501
// Inner class definitions
502
//==============================================================================
503

504 }
505
506
507 /*
508  * (c) Copyright 2001, 2002, 2003, 2004, 2005 Hewlett-Packard Development Company, LP
509  * All rights reserved.
510  *
511  * Redistribution and use in source and binary forms, with or without
512  * modification, are permitted provided that the following conditions
513  * are met:
514  * 1. Redistributions of source code must retain the above copyright
515  * notice, this list of conditions and the following disclaimer.
516  * 2. Redistributions in binary form must reproduce the above copyright
517  * notice, this list of conditions and the following disclaimer in the
518  * documentation and/or other materials provided with the distribution.
519  * 3. The name of the author may not be used to endorse or promote products
520  * derived from this software without specific prior written permission.
521  *
522  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
523  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
524  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
525  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
526  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
527  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
528  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
529  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
530  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
531  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
532  */

533
Popular Tags