org.deved.antlride.internal.ui.wizards.AntlrGrammarPage.java Source code

Java tutorial

Introduction

Here is the source code for org.deved.antlride.internal.ui.wizards.AntlrGrammarPage.java

Source

/*******************************************************************************
 * Copyright (c) 2007, 2008 Edgar Espina.
 * 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
 *
     
 *******************************************************************************/

package org.deved.antlride.internal.ui.wizards;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.deved.antlride.core.AntlrConstants;
import org.deved.antlride.core.AntlrCore;
import org.deved.antlride.core.AntlrLanguageTargetName;
import org.deved.antlride.core.build.AntlrBuildUnit;
import org.deved.antlride.core.model.GrammarType;
import org.deved.antlride.core.resources.AntlrResourceFinder;
import org.deved.antlride.core.util.AntlrTextHelper;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceVisitor;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
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.Path;
import org.eclipse.dltk.ui.DLTKUIPlugin;
import org.eclipse.dltk.ui.dialogs.StatusInfo;
import org.eclipse.jface.dialogs.IMessageProvider;
import org.eclipse.jface.window.Window;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.Widget;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.dialogs.ContainerSelectionDialog;
import org.eclipse.ui.ide.IDE;

public abstract class AntlrGrammarPage extends WizardPage {

    private static final String PROTOTYPE = "prototype";

    private class ValidationListener implements ModifyListener {
        public void modifyText(ModifyEvent e) {
            validate(getFolder(), getGrammarName(), getLanguage(), getTokenVocab());
        }
    }

    private class TokenVocabSelectionListener implements SelectionListener {

        public void widgetSelected(SelectionEvent e) {
            AntlrTokenVocabSelectionDialog dialog = new AntlrTokenVocabSelectionDialog(getShell());
            // dialog.addFilter(filter);
            IContainer container = ResourcesPlugin.getWorkspace().getRoot(); // getProject(getFolder());
            final List<IResource> resources = new ArrayList<IResource>();
            try {
                container.accept(new IResourceVisitor() {

                    public boolean visit(IResource resource) throws CoreException {
                        if (AntlrConstants.ANTLR_GRAMMAR_FILE_EXTENSION.equals(resource.getFileExtension())) {
                            GrammarType grammarType = AntlrResourceFinder.getGrammarType(resource);
                            if (grammarType == GrammarType.COMBINED || grammarType == GrammarType.PARSER
                                    || grammarType == GrammarType.LEXER) {
                                resources.add(resource);
                            }
                        }
                        return true;
                    }
                });
            } catch (CoreException ex) {
                AntlrCore.error(ex);
            }
            dialog.setElements(resources);
            if (dialog.open() == Window.OK) {
                Object selection = dialog.getFirstResult();
                if (selection != null) {
                    tokenVocabText.setText(resourceToString(((IFile) selection)));
                }
            }
        }

        public void widgetDefaultSelected(SelectionEvent e) {
        }
    }

    private class ProperyChangeListener implements SelectionListener {

        public void widgetDefaultSelected(SelectionEvent e) {
        }

        public void widgetSelected(SelectionEvent e) {
            Widget widget = e.widget;
            String property = (String) widget.getData(PROPERTY_NAME);
            String value = (String) widget.getData(property);
            if ((widget.getStyle() & SWT.CHECK) == SWT.CHECK) {
                value = "" + !Boolean.valueOf(value).booleanValue();
                widget.setData(property, value);
            }
            setProperty(property, value);
        }

    }

    private class ChooseFolderListener implements SelectionListener {

        public void widgetSelected(SelectionEvent e) {
            ContainerSelectionDialog dialog = new ContainerSelectionDialog(getShell(), folder, true,
                    "Select a grammar container: ");

            if (dialog.open() == Window.OK) {
                Object[] selection = dialog.getResult();
                if (selection != null && selection.length > 0) {
                    IPath path = (IPath) selection[0];
                    folderText.setText(resourceToString(path));
                }
            }
        }

        public void widgetDefaultSelected(SelectionEvent e) {
        }
    }

    protected static final String FILE_PATH = "path";

    protected static final String LANGUAGE = "language";

    protected static final String GRAMMAR_NAME = "name";

    private static final String PROPERTY_NAME = "keyName";

    protected static final String OUTPUT = "output";

    private Map<String, String> properties;

    private Text folderText;

    private IContainer folder;

    private Text nameText;

    private Combo languageCombo;

    private Text tokenVocabText;

    private Button tokenVocabButton;

    public AntlrGrammarPage(String pageName) {
        super(pageName);

        properties = new HashMap<String, String>();

        setTitle(getPageTitle());

        setDescription(getPageDescription());
    }

    protected String getProperty(String property) {
        return properties.get(property);
    }

    protected void setProperty(String property, String value) {
        properties.put(property, value);
    }

    protected abstract String getPageDescription();

    protected abstract String getPageTitle();

    public void createControl(Composite parent) {
        initializeDialogUnits(parent);

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

        GridLayout gridLayout = new GridLayout(3, false);
        gridLayout.verticalSpacing = 10;
        composite.setLayout(gridLayout);

        Label label = null;
        GridData gd = null;

        ValidationListener validator = new ValidationListener();

        label = new Label(composite, SWT.NONE);
        label.setText("Container:");
        folderText = new Text(composite, SWT.BORDER);
        folderText.setText(resourceToString(folder));
        folderText.addModifyListener(validator);
        gd = new GridData(GridData.FILL_HORIZONTAL);
        folderText.setLayoutData(gd);
        Button browse = new Button(composite, SWT.PUSH);
        browse.addSelectionListener(new ChooseFolderListener());
        browse.setText("    Browse...    ");

        label = new Label(composite, SWT.NONE);
        label.setText("Name:");
        nameText = new Text(composite, SWT.BORDER);
        nameText.addModifyListener(validator);
        gd = new GridData(GridData.FILL_HORIZONTAL);
        gd.horizontalSpan = 2;
        nameText.setLayoutData(gd);

        label = new Label(composite, SWT.SEPARATOR | SWT.HORIZONTAL);
        gd = new GridData(GridData.FILL_HORIZONTAL);
        gd.horizontalSpan = 3;
        label.setLayoutData(gd);

        if (hasOutputSection()) {
            createOutputSection(composite);
        }
        // language section
        label = new Label(composite, SWT.NONE);
        label.setText("Language:");
        Composite langSection = new Composite(composite, SWT.NONE);
        langSection.setLayout(new GridLayout(3, true));
        gd = new GridData(GridData.FILL_HORIZONTAL);
        gd.horizontalSpan = 2;
        langSection.setLayoutData(gd);
        String[] languages = AntlrLanguageTargetName.names();
        languageCombo = (Combo) addComboBox(langSection, "Language:", LANGUAGE, languages, languages,
                AntlrLanguageTargetName.Java.ordinal())[0];
        languageCombo.addModifyListener(validator);

        // Dependent section
        if (hasDependentSection()) {
            label = new Label(composite, SWT.NONE);
            label.setText("Dependent:");
            Button dependentButton = addCheckButton(composite, PROTOTYPE, "false", false);
            gd = new GridData(GridData.FILL_HORIZONTAL);
            gd.horizontalSpan = 2;
            dependentButton.setLayoutData(gd);
        }

        if (hasTokenVocabSection()) {
            createTokenVocabSection(composite);
        }

        setControl(composite);

        validate(getFolder(), getGrammarName(), getLanguage(), getTokenVocab());

        if (getFolder().length() > 0) {
            Display.getDefault().asyncExec(new Runnable() {

                public void run() {
                    nameText.setFocus();
                }
            });
        }
    }

    protected boolean hasOutputSection() {
        return false;
    }

    protected void createTokenVocabSection(Composite composite) {
        Label label;
        GridData gd;

        label = new Label(composite, SWT.NONE);
        label.setText("Token Vocabulary:");
        tokenVocabText = new Text(composite, SWT.BORDER);
        tokenVocabText.addModifyListener(new ValidationListener());
        gd = new GridData(GridData.FILL_HORIZONTAL);
        tokenVocabText.setLayoutData(gd);
        tokenVocabButton = new Button(composite, SWT.PUSH);
        tokenVocabButton.addSelectionListener(new TokenVocabSelectionListener());
        tokenVocabButton.setText("    Browse...    ");
    }

    protected void createOutputSection(Composite composite) {
        Label label = new Label(composite, SWT.NONE);
        label.setText("Output:");
        Composite outputSection = new Composite(composite, SWT.NONE);
        outputSection.setLayout(new GridLayout(3, true));
        GridData gd = new GridData(GridData.FILL_HORIZONTAL);
        gd.horizontalSpan = 2;

        outputSection.setLayoutData(gd);

        addRadioButton(outputSection, AntlrWizardMessages.NewGrammarFilePage_NoneOutput, OUTPUT, null, true);

        addRadioButton(outputSection, AntlrWizardMessages.NewGrammarFilePage_ASTOutput, OUTPUT, "AST", false);//$NON-NLS-1$

        addRadioButton(outputSection, AntlrWizardMessages.NewGrammarFilePage_TemplateOutput, OUTPUT, "template", //$NON-NLS-1$
                false);
    }

    protected Control[] addComboBox(Composite parent, String label, String key, String[] items, String[] values,
            int selected) {
        GridData gd = null;
        Combo combo = new Combo(parent, SWT.SINGLE);
        gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
        combo.setFont(parent.getFont());
        combo.setItems(items);
        combo.setLayoutData(gd);
        combo.select(selected);
        return new Control[] { combo };
    }

    protected Button addCheckButton(Composite parent, String key, String value, boolean selected) {
        Button checkbox = new Button(parent, SWT.CHECK);
        checkbox.setData(key, value);
        checkbox.setData(PROPERTY_NAME, key);
        checkbox.setSelection(selected);
        checkbox.addSelectionListener(new ProperyChangeListener());
        return checkbox;
    }

    protected Button addRadioButton(Composite parent, String label, String key, String value, boolean selected) {
        Button radio = new Button(parent, SWT.RADIO);
        radio.setData(key, value);
        radio.setData(PROPERTY_NAME, key);
        radio.setSelection(selected);
        radio.setText(label);
        radio.addSelectionListener(new ProperyChangeListener());
        return radio;
    }

    protected Composite createSubsection(Composite parent, String label, int align) {
        Group group = new Group(parent, SWT.SHADOW_NONE);
        group.setLayout(new FillLayout(align));
        group.setText(label);
        if (parent.getLayout() instanceof GridLayout) {
            GridData data = new GridData(SWT.FILL, SWT.CENTER, true, false);
            data.horizontalSpan = 3;
            group.setLayoutData(data);
        }
        return group;
    }

    public void init(IResource resource) {
        folder = null;
        if (resource != null) {
            if (resource instanceof IContainer) {
                folder = (IContainer) resource;
            } else {
                folder = resource.getParent();
            }
        }
    }

    protected void updateStatus(IStatus status) {
        setPageComplete(status.isOK());
        int severity = status.getSeverity();
        if (severity == IStatus.OK) {
            setMessage(status.getMessage(), IMessageProvider.NONE);
            setErrorMessage(null);
        } else {
            setMessage(null);
            setErrorMessage(status.getMessage());
        }
    }

    protected void validate(String folder, String name, String language, String tokenVocab) {
        enableTokenVocab(false);
        IStatus status = validateFolder(folder);
        if (status != null) {
            updateStatus(status);
            return;
        }
        status = validateGrammar(folder, name);
        if (status != null) {
            updateStatus(status);
            return;
        }
        status = validateLanguage(getLanguage());
        if (status != null) {
            updateStatus(status);
            return;
        }
        boolean dependent = Boolean.valueOf(getProperty(PROTOTYPE)).booleanValue();
        if (!dependent) {
            enableTokenVocab(true);
            status = validateTokenVocab(tokenVocab);
            if (status != null) {
                updateStatus(status);
                return;
            }
        }
        updateStatus(new StatusInfo(StatusInfo.OK, getPageDescription()));
    }

    private void enableTokenVocab(boolean enabled) {
        if (hasTokenVocabSection()) {
            tokenVocabButton.setEnabled(enabled);
            tokenVocabText.setEditable(enabled);
        }
    }

    protected boolean hasTokenVocabSection() {
        return false;
    }

    protected IStatus validateTokenVocab(String tokenVocab) {
        if (hasTokenVocabSection()) {
            if (tokenVocab == null || tokenVocab.length() == 0) {
                return createErrorStatus("Token Vocabulary is empty");
            }
            IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
            IFile tokenVocabFile = root.getFile(new Path(tokenVocab));
            if (tokenVocabFile == null || !tokenVocabFile.exists()) {
                return createErrorStatus("Token Vocabulary does not exist");
            }
        }
        return null;
    }

    protected IStatus validateFolder(String folder) {
        if (folder == null || folder.length() == 0) {
            return createErrorStatus("Container is empty");
        }
        IContainer container = getContainer(folder);
        if (container == null || !container.exists()) {
            return createErrorStatus("Container does not exist");
        }

        return null;
    }

    protected IStatus validateLanguage(String language) {
        if (language == null || language.length() == 0) {
            return createErrorStatus("Language is empty");
        }
        return null;
    }

    private String getLanguage() {
        return languageCombo.getText();
    }

    private IContainer getContainer(String path) {
        IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
        IPath containerPath = new Path(path);
        if (containerPath.segmentCount() == 1) {
            // is a project
            String projectName = containerPath.lastSegment();
            return root.getProject(projectName);
        }
        return root.getFolder(containerPath);
    }

    protected IStatus validateGrammar(String folder, String name) {
        if (name == null || name.length() == 0) {
            return createErrorStatus(AntlrWizardMessages.NewGrammarFilePage_Error_EmptyGrammarName);
        } else {
            if (!AntlrTextHelper.isGrammarName(name)) {
                return createErrorStatus(MessageFormat
                        .format(AntlrWizardMessages.NewGrammarFilePage_Error_InvalidGrammarName, name));
            }
            IPath path = new Path(folder).append(name).addFileExtension("g");
            IWorkspaceRoot ws = ResourcesPlugin.getWorkspace().getRoot();
            IFile file = ws.getFile(path);
            if (file.exists()) {
                return createErrorStatus(MessageFormat
                        .format(AntlrWizardMessages.NewGrammarFilePage_Error_GrammarAlreadyExist, name));
            }
        }
        return null;
    }

    protected IStatus createErrorStatus(String message) {
        StatusInfo status = new StatusInfo(StatusInfo.ERROR, message);
        return status;
    }

    private String getFolder() {
        return folderText.getText();
    }

    private String getTokenVocab() {
        if (hasTokenVocabSection())
            return tokenVocabText.getText();
        return null;
    }

    private String getGrammarName() {
        return nameText.getText();
    }

    protected String resourceToString(IResource resource) {
        if (resource == null) {
            return "";
        }
        return resourceToString(resource.getFullPath());
    }

    protected String resourceToString(IPath fullpath) {
        if (fullpath == null) {
            return "";
        }
        return fullpath.makeRelative().toString();
    }

    public final IFile createGrammar(IProgressMonitor monitor) {
        InputStream contents = null;
        try {
            IContainer folder = getContainer(getFolder());
            IFile file = folder.getFile(
                    new Path(getGrammarName()).addFileExtension(AntlrConstants.ANTLR_GRAMMAR_FILE_EXTENSION));
            // set all options
            setProperty(GRAMMAR_NAME, getGrammarName());
            setProperty(AntlrConstants.ANTLR_GRAMMAR_TYPE, getGrammarType());
            setProperty(LANGUAGE, getLanguage());
            setProperty(FILE_PATH, file.getFullPath().toString());
            setProperty("tokenVocab", getTokenVocab());
            contents = new ByteArrayInputStream(getContents().getBytes());
            file.create(contents, IResource.FORCE, monitor);
            file.setPersistentProperty(AntlrConstants.Q_ANTLR_GRAMMAR_TYPE, getGrammarType());
            fileCreated(file);
            return file;
        } catch (CoreException ex) {
            AntlrCore.error(ex);
        } finally {
            if (contents != null) {
                try {
                    contents.close();
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
        }
        return null;
    }

    protected abstract String getGrammarType();

    protected void fileCreated(IFile file) throws CoreException {
        if (hasDependentSection()) {
            String prototype = Boolean.valueOf(getProperty(PROTOTYPE)).toString();
            file.setPersistentProperty(AntlrBuildUnit.DEPENDENT_GRAMMAR, prototype);
        }
    }

    protected boolean hasDependentSection() {
        return true;
    }

    public void openGrammar(final IFile resource) {
        final IWorkbenchPage activePage = DLTKUIPlugin.getActivePage();
        if (activePage != null) {
            final Display display = getShell().getDisplay();
            if (display != null) {
                display.syncExec(new Runnable() {
                    public void run() {
                        try {
                            IDE.openEditor(activePage, resource, true);
                        } catch (PartInitException e) {
                            DLTKUIPlugin.log(e);
                        }
                    }
                });
            }
        }
    }

    protected abstract String getContents();
}