001: /*
002: * Copyright 2007 Google Inc.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License"); you may not
005: * use this file except in compliance with the License. You may obtain a copy of
006: * 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, WITHOUT
012: * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
013: * License for the specific language governing permissions and limitations under
014: * the License.
015: */
016: package com.google.gwt.i18n.client.impl;
017:
018: import java.util.ArrayList;
019: import java.util.Collection;
020: import java.util.HashMap;
021: import java.util.Iterator;
022: import java.util.Map;
023: import java.util.Set;
024:
025: /**
026: * Read only Map used when returning <code>Constants</code> maps. Preserves
027: * order. ConstantMap should only be created or modified by GWT, as constant
028: * maps are constructed using a very stereotyped algorithm, which allows
029: * <code>ConstantMap</code> to maintain order with very little code. In
030: * specific, no elements are every removed from them and all elements are added
031: * before the first user operation.
032: */
033: public class ConstantMap extends HashMap<String, String> {
034:
035: private static class DummyMapEntry implements
036: Map.Entry<String, String> {
037: private final String key;
038:
039: private final String value;
040:
041: DummyMapEntry(String key, String value) {
042: this .key = key;
043: this .value = value;
044: }
045:
046: public String getKey() {
047: return key;
048: }
049:
050: public String getValue() {
051: return value;
052: }
053:
054: public String setValue(String arg0) {
055: throw new UnsupportedOperationException();
056: }
057: }
058:
059: private class OrderedConstantSet<T> extends ArrayList<T> implements
060: Set<T> {
061: private class ImmutableIterator implements Iterator<T> {
062: private final Iterator<T> base;
063:
064: ImmutableIterator(Iterator<T> base) {
065: this .base = base;
066: }
067:
068: public boolean hasNext() {
069: return base.hasNext();
070: }
071:
072: public T next() {
073: return base.next();
074: }
075:
076: public void remove() {
077: throw new UnsupportedOperationException("Immutable set");
078: }
079: }
080:
081: @Override
082: public void clear() {
083: throw new UnsupportedOperationException("Immutable set");
084: }
085:
086: @Override
087: public Iterator<T> iterator() {
088: Iterator<T> base = super .iterator();
089: return new ImmutableIterator(base);
090: }
091: }
092:
093: private OrderedConstantSet<Map.Entry<String, String>> entries;
094:
095: private final OrderedConstantSet<String> keys = new OrderedConstantSet<String>();
096:
097: private OrderedConstantSet<String> values;
098:
099: @Override
100: public void clear() {
101: throw unsupported("clear");
102: }
103:
104: @Override
105: public Set<Map.Entry<String, String>> entrySet() {
106: if (entries == null) {
107: entries = new OrderedConstantSet<Map.Entry<String, String>>();
108: for (int i = 0; i < keys.size(); i++) {
109: String key = keys.get(i);
110: String value = get(key);
111: entries.add(new DummyMapEntry(key, value));
112: }
113: }
114: return entries;
115: }
116:
117: @Override
118: public Set<String> keySet() {
119: return keys;
120: }
121:
122: @Override
123: public String put(String key, String value) {
124: // We may want to find a more efficient implementation later.
125: boolean exists = keys.contains(key);
126: if (!exists) {
127: keys.add(key);
128: }
129: return super .put(key, value);
130: }
131:
132: @Override
133: public String remove(Object key) {
134: throw unsupported("remove");
135: }
136:
137: @Override
138: public Collection<String> values() {
139: if (values == null) {
140: values = new OrderedConstantSet<String>();
141: for (int i = 0; i < keys.size(); i++) {
142: Object element = keys.get(i);
143: values.add(this .get(element));
144: }
145: }
146: return values;
147: }
148:
149: private UnsupportedOperationException unsupported(String operation) {
150: return new UnsupportedOperationException(operation
151: + " not supported on a constant map");
152: }
153: }
|