001/*
002 * Copyright (C) 2012 The Guava Authors
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package com.google.common.collect.testing.google;
018
019import com.google.common.annotations.GwtCompatible;
020import com.google.common.collect.BiMap;
021import com.google.common.collect.testing.DerivedGenerator;
022import com.google.common.collect.testing.Helpers;
023import com.google.common.collect.testing.OneSizeTestContainerGenerator;
024import com.google.common.collect.testing.SampleElements;
025import com.google.common.collect.testing.TestMapGenerator;
026import com.google.common.collect.testing.TestSetGenerator;
027import com.google.common.collect.testing.TestSubjectGenerator;
028import java.util.ArrayList;
029import java.util.Collection;
030import java.util.List;
031import java.util.Map;
032import java.util.Map.Entry;
033import java.util.Set;
034
035/**
036 * Derived suite generators for Guava collection interfaces, split out of the suite builders so that
037 * they are available to GWT.
038 *
039 * @author Louis Wasserman
040 */
041@GwtCompatible
042public final class DerivedGoogleCollectionGenerators {
043  public static class MapGenerator<K, V> implements TestMapGenerator<K, V>, DerivedGenerator {
044
045    private final OneSizeTestContainerGenerator<BiMap<K, V>, Entry<K, V>> generator;
046
047    public MapGenerator(
048        OneSizeTestContainerGenerator<BiMap<K, V>, Entry<K, V>> oneSizeTestContainerGenerator) {
049      this.generator = oneSizeTestContainerGenerator;
050    }
051
052    @Override
053    public SampleElements<Entry<K, V>> samples() {
054      return generator.samples();
055    }
056
057    @Override
058    public Map<K, V> create(Object... elements) {
059      return generator.create(elements);
060    }
061
062    @Override
063    public Entry<K, V>[] createArray(int length) {
064      return generator.createArray(length);
065    }
066
067    @Override
068    public Iterable<Entry<K, V>> order(List<Entry<K, V>> insertionOrder) {
069      return generator.order(insertionOrder);
070    }
071
072    @SuppressWarnings("unchecked")
073    @Override
074    public K[] createKeyArray(int length) {
075      return (K[]) new Object[length];
076    }
077
078    @SuppressWarnings("unchecked")
079    @Override
080    public V[] createValueArray(int length) {
081      return (V[]) new Object[length];
082    }
083
084    @Override
085    public TestSubjectGenerator<?> getInnerGenerator() {
086      return generator;
087    }
088  }
089
090  public static class InverseBiMapGenerator<K, V>
091      implements TestBiMapGenerator<V, K>, DerivedGenerator {
092
093    private final OneSizeTestContainerGenerator<BiMap<K, V>, Entry<K, V>> generator;
094
095    public InverseBiMapGenerator(
096        OneSizeTestContainerGenerator<BiMap<K, V>, Entry<K, V>> oneSizeTestContainerGenerator) {
097      this.generator = oneSizeTestContainerGenerator;
098    }
099
100    @Override
101    public SampleElements<Entry<V, K>> samples() {
102      SampleElements<Entry<K, V>> samples = generator.samples();
103      return new SampleElements<>(
104          reverse(samples.e0()),
105          reverse(samples.e1()),
106          reverse(samples.e2()),
107          reverse(samples.e3()),
108          reverse(samples.e4()));
109    }
110
111    private Entry<V, K> reverse(Entry<K, V> entry) {
112      return Helpers.mapEntry(entry.getValue(), entry.getKey());
113    }
114
115    @SuppressWarnings("unchecked")
116    @Override
117    public BiMap<V, K> create(Object... elements) {
118      Entry<?, ?>[] entries = new Entry<?, ?>[elements.length];
119      for (int i = 0; i < elements.length; i++) {
120        entries[i] = reverse((Entry<K, V>) elements[i]);
121      }
122      return generator.create((Object[]) entries).inverse();
123    }
124
125    @SuppressWarnings("unchecked")
126    @Override
127    public Entry<V, K>[] createArray(int length) {
128      return new Entry[length];
129    }
130
131    @Override
132    public Iterable<Entry<V, K>> order(List<Entry<V, K>> insertionOrder) {
133      return insertionOrder;
134    }
135
136    @SuppressWarnings("unchecked")
137    @Override
138    public V[] createKeyArray(int length) {
139      return (V[]) new Object[length];
140    }
141
142    @SuppressWarnings("unchecked")
143    @Override
144    public K[] createValueArray(int length) {
145      return (K[]) new Object[length];
146    }
147
148    @Override
149    public TestSubjectGenerator<?> getInnerGenerator() {
150      return generator;
151    }
152  }
153
154  public static class BiMapValueSetGenerator<K, V>
155      implements TestSetGenerator<V>, DerivedGenerator {
156    private final OneSizeTestContainerGenerator<BiMap<K, V>, Entry<K, V>> mapGenerator;
157    private final SampleElements<V> samples;
158
159    public BiMapValueSetGenerator(
160        OneSizeTestContainerGenerator<BiMap<K, V>, Entry<K, V>> mapGenerator) {
161      this.mapGenerator = mapGenerator;
162      final SampleElements<Entry<K, V>> mapSamples = this.mapGenerator.samples();
163      this.samples =
164          new SampleElements<V>(
165              mapSamples.e0().getValue(),
166              mapSamples.e1().getValue(),
167              mapSamples.e2().getValue(),
168              mapSamples.e3().getValue(),
169              mapSamples.e4().getValue());
170    }
171
172    @Override
173    public SampleElements<V> samples() {
174      return samples;
175    }
176
177    @Override
178    public Set<V> create(Object... elements) {
179      @SuppressWarnings("unchecked")
180      V[] valuesArray = (V[]) elements;
181
182      // Start with a suitably shaped collection of entries
183      Collection<Entry<K, V>> originalEntries = mapGenerator.getSampleElements(elements.length);
184
185      // Create a copy of that, with the desired value for each value
186      Collection<Entry<K, V>> entries = new ArrayList<>(elements.length);
187      int i = 0;
188      for (Entry<K, V> entry : originalEntries) {
189        entries.add(Helpers.mapEntry(entry.getKey(), valuesArray[i++]));
190      }
191
192      return mapGenerator.create(entries.toArray()).values();
193    }
194
195    @Override
196    public V[] createArray(int length) {
197      final V[] vs =
198          ((TestBiMapGenerator<K, V>) mapGenerator.getInnerGenerator()).createValueArray(length);
199      return vs;
200    }
201
202    @Override
203    public Iterable<V> order(List<V> insertionOrder) {
204      return insertionOrder;
205    }
206
207    @Override
208    public TestSubjectGenerator<?> getInnerGenerator() {
209      return mapGenerator;
210    }
211  }
212
213  private DerivedGoogleCollectionGenerators() {}
214}