capture
[rrq/gorite.git] / com / intendico / data / Or.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.Observer;
23 import java.util.Vector;
24
25 /**
26  * The Or class implements a disjunction of multiple queries.
27  */
28 public class Or implements Query {
29
30     /**
31      * Holds the disjuncts being combined.
32      */
33     public Query [] disjuncts;
34
35     /**
36      * Keeps track of which query is current.
37      */
38     public int current;
39
40     /**
41      * Constructor.
42      */
43     public Or(Query/*...*/ [] q)
44         throws Exception {
45         disjuncts = q;
46         reset();
47     }
48
49     /**
50      * The {@link Query#copy} method implemented by creating a new
51      * Or object with copies of the disjuncts.
52      */
53     public Query copy(Vector/*<Ref>*/ newrefs) throws Exception {
54         Query [] q = new Query [ disjuncts.length ];
55         for ( int i = 0; i < q.length; i++ ) {
56             q[i] = disjuncts[i].copy( newrefs );
57         }
58         return new Or( q );
59     }
60
61     /**
62      * The {@link Query#reset} method implemented by reverting to the
63      * first disjunct and resetting it.
64      */
65     public void reset()
66         throws Exception
67     {
68         current = 0;
69         disjuncts[ 0 ].reset();
70     }
71
72     /**
73      * The {@link Query#next} method implemented by considering all
74      * disjucts one by one to the next match in a left-to-right fashion.
75      */
76     public boolean next()
77         throws Exception
78     {
79         while ( current < disjuncts.length ) {
80             if ( disjuncts[ current ].next() )
81                 return true;
82             current += 1;
83             if ( current >= disjuncts.length )
84                 break;
85             disjuncts[ current ].reset();
86         }
87         return false;
88     }
89
90     /**
91      * The {@link Query#getRefs} method implemented by combining the
92      * Ref objects of all disjuncts.
93      */
94     public Vector/*<Ref>*/ getRefs(Vector/*<Ref>*/ v) {
95         for ( int i=0; i < disjuncts.length; i++ )
96             disjuncts[ i ].getRefs( v );
97         return v;
98     }
99
100     /**
101      * The {@link Query#addObserver} method implemented by adding
102      * the observer to all the disjuncts.
103      */
104     public void addObserver(Observer x) {
105         for ( int i=0; i < disjuncts.length; i++ )
106             disjuncts[ i ].addObserver( x );
107     }
108
109     /**
110      * The {@link Query#deleteObserver} method implemented by
111      * removing the observer from all the disjuncts.
112      */
113     public void deleteObserver(Observer x) {
114         for ( int i=0; i < disjuncts.length; i++ )
115             disjuncts[ i ].deleteObserver( x );
116     }
117
118     /**
119      * The {@link Query#addable} method implemented by forwarding to all
120      * disjuncts.
121      */
122     public boolean addable()
123     {
124         for ( int i=0; i < disjuncts.length; i++ )
125             if ( disjuncts[ i ].addable() )
126                 return true;
127         return false;
128     }
129
130     /**
131      * The {@link Query#add} method implemented by forwarding to first
132      * addable disjunct.
133      */
134     public boolean add()
135     {
136         for ( int i=0; i < disjuncts.length; i++ ) {
137             if ( disjuncts[ i ].addable() )
138                 return disjuncts[ i ].add();
139         }
140         return false;
141     }
142
143     /**
144      * Implements {@link Query#removable} by checking that all
145      * disjuncts are removable.
146      */
147     public boolean removable()
148     {
149         for ( int i=0; i < disjuncts.length; i++ )
150             if ( ! disjuncts[ i ].removable() )
151                 return false;
152         return true;
153     }
154
155     /**
156      * Implements {@link Query#remove} by forwarding to all disjuncts.
157      */
158     public boolean remove() {
159         boolean removed = false;
160         for ( int i=0; i < disjuncts.length; i++ )
161             if ( disjuncts[ i ].removable() )
162                 removed |= disjuncts[ i ].remove();
163         return removed;
164     }
165
166     /**
167      * Returns a {@link String} representation of the Or object.
168      */
169     public String toString() {
170         StringBuffer s = new StringBuffer();
171         s.append( "Or(" );
172         for ( int i=0; i < disjuncts.length; i++ ) {
173             if ( i > 0 )
174                 s.append( "," );
175             s.append( " " );
176             s.append( disjuncts[ i ].toString() );
177         }
178         s.append( " )" );
179         return s.toString();
180     }
181 }