/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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 org.apache.directory.studio.connection.ui.widgets; import java.io.ByteArrayInputStream; import java.io.File; import java.security.cert.Certificate; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.util.Iterator; import org.apache.directory.api.util.FileUtils; import org.apache.directory.api.util.Strings; import org.apache.directory.studio.common.ui.widgets.BaseWidgetUtils; import org.apache.directory.studio.connection.core.StudioKeyStoreManager; import org.apache.directory.studio.connection.ui.ConnectionUIConstants; import org.apache.directory.studio.connection.ui.ConnectionUIPlugin; import org.apache.directory.studio.connection.ui.dialogs.CertificateInfoDialog; import org.apache.directory.studio.connection.ui.wizards.ExportCertificateWizard; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.viewers.DoubleClickEvent; import org.eclipse.jface.viewers.IDoubleClickListener; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredContentProvider; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.wizard.WizardDialog; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.FileDialog; /** * This composite displays a list of certificates and buttons * to add, delete and view certificates : * *
 * +-------------------------------------------------+
 * | +------------------------------------+          |
 * | | abc                                | (View)   |
 * | | xyz                                | (Add)    |
 * | |                                    | (Remove) |
 * | |                                    | (Export) |
 * | +------------------------------------+          |
 * +-------------------------------------------------+
 * 
* @author Apache Directory Project */ public class CertificateListComposite extends Composite { /** The KeyStore wrapper */ private StudioKeyStoreManager keyStoreManager; /** The table containing the KeyStore elements */ private TableViewer tableViewer; /** The View action button */ private Button viewButton; /** The Add action button */ private Button addButton; /** The Remove action button */ private Button removeButton; /** The Export action button */ private Button exportButton; /** * The listener called when the table selection has changed */ private ISelectionChangedListener tableViewerSelectionListener = new ISelectionChangedListener() { /** * {@inheritDoc} */ public void selectionChanged( SelectionChangedEvent event ) { // Enable and disable the button accordingly to the selection : // - 1 line selected : enable remove, view and export // - N lines selected : enable remove, disable view and export // - nothing selected, disable view, remove and exprt viewButton.setEnabled( ( ( IStructuredSelection ) event.getSelection() ).size() == 1 ); removeButton.setEnabled( !event.getSelection().isEmpty() ); exportButton.setEnabled( ( ( IStructuredSelection ) event.getSelection() ).size() == 1 ); } }; /** * The listener called when a line is double-clicked in the table : we will * open the Certificate dialog. */ private IDoubleClickListener tableViewerDoubleClickListener = new IDoubleClickListener() { /** * {@inheritDoc} */ public void doubleClick( DoubleClickEvent event ) { openCertificate( event.getSelection() ); } }; /** * A selection listener on the View button : we will open the Certificate Dialog */ private SelectionAdapter viewButtonSelectionListener = new SelectionAdapter() { /** * {@inheritDoc} */ public void widgetSelected( SelectionEvent event ) { openCertificate( tableViewer.getSelection() ); } }; /** * A selection listener on the Add button : we will open the File Dialog * and let the user select the KeyStore location to add in the table */ private SelectionAdapter addButtonSelectionListener = new SelectionAdapter() { /** * {@inheritDoc} */ public void widgetSelected( SelectionEvent event ) { // Asking the user for the certificate file FileDialog dialog = new FileDialog( getShell(), SWT.OPEN ); dialog.setText( Messages.getString( "CertificateListComposite.LoadCertificate" ) ); //$NON-NLS-1$ String returnedFileName = dialog.open(); if ( returnedFileName != null ) { try { // Reading the certificate X509Certificate certificate = generateCertificate( FileUtils.readFileToByteArray( new File( returnedFileName ) ) ); // Adding the certificate keyStoreManager.addCertificate( certificate ); // Refreshing the table viewer tableViewer.refresh(); tableViewer.setSelection( new StructuredSelection( certificate ) ); } catch ( Exception ex ) { MessageDialog.openError( addButton.getShell(), Messages.getString( "CertificateListComposite.ErrorDialogTitle" ), //$NON-NLS-1$ NLS.bind( Messages.getString( "CertificateListComposite.ErrorDialogMessage" ), //$NON-NLS-1$ ex.getMessage() ) ); } } } }; /** * A selection listener on the Remove button. */ private SelectionAdapter removeButtonSelectionListener = new SelectionAdapter() { /** * {@inheritDoc} */ public void widgetSelected( SelectionEvent event ) { IStructuredSelection selection = ( IStructuredSelection ) tableViewer.getSelection(); Iterator iterator = selection.iterator(); while ( iterator.hasNext() ) { X509Certificate certificate = ( X509Certificate ) iterator.next(); try { keyStoreManager.removeCertificate( certificate ); } catch ( CertificateException ce ) { throw new RuntimeException( ce ); } } tableViewer.refresh(); } }; /** * A selection listener on the Export button. We will open the Export wizard. */ private SelectionAdapter exportButtonSelectionListener = new SelectionAdapter() { /** * {@inheritDoc} */ public void widgetSelected( SelectionEvent event ) { X509Certificate certificate = ( X509Certificate ) ( ( IStructuredSelection ) tableViewer.getSelection() ) .getFirstElement(); WizardDialog dialog = new WizardDialog( getShell(), new ExportCertificateWizard( certificate ) ); dialog.open(); } }; /** * Creates a new instance of CertificateInfoComposite. * * @param parent The paren'ts composite * @param style The widget's style */ public CertificateListComposite( Composite parent, int style ) { super( parent, style ); GridLayout layout = new GridLayout( 1, false ); layout.marginWidth = 0; layout.marginHeight = 0; setLayout( layout ); setLayoutData( new GridData( SWT.FILL, SWT.FILL, true, true ) ); Composite container = new Composite( this, SWT.NONE ); layout = new GridLayout( 2, false ); container.setLayout( layout ); container.setLayoutData( new GridData( GridData.FILL, GridData.FILL, true, true ) ); // Create the Table Viewer tableViewer = new TableViewer( container, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER ); GridData gridData = new GridData( GridData.FILL, GridData.FILL, true, true ); gridData.widthHint = 360; gridData.heightHint = 10; tableViewer.getTable().setLayoutData( gridData ); tableViewer.setContentProvider( new KeyStoreContentProvider() ); tableViewer.setLabelProvider( new KeyStoreLabelProvider() ); tableViewer.addSelectionChangedListener( tableViewerSelectionListener ); tableViewer.addDoubleClickListener( tableViewerDoubleClickListener ); createButtons( container ); } /** * Creates the 4 buttons for this widget : * *
     * (view)
     * (Add)
     * (Remove)
     * (Export)
     * 
*/ private void createButtons( Composite container ) { Composite buttonContainer = BaseWidgetUtils.createColumnContainer( container, 1, 1 ); buttonContainer.setLayoutData( new GridData( GridData.FILL, GridData.FILL, false, false ) ); // The View Button viewButton = BaseWidgetUtils.createButton( buttonContainer, Messages .getString( "CertificateListComposite.ViewButton" ), 1 );//$NON-NLS-1$ viewButton.setEnabled( false ); viewButton.addSelectionListener( viewButtonSelectionListener ); // The Add button addButton = BaseWidgetUtils.createButton( buttonContainer, Messages .getString( "CertificateListComposite.AddButton" ), 1 ); //$NON-NLS-1$ addButton.addSelectionListener( addButtonSelectionListener ); // The remove button removeButton = BaseWidgetUtils.createButton( buttonContainer, Messages .getString( "CertificateListComposite.RemoveButton" ), 1 ); //$NON-NLS-1$ removeButton.setEnabled( false ); removeButton.addSelectionListener( removeButtonSelectionListener ); // The export button exportButton = BaseWidgetUtils.createButton( buttonContainer, Messages .getString( "CertificateListComposite.ExportButton" ), 1 ); //$NON-NLS-1$ exportButton.setEnabled( false ); exportButton.addSelectionListener( exportButtonSelectionListener ); } /** * Creates a certificate from a byte[]. */ private static X509Certificate generateCertificate( byte[] data ) throws CertificateException { CertificateFactory certificateFactory = CertificateFactory.getInstance( "X.509" ); //$NON-NLS-1$ Certificate certificate = certificateFactory.generateCertificate( new ByteArrayInputStream( data ) ); if ( certificate instanceof X509Certificate ) { return ( X509Certificate ) certificate; } return null; } /** * Sets the input for this composite. * * @param keyStoreManager the key store manager */ public void setInput( StudioKeyStoreManager keyStoreManager ) { this.keyStoreManager = keyStoreManager; tableViewer.setInput( keyStoreManager ); } /** * This class is used to give back the content of teh Table viewer */ private class KeyStoreContentProvider implements IStructuredContentProvider { /** * Gets the list of Certificates stored into the selected KeyStore * {@inheritDoc} */ public Object[] getElements( Object inputElement ) { if ( inputElement instanceof StudioKeyStoreManager ) { StudioKeyStoreManager keyStoreManager = ( StudioKeyStoreManager ) inputElement; try { return keyStoreManager.getCertificates(); } catch ( CertificateException e ) { throw new RuntimeException( e ); } } return new Object[]{}; } /** * {@inheritDoc} */ public void dispose() { } /** * {@inheritDoc} */ public void inputChanged( Viewer viewer, Object oldInput, Object newInput ) { } } /** * This helper class is used to decorate the elements in the table : we use the certificate name if any. * @author elecharny * */ class KeyStoreLabelProvider extends LabelProvider { /** * {@inheritDoc} */ public String getText( Object element ) { if ( element instanceof X509Certificate ) { X509Certificate certificate = ( X509Certificate ) element; String certificateName = certificate.getSubjectX500Principal().getName(); if ( Strings.isEmpty( certificateName ) ) { return Messages.getString( "CertificateListComposite.UntitledCertificate" ); //$NON-NLS-1$ } else { return certificateName; } } return super.getText( element ); } /** * {@inheritDoc} */ public Image getImage( Object element ) { if ( element instanceof X509Certificate ) { return ConnectionUIPlugin.getDefault().getImage( ConnectionUIConstants.IMG_CERTIFICATE ); } return super.getImage( element ); } } /** * A private method that opens the Certificate Dialog * @param selection */ private void openCertificate( ISelection selection ) { IStructuredSelection structuredSelection = ( IStructuredSelection ) selection; X509Certificate certificate = ( X509Certificate ) structuredSelection.getFirstElement(); new CertificateInfoDialog( getShell(), new X509Certificate[] { certificate } ).open(); } }