1/*
2 * Copyright (C) 2009 Google Inc.
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;
18
19import static com.google.common.base.Preconditions.checkNotNull;
20
21import com.google.common.annotations.GwtCompatible;
22import com.google.common.base.Objects;
23
24import java.util.Map;
25
26import javax.annotation.Nullable;
27
28/**
29 * An implementation of {@link ImmutableTable} that holds a single cell.
30 *
31 * @author gak@google.com (Gregory Kick)
32 */
33@GwtCompatible
34final class SingletonImmutableTable<R, C, V> extends ImmutableTable<R, C, V> {
35  private final R singleRowKey;
36  private final C singleColumnKey;
37  private final V singleValue;
38
39  SingletonImmutableTable(R rowKey, C columnKey, V value) {
40    this.singleRowKey = checkNotNull(rowKey);
41    this.singleColumnKey = checkNotNull(columnKey);
42    this.singleValue = checkNotNull(value);
43  }
44
45  SingletonImmutableTable(Cell<R, C, V> cell) {
46    this(cell.getRowKey(), cell.getColumnKey(), cell.getValue());
47  }
48
49  @Override public ImmutableSet<Cell<R, C, V>> cellSet() {
50    return ImmutableSet.of(
51        Tables.immutableCell(singleRowKey, singleColumnKey, singleValue));
52  }
53
54  @Override public ImmutableMap<R, V> column(C columnKey) {
55    checkNotNull(columnKey);
56    return containsColumn(columnKey)
57        ? ImmutableMap.of(singleRowKey, singleValue)
58        : ImmutableMap.<R, V>of();
59  }
60
61  @Override public ImmutableSet<C> columnKeySet() {
62    return ImmutableSet.of(singleColumnKey);
63  }
64
65  @Override public ImmutableMap<C, Map<R, V>> columnMap() {
66    return ImmutableMap.of(singleColumnKey,
67        (Map<R, V>) ImmutableMap.of(singleRowKey, singleValue));
68  }
69
70  @Override public boolean contains(@Nullable Object rowKey,
71      @Nullable Object columnKey) {
72    return containsRow(rowKey) && containsColumn(columnKey);
73  }
74
75  @Override public boolean containsColumn(@Nullable Object columnKey) {
76    return Objects.equal(this.singleColumnKey, columnKey);
77  }
78
79  @Override public boolean containsRow(@Nullable Object rowKey) {
80    return Objects.equal(this.singleRowKey, rowKey);
81  }
82
83  @Override public boolean containsValue(@Nullable Object value) {
84    return Objects.equal(this.singleValue, value);
85  }
86
87  @Override public V get(@Nullable Object rowKey, @Nullable Object columnKey) {
88    return contains(rowKey, columnKey) ? singleValue : null;
89  }
90
91  @Override public boolean isEmpty() {
92    return false;
93  }
94
95  @Override public ImmutableMap<C, V> row(R rowKey) {
96    checkNotNull(rowKey);
97    return containsRow(rowKey)
98        ? ImmutableMap.of(singleColumnKey, singleValue)
99        : ImmutableMap.<C, V>of();
100  }
101
102  @Override public ImmutableSet<R> rowKeySet() {
103    return ImmutableSet.of(singleRowKey);
104  }
105
106  @Override public ImmutableMap<R, Map<C, V>> rowMap() {
107    return ImmutableMap.of(singleRowKey,
108        (Map<C, V>) ImmutableMap.of(singleColumnKey, singleValue));
109  }
110
111  @Override public int size() {
112    return 1;
113  }
114
115  @Override public ImmutableCollection<V> values() {
116    return ImmutableSet.of(singleValue);
117  }
118
119  @Override public boolean equals(@Nullable Object obj) {
120    if (obj == this) {
121      return true;
122    } else if (obj instanceof Table<?, ?, ?>) {
123      Table<?, ?, ?> that = (Table<?, ?, ?>) obj;
124      if (that.size() == 1) {
125        Cell<?, ?, ?> thatCell = that.cellSet().iterator().next();
126        return Objects.equal(this.singleRowKey, thatCell.getRowKey()) &&
127            Objects.equal(this.singleColumnKey, thatCell.getColumnKey()) &&
128            Objects.equal(this.singleValue, thatCell.getValue());
129      }
130    }
131    return false;
132  }
133
134  @Override public int hashCode() {
135    return Objects.hashCode(singleRowKey, singleColumnKey, singleValue);
136  }
137
138  @Override public String toString() {
139    return new StringBuilder()
140        .append('{')
141        .append(singleRowKey)
142        .append("={")
143        .append(singleColumnKey)
144        .append('=')
145        .append(singleValue)
146        .append("}}")
147        .toString();
148  }
149}
150