org.jboss.tools.batch.ui.internal.wizard.NewBatchArtifactWizardPage.java Source code

Java tutorial

Introduction

Here is the source code for org.jboss.tools.batch.ui.internal.wizard.NewBatchArtifactWizardPage.java

Source

/*******************************************************************************
 * Copyright (c) 2015 Red Hat, Inc.
 * Distributed under license by Red Hat, Inc. All rights reserved.
 * This program is 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:
 *     Red Hat, Inc. - initial API and implementation
 ******************************************************************************/
package org.jboss.tools.batch.ui.internal.wizard;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.jdt.core.IBuffer;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IField;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.ISourceRange;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.ToolFactory;
import org.eclipse.jdt.core.formatter.CodeFormatter;
import org.eclipse.jdt.internal.corext.codemanipulation.CodeGenerationSettings;
import org.eclipse.jdt.internal.corext.codemanipulation.StubUtility;
import org.eclipse.jdt.internal.corext.util.JavaConventionsUtil;
import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
import org.eclipse.jdt.internal.ui.IJavaHelpContextIds;
import org.eclipse.jdt.internal.ui.dialogs.StatusInfo;
import org.eclipse.jdt.internal.ui.preferences.JavaPreferencesSettings;
import org.eclipse.jdt.ui.CodeGeneration;
import org.eclipse.jdt.ui.wizards.NewClassWizardPage;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.text.edits.TextEdit;
import org.eclipse.ui.PlatformUI;
import org.jboss.tools.batch.core.BatchArtifactType;
import org.jboss.tools.batch.core.BatchConstants;
import org.jboss.tools.batch.core.BatchCorePlugin;
import org.jboss.tools.batch.core.IBatchProject;
import org.jboss.tools.batch.ui.JobImages;
import org.jboss.tools.common.ui.widget.editor.IFieldEditor;
import org.jboss.tools.common.util.BeanUtil;

/**
 * 
 * @author Viacheslav Kabanovich
 *
 */
public class NewBatchArtifactWizardPage extends NewClassWizardPage implements PropertyChangeListener {
    protected String defaultTypeName = null;

    IFieldEditor artifacts;
    IFieldEditor derivedFrom;

    IFieldEditor nameOptions;
    IFieldEditor name;
    boolean canNameBeModified = true;

    IFieldEditor properties;

    protected StatusInfo artifactNameStatus = new StatusInfo();
    protected StatusInfo propertiesStatus = new StatusInfo();

    public NewBatchArtifactWizardPage() {
        setTitle(WizardMessages.NEW_BATCH_ARTIFACT_WIZARD_PAGE_NAME);
        setDescription(WizardMessages.NEW_BATCH_ARTIFACT_WIZARD_DESCRIPTION);
        setImageDescriptor(JobImages.getImageDescriptor(JobImages.NEW_ARTIFACT_IMAGE));
    }

    /**
     * Presets properties to artifact.
     * @param propertyNames
     */
    public void setProperties(List<String> propertyNames) {
        properties.setValue(propertyNames);
    }

    /**
     * Presets the artifact to be created.
     * @param type
     */
    public void setArtifact(BatchArtifactType type, boolean canBeModified) {
        String label = BatchFieldEditorFactory.getArtifactLabel(type);
        if (label != null) {
            setArtifactByLabel(label);
            setArtifactCanBeModified(canBeModified);
        }
    }

    /**
     * Presets name for the artifact to be created.
     * @param type
     */
    public void setArtifactName(String artifactName) {
        name.setValue(artifactName);
    }

    public void setArtifactName(String artifactName, boolean canBeModified) {
        name.setValue(artifactName);
        canNameBeModified = canBeModified;
        name.setEnabled(canBeModified);
    }

    public String getArtifactName() {
        return name.getValueAsString();
    }

    void setArtifactByLabel(String label) {
        artifacts.setValue(label);
    }

    /**
     * Presets artifact extending from abstract class if available for current artifact type.
     */
    public void setDeriveFromAbstractClass() {
        String artifactName = artifacts.getValueAsString();
        BatchArtifactType type = BatchFieldEditorFactory.ARTIFACTS.get(artifactName);
        if (type.getClassName() != null) {
            derivedFrom.setValue(BatchFieldEditorFactory.DERIVE_FROM_CLASS);
        }
    }

    /**
     * Presets artifact implementing from interface.
     */
    public void setDeriveFromInterface() {
        derivedFrom.setValue(BatchFieldEditorFactory.DERIVE_FROM_INTERFACE);
    }

    /**
     * 
     * @param b
     */
    public void setArtifactCanBeModified(boolean canBeModified) {
        artifacts.setEnabled(canBeModified);
    }

    @Override
    public void init(IStructuredSelection selection) {
        super.init(selection);
        defaultTypeName = null;
        setSuperClass(BatchArtifactType.ABSTRACT_BATCHLET_TYPE, false);

        List<BatchArtifactType> types = ((NewBatchArtifactWizard) getWizard()).getTypes();
        artifacts = types != null && types.size() > 1
                ? BatchFieldEditorFactory.createArtifactEditor(getDefaultArtifact(), types)
                : BatchFieldEditorFactory.createArtifactEditor(getDefaultArtifact());
        derivedFrom = BatchFieldEditorFactory.createDerivedFromEditor();

        nameOptions = BatchFieldEditorFactory.createNameOptionsEditor();
        name = BatchFieldEditorFactory.createArtifactNameEditor();

        properties = BatchFieldEditorFactory.createPropertiesEditor();

        doStatusUpdate();
    }

    @Override
    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);
        // createEnclosingTypeControls(composite, nColumns);

        createSeparator(composite, nColumns);

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

        artifacts.doFillIntoGrid(composite);
        derivedFrom.doFillIntoGrid(composite);

        createSeparator(composite, nColumns);

        nameOptions.doFillIntoGrid(composite);
        name.doFillIntoGrid(composite);
        Control c = (Control) name.getEditorControls()[1];
        GridData d = (GridData) c.getLayoutData();
        d.horizontalSpan--;
        c.setLayoutData(d);

        artifacts.addPropertyChangeListener(this);
        derivedFrom.addPropertyChangeListener(this);
        nameOptions.addPropertyChangeListener(this);
        name.addPropertyChangeListener(this);

        createSeparator(composite, nColumns);

        properties.doFillIntoGrid(composite);
        properties.addPropertyChangeListener(this);

        setControl(composite);

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

        onArtifactKindChange();
        doStatusUpdate();
    }

    protected BatchArtifactType getDefaultArtifact() {
        return BatchArtifactType.BATCHLET;
    }

    private void doStatusUpdate() {
        // status of all used components
        IStatus[] status = new IStatus[] { fContainerStatus,
                isEnclosingTypeSelected() ? fEnclosingTypeStatus : fPackageStatus, fTypeNameStatus, fModifierStatus,
                fSuperClassStatus, fSuperInterfacesStatus };

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

    @Override
    protected void updateStatus(IStatus[] status) {
        IStatus[] ns = new IStatus[status.length + 2];
        System.arraycopy(status, 0, ns, 0, status.length);
        ns[status.length] = artifactNameStatus;
        ns[status.length + 1] = propertiesStatus;
        status = ns;
        super.updateStatus(status);
    }

    @Override
    public void propertyChange(PropertyChangeEvent evt) {
        String name = evt.getPropertyName();
        if (BatchFieldEditorFactory.ARTIFACT_EDITOR.equals(name)) {
            onArtifactKindChange();
        } else if (BatchFieldEditorFactory.DERIVE_FROM_EDITOR.equals(name)) {
            onDerivedFromChange();
        } else if (BatchFieldEditorFactory.LOADER_OPTIONS_EDITOR.equals(name)) {
            onNameOptionChange();
        } else if (BatchFieldEditorFactory.NAME_EDITOR.equals(name)) {
            onNameChange();
        } else if (BatchFieldEditorFactory.PROPERTIES_EDITOR.equals(name)) {
            onFieldNameChange();
        }
        doStatusUpdate();
    }

    void onArtifactKindChange() {
        String artifactName = artifacts.getValueAsString();
        BatchArtifactType type = BatchFieldEditorFactory.ARTIFACTS.get(artifactName);
        if (type != null) {
            boolean hasNoClass = type.getClassName() == null;
            if (hasNoClass) {
                if (BatchFieldEditorFactory.DERIVE_FROM_CLASS.equals(derivedFrom.getValueAsString())) {
                    derivedFrom.setValue(BatchFieldEditorFactory.DERIVE_FROM_INTERFACE);
                }
            }
            if (getControl() != null) {
                Composite p = (Composite) derivedFrom.getEditorControls()[1];
                p.getChildren()[1].setEnabled(!hasNoClass);
            }
            onDerivedFromChange();
        }
    }

    void onDerivedFromChange() {
        String artifactName = artifacts.getValueAsString();
        BatchArtifactType type = BatchFieldEditorFactory.ARTIFACTS.get(artifactName);
        if (type != null) {
            if (BatchFieldEditorFactory.DERIVE_FROM_CLASS.equals(derivedFrom.getValueAsString())) {
                setSuperClass(type.getClassName(), false);
                setSuperInterfaces(new ArrayList<String>(), false);
            } else {
                setSuperClass("", false);
                setSuperInterfaces(Arrays.asList(type.getInterfaceName()), false);
            }
        }
    }

    void onNameOptionChange() {
        name.setEnabled(!isArtifactNameQualified());
        if (isArtifactNameQualified()) {
            name.setValue(getQualifiedName());
        } else {
            name.setValue(BeanUtil.getDefaultBeanName(getTypeName()));
        }
    }

    void onNameChange() {
        artifactNameStatus = new StatusInfo();
        if (getJavaProject() == null) {
            return;
        }
        IBatchProject bp = BatchCorePlugin.getBatchProject(getJavaProject().getProject(), true);
        if (bp != null) {
            String v = name.getValueAsString();
            if (v.length() == 0) {
                artifactNameStatus.setError(WizardMessages.errorArtifactNameIsEmpty);
            } else if (!bp.getArtifacts(v).isEmpty()) {
                artifactNameStatus.setError(WizardMessages.errorArtifactNameIsNotUnique);
            }
        }
    }

    void onFieldNameChange() {
        propertiesStatus = new StatusInfo();
        Set<String> fields = new HashSet<String>();
        for (String n : ((List<String>) properties.getValue())) {
            if (n == null || n.length() == 0)
                continue;
            IStatus val = JavaConventionsUtil.validateFieldName(n, null);
            if (val != null && val.getSeverity() == IStatus.ERROR) {
                propertiesStatus.setError(NLS.bind(WizardMessages.errorFieldNameIsNotValid, val.getMessage()));
                return;
            }
            if (fields.contains(n)) {
                propertiesStatus.setError(NLS.bind(WizardMessages.errorFieldNameIsNotUnique, n));
                return;
            }
            fields.add(n);
        }
    }

    boolean isArtifactNameQualified() {
        String nameOption = nameOptions.getValueAsString();
        return BatchFieldEditorFactory.LOADER_OPTION_QUALIFIED.equals(nameOption);
    }

    String getQualifiedName() {
        return getPackageText() + "." + getTypeName();
    }

    boolean isArtifactNameDefault = true;

    @Override
    protected IStatus typeNameChanged() {
        IStatus result = super.typeNameChanged();
        if (name != null && canNameBeModified) {
            if (isArtifactNameDefault) {
                if (!isArtifactNameQualified()) {
                    name.setValue(BeanUtil.getDefaultBeanName(getTypeName()));
                } else {
                    name.setValue(getPackageText() + "." + getTypeName());
                }
            }
        }
        //validate custom fields here
        return result;
    }

    @Override
    protected void createTypeMembers(IType newType, final ImportsManager imports, IProgressMonitor monitor)
            throws CoreException {
        createInheritedMethods(newType, true, true, imports, new SubProgressMonitor(monitor, 1));

        ISourceRange range = newType.getSourceRange();
        IBuffer buf = newType.getCompilationUnit().getBuffer();
        String lineDelimiter = StubUtility.getLineDelimiterUsed(newType.getJavaProject());
        StringBuffer sb = new StringBuffer();
        addAnnotations(imports, sb, lineDelimiter);
        buf.replace(range.getOffset(), 0, sb.toString());
        createFields(newType, imports, monitor, lineDelimiter);
    }

    void addAnnotations(ImportsManager imports, StringBuffer sb, String lineDelimiter) {
        if (BatchFieldEditorFactory.LOADER_OPTION_ANNOTATION.equals(nameOptions.getValueAsString())) {
            addNamedAnnotation(imports, sb, lineDelimiter);
        }
    }

    protected void addNamedAnnotation(ImportsManager imports, StringBuffer sb, String lineDelimiter) {
        String annotationValue = name.getValueAsString();
        if (BeanUtil.getDefaultBeanName(getTypeName()).equals(annotationValue)) {
            annotationValue = "";
        }
        addAnnotation(BatchConstants.NAMED_QUALIFIER_TYPE, annotationValue, imports, sb, lineDelimiter);
    }

    static void addAnnotation(String typeName, String value, ImportsManager imports, StringBuffer sb,
            String lineDelimiter) {
        int i = typeName.lastIndexOf('.');
        String name = typeName.substring(i + 1);
        imports.addImport(typeName);
        sb.append("@").append(name);
        if (value != null && value.length() > 0) {
            sb.append("(\"").append(value).append("\")");
        }
        sb.append(lineDelimiter);
    }

    protected void createFields(IType type, ImportsManager imports, IProgressMonitor monitor, String lineDelimiter)
            throws CoreException {
        imports.addImport(BatchConstants.INJECT_ANNOTATION_TYPE);
        imports.addImport(BatchConstants.BATCH_PROPERTY_QUALIFIER_TYPE);

        ICompilationUnit cu = type.getCompilationUnit();
        JavaModelUtil.reconcile(cu);
        CodeGenerationSettings settings = JavaPreferencesSettings.getCodeGenerationSettings(type.getJavaProject());
        settings.createComments = isAddComments();
        String access = "protected";
        String javatype = "String";

        IJavaElement[] cs = type.getChildren();
        IJavaElement sibling = cs == null || cs.length == 0 ? null : cs[0];

        for (String fieldName : ((List<String>) properties.getValue())) {
            String fieldHeader = "@Inject @BatchProperty " + access + " " + javatype + " " + fieldName + ";" //$NON-NLS-1$//$NON-NLS-2$
                    + lineDelimiter;
            IField m = type.createField(fieldHeader, sibling, true, null);
            editField(cu, m, javatype, fieldHeader, lineDelimiter);
        }
    }

    void editField(ICompilationUnit cu, IField m, String javatype, String fieldHeader, String lineDelimiter)
            throws CoreException {
        synchronized (cu) {
            cu.reconcile(ICompilationUnit.NO_AST, true, null, null);
        }
        ISourceRange range = m.getSourceRange();
        IBuffer buf = cu.getBuffer();
        StringBuffer sb = new StringBuffer(lineDelimiter);
        if (isAddComments()) {
            String fieldComment = CodeGeneration.getFieldComment(cu, javatype, m.getElementName(), lineDelimiter);
            sb.append(fieldComment).append(lineDelimiter);
        }
        sb.append(fieldHeader);
        String formattedContent = codeFormat2(CodeFormatter.K_CLASS_BODY_DECLARATIONS, sb.toString(), 1,
                lineDelimiter, cu.getJavaProject());
        if (formattedContent != null && formattedContent.startsWith("\t")) { //$NON-NLS-1$
            formattedContent = formattedContent.substring(1);
        }
        buf.replace(range.getOffset(), range.getLength(), formattedContent);
    }

    //JavaBeanGenerator
    static String codeFormat2(int kind, String sourceString, int indentationLevel, String lineSeparator,
            IJavaProject project) {
        TextEdit edit = ToolFactory.createCodeFormatter(project.getOptions(true)).format(kind, sourceString, 0,
                sourceString.length(), indentationLevel, lineSeparator);
        Document doc = new Document(sourceString);
        try {
            edit.apply(doc, 0);
            return doc.get();
        } catch (BadLocationException e) {
            return sourceString;
        }
    }

    public BatchArtifactType getArtifactType() {
        return BatchFieldEditorFactory.getArtifactType(artifacts.getValueAsString());
    }

}