@Test void parseTemplate() { Map<String, Object> template = named("a", _FIRST).named("b", _N(1)) .named("c", named("d", _LAST)); Map<String, Object> expected = new HashMap<String, Object>(){{ put("a", 1); put("b", new HashMap<String, Object>() {{put("x", 10);}}); put("c", new HashMap<String, Object>() {{put("d", 3);}}); }}; List<Map<String, Object>> params = Arrays.asList( value(1), named("x", 10), value(3) ); SemanticFunction fn = SemanticUtils.parseTemplate(template); assertEquals(Collections.singletonList(expected), fn.apply(params)); }
public static SemanticFunction parseTemplate(Map<String, Object> template){ return params -> { Map<String, Object> result = new HashMap<>(); LinkedList<Map<String, Object>> queueIn = new LinkedList<>(); LinkedList<Map<String, Object>> queueOut = new LinkedList<>(); queueIn.addLast(template); queueOut.addLast(result); while (!queueIn.isEmpty()) { final Map<String, Object> mapIn = queueIn.removeFirst(); final Map<String, Object> mapOut = queueOut.removeFirst(); for (Map.Entry<String, Object> entry : mapIn.entrySet()) { mapOut.put(entry.getKey(), entry.getValue()); if(entry.getKey().equals(_MERGE)) { if(entry.getValue() instanceof List){ List<Number> indices = (List<Number>)entry.getValue(); for(Number index: indices){ mapOut.putAll(params.get(index.intValue())); } } mapOut.remove(_MERGE); } else if (entry.getValue() instanceof Map) { Map<String, Object> child = new HashMap<>(); mapOut.put(entry.getKey(), child); queueIn.addLast((Map<String, Object>) entry.getValue()); queueOut.addLast(child); } else if (entry.getValue() instanceof String) { String value = (String) entry.getValue(); value = value.trim(); if(value.startsWith("@")) { switch (value) { case _FIRST: subsume(mapOut, params.get(0), entry.getKey()); break; case _LAST: subsume(mapOut, params.get(params.size() - 1), entry.getKey()); break; case _APPEND: mapOut.put(entry.getKey(), append(params, entry.getKey())); break; default: processNumberParam(mapOut, entry.getKey(), value, params); break; } } } } } return Collections.singletonList(result); }; }
SemanticUtils { public static SemanticFunction parseTemplate(Map<String, Object> template){ return params -> { Map<String, Object> result = new HashMap<>(); LinkedList<Map<String, Object>> queueIn = new LinkedList<>(); LinkedList<Map<String, Object>> queueOut = new LinkedList<>(); queueIn.addLast(template); queueOut.addLast(result); while (!queueIn.isEmpty()) { final Map<String, Object> mapIn = queueIn.removeFirst(); final Map<String, Object> mapOut = queueOut.removeFirst(); for (Map.Entry<String, Object> entry : mapIn.entrySet()) { mapOut.put(entry.getKey(), entry.getValue()); if(entry.getKey().equals(_MERGE)) { if(entry.getValue() instanceof List){ List<Number> indices = (List<Number>)entry.getValue(); for(Number index: indices){ mapOut.putAll(params.get(index.intValue())); } } mapOut.remove(_MERGE); } else if (entry.getValue() instanceof Map) { Map<String, Object> child = new HashMap<>(); mapOut.put(entry.getKey(), child); queueIn.addLast((Map<String, Object>) entry.getValue()); queueOut.addLast(child); } else if (entry.getValue() instanceof String) { String value = (String) entry.getValue(); value = value.trim(); if(value.startsWith("@")) { switch (value) { case _FIRST: subsume(mapOut, params.get(0), entry.getKey()); break; case _LAST: subsume(mapOut, params.get(params.size() - 1), entry.getKey()); break; case _APPEND: mapOut.put(entry.getKey(), append(params, entry.getKey())); break; default: processNumberParam(mapOut, entry.getKey(), value, params); break; } } } } } return Collections.singletonList(result); }; } }
SemanticUtils { public static SemanticFunction parseTemplate(Map<String, Object> template){ return params -> { Map<String, Object> result = new HashMap<>(); LinkedList<Map<String, Object>> queueIn = new LinkedList<>(); LinkedList<Map<String, Object>> queueOut = new LinkedList<>(); queueIn.addLast(template); queueOut.addLast(result); while (!queueIn.isEmpty()) { final Map<String, Object> mapIn = queueIn.removeFirst(); final Map<String, Object> mapOut = queueOut.removeFirst(); for (Map.Entry<String, Object> entry : mapIn.entrySet()) { mapOut.put(entry.getKey(), entry.getValue()); if(entry.getKey().equals(_MERGE)) { if(entry.getValue() instanceof List){ List<Number> indices = (List<Number>)entry.getValue(); for(Number index: indices){ mapOut.putAll(params.get(index.intValue())); } } mapOut.remove(_MERGE); } else if (entry.getValue() instanceof Map) { Map<String, Object> child = new HashMap<>(); mapOut.put(entry.getKey(), child); queueIn.addLast((Map<String, Object>) entry.getValue()); queueOut.addLast(child); } else if (entry.getValue() instanceof String) { String value = (String) entry.getValue(); value = value.trim(); if(value.startsWith("@")) { switch (value) { case _FIRST: subsume(mapOut, params.get(0), entry.getKey()); break; case _LAST: subsume(mapOut, params.get(params.size() - 1), entry.getKey()); break; case _APPEND: mapOut.put(entry.getKey(), append(params, entry.getKey())); break; default: processNumberParam(mapOut, entry.getKey(), value, params); break; } } } } } return Collections.singletonList(result); }; }  }
SemanticUtils { public static SemanticFunction parseTemplate(Map<String, Object> template){ return params -> { Map<String, Object> result = new HashMap<>(); LinkedList<Map<String, Object>> queueIn = new LinkedList<>(); LinkedList<Map<String, Object>> queueOut = new LinkedList<>(); queueIn.addLast(template); queueOut.addLast(result); while (!queueIn.isEmpty()) { final Map<String, Object> mapIn = queueIn.removeFirst(); final Map<String, Object> mapOut = queueOut.removeFirst(); for (Map.Entry<String, Object> entry : mapIn.entrySet()) { mapOut.put(entry.getKey(), entry.getValue()); if(entry.getKey().equals(_MERGE)) { if(entry.getValue() instanceof List){ List<Number> indices = (List<Number>)entry.getValue(); for(Number index: indices){ mapOut.putAll(params.get(index.intValue())); } } mapOut.remove(_MERGE); } else if (entry.getValue() instanceof Map) { Map<String, Object> child = new HashMap<>(); mapOut.put(entry.getKey(), child); queueIn.addLast((Map<String, Object>) entry.getValue()); queueOut.addLast(child); } else if (entry.getValue() instanceof String) { String value = (String) entry.getValue(); value = value.trim(); if(value.startsWith("@")) { switch (value) { case _FIRST: subsume(mapOut, params.get(0), entry.getKey()); break; case _LAST: subsume(mapOut, params.get(params.size() - 1), entry.getKey()); break; case _APPEND: mapOut.put(entry.getKey(), append(params, entry.getKey())); break; default: processNumberParam(mapOut, entry.getKey(), value, params); break; } } } } } return Collections.singletonList(result); }; }  static String _N(int item); static String _N_LONG(int item); static String _N_DOUBLE(int item); static ChainMap<String, Object> named(String name, Object value); static ChainMap<String, Object> value(Object value); static SemanticFunction valueFn(Object value); static List<Map<String, Object>> identity(List<Map<String, Object>> params); static List<Map<String, Object>> merge(List<Map<String, Object>> params); static List<Map<String, Object>> first(List<Map<String, Object>> params); static List<Map<String, Object>> last(List<Map<String, Object>> params); static SemanticFunction parseSemantics(String semantics); static SemanticFunction parseTemplate(Map<String, Object> template); }
SemanticUtils { public static SemanticFunction parseTemplate(Map<String, Object> template){ return params -> { Map<String, Object> result = new HashMap<>(); LinkedList<Map<String, Object>> queueIn = new LinkedList<>(); LinkedList<Map<String, Object>> queueOut = new LinkedList<>(); queueIn.addLast(template); queueOut.addLast(result); while (!queueIn.isEmpty()) { final Map<String, Object> mapIn = queueIn.removeFirst(); final Map<String, Object> mapOut = queueOut.removeFirst(); for (Map.Entry<String, Object> entry : mapIn.entrySet()) { mapOut.put(entry.getKey(), entry.getValue()); if(entry.getKey().equals(_MERGE)) { if(entry.getValue() instanceof List){ List<Number> indices = (List<Number>)entry.getValue(); for(Number index: indices){ mapOut.putAll(params.get(index.intValue())); } } mapOut.remove(_MERGE); } else if (entry.getValue() instanceof Map) { Map<String, Object> child = new HashMap<>(); mapOut.put(entry.getKey(), child); queueIn.addLast((Map<String, Object>) entry.getValue()); queueOut.addLast(child); } else if (entry.getValue() instanceof String) { String value = (String) entry.getValue(); value = value.trim(); if(value.startsWith("@")) { switch (value) { case _FIRST: subsume(mapOut, params.get(0), entry.getKey()); break; case _LAST: subsume(mapOut, params.get(params.size() - 1), entry.getKey()); break; case _APPEND: mapOut.put(entry.getKey(), append(params, entry.getKey())); break; default: processNumberParam(mapOut, entry.getKey(), value, params); break; } } } } } return Collections.singletonList(result); }; }  static String _N(int item); static String _N_LONG(int item); static String _N_DOUBLE(int item); static ChainMap<String, Object> named(String name, Object value); static ChainMap<String, Object> value(Object value); static SemanticFunction valueFn(Object value); static List<Map<String, Object>> identity(List<Map<String, Object>> params); static List<Map<String, Object>> merge(List<Map<String, Object>> params); static List<Map<String, Object>> first(List<Map<String, Object>> params); static List<Map<String, Object>> last(List<Map<String, Object>> params); static SemanticFunction parseSemantics(String semantics); static SemanticFunction parseTemplate(Map<String, Object> template); final static String _IDENTITY; final static String _FIRST; final static String _LAST; final static String _MERGE; final static String _APPEND; final static String KEY_UNNAMED; }