org.springframework.ide.eclipse.wizard.ui.BeanWizardPage.java Source code

Java tutorial

Introduction

Here is the source code for org.springframework.ide.eclipse.wizard.ui.BeanWizardPage.java

Source

/*******************************************************************************
 *  Copyright (c) 2012 VMware, Inc.
 *  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:
 *      VMware, Inc. - initial API and implementation
 *******************************************************************************/
package org.springframework.ide.eclipse.wizard.ui;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.internal.ui.wizards.NewClassCreationWizard;
import org.eclipse.jdt.ui.IJavaElementSearchConstants;
import org.eclipse.jdt.ui.JavaUI;
import org.eclipse.jdt.ui.wizards.NewClassWizardPage;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.fieldassist.TextContentAdapter;
import org.eclipse.jface.window.Window;
import org.eclipse.jface.wizard.WizardDialog;
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.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.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.dialogs.SelectionDialog;
import org.eclipse.ui.forms.events.HyperlinkAdapter;
import org.eclipse.ui.forms.events.HyperlinkEvent;
import org.eclipse.ui.forms.widgets.Hyperlink;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
import org.springframework.ide.eclipse.beans.core.BeansCoreUtils;
import org.springframework.ide.eclipse.config.core.contentassist.XmlBackedContentProposalAdapter;
import org.springframework.ide.eclipse.config.core.contentassist.XmlBackedContentProposalProvider;
import org.springframework.ide.eclipse.config.core.schemas.BeansSchemaConstants;
import org.springframework.ide.eclipse.core.StringUtils;
import org.springframework.ide.eclipse.quickfix.ContentAssistProposalWrapper;
import org.springframework.ide.eclipse.wizard.Messages;
import org.springframework.ide.eclipse.wizard.WizardPlugin;
import org.springframework.ide.eclipse.wizard.core.WizardBeanReferenceContentProposalProvider;
import org.springframework.ide.eclipse.wizard.core.WizardClassContentProposalProvider;
import org.springframework.ide.eclipse.wizard.core.WizardContentAssistConverter;
import org.springsource.ide.eclipse.commons.core.StatusHandler;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;

/**
 * Wizard page for creating or modifying a bean definition
 * @author Terry Denney
 * @author Leo Dos Santos
 * @author Christian Dupuis
 * @since 2.0
 */
@SuppressWarnings("restriction")
public class BeanWizardPage extends AbstractBeanWizardPage {

    private Label idLabel, nameLabel, parentLabel;

    private Hyperlink classLink;

    private Text idText, nameText, classText, parentText, fileText;

    private Button ignoreErrorButton, fileBrowseButton;

    private static final String DEFAULT_MESSAGE = Messages.getString("NewBeanWizardPage.TITLE_DESCRIPTION"); //$NON-NLS-1$

    private String fileErrorMessage, classErrorMessage, parentErrorMessage;

    private final Set<XmlBackedContentProposalAdapter> contentProposalAdapters;

    private WizardClassContentProposalProvider classProposalProvider;

    private WizardBeanReferenceContentProposalProvider parentProposalProvider;

    private final boolean fileBrowsingEnabled;

    public BeanWizardPage(String pageName, BeanWizard wizard, boolean fileBrowsingEnabled) {
        super(pageName, wizard);
        setTitle(Messages.getString("NewBeanWizardPage.TITLE")); //$NON-NLS-1$
        if (wizard.getBeanFile() == null) {
            setDescription(Messages.getString("NewBeanWizardPage.ENTER_BEAN_FILE")); //$NON-NLS-1$
        } else {
            setDescription(DEFAULT_MESSAGE);
        }

        this.wizard = wizard;
        this.fileBrowsingEnabled = fileBrowsingEnabled;
        this.contentProposalAdapters = new HashSet<XmlBackedContentProposalAdapter>();
    }

    private void addListener(final Text text, final String attributeName) {
        text.addModifyListener(new ModifyListener() {
            public void modifyText(ModifyEvent e) {
                updateAttribute(attributeName, text.getText());
            }
        });
    }

    @Override
    public boolean canFlipToNextPage() {
        return wizard.getBeanFile() != null && (BeanWizard.getIgnoreError() || classText.getText().length() > 0
                || parentText.getText().length() > 0);
    }

    private void createAttribute(String attributeName, Hyperlink link, Text text) {
        link.setText(getDisplayText(attributeName) + ":"); //$NON-NLS-1$
        link.setUnderlined(true);
        link.setLayoutData(new GridData());

        link.addHyperlinkListener(new HyperlinkAdapter() {
            @Override
            public void linkActivated(HyperlinkEvent e) {
                IProject project = BeanWizardPage.this.wizard.getBeanFile().getProject();
                String className = classText.getText();

                try {
                    if (project.hasNature(JavaCore.NATURE_ID)) {
                        IJavaProject javaProject = JavaCore.create(project);
                        IJavaElement result = null;
                        if (className.length() > 0) {
                            result = javaProject.findType(className);
                        }

                        if (result != null) {
                            JavaUI.openInEditor(result);
                            return;
                        }

                        NewClassWizardPage page = new NewClassWizardPage();

                        int index = className.lastIndexOf(".");
                        if (index > 0) {
                            String packageName = className.substring(0, index);
                            className = className.substring(index + 1);

                            IPackageFragment[] packageFragments = javaProject.getPackageFragments();
                            for (IPackageFragment packageFragment : packageFragments) {
                                if (packageFragment.getElementName().equals(packageName)) {
                                    page.setPackageFragment(packageFragment, true);

                                    IPackageFragmentRoot[] packageFragmentRoots = javaProject
                                            .getAllPackageFragmentRoots();
                                    for (IPackageFragmentRoot packageFragmentRoot : packageFragmentRoots) {
                                        if (packageFragmentRoot.getPath().isPrefixOf(packageFragment.getPath())) {
                                            page.setPackageFragmentRoot(packageFragmentRoot, true);
                                            break;
                                        }
                                    }
                                    break;
                                }
                            }
                        }

                        page.setTypeName(className, false);

                        NewClassCreationWizard wizard = new NewClassCreationWizard(page, true);
                        IWorkbench workbench = PlatformUI.getWorkbench();
                        wizard.init(workbench, null);

                        Shell shell = workbench.getActiveWorkbenchWindow().getShell();
                        WizardDialog dialog = new WizardDialog(shell, wizard);
                        dialog.create();
                        dialog.getShell().setText("New Class");

                        dialog.setBlockOnOpen(true);
                        if (dialog.open() == Window.OK) {
                            validateAttribute(BeansSchemaConstants.ATTR_CLASS, className);
                        }

                    }
                } catch (CoreException ex) {

                }

            }
        });

        createAttrbute(attributeName, text);
    }

    private void createAttribute(String attributeName, Label label, Text text) {
        label.setText(getDisplayText(attributeName) + ":"); //$NON-NLS-1$
        label.setLayoutData(new GridData());

        createAttrbute(attributeName, text);
    }

    private void createAttrbute(String attributeName, Text text) {
        text.setEditable(true);
        text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));

        IDOMElement newBean = wizard.getNewBean();
        String attributeValue = null;
        if (newBean != null) {
            attributeValue = newBean.getAttribute(attributeName);
        }

        if (attributeValue != null) {
            text.setText(attributeValue);
        }

        XmlBackedContentProposalProvider proposalProvider = null;

        IFile beanFile = wizard.getBeanFile();
        Document originalDocument = wizard.getOriginalDocument();
        if (attributeName.equals(BeansSchemaConstants.ATTR_CLASS)) {
            classProposalProvider = new WizardClassContentProposalProvider(newBean, attributeName, beanFile,
                    originalDocument);
            proposalProvider = classProposalProvider;
        } else if (attributeName.equals(BeansSchemaConstants.ATTR_PARENT)) {
            parentProposalProvider = new WizardBeanReferenceContentProposalProvider(newBean, attributeName,
                    beanFile, originalDocument);
            proposalProvider = parentProposalProvider;
        }

        if (proposalProvider != null) {
            contentProposalAdapters
                    .add(new XmlBackedContentProposalAdapter(text, new TextContentAdapter(), proposalProvider));
        }

        addListener(text, attributeName);
    }

    public void createControl(Composite parent) {
        Composite composite = new Composite(parent, SWT.NONE);
        composite.setLayout(new GridLayout());
        composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));

        createFileComposite(composite);

        Composite container = new Composite(composite, SWT.NONE);
        container.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));

        GridLayout layout = new GridLayout(2, false);
        layout.horizontalSpacing = 10;
        container.setLayout(layout);

        idLabel = new Label(container, SWT.NONE);
        idText = new Text(container, SWT.BORDER);
        createAttribute(BeansSchemaConstants.ATTR_ID, idLabel, idText);

        nameLabel = new Label(container, SWT.NONE);
        nameText = new Text(container, SWT.BORDER);
        createAttribute(BeansSchemaConstants.ATTR_NAME, nameLabel, nameText);

        classLink = new Hyperlink(container, SWT.UNDERLINE_LINK);

        Composite classContainer = new Composite(container, SWT.NONE);
        GridLayout classContainerLayout = new GridLayout(2, false);
        classContainer.setLayout(classContainerLayout);
        classContainerLayout.marginHeight = 0;
        classContainerLayout.marginWidth = 0;
        classContainer.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));

        classText = new Text(classContainer, SWT.BORDER);
        createAttribute(BeansSchemaConstants.ATTR_CLASS, classLink, classText);

        Button browseButton = new Button(classContainer, SWT.NONE);
        browseButton.setText(Messages.getString("NewBeanWizardPage.BROWSE_BUTTON_LABEL")); //$NON-NLS-1$
        browseButton.setLayoutData(new GridData());
        browseButton.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                String filter = classText.getText();
                if (filter == null) {
                    filter = ""; //$NON-NLS-1$
                }

                filter = filter.replace('$', '.');
                try {
                    int scope = IJavaElementSearchConstants.CONSIDER_CLASSES;

                    SelectionDialog dialog = JavaUI.createTypeDialog(getShell(),
                            PlatformUI.getWorkbench().getProgressService(), null, scope, false, filter);
                    dialog.setTitle(Messages.getString("NewBeanWizardPage.SELECT_TYPE_DIALOG_TITLE")); //$NON-NLS-1$

                    if (dialog.open() == Window.OK) {
                        IType type = (IType) dialog.getResult()[0];
                        String newValue = type.getFullyQualifiedName('$');
                        classText.setText(newValue);
                        updateAttribute(BeansSchemaConstants.ATTR_CLASS, newValue);
                    }
                } catch (JavaModelException ex) {
                    StatusHandler
                            .log(new Status(IStatus.ERROR, WizardPlugin.PLUGIN_ID, "Failed to select type.", ex));
                }

            }
        });

        parentLabel = new Label(container, SWT.NONE);
        parentText = new Text(container, SWT.BORDER);
        createAttribute(BeansSchemaConstants.ATTR_PARENT, parentLabel, parentText);

        Composite buttonComposite = new Composite(container, SWT.NONE);

        GridLayout buttonCompositeLayout = new GridLayout();
        buttonCompositeLayout.marginWidth = 0;
        buttonCompositeLayout.marginHeight = 0;
        buttonComposite.setLayout(buttonCompositeLayout);

        GridData buttonCompositeData = new GridData(SWT.FILL, SWT.FILL, true, false);
        buttonCompositeData.horizontalSpan = 2;
        buttonComposite.setLayoutData(buttonCompositeData);

        ignoreErrorButton = wizard.createIgnoreErrorButton(buttonComposite, this);
        ignoreErrorButton.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                getWizard().getContainer().updateButtons();
                updateMessage();
            }
        });

        updateFieldsEnablement();

        setControl(composite);
    }

    private void createFileComposite(Composite parent) {
        Composite fileComposite = new Composite(parent, SWT.NONE);

        fileComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));

        GridLayout compositeLayout = new GridLayout(2, false);
        compositeLayout.marginBottom = 10;
        fileComposite.setLayout(compositeLayout);

        Label fileLabel = new Label(fileComposite, SWT.NONE);
        fileLabel.setText(Messages.getString("NewBeanWizardPage.BEAN_FILE_LABEL")); //$NON-NLS-1$
        GridData labelData = new GridData(SWT.FILL, SWT.FILL, false, false);
        labelData.horizontalSpan = 2;
        fileLabel.setLayoutData(labelData);

        fileText = new Text(fileComposite, SWT.BORDER);
        fileText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
        fileText.setEditable(true);
        IFile beanFile = wizard.getBeanFile();
        if (beanFile != null) {
            fileText.setText(beanFile.getFullPath().toOSString());
        }

        fileText.addModifyListener(new ModifyListener() {
            public void modifyText(ModifyEvent e) {
                String filePath = fileText.getText();
                if (filePath.length() == 0) {
                    fileErrorMessage = Messages.getString("NewBeanWizardPage.EMPTY_BEAN_FILE"); //$NON-NLS-1$
                } else {
                    IResource resource = ResourcesPlugin.getWorkspace().getRoot().findMember(new Path(filePath));
                    validateFile(resource);
                }
            }
        });

        fileBrowseButton = new Button(fileComposite, SWT.PUSH);
        fileBrowseButton.setText(Messages.getString("NewBeanWizardPage.BROWSE_BEAN_FILE")); //$NON-NLS-1$
        fileBrowseButton.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));

        fileBrowseButton.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                BeanFileSelectionDialog dialog = new BeanFileSelectionDialog(getShell(), false,
                        ResourcesPlugin.getWorkspace().getRoot(), IResource.FILE);
                dialog.setTitle(Messages.getString("NewBeanWizardPage.BEAN_SELECTION_DIALOG_TITLE")); //$NON-NLS-1$
                int status = dialog.open();
                if (status == Dialog.OK) {
                    Object selection = dialog.getFirstResult();
                    if (selection != null && selection instanceof IFile) {
                        IFile beanFile = (IFile) selection;
                        fileText.setText(beanFile.getFullPath().toOSString());

                        validateFile(beanFile);
                    }
                }
            }
        });

        fileText.setEnabled(fileBrowsingEnabled);
        fileBrowseButton.setEnabled(fileBrowsingEnabled);
    }

    public String getClassName() {
        return getInputText(classText);
    }

    private String getDisplayText(String attributeName) {
        return StringUtils.capitalize(attributeName);
    }

    public String getId() {
        return getInputText(idText);
    }

    private String getInputText(Text text) {
        if (text != null) {
            String inputText = text.getText();
            if (inputText != null) {
                return inputText;
            }
        }
        return ""; //$NON-NLS-1$
    }

    @Override
    public String getName() {
        return getInputText(nameText);
    }

    @Override
    public boolean isPageComplete() {
        if (wizard.getBeanFile() == null) {
            return false;
        }

        if (getErrorMessage() != null && !BeanWizard.getIgnoreError()) {
            return false;
        }

        return super.isPageComplete();
    }

    private void updateAttribute(String attributeName, String value) {
        IDOMElement newBean = wizard.getNewBean();

        if (value.length() > 0) {
            if (newBean.getAttributeNode(attributeName) != null) {
                newBean.setAttribute(attributeName, value);
            } else {
                List<Attr> attributes = new ArrayList<Attr>();
                boolean found = false;
                for (String currAttributeName : BeanWizard.ATTRIBUTES) {
                    if (currAttributeName == attributeName) {
                        found = true;
                    } else if (found) {
                        Attr attributeNode = newBean.getAttributeNode(currAttributeName);
                        if (attributeNode != null) {
                            attributes.add(attributeNode);
                            newBean.removeAttributeNode(attributeNode);
                        }
                    }
                }
                newBean.setAttribute(attributeName, value);

                for (Attr attribute : attributes) {
                    newBean.setAttributeNode(attribute);
                }
            }
        } else {
            newBean.removeAttribute(attributeName);
        }

        validateAttribute(attributeName, value);
    }

    private void updateFieldsEnablement() {
        boolean enabled = fileErrorMessage == null && wizard.getBeanFile() != null;
        idText.setEnabled(enabled);
        nameText.setEnabled(enabled);
        classText.setEnabled(enabled);
        parentText.setEnabled(enabled);
        ignoreErrorButton.setEnabled(enabled);
    }

    @Override
    public void updateMessage() {
        if (fileErrorMessage != null) {
            setDialogMessage(fileErrorMessage, false);
        } else if (classErrorMessage != null) {
            setDialogMessage(classErrorMessage, true);
        } else if (parentErrorMessage != null) {
            setDialogMessage(parentErrorMessage, true);
        } else {
            setMessage(DEFAULT_MESSAGE);
        }

        getWizard().getContainer().updateButtons();
    }

    private void validateAttribute(String attributeName, String value) {
        IDOMElement newBean = wizard.getNewBean();
        WizardContentAssistConverter contentAssistConverter = new WizardContentAssistConverter(newBean,
                newBean.getAttributeNode(attributeName), wizard.getBeanFile(), wizard.getOriginalDocument());

        if (attributeName.equals(BeansSchemaConstants.ATTR_CLASS)) {
            if (value.length() > 0) {
                Set<ContentAssistProposalWrapper> classAttributeProposals = contentAssistConverter
                        .getClassAttributeProposals(value, true);
                if (classAttributeProposals.isEmpty()) {
                    classErrorMessage = Messages.getString("NewBeanWizardPage.UNKNOW_CLASS_MESSAGE"); //$NON-NLS-1$
                } else {
                    classErrorMessage = null;
                }
            } else {
                classErrorMessage = null;
            }
        } else if (attributeName.equals(BeansSchemaConstants.ATTR_PARENT)) {
            if (value.length() > 0) {
                Set<ContentAssistProposalWrapper> referenceableBeanDescriptions = contentAssistConverter
                        .getReferenceableBeanDescriptions(value, true);
                if (referenceableBeanDescriptions.isEmpty()) {
                    parentErrorMessage = Messages.getString("NewBeanWizardPage.UNKNOWN_PARENT_MESSAGE"); //$NON-NLS-1$
                } else {
                    parentErrorMessage = null;
                }
            } else {
                parentErrorMessage = null;
            }
        }

        updateMessage();
    }

    private void validateFields() {
        validateAttribute(BeansSchemaConstants.ATTR_CLASS, classText.getText());
        validateAttribute(BeansSchemaConstants.ATTR_PARENT, parentText.getText());
    }

    private void validateFile(IResource beanFile) {
        if (beanFile != null && BeansCoreUtils.isBeansConfig(beanFile)) {
            wizard.setBeanFile((IFile) beanFile);
            fileErrorMessage = null;
            validateFields();

            classProposalProvider.setFile((IFile) beanFile);
            parentProposalProvider.setFile((IFile) beanFile);

            classProposalProvider.setDocument(wizard.getOriginalDocument());
            parentProposalProvider.setDocument(wizard.getOriginalDocument());

            for (XmlBackedContentProposalAdapter contentProposalAdapter : contentProposalAdapters) {
                contentProposalAdapter.update(wizard.getNewBean());
            }
        } else {
            fileErrorMessage = Messages.getString("NewBeanWizardPage.BEAN_FILE_ERROR"); //$NON-NLS-1$
        }

        updateMessage();
        updateFieldsEnablement();
    }

}