org.eclipse.e4.xwt.ui.wizards.NewPresentationWizardPage.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.e4.xwt.ui.wizards.NewPresentationWizardPage.java

Source

/*******************************************************************************
 * Copyright (c) 2006, 2010 Soyatec (http://www.soyatec.com) 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:
 *     Soyatec - initial API and implementation
 *******************************************************************************/
package org.eclipse.e4.xwt.ui.wizards;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.PrintStream;
import java.net.URL;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.resources.IFile;
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.NullProgressMonitor;
import org.eclipse.e4.xwt.IConstants;
import org.eclipse.e4.xwt.javabean.metadata.Metaclass;
import org.eclipse.e4.xwt.ui.ExceptionHandle;
import org.eclipse.e4.xwt.ui.XWTUIPlugin;
import org.eclipse.e4.xwt.ui.jdt.ASTHelper;
import org.eclipse.e4.xwt.ui.jdt.ProjectHelper;
import org.eclipse.e4.xwt.ui.utils.ProjectContext;
import org.eclipse.jdt.core.ICompilationUnit;
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.JavaModelException;
import org.eclipse.jdt.core.search.IJavaSearchConstants;
import org.eclipse.jdt.core.search.IJavaSearchScope;
import org.eclipse.jdt.core.search.SearchEngine;
import org.eclipse.jdt.internal.ui.IJavaHelpContextIds;
import org.eclipse.jdt.internal.ui.dialogs.FilteredTypesSelectionDialog;
import org.eclipse.jdt.internal.ui.wizards.NewElementWizard;
import org.eclipse.jdt.internal.ui.wizards.dialogfields.DialogField;
import org.eclipse.jdt.internal.ui.wizards.dialogfields.IDialogFieldListener;
import org.eclipse.jdt.internal.ui.wizards.dialogfields.IStringButtonAdapter;
import org.eclipse.jdt.internal.ui.wizards.dialogfields.LayoutUtil;
import org.eclipse.jdt.internal.ui.wizards.dialogfields.StringButtonDialogField;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
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.ui.PlatformUI;

public class NewPresentationWizardPage extends org.eclipse.jdt.ui.wizards.NewClassWizardPage {
    protected String superClass;

    protected IResource guiResource;

    private boolean shouldGenMetaclass = false;

    private StringButtonDialogField fieldEditor;
    private Button metaclassButton;

    private IPackageFragment packageFragment;

    private String dataContext;

    public NewPresentationWizardPage() {
        setTitle("New Wizard Creation");
        setDescription("This wizard creates a data presentation.");
    }

    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);

        createTypeNameControls(composite, nColumns);

        createSeparator(composite, nColumns);
        {
            new Label(composite, SWT.NONE);
            metaclassButton = new Button(composite, SWT.CHECK);
            metaclassButton.setSelection(shouldGenMetaclass);
            metaclassButton.setText("Generating Metaclass");
            GridData data = new GridData();
            data.horizontalSpan = 3;
            metaclassButton.setLayoutData(data);
            metaclassButton.addSelectionListener(new SelectionAdapter() {
                public void widgetSelected(SelectionEvent e) {
                    shouldGenMetaclass = metaclassButton.getSelection();
                }
            });

            createDataContextComp(composite);
        }

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

        createSeparator(composite, nColumns);

        setControl(composite);

        NewElementWizard wizard = (NewElementWizard) getWizard();
        IStructuredSelection selection = (IStructuredSelection) wizard.getSelection();
        IType dataContextType = null;
        for (Iterator iterator = selection.iterator(); iterator.hasNext();) {
            Object element = iterator.next();
            if (element instanceof ICompilationUnit) {
                ICompilationUnit unit = (ICompilationUnit) element;
                dataContextType = unit.findPrimaryType();
                break;
            }
            if (element instanceof IType) {
                dataContextType = (IType) element;
                break;
            }
        }

        if (dataContextType != null) {
            setTypeName(dataContextType.getElementName(), true);
            fieldEditor.setText(dataContextType.getFullyQualifiedName('.'));
            metaclassButton.setSelection(shouldGenMetaclass);
        }

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

    /**
     * @param composite
     * @return
     */
    private void createDataContextComp(Composite composite) {
        DataContextFieldAdapter adapter = new DataContextFieldAdapter();
        fieldEditor = new StringButtonDialogField(adapter);
        fieldEditor.setDialogFieldListener(adapter);
        fieldEditor.setButtonLabel("Browse...");
        fieldEditor.setLabelText("Data Context Type:");
        fieldEditor.doFillIntoGrid(composite, 4);
        LayoutUtil.setWidthHint(fieldEditor.getTextControl(null), getMaxFieldWidth());
    }

    private class DataContextFieldAdapter implements IStringButtonAdapter, IDialogFieldListener {

        // -------- IStringButtonAdapter
        public void changeControlPressed(DialogField field) {
            IType type = chooseDataContext();
            if (type != null) {
                ((StringButtonDialogField) field).setText(type.getFullyQualifiedName());
            }
        }

        // -------- IDialogFieldListener
        public void dialogFieldChanged(DialogField field) {
            dataContext = ((StringButtonDialogField) field).getText();
            validateDataContext();
        }
    }

    public boolean isCreateConstructors() {
        return true;
    }

    /**
     * 
     */
    public void validateDataContext() {
        String newMessage = "Invalid Java Type for initializing DataContext.";
        String errorMessage = getErrorMessage();
        if (dataContext != null) {
            ProjectContext context = ProjectContext.getContext(getJavaProject());
            try {
                context.getClassLoader().loadClass(dataContext);
                if (newMessage.equals(errorMessage)) {
                    setErrorMessage(null);
                } else {
                    setErrorMessage(errorMessage);
                }
            } catch (ClassNotFoundException e) {
                setErrorMessage(newMessage);
            }
        } else {
            if (newMessage.equals(errorMessage)) {
                setErrorMessage(null);
            } else {
                setErrorMessage(errorMessage);
            }
        }
    }

    /**
     * @param field
     */
    public IType chooseDataContext() {
        IJavaProject project = getJavaProject();
        if (project == null) {
            return null;
        }

        IJavaElement[] elements = new IJavaElement[] { project };
        IJavaSearchScope scope = SearchEngine.createJavaSearchScope(elements);

        FilteredTypesSelectionDialog dialog = new FilteredTypesSelectionDialog(getShell(), false,
                getWizard().getContainer(), scope, IJavaSearchConstants.CLASS);
        dialog.setTitle("Choose a JavaBean");
        dialog.setMessage("Choose a JavaBean as a DataContext Type.");
        dialog.setInitialPattern("java.lang.Object");

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

    @Override
    protected void initTypePage(IJavaElement elem) {
        super.initTypePage(elem);
        setSuperClass(getSuperClassName(), false);
    }

    @Override
    public void setPackageFragment(IPackageFragment pack, boolean canBeModified) {

        String name = pack.getElementName() + ".ui";
        IPackageFragmentRoot root = (IPackageFragmentRoot) pack.getParent();
        IPackageFragment packageFragment = root.getPackageFragment(name);
        super.setPackageFragment(packageFragment, canBeModified);
    }

    protected String getSuperClassName() {
        return Composite.class.getName();
    }

    public int getModifiers() {
        return F_PUBLIC;
    }

    /**
     * Returns the chosen super interfaces.
     * 
     * @return a list of chosen super interfaces. The list's elements are of type <code>String</code>
     */
    public List getSuperInterfaces() {
        return Collections.EMPTY_LIST;
    }

    /**
     * Returns the current selection state of the 'Create Main' checkbox.
     * 
     * @return the selection state of the 'Create Main' checkbox
     */
    public boolean isCreateMain() {
        return false;
    }

    protected InputStream getContentStream() {
        IType type = getCreatedType();
        String hostClassName = type.getFullyQualifiedName();
        ByteArrayOutputStream arrayOutputStream = new ByteArrayOutputStream();
        PrintStream printStream = new PrintStream(arrayOutputStream);

        printStream.println("<Composite xmlns=\"" + IConstants.XWT_NAMESPACE + "\"");

        printStream.println("\t xmlns:x=\"" + IConstants.XWT_X_NAMESPACE + "\"");
        String packageName = type.getPackageFragment().getElementName();
        if (packageName != null/* && packageName.length() > 0 */) {
            printStream.println("\t xmlns:c=\"" + IConstants.XAML_CLR_NAMESPACE_PROTO + packageName + "\"");
        }
        printStream.println("\t xmlns:j=\"" + IConstants.XAML_CLR_NAMESPACE_PROTO + "java.lang\"");
        printStream.println("\t x:Class=\"" + hostClassName + "\">");
        printStream.println("\t <Composite.layout>");
        printStream.println("\t\t <GridLayout " + " numColumns=\"4\" />");
        printStream.println("\t </Composite.layout>");

        appendBeanContent(printStream);

        printStream.println("</Composite>");

        try {
            byte[] content = arrayOutputStream.toByteArray();
            printStream.close();
            arrayOutputStream.close();
            return new ByteArrayInputStream(content);
        } catch (Exception e) {
            XWTUIPlugin.log(e);
            ExceptionHandle.handle(e, "save failed in the file: " + getModifiedResource().getLocation());
        }
        return new ByteArrayInputStream(new byte[] {});
    }

    /**
     * @param printStream
     */
    private void appendBeanContent(PrintStream printStream) {
        Class<?> type = getDataContextType();
        if (type == null) {
            return;
        }
        try {
            BeanInfo beanInfo = java.beans.Introspector.getBeanInfo(type);
            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
            for (PropertyDescriptor pd : propertyDescriptors) {
                String name = pd.getName();
                if (name == null || "class".equals(name)) {
                    continue;
                }
                Class<?> propertyType = pd.getPropertyType();
                if (propertyType.isPrimitive() || propertyType == String.class || propertyType == URL.class) {
                    printStream.println("\t <Label text=\"" + pd.getDisplayName() + "\"/>");
                    printStream
                            .println("\t <Text x:Style=\"Border\" text=\"{Binding path=" + pd.getName() + "}\">");
                    printStream.println("\t\t <Text.layoutData>");
                    printStream.println("\t\t\t <GridData grabExcessHorizontalSpace=\"true\"");
                    printStream.println("\t\t\t\t horizontalAlignment=\"GridData.FILL\" widthHint=\"100\"/>");
                    printStream.println("\t\t </Text.layoutData>");
                    printStream.println("\t </Text>");
                } else if (propertyType.isEnum()) {
                    printStream.println("\t <Label text=\"" + pd.getDisplayName() + "\"/>");
                    printStream.println("\t <Combo text=\"{Binding path=" + pd.getName() + "}\">");
                    printStream.println("\t\t <Combo.layoutData>");
                    printStream.println("\t\t\t <GridData grabExcessHorizontalSpace=\"true\"");
                    printStream.println("\t\t\t\t horizontalAlignment=\"GridData.FILL\" widthHint=\"100\"/>");
                    printStream.println("\t\t </Combo.layoutData>");

                    printStream.println("\t\t <Combo.items>");
                    for (Object object : propertyType.getEnumConstants()) {
                        printStream.println("\t\t\t <j:String>" + object.toString() + "</j:String>");
                    }
                    printStream.println("\t\t </Combo.items>");
                    printStream.println("\t </Combo>");

                } else {
                    printStream.println("\t <Group text=\"" + pd.getDisplayName() + "\">");
                    printStream.println("\t\t <Group.layout>");
                    printStream.println("\t\t\t <FillLayout/>");
                    printStream.println("\t\t </Group.layout>");

                    String elementType = propertyType.getSimpleName();
                    printStream.println(
                            "\t\t <c:" + elementType + " DataContext=\"{Binding path=" + pd.getName() + "}\"/>");

                    printStream.println("\t\t <Group.layoutData>");
                    printStream.println("\t\t\t <GridData grabExcessHorizontalSpace=\"true\" horizontalSpan=\"4\"");
                    printStream.println("\t\t\t\t horizontalAlignment=\"GridData.FILL\" widthHint=\"200\"/>");
                    printStream.println("\t\t </Group.layoutData>");

                    printStream.println("\t </Group>");
                }
            }
        } catch (IntrospectionException e) {
        }
    }

    public void createType(IProgressMonitor monitor) throws CoreException, InterruptedException {
        // Add external Jars before create a new Java Source Type.
        ProjectHelper.checkDependenceJars(getJavaProject());
        super.createType(monitor);

        if (shouldGenMetaclass) {
            createMetaclass();
        }

        IResource resource = getModifiedResource();
        IPath resourcePath = resource.getProjectRelativePath().removeFileExtension();
        resourcePath = resourcePath.addFileExtension(IConstants.XWT_EXTENSION);
        try {
            IFile file = resource.getProject().getFile(resourcePath);
            file.create(getContentStream(), IResource.FORCE | IResource.KEEP_HISTORY, monitor);
            guiResource = file;
        } catch (Exception e) {
            e.printStackTrace();
            ExceptionHandle.handle(e, "save failed in the file: " + getModifiedResource().getLocation());
        }
        return;
    }

    public void createMetaclass() {
        IType type = getCreatedType();
        String typeName = type.getElementName();
        String metaclassName = typeName + "Metaclass";
        IType metaclassType = ASTHelper.createType(getPackageFragment(), metaclassName, null, Metaclass.class);
        if (metaclassType != null && dataContext != null) {
            ASTHelper.createMethod(metaclassType, "getDataContentType", getDataContextType().getClass(),
                    "" + getDataContextType().getName() + ".class", null);
        }
        ICompilationUnit cu = metaclassType.getCompilationUnit();
        try {
            cu.commitWorkingCopy(true, new NullProgressMonitor());
        } catch (JavaModelException e) {
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.jdt.ui.wizards.NewTypeWizardPage#getTypeName()
     */
    public String getTypeName() {
        String typeName = super.getTypeName();
        if (typeName == null || typeName.equals("")) {
            return typeName;
        }
        /*
         * Make sure the first character of the new Class name is a upperCase one. Because the Element parser of the XWT file convert the top element to this format.
         */
        return Character.toUpperCase(typeName.charAt(0)) + typeName.substring(1);
    }

    /**
     * Returns the current selection state of the 'Create inherited abstract methods' checkbox.
     * 
     * @return the selection state of the 'Create inherited abstract methods' checkbox
     */
    public boolean isCreateInherited() {
        return true;
    }

    public boolean shouldGenMetaclass() {
        return shouldGenMetaclass;
    }

    public Class<?> getDataContextType() {
        if (dataContext == null || dataContext.trim().length() == 0) {
            return null;
        }
        ProjectContext context = ProjectContext.getContext(getJavaProject());
        try {
            return context.getClassLoader().loadClass(dataContext);
        } catch (ClassNotFoundException e) {
        }
        return null;
    }

    public IResource getGuiResource() {
        return guiResource;
    }
}