/* * [ReplicatorUse.java] * * Summary: Show instructions for Replicator use, particularly off-net. * * 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: * 7.2 2006-02-11 add RETIREMENT property to delay deleting old zips. * 7.3 2006-03-05 reformat with IntelliJ and add Javadoc * 7.4 2007-05-30 * 7.5 2007-07-16 IntelliJ inspector. * 7.6 2007-07-17 refactor to use use enums, for:each, pass IntelliJ Inspector. * 7.7 2007-07-20 compress manifests * 7.8 2007-07-23 debugging logs, extra validations. * 7.9 2007-07-23 new way to do zip retires to avoid out-of-order bug. * 8.0 2007-07-28 fix log so works on virgin machines. * 8.1 2007-07-29 Remove Windows centric code. * 8.2 2007-07-30 propertes file specified on the command line. * 8.3 2007-08-04 Use new version of FileTransfer with timeouts, more efficient CPU use, etc. * 8.4 2007-08-18 merged clump, move fileLength to FD for verify. * sender and receiver to make it work properly on Ubuntu. More * efficient unpacking of zips, bypassing work it has done * previously. * 8.5 2007-09-02 better stats, can hit verify during download, more spacious layout. * 8.6 2007-09-13 reduced frequency of zip repacking * 8.7 2007-09-18 Fix zip order when deletions * 8.8 2007-09-20 flip to JDK 1.6 * 8.9 2007-09-22 now handles files that change length without changing date. * 9.0 2007-09-23 retirement time now specified in minutes rather than hours. * 9.1 2007-10-28 fix bug to ensure gui state persisted. * 9.2 2007-12-24 display range of times for retired. * 9.3 2008-01-07 emaciate and delete files in the same replicatorSender run. * 9.4 2008-01-28 calculate percentage of deadwood more conservatively * 9.5 2008-02-08 better error message if can't create dirs, tool tip help. * 9.6 2008-02-22 display computed lag and retirement timestamps * 9.7 2008-03-20 only unpack new files, not the entire zip. * 9.8 2008-03-28 fine tune generated JNLP * 9.9 2008-04-09 compact zips under tighter rules immediately after LAG days. * 10.0 2008-08-10 extend timeouts to be more patient with network congestion. * 10.1 2009-01-23 fix harmless bug in saving the internal state * 10.2 2009-04-03 tidy up code to check presence of necessary files to make it more WORA. * 10.3 2009-05-03 localise log output file with Localise and PrintWriterPortable * 10.4 2009-08-08 add RECOVER, HIGHEST_ACCEPTABLE_EXIT_CODE, MAX_UPLOAD_TRIES config parms. * 10.5 2011-04-22 fully automate StartOver.bat, so no additional copies are needed. * 10.6 2011-07-30 add support for Java 1.7 * 10.7 2011-08-05 add packing statistics * 10.8 2011-09-08 sort packing statistics, avoiding voids. * 10.9 2011-09-14 base stats on clumping, and stats on newest repackaged. * 11.0 2011-12-22 update the JNLP. * 11.1 2012-03-15 serialise arrays instead of ArrayLists. Correct docs on how LAG works. * 11.2 2012-05-12 more consistent use of empty timestamp markers. Should make more compact uploads. * 11.3 2012-05-13 further more consistent use of empty markers. * 11.4 2014-04-06 bypass Oracle dropping support for JNLP properties. * 11.5 2014-08-19 modify SortedArrayList to account for JDK 1.8.0_20s fobbing Collections.sort on ArrayList.sort. * 11.6 2015-03-10 sign the jar. */ package com.mindprod.replicatoruse; import com.mindprod.common18.FontFactory; import com.mindprod.common18.HybridJ; import com.mindprod.replicatorcommon.ReplicatorCommon; import javax.swing.BorderFactory; import javax.swing.BoxLayout; import javax.swing.ButtonGroup; import javax.swing.JApplet; import javax.swing.JEditorPane; import javax.swing.JPanel; import javax.swing.JRadioButton; import javax.swing.JTabbedPane; import javax.swing.border.TitledBorder; import java.awt.Color; import java.awt.Container; import java.awt.Font; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import static com.mindprod.replicatoruse.Phrase.FIRST_TIME; import static java.lang.System.*; /** * Show instructions for Replicator use, particularly off-net. * * @author Roedy Green, Canadian Mind Products * @version 11.6 2015-03-10 sign the jar. * @since 2003 */ public final class ReplicatorUse extends JApplet { /** * height of entire Applet */ private static final int APPLET_HEIGHT = 336; /** * widhth of entire Applet */ private static final int APPLET_WIDTH = 660; private static final int FIRST_COPYRIGHT_YEAR = 2003; /** * undisplayed copyright notice */ @SuppressWarnings( { "UnusedDeclaration" } ) private static final String EMBEDDED_COPYRIGHT = "Copyright: (c) 2003-2017 Roedy Green, Canadian Mind Products, http://mindprod.com"; /** * when version released. */ @SuppressWarnings( { "UnusedDeclaration" } ) private static final String RELEASE_DATE = ReplicatorCommon.RELEASE_DATE; /** * title */ private static final String TITLE_STRING = "Replicator Use"; /** * embedded version string. */ @SuppressWarnings( { "UnusedDeclaration" } ) private static final String VERSION_STRING = ReplicatorCommon.VERSION_STRING; private static final Color FOREGROUND_FOR_BORDER = new Color( 0x000033 ); private HowDistributeZips howDistributeZips; private JEditorPane instructions; private WhereGetZips whereGetZips; public ReplicatorUse() { } /** * calculate and display the instructions based on input choices. */ private void calcInstructions() { if ( instructions == null || whereGetZips == null || howDistributeZips == null ) { return; } final StringBuilder sb = new StringBuilder( 2000 ); sb.append( "" ); if ( whereGetZips == WhereGetZips .B_FROM_ORIGINALS ) { // original author sb.append( whereGetZips.instructions() ); sb.append( "

" ); sb.append( howDistributeZips .getAuthorHowDistributeInsructions() ); } else { // client or relay of some sort sb.append( whereGetZips.instructions() ); sb.append( "

" ); sb.append( FIRST_TIME ); sb.append( "

" ); sb.append( howDistributeZips .getRelayHowDistributeInsructions() ); } sb.append( "" ); final String instructionsHTML = sb.toString(); try { instructions.setText( instructionsHTML ); } catch ( Exception e ) { err.println( "Because of Sun bug, unable to display instructions, please exit browser and restart" ); e.printStackTrace( err ); err.println( instructionsHTML ); } } /** * standard main method. * * @param args no used. */ public static void main( String[] args ) { HybridJ.fireup( new ReplicatorUse(), TITLE_STRING + " " + VERSION_STRING, APPLET_WIDTH, APPLET_HEIGHT ); } /** * Called by the browser or Applet viewer to inform * this Applet that it is being reclaimed and that it should destroy * any resources that it has allocated. */ @Override public void destroy() { howDistributeZips = null; instructions = null; whereGetZips = null; } /** * Called by the browser or Applet viewer to inform * this Applet that it has been loaded into the system. */ @Override public void init() { Container contentPane = getContentPane(); contentPane.setLayout( new BoxLayout( contentPane, BoxLayout.Y_AXIS ) ); howDistributeZips = HowDistributeZips.A_NONE; instructions = new JEditorPane(); whereGetZips = WhereGetZips.A_FROM_WEBSITE; JTabbedPane tabbedPane = new JTabbedPane(); tabbedPane.addTab( "Where", null, new WhereGetZipsPanel(), "Where You Get Zips" ); tabbedPane.addTab( "HowToProcess", null, new HowDistributeZipsPanel(), "HowToProcess You Distribute Zips" ); tabbedPane.addTab( "Instructions", null, new InstructionsPanel(), "Instructions on Using the Replicator" ); contentPane.add( tabbedPane ); this.validate(); this.setVisible( true ); } /** * asks question about how you want to distribute ZIPs *

* created with Intellij Idea * * @author Roedy Green, Canadian Mind Products */ final class HowDistributeZipsPanel extends JPanel { final JRadioButton[] radio; /** * panel constructor */ @SuppressWarnings( { "ValueOfIncrementOrDecrementUsed" } ) HowDistributeZipsPanel() { this.setLayout( new BoxLayout( this, BoxLayout.Y_AXIS ) ); // ask the question, buried in the border this.setBorder( new TitledBorder( BorderFactory .createLineBorder( FOREGROUND_FOR_BORDER ), " " + HowDistributeZips.getQuestion() + " ", TitledBorder.LEADING, TitledBorder.TOP, FontFactory.build( "Dialog", Font.PLAIN, 15 ), Color.RED ) ); // set up multiple choice answers. User must select one. final ButtonGroup distributions = new ButtonGroup(); final ItemListener distributionListener = new ItemListener() { public void itemStateChanged( ItemEvent e ) { if ( e.getStateChange() != ItemEvent.SELECTED ) { return; } for ( int i = 0; i < radio.length; i++ ) { if ( radio[ i ].isSelected() ) { howDistributeZips = HowDistributeZips.values()[ i ]; calcInstructions(); return; } } assert false : "no howDistributeZips radio button match"; } }; radio = new JRadioButton[ HowDistributeZips.values().length ]; int r = 0; for ( HowDistributeZips distribution : HowDistributeZips.values() ) { JRadioButton b = new JRadioButton( distribution.getDescription() ); b.setAlignmentX( 0 ); distributions.add( b ); b.addItemListener( distributionListener ); this.add( b ); radio[ r++ ] = b; } radio[ 0 ].setSelected( true ); } // end constructor } // end HowDistributeZipsPanel final class InstructionsPanel extends JPanel { /** * panel constructor */ InstructionsPanel() { this.setLayout( new BoxLayout( this, BoxLayout.Y_AXIS ) ); this.setBorder( new TitledBorder( BorderFactory .createLineBorder( FOREGROUND_FOR_BORDER ), " " + "Instructions on Using the Replicator" + " ", TitledBorder.LEADING, TitledBorder.TOP, FontFactory.build( "Dialog", Font.PLAIN, 15 ), Color.RED ) ); instructions.setContentType( "text/html" ); instructions.setEditable( false ); calcInstructions(); this.add( instructions ); } } /** * asks question about how you want to distribute ZIPs *

* created with Intellij Idea * * @author Roedy Green, Canadian Mind Products */ final class WhereGetZipsPanel extends JPanel { private final JRadioButton[] radio; /** * panel constructor */ @SuppressWarnings( { "ValueOfIncrementOrDecrementUsed" } ) WhereGetZipsPanel() { this.setLayout( new BoxLayout( this, BoxLayout.Y_AXIS ) ); // ask the question, buried in the border this.setBorder( new TitledBorder( BorderFactory .createLineBorder( FOREGROUND_FOR_BORDER ), " " + WhereGetZips.getQuestion() + " ", TitledBorder.LEADING, TitledBorder.TOP, FontFactory.build( "Dialog", Font.PLAIN, 15 ), Color.RED ) ); // set up multiple choice answers. User must select one. final ButtonGroup sources = new ButtonGroup(); final ItemListener sourceListener = new ItemListener() { public void itemStateChanged( ItemEvent e ) { if ( e.getStateChange() != ItemEvent.SELECTED ) { return; } for ( int i = 0; i < radio.length; i++ ) { if ( radio[ i ].isSelected() ) { whereGetZips = WhereGetZips.values()[ i ]; calcInstructions(); return; } } assert false : "no WhereGetZips radio button match"; } }; radio = new JRadioButton[ WhereGetZips.values().length ]; int r = 0; for ( WhereGetZips source : WhereGetZips.values() ) { JRadioButton b = new JRadioButton( source.getDescription() ); b.setAlignmentX( 0 );/* left */ sources.add( b ); b.addItemListener( sourceListener ); this.add( b ); radio[ r++ ] = b; } radio[ 0 ].setSelected( true ); } // end constructor } } // end JApplet