001 /*
002 GRANITE DATA SERVICES
003 Copyright (C) 2013 GRANITE DATA SERVICES S.A.S.
004
005 This file is part of Granite Data Services.
006
007 Granite Data Services is free software; you can redistribute it and/or modify
008 it under the terms of the GNU Library General Public License as published by
009 the Free Software Foundation; either version 2 of the License, or (at your
010 option) any later version.
011
012 Granite Data Services is distributed in the hope that it will be useful, but
013 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
014 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License
015 for more details.
016
017 You should have received a copy of the GNU Library General Public License
018 along with this library; if not, see <http://www.gnu.org/licenses/>.
019 */
020
021 package org.granite.client.persistence.collection;
022
023 import java.io.ObjectInput;
024 import java.util.Comparator;
025 import java.util.Map;
026 import java.util.SortedMap;
027 import java.util.TreeMap;
028
029 import org.granite.messaging.persistence.PersistentCollectionSnapshot;
030 import org.granite.messaging.persistence.PersistentCollectionSnapshotFactory;
031
032 /**
033 * @author Franck WOLFF
034 */
035 public class PersistentSortedMap<K, V> extends AbstractPersistentMapCollection<K, V, SortedMap<K, V>> implements SortedMap<K, V>, PersistentSortedCollection<K> {
036
037 public PersistentSortedMap() {
038 }
039
040 public PersistentSortedMap(SortedMap<K, V> collection) {
041 this(collection, true);
042 }
043
044 public PersistentSortedMap(SortedMap<K, V> collection, boolean clone) {
045 if (collection != null)
046 init(clone ? new TreeMap<K, V>(collection) : collection, false);
047 }
048
049 public Comparator<? super K> comparator() {
050 checkInitialized();
051 return getCollection().comparator();
052 }
053
054 public SortedMap<K, V> subMap(K fromKey, K toKey) {
055 checkInitialized();
056 return new SortedMapProxy<K, V>(this, getCollection().subMap(fromKey, toKey));
057 }
058
059 public SortedMap<K, V> headMap(K toKey) {
060 checkInitialized();
061 return new SortedMapProxy<K, V>(this, getCollection().headMap(toKey));
062 }
063
064 public SortedMap<K, V> tailMap(K fromKey) {
065 checkInitialized();
066 return new SortedMapProxy<K, V>(this, getCollection().tailMap(fromKey));
067 }
068
069 public K firstKey() {
070 checkInitialized();
071 return getCollection().firstKey();
072 }
073
074 public K lastKey() {
075 checkInitialized();
076 return getCollection().lastKey();
077 }
078
079 @Override
080 protected PersistentCollectionSnapshot createSnapshot(boolean forReading) {
081 PersistentCollectionSnapshotFactory factory = PersistentCollectionSnapshotFactory.newInstance();
082 if (forReading || !wasInitialized())
083 return factory.newPersistentCollectionSnapshot(true);
084 return factory.newPersistentCollectionSnapshot(true, isDirty(), this);
085 }
086
087 @SuppressWarnings("unchecked")
088 @Override
089 protected void updateFromSnapshot(ObjectInput in, PersistentCollectionSnapshot snapshot) {
090 if (snapshot.isInitialized()) {
091 Comparator<? super K> comparator = null;
092 try {
093 comparator = snapshot.newComparator(in);
094 }
095 catch (Exception e) {
096 throw new RuntimeException("Could not create instance of comparator", e);
097 }
098 SortedMap<K, V> map = new TreeMap<K, V>(comparator);
099 map.putAll((Map<K, V>)snapshot.getElementsAsMap());
100 init(map, snapshot.isDirty());
101 }
102 else
103 init(null, false);
104 }
105 }