diff --git a/ragconnect.base/src/main/jastadd/Intermediate.jadd b/ragconnect.base/src/main/jastadd/Intermediate.jadd index 1a24fa97c1c561bd841944a82231fe2fd40aad69..036159fe322e9888e361bf554ff0554b198ff41d 100644 --- a/ragconnect.base/src/main/jastadd/Intermediate.jadd +++ b/ragconnect.base/src/main/jastadd/Intermediate.jadd @@ -333,6 +333,10 @@ aspect MustacheRagConnect { // === MappingDefinition === syn boolean MappingDefinition.isUsed() = !effectiveUsedAt().isEmpty(); + eq SerializeListMapping.isUsed() = ragconnect().defaultListToBytesMapping().isUsed(); + eq SerializeJavaUtilListMapping.isUsed() = ragconnect().defaultJavaUtilListToBytesMapping().isUsed(); + eq DeserializeListMapping.isUsed() = program().typeDecls().stream().anyMatch( + typeDecl -> ragconnect().defaultBytesToListMapping(typeDecl.getName()).isUsed()); // === attributes needed for computing above ones === syn List<EndpointDefinition> RagConnect.givenEndpointDefinitionList() { diff --git a/ragconnect.base/src/main/jastadd/IntermediateToYAML.jrag b/ragconnect.base/src/main/jastadd/IntermediateToYAML.jrag index 49c2693696a02de14852e252f3aadd3a722dfb95..23f32d98edeca8b6befa698e885d75d986a30860 100644 --- a/ragconnect.base/src/main/jastadd/IntermediateToYAML.jrag +++ b/ragconnect.base/src/main/jastadd/IntermediateToYAML.jrag @@ -147,6 +147,17 @@ aspect IntermediateToYAML { return result; } + syn Element TemplateDefaultMappingDefinition.toYAML() { + MappingElement result = new MappingElement(); + + // ragconnect / mapping + result.put("isUsed" , isUsed()); + result.put("isSerializeListMapping" , isSerializeListMapping()); + result.put("isSerializeJavaUtilListMapping" , isSerializeJavaUtilListMapping()); + result.put("isDeserializeListMapping" , isDeserializeListMapping()); + return result; + } + syn Element DependencyDefinition.toYAML() { MappingElement result = new MappingElement(); // dependencyDefinition diff --git a/ragconnect.base/src/main/jastadd/Mappings.jrag b/ragconnect.base/src/main/jastadd/Mappings.jrag index e92fc4fa27569ee353b0c16798e2ce3b7eb07a29..133fae2fe3faea33de05727c72bbab6e7046efa0 100644 --- a/ragconnect.base/src/main/jastadd/Mappings.jrag +++ b/ragconnect.base/src/main/jastadd/Mappings.jrag @@ -27,6 +27,16 @@ aspect DefaultMappings { result.setContent(content); return result; } + private TemplateDefaultMappingDefinition RagConnect.initTemplateMappingDefinition( + TemplateDefaultMappingDefinition prototype, String id, String type, boolean fromBytes) { + MappingDefinitionType givenType = new JavaMappingDefinitionType().setType(new SimpleJavaTypeUse(type)); + MappingDefinitionType bytesType = new JavaArrayMappingDefinitionType().setType(new SimpleJavaTypeUse("byte")); + + prototype.setID(id); + prototype.setFromType(fromBytes ? bytesType : givenType); + prototype.setToType(fromBytes ? givenType : bytesType); + return prototype; + } private DefaultMappingDefinition RagConnect.baseDefaultMappingDefinition(String fromTypeName, String toTypeName, String content) { return createDefaultMappingDefinition("_Default", fromTypeName, toTypeName, content); @@ -81,7 +91,7 @@ aspect DefaultMappings { "com.fasterxml.jackson.databind.ObjectMapper mapper = new com.fasterxml.jackson.databind.ObjectMapper();\n" + "com.fasterxml.jackson.core.JsonFactory factory = new com.fasterxml.jackson.core.JsonFactory();\n" + "com.fasterxml.jackson.core.JsonParser parser = factory.createParser(content);\n" + - configJastAddList() + "<" + typeName + ">" + " result = " + typeName + ".deserializeList((com.fasterxml.jackson.databind.node.ArrayNode)mapper.readTree(parser));\n" + + configJastAddList() + "<" + typeName + ">" + " result = " + typeName + ".deserializeListOf" + typeName + "((com.fasterxml.jackson.databind.node.ArrayNode)mapper.readTree(parser));\n" + "parser.close();\n" + "return result;" ); @@ -155,6 +165,15 @@ aspect DefaultMappings { "char", "String", "return String.valueOf(input);"); } +aspect TemplateDefaultMappingDefinitions { + syn nta TemplateDefaultMappingDefinition RagConnect.serializeListMapping() = initTemplateMappingDefinition( + new SerializeListMapping(), "SerializeListMapping", "JastAddList", false); + syn nta TemplateDefaultMappingDefinition RagConnect.serializeJavaUtilListMapping() = initTemplateMappingDefinition( + new SerializeListMapping(), "SerializeJavaUtilListMapping", "java.util.List", false); + syn nta TemplateDefaultMappingDefinition RagConnect.deserializeListMapping(String name) = initTemplateMappingDefinition( + new DeserializeListMapping().setName(name), "DeserializeListMapping", "JastAddList", true); +} + aspect Mappings { // --- effectiveMappings --- syn java.util.List<MappingDefinition> EndpointDefinition.effectiveMappings() { @@ -390,9 +409,12 @@ aspect Mappings { result.add(defaultBytesToTreeMapping(typeDecl.getName())); result.add(defaultTreeToBytesMapping(typeDecl.getName())); result.add(defaultBytesToListMapping(typeDecl.getName())); + result.add(deserializeListMapping(typeDecl.getName())); } result.add(defaultListToBytesMapping()); result.add(defaultJavaUtilListToBytesMapping()); + result.add(serializeListMapping()); + result.add(serializeJavaUtilListMapping()); // // string conversion // result.add(defaultStringToBooleanMapping()); // result.add(defaultStringToIntMapping()); diff --git a/ragconnect.base/src/main/jastadd/Navigation.jrag b/ragconnect.base/src/main/jastadd/Navigation.jrag index 5288a9f14f2cc8e3298d3d20fa53076fd72be09e..02f6f23ee92d2ab61a60a87928ef45921602484c 100644 --- a/ragconnect.base/src/main/jastadd/Navigation.jrag +++ b/ragconnect.base/src/main/jastadd/Navigation.jrag @@ -36,6 +36,24 @@ aspect GeneratedNavigation { syn boolean EndpointTarget.isRelationEndpointTarget() = false; eq RelationEndpointTarget.isRelationEndpointTarget() = true; + /** Tests if TemplateDefaultMappingDefinition is a SerializeListMapping. + * @return 'true' if this is a SerializeListMapping, otherwise 'false' + */ + syn boolean TemplateDefaultMappingDefinition.isSerializeListMapping() = false; + eq SerializeListMapping.isSerializeListMapping() = true; + + /** Tests if TemplateDefaultMappingDefinition is a SerializeJavaUtilListMapping. + * @return 'true' if this is a SerializeJavaUtilListMapping, otherwise 'false' + */ + syn boolean TemplateDefaultMappingDefinition.isSerializeJavaUtilListMapping() = false; + eq SerializeJavaUtilListMapping.isSerializeJavaUtilListMapping() = true; + + /** Tests if TemplateDefaultMappingDefinition is a DeserializeListMapping. + * @return 'true' if this is a DeserializeListMapping, otherwise 'false' + */ + syn boolean TemplateDefaultMappingDefinition.isDeserializeListMapping() = false; + eq DeserializeListMapping.isDeserializeListMapping() = true; + /** casts a EndpointTarget into a TokenEndpointTarget if possible. * @return 'this' cast to a TokenEndpointTarget or 'null' */ @@ -80,6 +98,13 @@ aspect GeneratedNavigation { } aspect RagConnectNavigation { + // adapted from generated navigation, was defined only for DefaultMappingDefinition + /** Tests if MappingDefinition is a TemplateDefaultMappingDefinition. + * @return 'true' if this is a TemplateDefaultMappingDefinition, otherwise 'false' + */ + syn boolean MappingDefinition.isTemplateDefaultMappingDefinition() = false; + eq TemplateDefaultMappingDefinition.isTemplateDefaultMappingDefinition() = true; + // --- program --- eq RagConnect.getChild().program() = getProgram(); diff --git a/ragconnect.base/src/main/jastadd/RagConnect.relast b/ragconnect.base/src/main/jastadd/RagConnect.relast index df50e3dab1dde22e38bca0588396de647b49c8cb..ef96abf63729ff856b65a3f108c44b5b01fe7ecb 100644 --- a/ragconnect.base/src/main/jastadd/RagConnect.relast +++ b/ragconnect.base/src/main/jastadd/RagConnect.relast @@ -28,6 +28,10 @@ abstract MappingDefinitionType ::= ; JavaMappingDefinitionType : MappingDefinitionType ::= Type:JavaTypeUse; JavaArrayMappingDefinitionType : MappingDefinitionType ::= Type:JavaTypeUse; DefaultMappingDefinition : MappingDefinition; +abstract TemplateDefaultMappingDefinition : DefaultMappingDefinition ; +SerializeListMapping : TemplateDefaultMappingDefinition ; +SerializeJavaUtilListMapping : TemplateDefaultMappingDefinition ; +DeserializeListMapping : TemplateDefaultMappingDefinition ::= <Name> ; Handler ::= <ClassName> <UniqueName> <InUse:boolean>; diff --git a/ragconnect.base/src/main/resources/mappingDefinition.mustache b/ragconnect.base/src/main/resources/mappingDefinition.mustache index b6a035eb41b9d3f877b731293203de399399e6c0..392f44418129861ebc51b7c5e91c5c2721cf58e1 100644 --- a/ragconnect.base/src/main/resources/mappingDefinition.mustache +++ b/ragconnect.base/src/main/resources/mappingDefinition.mustache @@ -1,3 +1,46 @@ +{{#isUsed}} + {{#isTemplateDefaultMappingDefinition}} + {{#isSerializeListMapping}} +public void {{configJastAddList}}.serialize(com.fasterxml.jackson.core.JsonGenerator g) throws SerializationException { + try { + g.writeStartArray(); + for (T child : this) { + child.serialize(g); + } + g.writeEndArray(); + } catch (java.io.IOException e) { + throw new SerializationException("unable to serialize {{configJastAddList}}", e); + } +} + {{/isSerializeListMapping}} + {{#SerializeJavaUtilListMapping}} +protected static <T extends ASTNode> void ASTNode.serializeJavaUtilList( + java.util.List<T> input, com.fasterxml.jackson.core.JsonGenerator g) throws SerializationException { + try { + g.writeStartArray(); + for (T child : input) { + child.serialize(g); + } + g.writeEndArray(); + } catch (java.io.IOException e) { + throw new SerializationException("unable to serialize list", e); + } +} + {{/SerializeJavaUtilListMapping}} + {{#DeserializeListMapping}} +public static {{configJastAddList}}<{{Name}}> {{Name}}.deserializeListOf{{Name}}(com.fasterxml.jackson.databind.node.ArrayNode node) throws DeserializationException { + {{configJastAddList}}<{{Name}}> result = new {{configJastAddList}}<>(); + for (java.util.Iterator<com.fasterxml.jackson.databind.JsonNode> it = node.elements(); it.hasNext();) { + com.fasterxml.jackson.databind.JsonNode element = it.next(); + result.add(deserialize(element)); + } + return result; +} + {{/DeserializeListMapping}} + {{/isTemplateDefaultMappingDefinition}} + {{^TemplateDefaultMappingDefinition}} protected {{{toType}}} ASTNode.{{methodName}}({{{fromType}}} {{FromVariableName}}) throws Exception { {{{Content}}} } + {{/TemplateDefaultMappingDefinition}} +{{/isUsed}} diff --git a/ragconnect.base/src/main/resources/ragconnect.mustache b/ragconnect.base/src/main/resources/ragconnect.mustache index c428021bf1eab32bf8baac8585a3f801ba8ad6ad..738ecbed63493e4d7fb1edcb1ed21de9b7c8fceb 100644 --- a/ragconnect.base/src/main/resources/ragconnect.mustache +++ b/ragconnect.base/src/main/resources/ragconnect.mustache @@ -15,9 +15,7 @@ aspect RagConnect { } {{#allMappingDefinitions}} - {{#isUsed}} {{> mappingDefinition}} - {{/isUsed}} {{/allMappingDefinitions}} {{#allDependencyDefinitionList}} @@ -65,7 +63,7 @@ aspect RagConnect { return this; } - {{> ListAspect}} +{{!{{> ListAspect}} static void ASTNode.{{logConsoleOut}}(String message, Object... args) { System.out.println(String.format(message, args));