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.Procedure;
27  import org.apache.commons.functor.UnaryPredicate;
28  import org.apache.commons.functor.UnaryProcedure;
29  
30  /**
31   * @version $Revision: 666157 $ $Date: 2008-06-10 17:34:23 +0200 (Tue, 10 Jun 2008) $
32   * @author Rodney Waldhoff
33   */
34  @SuppressWarnings("unchecked")
35  public class FunctoredMap implements Map {
36      public FunctoredMap(Map map) {
37          this.map = map;
38      }
39  
40      public int hashCode() {
41          return map.hashCode();
42      }
43  
44      public String toString() {
45          return map.toString();
46      }
47  
48      public Collection values() {
49          return map.values();
50      }
51  
52      public Set keySet() {
53          return map.keySet();
54      }
55  
56      public Object get(Object key) {
57          return onget.evaluate(map,key);
58      }
59  
60      public void clear() {
61          onclear.run(map);
62      }
63  
64      public int size() {
65          return map.size();
66      }
67  
68      public Object put(Object key, Object value) {
69          return onput.evaluate(map, new Object[] { key, value });
70      }
71  
72      public void putAll(Map src) {
73          onputall.run(map, src);
74      }
75  
76      public Set entrySet() {
77          return map.entrySet();
78      }
79  
80      public boolean containsKey(Object key) {
81          return map.containsKey(key);
82      }
83  
84      public boolean isEmpty() {
85          return map.isEmpty();
86      }
87  
88      public Object remove(Object key) {
89          return onremove.evaluate(map,key);
90      }
91  
92      public boolean equals(Object obj) {
93          return map.equals(obj);
94      }
95  
96      public boolean containsValue(Object value) {
97          return map.containsValue(value);
98      }
99  
100     // protected
101 
102     protected void setOnClear(UnaryProcedure procedure) {
103         onclear = procedure;
104     }
105 
106     protected void setOnPut(BinaryFunction function) {
107         onput = function;
108     }
109 
110     protected void setOnGet(BinaryFunction function) {
111         onget = function;
112     }
113 
114     protected void setOnPutAll(BinaryProcedure procedure) {
115         onputall = procedure;
116     }
117 
118     protected void setOnRemove(BinaryFunction function) {
119         onremove = function;
120     }
121 
122     // attributes
123 
124     protected static final BinaryFunction DEFAULT_ON_PUT = new BinaryFunction() {
125         public Object evaluate(Object a, Object b) {
126             Map map = (Map) a;
127             Object key = Array.get(b,0);
128             Object value = Array.get(b,1);
129             return map.put(key,value);
130         }
131     };
132 
133     private BinaryFunction onput = DEFAULT_ON_PUT;
134 
135     protected static final BinaryFunction DEFAULT_ON_GET = new BinaryFunction() {
136         public Object evaluate(Object map, Object key) {
137             return ((Map) map).get(key);
138         }
139     };
140 
141     private BinaryFunction onget = DEFAULT_ON_GET;
142 
143     protected static final BinaryProcedure DEFAULT_ON_PUT_ALL = new BinaryProcedure() {
144         public void run(Object a, Object b) {
145             Map dest = (Map) a;
146             Map src = (Map) b;
147             dest.putAll(src);
148         }
149     };
150 
151     private BinaryProcedure onputall = DEFAULT_ON_PUT_ALL;
152 
153     protected static final BinaryFunction DEFAULT_ON_REMOVE = new BinaryFunction() {
154         public Object evaluate(Object a, Object key) {
155             Map map = (Map) a;
156             return map.remove(key);
157         }
158     };
159 
160     private BinaryFunction onremove = DEFAULT_ON_REMOVE;
161 
162     protected static final UnaryProcedure DEFAULT_ON_CLEAR = new UnaryProcedure() {
163         public void run(Object map) {
164             ((Map) map).clear();
165         }
166     };
167 
168     private UnaryProcedure onclear = DEFAULT_ON_CLEAR;
169 
170     private Map map = null;
171 
172     // inner classes
173 
174     protected static class ContainsKey implements UnaryPredicate {
175         ContainsKey(Map map) {
176             this.map = map;
177         }
178 
179         public boolean test(Object obj) {
180             return map.containsKey(obj);
181         }
182 
183         private Map map = null;
184     }
185 
186     protected static class Throw implements Procedure, UnaryProcedure, BinaryProcedure {
187         Throw(RuntimeException e) {
188             this.klass = e.getClass();
189         }
190 
191         public void run() {
192             try {
193                 throw (RuntimeException)(klass.newInstance());
194             } catch(IllegalAccessException e) {
195                 throw new RuntimeException();
196             } catch (InstantiationException e) {
197                 throw new RuntimeException();
198             }
199         }
200 
201         public void run(Object obj) {
202             run();
203         }
204 
205         public void run(Object a, Object b) {
206             run();
207         }
208 
209         private Class klass = null;
210     }
211 }