• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
3  * Copyright (C) 2011, 2013-2016 The JavaParser Team.
4  *
5  * This file is part of JavaParser.
6  *
7  * JavaParser can be used either under the terms of
8  * a) the GNU Lesser General Public License as published by
9  *     the Free Software Foundation, either version 3 of the License, or
10  *     (at your option) any later version.
11  * b) the terms of the Apache License
12  *
13  * You should have received a copy of both licenses in LICENCE.LGPL and
14  * LICENCE.APACHE. Please refer to those files for details.
15  *
16  * JavaParser is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU Lesser General Public License for more details.
20  */
21 
22 package com.github.javaparser.utils;
23 
24 import java.util.Collection;
25 import java.util.HashSet;
26 import java.util.Iterator;
27 import java.util.Set;
28 import java.util.stream.Collectors;
29 
30 import com.github.javaparser.ast.Node;
31 import com.github.javaparser.ast.visitor.GenericVisitor;
32 import com.github.javaparser.ast.visitor.Visitable;
33 import com.github.javaparser.ast.visitor.VoidVisitor;
34 
35 /**
36  * A set that overrides the equals and hashcode calculation of the added nodes
37  * by using another equals and hashcode visitor for those methods.
38  */
39 public class VisitorSet<N extends Node> implements Set<N> {
40 
41     private final Set<EqualsHashcodeOverridingFacade> innerSet = new HashSet<>();
42     private final GenericVisitor<Integer, Void> hashcodeVisitor;
43     private final GenericVisitor<Boolean, Visitable> equalsVisitor;
44 
45     /**
46      * Pass the visitors to use for equals and hashcode.
47      */
VisitorSet(GenericVisitor<Integer, Void> hashcodeVisitor, GenericVisitor<Boolean, Visitable> equalsVisitor)48     public VisitorSet(GenericVisitor<Integer, Void> hashcodeVisitor, GenericVisitor<Boolean, Visitable> equalsVisitor) {
49         this.hashcodeVisitor = hashcodeVisitor;
50         this.equalsVisitor = equalsVisitor;
51     }
52 
53     @Override
add(N elem)54     public boolean add(N elem) {
55         return innerSet.add(new EqualsHashcodeOverridingFacade(elem));
56     }
57 
58     @Override
addAll(Collection<? extends N> col)59     public boolean addAll(Collection<? extends N> col) {
60         boolean modified = false;
61         for (N elem : col)
62             if (add(elem))
63                 modified = true;
64         return modified;
65     }
66 
67     @Override
clear()68     public void clear() {
69         innerSet.clear();
70     }
71 
72     @Override
contains(Object elem)73     public boolean contains(Object elem) {
74         return innerSet.contains(new EqualsHashcodeOverridingFacade((N) elem));
75     }
76 
77     @Override
containsAll(Collection<?> col)78     public boolean containsAll(Collection<?> col) {
79         for (Object elem : col)
80             if (!contains(elem))
81                 return false;
82         return true;
83     }
84 
85     @Override
isEmpty()86     public boolean isEmpty() {
87         return innerSet.isEmpty();
88     }
89 
90     @Override
iterator()91     public Iterator<N> iterator() {
92         return new Iterator<N>() {
93             final Iterator<EqualsHashcodeOverridingFacade> itr = innerSet.iterator();
94 
95             @Override
96             public boolean hasNext() {
97                 return itr.hasNext();
98             }
99 
100             @Override
101             public N next() {
102                 return itr.next().overridden;
103             }
104 
105             @Override
106             public void remove() {
107                 itr.remove();
108             }
109         };
110     }
111 
112     @Override
remove(Object elem)113     public boolean remove(Object elem) {
114         return innerSet.remove(new EqualsHashcodeOverridingFacade((N) elem));
115     }
116 
117     @Override
removeAll(Collection<?> col)118     public boolean removeAll(Collection<?> col) {
119         boolean modified = false;
120         for (Object elem : col)
121             if (remove(elem))
122                 modified = true;
123         return modified;
124     }
125 
126     @Override
retainAll(Collection<?> col)127     public boolean retainAll(Collection<?> col) {
128         int oldSize = size();
129         clear();
130         addAll((Collection<? extends N>) col);
131         return size() != oldSize;
132     }
133 
134     @Override
size()135     public int size() {
136         return innerSet.size();
137     }
138 
139     @Override
toArray()140     public Object[] toArray() {
141         return innerSet.stream().map(facade -> facade.overridden).collect(Collectors.toList()).toArray();
142     }
143 
144     @Override
toArray(T[] arr)145     public <T> T[] toArray(T[] arr) {
146         return innerSet.stream().map(facade -> facade.overridden).collect(Collectors.toList()).toArray(arr);
147     }
148 
149     @Override
toString()150     public String toString() {
151         StringBuilder sb = new StringBuilder("[");
152         if (size() == 0)
153             return sb.append("]").toString();
154         for (EqualsHashcodeOverridingFacade facade : innerSet) {
155             sb.append(facade.overridden.toString() + ",");
156         }
157         return sb.replace(sb.length() - 2, sb.length(), "]").toString();
158     }
159 
160     private class EqualsHashcodeOverridingFacade implements Visitable {
161         private final N overridden;
162 
EqualsHashcodeOverridingFacade(N overridden)163         EqualsHashcodeOverridingFacade(N overridden) {
164             this.overridden = overridden;
165         }
166 
167         @Override
accept(GenericVisitor<R, A> v, A arg)168         public <R, A> R accept(GenericVisitor<R, A> v, A arg) {
169             throw new AssertionError();
170         }
171 
172         @Override
accept(VoidVisitor<A> v, A arg)173         public <A> void accept(VoidVisitor<A> v, A arg) {
174             throw new AssertionError();
175         }
176 
177         @Override
hashCode()178         public final int hashCode() {
179             return overridden.accept(hashcodeVisitor, null);
180         }
181 
182         @Override
equals(final Object obj)183         public boolean equals(final Object obj) {
184             if (obj == null || !(obj instanceof VisitorSet.EqualsHashcodeOverridingFacade)) {
185                 return false;
186             }
187             return overridden.accept(equalsVisitor, ((EqualsHashcodeOverridingFacade) obj).overridden);
188         }
189     }
190 
191 }
192