/* * 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; } }