capture
[rrq/gorite.git] / com / intendico / data / Distinct.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.HashSet;
24
25 /**
26  * The Distinct class is a query to ensure that a collection of given
27  * {@link Ref} objects have distinct bindings.
28  */
29 public class Distinct extends Condition {
30
31     /**
32      * The Ref objects concerned.
33      */
34     public Object [] refs;
35
36     /**
37      * Constructor;
38      */
39     public Distinct(Object/*...*/ [] r) {
40         refs = r;
41     }
42
43     /**
44      * The {@link Query#copy} method implemented by creating a new
45      * Distinct object with the copies of the refs.
46      */
47     //@SuppressWarnings("unchecked")
48     public Query copy(Vector/*<Ref>*/ newrefs) throws Exception {
49         Object [] nrefs = new Object [ refs.length ];
50         for ( int i = 0; i < refs.length; i++ ) {
51             if ( refs[ i ] instanceof Ref ) {
52                 nrefs[ i ] = ((Ref) refs[ i ]).find( newrefs );
53             } else {
54                 nrefs[ i ] = refs[ i ];
55             }
56         }
57         return new Distinct( nrefs );
58     }
59
60     /**
61      * The distinction condition
62      * @return <em>false</em> if any {@link Ref} object is
63      * <em>null</em>, or equal to any other {@link Ref} object,
64      * otherwise <em>true</em>.
65      */
66     public boolean condition() {
67         HashSet/*<Object>*/ v = new HashSet/*<Object>*/();
68         for ( int i = 0; i < refs.length; i++ ) {
69             Object r = refs[ i ];
70             Object x = Ref.deref( r );
71             if ( x == null || v.contains( x ) )
72                 return false;
73             v.add( x );
74         }
75         return true;
76     }
77
78     /**
79      * The {@link Query#getRefs} method implemented by adding any Ref
80      * object not already in the vector.
81      */
82     public Vector/*<Ref>*/ getRefs(Vector/*<Ref>*/ v) {
83         for ( int i = 0; i < refs.length; i++ ) {
84             Object r = refs[ i ];
85             if ( r instanceof Ref ) {
86                 if ( ! v.contains( (Ref) r ) )
87                     v.add( (Ref) r );
88             }
89         }
90         return v;
91     }
92
93     /**
94      * Returns the textual representation of the query.
95      */
96     public String toString() {
97         return "Distinct(" + Ref.toString( refs ) + ")";
98     }
99 }