/* * Copyright (c) 2017 wetransform GmbH * * All rights reserved. This program and the accompanying materials are made * available under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of the License, * or (at your option) any later version. * * You should have received a copy of the GNU Lesser General Public License * along with this distribution. If not, see <http://www.gnu.org/licenses/>. * * Contributors: * wetransform GmbH <http://www.wetransform.to> */ package eu.esdihumboldt.hale.io.haleconnect.ui.projects; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.apache.commons.lang.StringUtils; import org.eclipse.jface.layout.GridDataFactory; import org.eclipse.jface.layout.TableColumnLayout; import org.eclipse.jface.viewers.ArrayContentProvider; import org.eclipse.jface.viewers.ColumnLabelProvider; import org.eclipse.jface.viewers.ColumnWeightData; import org.eclipse.jface.viewers.ComboViewer; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredContentProvider; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.viewers.TableViewerColumn; import org.eclipse.jface.viewers.Viewer; 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.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.Table; import org.eclipse.swt.widgets.Text; import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import de.fhg.igd.slf4jplus.ALogger; import de.fhg.igd.slf4jplus.ALoggerFactory; import eu.esdihumboldt.hale.io.haleconnect.HaleConnectException; import eu.esdihumboldt.hale.io.haleconnect.HaleConnectProjectInfo; import eu.esdihumboldt.hale.io.haleconnect.HaleConnectService; import eu.esdihumboldt.hale.io.haleconnect.HaleConnectServices; import eu.esdihumboldt.hale.io.haleconnect.HaleConnectUserInfo; import eu.esdihumboldt.hale.io.haleconnect.Owner; import eu.esdihumboldt.hale.io.haleconnect.OwnerType; import eu.esdihumboldt.hale.io.haleconnect.ui.preferences.PreferenceInitializer; import eu.esdihumboldt.hale.ui.HaleUI; import eu.esdihumboldt.hale.ui.util.wizard.ConfigurationWizard; import eu.esdihumboldt.hale.ui.util.wizard.ConfigurationWizardPage; /** * Wizard page for listing and choosing one of the available hale connect * projects. * * @author Florian Esser */ public class ChooseHaleConnectProjectWizardPage extends ConfigurationWizardPage<HaleConnectProjectConfig> { private static final ALogger log = ALoggerFactory .getLogger(ChooseHaleConnectProjectWizardPage.class); private static final OwnerFilterEntry NULL_FILTER = new OwnerFilterEntry(null, "All projects"); private final HaleConnectService haleConnect; private Text keywordFilter; private ComboViewer ownerFilter; private TableViewer projects; /** * Create the wizard page * * @param wizard Wizard this page is associated with * */ public ChooseHaleConnectProjectWizardPage( ConfigurationWizard<HaleConnectProjectConfig> wizard) { super(wizard, "hcLoadProject"); setTitle("Load project"); setMessage("Please select a project"); haleConnect = HaleUI.getServiceProvider().getService(HaleConnectService.class); } /** * @see eu.esdihumboldt.hale.ui.util.wizard.ConfigurationWizardPage#updateConfiguration(java.lang.Object) */ @Override public boolean updateConfiguration(HaleConnectProjectConfig configuration) { if (projects.getSelection().isEmpty()) { return false; } StructuredSelection selection = (StructuredSelection) projects.getSelection(); if (!(selection.getFirstElement() instanceof HaleConnectProjectInfo)) { return false; } HaleConnectProjectInfo pi = (HaleConnectProjectInfo) selection.getFirstElement(); configuration.setProjectId(pi.getId()); configuration.setProjectName(pi.getName()); configuration.setOwner(pi.getOwner()); return true; } /** * @see eu.esdihumboldt.hale.ui.util.wizard.ConfigurationWizardPage#createContent(org.eclipse.swt.widgets.Composite) */ @Override protected void createContent(Composite parent) { Composite page = new Composite(parent, SWT.NONE); page.setLayout(new GridLayout(4, false)); keywordFilter = new Text(page, SWT.SEARCH | SWT.ICON_SEARCH | SWT.BORDER | SWT.ICON_CANCEL); keywordFilter.setMessage("Enter search text here..."); GridDataFactory.fillDefaults().span(2, 1).grab(true, false).applyTo(keywordFilter); ownerFilter = new ComboViewer(page); GridDataFactory.fillDefaults().grab(false, false).applyTo(ownerFilter.getControl()); ownerFilter.setContentProvider(new IStructuredContentProvider() { @Override public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { new Object(); } @Override public void dispose() { // } @Override public Object[] getElements(Object inputElement) { if (inputElement instanceof List<?>) { List<?> elements = (List<?>) inputElement; return elements.toArray(); } else if (inputElement instanceof Object[]) { return (Object[]) inputElement; } return new Object[] {}; } }); ownerFilter.setLabelProvider(new LabelProvider() { @Override public String getText(Object element) { if (element instanceof OwnerFilterEntry) { return ((OwnerFilterEntry) element).getLabel(); } return super.getText(element); } }); List<OwnerFilterEntry> availableFilters = new ArrayList<>(); availableFilters.add(NULL_FILTER); availableFilters .add(new OwnerFilterEntry( new Owner[] { new Owner(OwnerType.USER, haleConnect.getSession().getUserId()) }, "My projects")); List<Owner> orgs = new ArrayList<>(); for (String orgId : haleConnect.getSession().getOrganisationIds()) { orgs.add(new Owner(OwnerType.ORGANISATION, orgId)); } if (!orgs.isEmpty()) { availableFilters.add(new OwnerFilterEntry(orgs.toArray(new Owner[] {}), "My organisation's projects")); } ownerFilter.setInput(availableFilters); ownerFilter.setSelection(new StructuredSelection(NULL_FILTER)); Composite tableComposite = new Composite(page, SWT.NONE); TableColumnLayout columnLayout = new TableColumnLayout(); tableComposite.setLayout(columnLayout); projects = new TableViewer(tableComposite, SWT.V_SCROLL | SWT.BORDER | SWT.H_SCROLL | SWT.SINGLE | SWT.FULL_SELECTION); projects.addSelectionChangedListener(new ISelectionChangedListener() { @Override public void selectionChanged(SelectionChangedEvent event) { update(); } }); TableViewerColumn nameColumn = new TableViewerColumn(projects, SWT.LEAD); nameColumn.getColumn().setText("Project name"); nameColumn.setLabelProvider(new ColumnLabelProvider() { /** * @see org.eclipse.jface.viewers.ColumnLabelProvider#getText(java.lang.Object) */ @Override public String getText(Object element) { if (element instanceof HaleConnectProjectInfo) { return ((HaleConnectProjectInfo) element).getName(); } return element.toString(); } }); columnLayout.setColumnData(nameColumn.getColumn(), new ColumnWeightData(45, 200, true)); TableViewerColumn authorColumn = new TableViewerColumn(projects, SWT.LEAD); authorColumn.getColumn().setText("Author"); authorColumn.setLabelProvider(new ColumnLabelProvider() { /** * @see org.eclipse.jface.viewers.ColumnLabelProvider#getText(java.lang.Object) */ @Override public String getText(Object element) { if (element instanceof HaleConnectProjectInfo) { return ((HaleConnectProjectInfo) element).getAuthor(); } return element.toString(); } }); columnLayout.setColumnData(authorColumn.getColumn(), new ColumnWeightData(20, 50, true)); TableViewerColumn ownerColumn = new TableViewerColumn(projects, SWT.LEAD); ownerColumn.getColumn().setText("Owner"); ownerColumn.setLabelProvider(new ColumnLabelProvider() { /** * @see org.eclipse.jface.viewers.ColumnLabelProvider#getText(java.lang.Object) */ @Override public String getText(Object element) { if (element instanceof HaleConnectProjectInfo) { Owner owner = ((HaleConnectProjectInfo) element).getOwner(); if (owner.isUser()) { try { HaleConnectUserInfo user = haleConnect.getUserInfo(owner.getId()); if (!StringUtils.isEmpty(user.getFullName())) { return user.getFullName(); } else if (!StringUtils.isEmpty(user.getScreenName())) { return user.getScreenName(); } else { return MessageFormat.format("<user {0}>", user.getUserId()); } } catch (HaleConnectException e) { log.error(e.getMessage(), e); return MessageFormat.format("<user {0}>", owner.getId()); } } else if (owner.isOrganisation()) { try { return haleConnect.getOrganisationInfo(owner.getId()).getName(); } catch (HaleConnectException e) { log.error(e.getMessage(), e); return MessageFormat.format("<organisation {0}>", owner.getId()); } } else { return "<unknown owner type> ID: " + owner.getId(); } } return element.toString(); } }); columnLayout.setColumnData(ownerColumn.getColumn(), new ColumnWeightData(35, 100, true)); final Table projectsTable = projects.getTable(); projectsTable.setHeaderVisible(true); projectsTable.setLinesVisible(true); tableComposite .setLayoutData(GridDataFactory.fillDefaults().span(4, 1).grab(true, true).create()); projects.setContentProvider(ArrayContentProvider.getInstance()); populateProjects(projectsTable); final ProjectFilter projectFilter = new ProjectFilter(projects); projects.addFilter(projectFilter); ownerFilter.addSelectionChangedListener(new ISelectionChangedListener() { @Override public void selectionChanged(SelectionChangedEvent event) { if (event.getSelection() instanceof StructuredSelection) { StructuredSelection selection = (StructuredSelection) event.getSelection(); if (selection.getFirstElement() instanceof OwnerFilterEntry) { OwnerFilterEntry selectedFilter = (OwnerFilterEntry) selection .getFirstElement(); if (selectedFilter.equals(NULL_FILTER)) { projectFilter.clearOwnerFilter(); } else { projectFilter.filterByOwners(Arrays.asList(selectedFilter.getOwner())); } } } } }); keywordFilter.addModifyListener(new ModifyListener() { @Override public void modifyText(ModifyEvent e) { projectFilter.setSearchText(keywordFilter.getText()); } }); final Button refresh = new Button(page, SWT.FLAT); refresh.setText("Refresh"); GridDataFactory.fillDefaults().span(1, 1).grab(false, false).applyTo(refresh); refresh.addSelectionListener(new SelectionAdapter() { /** * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent) */ @Override public void widgetSelected(SelectionEvent e) { populateProjects(projectsTable); } }); ownerFilter.getControl().setFocus(); setControl(page); update(); } private void populateProjects(final Table projectsTable) { projects.setInput(Arrays.asList("Loading...")); projects.getTable().setEnabled(false); ListenableFuture<List<HaleConnectProjectInfo>> projectsFuture; try { projectsFuture = haleConnect.getProjectsAsync(); Futures.addCallback(projectsFuture, new FutureCallback<List<HaleConnectProjectInfo>>() { @Override public void onSuccess(List<HaleConnectProjectInfo> result) { Display.getDefault().syncExec(new Runnable() { @Override public void run() { projects.setInput(result.toArray()); projectsTable.setEnabled(true); } }); } @Override public void onFailure(Throwable t) { String configuredBasePath = haleConnect.getBasePathManager() .getBasePath(HaleConnectServices.PROJECT_STORE); if (configuredBasePath .equals(PreferenceInitializer.HALE_CONNECT_BASEPATH_PROJECTS_DEFAULT)) { log.userError( "Unable to connect to hale connect, please check your network connection.", t); } else { // Inform user that the default base path was modified log.userError( MessageFormat.format( "Unable to connect to hale connect, please check your network connection.\n\nNote that the configured project store base path ({0}) differs from the default value ({1}), which may also be the cause of this error.", configuredBasePath, PreferenceInitializer.HALE_CONNECT_BASEPATH_PROJECTS_DEFAULT), t); } Display.getDefault().syncExec(new Runnable() { @Override public void run() { projects.setInput( Arrays.asList("Error retrieving projects from hale connect.")); } }); } }); } catch (HaleConnectException e1) { log.error(e1.getMessage(), e1); projects.setInput(Arrays.asList("Error retrieving projects from hale connect.")); } } private void update() { StructuredSelection selection = (StructuredSelection) projects.getSelection(); if (selection.getFirstElement() instanceof HaleConnectProjectInfo) { setPageComplete(true); } else { setPageComplete(false); } } }