/*****************************************************************************
* Copyright (c) 2008 g-Eclipse Consortium
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Initial development of the original code was made for the
* g-Eclipse project founded by European Union
* project number: FP6-IST-034327 http://www.geclipse.eu/
*
* Contributors:
* Ariel Garcia - initial API and implementation
*****************************************************************************/
package eu.geclipse.ui.dialogs;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
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.Control;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import eu.geclipse.core.accesscontrol.IACL;
import eu.geclipse.core.accesscontrol.IACLEntry;
import eu.geclipse.core.model.IProtectable;
import eu.geclipse.core.reporting.ProblemException;
import eu.geclipse.ui.comparators.TableColumnComparator;
import eu.geclipse.ui.listeners.TableColumnListener;
import eu.geclipse.ui.providers.ACLEntryLabelProvider;
/**
* A dialog for managing the access permissions of grid elements
* implementing {@link IProtectable}.
* <p>
* Editing multiple ACLs is supported only if:
* <ul>
* <li>for all of them <code>canSaveWholeACL() == true</code> (saving single
* entries at a time would be too risky)</li>
* <li>all of them belong to objects of the same type, resp. are instances
* of the same class</li>
* </ul>
*
* @author agarcia
*/
public class AccessControlDialog extends Dialog {
boolean canSaveWholeACL;
/** The list of ACLs to manage */
List< IACL > aclList;
/** The list of ACL entries to display in the dialog */
private List< IACLEntry > entriesList;
private TableViewer tableViewer;
/**
* Constructs the dialog used for access control management.
*
* @param acls the list of {@link IACL}s which should be managed.
* @param canSaveWholeACL if true then the ACL supports being saved as a whole.
* @param parentShell the parent shell for this (modal) dialog.
*/
public AccessControlDialog( final List< IACL > acls,
final boolean canSaveWholeACL,
final Shell parentShell )
{
super( parentShell );
setShellStyle( SWT.CLOSE | SWT.TITLE | SWT.BORDER | SWT.APPLICATION_MODAL
| SWT.RESIZE | SWT.MIN | SWT.MAX );
this.canSaveWholeACL = canSaveWholeACL;
this.aclList = acls;
this.entriesList = new ArrayList< IACLEntry >();
}
/*
* (non-Javadoc)
* @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite)
*/
@Override
public Control createDialogArea( final Composite parent ) {
GridData gData;
Composite mainComp = new Composite( parent, SWT.NONE );
mainComp.setLayout( new GridLayout( 1, false ) );
gData = new GridData( SWT.FILL, SWT.FILL, true, true );
gData.grabExcessHorizontalSpace = true;
gData.grabExcessVerticalSpace = true;
mainComp.setLayoutData( gData );
Group aclGroup = new Group( mainComp, SWT.NONE );
aclGroup.setLayout( new GridLayout( 2, false ) );
aclGroup.setText( Messages.getString("AccessControlDialog.group_title") ); //$NON-NLS-1$
gData = new GridData( SWT.FILL, SWT.FILL, true, true );
gData.heightHint = 200;
aclGroup.setLayoutData( gData );
int style = SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL | SWT.SINGLE;
Table aclEntriesTable = new Table( aclGroup, style );
gData = new GridData( SWT.FILL, SWT.FILL, true, true);
aclEntriesTable.setLayoutData( gData );
aclEntriesTable.setHeaderVisible( true );
TableColumn policyColumn = new TableColumn( aclEntriesTable, SWT.LEAD );
policyColumn.setText( Messages.getString("AccessControlDialog.policy_column_title") ); //$NON-NLS-1$
policyColumn.setToolTipText( Messages.getString("AccessControlDialog.policy_tooltip") ); //$NON-NLS-1$
policyColumn.setWidth( 120 );
policyColumn.setAlignment( SWT.LEAD );
TableColumn capabilityColumn = new TableColumn( aclEntriesTable, SWT.LEAD );
capabilityColumn.setText( Messages.getString("AccessControlDialog.capability_column_title") ); //$NON-NLS-1$
capabilityColumn.setToolTipText( Messages.getString("AccessControlDialog.capability_tooltip") ); //$NON-NLS-1$
capabilityColumn.setWidth( 100 );
capabilityColumn.setAlignment( SWT.LEAD );
TableColumn actorTypeColumn = new TableColumn( aclEntriesTable, SWT.LEAD );
actorTypeColumn.setText( Messages.getString("AccessControlDialog.actor_type_column_title") ); //$NON-NLS-1$
actorTypeColumn.setToolTipText( Messages.getString("AccessControlDialog.actor_type_tooltip") ); //$NON-NLS-1$
actorTypeColumn.setWidth( 130 );
actorTypeColumn.setAlignment( SWT.LEAD );
TableColumn actorIDColumn = new TableColumn( aclEntriesTable, SWT.LEAD );
actorIDColumn.setText( Messages.getString("AccessControlDialog.actor_ID_column_title") ); //$NON-NLS-1$
actorIDColumn.setToolTipText( Messages.getString("AccessControlDialog.actor_ID_tooltip") ); //$NON-NLS-1$
actorIDColumn.setWidth( 300 );
actorIDColumn.setAlignment( SWT.LEAD );
TableColumn actorCAColumn = new TableColumn( aclEntriesTable, SWT.LEAD );
actorCAColumn.setText( Messages.getString("AccessControlDialog.actor_CA_column_title") ); //$NON-NLS-1$
actorCAColumn.setToolTipText( Messages.getString("AccessControlDialog.actor_CA_tooltip") ); //$NON-NLS-1$
actorCAColumn.setWidth( 150 );
actorCAColumn.setAlignment( SWT.LEAD );
this.tableViewer = new TableViewer( aclEntriesTable );
this.tableViewer.setContentProvider( new ArrayContentProvider() );
this.tableViewer.setLabelProvider( new ACLEntryLabelProvider() );
// Add listener for column sorting
TableColumnListener columnListener = new TableColumnListener( this.tableViewer );
for ( TableColumn column : aclEntriesTable.getColumns() ) {
column.addSelectionListener( columnListener );
}
// Initially sort by the capability column, ascending
aclEntriesTable.setSortColumn( capabilityColumn );
aclEntriesTable.setSortDirection( SWT.UP );
// Set also the capability column as fall back sorting column
this.tableViewer.setComparator( new TableColumnComparator( capabilityColumn ) );
Composite buttons = new Composite( aclGroup, SWT.NULL );
gData = new GridData( SWT.CENTER, SWT.BEGINNING, false, false );
gData.horizontalSpan = 1;
buttons.setLayoutData( gData );
GridLayout gLayout = new GridLayout( 1, false );
gLayout.marginHeight = 0;
gLayout.marginWidth = 0;
buttons.setLayout( gLayout );
Button addEntryButton = new Button( buttons, SWT.PUSH );
addEntryButton.setText( Messages.getString("AccessControlDialog.add_button_text") ); //$NON-NLS-1$
gData = new GridData( GridData.FILL_HORIZONTAL );
addEntryButton.setLayoutData( gData );
addEntryButton.addSelectionListener( new SelectionAdapter() {
@Override
public void widgetSelected( final SelectionEvent e ) {
IACLEntry newEntry = AccessControlDialog.this.aclList.get( 0 ).getEmptyEntry();
editEntry( newEntry );
}
} );
Button editEntryButton = new Button( buttons, SWT.PUSH );
editEntryButton.setText( Messages.getString("AccessControlDialog.edit_button_text") ); //$NON-NLS-1$
gData = new GridData( GridData.FILL_HORIZONTAL );
editEntryButton.setLayoutData( gData );
editEntryButton.addSelectionListener( new SelectionAdapter() {
@Override
public void widgetSelected( final SelectionEvent e ) {
editEntry( getSelectedEntry() );
}
} );
Button removeEntryButton = new Button( buttons, SWT.PUSH );
removeEntryButton.setText( Messages.getString("AccessControlDialog.remove_button_text") ); //$NON-NLS-1$
gData = new GridData( GridData.FILL_HORIZONTAL );
removeEntryButton.setLayoutData( gData );
removeEntryButton.addSelectionListener( new SelectionAdapter() {
@Override
public void widgetSelected( final SelectionEvent e ) {
removeEntry();
}
} );
// Fetch the entries to initialise the table
initialize();
if ( this.entriesList != null ) {
this.tableViewer.setInput( this.entriesList );
}
return mainComp;
}
/**
* Initialises the entries which should be displayed and managed in the
* dialog.
*/
private void initialize() {
// TODO add Progress monitor!!
IACL acl = this.aclList.get( 0 );
if ( acl != null ) {
try {
for ( IACLEntry entry : acl.getEntries( null ) ) {
this.entriesList.add( entry );
}
} catch ( ProblemException pe ) {
// TODO: handle exception
}
}
}
/*
* (non-Javadoc)
* @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell)
*/
@Override
protected void configureShell( final Shell shell ) {
super.configureShell( shell );
shell.setText( Messages.getString("AccessControlDialog.dialog_title") ); //$NON-NLS-1$
}
/**
* Create the dialog buttons. We override the superclass' method to be
* able to modify the 'OK' button label if the ACL can be saved as a whole,
* and presenting only a 'Done' button if the entries are saved by the
* sub-dialog {@link AccessControlRuleDialog}.
*/
@Override
protected void createButtonsForButtonBar( final Composite parent ) {
// We just change the label of the OK button
String buttonText = null;
if ( this.canSaveWholeACL ) {
buttonText = Messages.getString("AccessControlDialog.save_button_text"); //$NON-NLS-1$
} else {
buttonText = Messages.getString("AccessControlDialog.done_button_text"); //$NON-NLS-1$
}
createButton( parent, IDialogConstants.OK_ID,
buttonText, true );
// Avoid having a Cancel button if there is nothing to cancel
if ( this.canSaveWholeACL ) {
createButton( parent, IDialogConstants.CANCEL_ID,
IDialogConstants.CANCEL_LABEL, false );
}
}
/**
* Returns the currently selected ACL entry.
*
* @return the {@link IACLEntry} that is currently selected in the table control.
*/
IACLEntry getSelectedEntry() {
IACLEntry entry = null;
IStructuredSelection selection
= ( IStructuredSelection ) this.tableViewer.getSelection();
Object obj = selection.getFirstElement();
if ( obj instanceof IACLEntry ) {
entry = ( IACLEntry ) obj;
}
return entry;
}
/**
* Helper method to edit an entry.
*
* @param entry the ACL entry to edit.
*/
void editEntry( final IACLEntry entry ) {
AccessControlRuleDialog dialog
= new AccessControlRuleDialog( entry,
! this.canSaveWholeACL,
this.getShell() );
int result = dialog.open();
switch ( result ) {
case Window.OK :
//save();
break;
case Window.CANCEL :
//undo();
break;
default :
break;
}
}
/**
* Helper method for removing the entry selected in the table.
*/
void removeEntry() {
/*
* We only ask for confirmation if the changes cannot be cancelled,
* i.e. if single ACL entries have to be saved separately.
*/
boolean confirm = true;
if ( ! this.canSaveWholeACL ) {
confirm = MessageDialog.openConfirm( this.getShell(),
"Remove rule",
"You are going to remove this access control rule. Continue?" );
}
// TODO add Progress monitor!!
if ( confirm ) {
IACLEntry entry = getSelectedEntry();
try {
// This ACLEntry may belong to several ACLs
for ( IACL acl : this.aclList ) {
acl.removeEntry( entry, null );
}
this.entriesList.remove( entry );
} catch ( ProblemException pe ) {
ProblemDialog.openProblem( this.getShell(),
"Error deleting rule",
"The selected rule could not be deleted",
pe );
}
}
}
}