1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package io.github.prolobjectlink.prolog.jlog;
23
24 import java.util.Collection;
25 import java.util.Iterator;
26 import java.util.LinkedHashMap;
27 import java.util.LinkedHashSet;
28 import java.util.Map;
29 import java.util.Set;
30
31 import io.github.prolobjectlink.prolog.AbstractIterator;
32 import io.github.prolobjectlink.prolog.PrologMap;
33 import io.github.prolobjectlink.prolog.PrologProvider;
34 import io.github.prolobjectlink.prolog.PrologTerm;
35 import io.github.prolobjectlink.prolog.PrologTermType;
36
37
38
39
40
41
42
43
44 public final class JLogMap extends JLogTerm implements PrologMap {
45
46 private Map<PrologTerm, PrologTerm> map;
47
48 JLogMap(PrologProvider provider, int size) {
49 super(PrologTermType.MAP_TYPE, provider);
50 map = new LinkedHashMap<PrologTerm, PrologTerm>(size);
51 }
52
53 JLogMap(PrologProvider provider, Map<? extends PrologTerm, ? extends PrologTerm> m) {
54 this(provider);
55 putAll(m);
56 }
57
58 JLogMap(PrologProvider provider) {
59 this(provider, 16);
60 }
61
62 public String getFunctor() {
63 return ".";
64 }
65
66 public PrologTerm[] getArguments() {
67 PrologProvider p = getProvider();
68 PrologTerm[] args = new PrologTerm[map.size()];
69 Set<Entry<PrologTerm, PrologTerm>> s = entrySet();
70 Iterator<Entry<PrologTerm, PrologTerm>> i = s.iterator();
71 for (int j = 0; j < args.length && i.hasNext(); j++) {
72 Entry<PrologTerm, PrologTerm> e = i.next();
73 args[j] = new JLogEntry(p, e.getKey(), e.getValue());
74 }
75 return args;
76 }
77
78 public PrologTerm getArgument(int index) {
79 int idx = 0;
80 PrologTerm term = null;
81 checkIndex(index, size());
82 Iterator<PrologTerm> i = iterator();
83 for (; i.hasNext() && idx <= index; idx++) {
84 term = i.next();
85 if (idx == index) {
86 return term;
87 }
88 }
89 return term;
90 }
91
92 public int hashCode() {
93 int result = 0;
94 final int prime = 31;
95 result = prime * result + ((map == null) ? 0 : map.hashCode());
96 return result;
97 }
98
99 public boolean equals(Object obj) {
100 if (this == obj)
101 return true;
102 if (obj == null)
103 return false;
104 if (getClass() != obj.getClass())
105 return false;
106 JLogMap other = (JLogMap) obj;
107 if (map == null) {
108 if (other.map != null)
109 return false;
110 } else if (!map.equals(other.map)) {
111 return false;
112 }
113 return true;
114 }
115
116 @Override
117 public String toString() {
118 StringBuilder b = new StringBuilder();
119 Set<Entry<PrologTerm, PrologTerm>> set = entrySet();
120 Iterator<Entry<PrologTerm, PrologTerm>> i = set.iterator();
121 b.append('[');
122 while (i.hasNext()) {
123 Entry<PrologTerm, PrologTerm> entry = i.next();
124 b.append(entry.getKey());
125 b.append('-');
126 b.append(entry.getValue());
127 if (i.hasNext()) {
128 b.append(',');
129 b.append(' ');
130 }
131 }
132 b.append(']');
133 return "" + b + "";
134 }
135
136 @Override
137 public Iterator<PrologTerm> iterator() {
138 return new PrologMapIterator();
139 }
140
141 @Override
142 public PrologTerm getHead() {
143 return iterator().next();
144 }
145
146 @Override
147 public PrologTerm getTail() {
148 JLogMap m = new JLogMap(provider, map);
149 m.remove(((Entry<?, ?>) getHead()).getKey());
150 return m;
151 }
152
153 public void putAll(Collection<Entry<PrologTerm, PrologTerm>> entries) {
154 for (Entry<PrologTerm, PrologTerm> entry : entries) {
155 put(entry);
156 }
157 }
158
159 public boolean contains(Entry<PrologTerm, PrologTerm> entry) {
160 PrologTerm value = get(entry.getKey());
161 return value != null ? value.equals(entry.getValue()) : false;
162 }
163
164 public void remove(Entry<PrologTerm, PrologTerm> entry) {
165 remove(entry.getKey());
166 }
167
168 public void put(Entry<PrologTerm, PrologTerm> entry) {
169 put(entry.getKey(), entry.getValue());
170 }
171
172 private class PrologMapIterator extends AbstractIterator<PrologTerm> implements Iterator<PrologTerm> {
173
174 private final Set<PrologTerm> set;
175 private final Iterator<PrologTerm> itr;
176
177 private PrologMapIterator() {
178 set = new LinkedHashSet<PrologTerm>(map.size());
179 for (Iterator<Entry<PrologTerm, PrologTerm>> i = map.entrySet().iterator(); i.hasNext();) {
180 Entry<PrologTerm, PrologTerm> e = i.next();
181 PrologTerm t = new JLogEntry(provider, e.getKey(), e.getValue());
182 set.add(t);
183 }
184 itr = set.iterator();
185 }
186
187 @Override
188 public boolean hasNext() {
189 return itr.hasNext();
190 }
191
192 @Override
193 public PrologTerm next() {
194 return itr.next();
195 }
196
197 }
198
199 public PrologTerm put(PrologTerm key, PrologTerm value) {
200 return map.put(key, value);
201 }
202
203 public Set<Entry<PrologTerm, PrologTerm>> entrySet() {
204 return map.entrySet();
205 }
206
207 @Override
208 public boolean containsKey(Object key) {
209 return map.containsKey(key);
210 }
211
212 @Override
213 public boolean containsValue(Object value) {
214 return map.containsValue(value);
215 }
216
217 @Override
218 public PrologTerm get(Object key) {
219 return map.get(key);
220 }
221
222 @Override
223 public PrologTerm remove(Object key) {
224 return map.remove(key);
225 }
226
227 @Override
228 public void putAll(Map<? extends PrologTerm, ? extends PrologTerm> m) {
229 map.putAll(m);
230 }
231
232 @Override
233 public Set<PrologTerm> keySet() {
234 return map.keySet();
235 }
236
237 @Override
238 public Collection<PrologTerm> values() {
239 return map.values();
240 }
241
242 @Override
243 public boolean isEmpty() {
244 return map.isEmpty();
245 }
246
247 @Override
248 public void clear() {
249 map.clear();
250 }
251
252 @Override
253 public int size() {
254 return map.size();
255 }
256
257 @Override
258 public int getArity() {
259 if (map.size() > 0) {
260 return 2;
261 }
262 return 0;
263 }
264
265 @Override
266 public PrologTerm getTerm() {
267 return this;
268 }
269
270 @Override
271 public boolean isEvaluable() {
272 return false;
273 }
274
275 @Override
276 public boolean isCompound() {
277 return true;
278 }
279
280 }