001/**
002 *
003 * Copyright (c) 2014, the Railo Company Ltd. All rights reserved.
004 *
005 * This library is free software; you can redistribute it and/or
006 * modify it under the terms of the GNU Lesser General Public
007 * License as published by the Free Software Foundation; either 
008 * version 2.1 of the License, or (at your option) any later version.
009 * 
010 * This library is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
013 * Lesser General Public License for more details.
014 * 
015 * You should have received a copy of the GNU Lesser General Public 
016 * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
017 * 
018 **/
019package lucee.commons.collection;
020
021import java.io.IOException;
022import java.io.ObjectOutputStream;
023import java.io.Serializable;
024import java.util.Collection;
025import java.util.Map;
026import java.util.Set;
027
028import lucee.runtime.exp.PageException;
029import lucee.runtime.type.util.StructUtil;
030
031
032public class SyncMap<K,V>
033        implements MapPro<K,V>, Serializable {
034        private static final long serialVersionUID = 1978198479659022715L;
035
036        private final MapPro<K,V> m;     // Backing Map
037        final Serializable      mutex;        // Object on which to synchronize
038
039        public SyncMap() {
040            this(null);
041        }
042        
043        public SyncMap(MapPro<K,V> m) {
044            if (m==null) this.m = new HashMapPro<K, V>();
045            else this.m = m;
046            mutex = this;
047        }
048
049        SyncMap(MapPro<K,V> m, Serializable mutex) {
050            this.m = m;
051            this.mutex = mutex;
052        }
053        
054
055        public int size() {
056            synchronized (mutex) {return m.size();}
057        }
058        public boolean isEmpty() {
059            synchronized (mutex) {return m.isEmpty();}
060        }
061        public boolean containsKey(Object key) {
062            synchronized (mutex) {return m.containsKey(key);}
063        }
064        public boolean containsValue(Object value) {
065            synchronized (mutex) {return m.containsValue(value);}
066        }
067        public V get(Object key) {
068            synchronized (mutex) {return m.get(key);}
069        }
070
071
072                @Override
073                public V g(K key) throws PageException {
074                        synchronized (mutex) {return m.g(key);}
075                }
076
077                @Override
078                public V g(K key, V defaultValue) {
079                        synchronized (mutex) {return m.g(key,defaultValue);}
080                }
081
082                @Override
083                public V r(K key) throws PageException {
084                        synchronized (mutex) {return m.r(key);}
085                }
086
087                @Override
088                public V r(K key, V defaultValue) {
089                        synchronized (mutex) {return m.r(key,defaultValue);}
090                }
091        
092        
093
094        public V put(K key, V value) {
095            synchronized (mutex) {return m.put(key, value);}
096        }
097        public V remove(Object key) {
098            synchronized (mutex) {return m.remove(key);}
099        }
100        
101        public void putAll(Map<? extends K, ? extends V> map) {
102            synchronized (mutex) {m.putAll(map);}
103        }
104        public void clear() {
105            synchronized (mutex) {m.clear();}
106        }
107
108        private transient Set<K> keySet = null;
109        private transient Set<MapPro.Entry<K,V>> entrySet = null;
110        private transient Collection<V> values = null;
111
112        public Set<K> keySet() {
113            synchronized (mutex) {
114                if (keySet==null)
115                    keySet = new SyncSet<K>(m.keySet(), mutex);
116                return keySet;
117            }
118        }
119
120        public Set<Map.Entry<K,V>> entrySet() {
121            synchronized (mutex) {
122                if (entrySet==null)
123                    entrySet = new SyncSet<Map.Entry<K,V>>(m.entrySet(), mutex);
124                return entrySet;
125            }
126        }
127
128        public Collection<V> values() {
129            synchronized (mutex) {
130                if (values==null)
131                    values = new SyncCollection<V>(m.values(), mutex);
132                return values;
133            }
134        }
135
136        public boolean equals(Object o) {
137            if (this == o)
138                return true;
139            synchronized (mutex) {return m.equals(o);}
140        }
141        public int hashCode() {
142            synchronized (mutex) {return m.hashCode();}
143        }
144        public String toString() {
145            synchronized (mutex) {return m.toString();}
146        }
147        private void writeObject(ObjectOutputStream s) throws IOException {
148            synchronized (mutex) {s.defaultWriteObject();}
149        }
150
151                public int getType() {
152                        return StructUtil.getType(m);
153                }
154    }