All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.juplo.plugins.hibernate.ModificationTracker Maven / Gradle / Ivy

There is a newer version: 2.1.1
Show newest version
package de.juplo.plugins.hibernate;


import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import org.apache.maven.plugin.logging.Log;



/**
 *
 * @author Kai Moritz
 */
public class ModificationTracker
{
  private Map properties;
  private Map classes;

  private final Set propertyNames;
  private final Set classNames;

  private boolean modified = false;
  private boolean failed = false;

  private final File saved;
  private final MessageDigest digest;
  private final Log log;


  ModificationTracker(String buildDirectory, String filename, Log log)
      throws
        NoSuchAlgorithmException
  {
    propertyNames = new HashSet();
    classNames = new HashSet();
    File output = new File(filename + ".md5s");
    if (output.isAbsolute())
    {
      saved = output;
    }
    else
    {
      // Interpret relative file path relative to build directory
      saved = new File(buildDirectory, output.getPath());
      log.debug("Adjusted relative path, resulting path is " + saved.getPath());
    }
    digest = java.security.MessageDigest.getInstance("MD5");
    this.log = log;
  }


  private String calculate(InputStream is)
      throws
        IOException
  {
    byte[] buffer = new byte[1024*4]; // copy data in 4MB-chunks
    int i;
    while((i = is.read(buffer)) > -1)
      digest.update(buffer, 0, i);
    is.close();
    byte[] bytes = digest.digest();
    BigInteger bi = new BigInteger(1, bytes);
    return String.format("%0" + (bytes.length << 1) + "x", bi);
  }

  private boolean check(Map values, String name, String value)
  {
    if (!values.containsKey(name) || !values.get(name).equals(value))
    {
      values.put(name, value);
      return true;
    }
    else
      return false;
  }


  boolean track(String name, InputStream is) throws IOException
  {
    boolean result = check(classes, name, calculate(is));
    classNames.add(name);
    modified |= result;
    return result;
  }


  boolean check(String name, String property)
  {
    propertyNames.add(name);
    return check(properties, name, property);
  }

  boolean track(String name, String property)
  {
    boolean result = check(name, property);
    modified |= result;
    return result;
  }

  boolean track(Properties properties)
  {
    boolean result = false;
    for (String name : properties.stringPropertyNames())
      result |= track(name, properties.getProperty(name));
    return result;
  }


  void touch()
  {
    modified = true;
  }

  boolean modified()
  {
    for (String property : new HashSet(properties.keySet()))
      if (!propertyNames.contains(property))
      {
        modified = true;
        properties.remove(property);
      }
     for (String clazz : new HashSet(classes.keySet()))
      if (!classNames.contains(clazz))
      {
        modified = true;
        classes.remove(clazz);
      }
    return modified;
  }


  void failed()
  {
    failed = true;
  }


  void load()
  {
    if (saved.isFile() && saved.length() > 0)
    {
      try
      {
        FileInputStream fis = new FileInputStream(saved);
        ObjectInputStream ois = new ObjectInputStream(fis);
        properties = (HashMap)ois.readObject();
        classes = (HashMap)ois.readObject();
        ois.close();
      }
      catch (Exception e)
      {
        properties = new HashMap();
        classes = new HashMap();
        log.warn("Cannot read md5s from saved: " + e);
      }
    }
    else
    {
      properties = new HashMap();
      classes = new HashMap();
      try
      {
        saved.createNewFile();
      }
      catch (IOException e)
      {
        log.debug("Cannot create file \"" + saved.getPath() + "\" for md5s: " + e);
      }
    }
  }

  void save()
  {
    if (failed)
    {
      saved.delete();
      return;
    }

    if (!modified)
      return;

    /** Write md5-sums for annotated classes to file */
    try
    {
      FileOutputStream fos = new FileOutputStream(saved);
      ObjectOutputStream oos = new ObjectOutputStream(fos);
      oos.writeObject(properties);
      oos.writeObject(classes);
      oos.close();
      fos.close();
    }
    catch (Exception e)
    {
      log.error("Cannot write md5-sums to file: " + e);
    }
  }  
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy