/*
* 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.apacheds.configuration.editor;
import java.net.InetAddress;
import java.net.UnknownHostException;
import org.apache.directory.server.config.beans.ConfigBean;
import org.apache.directory.server.config.beans.DirectoryServiceBean;
import org.apache.directory.studio.apacheds.configuration.actions.EditorExportConfigurationAction;
import org.apache.directory.studio.apacheds.configuration.actions.EditorImportConfigurationAction;
import org.apache.directory.studio.common.ui.CommonUIConstants;
import org.apache.directory.studio.connection.core.Connection;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.StructuredViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.events.VerifyEvent;
import org.eclipse.swt.events.VerifyListener;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
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.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.forms.IManagedForm;
import org.eclipse.ui.forms.editor.FormPage;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.ScrolledForm;
import org.eclipse.ui.forms.widgets.Section;
/**
* This class represents the General Page of the Server Configuration Editor.
*
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
*/
public abstract class ServerConfigurationEditorPage extends FormPage
{
/** The default LDAP port */
protected static final int DEFAULT_PORT_LDAP = 10389;
/** The default LDAPS port */
protected static final int DEFAULT_PORT_LDAPS = 10636;
/** The default Kerberos port */
protected static final int DEFAULT_PORT_KERBEROS = 60088;
/** The default LDAPS port */
protected static final int DEFAULT_PORT_CHANGE_PASSWORD = 60464;
/** The default IPV4 address for servers */
protected static final String DEFAULT_ADDRESS = "0.0.0.0"; //$NON-NLS-1$
protected static final String TABULATION = " "; //$NON-NLS-1$
/** A flag to indicate if the page is initialized */
protected boolean isInitialized = false;
// Dirty listeners
private ModifyListener dirtyModifyListener = new ModifyListener()
{
public void modifyText( ModifyEvent e )
{
setEditorDirty();
}
};
private SelectionListener dirtySelectionListener = new SelectionAdapter()
{
public void widgetSelected( SelectionEvent e )
{
setEditorDirty();
}
};
private ISelectionChangedListener dirtySelectionChangedListener = new ISelectionChangedListener()
{
public void selectionChanged( SelectionChangedEvent event )
{
setEditorDirty();
}
};
/**
* Creates a new instance of GeneralPage.
*
* @param editor the associated editor
* @param id the unique identifier
* @param title The page title
*/
public ServerConfigurationEditorPage( ServerConfigurationEditor editor, String id, String title )
{
super( editor, id, title );
}
/**
* Gets the ServerConfigurationEditor object associated with the page.
*
* @return the ServerConfigurationEditor object associated with the page
*/
public ServerConfigurationEditor getServerConfigurationEditor()
{
return ( ServerConfigurationEditor ) getEditor();
}
/**
* Sets the associated editor dirty.
*/
protected void setEditorDirty()
{
getServerConfigurationEditor().setDirty( true );
}
/**
* Gets the configuration bean associated with the editor.
*
* @return the configuration bean associated with the editor
*/
public ConfigBean getConfigBean()
{
Configuration configuration = getServerConfigurationEditor().getConfiguration();
if ( configuration == null )
{
configuration = new Configuration( new ConfigBean(), null );
getServerConfigurationEditor().setConfiguration( configuration );
}
return configuration.getConfigBean();
}
/**
* Gets the directory service associated with the editor.
*
* @return the directory service bean associated with the editor
*/
public DirectoryServiceBean getDirectoryServiceBean()
{
DirectoryServiceBean directoryServiceBean = getConfigBean().getDirectoryServiceBean();
if ( directoryServiceBean == null )
{
directoryServiceBean = new DirectoryServiceBean();
getConfigBean().addDirectoryService( directoryServiceBean );
}
return directoryServiceBean;
}
/**
* Gets the connection associated with the editor.
*
* @return the connection
*/
public Connection getConnection()
{
IEditorInput editorInput = getEditorInput();
if ( editorInput instanceof ConnectionServerConfigurationInput )
{
return ( ( ConnectionServerConfigurationInput ) editorInput ).getConnection();
}
return null;
}
/**
* {@inheritDoc}
*/
protected void createFormContent( IManagedForm managedForm )
{
ScrolledForm form = managedForm.getForm();
form.setText( getTitle() );
Composite parent = form.getBody();
parent.setLayout( new GridLayout() );
FormToolkit toolkit = managedForm.getToolkit();
toolkit.decorateFormHeading( form.getForm() );
ServerConfigurationEditor editor = ( ServerConfigurationEditor ) getEditor();
IToolBarManager toolbarManager = form.getToolBarManager();
toolbarManager.add( new EditorImportConfigurationAction( editor ) );
toolbarManager.add( new Separator() );
toolbarManager.add( new EditorExportConfigurationAction( editor ) );
toolbarManager.update( true );
createFormContent( parent, toolkit );
isInitialized = true;
}
/**
* Subclasses must implement this method to create the content of their form.
*
* @param parent the parent element
* @param toolkit the form toolkit
*/
protected abstract void createFormContent( Composite parent, FormToolkit toolkit );
/**
* Refreshes the UI.
*/
protected abstract void refreshUI();
/**
* Indicates if the page is initialized.
*
* @return <code>true</code> if the page is initialized,
* <code>false</code> if not.
*/
public boolean isInitialized()
{
return isInitialized;
}
/**
* Creates a Text that can be used to enter a port number.
*
* @param toolkit the toolkit
* @param parent the parent
* @return a Text that can be used to enter a port number
*/
protected Text createPortText( FormToolkit toolkit, Composite parent )
{
Text portText = toolkit.createText( parent, "" ); //$NON-NLS-1$
GridData gd = new GridData( SWT.NONE, SWT.NONE, false, false );
gd.widthHint = 42;
portText.setLayoutData( gd );
portText.addVerifyListener( new VerifyListener()
{
public void verifyText( VerifyEvent e )
{
// Check that it's a valid port. It should be
// any value between 0 and 65535
// Skip spaces on both sides
char[] port = e.text.trim().toCharArray();
if ( port.length > 0 )
{
for ( char c : port )
{
if ( ( c < '0' ) || ( c > '9' ) )
{
// This is an error
e.doit = false;
break;
}
}
}
}
} );
// the port can only have 5 chars max
portText.setTextLimit( 5 );
return portText;
}
/**
* Creates a Text that can be used to enter an address. If the address is incorrect,
* it will be in red while typing until it gets correct.
*
* @param toolkit the toolkit
* @param parent the parent
* @return a Text that can be used to enter an address
*/
protected Text createAddressText( FormToolkit toolkit, Composite parent )
{
final Text addressText = toolkit.createText( parent, "" ); //$NON-NLS-1$
GridData gd = new GridData( SWT.NONE, SWT.NONE, false, false );
gd.widthHint = 200;
addressText.setLayoutData( gd );
addressText.addModifyListener( new ModifyListener()
{
Display display = addressText.getDisplay();
// Check that the address is valid
public void modifyText( ModifyEvent e )
{
Text addressText = (Text)e.widget;
String address = addressText.getText();
try
{
InetAddress.getAllByName( address );
addressText.setForeground( null );
}
catch ( UnknownHostException uhe )
{
addressText.setForeground( display.getSystemColor( SWT.COLOR_RED ) );
}
}
} );
// An address can be fairly long...
addressText.setTextLimit( 256 );
return addressText;
}
/**
* Creates a Text that can be used to enter the number of threads
* (which limit is 999)
*
* @param toolkit the toolkit
* @param parent the parent
* @return a Text that can be used to enter the number of threads
*/
protected Text createNbThreadsText( FormToolkit toolkit, Composite parent )
{
Text nbThreadsText = toolkit.createText( parent, "" ); //$NON-NLS-1$
GridData gd = new GridData( SWT.NONE, SWT.NONE, false, false );
gd.widthHint = 42;
nbThreadsText.setLayoutData( gd );
nbThreadsText.addVerifyListener( new VerifyListener()
{
public void verifyText( VerifyEvent e )
{
// Check that it's a valid number of threads. It should be
// any value between 0 and 999
// Skip spaces on both sides
char[] nbThreads = e.text.trim().toCharArray();
if ( nbThreads.length > 0 )
{
for ( char c : nbThreads )
{
if ( ( c < '0' ) || ( c > '9' ) )
{
// This is an error
e.doit = false;
break;
}
}
}
}
} );
// We can't have more than 999 threads
nbThreadsText.setTextLimit( 3 );
return nbThreadsText;
}
/**
* Creates a Text that can be used to enter the backLog size
*
* @param toolkit the toolkit
* @param parent the parent
* @return a Text that can be used to enter the backlog size
*/
protected Text createBackLogSizeText( FormToolkit toolkit, Composite parent )
{
Text backLogSizetText = toolkit.createText( parent, "" ); //$NON-NLS-1$
GridData gd = new GridData( SWT.NONE, SWT.NONE, false, false );
gd.widthHint = 42;
backLogSizetText.setLayoutData( gd );
backLogSizetText.addVerifyListener( new VerifyListener()
{
public void verifyText( VerifyEvent e )
{
// Check that it's a valid size. It should be
// any value between 0 and 99999
// Skip spaces on both sides
char[] backlogSize = e.text.trim().toCharArray();
if ( backlogSize.length > 0 )
{
for ( char c : backlogSize )
{
if ( ( c < '0' ) || ( c > '9' ) )
{
// This is an error
e.doit = false;
break;
}
}
}
}
} );
// the backlog size can only have 5 chars max
backLogSizetText.setTextLimit( 5 );
return backLogSizetText;
}
/**
* Creates default value Label.
*
* @param toolkit the toolkit
* @param parent the parent
* @param text the text string
* @return a default value Label
*/
protected Label createDefaultValueLabel( FormToolkit toolkit, Composite parent, String text )
{
Label label = toolkit.createLabel( parent,
NLS.bind( Messages.getString( "ServerConfigurationEditorPage.DefaultWithValue" ), text ), SWT.WRAP ); //$NON-NLS-1$
label.setForeground( CommonUIConstants.M_GREY_COLOR );
return label;
}
/**
* Set some Label to Bold
*
* @param label the Label we want to see as Bold
* @return a Label with bold text
*/
protected Label setBold( Label label )
{
FontData fontData = label.getFont().getFontData()[0];
Font boldFont = JFaceResources.getFontRegistry().getBold( fontData.getName() );
label.setFont( boldFont );
return label;
}
/**
* Adds a modify listener to the given Text.
*
* @param text the Text control
* @param listener the listener
*/
protected void addModifyListener( Text text, ModifyListener listener )
{
if ( ( text != null ) && ( !text.isDisposed() ) && ( listener != null ) )
{
text.addModifyListener( listener );
}
}
/**
* Adds a selection changed listener to the given Viewer.
*
* @param viewer the viewer control
* @param listener the listener
*/
protected void addSelectionChangedListener( Viewer viewer, ISelectionChangedListener listener )
{
if ( ( viewer != null ) && ( viewer.getControl() != null ) && ( !viewer.getControl().isDisposed() )
&& ( listener != null ) )
{
viewer.addSelectionChangedListener( listener );
}
}
/**
* Adds a double click listener to the given StructuredViewer.
*
* @param viewer the viewer control
* @param listener the listener
*/
protected void addDoubleClickListener( StructuredViewer viewer, IDoubleClickListener listener )
{
if ( ( viewer != null ) && ( viewer.getControl() != null ) && ( !viewer.getControl().isDisposed() )
&& ( listener != null ) )
{
viewer.addDoubleClickListener( listener );
}
}
/**
* Adds a selection listener to the given Button.
*
* @param button the Button control
* @param listener the listener
*/
protected void addSelectionListener( Button button, SelectionListener listener )
{
if ( ( button != null ) && ( !button.isDisposed() ) && ( listener != null ) )
{
button.addSelectionListener( listener );
}
}
/**
* Removes a modify listener to the given Text.
*
* @param text the Text control
* @param listener the listener
*/
protected void removeModifyListener( Text text, ModifyListener listener )
{
if ( ( text != null ) && ( !text.isDisposed() ) && ( listener != null ) )
{
text.removeModifyListener( listener );
}
}
/**
* Removes a selection changed listener to the given Viewer.
*
* @param viewer the viewer control
* @param listener the listener
*/
protected void removeSelectionChangedListener( Viewer viewer, ISelectionChangedListener listener )
{
if ( ( viewer != null ) && ( viewer.getControl() != null ) && ( !viewer.getControl().isDisposed() )
&& ( listener != null ) )
{
viewer.removeSelectionChangedListener( listener );
}
}
/**
* Removes a selection changed listener to the given Viewer.
*
* @param viewer the viewer control
* @param listener the listener
*/
protected void removeDoubleClickListener( StructuredViewer viewer, IDoubleClickListener listener )
{
if ( ( viewer != null ) && ( viewer.getControl() != null ) && ( !viewer.getControl().isDisposed() )
&& ( listener != null ) )
{
viewer.removeDoubleClickListener( listener );
}
}
/**
* Removes a selection listener to the given Button.
*
* @param button the Button control
* @param listener the listener
*/
protected void removeSelectionListener( Button button, SelectionListener listener )
{
if ( ( button != null ) && ( !button.isDisposed() ) && ( listener != null ) )
{
button.removeSelectionListener( listener );
}
}
/**
* Adds a 'dirty' listener to the given Text.
*
* @param text the Text control
*/
protected void addDirtyListener( Text text )
{
addModifyListener( text, dirtyModifyListener );
}
/**
* Adds a 'dirty' listener to the given Button.
*
* @param button the Button control
*/
protected void addDirtyListener( Button button )
{
addSelectionListener( button, dirtySelectionListener );
}
/**
* Adds a 'dirty' listener to the given Viewer.
*
* @param viewer the viewer control
*/
protected void addDirtyListener( Viewer viewer )
{
addSelectionChangedListener( viewer, dirtySelectionChangedListener );
}
/**
* Removes a 'dirty' listener to the given Text.
*
* @param text the Text control
*/
protected void removeDirtyListener( Text text )
{
removeModifyListener( text, dirtyModifyListener );
}
/**
* Removes a 'dirty' listener to the given Button.
*
* @param button the Button control
*/
protected void removeDirtyListener( Button button )
{
removeSelectionListener( button, dirtySelectionListener );
}
/**
* Removes a 'dirty' listener to the given Viewer.
*
* @param viewer the viewer control
*/
protected void removeDirtyListener( Viewer viewer )
{
removeSelectionChangedListener( viewer, dirtySelectionChangedListener );
}
/**
* Sets the selection state of the button widget.
* <p>
* Verifies that the button exists and is not disposed
* before applying the new selection state.
*
* @param button the button
* @param selected the new selection state
*/
protected void setSelection( Button button, boolean selected )
{
if ( ( button != null ) && ( !button.isDisposed() ) )
{
button.setSelection( selected );
}
}
/**
* Sets the selection of the viewer widget.
* <p>
* Verifies that the viewer exists and is not disposed
* before applying the new selection.
*
* @param button the button
* @param selection the new selection
*/
protected void setSelection( Viewer viewer, Object selection )
{
if ( ( viewer != null ) && ( viewer.getControl() != null ) && ( !viewer.getControl().isDisposed() ) )
{
viewer.setSelection( new StructuredSelection( selection ) );
}
}
/**
* Sets the contents of the text widget.
* <p>
* Verifies that the button exists and is not disposed
* before applying the new text.
*
* @param text the text
* @param string the new text
*/
protected void setText( Text text, String string )
{
if ( ( text != null ) && ( !text.isDisposed() ) )
{
if ( string == null )
{
string = ""; //$NON-NLS-1$
}
text.setText( string );
}
}
/**
* Sets the focus to the given control.
*
* @param control the control
*/
protected void setFocus( Control control )
{
if ( ( control != null ) && ( !control.isDisposed() ) )
{
control.setFocus();
}
}
/**
* Sets the enabled state to the given control.
*
* @param control the control
* @param enabled the enabled state
*/
protected void setEnabled( Control control, boolean enabled )
{
if ( ( control != null ) && ( !control.isDisposed() ) )
{
control.setEnabled( enabled );
}
}
/**
* Sets the given {@link GridData} to the control
* and sets the width to a default value.
*
* @param control the control
* @param gd the grid data
*/
protected void setGridDataWithDefaultWidth( Control control, GridData gd )
{
gd.widthHint = 50;
control.setLayoutData( gd );
}
/**
* A shared method used to create a Section, based on a GridLayout.
*
* @param toolkit The Form toolkit
* @param parent The parent
* @param title The Section title
* @param nbColumns The number of columns for the inner grid
*
* @return The created Composite
*/
protected Composite createSection( FormToolkit toolkit, Composite parent, String title, int nbColumns, int style )
{
Section section = toolkit.createSection( parent, style );
section.setText( Messages.getString( title ) );
section.setLayoutData( new GridData( SWT.FILL, SWT.NONE, true, false ) );
Composite composite = toolkit.createComposite( section );
toolkit.paintBordersFor( composite );
GridLayout gridLayout = new GridLayout( nbColumns, false );
gridLayout.marginHeight = 0;
gridLayout.marginWidth = 0;
composite.setLayout( gridLayout );
section.setClient( composite );
return composite;
}
}