package org.webpieces.router.impl.params; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; public class ParamValueTreeCreator { //A Map comes in like this (key on left and value on right) // user.name = dean // user.accounts[2].accName = this // user.accounts[2].priority = 1 // user.accounts[2].addresses[0].street = MyStreet // user.accounts[2].roles[0] = 'admin' // user.accounts[2].roles[1] = 'manager' // user.account.company.address = xxxx // user.account.company.name = yyy // user.account.name = zzz // user.name = dean // color = blue // user.account = 111 should blow up public void createTree(ParamTreeNode paramTree, Map<String, String> params, FromEnum from) { List<String> listSubKeys = null; try { for(Map.Entry<String, String> entry : params.entrySet()) { String key = entry.getKey(); String[] subKeys = key.split("\\."); if(subKeys.length == 0) { listSubKeys = new ArrayList<>(Arrays.asList(entry.getKey())); } else { listSubKeys = new ArrayList<>(Arrays.asList(subKeys)); } createTree(paramTree, listSubKeys, entry.getValue(), key, from); } } catch (RuntimeException e) { throw new RuntimeException("Something bad happened with key list="+listSubKeys, e); } } private void createTree(ParamTreeNode trees, List<String> asList, String value, String fullKeyName, FromEnum from) { if(asList.size() == 0) return; String firstKey = asList.remove(0); if(firstKey.contains("[")) { createArray(trees, asList, value, fullKeyName, from, firstKey); return; } ParamNode node = trees.get(firstKey); if(node != null) { if(!(node instanceof ParamTreeNode)) throw new IllegalStateException("Bug, something went wrong with key="+firstKey); else if(asList.size() == 0) throw new IllegalArgumentException("Bug, not enough subkeys...conflict in param list like user.account.id=5 " + "and user.account=99 which is not allowed(since user.account would be an object so we can't set it to 99)"); ParamTreeNode tree = (ParamTreeNode) node; createTree(tree, asList, value, fullKeyName, from); return; } else if(asList.size() == 0) { ValueNode vNode = new ValueNode(value, fullKeyName, from); trees.put(firstKey, vNode); return; } ParamTreeNode p = new ParamTreeNode(); trees.put(firstKey, p); createTree(p, asList, value, fullKeyName, from); } private void createArray(ParamTreeNode trees, List<String> asList, String value, String fullKeyName, FromEnum from, String firstKey) { int indexOf = firstKey.indexOf("["); int nextIndex = firstKey.indexOf("]"); String key = firstKey.substring(0, indexOf); String number = firstKey.substring(indexOf+1, nextIndex); int arrayIndex = Integer.parseInt(number); ArrayNode n; ParamNode paramNode = trees.get(key); if(paramNode != null) { if(!(paramNode instanceof ArrayNode)) throw new IllegalStateException("Encountered name="+fullKeyName+" but there was another key being posted that conflicts as the original one wasn't an array"); n = (ArrayNode) paramNode; } else { n = new ArrayNode(); trees.put(key, n); } if(asList.size() > 0) { //complex bean ParamTreeNode treeNode = n.setOrGetTree(arrayIndex); createTree(treeNode, asList, value, fullKeyName, from); } else { //primitive String, int, etc. n.setElement(arrayIndex, new ValueNode(value, fullKeyName, from)); } } }