Index: modules/tools/src/main/java/org/apache/harmony/tools/appletviewer/AppletFrame.java =================================================================== --- modules/tools/src/main/java/org/apache/harmony/tools/appletviewer/AppletFrame.java (revision 618610) +++ modules/tools/src/main/java/org/apache/harmony/tools/appletviewer/AppletFrame.java (working copy) @@ -18,22 +18,42 @@ package org.apache.harmony.tools.appletviewer; import java.applet.Applet; + import java.awt.BorderLayout; import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Font; +import java.awt.GridLayout; import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; import java.awt.event.WindowEvent; import java.awt.event.WindowListener; + +import java.io.IOException; +import java.io.File; +import java.io.FileOutputStream; + +import java.util.Enumeration; import java.util.HashSet; import javax.swing.AbstractAction; +import javax.swing.BorderFactory; +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; +import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JSeparator; +import javax.swing.JTextField; import javax.swing.SwingConstants; +import javax.swing.border.Border; class AppletFrame extends JFrame { private final Applet applet; @@ -86,6 +106,8 @@ controlMenu.add(new JMenuItem(new StartAction())); controlMenu.add(new JMenuItem(new StopAction())); controlMenu.add(new JSeparator()); + controlMenu.add(new JMenuItem(new PropertiesAction())); + controlMenu.add(new JSeparator()); controlMenu.add(new JMenuItem(new CloseAction())); controlMenu.add(new JMenuItem(new ExitAction())); @@ -120,6 +142,277 @@ } } + private class PropertiesAction extends AbstractAction { + public PropertiesAction() { + super("Properties"); + } + + public void actionPerformed(final ActionEvent e) { + showSetPropDialog(AppletFrame.this); + } + + private void showSetPropDialog(final JFrame frame){ + final JDialog dialog = new JDialog(frame, "Harmony AppletViewer Properties"); + + // Sheet part of Dialog + JLabel httpHost = new JLabel(Main.httpProxyHost); + httpHost.setFont(httpHost.getFont().deriveFont(Font.PLAIN)); + + JLabel httpPort = new JLabel(Main.httpProxyPort); + httpPort.setFont(httpPort.getFont().deriveFont(Font.PLAIN)); + + JLabel httpsHost = new JLabel(Main.httpsProxyHost); + httpsHost.setFont(httpsHost.getFont().deriveFont(Font.PLAIN)); + + JLabel httpsPort = new JLabel(Main.httpsProxyPort); + httpsPort.setFont(httpsPort.getFont().deriveFont(Font.PLAIN)); + + JLabel ftpHost = new JLabel(Main.ftpProxyHost); + ftpHost.setFont(ftpHost.getFont().deriveFont(Font.PLAIN)); + + JLabel ftpPort = new JLabel(Main.ftpProxyPort); + ftpPort.setFont(ftpPort.getFont().deriveFont(Font.PLAIN)); + + final JTextField tfHttpHost = new JTextField(Main.properties.getProperty(Main.httpProxyHost)); + Dimension d = tfHttpHost.getPreferredSize(); + tfHttpHost.setPreferredSize(new Dimension(50, d.height)); + + final JTextField tfHttpPort = new JTextField(Main.properties.getProperty(Main.httpProxyPort)); + tfHttpPort.setPreferredSize(new Dimension(50, d.height)); + + final JTextField tfHttpsHost = new JTextField(Main.properties.getProperty(Main.httpsProxyHost)); + tfHttpsHost.setPreferredSize(new Dimension(50, d.height)); + + final JTextField tfHttpsPort = new JTextField(Main.properties.getProperty(Main.httpsProxyPort)); + tfHttpsPort.setPreferredSize(new Dimension(50, d.height)); + + final JTextField tfFtpHost = new JTextField(Main.properties.getProperty(Main.ftpProxyHost)); + tfFtpHost.setPreferredSize(new Dimension(50, d.height)); + + final JTextField tfFtpPort = new JTextField(Main.properties.getProperty(Main.ftpProxyPort)); + tfFtpPort.setPreferredSize(new Dimension(50, d.height)); + + JPanel sheetPanel = new JPanel(); + + sheetPanel.setLayout(new GridLayout(6,2)); + + sheetPanel.add(httpHost); + sheetPanel.add(tfHttpHost); + + sheetPanel.add(httpPort); + sheetPanel.add(tfHttpPort); + + sheetPanel.add(httpsHost); + sheetPanel.add(tfHttpsHost); + + sheetPanel.add(httpsPort); + sheetPanel.add(tfHttpsPort); + + sheetPanel.add(ftpHost); + sheetPanel.add(tfFtpHost); + + sheetPanel.add(ftpPort); + sheetPanel.add(tfFtpPort); + + sheetPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); + + final boolean useSameServer; + + final JCheckBox sameServer = new JCheckBox("Use same proxy server for all protocols"); + if(Main.properties.getProperty(Main.httpProxyHost).equals( + Main.properties.getProperty(Main.httpsProxyHost)) && + Main.properties.getProperty(Main.httpProxyHost).equals( + Main.properties.getProperty(Main.ftpProxyHost)) && + Main.properties.getProperty(Main.httpProxyPort).equals( + Main.properties.getProperty(Main.httpsProxyPort)) && + Main.properties.getProperty(Main.httpProxyPort).equals( + Main.properties.getProperty(Main.ftpProxyPort))) { + + sameServer.setSelected(true); + + tfHttpsHost.setText(""); + tfHttpsHost.setEditable(false); + + tfHttpsPort.setText(""); + tfHttpsPort.setEditable(false); + + tfFtpHost.setText(""); + tfFtpHost.setEditable(false); + + tfFtpPort.setText(""); + tfFtpPort.setEditable(false); + useSameServer = true; + } else { + sameServer.setSelected(false); + useSameServer = false; + } + + sameServer.addItemListener(new ItemListener() { + public void itemStateChanged(ItemEvent e) { + if(e.getStateChange() == ItemEvent.SELECTED){ + + tfHttpsHost.setText(""); + tfHttpsHost.setEditable(false); + + tfHttpsPort.setText(""); + tfHttpsPort.setEditable(false); + + tfFtpHost.setText(""); + tfFtpHost.setEditable(false); + + tfFtpPort.setText(""); + tfFtpPort.setEditable(false); + + } else { + + tfHttpsHost.setEditable(true); + + tfHttpsPort.setEditable(true); + + tfFtpHost.setEditable(true); + + tfFtpPort.setEditable(true); + + } + tfHttpHost.setCaretPosition(0); + } + }); + + JPanel checkBoxPanel = new JPanel(); + checkBoxPanel.add(sameServer); + checkBoxPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); + + + // Button part of Dialog + JButton apply = new JButton("Apply"); + apply.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + if(!checkPort(Main.httpProxyPort, tfHttpPort.getText().trim())){ + return; + } + if(sameServer.isSelected()){ + Main.properties.setProperty(Main.httpProxyHost, tfHttpHost.getText().trim()); + Main.properties.setProperty(Main.httpProxyPort, tfHttpPort.getText().trim()); + Main.properties.setProperty(Main.httpsProxyHost, tfHttpHost.getText().trim()); + Main.properties.setProperty(Main.httpsProxyPort, tfHttpPort.getText().trim()); + Main.properties.setProperty(Main.ftpProxyHost, tfHttpHost.getText().trim()); + Main.properties.setProperty(Main.ftpProxyPort, tfHttpPort.getText().trim()); + } else { + if(!checkPort(Main.httpsProxyPort, tfHttpsPort.getText().trim())){ + return; + } + if(!checkPort(Main.ftpProxyPort, tfFtpPort.getText().trim())){ + return; + } + Main.properties.setProperty(Main.httpProxyHost, tfHttpHost.getText().trim()); + Main.properties.setProperty(Main.httpProxyPort, tfHttpPort.getText().trim()); + Main.properties.setProperty(Main.httpsProxyHost, tfHttpsHost.getText().trim()); + Main.properties.setProperty(Main.httpsProxyPort, tfHttpsPort.getText().trim()); + Main.properties.setProperty(Main.ftpProxyHost, tfFtpHost.getText().trim()); + Main.properties.setProperty(Main.ftpProxyPort, tfFtpPort.getText().trim()); + } + + Enumeration en = Main.properties.propertyNames(); + + while(en.hasMoreElements()){ + String key = (String)en.nextElement(); + String val = Main.properties.getProperty(key); + if(val != null && val != ""){ + System.setProperty(key, val); + } + } + + Main.storeProxyProperties(); + + dialog.setVisible(false); + dialog.dispose(); + } + + private boolean checkPort(String portName, String value){ + boolean passed = true; + try{ + if(Integer.parseInt(value) < 0){ + passed = false; + showErrorMessage(portName); + } + } catch(NumberFormatException e){ + passed = false; + showErrorMessage(portName); + } + return passed; + } + + private void showErrorMessage(String portName){ + JOptionPane.showMessageDialog(frame, + portName + " must be a positive integer value", "Invalid entry", + JOptionPane.ERROR_MESSAGE); + } + }); + + JButton reset = new JButton("Reset"); + reset.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + + tfHttpHost.setText(Main.properties.getProperty(Main.httpProxyHost)); + tfHttpPort.setText(Main.properties.getProperty(Main.httpProxyPort)); + + if(useSameServer){ + sameServer.setSelected(true); + + tfHttpsHost.setText(""); + tfHttpsHost.setEditable(false); + + tfHttpsPort.setText(""); + tfHttpsPort.setEditable(false); + + tfFtpHost.setText(""); + tfFtpHost.setEditable(false); + + tfFtpPort.setText(""); + tfFtpPort.setEditable(false); + } else { + tfHttpsHost.setText(Main.properties.getProperty(Main.httpsProxyHost)); + tfHttpsPort.setText(Main.properties.getProperty(Main.httpsProxyPort)); + tfFtpHost.setText(Main.properties.getProperty(Main.ftpProxyHost)); + tfFtpPort.setText(Main.properties.getProperty(Main.ftpProxyPort)); + sameServer.setSelected(false); + } + + } + }); + + JButton cancel = new JButton("Cancel"); + cancel.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + dialog.setVisible(false); + dialog.dispose(); + } + }); + + JPanel buttonPanel = new JPanel(); + buttonPanel.setLayout(new FlowLayout(FlowLayout.CENTER)); + + buttonPanel.add(apply); + buttonPanel.add(reset); + buttonPanel.add(cancel); + + JPanel contentPane = new JPanel(); + contentPane.setLayout(new BorderLayout()); + contentPane.add(sheetPanel, BorderLayout.NORTH); + contentPane.add(checkBoxPanel, BorderLayout.CENTER); + contentPane.add(buttonPanel, BorderLayout.SOUTH); + + dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE); + dialog.setContentPane(contentPane); + dialog.setLocationRelativeTo(frame); + dialog.pack(); + + dialog.setVisible(true); + + tfHttpHost.setCaretPosition(0); + } + } + private class CloseAction extends AbstractAction { public CloseAction() { super("Close"); Index: modules/tools/src/main/java/org/apache/harmony/tools/appletviewer/HTMLParser.java =================================================================== --- modules/tools/src/main/java/org/apache/harmony/tools/appletviewer/HTMLParser.java (revision 618610) +++ modules/tools/src/main/java/org/apache/harmony/tools/appletviewer/HTMLParser.java (working copy) @@ -69,7 +69,13 @@ this.list = list; // Open the stream - InputStreamReader isr = new InputStreamReader(documentBase.openStream()); + InputStreamReader isr = null; + try{ + isr = new InputStreamReader(documentBase.openStream()); + } catch(IOException e){ + System.err.println("I/O exception while reading: " + e.getMessage()); + System.exit(-1); + } parse(isr); } @@ -98,9 +104,12 @@ appletInfo.setParameter("WIDTH", (String)attributes.getAttribute(HTML.Attribute.WIDTH)); appletInfo.setParameter("HEIGHT", (String)attributes.getAttribute(HTML.Attribute.HEIGHT)); appletInfo.setParameter("CODE", (String)attributes.getAttribute(HTML.Attribute.CODE)); - appletInfo.setParameter("CODEBASE", (String)attributes.getAttribute(HTML.Attribute.CODEBASE)); appletInfo.setParameter("ARCHIVE", (String)attributes.getAttribute(HTML.Attribute.ARCHIVE)); + if (htmlTag != HTML.Tag.OBJECT) { + appletInfo.setParameter("CODEBASE", (String)attributes.getAttribute(HTML.Attribute.CODEBASE)); + } + } } Index: modules/tools/src/main/java/org/apache/harmony/tools/appletviewer/Main.java =================================================================== --- modules/tools/src/main/java/org/apache/harmony/tools/appletviewer/Main.java (revision 618610) +++ modules/tools/src/main/java/org/apache/harmony/tools/appletviewer/Main.java (working copy) @@ -17,24 +17,173 @@ package org.apache.harmony.tools.appletviewer; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; + +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.Iterator; +import java.util.Properties; + public class Main { + + static final String propertiesFileName = ".harmony.appletviewer.properties"; + static final String httpProxyHost = "http.proxyHost"; + static final String httpProxyPort = "http.proxyPort"; + static final String httpsProxyHost = "https.proxyHost"; + static final String httpsProxyPort = "https.proxyPort"; + static final String ftpProxyHost = "ftp.proxyHost"; + static final String ftpProxyPort = "ftp.proxyPort"; + static final Properties properties = new Properties(); + + static File propertiesFile; + public static void main(String argv[]) throws Exception { + if (argv.length == 0) { printHelp(); return; } + + ArrayList propertiesList = new ArrayList(); + ArrayList urlsList = new ArrayList(); + + for(int i = 0; i < argv.length; i++){ + if(argv[i].startsWith("-D")){ + propertiesList.add(argv[i].substring(2)); + } else { + urlsList.add(argv[i]); + } + } + + if (urlsList.size() == 0) { + printHelp(); + return; + } + + // Load stored java.properties + String userHomeDir = System.getProperty("user.home"); + propertiesFile = new File(userHomeDir + + File.separator + Main.propertiesFileName); + + boolean needStore = false; + if(propertiesFile.exists()){ + try{ + properties.load(new FileInputStream(propertiesFile)); + } catch(IOException e){ + } + } else { + properties.setProperty(httpProxyHost, ""); + properties.setProperty(httpProxyPort, ""); + properties.setProperty(httpsProxyHost, ""); + properties.setProperty(httpsProxyPort, ""); + properties.setProperty(ftpProxyHost, ""); + properties.setProperty(ftpProxyPort, ""); + needStore = true; + } + + // Parse command line java.properties + + Iterator iterator = propertiesList.iterator(); + while(iterator.hasNext()){ + String prop = iterator.next(); + if(prop != null){ + String[] pair = prop.split("="); + String key = null; + String val = null; + + if(pair[0] != null){ + key = pair[0].trim(); + } + + if(pair[1] != null){ + val = pair[1].trim(); + } + + if(key != null && key != "" && val != null && val != ""){ + if(validatePropertyName(key)){ + properties.setProperty(key, val); + needStore = true; + } else { + System.err.println("Unknown proxy property: " + key); + System.exit(-1); + } + + if(key.endsWith("Port")){ + try{ + if(Integer.parseInt(val) < 0){ + wrongPortMessage(val); + System.exit(-1); + } + } catch(NumberFormatException ex){ + wrongPortMessage(key); + System.exit(-1); + } + } + } + } + } + + if(needStore) storeProxyProperties(); + + Enumeration e = properties.propertyNames(); + + while(e.hasMoreElements()){ + String key = (String)e.nextElement(); + String val = properties.getProperty(key); + if(val != null && val != ""){ + System.setProperty(key, val); + } + } + HTMLParser parser = new HTMLParser(); - Object []applets = parser.parse(argv, 0); + Object []applets = parser.parse(urlsList.toArray(new String[urlsList.size()]), 0); // Start applets for (int i = 0; i < applets.length; i++) new AppletFrame((AppletInfo)applets[i]); } + static void storeProxyProperties(){ + try{ + if(!propertiesFile.exists()) propertiesFile.createNewFile(); + properties.store(new FileOutputStream(propertiesFile), + "User-specific properties for Harmony AppletViewer"); + } catch(IOException e){ + } + } + + private static boolean validatePropertyName(String name){ + if(!name.equals(httpProxyHost) && !name.equals(httpProxyPort) && + !name.equals(httpsProxyHost) && !name.equals(httpsProxyPort) && + !name.equals(ftpProxyHost) && !name.equals(ftpProxyPort)){ + + return false; + } else { + return true; + } + } + + private static void wrongPortMessage(String portName){ + System.err.println(); + System.err.println("Proxy parameter error: " + portName + " must be a positive integer value"); + } + private static void printHelp() { - System.err.println("Applet viewer"); - System.err.println("Usage: appletviewer urls"); + System.err.println("AppletViewer"); + System.err.println("Usage: appletviewer [[-Dproxy.property] ... ] url(s)"); + System.err.println(); + System.err.println("Available proxy properties:"); + System.err.println(); + System.err.println("\thttp.proxyHost"); + System.err.println("\thttp.proxyPort"); + System.err.println("\thttps.proxyHost"); + System.err.println("\thttps.proxyPort"); + System.err.println("\tftp.proxyHost"); + System.err.println("\tftp.proxyPort"); } }