Java tutorial
/******************************************************************************* * 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()); } } }