descent.ui.wizards.NewModuleWizardPage.java Source code

Java tutorial

Introduction

Here is the source code for descent.ui.wizards.NewModuleWizardPage.java

Source

/*******************************************************************************
 * Copyright (c) 2000, 2006 IBM Corporation and others.
 * 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:
 *     IBM Corporation - initial API and implementation
 *     John Kaplan, johnkaplantech@gmail.com - 108071 [code templates] template for body of newly created class
 *******************************************************************************/
package descent.ui.wizards;

import java.lang.reflect.InvocationTargetException;
import java.net.URI;

import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.filesystem.IFileStore;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.preference.PreferenceDialog;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.text.templates.Template;
import org.eclipse.jface.text.templates.TemplateException;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Link;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.dialogs.ElementListSelectionDialog;
import org.eclipse.ui.dialogs.PreferencesUtil;

import descent.core.IBuffer;
import descent.core.ICompilationUnit;
import descent.core.IJavaElement;
import descent.core.IJavaProject;
import descent.core.IPackageFragment;
import descent.core.IPackageFragmentRoot;
import descent.core.JavaConventions;
import descent.core.JavaModelException;
import descent.core.ToolFactory;
import descent.core.compiler.IScanner;
import descent.core.compiler.ITerminalSymbols;
import descent.core.compiler.InvalidInputException;
import descent.core.dom.AST;
import descent.core.dom.ASTParser;
import descent.core.dom.CompilationUnit;
import descent.internal.corext.codemanipulation.StubUtility;
import descent.internal.corext.dom.TokenScanner;
import descent.internal.corext.template.java.JavaContext;
import descent.internal.corext.util.JavaModelUtil;
import descent.internal.corext.util.Messages;
import descent.internal.corext.util.Resources;
import descent.internal.ui.IJavaHelpContextIds;
import descent.internal.ui.JavaPlugin;
import descent.internal.ui.dialogs.StatusInfo;
import descent.internal.ui.dialogs.TextFieldNavigationHandler;
import descent.internal.ui.preferences.CodeTemplatePreferencePage;
import descent.internal.ui.refactoring.contentassist.ControlContentAssistHelper;
import descent.internal.ui.refactoring.contentassist.JavaPackageCompletionProcessor;
import descent.internal.ui.wizards.NewWizardMessages;
import descent.internal.ui.wizards.dialogfields.DialogField;
import descent.internal.ui.wizards.dialogfields.IDialogFieldListener;
import descent.internal.ui.wizards.dialogfields.IListAdapter;
import descent.internal.ui.wizards.dialogfields.IStringButtonAdapter;
import descent.internal.ui.wizards.dialogfields.LayoutUtil;
import descent.internal.ui.wizards.dialogfields.ListDialogField;
import descent.internal.ui.wizards.dialogfields.SelectionButtonDialogField;
import descent.internal.ui.wizards.dialogfields.Separator;
import descent.internal.ui.wizards.dialogfields.StringButtonStatusDialogField;
import descent.internal.ui.wizards.dialogfields.StringDialogField;
import descent.ui.CodeGeneration;
import descent.ui.JavaElementLabelProvider;

/**
 * The class <code>NewModuleWizardPage</code> contains controls and validation routines 
 * for a 'New Module WizardPage'.
 */
public class NewModuleWizardPage extends NewContainerWizardPage {

    private final static String PAGE_NAME = "NewModuleWizardPage"; //$NON-NLS-1$

    /** Field ID of the package input field. */
    protected final static String PACKAGE = PAGE_NAME + ".package"; //$NON-NLS-1$
    /** Field ID of the type name input field. */
    protected final static String MODULENAME = PAGE_NAME + ".modulename"; //$NON-NLS-1$
    /** Field ID of the method stubs check boxes. */
    protected final static String METHODS = PAGE_NAME + ".methods"; //$NON-NLS-1$

    private StringButtonStatusDialogField fPackageDialogField;

    private boolean fCanModifyPackage;

    private IPackageFragment fCurrPackage;
    /**
     * a handle to the type to be created (does usually not exist, can be null)
     */
    private StringDialogField fTypeNameDialogField;

    private SelectionButtonDialogField fAddCommentButton;
    private boolean fUseAddCommentButtonValue; // used for compatibility: Wizards that don't show the comment button control
    // will use the preferences settings

    private ICompilationUnit fCreatedCompilationUnit;

    private JavaPackageCompletionProcessor fCurrPackageCompletionProcessor;

    protected IStatus fPackageStatus;
    protected IStatus fTypeNameStatus;

    /**
     * Creates a new <code>NewTypeWizardPage</code>.
     * 
     * @param typeKind Signals the kind of the type to be created. Valid kinds are
     * {@link #CLASS_TYPE}, {@link #INTERFACE_TYPE}, {@link #ENUM_TYPE} and {@link #ANNOTATION_TYPE}
     * @param pageName the wizard page's name
     * @since 3.1
     */
    public NewModuleWizardPage() {
        super(PAGE_NAME);

        fCreatedCompilationUnit = null;

        TypeFieldsAdapter adapter = new TypeFieldsAdapter();

        fPackageDialogField = new StringButtonStatusDialogField(adapter);
        fPackageDialogField.setDialogFieldListener(adapter);
        fPackageDialogField.setLabelText(getPackageLabel());
        fPackageDialogField.setButtonLabel(NewWizardMessages.NewTypeWizardPage_package_button);
        fPackageDialogField.setStatusWidthHint(NewWizardMessages.NewTypeWizardPage_default);

        fTypeNameDialogField = new StringDialogField();
        fTypeNameDialogField.setDialogFieldListener(adapter);
        fTypeNameDialogField.setLabelText(getTypeNameLabel());

        fAddCommentButton = new SelectionButtonDialogField(SWT.CHECK);
        fAddCommentButton.setLabelText(NewWizardMessages.NewTypeWizardPage_addcomment_label);

        fUseAddCommentButtonValue = false; // only used when enabled

        fCurrPackageCompletionProcessor = new JavaPackageCompletionProcessor();

        fPackageStatus = new StatusInfo();

        fCanModifyPackage = true;
        updateEnableState();

        fTypeNameStatus = new StatusInfo();

        setTitle(NewWizardMessages.NewModuleWizardPage_title);
        setDescription(NewWizardMessages.NewModuleWizardPage_description);
    }

    // -------- Initialization ---------

    /**
     * The wizard owning this page is responsible for calling this method with the
     * current selection. The selection is used to initialize the fields of the wizard 
     * page.
     * 
     * @param selection used to initialize the fields
     */
    public void init(IStructuredSelection selection) {
        IJavaElement jelem = getInitialJavaElement(selection);
        initContainerPage(jelem);
        initTypePage(jelem);
        doStatusUpdate();
    }

    //    ------ validation --------
    private void doStatusUpdate() {
        // status of all used components
        IStatus[] status = new IStatus[] { fContainerStatus, fPackageStatus, fTypeNameStatus, };

        // the mode severe status will be displayed and the OK button enabled/disabled.
        updateStatus(status);
    }

    /**
     * Initializes all fields provided by the page with a given selection.
     * 
     * @param elem the selection used to initialize this page or <code>
     * null</code> if no selection was available
     */
    protected void initTypePage(IJavaElement elem) {
        IJavaProject project = null;
        IPackageFragment pack = null;

        if (elem != null) {
            // evaluate the enclosing type
            project = elem.getJavaProject();
            pack = (IPackageFragment) elem.getAncestor(IJavaElement.PACKAGE_FRAGMENT);
        }

        String typeName = ""; //$NON-NLS-1$

        ITextSelection selection = getCurrentTextSelection();
        if (selection != null) {
            String text = selection.getText();
            if (text != null && JavaConventions.validateJavaTypeName(text).isOK()) {
                typeName = text;
            }
        }

        setPackageFragment(pack, true);
        setTypeName(typeName, true);
        setAddComments(StubUtility.doAddComments(project), true); // from project or workspace
    }

    // -------- UI Creation ---------

    /**
     * Returns the label that is used for the package input field.
     * 
     * @return the label that is used for the package input field.
     * @since 3.2
     */
    protected String getPackageLabel() {
        return NewWizardMessages.NewTypeWizardPage_package_label;
    }

    /**
     * Returns the label that is used for the type name input field.
     * 
     * @return the label that is used for the type name input field.
     * @since 3.2
     */
    protected String getTypeNameLabel() {
        return NewWizardMessages.NewTypeWizardPage_typename_label;
    }

    /**
     * Creates a separator line. Expects a <code>GridLayout</code> with at least 1 column.
     * 
     * @param composite the parent composite
     * @param nColumns number of columns to span
     */
    protected void createSeparator(Composite composite, int nColumns) {
        (new Separator(SWT.SEPARATOR | SWT.HORIZONTAL)).doFillIntoGrid(composite, nColumns,
                convertHeightInCharsToPixels(1));
    }

    /**
     * Creates the controls for the package name field. Expects a <code>GridLayout</code> with at 
     * least 4 columns.
     * 
     * @param composite the parent composite
     * @param nColumns number of columns to span
     */
    protected void createPackageControls(Composite composite, int nColumns) {
        fPackageDialogField.doFillIntoGrid(composite, nColumns);
        Text text = fPackageDialogField.getTextControl(null);
        LayoutUtil.setWidthHint(text, getMaxFieldWidth());
        LayoutUtil.setHorizontalGrabbing(text);
        ControlContentAssistHelper.createTextContentAssistant(text, fCurrPackageCompletionProcessor);
        TextFieldNavigationHandler.install(text);
    }

    /**
     * Creates the controls for the type name field. Expects a <code>GridLayout</code> with at 
     * least 2 columns.
     * 
     * @param composite the parent composite
     * @param nColumns number of columns to span
     */
    protected void createTypeNameControls(Composite composite, int nColumns) {
        fTypeNameDialogField.doFillIntoGrid(composite, nColumns - 1);
        DialogField.createEmptySpace(composite);

        Text text = fTypeNameDialogField.getTextControl(null);
        LayoutUtil.setWidthHint(text, getMaxFieldWidth());
        TextFieldNavigationHandler.install(text);
    }

    /**
     * Creates the controls for the preference page links. Expects a <code>GridLayout</code> with 
     * at least 3 columns.
     * 
     * @param composite the parent composite
     * @param nColumns number of columns to span
     * 
     * @since 3.1
     */
    protected void createCommentControls(Composite composite, int nColumns) {
        Link link = new Link(composite, SWT.NONE);
        link.setText(NewWizardMessages.NewTypeWizardPage_addcomment_description);
        link.addSelectionListener(new TypeFieldsAdapter());
        link.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, false, false, nColumns, 1));
        DialogField.createEmptySpace(composite);
        fAddCommentButton.doFillIntoGrid(composite, nColumns - 1);
    }

    /*
     * @see WizardPage#becomesVisible
     */
    public void setVisible(boolean visible) {
        super.setVisible(visible);
        if (visible) {
            setFocus();
        }
    }

    /**
     * Sets the focus on the type name input field.
     */
    protected void setFocus() {
        fTypeNameDialogField.setFocus();
    }

    // -------- TypeFieldsAdapter --------

    private class TypeFieldsAdapter
            implements IStringButtonAdapter, IDialogFieldListener, IListAdapter, SelectionListener {

        // -------- IStringButtonAdapter
        public void changeControlPressed(DialogField field) {
            typePageChangeControlPressed(field);
        }

        // -------- IListAdapter
        public void customButtonPressed(ListDialogField field, int index) {

        }

        public void selectionChanged(ListDialogField field) {
        }

        // -------- IDialogFieldListener
        public void dialogFieldChanged(DialogField field) {
            typePageDialogFieldChanged(field);
        }

        public void doubleClicked(ListDialogField field) {
        }

        public void widgetSelected(SelectionEvent e) {
            typePageLinkActivated(e);
        }

        public void widgetDefaultSelected(SelectionEvent e) {
            typePageLinkActivated(e);
        }
    }

    private void typePageLinkActivated(SelectionEvent e) {
        IPackageFragmentRoot root = getPackageFragmentRoot();
        if (root != null) {
            PreferenceDialog dialog = PreferencesUtil.createPropertyDialogOn(getShell(),
                    root.getJavaProject().getProject(), CodeTemplatePreferencePage.PROP_ID, null, null);
            dialog.open();
        } else {
            String title = NewWizardMessages.NewTypeWizardPage_configure_templates_title;
            String message = NewWizardMessages.NewTypeWizardPage_configure_templates_message;
            MessageDialog.openInformation(getShell(), title, message);
        }
    }

    private void typePageChangeControlPressed(DialogField field) {
        if (field == fPackageDialogField) {
            IPackageFragment pack = choosePackage();
            if (pack != null) {
                fPackageDialogField.setText(pack.getElementName());
            }
        }
    }

    /*
     * A field on the type has changed. The fields' status and all dependent
     * status are updated.
     */
    private void typePageDialogFieldChanged(DialogField field) {
        String fieldName = null;
        if (field == fPackageDialogField) {
            fPackageStatus = packageChanged();
            updatePackageStatusLabel();
            fTypeNameStatus = typeNameChanged();
            fieldName = PACKAGE;
        } else if (field == fTypeNameDialogField) {
            fTypeNameStatus = typeNameChanged();
            fieldName = MODULENAME;
        } else {
            fieldName = METHODS;
        }
        // tell all others
        handleFieldChanged(fieldName);
    }

    // -------- update message ----------------      

    /*
     * @see descent.ui.wizards.NewContainerWizardPage#handleFieldChanged(String)
     */
    protected void handleFieldChanged(String fieldName) {
        super.handleFieldChanged(fieldName);
        if (fieldName == CONTAINER) {
            fPackageStatus = packageChanged();
            fTypeNameStatus = typeNameChanged();
        }

        doStatusUpdate();
    }

    // ---- set / get ----------------

    /**
     * Returns the text of the package input field.
     * 
     * @return the text of the package input field
     */
    public String getPackageText() {
        return fPackageDialogField.getText();
    }

    /**
     * Returns the package fragment corresponding to the current input.
     * 
     * @return a package fragment or <code>null</code> if the input 
     * could not be resolved.
     */
    public IPackageFragment getPackageFragment() {
        return fCurrPackage;
    }

    /**
     * Sets the package fragment to the given value. The method updates the model 
     * and the text of the control.
     * 
     * @param pack the package fragment to be set
     * @param canBeModified if <code>true</code> the package fragment is
     * editable; otherwise it is read-only.
     */
    public void setPackageFragment(IPackageFragment pack, boolean canBeModified) {
        fCurrPackage = pack;
        fCanModifyPackage = canBeModified;
        String str = (pack == null) ? "" : pack.getElementName(); //$NON-NLS-1$
        fPackageDialogField.setText(str);
        updateEnableState();
    }

    /**
     * Returns the type name entered into the type input field.
     * 
     * @return the type name
     */
    public String getModuleName() {
        return fTypeNameDialogField.getText();
    }

    /**
     * Sets the type name input field's text to the given value. Method doesn't update
     * the model.
     * 
     * @param name the new type name
     * @param canBeModified if <code>true</code> the type name field is
     * editable; otherwise it is read-only.
     */
    public void setTypeName(String name, boolean canBeModified) {
        fTypeNameDialogField.setText(name);
        fTypeNameDialogField.setEnabled(canBeModified);
    }

    /**
     * Sets 'Add comment' checkbox. The value set will only be used when creating source when
     * the comment control is enabled (see {@link #enableCommentControl(boolean)}
     * 
     * @param doAddComments if <code>true</code>, comments are added.
     * @param canBeModified if <code>true</code> check box is
     * editable; otherwise it is read-only.
     *    @since 3.1
     */
    public void setAddComments(boolean doAddComments, boolean canBeModified) {
        fAddCommentButton.setSelection(doAddComments);
        fAddCommentButton.setEnabled(canBeModified);
    }

    /**
     * Sets to use the 'Add comment' checkbox value. Clients that use the 'Add comment' checkbox
     * additionally have to enable the control. This has been added for backwards compatibility.
     * 
     * @param useAddCommentValue if <code>true</code>, 
     *    @since 3.1
     */
    public void enableCommentControl(boolean useAddCommentValue) {
        fUseAddCommentButtonValue = useAddCommentValue;
    }

    /**
     * Returns if comments are added. This method can be overridden by clients.
     * The selection of the comment control is taken if enabled (see {@link #enableCommentControl(boolean)}, otherwise
     * the settings as specified in the preferences is used.
     * 
     * @return Returns <code>true</code> if comments can be added
     * @since 3.1
     */
    public boolean isAddComments() {
        if (fUseAddCommentButtonValue) {
            return fAddCommentButton.isSelected();
        }
        IPackageFragmentRoot root = getPackageFragmentRoot();
        IJavaProject project = (root != null) ? root.getJavaProject() : null; // use project settings 
        return StubUtility.doAddComments(project);
    }

    /**
     * Returns the resource handle that corresponds to the compilation unit to was or
     * will be created or modified.
     * @return A resource or null if the page contains illegal values.
     * @since 3.0
     */
    public IResource getModifiedResource() {
        IPackageFragment pack = getPackageFragment();
        if (pack != null) {
            String cuName = getCompilationUnitName(getModuleName());
            return pack.getCompilationUnit(cuName).getResource();
        }
        return null;
    }

    // ----------- validation ----------

    /*
     * @see descent.ui.wizards.NewContainerWizardPage#containerChanged()
     */
    protected IStatus containerChanged() {
        IStatus status = super.containerChanged();
        fCurrPackageCompletionProcessor.setPackageFragmentRoot(getPackageFragmentRoot());
        return status;
    }

    /**
     * A hook method that gets called when the package field has changed. The method 
     * validates the package name and returns the status of the validation. The validation
     * also updates the package fragment model.
     * <p>
     * Subclasses may extend this method to perform their own validation.
     * </p>
     * 
     * @return the status of the validation
     */
    protected IStatus packageChanged() {
        StatusInfo status = new StatusInfo();
        fPackageDialogField.enableButton(getPackageFragmentRoot() != null);

        String packName = getPackageText();
        if (packName.length() > 0) {
            IStatus val = JavaConventions.validatePackageName(packName);
            if (val.getSeverity() == IStatus.ERROR) {
                status.setError(Messages.format(NewWizardMessages.NewTypeWizardPage_error_InvalidPackageName,
                        val.getMessage()));
                return status;
            } else if (val.getSeverity() == IStatus.WARNING) {
                status.setWarning(Messages.format(
                        NewWizardMessages.NewTypeWizardPage_warning_DiscouragedPackageName, val.getMessage()));
                // continue
            }
        } else {
            //status.setWarning(NewWizardMessages.NewTypeWizardPage_warning_DefaultPackageDiscouraged); 
        }

        IPackageFragmentRoot root = getPackageFragmentRoot();
        if (root != null) {
            if (root.getJavaProject().exists() && packName.length() > 0) {
                try {
                    IPath rootPath = root.getPath();
                    IPath outputPath = root.getJavaProject().getOutputLocation();
                    if (rootPath.isPrefixOf(outputPath) && !rootPath.equals(outputPath)) {
                        // if the bin folder is inside of our root, don't allow to name a package
                        // like the bin folder
                        IPath packagePath = rootPath.append(packName.replace('.', '/'));
                        if (outputPath.isPrefixOf(packagePath)) {
                            status.setError(NewWizardMessages.NewTypeWizardPage_error_ClashOutputLocation);
                            return status;
                        }
                    }
                } catch (JavaModelException e) {
                    JavaPlugin.log(e);
                    // let pass         
                }
            }

            fCurrPackage = root.getPackageFragment(packName);
        } else {
            status.setError(""); //$NON-NLS-1$
        }
        return status;
    }

    /*
     * Updates the 'default' label next to the package field.
     */
    private void updatePackageStatusLabel() {
        String packName = getPackageText();

        if (packName.length() == 0) {
            fPackageDialogField.setStatus(NewWizardMessages.NewTypeWizardPage_default);
        } else {
            fPackageDialogField.setStatus(""); //$NON-NLS-1$
        }
    }

    /*
     * Updates the enable state of buttons related to the enclosing type selection checkbox.
     */
    private void updateEnableState() {
        fPackageDialogField.setEnabled(fCanModifyPackage);
    }

    /**
     * Hook method that is called when evaluating the name of the compilation unit to create. By default, a file extension
     * <code>java</code> is added to the given type name, but implementors can override this behavior.
     * 
     * @param typeName the name of the type to create the compilation unit for.
     * @return the name of the compilation unit to be created for the given name
     * 
     * @since 3.2
     */
    protected String getCompilationUnitName(String typeName) {
        return typeName + JavaModelUtil.DEFAULT_CU_SUFFIX;
    }

    /**
     * Hook method that gets called when the type name has changed. The method validates the 
     * type name and returns the status of the validation.
     * <p>
     * Subclasses may extend this method to perform their own validation.
     * </p>
     * 
     * @return the status of the validation
     */
    protected IStatus typeNameChanged() {
        StatusInfo status = new StatusInfo();
        String typeNameWithParameters = getModuleName();
        // must not be empty
        if (typeNameWithParameters.length() == 0) {
            status.setError(NewWizardMessages.NewModuleWizardPage_error_EnterModuleName);
            return status;
        }

        String typeName = getModuleName();
        if (typeName.indexOf('.') != -1) {
            status.setError(NewWizardMessages.NewModuleWizardPage_error_QualifiedName);
            return status;
        }
        IStatus val = JavaConventions.validateJavaTypeName(typeName);
        if (val.getSeverity() == IStatus.ERROR) {
            status.setError(Messages.format(NewWizardMessages.NewModuleWizardPage_error_InvalidModuleName,
                    val.getMessage()));
            return status;
        } else if (val.getSeverity() == IStatus.WARNING) {
            //status.setWarning(Messages.format(NewWizardMessages.NewModuleWizardPage_warning_TypeNameDiscouraged, val.getMessage())); 
            // continue checking
        }

        // must not exist
        IPackageFragment pack = getPackageFragment();
        if (pack != null) {
            ICompilationUnit cu = pack.getCompilationUnit(getCompilationUnitName(typeName));
            IResource resource = cu.getResource();

            if (resource.exists()) {
                status.setError(NewWizardMessages.NewModuleWizardPage_error_ModuleNameExists);
                return status;
            }
            URI location = resource.getLocationURI();
            if (location != null) {
                try {
                    IFileStore store = EFS.getStore(location);
                    if (store.fetchInfo().exists()) {
                        status.setError(NewWizardMessages.NewModuleWizardPage_error_ModuleNameExistsDifferentCase);
                        return status;
                    }
                } catch (CoreException e) {
                    status.setError(Messages.format(NewWizardMessages.NewModuleWizardPage_error_uri_location_unkown,
                            Resources.getLocationString(resource)));
                }
            }
        }

        /*
        if (typeNameWithParameters != typeName) {
           IPackageFragmentRoot root= getPackageFragmentRoot();
           if (root != null) {
        if (!JavaModelUtil.is50OrHigher(root.getJavaProject())) {
           status.setError(NewWizardMessages.NewTypeWizardPage_error_TypeParameters); 
           return status;
        }
        String typeDeclaration= "class " + typeNameWithParameters + " {}"; //$NON-NLS-1$//$NON-NLS-2$
        ASTParser parser= ASTParser.newParser(AST.D2);
        parser.setSource(typeDeclaration.toCharArray());
        parser.setProject(root.getJavaProject());
        CompilationUnit compilationUnit= (CompilationUnit) parser.createAST(null);
        IProblem[] problems= compilationUnit.getProblems();
        if (problems.length > 0) {
           status.setError(Messages.format(NewWizardMessages.NewTypeWizardPage_error_InvalidTypeName, problems[0].getMessage())); 
           return status;
        }
           }
        }
        */
        return status;
    }

    // selection dialogs

    /**
     * Opens a selection dialog that allows to select a package. 
     * 
     * @return returns the selected package or <code>null</code> if the dialog has been canceled.
     * The caller typically sets the result to the package input field.
     * <p>
     * Clients can override this method if they want to offer a different dialog.
     * </p>
     * 
     * @since 3.2
     */
    protected IPackageFragment choosePackage() {
        IPackageFragmentRoot froot = getPackageFragmentRoot();
        IJavaElement[] packages = null;
        try {
            if (froot != null && froot.exists()) {
                packages = froot.getChildren();
            }
        } catch (JavaModelException e) {
            JavaPlugin.log(e);
        }
        if (packages == null) {
            packages = new IJavaElement[0];
        }

        ElementListSelectionDialog dialog = new ElementListSelectionDialog(getShell(),
                new JavaElementLabelProvider(JavaElementLabelProvider.SHOW_DEFAULT));
        dialog.setIgnoreCase(false);
        dialog.setTitle(NewWizardMessages.NewTypeWizardPage_ChoosePackageDialog_title);
        dialog.setMessage(NewWizardMessages.NewTypeWizardPage_ChoosePackageDialog_description);
        dialog.setEmptyListMessage(NewWizardMessages.NewTypeWizardPage_ChoosePackageDialog_empty);
        dialog.setElements(packages);
        dialog.setHelpAvailable(false);

        IPackageFragment pack = getPackageFragment();
        if (pack != null) {
            dialog.setInitialSelections(new Object[] { pack });
        }

        if (dialog.open() == Window.OK) {
            return (IPackageFragment) dialog.getFirstResult();
        }
        return null;
    }

    // ---- creation ----------------

    /**
     * Creates the new compilation unit using the entered field values.
     * 
     * @param monitor a progress monitor to report progress.
     * @throws CoreException Thrown when the creation failed.
     * @throws InterruptedException Thrown when the operation was canceled.
     */
    public void createCompilationUnit(IProgressMonitor monitor) throws CoreException, InterruptedException {
        if (monitor == null) {
            monitor = new NullProgressMonitor();
        }

        monitor.beginTask(NewWizardMessages.NewModuleWizardPage_operationdesc, 8);

        IPackageFragmentRoot root = getPackageFragmentRoot();
        IPackageFragment pack = getPackageFragment();
        if (pack == null) {
            pack = root.getPackageFragment(""); //$NON-NLS-1$
        }

        if (!pack.exists()) {
            String packName = pack.getElementName();
            pack = root.createPackageFragment(packName, true, new SubProgressMonitor(monitor, 1));
        } else {
            monitor.worked(1);
        }

        boolean needsSave;
        ICompilationUnit connectedCU = null;

        try {
            String moduleName = getModuleName();

            String lineDelimiter = null;
            lineDelimiter = StubUtility.getLineDelimiterUsed(pack.getJavaProject());

            String cuName = getCompilationUnitName(moduleName);
            connectedCU = pack.createCompilationUnit(cuName, "", false, new SubProgressMonitor(monitor, 2)); //$NON-NLS-1$
            // create a working copy with a new owner

            needsSave = true;
            connectedCU.becomeWorkingCopy(null, new SubProgressMonitor(monitor, 1)); // cu is now a (primary) working copy

            IBuffer buffer = connectedCU.getBuffer();

            String cuContent = constructCUContent(connectedCU, moduleName, lineDelimiter);
            buffer.setContents(cuContent);

            JavaModelUtil.reconcile(connectedCU);

            if (monitor.isCanceled()) {
                throw new InterruptedException();
            }

            IBuffer buf = connectedCU.getBuffer();

            String fileComment = getFileComment(connectedCU, lineDelimiter);
            if (fileComment != null && fileComment.length() > 0) {
                buf.replace(0, 0, fileComment + lineDelimiter);
            }
            fCreatedCompilationUnit = connectedCU;

            if (needsSave) {
                connectedCU.commitWorkingCopy(true, new SubProgressMonitor(monitor, 1));
            } else {
                monitor.worked(1);
            }

        } finally {
            if (connectedCU != null) {
                connectedCU.discardWorkingCopy();
            }
            monitor.done();
        }
    }

    /**
     * Uses the New Java file template from the code template page to generate a
     * compilation unit with the given type content.
     * @param cu The new created compilation unit
     * @param typeContent The content of the type, including signature and type
     * body.
     * @param lineDelimiter The line delimiter to be used.
     * @return String Returns the result of evaluating the new file template
     * with the given type content.
     * @throws CoreException
     * @since 2.1
     */
    protected String constructCUContent(ICompilationUnit cu, String moduleName, String lineDelimiter)
            throws CoreException {
        String fileComment = getFileComment(cu, lineDelimiter);
        IPackageFragment pack = (IPackageFragment) cu.getParent();
        String content = CodeGeneration.getCompilationUnitContent(cu, fileComment, lineDelimiter);
        if (content != null) {
            ASTParser parser = ASTParser.newParser(AST.D2);
            parser.setProject(cu.getJavaProject());
            parser.setSource(content.toCharArray());
            CompilationUnit unit = (CompilationUnit) parser.createAST(null);
            if ((pack.isDefaultPackage() || unit.getModuleDeclaration() != null)
                    && !unit.declarations().isEmpty()) {
                return content;
            }
        }
        StringBuffer buf = new StringBuffer();
        buf.append("module "); //$NON-NLS-1$
        if (!pack.isDefaultPackage()) {
            buf.append(pack.getElementName());
            buf.append('.');
        }
        buf.append(moduleName);
        buf.append(';');
        buf.append(lineDelimiter).append(lineDelimiter);
        return buf.toString();
    }

    /**
     * Returns the created type or <code>null</code> is the type has not been created yet. The method
     * only returns a valid type after <code>createType</code> has been called.
     * 
     * @return the created type
     * @see #createCompilationUnit(IProgressMonitor)
     */
    public ICompilationUnit getCreatedCompilationUnit() {
        return fCreatedCompilationUnit;
    }

    // ---- construct CU body----------------

    /**
     * Hook method that gets called from <code>createType</code> to retrieve 
     * a file comment. This default implementation returns the content of the 
     * 'file comment' template or <code>null</code> if no comment should be created.
     * 
     * @param parentCU the parent compilation unit
     * @param lineDelimiter the line delimiter to use
     * @return the file comment or <code>null</code> if a file comment 
     * is not desired
     * @throws CoreException 
      *
      * @since 3.1
     */
    protected String getFileComment(ICompilationUnit parentCU, String lineDelimiter) throws CoreException {
        if (isAddComments()) {
            return CodeGeneration.getFileComment(parentCU, lineDelimiter);
        }
        return null;

    }

    private boolean isValidComment(String template) {
        IScanner scanner = ToolFactory.createScanner(true, false, false, false);
        scanner.setSource(template.toCharArray());
        try {
            int next = scanner.getNextToken();
            while (TokenScanner.isComment(next)) {
                next = scanner.getNextToken();
            }
            return next == ITerminalSymbols.TokenNameEOF;
        } catch (InvalidInputException e) {
        }
        return false;
    }

    /**
     * Hook method that gets called from <code>createType</code> to retrieve 
     * a type comment. This default implementation returns the content of the 
     * 'type comment' template.
     * 
     * @param parentCU the parent compilation unit
     * @param lineDelimiter the line delimiter to use
     * @return the type comment or <code>null</code> if a type comment 
     * is not desired
      *
      * @since 3.0
     */
    protected String getTypeComment(ICompilationUnit parentCU, String lineDelimiter) {
        if (isAddComments()) {
            try {
                StringBuffer typeName = new StringBuffer();
                typeName.append(getModuleName());
                String[] typeParamNames = new String[0];
                String comment = CodeGeneration.getTypeComment(parentCU, typeName.toString(), typeParamNames,
                        lineDelimiter);
                if (comment != null && isValidComment(comment)) {
                    return comment;
                }
            } catch (CoreException e) {
                JavaPlugin.log(e);
            }
        }
        return null;
    }

    /**
     * @deprecated Use getTypeComment(ICompilationUnit, String)
     */
    protected String getTypeComment(ICompilationUnit parentCU) {
        if (StubUtility.doAddComments(parentCU.getJavaProject()))
            return getTypeComment(parentCU, StubUtility.getLineDelimiterUsed(parentCU));
        return null;
    }

    /**
     * @deprecated Use getTemplate(String,ICompilationUnit,int)
     */
    protected String getTemplate(String name, ICompilationUnit parentCU) {
        return getTemplate(name, parentCU, 0);
    }

    /**
     * Returns the string resulting from evaluation the given template in
     * the context of the given compilation unit. This accesses the normal
     * template page, not the code templates. To use code templates use
     * <code>constructCUContent</code> to construct a compilation unit stub or
     * getTypeComment for the comment of the type.
     * 
     * @param name the template to be evaluated
     * @param parentCU the templates evaluation context
     * @param pos a source offset into the parent compilation unit. The
     * template is evaluated at the given source offset
     */
    protected String getTemplate(String name, ICompilationUnit parentCU, int pos) {
        try {
            Template template = JavaPlugin.getDefault().getTemplateStore().findTemplate(name);
            if (template != null) {
                return JavaContext.evaluateTemplate(template, parentCU, pos);
            }
        } catch (CoreException e) {
            JavaPlugin.log(e);
        } catch (BadLocationException e) {
            JavaPlugin.log(e);
        } catch (TemplateException e) {
            JavaPlugin.log(e);
        }
        return null;
    }

    // ---- creation ----------------

    /**
     * Returns the runnable that creates the type using the current settings.
     * The returned runnable must be executed in the UI thread.
     * 
     * @return the runnable to create the new type
     */
    public IRunnableWithProgress getRunnable() {
        return new IRunnableWithProgress() {
            public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
                try {
                    if (monitor == null) {
                        monitor = new NullProgressMonitor();
                    }
                    createCompilationUnit(monitor);
                } catch (CoreException e) {
                    throw new InvocationTargetException(e);
                }
            }
        };
    }

    //

    /*
     * @see WizardPage#createControl
     */
    public void createControl(Composite parent) {
        initializeDialogUnits(parent);

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

        int nColumns = 4;

        GridLayout layout = new GridLayout();
        layout.numColumns = nColumns;
        composite.setLayout(layout);

        // pick & choose the wanted UI components

        createContainerControls(composite, nColumns);
        createPackageControls(composite, nColumns);

        createSeparator(composite, nColumns);

        createTypeNameControls(composite, nColumns);
        //createMethodStubSelectionControls(composite, nColumns);

        createSeparator(composite, nColumns);

        createCommentControls(composite, nColumns);
        enableCommentControl(true);

        setControl(composite);

        Dialog.applyDialogFont(composite);
        PlatformUI.getWorkbench().getHelpSystem().setHelp(composite, IJavaHelpContextIds.NEW_CLASS_WIZARD_PAGE);
    }

}