/*******************************************************************************
 * Copyright (c) 2008 IONA Technologies PLC
 * 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
 *
 * Contributors:
 * IONA Technologies PLC - initial API and implementation
 *******************************************************************************/
package org.eclipse.jst.ws.internal.cxf.ui.preferences;

import java.io.File;
import java.io.FilenameFilter;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.preference.PreferencePage;
import org.eclipse.jst.ws.internal.cxf.core.CXFCorePlugin;
import org.eclipse.jst.ws.internal.cxf.core.model.CXFContext;
import org.eclipse.jst.ws.internal.cxf.core.model.CXFPackage;
import org.eclipse.jst.ws.internal.cxf.core.utils.CXFModelUtils;
import org.eclipse.jst.ws.internal.cxf.core.utils.LaunchUtils;
import org.eclipse.jst.ws.internal.cxf.ui.CXFUIMessages;
import org.eclipse.jst.ws.internal.cxf.ui.CXFUIPlugin;
import org.eclipse.jst.ws.internal.cxf.ui.widgets.AnnotationsComposite;
import org.eclipse.jst.ws.internal.cxf.ui.widgets.BlankRuntimePreferencesComposite;
import org.eclipse.jst.ws.internal.cxf.ui.widgets.CXF20WSDL2JavaPreferencesComposite;
import org.eclipse.jst.ws.internal.cxf.ui.widgets.CXF21WSDL2JavaPreferencesComposite;
import org.eclipse.jst.ws.internal.cxf.ui.widgets.Java2WSDLRuntimePreferencesComposite;
import org.eclipse.jst.ws.internal.cxf.ui.widgets.Java2WSRuntimePreferencesComposite;
import org.eclipse.jst.ws.internal.cxf.ui.widgets.SpringConfigComposite;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StackLayout;
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.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.DirectoryDialog;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.TabFolder;
import org.eclipse.swt.widgets.TabItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPreferencePage;
import org.osgi.framework.Version;

public class CXFRuntimePreferencePage extends PreferencePage implements IWorkbenchPreferencePage {
    private IStatus CXF_LOCATION_STATUS = new Status(IStatus.OK, CXFUIPlugin.PLUGIN_ID, null);
    private IStatus OK_STATUS = new Status(IStatus.OK, CXFUIPlugin.PLUGIN_ID, ""); //$NON-NLS-1$
    
    private Pattern digitPattern = Pattern.compile("\\d"); //$NON-NLS-1$
    
    private Button browseButton;
    private Text cxfHomeDirText;

    private Label cxfToolVersionLabel;
    
    private Button exportCXFClasspathContainerButton;

    private CXFContext context;

    private Java2WSDLRuntimePreferencesComposite java2WSDLRuntimePreferencesComposite;
    private Java2WSRuntimePreferencesComposite java2WSRuntimePreferencesComposite ;
    
    private CXF20WSDL2JavaPreferencesComposite cxf20WSDL2JavaPreferencesComposite;
    private CXF21WSDL2JavaPreferencesComposite cxf21WSDL2JavaPreferencesComposite;
    
    private AnnotationsComposite annotationsComposite;
    
    private SpringConfigComposite springConfigComposite;
    
    private StackLayout java2WSStackLayout;
    private StackLayout wsdl2javaStackLayout;
    private StackLayout jaxwsStackLayout;
    private StackLayout springConfigStackLayout;
    
    private Composite java2WSPreferncesGroup;
    private Composite wsdl2JavaPreferencesGroup;
    private Composite jaxwsPreferencesGroup;
    private Composite springConfigPreferncesGroup;
    
    private Composite java2WSDLPreferencesComposite;
    private Composite java2WSPreferencesComposite;
    
    private Composite jaxwsPreferencesComposite;
    
    private Composite wsdl2Java20PreferencesComposite;
    private Composite wsdl2Java21PreferencesComposite;

    private Composite springPreferencesComposite;
    
    private BlankRuntimePreferencesComposite java2WSBlankPreferencesComposite;
    private BlankRuntimePreferencesComposite wsdl2JavaBlankPreferencesComposite;
    private BlankRuntimePreferencesComposite jaxwsBlankPreferencesComposite;
    private BlankRuntimePreferencesComposite springConfigBlankPreferencesComposite;

    public CXFRuntimePreferencePage() {
    }

    public void init(IWorkbench workbench) {
    }

    @Override
    protected Control createContents(Composite parent) {
        context = CXFCorePlugin.getDefault().getJava2WSContext();

        final Composite composite = new Composite(parent, SWT.NONE);

        GridLayout mainLayout = new GridLayout();
        composite.setLayout(mainLayout);
        GridData gridData = new GridData(GridData.FILL_BOTH);
        composite.setLayoutData(gridData);

        TabFolder cxfPreferenceTab = new TabFolder(composite, SWT.NONE);
        gridData = new GridData(GridData.FILL_BOTH);
        cxfPreferenceTab.setLayoutData(gridData);

        //CXF Runtime Location
        TabItem runtimeInstalLocationItem = new TabItem(cxfPreferenceTab, SWT.NONE);
        runtimeInstalLocationItem.setText(CXFUIMessages.CXF_RUNTIME_PREFERENCE_PAGE_RUNTIME_HOME_TAB_NAME);
        runtimeInstalLocationItem
                .setToolTipText(CXFUIMessages.CXF_RUNTIME_PREFERENCE_PAGE_RUNTIME_HOME_TAB_TOOLTIP);

        final Composite runtimeGroup = new Composite(cxfPreferenceTab, SWT.NONE);

        runtimeInstalLocationItem.setControl(runtimeGroup);
        runtimeGroup.setToolTipText(CXFUIMessages.CXF_RUNTIME_PREFERENCE_PAGE_RUNTIME_HOME_TAB_TOOLTIP);

        GridLayout runtimeLoactionlayout = new GridLayout();

        runtimeLoactionlayout.numColumns = 3;
        runtimeLoactionlayout.marginHeight = 10;
        runtimeGroup.setLayout(runtimeLoactionlayout);
        gridData = new GridData(GridData.FILL_BOTH);
        runtimeGroup.setLayoutData(gridData);

        Label label = new Label(runtimeGroup, SWT.NONE);
        label.setText(CXFUIMessages.CXF_RUNTIME_PREFERENCE_PAGE_CXF_HOME_DIR_LABEL);

        cxfHomeDirText = new Text(runtimeGroup, SWT.BORDER);
        if (context.getCxfRuntimeLocation() != null) {
            cxfHomeDirText.setText(context.getCxfRuntimeLocation());
        }

        gridData = new GridData(GridData.FILL_HORIZONTAL);

        cxfHomeDirText.setLayoutData(gridData);
        cxfHomeDirText.addModifyListener(new ModifyListener() {
            public void modifyText(ModifyEvent e) {
                context.setCxfRuntimeLocation(cxfHomeDirText.getText());
                updateStatus();
                handlePreferenceControls();
            }
        });

        browseButton = new Button(runtimeGroup, SWT.NONE);
        browseButton.setText(CXFUIMessages.CXF_RUNTIME_PREFERENCE_PAGE_BROWSE_BUTTON_LABEL);

        browseButton.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                DirectoryDialog fileDialog = new DirectoryDialog(composite.getShell());
                String fileName = fileDialog.open();
                if (fileName != null) {
                    cxfHomeDirText.setText(fileName);
                    context.setCxfRuntimeLocation(cxfHomeDirText.getText());
                }
            }
        });

        // CXF Version
        Label cxfVersionLabel = new Label(runtimeGroup, SWT.NONE);
        cxfVersionLabel.setText(CXFUIMessages.CXF_RUNTIME_PREFERENCE_PAGE_CXF_VERSON_LABEL);
        gridData = new GridData(SWT.FILL, SWT.FILL, false, false);
        cxfVersionLabel.setLayoutData(gridData);

        cxfToolVersionLabel = new Label(runtimeGroup, SWT.NONE);
        gridData = new GridData(SWT.FILL, SWT.FILL, false, false);
        gridData.horizontalSpan = 2;
        cxfToolVersionLabel.setLayoutData(gridData);
        
        Label paddingLabel = new Label(runtimeGroup, SWT.NONE);
        gridData = new GridData(SWT.FILL, SWT.FILL, false, false);
        gridData.horizontalSpan = 3;
        paddingLabel.setLayoutData(gridData);
        
        exportCXFClasspathContainerButton = new Button(runtimeGroup, SWT.CHECK);
        exportCXFClasspathContainerButton.setText(
                CXFUIMessages.CXF_RUNTIME_PREFERENCE_PAGE_EXPORT_CXF_CLASSPATH_CONTAINER);
        exportCXFClasspathContainerButton.setSelection(context.isExportCXFClasspathContainer());
        exportCXFClasspathContainerButton.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                context.setExportCXFClasspathContainer(((Button) e.widget).getSelection());
            }
        });
        gridData = new GridData(SWT.FILL, SWT.FILL, false, false);
        gridData.horizontalSpan = 3;
        exportCXFClasspathContainerButton.setLayoutData(gridData);
        
        if (context.getCxfRuntimeVersion().length() > 0) {
            cxfToolVersionLabel.setText(context.getCxfRuntimeEdition() + " " + context.getCxfRuntimeVersion()); //$NON-NLS-1$
            exportCXFClasspathContainerButton.setEnabled(true);
        } else {
            exportCXFClasspathContainerButton.setEnabled(false);
        }
        
        //Java2WS
        TabItem java2WSTabItem = new TabItem(cxfPreferenceTab, SWT.NONE);
        java2WSTabItem.setText(CXFUIMessages.JAVA2WS_PREFERENCES_TAB_NAME);
        java2WSTabItem.setToolTipText(CXFUIMessages.JAVA2WS_PREFERENCES_TAB_TOOLTIP);

        java2WSPreferncesGroup = new Composite(cxfPreferenceTab, SWT.NONE);

        java2WSStackLayout = new StackLayout();
        java2WSPreferncesGroup.setLayout(java2WSStackLayout);

        java2WSDLPreferencesComposite = new Composite(java2WSPreferncesGroup, SWT.NONE);
        GridLayout java2WSGridLayout = new GridLayout(1, true);
        java2WSDLPreferencesComposite.setLayout(java2WSGridLayout);

        java2WSDLRuntimePreferencesComposite = new Java2WSDLRuntimePreferencesComposite(
                java2WSDLPreferencesComposite, SWT.NONE, cxfPreferenceTab);
        java2WSDLRuntimePreferencesComposite.addControls();

        java2WSPreferencesComposite = new Composite(java2WSPreferncesGroup, SWT.NONE);
        GridLayout java2WSDLGridLayout = new GridLayout(1, true);
        java2WSPreferencesComposite.setLayout(java2WSDLGridLayout);

        java2WSRuntimePreferencesComposite = new Java2WSRuntimePreferencesComposite(
                java2WSPreferencesComposite, SWT.NONE, cxfPreferenceTab);
        java2WSRuntimePreferencesComposite.addControls();

        java2WSBlankPreferencesComposite = new BlankRuntimePreferencesComposite(java2WSPreferncesGroup,
                SWT.NONE);

        java2WSTabItem.setControl(java2WSPreferncesGroup);
        
        //WSDL2Java
        TabItem wsdl2JavaTabItem = new TabItem(cxfPreferenceTab, SWT.NONE);
        wsdl2JavaTabItem.setText(CXFUIMessages.WSDL2JAVA_PREFERENCES_TAB_NAME);
        wsdl2JavaTabItem.setToolTipText(CXFUIMessages.WSDL2JAVA_PREFERENCES_TAB_TOOLTIP);

        wsdl2JavaPreferencesGroup = new Composite(cxfPreferenceTab, SWT.NONE);
        
        wsdl2javaStackLayout = new StackLayout();
        wsdl2JavaPreferencesGroup.setLayout(wsdl2javaStackLayout);

        wsdl2Java20PreferencesComposite = new Composite(wsdl2JavaPreferencesGroup, SWT.NONE);
        GridLayout wsdl2Java20GridLayout = new GridLayout(1, true);
        wsdl2Java20PreferencesComposite.setLayout(wsdl2Java20GridLayout);

        cxf20WSDL2JavaPreferencesComposite = new CXF20WSDL2JavaPreferencesComposite(
                wsdl2Java20PreferencesComposite, SWT.NONE);
        cxf20WSDL2JavaPreferencesComposite.addControls();

        wsdl2Java21PreferencesComposite = new Composite(wsdl2JavaPreferencesGroup, SWT.NONE);
        GridLayout wsdl2Java21GridLayout = new GridLayout(1, true);
        wsdl2Java21PreferencesComposite.setLayout(wsdl2Java21GridLayout);

        cxf21WSDL2JavaPreferencesComposite = new CXF21WSDL2JavaPreferencesComposite(
                wsdl2Java21PreferencesComposite, SWT.NONE);
        cxf21WSDL2JavaPreferencesComposite.addControls();

        wsdl2JavaBlankPreferencesComposite = new BlankRuntimePreferencesComposite(wsdl2JavaPreferencesGroup,
                SWT.NONE);

        wsdl2JavaTabItem.setControl(wsdl2JavaPreferencesGroup);
        
        //JAX-WS
        TabItem annotationsTabItem = new TabItem(cxfPreferenceTab, SWT.NONE);
        annotationsTabItem.setText(CXFUIMessages.ANNOTATIONS_PREFERENCES_TAB_NAME);
        annotationsTabItem.setToolTipText(CXFUIMessages.ANNOTATIONS_PREFERENCES_TAB_TOOLTIP);
        
        jaxwsPreferencesGroup = new Composite(cxfPreferenceTab, SWT.NONE);
        
        jaxwsStackLayout = new StackLayout();
        jaxwsPreferencesGroup.setLayout(jaxwsStackLayout);
        
        jaxwsPreferencesComposite = new Composite(jaxwsPreferencesGroup, SWT.NONE);
        GridLayout jaxwsGridLayout = new GridLayout(1, true);
        jaxwsPreferencesComposite.setLayout(jaxwsGridLayout);
        annotationsComposite = new AnnotationsComposite(jaxwsPreferencesComposite,  SWT.SHADOW_IN);
        
        jaxwsBlankPreferencesComposite = new BlankRuntimePreferencesComposite(jaxwsPreferencesGroup,
                SWT.NONE);
        
        annotationsTabItem.setControl(jaxwsPreferencesGroup);
        
        //Spring Config
        TabItem springConfigTabItem = new TabItem(cxfPreferenceTab, SWT.NONE);
        springConfigTabItem.setText(CXFUIMessages.SPRING_CONFIG_PREFERENCES_TAB_NAME);
        springConfigTabItem.setToolTipText(CXFUIMessages.SPRING_CONFIG_PREFERENCES_TAB_TOOLTIP);
        
        springConfigPreferncesGroup = new Composite(cxfPreferenceTab, SWT.NONE);
        
        springConfigStackLayout = new StackLayout();
        springConfigPreferncesGroup.setLayout(springConfigStackLayout);
        
        springPreferencesComposite = new Composite(springConfigPreferncesGroup, SWT.NONE);
        GridLayout springGridLayout = new GridLayout(1, true);
        springPreferencesComposite.setLayout(springGridLayout);
        springConfigComposite = new SpringConfigComposite(springPreferencesComposite, SWT.SHADOW_IN);
        
        springConfigBlankPreferencesComposite = new BlankRuntimePreferencesComposite(springConfigPreferncesGroup,
                SWT.NONE);

        springConfigTabItem.setControl(springConfigPreferncesGroup);

        handlePreferenceControls();

        return composite;
    }

    private void handlePreferenceControls() {
        if (context.getCxfRuntimeLocation().equals("") || context.getCxfRuntimeVersion().equals("")) { //$NON-NLS-1$ //$NON-NLS-2$
            java2WSStackLayout.topControl = java2WSBlankPreferencesComposite;
            wsdl2javaStackLayout.topControl = wsdl2JavaBlankPreferencesComposite;
            jaxwsStackLayout.topControl = jaxwsBlankPreferencesComposite;
            springConfigStackLayout.topControl = springConfigBlankPreferencesComposite;
        } else if (context.getCxfRuntimeVersion().compareTo(CXFCorePlugin.CXF_VERSION_2_1) >= 0) {
            java2WSStackLayout.topControl = java2WSPreferencesComposite;
            wsdl2javaStackLayout.topControl = wsdl2Java21PreferencesComposite;
            jaxwsStackLayout.topControl = jaxwsPreferencesComposite;
            springConfigStackLayout.topControl = springPreferencesComposite;
        } else {
            java2WSStackLayout.topControl = java2WSDLPreferencesComposite;
            wsdl2javaStackLayout.topControl = wsdl2Java20PreferencesComposite;
            jaxwsStackLayout.topControl = jaxwsPreferencesComposite;
            springConfigStackLayout.topControl = springPreferencesComposite;
        }
        java2WSPreferncesGroup.layout();
        wsdl2JavaPreferencesGroup.layout();
        jaxwsPreferencesGroup.layout();
        springConfigPreferncesGroup.layout();
        refresh();
    }

    private IStatus checkRuntimeExist(String path) {
        File cxfHomeDir = new File(path);
        if (cxfHomeDirText.getText().equals("")) { //$NON-NLS-1$
            CXF_LOCATION_STATUS = new Status(IStatus.ERROR, CXFUIPlugin.PLUGIN_ID,
                    CXFUIMessages.CXF_RUNTIME_PREFERENCE_PAGE_RUNTIME_NOT_SET);
        }
        String cxfLibPath = cxfHomeDir + System.getProperty("file.separator") + "lib"; //$NON-NLS-1$ //$NON-NLS-2$
        if (cxfHomeDir.isDirectory()) {
            File cxfLibFolder = new File(cxfLibPath);
            if (cxfLibFolder.isDirectory()) {
                String[] cxfJarFiles = getCXFJarFiles(cxfLibFolder);
                if (cxfJarFiles != null && cxfJarFiles.length > 0) {
                    IStatus toolVersionStatus = getToolVersion(cxfLibPath);
                    processToolVersion(toolVersionStatus);
                    CXF_LOCATION_STATUS = OK_STATUS;
                    exportCXFClasspathContainerButton.setEnabled(true);
                    return CXF_LOCATION_STATUS;
                }
            }
        }
        context.setCxfRuntimeLocation(""); //$NON-NLS-1$
        context.setCxfRuntimeVersion(""); //$NON-NLS-1$
        cxfToolVersionLabel.setText(""); //$NON-NLS-1$
        exportCXFClasspathContainerButton.setEnabled(false);
        CXF_LOCATION_STATUS = new Status(Status.ERROR, CXFUIPlugin.PLUGIN_ID,
                CXFUIMessages.CXF_RUNTIME_PREFERENCE_PAGE_RUNTIME_NOT_SET);
        return CXF_LOCATION_STATUS;
    }

    private IStatus getToolVersion(String cxLibFolderPath) {
        File cxfLibFolder = new File(cxLibFolderPath);
        List<String> cxfLib = new ArrayList<String>();
        String[] jarFiles = cxfLibFolder.list(new FilenameFilter() {
            public boolean accept(File dir, String name) {
                if (name.endsWith(".jar")) { //$NON-NLS-1$
                    return true;
                }
                return false;
            }
        });

        for (String jarFile : jarFiles) {
            cxfLib.add(cxLibFolderPath + System.getProperty("file.separator") + jarFile); //$NON-NLS-1$
        }

        IStatus toolVersionStatus = LaunchUtils.launch(cxfLib.toArray(new String[cxfLib.size()]),
                "org.apache.cxf.tools.wsdlto.WSDLToJava", new String[] { "-v" }); //$NON-NLS-1$ //$NON-NLS-2$
        return toolVersionStatus;
    }

    private String[] getCXFJarFiles(File directory) {
        String[] cxfJarFiles = directory.list(new FilenameFilter() {
            public boolean accept(File dir, String name) {
                if (name.startsWith("cxf") && name.endsWith(".jar") //$NON-NLS-1$ //$NON-NLS-2$
                        && digitPattern.matcher(name).find()) {
                    return true;
                }
                return false;
            }
        });
        return cxfJarFiles;
    }

    private void processToolVersion(IStatus toolVersionStatus) {
        if (toolVersionStatus.getSeverity() == IStatus.INFO) {
            String cxfToolVersion = toolVersionStatus.getMessage();

            cxfToolVersion = cxfToolVersion.substring(cxfToolVersion.indexOf("-") + 1, //$NON-NLS-1$
                    cxfToolVersion.length()).trim();

            String cxfRuntimeEdition = ""; //$NON-NLS-1$
            String cxfRuntimeVersion = ""; //$NON-NLS-1$

            Matcher matcher = digitPattern.matcher(cxfToolVersion);
            if (matcher.find()) {
                int start = matcher.start();
                int end = matcher.end();
                while (matcher.find()) {
                    end = matcher.end();
                }
                cxfRuntimeEdition = cxfToolVersion.substring(0, start).trim();
                cxfRuntimeVersion = cxfToolVersion.substring(start, end);
            }
            
            cxfToolVersionLabel.setText(cxfRuntimeEdition + " " + cxfRuntimeVersion); //$NON-NLS-1$

            context.setCxfRuntimeVersion(cxfRuntimeVersion);
            context.setCxfRuntimeEdition(cxfRuntimeEdition);
            
            CXFCorePlugin.getDefault().setCurrentRuntimeVersion(new Version(cxfRuntimeVersion));
        }
    }

    private void updateStatus() {
        CXF_LOCATION_STATUS = checkRuntimeExist(cxfHomeDirText.getText());
        applyStatusToPage(findMostSevere());
    }

    private void applyStatusToPage(IStatus status) {
        String message = status.getMessage();
        if (status.getSeverity() > IStatus.OK) {
            setErrorMessage(message);
        } else {
            setMessage(getTitle());
            setErrorMessage(null);
        }

    }

    private IStatus findMostSevere() {
        return CXF_LOCATION_STATUS;
    }

    private void setDefaults() {
        exportCXFClasspathContainerButton.setSelection(CXFModelUtils.getDefaultBooleanValue(
                CXFPackage.CXF_CONTEXT, CXFPackage.CXF_CONTEXT__EXPORT_CXF_CLASSPATH_CONTAINER));
        
        java2WSDLRuntimePreferencesComposite.setDefaults();
        java2WSRuntimePreferencesComposite.setDefaults();
        cxf20WSDL2JavaPreferencesComposite.setDefaults();
        cxf21WSDL2JavaPreferencesComposite.setDefaults();
        annotationsComposite.setDefaults();
        springConfigComposite.setDefaults();
    }
    
    private void refresh() {
        if (context.getCxfRuntimeVersion().compareTo(CXFCorePlugin.CXF_VERSION_2_1) >= 0) {
            java2WSRuntimePreferencesComposite.refresh();
            cxf21WSDL2JavaPreferencesComposite.refresh();
        } else {
            java2WSDLRuntimePreferencesComposite.refresh();
            cxf20WSDL2JavaPreferencesComposite.refresh();
        }
    }
    
    private void storeValues() {
        context.setExportCXFClasspathContainer(exportCXFClasspathContainerButton.getSelection());
        
        if (context.getCxfRuntimeVersion().compareTo(CXFCorePlugin.CXF_VERSION_2_1) >= 0) {
            java2WSRuntimePreferencesComposite.storeValues();
            cxf21WSDL2JavaPreferencesComposite.storeValues();
        } else {
            java2WSDLRuntimePreferencesComposite.storeValues();
            cxf20WSDL2JavaPreferencesComposite.storeValues();
        }
        annotationsComposite.storeValues();
        springConfigComposite.storeValues();
    }
    
    @Override
    protected void performApply() {
        super.performApply();
    }

    @Override
    public boolean performCancel() {
        return super.performCancel();
    }

    @Override
    protected void performDefaults() {
        super.performDefaults();
        setDefaults();
    }

    @Override
    public boolean performOk() {
        storeValues();
        return true;
    }
}
