capture
[rrq/gorite.git] / com / intendico / data / Not.java
1 /*********************************************************************
2 Copyright 2012, Ralph Ronnquist.
3
4 This file is part of GORITE.
5
6 GORITE is free software: you can redistribute it and/or modify it
7 under the terms of the Lesser GNU General Public License as published
8 by the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 GORITE is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
14 License for more details.
15
16 You should have received a copy of the Lesser GNU General Public
17 License along with GORITE.  If not, see <http://www.gnu.org/licenses/>.
18 **********************************************************************/
19
20 package com.intendico.data;
21
22 import java.util.Vector;
23 import java.util.Iterator;
24 import java.util.Observer;
25
26 /**
27  * The Not class implements a negation-by-failure query, which is true
28  * only if the wrapped {@link Query} does not provide any valid
29  * bindings. The Not class also manages input bindings to ensure that
30  * nothing unbound gets bound by the wrapped query.
31  */
32 public class Not implements Query {
33
34     /**
35      * Flag to mark whether the query has been tested.
36      */
37     public boolean tested;
38
39     /**
40      * Holds unbound input variables.
41      */
42     public Vector/*<Ref>*/ unbound;
43
44     /**
45      * Holds wrapped query.
46      */
47     public Query query;
48
49     /**
50      * Constructor.
51      */
52     public Not(Query q) throws Exception {
53         query = q;
54         reset();
55     }
56
57     /**
58      * Implements {@link Query#copy} by creating a new Not object
59      * around a copy of the wrapped query.
60      */
61     public Query copy(Vector/*<Ref>*/ newrefs) throws Exception {
62         return new Not( query.copy( newrefs ) );
63     }
64
65     /**
66      * Implements {@link Query#reset} by capturing unbound Ref
67      * objects, then forwarding the reset call to the wrapped query.
68      */
69     public void reset() throws Exception {
70         unbound = new Vector/*<Ref>*/();
71         for ( Iterator/*<Ref>*/ i =
72                   query.getRefs( new Vector/*<Ref>*/() ).iterator();
73               i.hasNext(); ) {
74             Ref r = (Ref) i.next();
75             if ( r.get() == null )
76                 unbound.add( r );
77         }
78         tested = false;
79         query.reset();
80     }
81
82     /**
83      * Implements {@link Query#next} by calling on the wrapped query,
84      * then remove any bindings.
85      */
86     //@SuppressWarnings("unchecked")
87     public boolean next() throws Exception {
88         if ( tested )
89             return false;
90         tested = true;
91         boolean b = query.next();
92         for ( Iterator/*<Ref>*/ i = unbound.iterator(); i.hasNext(); ) {
93             Ref r = (Ref) i.next();
94             r.set( null );
95         }
96         return ! b;
97     }
98
99     /**
100      * Implements {@link Query#getRefs} by forwarding to the wrapped
101      * query.
102      */
103     public Vector/*<Ref>*/ getRefs(Vector/*<Ref>*/ v) {
104         return query.getRefs( v );
105     }
106
107     /**
108      * Implements {@link Query#addObserver} by forwarding to the
109      * wrapped query.
110      */
111     public void addObserver(Observer x) {
112         query.addObserver( x );
113     }
114
115     /**
116      * Implements {@link Query#deleteObserver} by forwarding to the
117      * wrapped query.
118      */
119     public void deleteObserver(Observer x) {
120         query.deleteObserver( x );
121     }
122
123     /**
124      * Implements {@link Query#addable} by calling {@link
125      * Query#removable} on the wrapped query.
126      */
127     public boolean addable() {
128         return query.removable();
129     }
130
131     /**
132      * Implements {@link Query#add} by calling {@link Query#remove} on
133      * the wrapped query.
134      */
135     public boolean add() {
136         return query.remove();
137     }
138
139     /**
140      * Implements {@link Query#removable} by calling {@link
141      * Query#addable} on the wrapped query.
142      */
143     public boolean removable() {
144         return query.addable();
145     }
146
147     /**
148      * Implements {@link Query#remove} by calling {@link Query#add} on
149      * the wrapped query.
150      */
151     public boolean remove() {
152         return query.add();
153     }
154
155     /**
156      * Returns the textual representation of the wrapped query, within
157      * parentheses.
158      */
159     public String toString() {
160         return "(" + query + ")";
161     }
162 }