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 for (String property : new HashSet<String>(properties.keySet()))
130 if (!propertyNames.contains(property))
133 properties.remove(property);
135 for (String clazz : new HashSet<String>(classes.keySet()))
136 if (!classNames.contains(clazz))
139 classes.remove(clazz);
153 if (saved.isFile() && saved.length() > 0)
157 FileInputStream fis = new FileInputStream(saved);
158 ObjectInputStream ois = new ObjectInputStream(fis);
159 properties = (HashMap<String,String>)ois.readObject();
160 classes = (HashMap<String,String>)ois.readObject();
165 properties = new HashMap<String,String>();
166 classes = new HashMap<String,String>();
167 log.warn("Cannot read md5s from saved: " + e);
172 properties = new HashMap<String,String>();
173 classes = new HashMap<String,String>();
176 saved.createNewFile();
178 catch (IOException e)
180 log.debug("Cannot create file \"" + saved.getPath() + "\" for md5s: " + e);
196 /** Write md5-sums for annotated classes to file */
199 FileOutputStream fos = new FileOutputStream(saved);
200 ObjectOutputStream oos = new ObjectOutputStream(fos);
201 oos.writeObject(properties);
202 oos.writeObject(classes);
208 log.error("Cannot write md5-sums to file: " + e);