// grab the group name for the map, and create the compound node
// that holds the map entries of the map as child nodes, and add it
// to the parent node
final String group = getGroupName( keyValues.get( 0 ).getFirst() );
final InfoNode mapNode = InfoNode.createCompoundNode( null, group, null );
parentNode.addChild( mapNode );
// construct the patterns to determine if the node should be a compound node,
// in which case we recurse back to the builder, or a leaf node, in which case
// we simply create it here and add it to the collection node
final String compoundRegex = "^" + group + decorationRegex;
final Pattern compoundPattern = Pattern.compile( compoundRegex );
final String leafRegex = compoundRegex + "$";
final Pattern leafPattern = Pattern.compile( leafRegex );
// we want to have groups by the map key. the map key is the map key in the key-value pair that.
// for example, in friends{"Polly"}, the map key is "Polly" (including the quotes). then we
// can parse each group into its proper node.
final Map< String, List< Pair< String, String > > > mapKeyGroups = getMapKeyGroups( keyValues );
for( Map.Entry< String, List< Pair< String, String > > > entry : mapKeyGroups.entrySet() )
{
// for each group, i.e. each key, we need a map entry node attached to the map node.
final InfoNode mapEntryNode = InfoNode.createCompoundNode( null, mapEntryName, null );
mapNode.addChild( mapEntryNode );
// grab the map key and the list of key-values associated with that map key
final String mapKey = entry.getKey();
// run through the list of key-values creating the child nodes for the map-entry node
final List< Pair< String, String > > keyValueGroup = entry.getValue();
final List< Pair< String, String > > copiedKeyValues = new ArrayList<>( keyValueGroup );
for( Pair< String, String > keyValue : keyValueGroup )
{
// check to see if any items have been removed from the list. this could happen
// when there is a compound node that we have combined, and removed all the entries
// from this list
if( !copiedKeyValues.contains( keyValue ) )
{
continue;
}
// grab the key
final String key = keyValue.getFirst();
// we must figure out whether this is a compound node or a leaf node
final Matcher compoundMatcher = compoundPattern.matcher( key );
final Matcher leafMatcher = leafPattern.matcher( key );
if( leafMatcher.find() )
{
// its a leaf, create the key node
final String rawMapKey = getDecorator( mapKey ).undecorate( mapKey );
final InfoNode keyNode = InfoNode.createLeafNode( null, rawMapKey, mapKeyName, null );
mapEntryNode.addChild( keyNode );
// so now we need to figure out what the value is. we know that
// it must be a number (integer, double) or a string.
final String value = keyValue.getSecond();
final String rawValue = getDecorator( value ).undecorate( value );
// create the leaf info node and add it to the collection node
final InfoNode valueNode = InfoNode.createLeafNode( null, rawValue, mapValueName, null );
mapEntryNode.addChild( valueNode );
}
else if( compoundMatcher.find() )
{
// its a compound node, create the key node
final String rawMapKey = getDecorator( mapKey ).undecorate( mapKey );
final InfoNode keyNode = InfoNode.createLeafNode( null, rawMapKey, mapKeyName, null );
mapEntryNode.addChild( keyNode );
// in this case, we'll have several entries that have the same index, so
// we'll need to pull those out and put them into a new key-value list
final String separator = getPersistenceBuilder().getSeparator();