View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.functor.example.map;
18  
19  import java.lang.reflect.Array;
20  import java.util.Collection;
21  import java.util.Map;
22  import java.util.Set;
23  
24  import org.apache.commons.functor.BinaryFunction;
25  import org.apache.commons.functor.BinaryProcedure;
26  import org.apache.commons.functor.NullaryProcedure;
27  import org.apache.commons.functor.Predicate;
28  import org.apache.commons.functor.Procedure;
29  
30  /**
31   * @version $Revision: 1508677 $ $Date: 2013-07-31 00:48:02 +0200 (Mi, 31 Jul 2013) $
32   */
33  @SuppressWarnings("unchecked")
34  public class FunctoredMap<K, V> implements Map<K, V> {
35      public FunctoredMap(Map<? super K, ? super V> map) {
36          this.map = (Map<K, V>)map;
37      }
38  
39      @Override
40      public int hashCode() {
41          return map.hashCode();
42      }
43  
44      @Override
45      public String toString() {
46          return map.toString();
47      }
48  
49      public Collection<V> values() {
50          return map.values();
51      }
52  
53      public Set<K> keySet() {
54          return map.keySet();
55      }
56  
57      public V get(Object key) {
58          return onget.evaluate(map, (K)key);
59      }
60  
61      public void clear() {
62          onclear.run(map);
63      }
64  
65      public int size() {
66          return map.size();
67      }
68  
69      public Object put(Object key, Object value) {
70          return onput.evaluate(map, new Object[] { key, value });
71      }
72  
73      public void putAll(Map<? extends K, ? extends V> src) {
74          onputall.run(map, (Map<K, V>)src);
75      }
76  
77      public Set<Map.Entry<K, V>> entrySet() {
78          return map.entrySet();
79      }
80  
81      public boolean containsKey(Object key) {
82          return map.containsKey(key);
83      }
84  
85      public boolean isEmpty() {
86          return map.isEmpty();
87      }
88  
89      public V remove(Object key) {
90          return onremove.evaluate(map, (K)key);
91      }
92  
93      @Override
94      public boolean equals(Object obj) {
95          return map.equals(obj);
96      }
97  
98      public boolean containsValue(Object value) {
99          return map.containsValue(value);
100     }
101 
102     // protected
103 
104     protected void setOnClear(Procedure<Map<K, V>> procedure) {
105         onclear = procedure;
106     }
107 
108     protected void setOnPut(BinaryFunction<Map<K, V>, Object[], V> function) {
109         onput = function;
110     }
111 
112     protected void setOnGet(BinaryFunction<Map<K, V>, K, V> function) {
113         onget = function;
114     }
115 
116     protected void setOnPutAll(BinaryProcedure<Map<K, V>, Map<K, V>> procedure) {
117         onputall = procedure;
118     }
119 
120     protected void setOnRemove(BinaryFunction<Map<K, V>, K, V> function) {
121         onremove = function;
122     }
123 
124     // attributes
125 
126     protected BinaryFunction<Map<K, V>, Object[], V> DEFAULT_ON_PUT = new BinaryFunction<Map<K, V>, Object[], V>() {
127         public V evaluate(Map<K, V> a, Object[] b) {
128             Map<K, V> map = a;
129             K key = (K)Array.get(b,0);
130             V value = (V)Array.get(b,1);
131             return map.put(key,value);
132         }
133     };
134 
135     private BinaryFunction<Map<K, V>, Object[], V> onput = DEFAULT_ON_PUT;
136 
137     protected BinaryFunction<Map<K, V>, K, V> DEFAULT_ON_GET = new BinaryFunction<Map<K, V>, K, V>() {
138         public V evaluate(Map<K, V> map, K key) {
139             return map.get(key);
140         }
141     };
142 
143     private BinaryFunction<Map<K, V>, K, V> onget = DEFAULT_ON_GET;
144     
145     protected BinaryProcedure<Map<K, V>, Map<K, V>> DEFAULT_ON_PUT_ALL = new BinaryProcedure<Map<K, V>, Map<K, V>>() {
146         public void run(Map<K, V> a, Map<K, V> b) {
147             Map<K, V> dest = a;
148             Map<K, V> src = b;
149             dest.putAll(src);
150         }
151     };
152 
153     private BinaryProcedure<Map<K, V>, Map<K, V>> onputall = DEFAULT_ON_PUT_ALL;
154 
155     protected BinaryFunction<Map<K, V>, K, V> DEFAULT_ON_REMOVE = new BinaryFunction<Map<K, V>, K, V>() {
156         public V evaluate(Map<K, V> a, K key) {
157             Map<K, V> map = a;
158             return map.remove(key);
159         }
160     };
161 
162     private BinaryFunction<Map<K, V>, K, V> onremove = DEFAULT_ON_REMOVE;
163 
164     protected Procedure<Map<K, V>> DEFAULT_ON_CLEAR = new Procedure<Map<K, V>>() {
165         public void run(Map<K, V> map) {
166             map.clear();
167         }
168     };
169 
170     private Procedure<Map<K, V>> onclear = DEFAULT_ON_CLEAR;
171 
172     private Map<K, V> map = null;
173 
174     // inner classes
175 
176     protected static class ContainsKey implements Predicate<Object> {
177         ContainsKey(Map<?, ?> map) {
178             this.map = map;
179         }
180 
181         public boolean test(Object obj) {
182             return map.containsKey(obj);
183         }
184 
185         private Map<?, ?> map = null;
186     }
187 
188     protected static class Throw<K, V> implements NullaryProcedure, Procedure<Map<K, V>>, BinaryProcedure<K, V> {
189         Throw(RuntimeException e) {
190             this.klass = e.getClass();
191         }
192 
193         public void run() {
194             try {
195                 throw (RuntimeException)(klass.newInstance());
196             } catch(IllegalAccessException e) {
197                 throw new RuntimeException();
198             } catch (InstantiationException e) {
199                 throw new RuntimeException();
200             }
201         }
202 
203         public void run(Map<K, V> obj) {
204             run();
205         }
206 
207         public void run(K a, V b) {
208             run();
209         }
210 
211         private Class<?> klass = null;
212     }
213 }