<?xml version="1.0" encoding="UTF-8"?>
<!--
 Licensed to the Apache Software Foundation (ASF) under one
 or more contributor license agreements.  See the NOTICE file
 distributed with this work for additional information
 regarding copyright ownership.  The ASF licenses this file
 to you under the Apache License, Version 2.0 (the
 "License"); you may not use this file except in compliance
 with the License.  You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing,
 software distributed under the License is distributed on an
 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 KIND, either express or implied.  See the License for the
 specific language governing permissions and limitations
 under the License.
-->

<document>

 <properties>
  <title>Existing Target Modes</title>
 </properties>

 <body>
  <section name="Existing Target Modes">
    <p>
      This page explains the possible modes to handle existing target files.
      If the generator encounters a file to be generated which already exists,
      it can be instructed to treat it the following ways:
      <ul>
        <li>
          <code>replace</code> (default): 
          The existing file is replaced by the newly generated file.
        </li>
        <li>
          <code>skip</code>: Generation is skipped, the existing file is left
          as is.
        </li>
        <li>
          <code>append</code>: The generation result is appended to the
          content of the existing file.
        </li>
        <li>
          <code>merge</code>: The generation result merged with the
          content of the existing file.
        </li>
      </ul>
      The replace mode is suitable when the target file is not intended to be
      edited.<br/>
      The skip mode is suitable when a starting point for a file should be
      generated, which can then subsequently be edited by the user.<br/>
      The append mode can be useful for generating log files and similar.<br/>
      The merge mode is suitable when a file should be generated
      which content can then either be changed by the user and the generator.
      <br/>
    </p>
  </section>
  <section name="Allow user to change generated code">
    <p>
      Three of the modes above allows the user to change generated files:
      skip, append and merge. From those, append is unlikely to appear in code
      generation so it will not be considered further. The two other modes, 
      skip and merge, have different merits in user-generator interaction. 
    </p>
    <p>
      The mode <code>skip</code> should be used if the generated file is just a starting
      point, or if the generation result is very unlikely to change,
      e.g. if the code templates are believed to have all needed features
      and the sources are unlikely to change.<br/>
      It is a strategy which is simple to understand and use, so if a problem
      can be solved by both the <code>skip</code> mode and the <code>merge</code>  mode, 
      the skip mode should be used. 
    </p>
    <p>
      The mode <code>merge</code> should be used if the generated code is not stable yet
      (e.g. because the generator lacks features, or the source is likely
      to change in such a way that the contents of a generated file is changed),
      and it is likely that user interaction is needed in the generated files.
      <br/>
      Even if the above is the case, it may be better to separate generated 
      content and user-written content by using a delegation or inheritance
      strategy (e.g. see the inheritance strategy in the Torque templates).
      Delegation or inheritance will usually work if the user changes
      involve changing whole methods; it will not work if changes involve only
      parts of methods and these parts cannot (or should not) be factored out.
      The reasons for trying to avoud merging are:
      <ul>
        <li>Merging is complicated to understand.</li>
        <li>Merging is complicated to use.</li>
      </ul>
      That said, there are situations where merging saves a lot of pain,
      so it should be considered whenever generated and user-written code
      are very interwoven.
    </p>
    <subsection name="Merge Mode">
      <p>
        The <code>merge</code> mode works as follows:
        If a file is generated which existingTargetStrategy is
        <code>merge</code>is generated, the generator will store the generated 
        code in two files: one file being the nominal target, and the other
        file is stored in another directory tree 
        (e.g. src/unmerged-gen-output/).
        Once this has happened, the user can change the generated file
        (all changes should be in the nominal target file, the file in 
        src/unmerged-gen-output/ should _NOT_ be edited),
        Also changes can be made to the generator.<br/>
        As an example, let us assume that in the second generator run,
        both the file which was generated in the first generator run
        and the generation result have changed.
        The generator will now produce the generation output in memory
        and will compare 
        a) the src/unmerged-gen-output file with the new generation result and
        b) the src/unmerged-gen-output file with the nominal target file.
        This way the generator can determine which changes were made
        in the generator output and which changes were made by the user.
        Then, the generator will perform a three-way-merge with the two 
        changesets and overwrite the nominal target file with the results
        of the merge and the src/unmerged-gen-output file with the raw
        (unmerged) generation result.
        In the case that conflicts appear in the merge,
        the merger will produce the usual &lt; and &gt; marked sections
        with both the conflicting inputs.<br/>
        Of course, other generation runs can follow, with either the user
        editing the generated file, wit changed generation output, or both.
      </p>
      <p>
        There are a couple of things to consider when operating in merge mode:
        <ul>
          <li>
            Conflicts should be resolved before attempting a new generation
            run. Otherwise, the &lt; and &gt; marked sections will probably
            produce more conflicts, eventually ending in &lt; and &gt;
            merge hell.
          </li>
          <li>
            When several copies of the project exist where the generation 
            is run, the unmerged files 
            (in src/unmerged-gen-output in the above example)
            should also be shared between the copies
            (this usually implies that they are checked in version control).
            Otherwise, the three-way-merge can produce strage results
            because the merge basis is different in different copies.
          </li>
          <li>
            If the unmerged files 
            (in src/unmerged-gen-output in the above example)
            are checked into version control, care should be taken to always
            check in the nominal target files and the src/unmerged-gen-output
            files in the same commit; otherwise different people may
            use a different merge basis which can produce a different merge
            result. 
          </li>
        </ul>
      </p>
    </subsection>
  </section>
 </body>
</document>