From b7dd29046e232e4d42623655efc28965cce942b8 Mon Sep 17 00:00:00 2001 From: clemenso Date: Fri, 13 Nov 2009 15:13:21 +0000 Subject: git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@546 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4 --- .../main/java/at/gv/egiz/bku/gui/BKUGUIFacade.java | 5 +- .../main/java/at/gv/egiz/bku/gui/BKUGUIImpl.java | 318 +++++++++++---------- .../main/java/at/gv/egiz/bku/gui/MimeFilter.java | 110 ------- .../at/gv/egiz/bku/gui/SecureViewerDialog.java | 146 ++++------ .../java/at/gv/egiz/bku/gui/viewer/MimeFilter.java | 115 ++++++++ .../bku/gui/viewer/SecureViewerSaveDialog.java | 120 ++++++++ .../at/gv/egiz/bku/gui/Messages.properties | 4 + .../at/gv/egiz/bku/gui/Messages_en.properties | 2 +- .../at/gv/egiz/bku/gui/SecureViewerDialogTest.java | 4 +- 9 files changed, 458 insertions(+), 366 deletions(-) delete mode 100644 BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/MimeFilter.java create mode 100644 BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/viewer/MimeFilter.java create mode 100644 BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/viewer/SecureViewerSaveDialog.java (limited to 'BKUCommonGUI') diff --git a/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/BKUGUIFacade.java b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/BKUGUIFacade.java index e4af6443..91c91dcb 100644 --- a/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/BKUGUIFacade.java +++ b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/BKUGUIFacade.java @@ -46,7 +46,7 @@ public interface BKUGUIFacade { public static final String DEFAULT_BACKGROUND = "/at/gv/egiz/bku/gui/chip32.png"; public static final String DEFAULT_ICON = "/at/gv/egiz/bku/gui/chiperling105.png"; public static final String HELP_IMG = "/at/gv/egiz/bku/gui/help.png"; - public static final String HELP_IMG_FOCUS = "/at/gv/egiz/bku/gui/help_focus.png"; + public static final String HELP_IMG_FOCUS = "/at/gv/egiz/bku/gui/help.png"; //help_focus.png"; public static final String HASHDATA_FONT = "Monospaced"; public static final Color ERROR_COLOR = Color.RED; public static final Color HYPERLINK_COLOR = Color.BLUE; @@ -56,6 +56,7 @@ public interface BKUGUIFacade { public static final String TITLE_CARDPIN = "title.cardpin"; public static final String TITLE_SIGN = "title.sign"; public static final String TITLE_ERROR = "title.error"; + public static final String TITLE_WARNING = "title.warning"; public static final String TITLE_ENTRY_TIMEOUT = "title.entry.timeout"; public static final String TITLE_RETRY = "title.retry"; public static final String TITLE_WAIT = "title.wait"; @@ -79,6 +80,8 @@ public interface BKUGUIFacade { public static final String MESSAGE_HASHDATALINK_FOCUS = "hashdatalink.focus"; public static final String MESSAGE_HASHDATALINK_TINY_FOCUS = "hashdatalink.tiny.focus"; public static final String MESSAGE_HASHDATALIST = "hashdatalist"; + public static final String MESSAGE_HASHDATA_VIEWER = "hashdata.viewer"; + public static final String MESSAGE_UNSUPPORTED_MIMETYPE = "unsupported.mimetype"; public static final String MESSAGE_RETRIES = "retries"; public static final String MESSAGE_LAST_RETRY = "retries.last"; public static final String MESSAGE_RETRIES_PINPAD = "retries.pinpad"; diff --git a/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/BKUGUIImpl.java b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/BKUGUIImpl.java index 20fe4f56..baffb3fd 100644 --- a/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/BKUGUIImpl.java +++ b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/BKUGUIImpl.java @@ -19,6 +19,7 @@ package at.gv.egiz.bku.gui; import at.gv.egiz.bku.gui.viewer.FontProviderException; import at.gv.egiz.bku.gui.viewer.FontProvider; +import at.gv.egiz.bku.gui.viewer.SecureViewerSaveDialog; import at.gv.egiz.smcc.PINSpec; import at.gv.egiz.stal.HashDataInput; import java.awt.Color; @@ -1384,26 +1385,34 @@ public class BKUGUIImpl implements BKUGUIFacade { new Object[] {"no signature data provided"}, backListener, backCommand); } else if (dataToBeSigned.size() == 1) { - try { - log.debug("[" + Thread.currentThread().getName() + "] scheduling secure viewer"); - - SwingUtilities.invokeLater(new Runnable() { - - @Override - public void run() { - try { - showSecureViewer(dataToBeSigned.get(0)); - } catch (FontProviderException ex) { - log.error("failed to display secure viewer", ex); - showErrorDialog(ERR_VIEWER, new Object[] {ex.getMessage()}, backListener, backCommand); + //TODO pull out (see also SignedReferencesSelectionListener) + if (SecureViewerDialog.SUPPORTED_MIME_TYPES.contains(dataToBeSigned.get(0).getMimeType())) { + try { + log.debug("[" + Thread.currentThread().getName() + "] scheduling secure viewer"); + + SwingUtilities.invokeLater(new Runnable() { + + @Override + public void run() { + try { + showMessageDialog(TITLE_HASHDATA, MESSAGE_HASHDATA_VIEWER); + showSecureViewer(dataToBeSigned.get(0), backListener, backCommand); + } catch (FontProviderException ex) { + log.error("failed to display secure viewer", ex); + showErrorDialog(ERR_VIEWER, new Object[] {ex.getMessage()}, backListener, backCommand); + } } - } - }); - - } catch (Exception ex) { //InterruptedException InvocationTargetException - log.error("Failed to display secure viewer: " + ex.getMessage()); - log.trace(ex); - showErrorDialog(ERR_UNKNOWN, null, backListener, backCommand); + }); + + } catch (Exception ex) { //InterruptedException InvocationTargetException + log.error("Failed to display secure viewer: " + ex.getMessage()); + log.trace(ex); + showErrorDialog(ERR_UNKNOWN, null, backListener, backCommand); + } + } else { + log.debug("[" + Thread.currentThread().getName() + "] mime-type not supported by secure viewer, scheduling save dialog"); + showMessageDialog(TITLE_HASHDATA, MESSAGE_UNSUPPORTED_MIMETYPE); + SecureViewerSaveDialog.showSaveDialog(dataToBeSigned.get(0), messages, backListener, backCommand); } } else { showSignedReferencesListDialog(dataToBeSigned, backListener, backCommand); @@ -1412,30 +1421,48 @@ public class BKUGUIImpl implements BKUGUIFacade { /** * has to be called from event dispatcher thread - * This method blocks until the dialog's close button is pressed. * @param hashDataText * @param saveListener * @param saveCommand */ - private void showSecureViewer(HashDataInput dataToBeSigned) throws FontProviderException { +// private void showSecureViewer(HashDataInput dataToBeSigned) throws FontProviderException { +// +// log.debug("[" + Thread.currentThread().getName() + "] show secure viewer"); +// if (secureViewer == null) { +// secureViewer = new SecureViewerDialog(null, messages, +// fontProvider, helpMouseListener.getActionListener()); +// +// // workaround for [#439] +// // avoid AlwaysOnTop at least in applet, otherwise make secureViewer AlwaysOnTop since MOCCA Dialog (JFrame created in LocalSTALFactory) is always on top. +// Window window = SwingUtilities.getWindowAncestor(contentPane); +// if (window != null && window.isAlwaysOnTop()) { +// log.debug("make secureViewer alwaysOnTop"); +// secureViewer.setAlwaysOnTop(true); +// } +// } +// secureViewer.setContent(dataToBeSigned); +// log.trace("show secure viewer returned"); +// } + private void showSecureViewer(HashDataInput dataToBeSigned, ActionListener closeListener, String closeCommand) throws FontProviderException { log.debug("[" + Thread.currentThread().getName() + "] show secure viewer"); - if (secureViewer == null) { - secureViewer = new SecureViewerDialog(null, messages, - fontProvider, helpMouseListener.getActionListener()); - - // workaround for [#439] - // avoid AlwaysOnTop at least in applet, otherwise make secureViewer AlwaysOnTop since MOCCA Dialog (JFrame created in LocalSTALFactory) is always on top. - Window window = SwingUtilities.getWindowAncestor(contentPane); - if (window != null && window.isAlwaysOnTop()) { - log.debug("make secureViewer alwaysOnTop"); - secureViewer.setAlwaysOnTop(true); - } + SecureViewerDialog secureViewer = new SecureViewerDialog(null, messages, + closeListener, closeCommand, + fontProvider, helpMouseListener.getActionListener()); + + // workaround for [#439] + // avoid AlwaysOnTop at least in applet, otherwise make secureViewer AlwaysOnTop since MOCCA Dialog (JFrame created in LocalSTALFactory) is always on top. + Window window = SwingUtilities.getWindowAncestor(contentPane); + if (window != null && window.isAlwaysOnTop()) { + log.debug("make secureViewer alwaysOnTop"); + secureViewer.setAlwaysOnTop(true); } secureViewer.setContent(dataToBeSigned); - log.trace("show secure viewer returned"); + log.trace("viewer setContent returned"); } + + private void showSignedReferencesListDialog(final List signedReferences, final ActionListener backListener, final String backCommand) { @@ -1468,44 +1495,10 @@ public class BKUGUIImpl implements BKUGUIFacade { hashDataTable.setDefaultRenderer(HashDataInput.class, new HyperlinkRenderer(renderRefId)); hashDataTable.setTableHeader(null); - // not possible to add mouse listener to TableCellRenderer - hashDataTable.addMouseMotionListener(new MouseMotionAdapter() { - - @Override - public void mouseMoved(MouseEvent e) { - if (hashDataTable.columnAtPoint(e.getPoint()) == 0) { - hashDataTable.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); - } else { - hashDataTable.setCursor(Cursor.getDefaultCursor()); - } - } - }); + hashDataTable.addMouseMotionListener(new SignedReferencesMouseMotionListener(hashDataTable)); hashDataTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); - hashDataTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() { - - @Override - public void valueChanged(final ListSelectionEvent e) { - //invoke later to allow thread to paint selection background - SwingUtilities.invokeLater(new Runnable() { - - @Override - public void run() { - ListSelectionModel lsm = (ListSelectionModel) e.getSource(); - int selectionIdx = lsm.getMinSelectionIndex(); - if (selectionIdx >= 0) { - final HashDataInput selection = signedReferences.get(selectionIdx); - try { - showSecureViewer(selection); - } catch (FontProviderException ex) { - log.error("failed to display secure viewer", ex); - showErrorDialog(ERR_VIEWER, new Object[] {ex.getMessage()}, backListener, backCommand); - } - } - } - }); - } - }); + hashDataTable.getSelectionModel().addListSelectionListener(new SignedReferencesSelectionListener(signedReferences, backListener, backCommand)); JScrollPane hashDataScrollPane = new JScrollPane(hashDataTable); @@ -1560,97 +1553,106 @@ public class BKUGUIImpl implements BKUGUIFacade { }); } + + /** - * @param okListener may be null + * not possible to add mouse listener to TableCellRenderer + * to change cursor on specific columns only, use table.columnAtPoint(e.getPoint()) + * */ -// private void showSaveDialog(final List signedRefs, -// final ActionListener okListener, final String okCommand) { -// -// log.debug("scheduling save dialog"); -// -// SwingUtilities.invokeLater(new Runnable() { -// -// @Override -// public void run() { -// -// log.debug("show save dialog"); -// -// String userHome = System.getProperty("user.home"); -// -// JFileChooser fileDialog = new JFileChooser(userHome); -// fileDialog.setMultiSelectionEnabled(false); -// fileDialog.setDialogType(JFileChooser.SAVE_DIALOG); -// fileDialog.setFileHidingEnabled(true); -// if (signedRefs.size() == 1) { -// fileDialog.setDialogTitle(getMessage(WINDOWTITLE_SAVE)); -// fileDialog.setFileSelectionMode(JFileChooser.FILES_ONLY); -// String mimeType = signedRefs.get(0).getMimeType(); -// MimeFilter mimeFilter = new MimeFilter(mimeType, messages); -// fileDialog.setFileFilter(mimeFilter); -// String filename = getMessage(SAVE_HASHDATAINPUT_PREFIX) + MimeFilter.getExtension(mimeType); -// fileDialog.setSelectedFile(new File(userHome, filename)); -// } else { -// fileDialog.setDialogTitle(getMessage(WINDOWTITLE_SAVEDIR)); -// fileDialog.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); -// } -// -// //parent contentPane -> placed over applet -// switch (fileDialog.showSaveDialog(fileDialog)) { -// case JFileChooser.APPROVE_OPTION: -// File f = fileDialog.getSelectedFile(); -// for (HashDataInput hashDataInput : signedRefs) { -// String mimeType = hashDataInput.getMimeType(); -// String id = hashDataInput.getReferenceId(); -// File file; -// if (f.isDirectory()) { -// String filename = getMessage(SAVE_HASHDATAINPUT_PREFIX) + '_' + id + MimeFilter.getExtension(mimeType); -// file = new File(f, filename); -// } else { -// file = f; -// } -// if (file.exists()) { -// String ovrwrt = getMessage(MESSAGE_OVERWRITE); -// int overwrite = JOptionPane.showConfirmDialog(fileDialog, MessageFormat.format(ovrwrt, file), getMessage(WINDOWTITLE_OVERWRITE), JOptionPane.OK_CANCEL_OPTION); -// if (overwrite != JOptionPane.OK_OPTION) { -// continue; -// } -// } -// if (log.isDebugEnabled()) { -// log.debug("writing hashdata input " + id + " (" + mimeType + ") to file " + file); -// } -// FileOutputStream fos = null; -// try { -// fos = new FileOutputStream(file); -// BufferedOutputStream bos = new BufferedOutputStream(fos); -// InputStream hdi = hashDataInput.getHashDataInput(); -// int b; -// while ((b = hdi.read()) != -1) { -// bos.write(b); -// } -// bos.flush(); -// bos.close(); -// } catch (IOException ex) { -// log.error("Failed to write " + file + ": " + ex.getMessage()); -// showErrorDialog(ERR_WRITE_HASHDATA, new Object[] {ex.getMessage()}, null, null); -// ex.printStackTrace(); -// } finally { -// try { -// fos.close(); -// } catch (IOException ex) { -// } -// } -// } -// break; -// case JFileChooser.CANCEL_OPTION : -// log.debug("cancelled save dialog"); -// break; -// } -// if (okListener != null) { -// okListener.actionPerformed(new ActionEvent(fileDialog, ActionEvent.ACTION_PERFORMED, okCommand)); -// } -// } -// }); -// } + private class SignedReferencesMouseMotionListener extends MouseMotionAdapter { + + JTable hashDataTable; + + public SignedReferencesMouseMotionListener(JTable table) { + this.hashDataTable = table; + } + + @Override + public void mouseMoved(MouseEvent e) { +// if (hashDataTable.columnAtPoint(e.getPoint()) == 0) { + hashDataTable.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); + } + } + + /////////// + // SignedReferencesList (TODO pull out) + + public class SignedReferencesSelectionListener implements ListSelectionListener { + + List signedReferences; + ActionListener backListener; + String backCommand; + + public SignedReferencesSelectionListener(List signedReferences, ActionListener backListener, String backCommand) { + this.signedReferences = signedReferences; + this.backListener = backListener; + this.backCommand = backCommand; + } + + @Override + public void valueChanged(ListSelectionEvent event) { + + if (event.getValueIsAdjusting()) { + return; + } + + ListSelectionModel lsm = (ListSelectionModel) event.getSource(); + int selectionIdx = lsm.getMinSelectionIndex(); + + log.debug("[" + Thread.currentThread().getName() + "] reference " + selectionIdx + " selected"); + + if (selectionIdx >= 0) { + final HashDataInput selection = signedReferences.get(selectionIdx); + final SignedReferencesListDisplayer backToListListener = new SignedReferencesListDisplayer(signedReferences, backListener, backCommand); + + if (SecureViewerDialog.SUPPORTED_MIME_TYPES.contains(selection.getMimeType())) { + log.debug("[" + Thread.currentThread().getName() + "] scheduling secure viewer dialog"); + SwingUtilities.invokeLater(new Runnable() { + + @Override + public void run() { + try { + showMessageDialog(TITLE_HASHDATA, MESSAGE_HASHDATA_VIEWER); + showSecureViewer(selection, backToListListener, null); +// SecureViewerDialog.showSecureViewer(selection, messages, fontProvider, helpMouseListener.getActionListener(), false); + } catch (FontProviderException ex) { + log.error("failed to display secure viewer", ex); + showErrorDialog(BKUGUIFacade.ERR_VIEWER, new Object[] {ex.getMessage()}, backToListListener, null); + } + + } + }); + } else { + log.debug("[" + Thread.currentThread().getName() + "] mime-type not supported by secure viewer, scheduling save dialog"); + showMessageDialog(BKUGUIFacade.TITLE_HASHDATA, BKUGUIFacade.MESSAGE_UNSUPPORTED_MIMETYPE); + SecureViewerSaveDialog.showSaveDialog(selection, messages, backToListListener, null); + } + } + } + + /** + * ActionListener that returns to signed references list + */ + private class SignedReferencesListDisplayer implements ActionListener { + List sr; + ActionListener bl; + String bc; + + public SignedReferencesListDisplayer(List signedReferences, ActionListener backListener, String backCommand) { + sr = signedReferences; + bl = backListener; + bc = backCommand; + } + + @Override + public void actionPerformed(ActionEvent e) { +// log.debug("[" + Thread.currentThread().getName() + "] displaying signed references list"); + showSignedReferencesListDialog(sr, bl, bc); + } + } + } + //////////////////////////////////////////////////////////////////////////// // UTILITY METHODS diff --git a/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/MimeFilter.java b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/MimeFilter.java deleted file mode 100644 index 4b48081a..00000000 --- a/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/MimeFilter.java +++ /dev/null @@ -1,110 +0,0 @@ -/* -* Copyright 2008 Federal Chancellery Austria and -* Graz University of Technology -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -package at.gv.egiz.bku.gui; - -import java.io.File; -import java.util.ResourceBundle; -import javax.swing.filechooser.FileFilter; - -/** - * - * @author clemens - */ -class MimeFilter extends FileFilter { - - private static final String MIMETYPE_DESC_XML = "mimetype.desc.xml"; - private static final String MIMETYPE_DESC_HTML = "mimetype.desc.html"; - private static final String MIMETYPE_DESC_XHTML = "mimetype.desc.xhtml"; - private static final String MIMETYPE_DESC_TXT = "mimetype.desc.txt"; - private static final String MIMETYPE_DESC_PDF = "mimetype.desc.pdf"; - private static final String MIMETYPE_DESC_BIN = "mimetype.desc.bin"; - - protected String mimeType; - protected ResourceBundle messages; - - public MimeFilter(String mimeType, ResourceBundle messages) { - this.mimeType = mimeType; - this.messages = messages; - } - - @Override - public boolean accept(File f) { - - if (f.isDirectory()) { - return true; - } - - String ext = getExtension(f); - if ("text/xml".equals(mimeType)) { - return "xml".equalsIgnoreCase(ext); - } else if ("text/html".equals(mimeType)) { - return "html".equalsIgnoreCase(ext) || "htm".equalsIgnoreCase(ext); - } else if ("application/xhtml+xml".equals(mimeType)) { - return "xhtml".equalsIgnoreCase(ext); - } else if ("text/plain".equals(mimeType)) { - return "txt".equalsIgnoreCase(ext); - } else if ("application/pdf".equals(mimeType)) { - return "pdf".equalsIgnoreCase(ext); - } else { - return true; - } - } - - private String getExtension(File f) { - String ext = null; - String s = f.getName(); - int i = s.lastIndexOf('.'); - - if (i > 0 && i < s.length() - 1) { - ext = s.substring(i + 1).toLowerCase(); - } - return ext; - } - - @Override - public String getDescription() { - if ("text/xml".equals(mimeType)) { - return messages.getString(MIMETYPE_DESC_XML); - } else if ("text/html".equals(mimeType)) { - return messages.getString(MIMETYPE_DESC_HTML); - } else if ("application/xhtml+xml".equals(mimeType)) { - return messages.getString(MIMETYPE_DESC_XHTML); - } else if ("text/plain".equals(mimeType)) { - return messages.getString(MIMETYPE_DESC_TXT); - } else if ("application/pdf".equals(mimeType)) { - return messages.getString(MIMETYPE_DESC_PDF); - } else { - return messages.getString(MIMETYPE_DESC_BIN); - } - } - - public static String getExtension(String mimeType) { - if ("text/xml".equals(mimeType)) { - return ".xml"; - } else if ("text/html".equals(mimeType)) { - return ".html"; - } else if ("application/xhtml+xml".equals(mimeType)) { - return ".xhtml"; - } else if ("text/plain".equals(mimeType)) { - return ".txt"; - } else if ("application/pdf".equals(mimeType)) { - return ".pdf"; - } else { - return ".bin"; - } - } -} \ No newline at end of file diff --git a/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/SecureViewerDialog.java b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/SecureViewerDialog.java index 878a998b..7bae4673 100644 --- a/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/SecureViewerDialog.java +++ b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/SecureViewerDialog.java @@ -17,12 +17,15 @@ package at.gv.egiz.bku.gui; import at.gv.egiz.bku.gui.viewer.FontProvider; +import at.gv.egiz.bku.gui.viewer.FontProviderException; +import at.gv.egiz.bku.gui.viewer.SecureViewerSaveDialog; import at.gv.egiz.stal.HashDataInput; import java.awt.Container; import java.awt.Cursor; import java.awt.Dimension; import java.awt.Font; import java.awt.Frame; +import java.awt.Window; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.FocusAdapter; @@ -41,6 +44,9 @@ import java.io.InputStreamReader; import java.io.Reader; import java.nio.charset.Charset; import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; import java.util.ResourceBundle; import javax.swing.GroupLayout; import javax.swing.ImageIcon; @@ -72,6 +78,12 @@ public class SecureViewerDialog extends JDialog implements ActionListener { * BKUViewer has compile dependency BKUFonts, transitive in BKUOnline and BKULocal */ public static final Dimension VIEWER_DIMENSION = new Dimension(600, 400); + + public static final List SUPPORTED_MIME_TYPES = new ArrayList(); + static { + SUPPORTED_MIME_TYPES.add("text/plain"); + SUPPORTED_MIME_TYPES.add("application/xhtml+xml"); + } protected static final Log log = LogFactory.getLog(SecureViewerDialog.class); // private static SecureViewerDialog dialog; protected ResourceBundle messages; @@ -102,7 +114,7 @@ public class SecureViewerDialog extends JDialog implements ActionListener { // dialog.setVisible(true); // } public SecureViewerDialog(Frame owner, ResourceBundle messages, - // ActionListener saveListener, String saveCommand, + ActionListener closeListener, String closeCommand, FontProvider fontProvider, ActionListener helpListener) { super(owner, messages.getString(BKUGUIFacade.WINDOWTITLE_VIEWER), true); this.setIconImages(BKUIcons.icons); @@ -111,7 +123,7 @@ public class SecureViewerDialog extends JDialog implements ActionListener { initContentPane(VIEWER_DIMENSION, createViewerPanel(helpListener), - createButtonPanel()); //saveListener, saveCommand)); + createButtonPanel(closeListener, closeCommand)); pack(); if (owner != null) { @@ -289,15 +301,22 @@ public class SecureViewerDialog extends JDialog implements ActionListener { toFront(); } - private JPanel createButtonPanel() { //ActionListener saveListener, String saveCommand) { + private JPanel createButtonPanel(ActionListener closeListener, String closeCommand) { JButton closeButton = new JButton(); closeButton.setText(messages.getString(BKUGUIFacade.BUTTON_CLOSE)); - closeButton.setActionCommand("close"); - closeButton.addActionListener(this); + closeButton.setActionCommand(closeCommand); + closeButton.addActionListener(closeListener); + closeButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + log.trace("[" + Thread.currentThread().getName() + "] closing secure viewer"); + setVisible(false); + } + }); JButton saveButton = new JButton(); saveButton.setText(messages.getString(BKUGUIFacade.BUTTON_SAVE)); - saveButton.setActionCommand("save"); + saveButton.setActionCommand("save"); //TODO ensure unequal to closeCommand saveButton.addActionListener(this); int buttonSize = closeButton.getPreferredSize().width; @@ -319,100 +338,37 @@ public class SecureViewerDialog extends JDialog implements ActionListener { @Override public void actionPerformed(ActionEvent e) { - if ("close".equals(e.getActionCommand())) { - log.trace("[" + Thread.currentThread().getName() + "] closing secure viewer"); - setVisible(false); - log.trace("secure viewer closed"); - } else if ("save".equals(e.getActionCommand())) { + if ("save".equals(e.getActionCommand())) { log.trace("[" + Thread.currentThread().getName() + "] display secure viewer save dialog"); - showSaveDialog(content, null, null); + SecureViewerSaveDialog.showSaveDialog(content, messages, null, null); log.trace("done secure viewer save"); } else { log.warn("unknown action command " + e.getActionCommand()); } } + + +// //TEST +// private static SecureViewerDialog secureViewer; +// public static void showSecureViewerXXX(HashDataInput dataToBeSigned, ResourceBundle messages, FontProvider fontProvider, ActionListener helpListener, boolean alwaysOnTop) throws FontProviderException { +// +//// ResourceBundle messages = ResourceBundle.getBundle(BKUGUIFacade.MESSAGES_BUNDLE, locale); +// +// log.debug("[" + Thread.currentThread().getName() + "] show secure viewer"); +// if (secureViewer == null) { +// secureViewer = new SecureViewerDialog(null, messages, +// fontProvider, helpListener); +// +// // workaround for [#439] +// // avoid AlwaysOnTop at least in applet, otherwise make secureViewer AlwaysOnTop since MOCCA Dialog (JFrame created in LocalSTALFactory) is always on top. +//// Window window = SwingUtilities.getWindowAncestor(contentPane); +//// if (window != null && window.isAlwaysOnTop()) { +//// log.debug("make secureViewer alwaysOnTop"); +// secureViewer.setAlwaysOnTop(alwaysOnTop); +//// } +// } +// secureViewer.setContent(dataToBeSigned); +// log.trace("show secure viewer returned"); +// } - private void showSaveDialog(final HashDataInput hashDataInput, - final ActionListener okListener, final String okCommand) { - - log.debug("[" + Thread.currentThread().getName() + "] scheduling save dialog"); - - SwingUtilities.invokeLater(new Runnable() { - - @Override - public void run() { - - log.debug("[" + Thread.currentThread().getName() + "] show save dialog"); - - String userHome = System.getProperty("user.home"); - - JFileChooser fileDialog = new JFileChooser(userHome); - fileDialog.setMultiSelectionEnabled(false); - fileDialog.setDialogType(JFileChooser.SAVE_DIALOG); - fileDialog.setFileHidingEnabled(true); - fileDialog.setDialogTitle(messages.getString(BKUGUIFacade.WINDOWTITLE_SAVE)); - fileDialog.setFileSelectionMode(JFileChooser.FILES_ONLY); - String mimeType = hashDataInput.getMimeType(); - MimeFilter mimeFilter = new MimeFilter(mimeType, messages); - fileDialog.setFileFilter(mimeFilter); - String filename = messages.getString(BKUGUIFacade.SAVE_HASHDATAINPUT_PREFIX) + - MimeFilter.getExtension(mimeType); - fileDialog.setSelectedFile(new File(userHome, filename)); - - //parent contentPane -> placed over applet - switch (fileDialog.showSaveDialog(fileDialog)) { - case JFileChooser.APPROVE_OPTION: - File file = fileDialog.getSelectedFile(); - String id = hashDataInput.getReferenceId(); - if (file.exists()) { - String msgPattern = messages.getString(BKUGUIFacade.MESSAGE_OVERWRITE); - int overwrite = JOptionPane.showConfirmDialog(fileDialog, - MessageFormat.format(msgPattern, file), - messages.getString(BKUGUIFacade.WINDOWTITLE_OVERWRITE), - JOptionPane.OK_CANCEL_OPTION); - if (overwrite != JOptionPane.OK_OPTION) { - return; - } - } - if (log.isDebugEnabled()) { - log.debug("writing hashdata input " + id + " (" + mimeType + ") to file " + file); - } - FileOutputStream fos = null; - try { - fos = new FileOutputStream(file); - BufferedOutputStream bos = new BufferedOutputStream(fos); - InputStream hdi = hashDataInput.getHashDataInput(); - int b; - while ((b = hdi.read()) != -1) { - bos.write(b); - } - bos.flush(); - bos.close(); - } catch (IOException ex) { - log.error("Failed to write " + file + ": " + ex.getMessage()); - log.debug(ex); - String errPattern = messages.getString(BKUGUIFacade.ERR_WRITE_HASHDATA); - JOptionPane.showMessageDialog(fileDialog, - MessageFormat.format(errPattern, ex.getMessage()), - messages.getString(BKUGUIFacade.WINDOWTITLE_ERROR), - JOptionPane.ERROR_MESSAGE); - } finally { - try { - if (fos != null) { - fos.close(); - } - } catch (IOException ex) { - } - } - break; - case JFileChooser.CANCEL_OPTION: - log.debug("cancelled save dialog"); - break; - } - if (okListener != null) { - okListener.actionPerformed(new ActionEvent(fileDialog, ActionEvent.ACTION_PERFORMED, okCommand)); - } - } - }); - } } diff --git a/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/viewer/MimeFilter.java b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/viewer/MimeFilter.java new file mode 100644 index 00000000..c0385dce --- /dev/null +++ b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/viewer/MimeFilter.java @@ -0,0 +1,115 @@ +/* +* Copyright 2008 Federal Chancellery Austria and +* Graz University of Technology +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package at.gv.egiz.bku.gui.viewer; + +import java.io.File; +import java.util.ResourceBundle; +import javax.swing.filechooser.FileFilter; + +/** + * + * @author clemens + */ +class MimeFilter extends FileFilter { + + private static final String MIMETYPE_DESC_XML = "mimetype.desc.xml"; + private static final String MIMETYPE_DESC_HTML = "mimetype.desc.html"; + private static final String MIMETYPE_DESC_XHTML = "mimetype.desc.xhtml"; + private static final String MIMETYPE_DESC_TXT = "mimetype.desc.txt"; + private static final String MIMETYPE_DESC_PDF = "mimetype.desc.pdf"; + private static final String MIMETYPE_DESC_BIN = "mimetype.desc.bin"; + private static final String MIMETYPE_DESC_UNKNOWN = "mimetype.desc.unknown"; + + protected String mimeType; + protected ResourceBundle messages; + + public MimeFilter(String mimeType, ResourceBundle messages) { + this.mimeType = mimeType; + this.messages = messages; + } + + @Override + public boolean accept(File f) { + + if (f.isDirectory()) { + return true; + } + + String ext = getExtension(f); + if ("text/xml".equals(mimeType)) { + return "xml".equalsIgnoreCase(ext); + } else if ("text/html".equals(mimeType)) { + return "html".equalsIgnoreCase(ext) || "htm".equalsIgnoreCase(ext); + } else if ("application/xhtml+xml".equals(mimeType)) { + return "xhtml".equalsIgnoreCase(ext); + } else if ("text/plain".equals(mimeType)) { + return "txt".equalsIgnoreCase(ext); + } else if ("application/pdf".equals(mimeType)) { + return "pdf".equalsIgnoreCase(ext); + } else { + return true; + } + } + + private String getExtension(File f) { + String ext = null; + String s = f.getName(); + int i = s.lastIndexOf('.'); + + if (i > 0 && i < s.length() - 1) { + ext = s.substring(i + 1).toLowerCase(); + } + return ext; + } + + @Override + public String getDescription() { + if ("text/xml".equals(mimeType)) { + return messages.getString(MIMETYPE_DESC_XML); + } else if ("text/html".equals(mimeType)) { + return messages.getString(MIMETYPE_DESC_HTML); + } else if ("application/xhtml+xml".equals(mimeType)) { + return messages.getString(MIMETYPE_DESC_XHTML); + } else if ("text/plain".equals(mimeType)) { + return messages.getString(MIMETYPE_DESC_TXT); + } else if ("application/pdf".equals(mimeType)) { + return messages.getString(MIMETYPE_DESC_PDF); + } else if ("application/octet-stream".equals(mimeType)) { + return messages.getString(MIMETYPE_DESC_BIN); + } else { + return messages.getString(MIMETYPE_DESC_UNKNOWN); + } + } + + public static String getExtension(String mimeType) { + if ("text/xml".equals(mimeType)) { + return ".xml"; + } else if ("text/html".equals(mimeType)) { + return ".html"; + } else if ("application/xhtml+xml".equals(mimeType)) { + return ".xhtml"; + } else if ("text/plain".equals(mimeType)) { + return ".txt"; + } else if ("application/pdf".equals(mimeType)) { + return ".pdf"; + } else if ("application/octet-stream".equals(mimeType)) { + return ".bin"; + } else { + return ""; + } + } +} \ No newline at end of file diff --git a/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/viewer/SecureViewerSaveDialog.java b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/viewer/SecureViewerSaveDialog.java new file mode 100644 index 00000000..40133f95 --- /dev/null +++ b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/viewer/SecureViewerSaveDialog.java @@ -0,0 +1,120 @@ +package at.gv.egiz.bku.gui.viewer; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.text.MessageFormat; +import java.util.Locale; +import java.util.ResourceBundle; + +import javax.swing.JFileChooser; +import javax.swing.JOptionPane; +import javax.swing.SwingUtilities; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import at.gv.egiz.bku.gui.BKUGUIFacade; +import at.gv.egiz.stal.HashDataInput; + +public class SecureViewerSaveDialog { + + protected static final Log log = LogFactory.getLog(SecureViewerSaveDialog.class); + + public static void showSaveDialog(final HashDataInput hashDataInput, final ResourceBundle messages, + final ActionListener okListener, final String okCommand) { + + log.debug("[" + Thread.currentThread().getName() + + "] scheduling save dialog"); + + SwingUtilities.invokeLater(new Runnable() { + + @Override + public void run() { + + log + .debug("[" + Thread.currentThread().getName() + + "] show save dialog"); + + String userHome = System.getProperty("user.home"); + + JFileChooser fileDialog = new JFileChooser(userHome); + fileDialog.setMultiSelectionEnabled(false); + fileDialog.setDialogType(JFileChooser.SAVE_DIALOG); + fileDialog.setFileHidingEnabled(true); + fileDialog.setDialogTitle(messages + .getString(BKUGUIFacade.WINDOWTITLE_SAVE)); + fileDialog.setFileSelectionMode(JFileChooser.FILES_ONLY); + String mimeType = hashDataInput.getMimeType(); + MimeFilter mimeFilter = new MimeFilter(mimeType, messages); + fileDialog.setFileFilter(mimeFilter); + String filename = messages + .getString(BKUGUIFacade.SAVE_HASHDATAINPUT_PREFIX) + + MimeFilter.getExtension(mimeType); + fileDialog.setSelectedFile(new File(userHome, filename)); + + // parent contentPane -> placed over applet + switch (fileDialog.showSaveDialog(fileDialog)) { + case JFileChooser.APPROVE_OPTION: + File file = fileDialog.getSelectedFile(); + String id = hashDataInput.getReferenceId(); + if (file.exists()) { + String msgPattern = messages + .getString(BKUGUIFacade.MESSAGE_OVERWRITE); + int overwrite = JOptionPane.showConfirmDialog(fileDialog, + MessageFormat.format(msgPattern, file), messages + .getString(BKUGUIFacade.WINDOWTITLE_OVERWRITE), + JOptionPane.OK_CANCEL_OPTION); + if (overwrite != JOptionPane.OK_OPTION) { + break; + } + } + if (log.isDebugEnabled()) { + log.debug("writing hashdata input " + id + " (" + mimeType + + ") to file " + file); + } + FileOutputStream fos = null; + try { + fos = new FileOutputStream(file); + BufferedOutputStream bos = new BufferedOutputStream(fos); + InputStream hdi = hashDataInput.getHashDataInput(); + int b; + while ((b = hdi.read()) != -1) { + bos.write(b); + } + bos.flush(); + bos.close(); + } catch (IOException ex) { + log.error("Failed to write " + file + ": " + ex.getMessage()); + log.debug(ex); + String errPattern = messages + .getString(BKUGUIFacade.ERR_WRITE_HASHDATA); + JOptionPane.showMessageDialog(fileDialog, MessageFormat.format( + errPattern, ex.getMessage()), messages + .getString(BKUGUIFacade.WINDOWTITLE_ERROR), + JOptionPane.ERROR_MESSAGE); + } finally { + try { + if (fos != null) { + fos.close(); + } + } catch (IOException ex) { + } + } + break; + case JFileChooser.CANCEL_OPTION: + log.debug("cancelled save dialog"); + break; + } + if (okListener != null) { + okListener.actionPerformed(new ActionEvent(fileDialog, + ActionEvent.ACTION_PERFORMED, okCommand)); + } + } + }); + } +} diff --git a/BKUCommonGUI/src/main/resources/at/gv/egiz/bku/gui/Messages.properties b/BKUCommonGUI/src/main/resources/at/gv/egiz/bku/gui/Messages.properties index b458a214..7135b561 100644 --- a/BKUCommonGUI/src/main/resources/at/gv/egiz/bku/gui/Messages.properties +++ b/BKUCommonGUI/src/main/resources/at/gv/egiz/bku/gui/Messages.properties @@ -20,6 +20,7 @@ title.cardnotsupported=Die Karte wird nicht unterst\u00FCtzt title.cardpin=Karte wird gelesen title.sign=Signatur erstellen title.error=Fehler +title.warning=Achtung title.entry.timeout=Zeit\u00FCberschreitung title.retry=Falsche PIN title.wait=Bitte warten @@ -46,6 +47,8 @@ hashdatalink.tiny.focus=[Signaturdaten] #message.hashdata=Dies ist eine Voransicht des zu signierenden Inhaltes. F\u00FCr Details siehe Hilfe (i). #verwenden sie bitte die von ihrem System zur Verf\u00FCgung gestellte {0} Anwendung. hashdatalist={0} Signaturdaten: +hashdata.viewer=Signaturdaten werden im Betrachter angezeigt +unsupported.mimetype=Signaturdaten können nicht angezeigt werden retries.last=Letzter Versuch! retries=Noch {0} Versuche retries.pinpad.last=Eingabe wiederholen, letzter Versuch! @@ -68,6 +71,7 @@ mimetype.desc.xhtml=XHTML-Dateien (.xhtml) mimetype.desc.txt=Textdateien (.txt) mimetype.desc.pdf=Adobe PDF-Dateien (.pdf) mimetype.desc.bin=Bin\u00E4rdateien (.bin) +mimetype.desc.unknown=Alle Dateien (.*) save.hashdatainput.prefix=Signaturdaten alt.help=Hilfe diff --git a/BKUCommonGUI/src/main/resources/at/gv/egiz/bku/gui/Messages_en.properties b/BKUCommonGUI/src/main/resources/at/gv/egiz/bku/gui/Messages_en.properties index 109b4faa..6e89510e 100644 --- a/BKUCommonGUI/src/main/resources/at/gv/egiz/bku/gui/Messages_en.properties +++ b/BKUCommonGUI/src/main/resources/at/gv/egiz/bku/gui/Messages_en.properties @@ -54,7 +54,7 @@ retries.pinpad=Re-enter pin, {0} tries left overwrite=Overwrite {0}? help=Help topic {0} -warning.xhtml=Remark: This is a preview of the data to-be signed. For standards compliant display see help. +warning.xhtml=Remark: This is a preview of the data to-be signed. For standard-compliant display see help. label.pin={0}: label.pinsize=({0} digits) button.ok=OK diff --git a/BKUCommonGUI/src/test/java/at/gv/egiz/bku/gui/SecureViewerDialogTest.java b/BKUCommonGUI/src/test/java/at/gv/egiz/bku/gui/SecureViewerDialogTest.java index fc8dcd96..131a344f 100644 --- a/BKUCommonGUI/src/test/java/at/gv/egiz/bku/gui/SecureViewerDialogTest.java +++ b/BKUCommonGUI/src/test/java/at/gv/egiz/bku/gui/SecureViewerDialogTest.java @@ -7,6 +7,8 @@ package at.gv.egiz.bku.gui; import at.gv.egiz.stal.impl.ByteArrayHashDataInput; import java.awt.Font; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; import java.io.BufferedInputStream; import java.io.FileInputStream; import java.io.FileNotFoundException; @@ -33,7 +35,7 @@ public class SecureViewerDialogTest { @BeforeClass public static void setUpClass() throws Exception { messages = ResourceBundle.getBundle("at/gv/egiz/bku/gui/Messages"); - secureViewer = new SecureViewerDialog(null, messages, new DummyFontLoader(), null); + secureViewer = new SecureViewerDialog(null, messages,null, null, new DummyFontLoader(), null); } @AfterClass -- cgit v1.2.3