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