/* * [FileIO.java] * * Summary: File I/O Amanuensis. Generates sample I/O code for Java novices. * * Copyright: (c) 1997-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: * 1.0 1997-12-17 * 1.1 1997-12-22 uses layouts * generates BufferedReader.ReadLine() * 1.2 1998-01-02 handles URLConnection * handle append * handle autoflush * handle buffered on all types * 1.3 1998-01-03 internal reorganisation * O P E N comments * consistent short variable naming conventions. * StringBuilder renamed to String * Buffered now applies to all file types * RandomAccessFile * 1.4 1998-01-04 make into both application and applet * change reference to LEDataInputStream * 1.5 1998-01-08 warnings about applets and writing URLs. * 1.6 1998-01-09 reference to availability of LERandomAccessFile * change way LERandomAccess constructor works * 1.7 1998-01-12 add Sockets * remove connect out URL output. - * simplify interface to HowToProcess by making all methods static. * 1.8 1998-01-13 add Pipes * 1.9 1998-01-13 minor changes on how buffered handled * fix erroneous deprecated comment. * add readLine to more places. * 2.0 1998-01-17 GZIPOutputStream support * 2.1 1998-01-20 code to analyse a URL * code to flush * 2.2 1998-03-22 add ByteArrayInputStream ByteArrayOutputStream. * redo code to check for supported cases. * expectExceptions * expectExceptionOnFlush expectExceptionOnClose computed as you go rather than * trying to figure it out all in once place. * 2.3 1998-04-13 single character read for BufferedReader. * 2.4 1998-05-08 no url connect() on output. * Activator HTML * Compile on Symantec VC 2.5 * SlickEdit code tidy * 2.5 1998-06-24 add Javadoc. * 2.6 1998-11-10 new address and phone. * 2.7 1998-12-14 switch to jar file. * use new colour scheme. * check JVM version * 2.8 1998-12-28 add sample HTML and BAT file. * 2.9 1999-09-02 URLConnection.getContentLength * 3.0 1999-09-03 warning about URL uploads. * put connect back * harmless if already connected. * 3.1 1999-09-07 read/write get/post HTTP CGI * 3.2 1999-10-08 support for encoding * 3.3 1999-10-12 references to where to get ledatastream and * FileTransfer * 3.4 1999-10-21 warning about Netscape * 3.5 1999-10-22 stronger warning about Netscape * 3.6 2001-02-05 warning about readLine demanding a final \n * 3.7 2001-03-07 better fileio.use file. * 3.8 2002-02-15 use of .finish in compression. * rename variables to better fit Sun conventions. * variable Source/Target label * that tracks read/write. label "Data Type" * 3.9 2002-02-20 warning on pipes they are for inter-thread * communication only. * 4.0 2002-04-04 package name now lower case * fitting Sun conventions * 4.1 2002-04-19 replace term ASCII with accurate wordings * throughout. * autoflush for pipes and sockets. - rename all datatypes * for greater clarity. * 4.2 2003-05-19 better spacing. * Notes about Serialisation. * notes about -1 bytesRead means EOF. * 4.3 2003-05-26 note about missing readLine method in unbuffered * Readers. * 4.4 2003-05-27 Dropped all Exception catching for simplicity. * Redid code using StringBuilders instead of concatenation. * use of readEverything for HttpURLConnections. * 4.5 2004-05-04 add HEAD and turn off keep-alive * 4.6 2004-06-09 warnings about read not giving all bytes/chars you ask * for in one go. * add version check safety add about box tidier add code. * 4.7 2004-07-21 use UTF-8 instead of Cp437 as example encoding. * 4.8 2005-06-24 notes on safety of bad line separators in Reader files. * parameterised RELEASE_DATE. * 4.9 2005-11-30 add User-Agent and setRequestMethod to URL GET * 5.0 2006-01-04 add warnings about readUTF and writeUTF. * 5.1 2006-03-05 * 5.2 2007-07-12 add reference to com.mindprod.http package. * convert to JDK 1.5 and Swing * use of enum * pass IntelliJ inspector. * 5.3 2007-07-19 notes in GET/POST about HTTPClient, changed ordering. * 5.4 2007-07-27 correct code generated for URL read, and PIPE write. * 5.5 2007-08-05 major rewrite. refactor, simplify, make code more orthogonal, * generate code for more cases, timeouts. * 5.6 2007-08-24 notes on where to get source for readBytesBlocking. * 5.7 2008-04-02 add build number to title * 5.8 2009-12-21 use keyword final as much as possible in generated code. * 5.9 2010-02-21 use of FastCat instead of StringBuilder. Generate code to use Aux buffering for Readers and Writers. * 6.0 2010-12-06 support getResourceAsStream, FileReader, FileWriter. * 6.1 2011-12-03 configurable Look and Feel * 6.2 2014-05-10 optimal buffering ratios */ package com.mindprod.fileio; import com.mindprod.common18.Build; import com.mindprod.common18.CMPAboutJBox; import com.mindprod.common18.FontFactory; import com.mindprod.common18.HybridJ; import com.mindprod.common18.Laf; import com.mindprod.common18.VersionCheck; import javax.swing.ButtonGroup; import javax.swing.JApplet; import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JLabel; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.JScrollBar; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.SwingUtilities; import java.awt.Color; import java.awt.Container; import java.awt.Font; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.Label; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; /** * File I/O Amanuensis. Generates sample I/O code for Java novices. *

* * @author Roedy Green, Canadian Mind Products * @version 6.2 2014-05-10 optimal buffering ratios * @noinspection FieldCanBeLocal * @since 1997-12-17 */ public final class FileIO extends JApplet { /** * if true, will generate file E:\com\mindprod\fileio\Test.java so can test compile all possible outputs. */ static final boolean DEBUGGING = false; /** * height of Applet box in pixels. Does not include surrounding frame. */ private static final int APPLET_HEIGHT = 696; /** * Width of Applet box in pixels. */ private static final int APPLET_WIDTH = 646; private static final int FIRST_COPYRIGHT_YEAR = 1997; /** * undisplayed copyright notice * * @noinspection UnusedDeclaration */ private static final String EMBEDDED_COPYRIGHT = "Copyright: (c) 1997-2017 Roedy Green, Canadian Mind Products, http://mindprod.com"; /* date this version released */ private static final String RELEASE_DATE = "2014-05-10"; private static final String TITLE_STRING = "File I/O Amanuensis"; private static final String VERSION_STRING = "6.2"; /** * pale apricot background */ private static final Color BACKGROUND_FOR_APPLET = new Color( 0xfae5b7 ); /** * instructions */ private static final Color FOREGROUND_FOR_INSTRUCTIONS = new Color( 0x008000 ); /** * text for labels */ private static final Color FOREGROUND_FOR_LABEL = new Color( 0x0000b0 ); /** * usual text */ private static final Color FOREGROUND_FOR_RESULTS = Color.BLACK; /** * for titles */ private static final Color FOREGROUND_FOR_TITLE = new Color( 0xdc143c ); /** * font for labels */ private static final Font FONT_FOR_LABEL = FontFactory.build( "Dialog", Font.BOLD, 15 ); /** * font to display generated code */ private static final Font FONT_FOR_RESULTS = FontFactory.build( "Dialog", Font.PLAIN, 13 ); /** * for for titles and About buttons */ private static final Font FONT_FOR_TITLE = FontFactory.build( "Dialog", Font.BOLD, 16 ); /** * for for title second line */ private static final Font FONT_FOR_TITLE2 = FontFactory.build( "Dialog", Font.PLAIN, 14 ); /** * the buffer/compressed CheckBoxes */ private ButtonGroup bufferCheckBoxes; /** * the read/write buttons. */ private ButtonGroup readWriteCheckBoxes; /** * radio button to select buffered file io */ private JCheckBox bufferedButton; /** * radio button to select compressed file io. */ private JCheckBox compressedButton; /** * radiobutton to select that you want file input code generated. */ private JCheckBox readButton; /** * radio button to select unbuffered file io. */ private JCheckBox unbufferedButton; /** * radio button to select that you want output code generated. */ private JCheckBox writeButton; /** * Multiple choice: which type of data is in your file. */ private JComboBox data; /** * Multiple choice: which type of "file" are you doing I/O to. */ private JComboBox sourceTarget; /** * label "data" */ private JLabel dataLabel; /** * Label "file" */ private JLabel fileSourceTargetLabel; /** * label suggestions to use cut/paste. */ private JLabel instructions; /** * Title and version for the applet. */ private JLabel title; /** * title, second line */ private JLabel title2; /** * allow generated sample code to scroll */ private JScrollPane howToScroller; /** * scrollable text area to contain the generated sample Java source code. */ private JTextArea howTo; private void buildComponents() { title = new JLabel( TITLE_STRING + " " + VERSION_STRING ); title.setFont( FONT_FOR_TITLE ); title.setForeground( FOREGROUND_FOR_TITLE ); title2 = new JLabel( "released:" + RELEASE_DATE + " build:" + Build.BUILD_NUMBER ); title2.setFont( FONT_FOR_TITLE2 ); title2.setForeground( FOREGROUND_FOR_TITLE ); /* variable Source/Target depending on read/write button. */ fileSourceTargetLabel = new JLabel( "Source" ); fileSourceTargetLabel.setFont( FONT_FOR_LABEL ); fileSourceTargetLabel.setForeground( FOREGROUND_FOR_LABEL ); sourceTarget = new JComboBox<>( FileType.values() ); sourceTarget.setSelectedItem( FileType.SEQUENTIAL ); dataLabel = new JLabel( "Data FormatPadSites", Label.RIGHT ); dataLabel.setFont( FONT_FOR_LABEL ); dataLabel.setForeground( FOREGROUND_FOR_LABEL ); data = new JComboBox<>( DataType.values() ); data.setSelectedItem( DataType.BIGEND ); readButton = new JCheckBox( "read", true ); readButton.setForeground( FOREGROUND_FOR_LABEL ); readButton.setBackground( BACKGROUND_FOR_APPLET ); writeButton = new JCheckBox( "write", false ); writeButton.setForeground( FOREGROUND_FOR_LABEL ); writeButton.setBackground( BACKGROUND_FOR_APPLET ); readWriteCheckBoxes = new ButtonGroup(); readWriteCheckBoxes.add( readButton ); readWriteCheckBoxes.add( writeButton ); unbufferedButton = new JCheckBox( "unbuffered", true ); unbufferedButton.setForeground( FOREGROUND_FOR_LABEL ); unbufferedButton.setBackground( BACKGROUND_FOR_APPLET ); bufferedButton = new JCheckBox( "buffered", false ); bufferedButton.setForeground( FOREGROUND_FOR_LABEL ); bufferedButton.setBackground( BACKGROUND_FOR_APPLET ); compressedButton = new JCheckBox( "compressed", false ); compressedButton.setForeground( FOREGROUND_FOR_LABEL ); compressedButton.setBackground( BACKGROUND_FOR_APPLET ); bufferCheckBoxes = new ButtonGroup(); bufferCheckBoxes.add( unbufferedButton ); bufferCheckBoxes.add( bufferedButton ); bufferCheckBoxes.add( compressedButton ); howTo = new JTextArea( How.how( FileType.SEQUENTIAL, DataType.BIGEND, true /* input */, false /* buffered */, false /* compressed */ ), 40, 0 ); howTo.setEditable( false ); howTo.setFont( FONT_FOR_RESULTS ); howTo.setForeground( FOREGROUND_FOR_RESULTS ); howTo.setMargin( new Insets( 5, 5, 5, 5 ) ); howToScroller = new JScrollPane( howTo, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED ); instructions = new JLabel( "Cut and Paste results into your own code.", JLabel.CENTER ); instructions.setForeground( FOREGROUND_FOR_INSTRUCTIONS ); } /** * build a menu with Look & Feel and About across the top */ private void buildMenu() { // turn on anti-alias System.setProperty( "swing.aatext", "true" ); final JMenuBar menubar = new JMenuBar(); setJMenuBar( menubar ); final JMenu lafMenu = Laf.buildLookAndFeelMenu(); if ( lafMenu != null ) { menubar.add( lafMenu ); } final JMenu menuHelp = new JMenu( "Help" ); menubar.add( menuHelp ); final JMenuItem aboutItem = new JMenuItem( "About" ); menuHelp.add( aboutItem ); aboutItem.addActionListener( new ActionListener() { public void actionPerformed( ActionEvent e ) { // open about frame new CMPAboutJBox( TITLE_STRING, VERSION_STRING, "Generates Java source to do I/Os,", "e.g. code for files, socket, CGI, pipes and in-RAM I/O.", "freeware", RELEASE_DATE, FIRST_COPYRIGHT_YEAR, "Roedy Green", "FILEIO", "1.8" ); } } ); } /** * register listeners */ private void hookListeners() { // REGISTER_LISTENERS TheListener theListener = new TheListener(); sourceTarget.addItemListener( theListener ); data.addItemListener( theListener ); readButton.addItemListener( theListener ); writeButton.addItemListener( theListener ); unbufferedButton.addItemListener( theListener ); bufferedButton.addItemListener( theListener ); compressedButton.addItemListener( theListener ); } /** * layout components in a GridBag * * @param contentPane contentPane of JApplet */ private void layoutComponents( Container contentPane ) { /** * layout * --- 0 -----1------- 2 -------------3------ * 0--title ----------------------- -title2- 0 * 2 "source" * read unbuffered "dataformat" 2 * 3 source write buffered dataformat------- 3 * 4 * compressed ----------------- 4 * 5 ------------- how---------------------- 5 * 6 ------------- instructions ----------- 6 * --- 0 -----1------- 2 ----------------3---- */ // x y w h wtx wty anchor fill T L B R padx pady contentPane.add( title, new GridBagConstraints( 0, 0, 3, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets( 10, 10, 10, 5 ), 0, 0 ) ); contentPane.add( title2, new GridBagConstraints( 3, 0, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets( 10, 5, 10, 10 ), 0, 0 ) ); // x y w h wtx wty anchor fill T L B R padx pady contentPane.add( fileSourceTargetLabel, new GridBagConstraints( 0, 2, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets( 5, 10, 0, 5 ), 0, 0 ) ); // x y w h wtx wty anchor fill T L B R padx pady contentPane.add( readButton, new GridBagConstraints( 1, 2, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets( 5, 5, 0, 5 ), 0, 0 ) ); // x y w h wtx wty anchor fill T L B R padx pady contentPane.add( unbufferedButton, new GridBagConstraints( 2, 2, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets( 5, 5, 0, 5 ), 0, 0 ) ); // x y w h wtx wty anchor fill T L B R padx pady contentPane.add( dataLabel, new GridBagConstraints( 3, 2, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets( 5, 5, 0, 10 ), 0, 0 ) ); // x y w h wtx wty anchor fill T L B R padx pady contentPane.add( sourceTarget, new GridBagConstraints( 0, 3, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets( 5, 10, 0, 5 ), 0, 0 ) ); // x y w h wtx wty anchor fill T L B R padx pady contentPane.add( writeButton, new GridBagConstraints( 1, 3, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets( 5, 5, 0, 5 ), 0, 0 ) ); // x y w h wtx wty anchor fill T L B R padx pady contentPane.add( bufferedButton, new GridBagConstraints( 2, 3, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets( 5, 5, 0, 5 ), 0, 0 ) ); // x y w h wtx wty anchor fill T L B R padx pady contentPane.add( data, new GridBagConstraints( 3, 3, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets( 5, 5, 0, 10 ), 0, 0 ) ); // x y w h wtx wty anchor fill T L B R padx pady contentPane.add( compressedButton, new GridBagConstraints( 2, 4, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets( 5, 5, 0, 5 ), 0, 0 ) ); // x y w h wtx wty anchor fill T L B R padx pady contentPane.add( howToScroller, new GridBagConstraints( 0, 5, 4, 1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets( 5, 10, 0, 10 ), 0, 0 ) ); // x y w h wtx wty anchor fill T L B R padx pady contentPane.add( instructions, new GridBagConstraints( 0, 6, 4, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets( 5, 10, 10, 10 ), 0, 0 ) ); } /** * Allow this Applet to run as as application as well. * * @param args command line arguments are ignored. */ public static void main( String args[] ) { HybridJ.fireup( new FileIO(), TITLE_STRING + " " + VERSION_STRING, APPLET_WIDTH, APPLET_HEIGHT ); } // end main /** * 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() { bufferCheckBoxes = null; bufferedButton = null; compressedButton = null; data = null; dataLabel = null; fileSourceTargetLabel = null; howTo = null; howToScroller = null; instructions = null; readButton = null; readWriteCheckBoxes = null; sourceTarget = null; title = null; title2 = null; unbufferedButton = null; writeButton = null; } // }} /** * Called by the browser or Applet viewer to inform * this Applet that it has been loaded into the system. */ @Override public void init() { if ( !VersionCheck.isJavaVersionOK( 1, 8, 0, this ) ) { return; } buildMenu(); Container contentPane = this.getContentPane(); contentPane.setBackground( BACKGROUND_FOR_APPLET ); contentPane.setLayout( new GridBagLayout() ); buildComponents(); // add components: layoutComponents( contentPane ); hookListeners(); this.validate(); this.setVisible( true ); } // end init /** * Inner class to act as listener for end user actions. */ private final class TheListener implements ItemListener { /** * Listen for any actions from the end-user. * * @param e details of what end user just clicked. */ public void itemStateChanged( ItemEvent e ) { // It does not matter which control triggered the event, the // response is the same, // to recalculate the text of the howTo. // Make Source/Target appear depending on whether read/write. fileSourceTargetLabel.setText( readButton.isSelected() ? "Source" : "Target" ); // get states of controls and generate display: // HowToProcess will return code to display. howTo.setText( How.how( ( FileType ) sourceTarget.getSelectedItem(), /* sourceTarget */ ( DataType ) data.getSelectedItem(), /* dataType */ readButton.isSelected(), /* input? */ bufferedButton.isSelected(), /* buffered */ compressedButton.isSelected() ) );/* compressed */ // invoke later to give time for text to render. SwingUtilities.invokeLater( new Runnable() { public void run() { final JScrollBar v = howToScroller.getVerticalScrollBar(); v.setValue( v.getMinimum() ); } } ); } // end itemStateChanged } // end TheListener }