/* * Copyright (C) 2006-2016 DLR, Germany * * All rights reserved * * http://www.rcenvironment.de/ */ package de.rcenvironment.components.cpacs.writer.gui.runtime; import java.io.File; import java.io.IOException; import java.io.Serializable; import java.nio.charset.Charset; import java.util.List; import java.util.Map; import org.apache.commons.io.FileUtils; import org.apache.commons.logging.Log; import org.eclipse.core.runtime.Platform; import org.eclipse.swt.SWT; 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.Composite; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.forms.widgets.FormToolkit; import org.eclipse.ui.forms.widgets.ScrolledForm; import org.eclipse.ui.part.ViewPart; import de.rcenvironment.components.cpacs.writer.common.CpacsWriterComponentConstants; import de.rcenvironment.core.communication.common.CommunicationException; import de.rcenvironment.core.component.execution.api.ComponentExecutionInformation; import de.rcenvironment.core.datamanagement.DataManagementService; import de.rcenvironment.core.gui.workflow.view.ComponentRuntimeView; import de.rcenvironment.core.notification.Notification; import de.rcenvironment.core.notification.SimpleNotificationService; import de.rcenvironment.core.utils.common.TempFileService; import de.rcenvironment.core.utils.common.TempFileServiceAccess; import de.rcenvironment.core.utils.common.rpc.RemoteOperationException; import de.rcenvironment.core.utils.incubator.ServiceRegistry; import de.rcenvironment.core.utils.incubator.ServiceRegistryAccess; /** * Abstract super class of all runtime views in this bundle. * * @author Arne Bachmann * @author Markus Kunde * @author Sascha Zur */ public abstract class AbstractCpacsRuntimeView extends ViewPart implements ComponentRuntimeView { protected static final TempFileService TEMP_MANAGER = TempFileServiceAccess.getInstance(); private static final int MINIMUM_HEIGHT_OF_FILE_CONTENT_TEXT = 300; private static File managedTempDir = null; /** * Component information of this component view. */ protected ComponentExecutionInformation componentInstanceDescriptor = null; /** * Notification service to get notified on new history objects. */ protected SimpleNotificationService notificationService = new SimpleNotificationService(); /** * The simplified version for DM reference accesses. */ protected DataManagementService dataManagementService; /** * The form for the widgets. */ protected ScrolledForm form = null; private Text fileContentText; private Log log; private File cpacsFile = null; private Button mappedB; @Deprecated public AbstractCpacsRuntimeView() { super(); } @Override public void initializeData(ComponentExecutionInformation componentExecutionInformation) { componentInstanceDescriptor = componentExecutionInformation; if (managedTempDir == null) { try { managedTempDir = TEMP_MANAGER.createManagedTempDir(); } catch (IOException e) { throw new IllegalStateException(e); } } ServiceRegistryAccess serviceRegistryAccess = ServiceRegistry.createAccessFor(this); dataManagementService = serviceRegistryAccess.getService(DataManagementService.class); final String tempFileReference = getFileReference(); if (tempFileReference != null) { try { cpacsFile = new File(managedTempDir, tempFileReference + ".xml"); if (!cpacsFile.exists()) { // As the file is disposed when the view is disposed, the file will never exist at that point and must be fetched // anew. As the view won't be re-opened very often and won't be executed an a remote node very often, this behavior // is acceptable for now. Will be changed if temp file clean up on RCE shutdown is improved -seid_do dataManagementService.copyReferenceToLocalFile( tempFileReference, cpacsFile, componentInstanceDescriptor.getDefaultStorageNodeId()); } } catch (final IOException | CommunicationException e) { log.error("Fetching CPACS file failed", e); } } } @Override public void initializeView() { if (mappedB != null) { // This button only exists on Windows mappedB.setEnabled(cpacsFile != null); } if (cpacsFile != null && cpacsFile.exists()) { try { fileContentText.setText(FileUtils.readFileToString(cpacsFile, Charset.defaultCharset())); } catch (IOException e) { log.error(e); } } else { fileContentText.setText(""); } } /** * To be used by inheriting classes. * * @param parent The parent frame * @return null or an error */ protected void createPartControl(final Composite parent, final Log logger) { final FormToolkit tk = new FormToolkit(parent.getDisplay()); // factory to create fancy form this.log = logger; // controls and layout form = tk.createScrolledForm(parent); form.getBody().setLayout(new GridLayout()); if (Platform.OS_WIN32.equals(Platform.getOS())) { final Composite main = tk.createComposite(form.getBody()); main.setLayout(new FillLayout(SWT.HORIZONTAL)); mappedB = tk.createButton(main, "Show in TiGL Viewer", SWT.PUSH); mappedB.setEnabled(false); mappedB.addListener(SWT.Selection, new Listener() { @Override public void handleEvent(final Event event) { if (cpacsFile != null) { performShowAction(cpacsFile); } } }); } GridData gridData = new GridData(GridData.FILL_BOTH | GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL); gridData.heightHint = MINIMUM_HEIGHT_OF_FILE_CONTENT_TEXT; fileContentText = tk.createText(form.getBody(), "", SWT.V_SCROLL | SWT.H_SCROLL); fileContentText.setEditable(false); fileContentText.setLayoutData(gridData); } /** * This needs to be implemented by the specific view/editor. * * @param file The file to show */ protected abstract void performShowAction(final File file); /** * Check if there is a recent history entry notification. This is needed to show the last version of the incoming + mapped CPACS * document. * * @return The object or null if unavailable */ private String getFileReference() { Map<String, List<Notification>> all; try { all = notificationService.getNotifications(componentInstanceDescriptor.getExecutionIdentifier() + CpacsWriterComponentConstants.RUNTIME_CPACS_UUIDS, componentInstanceDescriptor.getNodeId()); if (all.size() >= 1) { final List<Notification> notifications = all.values().iterator().next(); // get list of // notifications // for first (and // only) id in map if (notifications.size() < 1) { return null; // no notification in queue } final Serializable object = notifications.get(0).getBody(); if (object instanceof String) { return (String) object; } } } catch (RemoteOperationException e) { log.error("Getting CPACS file reference failed."); } return null; } @Override public void dispose() { super.dispose(); if (cpacsFile != null) { try { TEMP_MANAGER.disposeManagedTempDirOrFile(cpacsFile); } catch (IOException e) { log.error("Deleting CPACS file in temp directory failed", e); } } } }