astra.reasoner.util.ContentCodec Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of astra-interpreter Show documentation
Show all versions of astra-interpreter Show documentation
Core interpreter artifact for the ASTRA Language
package astra.reasoner.util;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import astra.formula.Formula;
import astra.formula.Predicate;
import astra.term.Funct;
import astra.term.ListTerm;
import astra.term.Primitive;
import astra.term.Term;
import astra.type.ObjectType;
public class ContentCodec {
private static ContentCodec codec;
private ObjectMapper mapper = new ObjectMapper();
public static ContentCodec getInstance() {
if (codec == null) codec = new ContentCodec();
return codec;
}
public String encode(Formula formula) {
if (formula instanceof Predicate) return encode((Predicate) formula);
System.out.println("Unexpected format: " + formula.getClass().getCanonicalName());
return null;
}
private String encode(Predicate predicate) {
ArrayNode terms = mapper.createArrayNode();
for(Term term: predicate.terms()) {
terms.add(encode(term));
}
ObjectNode node = mapper.createObjectNode();
node.put("predicate", predicate.predicate());
node.set("terms", terms);
try {
return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(node);
} catch (JsonProcessingException e) {
e.printStackTrace();
return null;
}
}
private ObjectNode encode(Term term) {
if (term instanceof Primitive>) return encode((Primitive>) term);
if (term instanceof ListTerm) return encode((ListTerm) term);
if (term instanceof Funct) return encode((Funct) term);
throw new RuntimeException("Could not encode: " + term);
}
private ObjectNode encode(Primitive> primitive) {
ObjectNode node = mapper.createObjectNode();
if (primitive.type() instanceof ObjectType) {
ByteArrayOutputStream bout = new ByteArrayOutputStream();
ObjectOutputStream out = null;
try {
out = new ObjectOutputStream(bout);
out.writeObject(primitive.value());
node.put("type","object");
node.put("value", bout.toByteArray());
} catch (IOException e) {
e.printStackTrace();
return null;
}
} else {
node.put("type", primitive.type().toString());
node.putPOJO("value", primitive.value() );
}
return node;
}
private ObjectNode encode(ListTerm list) {
ArrayNode array = mapper.createArrayNode();
for (Term term : list) {
array.add(encode(term));
}
ObjectNode node = mapper.createObjectNode();
node.put("type", "list");
node.set("value", array);
return node;
}
private ObjectNode encode(Funct funct) {
ArrayNode array = mapper.createArrayNode();
for (Term term : funct.terms()) {
array.add(encode(term));
}
ObjectNode node = mapper.createObjectNode();
node.put("type", "funct");
node.put("functor", funct.functor());
node.set("value", array);
return node;
}
public Formula decode(String json) {
ObjectMapper mapper = new ObjectMapper();
// mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_CONTROL_CHARS, true);
try {
return decode(mapper.readTree(json));
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
private Formula decode(JsonNode node) {
if (node instanceof ObjectNode) {
return decode((ObjectNode) node);
} else if (node instanceof ArrayNode) {
return decode((ArrayNode) node);
}
return null;
}
public Formula decode(ObjectNode ObjectNode) {
String predicate = ObjectNode.get("predicate").asText();
if (predicate != null) return decode_predicate(predicate, ObjectNode);
return null;
}
private Predicate decode_predicate(String predicate, ObjectNode ObjectNode) {
ArrayNode array = (ArrayNode) ObjectNode.get("terms");
Term[] terms = new Term[array.size()];
for (int i=0; i < array.size(); i++) {
terms[i] = decode_term((ObjectNode) array.get(i));
}
return new Predicate(predicate, terms);
}
private Term decode_term(ObjectNode object) {
String type = object.get("type").asText();
if (type.equals("string")) return Primitive.newPrimitive(object.get("value").asText());
if (type.equals("integer")) return Primitive.newPrimitive(object.get("value").asInt());
if (type.equals("long")) return Primitive.newPrimitive(object.get("value").asLong());
if (type.equals("float")) return Primitive.newPrimitive(object.get("value").floatValue());
if (type.equals("double")) return Primitive.newPrimitive(object.get("value").asDouble());
if (type.equals("char")) return Primitive.newPrimitive(object.get("value").asText().charAt(0));
if (type.equals("boolean")) return Primitive.newPrimitive(object.get("value").asBoolean());
if (type.equals("list")) return decode_list((ArrayNode) object.get("value"));
if (type.equals("funct")) return decode_funct(object);
if (type.equals("object")) return decode_object(object);
return null;
}
private Term decode_object(ObjectNode object) {
try {
ByteArrayInputStream bin = new ByteArrayInputStream(object.get("value").binaryValue());
ObjectInputStream in = new ObjectInputStream(bin);
Object obj = in.readObject();
return Primitive.newPrimitive(obj);
} catch (IOException e) {
e.printStackTrace();
return null;
} catch (ClassNotFoundException e) {
e.printStackTrace();
return null;
}
}
private Term decode_funct(ObjectNode object) {
String functor = object.get("functor").asText();
ArrayNode array = (ArrayNode) object.get("value");
Term[] terms = new Term[array.size()];
for (int i=0; i < array.size(); i++) {
terms[i] = decode_term((ObjectNode) array.get(i));
}
return new Funct(functor, terms);
}
private Term decode_list(ArrayNode array) {
Term[] terms = new Term[array.size()];
for (int i=0; i < terms.length; i++) {
terms[i] = decode_term((ObjectNode) array.get(i));
}
return new ListTerm(terms);
}
private static class Test implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
String value = "hello world";
public String toString() { return value; }
}
public static void main(String[] args) {
test_predicate(new Predicate("test", new Term[] {Primitive.newPrimitive("rem"), Primitive.newPrimitive("happy")}));
test_predicate(new Predicate("test", new Term[] {Primitive.newPrimitive("rem"), Primitive.newPrimitive(42)}));
test_predicate(new Predicate("test", new Term[] {Primitive.newPrimitive("rem"), Primitive.newPrimitive(42l)}));
test_predicate(new Predicate("test", new Term[] {Primitive.newPrimitive("rem"), Primitive.newPrimitive(42.0f)}));
test_predicate(new Predicate("test", new Term[] {Primitive.newPrimitive("rem"), Primitive.newPrimitive(42.5)}));
test_predicate(new Predicate("test", new Term[] {Primitive.newPrimitive("rem"), Primitive.newPrimitive('a')}));
test_predicate(new Predicate("test", new Term[] {Primitive.newPrimitive("rem"), Primitive.newPrimitive(true)}));
test_predicate(new Predicate("test", new Term[] {Primitive.newPrimitive("rem"), new ListTerm(new Term[] {Primitive.newPrimitive(104), Primitive.newPrimitive(105)})}));
test_predicate(new Predicate("test", new Term[] {Primitive.newPrimitive("rem"), new Funct("test", new Term[] {Primitive.newPrimitive(true)})}));
test_predicate(new Predicate("test", new Term[] {Primitive.newPrimitive("rem"), Primitive.newPrimitive(new Test())}));
}
private static void test_predicate(Predicate p) {
String json = ContentCodec.getInstance().encode(p);
System.out.println(json);
Formula f = ContentCodec.getInstance().decode(json);
System.out.println("predicate: " + f.toString());
}
}