View Javadoc

1   package org.apache.torque.generator.control.existingtargetstrategy;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.io.File;
23  import java.io.IOException;
24  
25  import org.apache.commons.io.FileUtils;
26  import org.apache.commons.io.FilenameUtils;
27  import org.apache.commons.logging.Log;
28  import org.apache.commons.logging.LogFactory;
29  import org.apache.torque.generator.GeneratorException;
30  import org.apache.torque.generator.configuration.UnitConfiguration;
31  import org.apache.torque.generator.control.ControllerException;
32  import org.apache.torque.generator.control.ControllerHelper;
33  import org.apache.torque.generator.merge.ThreeWayMerger;
34  import org.apache.torque.generator.outlet.OutletResult;
35  
36  /**
37   * A handler which implements the strategy to replace existing target files.
38   *
39   * @version $Id: MergeTargetFileStrategy.java 1368426 2012-08-02 11:46:37Z tfischer $
40   */
41  public class MergeTargetFileStrategy implements ExistingTargetStrategy
42  {
43      /** The strategy name "replace". */
44      public static final String STRATEGY_NAME = "merge";
45  
46      /** The subdirectory in the work directory<. */
47      public static final String WORK_SUBDIR = "raw-generated";
48  
49      /** The classlogger. */
50      private static Log log = LogFactory.getLog(MergeTargetFileStrategy.class);
51  
52      /** The merger. */
53      private final ThreeWayMerger merger = new ThreeWayMerger();
54  
55      /**
56       * Will be called before the generation is started and decides whether
57       * the generation process for this file should proceed.
58       *
59       * @param outputDirKey the key for the output directory
60       *        into which the generated file should be written,
61       *        null for the default output directory.
62       * @param outputPath the path to which the output should be written,
63       *        relative to the output base directory.
64       * @param encoding The character encoding of the generated file,
65       *        or null for the platform default encoding.
66       * @param unitConfiguration the configuration of the current configuration
67       *        unit, not null.
68       *
69       * @return true always.
70       */
71      public boolean beforeGeneration(
72              String outputDirKey,
73              String outputPath,
74              String encoding,
75              UnitConfiguration unitConfiguration)
76      {
77          return true;
78      }
79  
80      /**
81       * Processes the results of the generation.
82       *
83       * @param outputDirKey the key for the output directory
84       *        into which the generated file should be written,
85       *        null for the default output directory.
86       * @param outputFile the location to which the output should be written.
87       * @param encoding The character encoding of the generated file,
88       *        or null for the platform default encoding.
89       * @param generationResult the result of the generation, not null.
90       * @param unitConfiguration the configuration of the current configuration
91       *        unit, not null.
92       * @throws GeneratorException on an error.
93       */
94      public void afterGeneration(
95                  String outputDirKey,
96                  String outputPath,
97                  String encoding,
98                  OutletResult generationResult,
99                  UnitConfiguration unitConfiguration)
100             throws GeneratorException
101     {
102         File generationStorageDir
103                 = new File(unitConfiguration.getWorkDirectory(), WORK_SUBDIR);
104         File generationStorageFile;
105         if (outputDirKey == null)
106         {
107             generationStorageFile
108                     = new File(generationStorageDir,
109                             FilenameUtils.concat("default", outputPath));
110         }
111         else
112         {
113             generationStorageFile
114                     = new File(generationStorageDir,
115                         FilenameUtils.concat("other",
116                             FilenameUtils.concat(outputDirKey, outputPath)));
117         }
118         String oldGenerationContent = readFileToString(
119                 generationStorageFile,
120                 encoding);
121 
122         File targetFile = ControllerHelper.getOutputFile(
123                 outputDirKey,
124                 outputPath,
125                 unitConfiguration);
126         String oldTargetContent = readFileToString(
127                 targetFile,
128                 encoding);
129 
130         if (!generationResult.isStringResult())
131         {
132             throw new GeneratorException(
133                     "The merge target file strategy onlys works"
134                     + " for String generation results (target file="
135                     + targetFile.getAbsolutePath() + ")");
136         }
137 
138         String newTargetContent = null;
139         if (oldTargetContent == null)
140         {
141             log.debug("no old target content found, using generation result");
142             newTargetContent = generationResult.getStringResult();
143         }
144         else if (oldGenerationContent == null)
145         {
146             log.info("no old generation content found,"
147                     + "using old target content."
148                     + " This is a bit unusual, but may be ok"
149                     + " depending on the circumstances");
150             newTargetContent = generationResult.getStringResult();
151         }
152         else
153         {
154             log.debug("merging generation result and old target content");
155             newTargetContent = merger.merge(
156                     oldGenerationContent,
157                     generationResult.getStringResult(),
158                     oldTargetContent,
159                     encoding);
160         }
161         writeStringToFile(targetFile, newTargetContent, encoding);
162         writeStringToFile(
163                 generationStorageFile,
164                 generationResult.getStringResult(),
165                 encoding);
166     }
167 
168     /**
169      * Returns the name of the existing target strategy.
170      *
171      * @return "merge"
172      */
173     public String getStrategyName()
174     {
175         return STRATEGY_NAME;
176     }
177 
178     /**
179      * Reads a String to a file.
180      *
181      * @param file the file to read, not null.
182      * @param charset the character set to use for reading the file,
183      *        or null for platform default.
184      * @return the file's contents, or null if the file does not exist.
185      *
186      * @throws ControllerException if an error occurs while reading the file.
187      */
188     private String readFileToString(
189                 File file,
190                 String charset)
191             throws ControllerException
192     {
193         String result = null;
194         if (file.exists())
195         {
196             try
197             {
198                 result = FileUtils.readFileToString(
199                         file,
200                         charset);
201             }
202             catch (IOException e)
203             {
204                 throw new ControllerException(
205                         "Could not read file \""
206                             + file.getAbsolutePath()
207                             + "\"",
208                         e);
209             }
210         }
211         return result;
212     }
213 
214     /**
215      * Writes a String to a file.
216      *
217      * @param file the location to write to, not null.
218      * @param content the content of the file, not null.
219      * @param charset the character set to use for writing the file,
220      *        or null for platform default.
221      *
222      * @throws ControllerException if writing the file fails.
223      */
224     private void writeStringToFile(
225                 File file,
226                 String content,
227                 String charset)
228             throws ControllerException
229     {
230         try
231         {
232             FileUtils.writeStringToFile(file, content, charset);
233         }
234         catch (IOException e)
235         {
236             throw new ControllerException(
237                     "Could not write file \""
238                         + file.getAbsolutePath()
239                         + "\"",
240                     e);
241         }
242     }
243 }