public String merge (String newlyGenerated, String previouslyGenerated)
        throws Exception
    {
        // Extract the generated section names from the output and make sure they're all matched
        Map<String, Section> sections = Maps.newLinkedHashMap();
        Matcher m = _sectionDelimiter.matcher(newlyGenerated);
        while (m.find()) {
            Section section = extractGeneratedSection(m, newlyGenerated);
            Preconditions.checkArgument(!sections.containsKey(section.name),
                "Section '%s' used more than once", section.name);
            sections.put(section.name, section);
        }

        // Merge with the previously generated source
        StringBuilder merged = new StringBuilder();
        m = _sectionDelimiter.matcher(previouslyGenerated);
        int currentStart = 0;
        while (m.find()) {
            merged.append(previouslyGenerated.substring(currentStart, m.start()));
            Section existingSection = extractGeneratedSection(m, previouslyGenerated);
            Section newSection = sections.remove(existingSection.name);
            if (newSection == null) {
                // Allow generated sections to be dropped in the template, but warn in case
                // something odd's happening
                System.err.println("Dropping previously generated section '" + m.group(1)
                    + "' that's no longer generated by the template");
            } else  if (existingSection.disabled) {
                // If the existing code disables this generation, add that disabled comment
                merged.append(existingSection.contents);
            } else {
                // Otherwise pop in the newly generated code in the place of what was there before
                merged.append(newSection.contents);
            }
            currentStart = m.end();
        }
        // Add generated sections that weren't present in the old output before the last
        // non-generated code.  It's a 50-50 shot, so warn when this happens
        for (Section newSection : sections.values()) {
            System.err.println("Adding previously missing generated section '"
                + newSection.name + "' before the last non-generated text");
            merged.append(newSection.contents);
        }
        // Add any text past the last previously generated section
        merged.append(previouslyGenerated.substring(currentStart));

        return merged.toString();
    }
public String merge ( String newlyGenerated , String previouslyGenerated ) throws Exception { Map < String , Section > sections = Maps . newLinkedHashMap ( ) ; Matcher m = _sectionDelimiter . matcher ( newlyGenerated ) ; while ( m . find ( ) ) { Section section = extractGeneratedSection ( m , newlyGenerated ) ; Preconditions . checkArgument ( ! sections . containsKey ( section . name ) , "Section '%s' used more than once" , section . name ) ; sections . put ( section . name , section ) ; } StringBuilder merged = new StringBuilder ( ) ; m = _sectionDelimiter . matcher ( previouslyGenerated ) ; int currentStart = 0 ; while ( m . find ( ) ) { merged . append ( previouslyGenerated . substring ( currentStart , m . start ( ) ) ) ; Section existingSection = extractGeneratedSection ( m , previouslyGenerated ) ; Section newSection = sections . remove ( existingSection . name ) ; if ( newSection == null ) { System . err . println ( "Dropping previously generated section '" + m . group ( 1 ) + "' that's no longer generated by the template" ) ; } else if ( existingSection . disabled ) { merged . append ( existingSection . contents ) ; } else { merged . append ( newSection . contents ) ; } currentStart = m . end ( ) ; } for ( Section newSection : sections . values ( ) ) { System . err . println ( "Adding previously missing generated section '" + newSection . name + "' before the last non-generated text" ) ; merged . append ( newSection . contents ) ; } merged . append ( previouslyGenerated . substring ( currentStart ) ) ; return merged . toString ( ) ; }
Returns <code>previouslyGenerated</code> with marked sections updated from the same marked
sections in <code>newlyGenerated</code>. Everything outside these sections in
<code>previouslyGenerated</code> is returned as is. A marked section starts with <code>//
GENERATED {name} START</code> and ends with <code>// GENERATED {name} END</code><p>

If <code>previouslyGenerated</code> has a generated section replaced with <code>//
GENERATED {name} DISABLED</code>, that section will no longer be updated.