private static void join ( ArrayList < AbstractConfigValue > builder , AbstractConfigValue origRight ) { AbstractConfigValue left = builder . get ( builder . size ( ) - 1 ) ; AbstractConfigValue right = origRight ; // check for an object which can be converted to a list // (this will be an object with numeric keys, like foo.0, foo.1) if ( left instanceof ConfigObject && right instanceof SimpleConfigList ) { left = DefaultTransformer . transform ( left , ConfigValueType . LIST ) ; } else if ( left instanceof SimpleConfigList && right instanceof ConfigObject ) { right = DefaultTransformer . transform ( right , ConfigValueType . LIST ) ; } // Since this depends on the type of two instances, I couldn't think // of much alternative to an instanceof chain. Visitors are sometimes // used for multiple dispatch but seems like overkill. AbstractConfigValue joined = null ; if ( left instanceof ConfigObject && right instanceof ConfigObject ) { joined = right . withFallback ( left ) ; } else if ( left instanceof SimpleConfigList && right instanceof SimpleConfigList ) { joined = ( ( SimpleConfigList ) left ) . concatenate ( ( SimpleConfigList ) right ) ; } else if ( left instanceof ConfigConcatenation || right instanceof ConfigConcatenation ) { throw new BugOrBroken ( "unflattened ConfigConcatenation" ) ; } else if ( left instanceof Unmergeable || right instanceof Unmergeable ) { // leave joined=null, cannot join } else { // handle primitive type or primitive type mixed with object or list String s1 = left . transformToString ( ) ; String s2 = right . transformToString ( ) ; if ( s1 == null || s2 == null ) { throw new WrongType ( left . origin ( ) , "Cannot concatenate object or list with a non-object-or-list, " + left + " and " + right + " are not compatible" ) ; } else { ConfigOrigin joinedOrigin = SimpleConfigOrigin . mergeOrigins ( left . origin ( ) , right . origin ( ) ) ; joined = new ConfigString ( joinedOrigin , s1 + s2 ) ; } } if ( joined == null ) { builder . add ( right ) ; } else { builder . remove ( builder . size ( ) - 1 ) ; builder . add ( joined ) ; } }
Add left and right or their merger to builder .