1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 package io.github.prolobjectlink.prolog;
27
28 import static io.github.prolobjectlink.prolog.PrologTermType.ATOM_TYPE;
29 import static io.github.prolobjectlink.prolog.PrologTermType.DOUBLE_TYPE;
30 import static io.github.prolobjectlink.prolog.PrologTermType.FALSE_TYPE;
31 import static io.github.prolobjectlink.prolog.PrologTermType.FLOAT_TYPE;
32 import static io.github.prolobjectlink.prolog.PrologTermType.INTEGER_TYPE;
33 import static io.github.prolobjectlink.prolog.PrologTermType.LIST_TYPE;
34 import static io.github.prolobjectlink.prolog.PrologTermType.LONG_TYPE;
35 import static io.github.prolobjectlink.prolog.PrologTermType.NIL_TYPE;
36 import static io.github.prolobjectlink.prolog.PrologTermType.OBJECT_TYPE;
37 import static io.github.prolobjectlink.prolog.PrologTermType.STRUCTURE_TYPE;
38 import static io.github.prolobjectlink.prolog.PrologTermType.TRUE_TYPE;
39 import static io.github.prolobjectlink.prolog.PrologTermType.VARIABLE_TYPE;
40
41 import java.lang.reflect.Array;
42 import java.util.ArrayList;
43 import java.util.HashMap;
44 import java.util.List;
45 import java.util.Map;
46 import java.util.Map.Entry;
47
48
49
50
51
52
53
54 public abstract class AbstractJavaConverter implements PrologJavaConverter {
55
56 private final PrologProvider provider;
57
58 protected AbstractJavaConverter(PrologProvider provider) {
59 this.provider = provider;
60 }
61
62 public final boolean containQuotes(String functor) {
63 if (functor != null && !functor.isEmpty()) {
64 return functor.startsWith("\'") && functor.endsWith("\'");
65 }
66 return false;
67 }
68
69 public final String removeQuotes(String functor) {
70 if (containQuotes(functor)) {
71 return functor.substring(1, functor.length() - 1);
72 }
73 return functor;
74 }
75
76 public final Object toObject(PrologTerm prologTerm) {
77 if (prologTerm == null) {
78 return null;
79 }
80
81 switch (prologTerm.getType()) {
82 case NIL_TYPE:
83 return null;
84 case TRUE_TYPE:
85 return true;
86 case FALSE_TYPE:
87 return false;
88 case ATOM_TYPE:
89 return removeQuotes(prologTerm.getFunctor());
90 case INTEGER_TYPE:
91 return ((PrologInteger) prologTerm).getIntegerValue();
92 case FLOAT_TYPE:
93 return ((PrologFloat) prologTerm).getFloatValue();
94 case LONG_TYPE:
95 return ((PrologLong) prologTerm).getLongValue();
96 case DOUBLE_TYPE:
97 return ((PrologDouble) prologTerm).getDoubleValue();
98 case VARIABLE_TYPE:
99 return prologTerm;
100 case LIST_TYPE:
101 return toObjectsArray(prologTerm.getArguments());
102 case STRUCTURE_TYPE:
103 return prologTerm;
104 case OBJECT_TYPE:
105 return prologTerm.getObject();
106 default:
107 throw new UnknownTermError(prologTerm);
108 }
109 }
110
111 public final Object[] toObjectsArray(PrologTerm[] terms) {
112 Object array = Array.newInstance(Object.class, terms.length);
113 for (int i = 0; i < terms.length; i++) {
114 Array.set(array, i, toObject(terms[i]));
115 }
116 return (Object[]) array;
117 }
118
119 public final PrologTerm toTerm(Object object) {
120
121 if (object == null) {
122 return provider.prologNil();
123 }
124
125
126 else if (object instanceof String) {
127 if (((String) object).matches("[A-Z_]*")) {
128 return provider.newVariable("" + (String) object + "", 0);
129 }
130 return provider.newAtom("" + (String) object + "");
131 }
132
133
134 else if (object.getClass() == char.class || object instanceof Character) {
135 return provider.newAtom("" + (String) object + "");
136 } else if (object.getClass() == byte.class || object instanceof Byte) {
137 return provider.newInteger((Integer) object);
138 } else if (object.getClass() == short.class || object instanceof Short) {
139 return provider.newInteger((Integer) object);
140 } else if (object.getClass() == boolean.class || object instanceof Boolean) {
141 return (Boolean) object ? provider.prologTrue() : provider.prologFalse();
142 } else if (object.getClass() == int.class || object instanceof Integer) {
143 return provider.newInteger((Integer) object);
144 } else if (object.getClass() == float.class || object instanceof Float) {
145 return provider.newFloat((Float) object);
146 } else if (object.getClass() == long.class || object instanceof Long) {
147 return provider.newLong((Long) object);
148 } else if (object.getClass() == double.class || object instanceof Double) {
149 return provider.newDouble((Double) object);
150 }
151
152
153 else if (object instanceof Object[]) {
154 return provider.newList(toTermsArray((Object[]) object));
155 }
156
157 throw new UnknownTermError(object);
158
159 }
160
161 public final PrologTerm[] toTermsArray(Object[] objects) {
162 PrologTerm[] terms = new PrologTerm[objects.length];
163 for (int i = 0; i < objects.length; i++) {
164 terms[i] = toTerm(objects[i]);
165 }
166 return terms;
167 }
168
169 public final List<Map<String, Object>> toObjectMaps(Map<String, PrologTerm>[] maps) {
170 List<Map<String, Object>> list = new ArrayList<Map<String, Object>>(maps.length);
171 for (Map<String, PrologTerm> map : maps) {
172 list.add(toObjectMap(map));
173 }
174 return list;
175 }
176
177 public final Map<String, Object> toObjectMap(Map<String, PrologTerm> map) {
178 Map<String, Object> objects = new HashMap<String, Object>(map.size());
179 for (Entry<String, PrologTerm> entry : map.entrySet()) {
180 objects.put(entry.getKey(), toObject(entry.getValue()));
181 }
182 return objects;
183 }
184
185 public final List<Object> toObjectList(PrologTerm[] terms) {
186 List<Object> list = new ArrayList<Object>(terms.length);
187 for (PrologTerm prologTerm : terms) {
188 list.add(toObject(prologTerm));
189 }
190 return list;
191 }
192
193 public final List<List<Object>> toObjectLists(PrologTerm[][] terms) {
194 List<List<Object>> list = new ArrayList<List<Object>>(terms.length);
195 for (PrologTerm[] prologTerms : terms) {
196 list.add(toObjectList(prologTerms));
197 }
198 return list;
199 }
200
201 @Override
202 public int hashCode() {
203 final int prime = 31;
204 int result = super.hashCode();
205 result = prime * result + ((provider == null) ? 0 : provider.hashCode());
206 return result;
207 }
208
209 @Override
210 public boolean equals(Object obj) {
211 if (this == obj)
212 return true;
213 if (!super.equals(obj))
214 return false;
215 if (getClass() != obj.getClass())
216 return false;
217 AbstractJavaConverter other = (AbstractJavaConverter) obj;
218 if (provider == null) {
219 if (other.provider != null)
220 return false;
221 } else if (!provider.equals(other.provider)) {
222 return false;
223 }
224 return true;
225 }
226
227 }