org.eclipse.mylyn.internal.web.tasks.WebQueryWizardPage.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.mylyn.internal.web.tasks.WebQueryWizardPage.java

Source

/*******************************************************************************
 * Copyright (c) 2004, 2009 Eugene Kuleshov 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:
 *     Eugene Kuleshov - initial API and implementation
 *******************************************************************************/

package org.eclipse.mylyn.internal.web.tasks;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IMessageProvider;
import org.eclipse.jface.fieldassist.ControlDecoration;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.mylyn.commons.ui.CommonUiUtil;
import org.eclipse.mylyn.commons.workbench.browser.BrowserUtil;
import org.eclipse.mylyn.tasks.core.IRepositoryQuery;
import org.eclipse.mylyn.tasks.core.TaskRepository;
import org.eclipse.mylyn.tasks.core.data.TaskData;
import org.eclipse.mylyn.tasks.core.data.TaskDataCollector;
import org.eclipse.mylyn.tasks.core.data.TaskMapper;
import org.eclipse.mylyn.tasks.ui.wizards.AbstractRepositoryQueryPage;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
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.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.browser.IWorkbenchBrowserSupport;
import org.eclipse.ui.forms.events.ExpansionAdapter;
import org.eclipse.ui.forms.events.ExpansionEvent;
import org.eclipse.ui.forms.widgets.ExpandableComposite;
import org.eclipse.ui.forms.widgets.FormToolkit;

/**
 * Wizard page for configuring and preview web query
 * 
 * @author Eugene Kuleshov
 */
public class WebQueryWizardPage extends AbstractRepositoryQueryPage {

    private Text queryUrlText;

    private Text queryPatternText;

    private TableViewer previewTable;

    private String webPage;

    private UpdatePreviewJob updatePreviewJob;

    private final FormToolkit toolkit = new FormToolkit(Display.getCurrent());

    private ParametersEditor parametersEditor;

    private Map<String, String> oldProperties;

    private final ArrayList<ControlDecoration> decorations = new ArrayList<ControlDecoration>();

    private Text title;

    public WebQueryWizardPage(TaskRepository repository, IRepositoryQuery query) {
        super(Messages.WebQueryWizardPage_New_web_query, repository, query);
        setTitle(Messages.WebQueryWizardPage_Create_web_query);
        setDescription(Messages.bind(Messages.WebQueryWizardPage_Specify_query_parameters_for_X,
                repository.getRepositoryUrl()));
    }

    @Override
    public void dispose() {
        for (ControlDecoration decoration : decorations) {
            decoration.dispose();
        }
        super.dispose();
    }

    private static String getDefaultQueryTitle(TaskRepository repository) {
        String label = repository.getRepositoryLabel();
        String title = label;
        for (int n = 1; hasQueryWithTitle(repository, title); n++) {
            title = label + " " + n;
        }
        return title;
    }

    @SuppressWarnings("restriction")
    private static boolean hasQueryWithTitle(TaskRepository repository, String title) {
        Set<org.eclipse.mylyn.internal.tasks.core.RepositoryQuery> queries = org.eclipse.mylyn.internal.tasks.ui.TasksUiPlugin
                .getTaskList().getRepositoryQueries(repository.getRepositoryUrl());
        for (IRepositoryQuery query : queries) {
            if (query.getSummary().equals(title)) {
                return true;
            }
        }
        return false;
    }

    private void createTitleGroup(Composite parent) {
        Composite group = new Composite(parent, SWT.NONE);

        GridLayout layout = new GridLayout(2, false);
        group.setLayout(layout);

        GridData gd = new GridData(GridData.FILL_HORIZONTAL);
        gd.horizontalSpan = 1;
        group.setLayoutData(gd);

        Label label = new Label(group, SWT.NONE);
        label.setText(Messages.WebQueryWizardPage_Query_Title_);

        title = new Text(group, SWT.BORDER);
        title.setLayoutData(new GridData(GridData.FILL_HORIZONTAL | GridData.GRAB_HORIZONTAL));
        title.setText(getQuery() == null ? getDefaultQueryTitle(getTaskRepository()) : getQuery().getSummary());
        title.addModifyListener(new ModifyListener() {
            public void modifyText(ModifyEvent e) {
                setPageComplete(isPageComplete());
            }
        });
        title.setFocus();
    }

    @Override
    public String getQueryTitle() {
        return (title != null) ? title.getText() : null;
    }

    public void createControl(Composite parent) {
        final Composite composite = new Composite(parent, SWT.NONE);
        GridLayout gridLayout = new GridLayout();
        gridLayout.marginHeight = 0;
        gridLayout.marginWidth = 0;
        gridLayout.verticalSpacing = 0;
        gridLayout.numColumns = 1;
        composite.setLayout(gridLayout);

        if (!inSearchContainer()) {
            createTitleGroup(composite);
        }

        parametersEditor = new ParametersEditor(composite, SWT.NONE);
        GridData gridData1 = new GridData(SWT.FILL, SWT.FILL, true, true);
        gridData1.minimumHeight = 90;
        parametersEditor.setLayoutData(gridData1);

        ExpandableComposite expComposite = toolkit.createExpandableComposite(composite,
                ExpandableComposite.COMPACT | ExpandableComposite.TWISTIE);
        expComposite.setFont(parent.getFont());
        GridData gridData_1 = new GridData(SWT.FILL, SWT.FILL, true, false);
        gridData_1.heightHint = 150;
        gridData_1.minimumHeight = 150;
        expComposite.setLayoutData(gridData_1);
        expComposite.setBackground(parent.getBackground());
        expComposite.setText(Messages.WebQueryWizardPage_Advanced_Configuration);
        expComposite.addExpansionListener(new ExpansionAdapter() {
            @Override
            public void expansionStateChanged(ExpansionEvent e) {
                getControl().getShell().pack();
            }
        });
        toolkit.paintBordersFor(expComposite);

        Composite composite1 = toolkit.createComposite(expComposite, SWT.BORDER);
        composite1.setLayout(new GridLayout(3, false));
        expComposite.setClient(composite1);

        toolkit.createLabel(composite1, Messages.WebQueryWizardPage_Query_URL_, SWT.NONE);

        queryUrlText = new Text(composite1, SWT.BORDER);
        final GridData gridData_2 = new GridData(SWT.FILL, SWT.CENTER, true, false);
        gridData_2.widthHint = 200;
        queryUrlText.setLayoutData(gridData_2);
        queryUrlText.addModifyListener(new ModifyListener() {
            public void modifyText(final ModifyEvent e) {
                webPage = null;
            }
        });
        decorations.add(WebContentProposalProvider.createDecoration(queryUrlText, parametersEditor, false));

        Button button = new Button(composite1, SWT.NONE);
        button.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
        button.setText(Messages.WebQueryWizardPage_Open);
        button.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                openBrowser();
            }
        });

        Label queryPatternLabel = toolkit.createLabel(composite1, Messages.WebQueryWizardPage_Query_Pattern_,
                SWT.NONE);
        queryPatternLabel.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false));

        queryPatternText = new Text(composite1, SWT.V_SCROLL | SWT.MULTI | SWT.BORDER | SWT.WRAP);
        GridData gridData = new GridData(SWT.FILL, SWT.TOP, true, false);
        gridData.widthHint = 200;
        gridData.heightHint = 60;
        queryPatternText.setLayoutData(gridData);
        decorations.add(WebContentProposalProvider.createDecoration(queryPatternText, parametersEditor, true));

        Button preview = new Button(composite1, SWT.NONE);
        preview.setLayoutData(new GridData(SWT.FILL, SWT.TOP, false, false));
        preview.setText(Messages.WebQueryWizardPage_Preview);
        preview.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(final SelectionEvent e) {
                webPage = null;
                updatePreview();
            }
        });

        previewTable = new TableViewer(composite1, SWT.BORDER);
        // previewTable = new Table(composite1, SWT.BORDER);
        GridData gridData2 = new GridData(SWT.FILL, SWT.FILL, false, true, 3, 1);
        gridData2.heightHint = 60;

        Table table = previewTable.getTable();
        table.setLayoutData(gridData2);
        table.setLinesVisible(true);
        table.setHeaderVisible(true);

        TableColumn colId = new TableColumn(table, SWT.NONE);
        colId.setWidth(100);
        colId.setText(Messages.WebQueryWizardPage_Id);

        TableColumn colDescription = new TableColumn(table, SWT.NONE);
        colDescription.setWidth(200);
        colDescription.setText(Messages.WebQueryWizardPage_Description);

        TableColumn colStatus = new TableColumn(table, SWT.NONE);
        colStatus.setText(Messages.WebQueryWizardPage_Status);
        colStatus.setWidth(80);

        TableColumn colType = new TableColumn(table, SWT.NONE);
        colType.setText(Messages.WebQueryWizardPage_Type);
        colType.setWidth(80);

        TableColumn colOwner = new TableColumn(table, SWT.NONE);
        colOwner.setText(Messages.WebQueryWizardPage_Owner);
        colOwner.setWidth(120);

        previewTable.setColumnProperties(new String[] { "Id", "Description", "Status", "Type", "Owner" }); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
        previewTable.setContentProvider(new IStructuredContentProvider() {

            public void dispose() {
            }

            public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
            }

            public Object[] getElements(Object inputElement) {
                if (inputElement instanceof Collection<?>) {
                    return ((Collection<?>) inputElement).toArray();
                }
                return new Object[0];
            }
        });

        previewTable.setLabelProvider(new ITableLabelProvider() {

            public String getColumnText(Object element, int columnIndex) {
                TaskMapper task = (TaskMapper) element;
                switch (columnIndex) {
                case 0:
                    return task.getTaskData().getTaskId();
                case 1:
                    return task.getSummary();
                case 2:
                    return task.getCompletionDate() != null ? Messages.WebQueryWizardPage_complete
                            : Messages.WebQueryWizardPage_incomplete;
                case 3:
                    return task.getTaskKind();
                case 4:
                    return task.getOwner();
                }
                return null;
            }

            public Image getColumnImage(Object element, int columnIndex) {
                return null;
            }

            public void addListener(ILabelProviderListener listener) {
            }

            public void dispose() {
            }

            public boolean isLabelProperty(Object element, String property) {
                return false;
            }

            public void removeListener(ILabelProviderListener listener) {
            }
        });

        setControl(composite);

        LinkedHashMap<String, String> vars = new LinkedHashMap<String, String>();
        Map<String, String> params = new LinkedHashMap<String, String>();
        if (getTaskRepository() != null) {
            queryUrlText.setText(
                    addVars(vars, getTaskRepository().getProperty(WebRepositoryConnector.PROPERTY_QUERY_URL)));
            queryPatternText.setText(
                    addVars(vars, getTaskRepository().getProperty(WebRepositoryConnector.PROPERTY_QUERY_REGEXP)));

            oldProperties = getTaskRepository().getProperties();
            params.putAll(oldProperties);
        }
        IRepositoryQuery query = getQuery();
        if (query != null) {
            setTitle(query.getSummary());
            queryUrlText.setText(addVars(vars, query.getAttribute(WebRepositoryConnector.KEY_QUERY_TEMPLATE)));
            queryPatternText.setText(addVars(vars, query.getAttribute(WebRepositoryConnector.KEY_QUERY_PATTERN)));
            params.putAll(WebRepositoryConnector.getQueryParams(query));
        }
        parametersEditor.addParams(params, vars);

        Dialog.applyDialogFont(composite);
    }

    private static String addVars(LinkedHashMap<String, String> vars, String property) {
        if (property == null) {
            return ""; //$NON-NLS-1$
        }
        for (String var : WebRepositoryConnector.getTemplateVariables(property)) {
            vars.put(var, ""); //$NON-NLS-1$
        }
        return property;
    }

    synchronized void updatePreview() {
        if (updatePreviewJob == null) {
            updatePreviewJob = new UpdatePreviewJob(Messages.WebQueryWizardPage_Updating_preview);
            updatePreviewJob.setPriority(Job.DECORATE);
        }
        updatePreviewJob.setParams(queryUrlText.getText(), queryPatternText.getText(),
                parametersEditor.getParameters());
        if (!updatePreviewJob.isActive()) {
            updatePreviewJob.schedule();
        }
    }

    protected void openBrowser() {
        final String url = queryUrlText.getText();
        final Map<String, String> params = parametersEditor.getParameters();

        new Job("Opening Browser") {
            @Override
            protected IStatus run(IProgressMonitor monitor) {
                final String evaluatedUrl = WebRepositoryConnector.evaluateParams(url, params, getTaskRepository());
                try {
                    String webPage = WebRepositoryConnector.fetchResource(evaluatedUrl, params,
                            getTaskRepository());
                    File webPageFile = File.createTempFile("mylyn-web-connector", ".html");
                    webPageFile.deleteOnExit();

                    FileWriter w = new FileWriter(webPageFile);
                    try {
                        w.write(webPage);
                    } finally {
                        w.close();
                    }

                    final String location = webPageFile.toURI().toURL().toString();
                    Display.getDefault().asyncExec(new Runnable() {
                        public void run() {
                            BrowserUtil.openUrl(location, IWorkbenchBrowserSupport.AS_EXTERNAL);
                        }
                    });
                } catch (final Exception e) {
                    Display.getDefault().asyncExec(new Runnable() {
                        public void run() {
                            CommonUiUtil.setMessage(WebQueryWizardPage.this,
                                    new Status(IStatus.ERROR, TasksWebPlugin.ID_PLUGIN,
                                            NLS.bind("Failed to open ''{0}'': {1}", evaluatedUrl, e.getMessage()),
                                            e));
                        }
                    });
                }

                return Status.OK_STATUS;
            }
        }.schedule();
    }

    @Override
    public boolean isPageComplete() {
        return super.isPageComplete();
    }

    void updatePreviewTable(List<TaskMapper> queryHits, MultiStatus queryStatus) {
        previewTable.setInput(queryHits);

        if (queryStatus.isOK()) {
            setMessage(null, IMessageProvider.WARNING);
        } else {
            StringBuffer sb = new StringBuffer();
            for (IStatus status : queryStatus.getChildren()) {
                sb.append(status.getMessage()).append("\n"); //$NON-NLS-1$
            }
            setMessage(sb.toString(), IMessageProvider.WARNING);
        }
    }

    private final class UpdatePreviewJob extends Job {
        private volatile String url;

        private volatile String regexp;

        private volatile Map<String, String> params;

        private volatile boolean active = false;

        private UpdatePreviewJob(String name) {
            super(name);
        }

        public boolean isActive() {
            return active;
        }

        public void setParams(String url, String regexp, Map<String, String> params) {
            this.url = url;
            this.regexp = regexp;
            this.params = params;
        }

        @Override
        protected IStatus run(IProgressMonitor monitor) {
            String currentRegexp = regexp;
            String queryPattern = WebRepositoryConnector.evaluateParams(currentRegexp, params, getTaskRepository());
            String evaluatedUrl = WebRepositoryConnector.evaluateParams(url, params, getTaskRepository());
            String taskPrefix = WebRepositoryConnector.evaluateParams(
                    getTaskRepository().getProperty(WebRepositoryConnector.PROPERTY_TASK_URL), params,
                    getTaskRepository());
            active = true;
            do {
                final MultiStatus queryStatus = new MultiStatus(TasksWebPlugin.ID_PLUGIN, IStatus.OK,
                        Messages.WebQueryWizardPage_Query_result, null);
                final List<TaskMapper> queryHits = new ArrayList<TaskMapper>();
                try {
                    if (webPage == null) {
                        webPage = WebRepositoryConnector.fetchResource(evaluatedUrl, params, getTaskRepository());
                    }

                    TaskDataCollector collector = new TaskDataCollector() {
                        @Override
                        public void accept(TaskData taskData) {
                            queryHits.add(new TaskMapper(taskData));
                        }
                    };
                    IStatus status;
                    if (queryPattern != null && queryPattern.trim().length() > 0) {
                        status = WebRepositoryConnector.performQuery(webPage, queryPattern, taskPrefix, monitor,
                                collector, getTaskRepository());
                    } else {
                        status = WebRepositoryConnector.performRssQuery(webPage, monitor, collector,
                                getTaskRepository());
                    }

                    if (!status.isOK()) {
                        queryStatus.add(status);
                    } else if (queryHits.size() == 0) {
                        queryStatus.add(new Status(IStatus.ERROR, TasksWebPlugin.ID_PLUGIN, 0,
                                Messages.WebQueryWizardPage_No_matching_results_Check_query_regexp, null));
                    }

                } catch (IOException ex) {
                    queryStatus.add(new Status(IStatus.ERROR, TasksWebPlugin.ID_PLUGIN, IStatus.ERROR, //
                            Messages.WebQueryWizardPage_Unable_to_fetch_resource_ + ex.getMessage(), null));
                } catch (Exception ex) {
                    queryStatus.add(new Status(IStatus.ERROR, TasksWebPlugin.ID_PLUGIN, IStatus.ERROR, //
                            Messages.WebQueryWizardPage_Parsing_error_ + ex.getMessage(), null));
                }

                Display.getDefault().asyncExec(new Runnable() {
                    public void run() {
                        updatePreviewTable(queryHits, queryStatus);
                    }
                });
            } while (!currentRegexp.equals(currentRegexp) && !monitor.isCanceled());
            active = false;
            return Status.OK_STATUS;
        }
    }

    @Override
    public void applyTo(IRepositoryQuery query) {
        query.setSummary(getQueryTitle());
        query.setAttribute(WebRepositoryConnector.KEY_QUERY_TEMPLATE, queryUrlText.getText());
        query.setAttribute(WebRepositoryConnector.KEY_QUERY_PATTERN, queryPatternText.getText());
        query.setAttribute(WebRepositoryConnector.KEY_TASK_PREFIX,
                getTaskRepository().getProperty(WebRepositoryConnector.PROPERTY_TASK_URL));
        Map<String, String> params = parametersEditor.getParameters();
        query.setUrl(WebRepositoryConnector.evaluateParams(queryUrlText.getText(), params, getTaskRepository()));
        for (Map.Entry<String, String> entry : params.entrySet()) {
            query.setAttribute(entry.getKey(), entry.getValue());
        }
    }

}