package aliview.aligner; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.math.BigInteger; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.text.SimpleDateFormat; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import org.apache.log4j.Logger; import utils.OSNativeUtils; public class MuscleWrapper { public static void main(String[] args) { getMusclePath(); } private static final Logger logger = Logger.getLogger(MuscleWrapper.class); public static File getMusclePath(){ // get predefined path // if no predefined path create one for distributed program File localMuscleBinFile = new File(getAliViewUserDataDirectory(), "/binaries" + File.separator + getMuscleBinDependingOnOS()); //logger.info("localMuscleBinFile.lastModified()" + localMuscleBinFile.lastModified()); //SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd HH:mm:ss"); //System.out.println("After Format : " + sdf.format(localMuscleBinFile.lastModified())); // check if file exist if not extract it from jar if(! localMuscleBinFile.exists() || localMuscleBinFile.length() == 0 || localMuscleBinFile.lastModified() < 1395868152000L){ // modified date = 20140326 22:09:12 (this is the date when saving file problem finally was resolved) ClassLoader cl = MuscleWrapper.class.getClassLoader(); try { boolean fileISOK = false; int nTries = 0; while(! fileISOK && nTries <=3){ nTries ++; InputStream muscleStreamFromJar = cl.getResourceAsStream(localMuscleBinFile.getName()); logger.info(muscleStreamFromJar); copyMuscleFileToLocalDir(muscleStreamFromJar, localMuscleBinFile); // reopen stream muscleStreamFromJar = cl.getResourceAsStream(localMuscleBinFile.getName()); fileISOK = verifyMD5(muscleStreamFromJar, localMuscleBinFile); if(! fileISOK){ FileUtils.deleteQuietly(localMuscleBinFile); }else{ localMuscleBinFile.setExecutable(true); } } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); // TODO Maybe notify something went wrong with installing muscle } } logger.info(localMuscleBinFile); return localMuscleBinFile; } private static boolean verifyMD5(InputStream streamFromJar,File localMuscleBinFile) throws FileNotFoundException { boolean checksumOK = false; String checksum1 = checkSum(streamFromJar); String checksum2 = checkSum(new FileInputStream(localMuscleBinFile)); logger.info(checksum1); logger.info(checksum2); if(checksum1 != null && checksum2 != null && checksum1.equals(checksum2)){ checksumOK = true; } return checksumOK; } private static void copyMuscleFileToLocalDir(InputStream muscleStreamFromJar, File localMuscleBinFile) throws IOException { FileUtils.forceMkdir(localMuscleBinFile.getParentFile()); FileUtils.copyInputStreamToFile(muscleStreamFromJar, localMuscleBinFile); } public static final String getAliViewUserDataDirectory() { return System.getProperty("user.home") + File.separator + ".AliView"; } public static final String getMuscleBinDependingOnOS() { String binName = ""; // 64-bit if(OSNativeUtils.is64BitOS()){ if(OSNativeUtils.isMac()){ binName = "muscle3.8.31_i86darwin64"; } else if(OSNativeUtils.isLinuxOrUnix()){ binName = "muscle3.8.425_i86linux64"; } // default else{ binName = "muscle3.8.425_win32.exe"; } // 32-bit }else{ if(OSNativeUtils.isMac()){ if(OSNativeUtils.isPowerPC()){ binName = "muscle3.8.31_macppc"; } else{ binName = "muscle3.8.31_i86darwin32"; } } else if(OSNativeUtils.isLinuxOrUnix()){ binName = "muscle3.8.425_i86linux32"; } // default else{ binName = "muscle3.8.425_win32.exe"; } } return binName; } /* * Calculate checksum of a File using MD5 algorithm */ public static String checkSum(InputStream instream){ String checksum = null; try { BufferedInputStream bis = new BufferedInputStream(instream); MessageDigest md = MessageDigest.getInstance("MD5"); //Using MessageDigest update() method to provide input byte[] buffer = new byte[8192]; int numOfBytesRead; while( (numOfBytesRead = bis.read(buffer)) > 0){ md.update(buffer, 0, numOfBytesRead); } byte[] hash = md.digest(); checksum = new BigInteger(1, hash).toString(16); //don't use this, truncates leading zero } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (NoSuchAlgorithmException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return checksum; } }