1/*
2 * Copyright (C) 2012 The Guava Authors
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.google.common.collect.testing.google;
18
19import com.google.common.annotations.GwtCompatible;
20import com.google.common.collect.BiMap;
21import com.google.common.collect.testing.DerivedGenerator;
22import com.google.common.collect.testing.Helpers;
23import com.google.common.collect.testing.OneSizeTestContainerGenerator;
24import com.google.common.collect.testing.SampleElements;
25import com.google.common.collect.testing.TestMapGenerator;
26import com.google.common.collect.testing.TestSetGenerator;
27import com.google.common.collect.testing.TestSubjectGenerator;
28
29import java.util.ArrayList;
30import java.util.Collection;
31import java.util.List;
32import java.util.Map;
33import java.util.Map.Entry;
34import java.util.Set;
35
36/**
37 * Derived suite generators for Guava collection interfaces, split out of the suite builders so that
38 * they are available to GWT.
39 *
40 * @author Louis Wasserman
41 */
42@GwtCompatible
43public final class DerivedGoogleCollectionGenerators {
44  public static class MapGenerator<K, V> implements TestMapGenerator<K, V>, DerivedGenerator {
45
46    private final OneSizeTestContainerGenerator<BiMap<K, V>, Entry<K, V>> generator;
47
48    public MapGenerator(
49        OneSizeTestContainerGenerator<BiMap<K, V>, Entry<K, V>> oneSizeTestContainerGenerator) {
50      this.generator = oneSizeTestContainerGenerator;
51    }
52
53    @Override
54    public SampleElements<Map.Entry<K, V>> samples() {
55      return generator.samples();
56    }
57
58    @Override
59    public Map<K, V> create(Object... elements) {
60      return generator.create(elements);
61    }
62
63    @Override
64    public Map.Entry<K, V>[] createArray(int length) {
65      return generator.createArray(length);
66    }
67
68    @Override
69    public Iterable<Map.Entry<K, V>> order(List<Map.Entry<K, V>> insertionOrder) {
70      return generator.order(insertionOrder);
71    }
72
73    @SuppressWarnings("unchecked")
74    @Override
75    public K[] createKeyArray(int length) {
76      return (K[]) new Object[length];
77    }
78
79    @SuppressWarnings("unchecked")
80    @Override
81    public V[] createValueArray(int length) {
82      return (V[]) new Object[length];
83    }
84
85    public TestSubjectGenerator<?> getInnerGenerator() {
86      return generator;
87    }
88  }
89
90  public static class InverseBiMapGenerator<K, V>
91      implements TestBiMapGenerator<V, K>, DerivedGenerator {
92
93    private final OneSizeTestContainerGenerator<BiMap<K, V>, Entry<K, V>> generator;
94
95    public InverseBiMapGenerator(
96        OneSizeTestContainerGenerator<BiMap<K, V>, Entry<K, V>> oneSizeTestContainerGenerator) {
97      this.generator = oneSizeTestContainerGenerator;
98    }
99
100    @Override
101    public SampleElements<Map.Entry<V, K>> samples() {
102      SampleElements<Entry<K, V>> samples = generator.samples();
103      return new SampleElements<Map.Entry<V, K>>(reverse(samples.e0), reverse(samples.e1),
104          reverse(samples.e2), reverse(samples.e3), reverse(samples.e4));
105    }
106
107    private Map.Entry<V, K> reverse(Map.Entry<K, V> entry) {
108      return Helpers.mapEntry(entry.getValue(), entry.getKey());
109    }
110
111    @SuppressWarnings("unchecked")
112    @Override
113    public BiMap<V, K> create(Object... elements) {
114      Entry<?, ?>[] entries = new Entry<?, ?>[elements.length];
115      for (int i = 0; i < elements.length; i++) {
116        entries[i] = reverse((Entry<K, V>) elements[i]);
117      }
118      return generator.create((Object[]) entries).inverse();
119    }
120
121    @SuppressWarnings("unchecked")
122    @Override
123    public Map.Entry<V, K>[] createArray(int length) {
124      return new Entry[length];
125    }
126
127    @Override
128    public Iterable<Entry<V, K>> order(List<Entry<V, K>> insertionOrder) {
129      return insertionOrder;
130    }
131
132    @SuppressWarnings("unchecked")
133    @Override
134    public V[] createKeyArray(int length) {
135      return (V[]) new Object[length];
136    }
137
138    @SuppressWarnings("unchecked")
139    @Override
140    public K[] createValueArray(int length) {
141      return (K[]) new Object[length];
142    }
143
144    public TestSubjectGenerator<?> getInnerGenerator() {
145      return generator;
146    }
147  }
148
149  public static class BiMapValueSetGenerator<K, V>
150      implements TestSetGenerator<V>, DerivedGenerator {
151    private final OneSizeTestContainerGenerator<BiMap<K, V>, Map.Entry<K, V>>
152        mapGenerator;
153    private final SampleElements<V> samples;
154
155    public BiMapValueSetGenerator(
156        OneSizeTestContainerGenerator<BiMap<K, V>, Entry<K, V>> mapGenerator) {
157      this.mapGenerator = mapGenerator;
158      final SampleElements<Map.Entry<K, V>> mapSamples =
159          this.mapGenerator.samples();
160      this.samples = new SampleElements<V>(
161          mapSamples.e0.getValue(),
162          mapSamples.e1.getValue(),
163          mapSamples.e2.getValue(),
164          mapSamples.e3.getValue(),
165          mapSamples.e4.getValue());
166    }
167
168    @Override
169    public SampleElements<V> samples() {
170      return samples;
171    }
172
173    @Override
174    public Set<V> create(Object... elements) {
175      @SuppressWarnings("unchecked")
176      V[] valuesArray = (V[]) elements;
177
178      // Start with a suitably shaped collection of entries
179      Collection<Map.Entry<K, V>> originalEntries =
180          mapGenerator.getSampleElements(elements.length);
181
182      // Create a copy of that, with the desired value for each value
183      Collection<Map.Entry<K, V>> entries =
184          new ArrayList<Entry<K, V>>(elements.length);
185      int i = 0;
186      for (Map.Entry<K, V> entry : originalEntries) {
187        entries.add(Helpers.mapEntry(entry.getKey(), valuesArray[i++]));
188      }
189
190      return mapGenerator.create(entries.toArray()).values();
191    }
192
193    @Override
194    public V[] createArray(int length) {
195      final V[] vs = ((TestBiMapGenerator<K, V>) mapGenerator.getInnerGenerator())
196          .createValueArray(length);
197      return vs;
198    }
199
200    @Override
201    public Iterable<V> order(List<V> insertionOrder) {
202      return insertionOrder;
203    }
204
205    public TestSubjectGenerator<?> getInnerGenerator() {
206      return mapGenerator;
207    }
208  }
209
210  private DerivedGoogleCollectionGenerators() {}
211}
212