View Javadoc

1   /***
2    * 
3    */
4   package atg.test.util;
5   
6   import java.io.BufferedReader;
7   import java.io.BufferedWriter;
8   import java.io.File;
9   import java.io.FileInputStream;
10  import java.io.FileOutputStream;
11  import java.io.FileReader;
12  import java.io.FileWriter;
13  import java.io.IOException;
14  import java.io.ObjectInputStream;
15  import java.io.ObjectOutput;
16  import java.io.ObjectOutputStream;
17  import java.nio.channels.FileChannel;
18  import java.util.HashMap;
19  import java.util.Iterator;
20  import java.util.List;
21  import java.util.Map;
22  import java.util.Map.Entry;
23  
24  import org.apache.log4j.Logger;
25  
26  import atg.applauncher.core.util.JarUtils;
27  
28  
29  
30  /***
31   * A collection of utility methods for dealing with the filesystem.
32   * @author robert
33   * 
34   */
35  @SuppressWarnings("unchecked")
36  public class FileUtil {
37  
38    private static Logger log = Logger.getLogger(FileUtil.class);
39  
40    private static boolean isDirty = false;;
41  
42    private static Map<String, Long> CONFIG_FILES_TIMESTAMPS,
43        CONFIG_FILES_GLOBAL_FORCE;
44  
45    /***
46     * 
47     * @param srcDir
48     * @param dstDir
49     * @param excludes
50     * @throws IOException
51     */
52    public static void copyDirectory(String srcDir, String dstDir,
53        final List<String> excludes) throws IOException {
54      if (new File(srcDir).exists()) {
55        new File(dstDir).mkdirs();
56        for (final String file : new File(srcDir).list()) {
57          final String source = srcDir + File.separator + file, destination = dstDir
58              + File.separator + file;
59          boolean dir = new File(source).isDirectory();
60          if (dir && !excludes.contains(file)) {
61            copyDirectory(source, destination, excludes);
62          }
63          else {
64            if (!excludes.contains(file)) {
65              copyFile(source, destination);
66            }
67          }
68        }
69      }
70    }
71  
72    /***
73     * 
74     * @param src
75     * @param dst
76     * @throws IOException
77     */
78    public static void copyFile(final String src, final String dst)
79        throws IOException {
80      final File srcFile = new File(src);
81      final File dstFile = new File(dst);
82  
83      if (CONFIG_FILES_TIMESTAMPS != null
84          && CONFIG_FILES_TIMESTAMPS.get(src) != null
85          && CONFIG_FILES_TIMESTAMPS.get(src) == srcFile.lastModified()
86          && dstFile.exists()) {
87        if (log.isDebugEnabled()) {
88          log.debug(String
89              .format(
90                  "%s last modified hasn't changed and destination still exists",
91                  src));
92        }
93      }
94      else {
95        if (log.isDebugEnabled()) {
96          log.debug(String.format("Copy: src file %s ts %s : ", src, srcFile
97              .lastModified()));
98          log.debug(String.format("Copy: dest file %s ts %s : ", dst, dstFile
99              .lastModified()));
100       }
101 
102       final FileChannel srcChannel = new FileInputStream(src).getChannel();
103       final FileChannel dstChannel = new FileOutputStream(dst).getChannel();
104       dstChannel.transferFrom(srcChannel, 0, srcChannel.size());
105       dstChannel.close();
106       srcChannel.close();
107     }
108 
109   }
110 
111   /***
112    * 
113    * @param componentName
114    *          The name of the nucleus component
115    * @param configurationStagingLocation
116    *          A valid not <code>null</code> directory.
117    * @param clazz
118    *          The class implementing the nucleus component
119    * @param settings
120    *          An implementation of {@link Map} containing all needed properties
121    *          the component is depended on (eg key = username, value = test).
122    *          Can be <code>null</code> or empty.
123    * @throws IOException
124    */
125   public static void createPropertyFile(final String componentName,
126       final File configurationStagingLocation, final Class<?> clazz,
127       final Map<String, String> settings) throws IOException {
128 
129     configurationStagingLocation.mkdirs();
130     final File propertyFile = new File(configurationStagingLocation,
131         componentName.replace("/", File.separator) + ".properties");
132     new File(propertyFile.getParent()).mkdirs();
133     propertyFile.createNewFile();
134     final BufferedWriter out = new BufferedWriter(new FileWriter(propertyFile));
135 
136     try {
137       if (clazz != null) {
138         out.write("$class=" + clazz.getName());
139         out.newLine();
140       }
141       if (settings != null) {
142         for (final Iterator<Entry<String, String>> it = settings.entrySet()
143             .iterator(); it.hasNext();) {
144           final Entry<String, String> entry = it.next();
145           out.write(new StringBuilder(entry.getKey()).append("=").append(
146               entry.getValue()).toString());
147           out.newLine();
148         }
149       }
150     }
151     finally {
152       out.close();
153     }
154   }
155 
156   public static final String COULD_NOT_DELETE_TEMP_DIRECTORY = "Couldn't delete temp directory. ";
157 
158   public void searchAndReplace(final String originalValue,
159       final String newValue, final File file) throws IOException {
160     
161     final File TMP_FILE = new File(System
162         .getProperty("java.io.tmpdir")
163         + File.separator + System.currentTimeMillis()+this+"-atg-dust-rh.tmp");
164     TMP_FILE.deleteOnExit();
165 
166     if (CONFIG_FILES_GLOBAL_FORCE != null
167         && CONFIG_FILES_GLOBAL_FORCE.get(file.getPath()) != null
168         && CONFIG_FILES_GLOBAL_FORCE.get(file.getPath()) == file.lastModified()
169         && file.exists()) {
170       isDirty = false;
171       if (log.isDebugEnabled()) {
172         log.debug(String.format(
173             "%s last modified hasn't changed and file still exists, no need for global scope force",
174             file.getPath()));
175       }
176     }
177     else {
178       final BufferedWriter out = new BufferedWriter(new FileWriter(TMP_FILE));
179       final BufferedReader in = new BufferedReader(new FileReader(file));
180       String str;
181       while ((str = in.readLine()) != null) {
182         if (str.contains(originalValue)) {
183           out.write(newValue);
184         }
185         else {
186           out.write(str);
187           out.newLine();
188         }
189       }
190       out.close();
191       in.close();
192       JarUtils.copy(TMP_FILE, file, true, false);
193       CONFIG_FILES_GLOBAL_FORCE.put(file.getPath(), file.lastModified());
194       isDirty = true;
195     }
196 
197   }
198 
199   /***
200    * Deletes the given directory when the JVM exits.
201    * This method does so by implementing a shutdown hook.
202    * @param tmpDir
203    */
204   public static void deleteDirectoryOnShutdown(final File tmpDir) {
205     Runtime.getRuntime().addShutdownHook(new Thread() {
206       public void run() {
207         try {
208           atg.core.io.FileUtils.deleteDir(tmpDir.getAbsolutePath());
209         } catch (IOException e) {
210           log.error(FileUtil.COULD_NOT_DELETE_TEMP_DIRECTORY, e);
211         }
212       }
213     });
214   }
215 
216   public static void serialize(final File file, final Object o)
217       throws IOException {
218 
219     ObjectOutput out = null;
220     try {
221       out = new ObjectOutputStream(new FileOutputStream(file));
222       out.writeObject(o);
223     }
224     finally {
225       if (out != null) {
226         out.close();
227       }
228     }
229   }
230 
231   public static Map<String, Long> deserialize(final File file,
232       final long serialTtl) {
233 
234     if (file.exists()
235         && file.lastModified() < System.currentTimeMillis() - serialTtl) {
236       if (log.isDebugEnabled()) {
237         log.debug(String.format("Deleting previous serial %s "
238             + "because it's older then %s m/s", file.getPath(), serialTtl));
239       }
240       file.delete();
241     }
242 
243     Map<String, Long> o = null;
244     try {
245       if (file.exists()) {
246         final ObjectInputStream in = new ObjectInputStream(new FileInputStream(
247             file));
248         try {
249           o = (Map<String, Long>) in.readObject();
250         }
251         finally {
252           if (in != null) {
253             in.close();
254           }
255         }
256       }
257     }
258     catch (Exception e) {
259       log.error("Error: ", e);
260     }
261     if (o == null) {
262       o = new HashMap<String, Long>();
263     }
264     return o;
265   }
266 
267   public static void setConfigFilesTimestamps(
268       Map<String, Long> config_files_timestamps) {
269     CONFIG_FILES_TIMESTAMPS = config_files_timestamps;
270   }
271 
272   public static void setConfigFilesGlobalForce(
273       Map<String, Long> config_files_global_force) {
274     CONFIG_FILES_GLOBAL_FORCE = config_files_global_force;
275   }
276 
277   public static boolean isDirty() {
278     return isDirty;
279   }
280 
281   public static Map<String, Long> getConfigFilesTimestamps() {
282     return CONFIG_FILES_GLOBAL_FORCE;
283   }
284 
285 }