/* * 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 static eu.esdihumboldt.hale.io.haleconnect.HaleConnectService.PERMISSION_CREATE; import static eu.esdihumboldt.hale.io.haleconnect.HaleConnectService.RESOURCE_TRANSFORMATION_PROJECT; import java.io.IOException; import java.io.OutputStream; import java.net.URI; import java.text.MessageFormat; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.preference.FieldEditor; import org.eclipse.jface.preference.StringFieldEditor; import org.eclipse.jface.util.IPropertyChangeListener; import org.eclipse.jface.util.PropertyChangeEvent; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.StackLayout; import org.eclipse.swt.events.MouseAdapter; import org.eclipse.swt.events.MouseEvent; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; 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.Group; import org.eclipse.swt.widgets.Label; import de.fhg.igd.slf4jplus.ALogger; import de.fhg.igd.slf4jplus.ALoggerFactory; import eu.esdihumboldt.hale.common.core.io.Value; import eu.esdihumboldt.hale.common.core.io.project.ProjectInfoService; import eu.esdihumboldt.hale.common.core.io.project.impl.ArchiveProjectWriter; import eu.esdihumboldt.hale.common.core.io.supplier.LocatableOutputSupplier; import eu.esdihumboldt.hale.io.haleconnect.HaleConnectProjectInfo; import eu.esdihumboldt.hale.io.haleconnect.HaleConnectService; import eu.esdihumboldt.hale.io.haleconnect.HaleConnectUrnBuilder; import eu.esdihumboldt.hale.io.haleconnect.Owner; import eu.esdihumboldt.hale.io.haleconnect.OwnerType; import eu.esdihumboldt.hale.io.haleconnect.project.HaleConnectProjectWriter; import eu.esdihumboldt.hale.io.haleconnect.ui.HaleConnectLoginDialog; import eu.esdihumboldt.hale.io.haleconnect.ui.HaleConnectLoginHandler; import eu.esdihumboldt.hale.ui.HaleUI; import eu.esdihumboldt.hale.ui.io.target.AbstractTarget; /** * hale connect export target * * @author Florian Esser */ public class HaleConnectTarget extends AbstractTarget<HaleConnectProjectWriter> { private static final ALogger log = ALoggerFactory.getLogger(HaleConnectTarget.class); private final HaleConnectService haleConnect; private Label loginStatusLabel; private Button loginButton; private Button enableVersioning; private Button publicAccess; private Composite ownershipGroup; private Button ownerUser; private Button ownerOrg; private Button includeWebResources; private Button excludeData; private Group updateOrNewGroup; private Button newProject; private Button updateProject; private Composite controlsStack; private StackLayout controlsStackLayout; private Composite newProjectControls; private Composite updateProjectControls; private StringFieldEditor projectName; private Button selectProjectButton; private boolean createNewProject; private HaleConnectProjectConfig targetProject; /** * Default constructor */ public HaleConnectTarget() { haleConnect = HaleUI.getServiceProvider().getService(HaleConnectService.class); } @Override public void createControls(Composite parent) { getPage().setDescription("Please select a destination file for the export"); parent.setLayout(new GridLayout(3, false)); /* * Login status label */ loginStatusLabel = new Label(parent, SWT.NONE); loginStatusLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1)); loginButton = new Button(parent, SWT.PUSH); loginButton.setText("Login"); loginButton.addSelectionListener(new SelectionAdapter() { /** * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent) */ @Override public void widgetSelected(SelectionEvent e) { HaleConnectLoginDialog loginDialog = HaleConnectLoginHandler .createLoginDialog(Display.getCurrent().getActiveShell()); if (loginDialog.open() == Dialog.OK) { HaleConnectLoginHandler.performLogin(loginDialog); updateState(); } } }); updateOrNewGroup = new Group(parent, SWT.NONE); updateOrNewGroup.setText("Please choose whether you would like to..."); updateOrNewGroup.setLayout(new GridLayout(3, true)); updateOrNewGroup.setLayoutData(new GridData(SWT.LEAD, SWT.LEAD, true, false, 3, 1)); newProject = new Button(updateOrNewGroup, SWT.RADIO); newProject.setText("create a new project on hale connect"); newProject.setSelection(true); newProject.addSelectionListener(new SelectionAdapter() { /** * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent) */ @Override public void widgetSelected(SelectionEvent e) { updateState(); } }); updateProject = new Button(updateOrNewGroup, SWT.RADIO); updateProject.setText("update an existing project"); updateProject.addSelectionListener(new SelectionAdapter() { /** * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent) */ @Override public void widgetSelected(SelectionEvent e) { updateState(); } }); controlsStackLayout = new StackLayout(); controlsStack = new Composite(parent, SWT.NONE); controlsStack.setLayout(controlsStackLayout); newProjectControls = new Composite(controlsStack, SWT.NONE); newProjectControls.setLayout(new GridLayout(3, true)); GridData grid = new GridData(SWT.FILL, SWT.FILL, true, true, 3, 1); newProjectControls.setLayoutData(grid); ownershipGroup = new Composite(newProjectControls, SWT.NONE); ownershipGroup.setLayout(new GridLayout(3, false)); ownershipGroup.setLayoutData(new GridData(SWT.LEAD, SWT.LEAD, false, false, 3, 1)); Label ownerLabel = new Label(ownershipGroup, SWT.NONE); ownerLabel.setText("Who should own the uploaded project?"); ownerUser = new Button(ownershipGroup, SWT.RADIO); ownerUser.setText("You"); ownerOrg = new Button(ownershipGroup, SWT.RADIO); ownerOrg.setText("Your organisation"); enableVersioning = new Button(newProjectControls, SWT.CHECK); enableVersioning.setText("Enable versioning?"); enableVersioning.setLayoutData(new GridData(SWT.LEAD, SWT.LEAD, true, false, 3, 1)); publicAccess = new Button(newProjectControls, SWT.CHECK); publicAccess.setText("Allow public access?"); publicAccess.setLayoutData(new GridData(SWT.LEAD, SWT.LEAD, true, false, 3, 1)); includeWebResources = new Button(parent, SWT.CHECK); includeWebResources.setText("Include web resources?"); includeWebResources.setLayoutData(new GridData(SWT.LEAD, SWT.LEAD, true, false, 3, 1)); excludeData = new Button(parent, SWT.CHECK); excludeData.setText("Exclude source data?"); excludeData.setLayoutData(new GridData(SWT.LEAD, SWT.LEAD, true, false, 3, 1)); excludeData.setSelection(true); updateProjectControls = new Composite(controlsStack, SWT.NONE); updateProjectControls.setVisible(false); updateProjectControls.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 3, 1)); /* * Project name text field */ projectName = new StringFieldEditor("project", "Project to update", updateProjectControls) { // the following methods are overridden so the button // may appear on the same line @Override public int getNumberOfControls() { return super.getNumberOfControls() + 1; } @Override protected void doFillIntoGrid(Composite parent, int numColumns) { super.doFillIntoGrid(parent, numColumns - 1); } }; projectName.setEmptyStringAllowed(false); projectName.setErrorMessage("Please select a project before continuing."); projectName.setPage(getPage()); projectName.getTextControl(updateProjectControls).setEditable(false); projectName.getTextControl(updateProjectControls).addMouseListener(new MouseAdapter() { @Override public void mouseDown(MouseEvent e) { selectProject(); } }); projectName.setPropertyChangeListener(new IPropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent event) { if (event.getProperty().equals(FieldEditor.IS_VALID)) { getPage().setMessage(null); updateState(); } else if (event.getProperty().equals(FieldEditor.VALUE)) { getPage().setMessage(null); updateState(); } } }); /* * Select project button */ selectProjectButton = new Button(updateProjectControls, SWT.PUSH); selectProjectButton.setText("Select"); selectProjectButton.setToolTipText("Select project"); selectProjectButton.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false, 1, 1)); selectProjectButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { selectProject(); } }); ProjectInfoService pis = HaleUI.getServiceProvider().getService(ProjectInfoService.class); URI loadLocation = pis.getLoadLocation(); if (loadLocation != null) { // If project was loaded from hale connect, prefill project name try { if (HaleConnectUrnBuilder.isValidProjectUrn(loadLocation)) { String projectId = HaleConnectUrnBuilder.extractProjectId(loadLocation); Owner owner = HaleConnectUrnBuilder.extractProjectOwner(loadLocation); HaleConnectProjectInfo projectInfo = haleConnect.getProject(owner, projectId); if (projectInfo != null) { targetProject = new HaleConnectProjectConfig(); targetProject.setOwner(owner); targetProject.setProjectId(projectId); targetProject.setProjectName(projectInfo.getName()); newProject.setSelection(false); updateProject.setSelection(true); projectName.setStringValue(projectInfo.getName()); } } } catch (Throwable t) { // Non-fatal log.warn(MessageFormat.format("Unable to prefill target project: {0}", t.getMessage()), t); } } updateState(); } /** * Update the page state. */ protected void updateState() { updateLoginStatus(); setValid(haleConnect.isLoggedIn() && (ownerUser.isEnabled() || ownerOrg.isEnabled()) && (newProject.getSelection() || targetProject != null)); if (newProject.getSelection()) { controlsStackLayout.topControl = newProjectControls; createNewProject = true; } else { controlsStackLayout.topControl = updateProjectControls; createNewProject = false; } controlsStack.layout(); } @Override public void onShowPage(boolean firstShow) { super.onShowPage(firstShow); updateState(); } @Override public boolean updateConfiguration(HaleConnectProjectWriter provider) { provider.setParameter(HaleConnectProjectWriter.ENABLE_VERSIONING, Value.of(enableVersioning.getSelection())); provider.setParameter(HaleConnectProjectWriter.SHARING_PUBLIC, Value.of(publicAccess.getSelection())); Value ownerValue = Value.of(ownerUser.getSelection() ? OwnerType.USER.getJsonValue() : OwnerType.ORGANISATION.getJsonValue()); provider.setParameter(HaleConnectProjectWriter.OWNER_TYPE, ownerValue); provider.setParameter(ArchiveProjectWriter.EXLUDE_DATA_FILES, Value.of(excludeData.getSelection())); provider.setParameter(ArchiveProjectWriter.INCLUDE_WEB_RESOURCES, Value.of(includeWebResources.getSelection())); provider.setTarget(new LocatableOutputSupplier<OutputStream>() { @Override public OutputStream getOutput() throws IOException { return null; } @Override public URI getLocation() { if (createNewProject) { // Returning null will advise HaleConnectProjectWriter to // create a new hale connect transformation project return null; } else if (targetProject != null) { return HaleConnectUrnBuilder.buildProjectUrn(targetProject.getOwner(), targetProject.getProjectId()); } else { throw new IllegalStateException("No target project selected."); } } }); return true; } private void updateLoginStatus() { HaleConnectService hcs = HaleUI.getServiceProvider().getService(HaleConnectService.class); boolean loggedIn = hcs.isLoggedIn(); loginButton.setEnabled(!loggedIn); ownershipGroup.setEnabled(loggedIn); enableVersioning.setEnabled(loggedIn); publicAccess.setEnabled(loggedIn); ownerUser.setEnabled(loggedIn); includeWebResources.setEnabled(loggedIn); excludeData.setEnabled(loggedIn); selectProjectButton.setEnabled(loggedIn); newProject.setEnabled(loggedIn); updateProject.setEnabled(loggedIn); if (loggedIn) { loginStatusLabel .setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_DARK_GREEN)); loginStatusLabel.setText( MessageFormat.format("Logged in as {0}", hcs.getSession().getUsername())); boolean orgAllowed; if (hcs.getSession().getOrganisationIds().isEmpty()) { orgAllowed = false; } else { try { orgAllowed = hcs.testUserPermission(RESOURCE_TRANSFORMATION_PROJECT, hcs.getSession().getOrganisationIds().iterator().next(), PERMISSION_CREATE); } catch (Throwable t) { log.userError( "A problem occurred while contacting hale connect. Functionality may be limited.", t); orgAllowed = false; } } ownerOrg.setEnabled(orgAllowed); ownerOrg.setSelection(orgAllowed); boolean userAllowed; try { userAllowed = hcs.testUserPermission(RESOURCE_TRANSFORMATION_PROJECT, OwnerType.USER.getJsonValue(), PERMISSION_CREATE); } catch (Throwable t) { log.userError( "A problem occurred while contacting hale connect. Functionality may be limited.", t); userAllowed = false; } ownerUser.setEnabled(userAllowed); ownerUser.setSelection(userAllowed); if (!userAllowed && !orgAllowed) { loginStatusLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1)); loginStatusLabel .setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_DARK_RED)); loginStatusLabel.setText( "You do not have sufficient permissions to upload transformation projects to hale connect."); } } else { loginStatusLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1)); loginStatusLabel.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_DARK_RED)); loginStatusLabel.setText( "You are not logged in to hale connect. Please login before sharing a project."); ownerOrg.setEnabled(false); } } private void selectProject() { targetProject = ChooseHaleConnectProjectWizard.openSelectProject(); if (targetProject != null) { projectName.setStringValue(targetProject.getProjectName()); } else { projectName.setStringValue(""); } } }