/* * [DistributeAuxAndJNLP.java] * * Summary: Prepares aux files such as the JNLP files ready to be uploaded to the website. * * Copyright: (c) 2003-2017 Roedy Green, Canadian Mind Products, http://mindprod.com * * Licence: This software may be copied and used freely for any purpose but military. * http://mindprod.com/contact/nonmil.html * * Requires: JDK 1.8+ * * Created with: JetBrains IntelliJ IDEA IDE http://www.jetbrains.com/idea/ * * Version History: * 6.4 2004-04-04 regenerate date embeded in jnlp files to * foil untouch. It was needlessly regenerating jnlp files over * and over since untouch redated them back to look too old. */ package com.mindprod.replicatorsender; import com.mindprod.common18.Build; import com.mindprod.common18.EIO; import com.mindprod.common18.Localise; import com.mindprod.fastcat.FastCat; import com.mindprod.replicatorcommon.Config; import com.mindprod.replicatorcommon.IO; import com.mindprod.replicatorcommon.MiniFD; import com.mindprod.replicatorcommon.ReplicatorCommon; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; import java.io.PrintWriter; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.zip.GZIPOutputStream; import static com.mindprod.replicatorsender.ConfigForSender.*; import static java.lang.System.*; /** * Prepares aux files such as the JNLP files ready to be uploaded to the website. *

* Prepare files for distribution to the client, other than the zips * and the zip manifest. e.g. replicator.icon64.gif, replicator.jnlp, * (*).jnlp, replicator.jar * * @author Roedy Green, Canadian Mind Products * @version 6.4 2004-04-04 regenerate date embedded in jnlp files to * foil untouch. It was needlessly regenerating jnlp files over * and over since untouch redated them back to look too old. * @since 2003-10-05 */ final class DistributeAuxAndJNLP { /** * We round published file sizes to multiples of this number. Does not have to be a power of two. */ private static final int ROUND_TO = 16 * 1024; /** * field ending for non-paired field */ private static final String FE = " />\n"; /** * Time NOW_STRING, sampled only once so all files will be dated consistently. mask for: 2005-01-20 23:59 GMT */ private static final String NOW_STRING = new SimpleDateFormat( "yyyy-MM-dd HH:mm zz" ) .format( new Date() ); /** * Timestamp that means generated files are considered fresh. Any older than this and they will be regenerated. */ private static long freshDate; /** * Sanity check. Ensure crucial files are present sender sender zip staging direectory */ static void auxRollCall() { try { // xxxreplicator.properties should be in E:\com\mindprod\replicatorsender // It must be there, or we could not have got started. // presume current dir in E:\com\mindprod\replicatorsender IO.ensureFileExists( new File( "replicatorsender.jar" ) ); // these should exist in E:\mindprod\replicator // We don't copy them in from anywhere. Should be manually placed // using prop.bat no longer use any *.gif files. final String[] crucialFiles = { "autorun.inf", Config.CODE_SIGNING_CERT + ".cer", "replicator.icon64.png", "replicator.ico", "replicator.jar", "replicator.splash.png", "setup.exe" }; for ( String crucialFile : crucialFiles ) { IO.ensureFileExists( new File( SENDER_ZIP_STAGING_DIR, crucialFile ) ); } } catch ( IOException e ) { ReplicatorCommon.fatal( e.getMessage() + "\n" + "Current directory: " + IO.getCurrentDir() ); } } /** * Calculate the timestamp that means generated files are considered fresh. Any older than this and they will be * regenerated. */ private static void calcFreshDate() { final long propertiesDate = new File( PROPERTIES_FILE ) .lastModified(); final long receiverDate = new File( SENDER_ZIP_STAGING_DIR, "replicator.jar" ).lastModified(); // 0 if file missing. // replicatorsender.jar is not in staging dir. freshDate = Math.max( propertiesDate, receiverDate ); } /** * distribute freshness.ser to help client decide which files it needs to download. */ private static void distributeFreshness() { // zipmanifest.ser not included. It's timestamp is not yet known. out.println( Localise.localise( "regenerating " + Config.FRESHNESS_SER ) ); // aux files we distribute as well that live int the replicator // directory final String[] auxFiles = { "autorun.inf", Config.CODE_SIGNING_CERT + ".cer", "replicator.icon64.png", "replicator.splash.png", "replicator.ico", "replicator.jar", "replicatorreceiverlan.jnlp", "replicatorreceiverrelay.jnlp", "replicatorreceiverwebsite.jnlp", "setup.exe" }; // don't distribute replicatorreceivertest.jnlp final ArrayList distributeAlso = new ArrayList<>( auxFiles.length + 26 ); for ( String auxFile : auxFiles ) { final MiniFD fd = new MiniFD( "", auxFile ); final File f = new File( SENDER_ZIP_STAGING_DIR, auxFile ); fd.setClumping( f.lastModified() ); distributeAlso.add( fd ); } // handle all the replicatorreceivercdX.jnlp files for ( char driveLetter = 'A'; driveLetter <= 'Z'; driveLetter++ ) { final MiniFD fd = new MiniFD( "", "replicatorreceivercd" + driveLetter + ".jnlp" ); final File f = new File( SENDER_ZIP_STAGING_DIR, "replicatorreceivercd" + driveLetter + ".jnlp" ); fd.setClumping( f.lastModified() ); distributeAlso.add( fd ); } final String freshnessFilename = SENDER_ZIP_STAGING_DIR + File .separatorChar + Config .FRESHNESS_SER; try { final FileOutputStream fos = new FileOutputStream( freshnessFilename ); final GZIPOutputStream gzos = new GZIPOutputStream( fos, 4 * 1024/* buffsize */ ); final ObjectOutputStream oos = new ObjectOutputStream( gzos ); oos.writeObject( distributeAlso.toArray( new MiniFD[ distributeAlso .size() ] ) ); oos.close(); } catch ( IOException e ) { ReplicatorCommon.fatal( "Unable to save " + freshnessFilename + " file." + "\n" + e.getMessage() ); } } /** * Generate jnlp file directly in sender staging dir. * * @param via VIA_WEBSITE VIA_LAN VIA_RELAY VIA_TEST VIA_CD * @param driveLetter e.g. R drive letter for CDROM, in caps. */ private static void distributeJNLP( ViaForSender via, char driveLetter ) { final String jnlpName = via.getJnlpName( driveLetter ); final String codebase = via.getCodebase( driveLetter ); final boolean keepZips = via.defaultKeepZips(); final boolean unpackZips = via.defaultUnpackZips(); final String authentication = via.getAuthentication(); final boolean offlineAllowed = via.isOfflineAllowed(); try { // O P E N final File jnlpFile = new File( SENDER_ZIP_STAGING_DIR, jnlpName ); // don't regenerate the jnlp file unless it will change. if ( jnlpFile.exists() && jnlpFile.lastModified() > freshDate ) { return; } out.println( "regenerating " + jnlpName ); final PrintWriter prw = EIO.getPrintWriter( jnlpFile, 4 * 1024, EIO.UTF8 ); // round to make it more stable. final long jarSize = ( ( new File( ConfigForSender.SENDER_ZIP_STAGING_DIR, "replicator.jar" ).length() + ROUND_TO / 2 ) / ROUND_TO ) * ROUND_TO; // W R I T E final FastCat sb = new FastCat( 170 ); sb.append( "\n" ); sb.append( "\n" ); sb.append( "\n" ); // sb.append( "\n" ); // sb.append( "\n" ); sb.append( "\n" ); sb.append( " \n" ); sb.append( " The Replicator " ); sb.append( Config.VERSION ); sb.append( " via " ); sb.append( via ); sb.append( "\n" ); sb.append( "\n" ); sb.append( " Canadian Mind Products\n" ); sb.append( " Replicates files " ); sb.append( via.getDescription() ); sb.append( ". Also keeps them up to date efficiently." ); sb.append( "\n" ); sb.append( " Replicates files " ); sb.append( via.getDescription() ); sb.append( ".\n" ); sb.append( " Replicates files " ); sb.append( via.getDescription() ); sb.append( ".\n" ); sb.append( " the Replicator\n" ); sb.append( " \n" ); sb.append( " " ); sb.append( "\n" ); sb.append( " \n" ); sb.append( " \n" ); sb.append( " \n" ); sb.append( " \n" ); sb.append( "\n" ); sb.append( " \n" ); sb.append( " \n" ); sb.append( "\n" ); sb.append( " \n" ); sb.append( "\n" ); sb.append( " \n" ); sb.append( " \n" ); sb.append( " \n" ); sb.append( " \n" ); sb.append( " \n" ); sb.append( "\n" ); sb.append( " \n" ); sb.append( " \n" ); sb.append( "\n" ); prw.write( sb.toString() ); // C L O S E prw.close(); } catch ( IOException e ) { ReplicatorCommon.fatal( "Unable to create " + jnlpName + "\n" + e.getMessage() ); } } /** * Generate startover.bat to start over in E:\com\mindprod\replicatorsender */ private static void distributeStartOver() { try { // presume current directory is E:\com\mindprod\replicatorsender // O P E N final File batfile = new File( "startover.bat" ); // don't regenerate the bat file unless it will change. if ( batfile.exists() && batfile.lastModified() > freshDate ) { return; } out.println( "regenerating startover.bat" ); final PrintWriter prw = EIO.getPrintWriter( batfile, 4 * 1024, EIO.UTF8 ); // W R I T E final FastCat sb = new FastCat( 125 ); sb.append( "@echo off\n" ); sb.append( "rem startOver.bat start from scratch\n" ); sb.append( "rem this runs only under Windows. You will need to convert to other OSes.\n" ); sb.append( "rem may be run from any directory\n" ); sb.append( "rem last regenerated " ); sb.append( NOW_STRING ); sb.append( "\n" ); sb.append( "if not exist " ); sb.append( SENDER_ZIP_STAGING_DIR ); sb.append( "\\replicatorreceiverwebsite.jnlp " ); sb.append( "echo missing " ); sb.append( SENDER_ZIP_STAGING_DIR ); sb.append( "\\replicatorreceiverwebsite.jnlp\n" ); sb.append( "echo About to start The Replicator over from scratch, To abort, hit Ctrl-C now.\n" ); sb.append( "pause\n" ); sb.append( "del " ); sb.append( SENDER_ZIP_STAGING_DIR ); sb.append( "\\" ); sb.append( Config.FRESHNESS_SER ); sb.append( "\n" ); sb.append( "del " ); sb.append( SENDER_ZIP_STAGING_DIR ); sb.append( "\\" ); sb.append( Config.ZIPDETAILEDMANIFEST_SER ); sb.append( "\n" ); sb.append( "del " ); sb.append( SENDER_ZIP_STAGING_DIR ); sb.append( "\\" ); sb.append( Config.ZIPMANIFEST_SER ); sb.append( "\n" ); sb.append( "del " ); sb.append( SENDER_ZIP_STAGING_DIR ); sb.append( "\\replicatorreceivercd*.jnlp\n" ); sb.append( "del " ); sb.append( SENDER_ZIP_STAGING_DIR ); sb.append( "\\replicatorreceiverlan.jnlp\n" ); sb.append( "del " ); sb.append( SENDER_ZIP_STAGING_DIR ); sb.append( "\\replicatorreceiverrelay.jnlp\n" ); sb.append( "del " ); sb.append( SENDER_ZIP_STAGING_DIR ); sb.append( "\\replicatorreceivertest.jnlp\n" ); sb.append( "del " ); sb.append( SENDER_ZIP_STAGING_DIR ); sb.append( "\\replicatorreceiverwebsite.jnlp\n" ); sb.append( "del " ); sb.append( SENDER_ZIP_STAGING_DIR ); sb.append( "\\z*.zip\n" ); sb.append( "del " ); sb.append( SENDER_PERSIST_DIR ); sb.append( "\\" ); sb.append( SENDER_SER ); sb.append( "\n" ); sb.append( "del " ); sb.append( SENDER_PERSIST_DIR ); sb.append( "\\" ); sb.append( SENDER_LOG ); sb.append( "\n" ); // // replace files that won't be regenerated // sb.append( "copy " ); sb.append( SENDER_PERSIST_DIR ); sb.append( "\\autorun.inf " ); sb.append( SENDER_ZIP_STAGING_DIR ); sb.append( "\n" ); sb.append( "copy " ); sb.append( SENDER_PERSIST_DIR ); sb.append( "\\" ); sb.append( Config.CODE_SIGNING_CERT ); sb.append( ".cer " ); sb.append( SENDER_ZIP_STAGING_DIR ); sb.append( "\n" ); sb.append( "copy " ); sb.append( SENDER_PERSIST_DIR ); sb.append( "\\setup.exe " ); sb.append( SENDER_ZIP_STAGING_DIR ); sb.append( "\n" ); sb.append( "copy " ); sb.append( REPLICATOR_SOURCE_DIR ); sb.append( "\\replicator.ico " ); sb.append( SENDER_ZIP_STAGING_DIR ); sb.append( "\n" ); sb.append( "copy " ); sb.append( REPLICATOR_SOURCE_DIR ); sb.append( "\\replicator.jar " ); sb.append( SENDER_ZIP_STAGING_DIR ); sb.append( "\n" ); sb.append( "copy " ); sb.append( REPLICATOR_SOURCE_DIR ); sb.append( "\\replicator.icon64.png " ); sb.append( SENDER_ZIP_STAGING_DIR ); sb.append( "\n" ); sb.append( "copy " ); sb.append( REPLICATOR_SOURCE_DIR ); sb.append( "\\replicator.splash.png " ); sb.append( SENDER_ZIP_STAGING_DIR ); sb.append( "\n" ); sb.append( "rem -30-\n" ); prw.print( sb.toString() ); // C L O S E prw.close(); } catch ( IOException e ) { ReplicatorCommon.fatal( "Unable to create startover.bat file." + "\n" + e.getMessage() ); } } /** * Prepare files for distribution to the client, other than the zips and the zip manifest. e.g. * replicator.icon64.gif, replicatorreceiver.jnlp, complexreplicatorreceiver.jnlp, replicator.jar */ public static void distribute() { // calc freshDate that lets know when files are stale and need to be // regenerated. calcFreshDate(); // distribute four types of jnlp file, put directly in sender staging // dir distributeJNLP( ViaForSender.VIA_WEBSITE, ' ' ); distributeJNLP( ViaForSender.VIA_LAN, ' ' ); distributeJNLP( ViaForSender.VIA_RELAY, ' ' ); distributeJNLP( ViaForSender.VIA_TEST, ' ' ); // arrgh. Have to generate a different jnlp file for possible CD drive // letter. for ( char driveLetter = 'A'; driveLetter <= 'Z'; driveLetter++ ) { distributeJNLP( ViaForSender.VIA_CD, driveLetter ); } // put startover.bat in E:\com\mindprod\replicatorsender distributeStartOver(); // create file of freshness dates of all auxiliary files // generate directly into sender staging directory distributeFreshness(); // block untouch //noinspection ResultOfMethodCallIgnored new File( SENDER_ZIP_STAGING_DIR, "untouch.digest" ) .delete(); } }