e03f78e9ab96bcb6a43d75b5541b15427ce577b9
[hibernate4-maven-plugin] / src / main / java / de / juplo / plugins / hibernate / ModificationTracker.java
1 package de.juplo.plugins.hibernate;
2
3
4 import java.io.File;
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;
16 import java.util.Map;
17 import java.util.Properties;
18 import java.util.Set;
19 import org.apache.maven.plugin.logging.Log;
20
21
22
23 /**
24  *
25  * @author Kai Moritz
26  */
27 public class ModificationTracker
28 {
29   public final static String MD5S = "hibernate-generatedschema.md5s";
30
31   private Map<String,String> properties;
32   private Map<String,String> classes;
33
34   private final Set<String> propertyNames;
35   private final Set<String> classNames;
36
37   private boolean modified = false;
38
39   private final File saved;
40   private final MessageDigest digest;
41   private final Log log;
42
43
44   ModificationTracker(String buildDirectory, Log log)
45       throws
46         NoSuchAlgorithmException
47   {
48     propertyNames = new HashSet<String>();
49     classNames = new HashSet<String>();
50     saved = new File(buildDirectory + File.separator + MD5S);
51     digest = java.security.MessageDigest.getInstance("MD5");
52     this.log = log;
53   }
54
55
56   private String calculate(InputStream is)
57       throws
58         IOException
59   {
60     byte[] buffer = new byte[1024*4]; // copy data in 4MB-chunks
61     int i;
62     while((i = is.read(buffer)) > -1)
63       digest.update(buffer, 0, i);
64     is.close();
65     byte[] bytes = digest.digest();
66     BigInteger bi = new BigInteger(1, bytes);
67     return String.format("%0" + (bytes.length << 1) + "x", bi);
68   }
69
70   private boolean check(Map<String,String> values, String name, String value)
71   {
72     if (!values.containsKey(name) || !values.get(name).equals(value))
73     {
74       values.put(name, value);
75       return true;
76     }
77     else
78       return false;
79   }
80
81
82   boolean check(String name, InputStream is) throws IOException
83   {
84     boolean result = check(classes, name, calculate(is));
85     classNames.add(name);
86     modified |= result;
87     return result;
88   }
89
90   boolean check(String name, String property)
91   {
92     boolean result = check(properties, name, property);
93     propertyNames.add(name);
94     modified |= result;
95     return result;
96   }
97
98   boolean check(Properties properties)
99   {
100     boolean result = false;
101     for (String name : properties.stringPropertyNames())
102       result |= check(name, properties.getProperty(name));
103     return result;
104   }
105
106
107   boolean modified()
108   {
109     modified |= !propertyNames.containsAll(properties.keySet());
110     modified |= !properties.keySet().containsAll(propertyNames);
111     modified |= !classNames.containsAll(classes.keySet());
112     modified |= !classes.keySet().containsAll(classNames);
113     return modified;
114   }
115
116
117   void load()
118   {
119     if (saved.isFile() && saved.length() > 0)
120     {
121       try
122       {
123         FileInputStream fis = new FileInputStream(saved);
124         ObjectInputStream ois = new ObjectInputStream(fis);
125         properties = (HashMap<String,String>)ois.readObject();
126         classes = (HashMap<String,String>)ois.readObject();
127         ois.close();
128       }
129       catch (Exception e)
130       {
131         properties = new HashMap<String,String>();
132         classes = new HashMap<String,String>();
133         log.warn("Cannot read md5s from saved: " + e);
134       }
135     }
136     else
137     {
138       properties = new HashMap<String,String>();
139       classes = new HashMap<String,String>();
140       try
141       {
142         saved.createNewFile();
143       }
144       catch (IOException e)
145       {
146         log.debug("Cannot create file \"" + saved.getPath() + "\" for md5s: " + e);
147       }
148     }
149   }
150
151   void save()
152   {
153     if (!modified)
154       return;
155
156     /** Write md5-sums for annotated classes to file */
157     try
158     {
159       FileOutputStream fos = new FileOutputStream(saved);
160       ObjectOutputStream oos = new ObjectOutputStream(fos);
161       oos.writeObject(properties);
162       oos.writeObject(classes);
163       oos.close();
164       fos.close();
165     }
166     catch (Exception e)
167     {
168       log.error("Cannot write md5-sums to file: " + e);
169     }
170   }  
171 }