1 package de.juplo.plugins.hibernate;
5 import java.io.FileInputStream;
6 import java.io.FileOutputStream;
7 import java.io.IOException;
8 import java.io.InputStream;
9 import java.io.ObjectInputStream;
10 import java.io.ObjectOutputStream;
11 import java.math.BigInteger;
12 import java.security.MessageDigest;
13 import java.security.NoSuchAlgorithmException;
14 import java.util.HashMap;
15 import java.util.HashSet;
17 import java.util.Properties;
19 import org.apache.maven.plugin.logging.Log;
27 public class ModificationTracker
29 private Map<String,String> properties;
30 private Map<String,String> classes;
32 private final Set<String> propertyNames;
33 private final Set<String> classNames;
35 private boolean modified = false;
36 private boolean failed = false;
38 private final File saved;
39 private final MessageDigest digest;
40 private final Log log;
43 ModificationTracker(String buildDirectory, String filename, Log log)
45 NoSuchAlgorithmException
47 propertyNames = new HashSet<String>();
48 classNames = new HashSet<String>();
49 File output = new File(filename + ".md5s");
50 if (output.isAbsolute())
56 // Interpret relative file path relative to build directory
57 saved = new File(buildDirectory, output.getPath());
58 log.debug("Adjusted relative path, resulting path is " + saved.getPath());
60 digest = java.security.MessageDigest.getInstance("MD5");
65 private String calculate(InputStream is)
69 byte[] buffer = new byte[1024*4]; // copy data in 4MB-chunks
71 while((i = is.read(buffer)) > -1)
72 digest.update(buffer, 0, i);
74 byte[] bytes = digest.digest();
75 BigInteger bi = new BigInteger(1, bytes);
76 return String.format("%0" + (bytes.length << 1) + "x", bi);
79 private boolean check(Map<String,String> values, String name, String value)
81 if (!values.containsKey(name) || !values.get(name).equals(value))
83 values.put(name, value);
91 boolean track(String name, InputStream is) throws IOException
93 boolean result = check(classes, name, calculate(is));
100 boolean check(String name, String property)
102 propertyNames.add(name);
103 return check(properties, name, property);
106 boolean track(String name, String property)
108 boolean result = check(name, property);
113 boolean track(Properties properties)
115 boolean result = false;
116 for (String name : properties.stringPropertyNames())
117 result |= track(name, properties.getProperty(name));
129 modified |= !propertyNames.containsAll(properties.keySet());
130 modified |= !properties.keySet().containsAll(propertyNames);
131 modified |= !classNames.containsAll(classes.keySet());
132 modified |= !classes.keySet().containsAll(classNames);
145 if (saved.isFile() && saved.length() > 0)
149 FileInputStream fis = new FileInputStream(saved);
150 ObjectInputStream ois = new ObjectInputStream(fis);
151 properties = (HashMap<String,String>)ois.readObject();
152 classes = (HashMap<String,String>)ois.readObject();
157 properties = new HashMap<String,String>();
158 classes = new HashMap<String,String>();
159 log.warn("Cannot read md5s from saved: " + e);
164 properties = new HashMap<String,String>();
165 classes = new HashMap<String,String>();
168 saved.createNewFile();
170 catch (IOException e)
172 log.debug("Cannot create file \"" + saved.getPath() + "\" for md5s: " + e);
188 /** Write md5-sums for annotated classes to file */
191 FileOutputStream fos = new FileOutputStream(saved);
192 ObjectOutputStream oos = new ObjectOutputStream(fos);
193 oos.writeObject(properties);
194 oos.writeObject(classes);
200 log.error("Cannot write md5-sums to file: " + e);