001/** 002 * GRANITE DATA SERVICES 003 * Copyright (C) 2006-2013 GRANITE DATA SERVICES S.A.S. 004 * 005 * This file is part of the Granite Data Services Platform. 006 * 007 * Granite Data Services is free software; you can redistribute it and/or 008 * modify it under the terms of the GNU Lesser General Public 009 * License as published by the Free Software Foundation; either 010 * version 2.1 of the License, or (at your option) any later version. 011 * 012 * Granite Data Services is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser 015 * General Public License for more details. 016 * 017 * You should have received a copy of the GNU Lesser General Public 018 * License along with this library; if not, write to the Free Software 019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 020 * USA, or see <http://www.gnu.org/licenses/>. 021 */ 022package org.granite.messaging.amf.persistence; 023 024import java.io.IOException; 025import java.io.ObjectInput; 026import java.io.ObjectOutput; 027import java.util.Arrays; 028import java.util.Collection; 029import java.util.Comparator; 030import java.util.Iterator; 031import java.util.Map; 032import java.util.Map.Entry; 033import java.util.NoSuchElementException; 034import java.util.Set; 035 036import org.granite.messaging.persistence.PersistentCollectionSnapshot; 037 038/** 039 * @author Franck WOLFF 040 */ 041public class AMFPersistentCollectionSnapshot implements PersistentCollectionSnapshot { 042 043 private static final long serialVersionUID = 1L; 044 045 protected boolean initialized = false; 046 protected String detachedState = null; 047 protected boolean dirty = false; 048 protected Object[] elements = null; 049 050 public AMFPersistentCollectionSnapshot(String detachedState) { 051 this.detachedState = detachedState; 052 } 053 054 public AMFPersistentCollectionSnapshot(boolean sorted, String detachedState) { 055 this.detachedState = detachedState; 056 } 057 058 public AMFPersistentCollectionSnapshot(boolean initialized, String detachedState, boolean dirty, Collection<?> collection) { 059 this.initialized = initialized; 060 this.detachedState = detachedState; 061 if (initialized) { 062 this.dirty = dirty; 063 this.elements = collection.toArray(); 064 } 065 } 066 067 public AMFPersistentCollectionSnapshot(boolean initialized, String detachedState, boolean dirty, Map<?, ?> collection) { 068 this.initialized = initialized; 069 this.detachedState = detachedState; 070 if (initialized) { 071 this.dirty = dirty; 072 073 Object[] entries = collection.entrySet().toArray(); 074 this.elements = new Object[entries.length]; 075 076 int elementIndex = 0; 077 for (int entryIndex = 0; entryIndex < entries.length; entryIndex++) { 078 Map.Entry<?, ?> entry = (Map.Entry<?, ?>)entries[entryIndex]; 079 this.elements[elementIndex++] = new Object[] { entry.getKey(), entry.getValue() }; 080 } 081 } 082 } 083 084 public boolean isInitialized() { 085 return initialized; 086 } 087 088 public String getDetachedState() { 089 return detachedState; 090 } 091 092 public boolean isDirty() { 093 return dirty; 094 } 095 096 public boolean isSorted() { 097 return false; 098 } 099 100 public <T> Comparator<T> newComparator(ObjectInput in) { 101 return null; 102 } 103 104 @SuppressWarnings("unchecked") 105 public <T> Collection<T> getElementsAsCollection() { 106 return (Collection<T>)Arrays.asList(elements); 107 } 108 109 public <K, V> Map<K, V> getElementsAsMap() { 110 return new SnapshotMap<K, V>(elements); 111 } 112 113 public void writeExternal(ObjectOutput out) throws IOException { 114 out.writeObject(initialized); 115 out.writeObject(detachedState); 116 if (initialized) { 117 out.writeObject(dirty); 118 out.writeObject(elements); 119 } 120 } 121 122 public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { 123 readInitializationData(in); 124 if (initialized) 125 readCoreData(in); 126 } 127 128 public void readInitializationData(ObjectInput in) throws IOException, ClassNotFoundException { 129 initialized = ((Boolean)in.readObject()).booleanValue(); 130 detachedState = (String)in.readObject(); 131 } 132 133 public void readCoreData(ObjectInput in) throws IOException, ClassNotFoundException { 134 this.dirty = ((Boolean)in.readObject()).booleanValue(); 135 this.elements = (Object[])in.readObject(); 136 } 137 138 static class SnapshotMap<K, V> implements Map<K, V> { 139 140 private final Object[] elements; 141 142 public SnapshotMap(Object[] elements) { 143 this.elements = elements; 144 } 145 146 public int size() { 147 return elements.length; 148 } 149 150 public boolean isEmpty() { 151 return elements.length == 0; 152 } 153 154 public Set<Entry<K, V>> entrySet() { 155 return new Set<Entry<K, V>>() { 156 157 public int size() { 158 return elements.length; 159 } 160 161 public boolean isEmpty() { 162 return elements.length == 0; 163 } 164 165 public Iterator<Entry<K, V>> iterator() { 166 167 return new Iterator<Entry<K, V>>() { 168 169 private int cursor = 0; 170 171 public boolean hasNext() { 172 return cursor < elements.length; 173 } 174 175 @SuppressWarnings("unchecked") 176 public Entry<K, V> next() { 177 if (cursor >= elements.length) 178 throw new NoSuchElementException(); 179 180 Object[] element = (Object[])elements[cursor++]; 181 K key = (K)element[0]; 182 V value = (V)element[1]; 183 return new SnapshotMapEntry<K, V>(key, value); 184 } 185 186 public void remove() { 187 throw new UnsupportedOperationException(); 188 } 189 }; 190 } 191 192 public boolean contains(Object o) { 193 throw new UnsupportedOperationException(); 194 } 195 196 public Object[] toArray() { 197 throw new UnsupportedOperationException(); 198 } 199 200 public <T> T[] toArray(T[] a) { 201 throw new UnsupportedOperationException(); 202 } 203 204 public boolean add(Entry<K, V> e) { 205 throw new UnsupportedOperationException(); 206 } 207 208 public boolean remove(Object o) { 209 throw new UnsupportedOperationException(); 210 } 211 212 public boolean containsAll(Collection<?> c) { 213 throw new UnsupportedOperationException(); 214 } 215 216 public boolean addAll(Collection<? extends Entry<K, V>> c) { 217 throw new UnsupportedOperationException(); 218 } 219 220 public boolean retainAll(Collection<?> c) { 221 throw new UnsupportedOperationException(); 222 } 223 224 public boolean removeAll(Collection<?> c) { 225 throw new UnsupportedOperationException(); 226 } 227 228 public void clear() { 229 throw new UnsupportedOperationException(); 230 } 231 232 @Override 233 public int hashCode() { 234 throw new UnsupportedOperationException(); 235 } 236 237 @Override 238 public boolean equals(Object obj) { 239 throw new UnsupportedOperationException(); 240 } 241 }; 242 } 243 244 public boolean containsKey(Object key) { 245 throw new UnsupportedOperationException(); 246 } 247 248 public boolean containsValue(Object value) { 249 throw new UnsupportedOperationException(); 250 } 251 252 public V get(Object key) { 253 throw new UnsupportedOperationException(); 254 } 255 256 public V put(K key, V value) { 257 throw new UnsupportedOperationException(); 258 } 259 260 public V remove(Object key) { 261 throw new UnsupportedOperationException(); 262 } 263 264 public void putAll(Map<? extends K, ? extends V> m) { 265 throw new UnsupportedOperationException(); 266 } 267 268 public void clear() { 269 throw new UnsupportedOperationException(); 270 } 271 272 public Set<K> keySet() { 273 throw new UnsupportedOperationException(); 274 } 275 276 public Collection<V> values() { 277 throw new UnsupportedOperationException(); 278 } 279 280 @Override 281 public int hashCode() { 282 throw new UnsupportedOperationException(); 283 } 284 285 @Override 286 public boolean equals(Object obj) { 287 throw new UnsupportedOperationException(); 288 } 289 } 290 291 static class SnapshotMapEntry<K, V> implements Entry<K, V> { 292 293 private final K key; 294 private final V value; 295 296 public SnapshotMapEntry(K key, V value) { 297 this.key = key; 298 this.value = value; 299 } 300 301 public K getKey() { 302 return key; 303 } 304 305 public V getValue() { 306 return value; 307 } 308 309 public V setValue(V value) { 310 throw new UnsupportedOperationException(); 311 } 312 313 @Override 314 public int hashCode() { 315 return (key == null ? 0 : key.hashCode()) ^ (value == null ? 0 : value.hashCode()); 316 } 317 318 @Override 319 public boolean equals(Object obj) { 320 if (!(obj instanceof Entry)) 321 return false; 322 Entry<?, ?> e = (Entry<?, ?>)obj; 323 return ( 324 (key == null ? e.getKey() == null : key.equals(e.getKey())) && 325 (value == null ? e.getValue() == null : value.equals(e.getValue())) 326 ); 327 } 328 } 329}