/* * Copyright (C) 2006-2016 DLR, Germany * * All rights reserved * * http://www.rcenvironment.de/ */ package de.rcenvironment.core.gui.datamanagement.commons; import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.nio.file.StandardCopyOption; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.eclipse.core.filesystem.EFS; import org.eclipse.core.filesystem.IFileStore; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.swt.widgets.Display; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchListener; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.PartInitException; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.ide.FileStoreEditorInput; import de.rcenvironment.core.authorization.AuthorizationException; import de.rcenvironment.core.communication.common.CommunicationException; import de.rcenvironment.core.communication.common.InstanceNodeSessionId; import de.rcenvironment.core.communication.common.ResolvableNodeId; import de.rcenvironment.core.datamanagement.DataManagementService; import de.rcenvironment.core.gui.datamanagement.browser.Activator; import de.rcenvironment.core.gui.utils.common.EditorsHelper; import de.rcenvironment.core.utils.common.StringUtils; import de.rcenvironment.core.utils.incubator.ServiceRegistry; /** * Utilities for data management tasks in the RCP workbench environment. * * TODO review authors list; may be incomplete * * @author Robert Mischke * @author Doreen Seider */ public final class DataManagementWorkbenchUtils { private static final DataManagementWorkbenchUtils INSTANCE = new DataManagementWorkbenchUtils(); private final DataManagementService dataManagementService; private final Log log = LogFactory.getLog(DataManagementWorkbenchUtils.class); private DataManagementWorkbenchUtils() { dataManagementService = ServiceRegistry.createAccessFor(this).getService(DataManagementService.class); } public static DataManagementWorkbenchUtils getInstance() { return INSTANCE; } public DataManagementService getDataManagementService() { return dataManagementService; } // FIXME code review; purpose in this utility class? /** * Javadoc. * * @param dataReferenceId the data management reference * @param fileReferencePath the reference to the temp file * @param filename the filename for the given data * @throws AuthorizationException : * @throws IOException Exception * @param rceNodeIdentifier {@link InstanceNodeSessionId} of the RCE node, which store the file to open */ public void saveReferenceToFile(final String dataReferenceId, final String fileReferencePath, final String filename, final ResolvableNodeId rceNodeIdentifier) throws AuthorizationException, IOException { final File file = new File(filename); if (dataReferenceId != null && fileReferencePath == null) { try { dataManagementService.copyReferenceToLocalFile(dataReferenceId, file, rceNodeIdentifier); } catch (CommunicationException e) { throw new RuntimeException(StringUtils.format("Failed to copy data reference from remote node @%s to local file: ", rceNodeIdentifier) + e.getMessage(), e); } } else if (dataReferenceId == null && fileReferencePath != null) { File tempFile = new File(fileReferencePath); Files.copy(tempFile.toPath(), file.toPath(), StandardCopyOption.COPY_ATTRIBUTES); } else if (dataReferenceId != null && fileReferencePath != null) { log.debug("When saving file both data reference ID and file reference path are set. Only one of these should be set."); } else if (dataReferenceId == null && fileReferencePath == null) { log.debug("When saving file neither data reference ID nor file reference path are set. One of these should be set."); } } /** * Tries to open a data management reference in a read-only workbench text editor. * * @param dataReferenceId the data management reference * @param fileReferencePath the reference to the temp file * @param filename the filename to use for the given data * @param rceNodeIdentifier {@link InstanceNodeSessionId} of the RCE node, which store the file to open * @param inTiglViewer true if CPACS File should be opened in TiGL Viewer */ public void tryOpenDataReferenceInReadonlyEditor(final String dataReferenceId, final String fileReferencePath, final String filename, final ResolvableNodeId rceNodeIdentifier, final boolean inTiglViewer) { if (dataReferenceId != null && fileReferencePath == null) { // open = copy to local temporary file + open in editor final Job openJob = new Job("Loading data") { @Override protected IStatus run(IProgressMonitor monitor) { File tempFile = null; try { // acquire local temporary file with the associated filename File tempDir = new File(Activator.getInstance().getBundleSpecificTempDir(), dataReferenceId); tempDir.mkdir(); if (!tempDir.mkdir() && !tempDir.exists()) { log.error("Temp directory could not be created or did already exist as file: " + tempDir); return Status.OK_STATUS; } tempFile = new File(tempDir, filename); if (!(tempDir.exists() && tempDir.list().length == 1 && tempDir.list()[0].equals(filename))) { // copy data reference content to local temporary file dataManagementService.copyReferenceToLocalFile(dataReferenceId, tempFile, rceNodeIdentifier); } if (inTiglViewer) { openInTigl(tempFile); } else { openInEditor(tempFile); } } catch (AuthorizationException e) { log.error("Failed to copy datamanagement reference to local file.", e); } catch (IOException e) { log.error("Failed to copy datamanagement reference to local file.", e); } catch (CommunicationException e) { throw new RuntimeException(StringUtils.format( "Failed to copy data reference from remote node @%s to local file: ", rceNodeIdentifier) + e.getMessage(), e); } return Status.OK_STATUS; } }; openJob.setUser(true); openJob.schedule(); } else if (dataReferenceId == null && fileReferencePath != null) { // otherwise handle it as a file directly // open = open in editor directly final Job openJob = new Job("Loading data") { @Override protected IStatus run(IProgressMonitor monitor) { if (inTiglViewer) { openInTigl(new File(fileReferencePath)); } else { openInEditor(new File(fileReferencePath)); } return Status.OK_STATUS; } }; openJob.setUser(true); openJob.schedule(); } else if (dataReferenceId != null && fileReferencePath != null) { MessageDialog.openInformation(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), "Open in Editor", "Failed to open data in editor. Refresh the workflow entry and try again."); log.error("When opening in editor both data reference ID and file reference path are set. Only one of these should be set."); } else if (dataReferenceId == null && fileReferencePath == null) { MessageDialog.openInformation(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), "Open in Editor", "Failed to open data in editor. Refresh the workflow entry and try again."); log.warn("When opening in editor neither data reference ID nor file reference path are set. One of these should be set."); } } private void openInEditor(final File tempFile) { // best-effort try to make the file read-only; the actual outcome is ignored tempFile.setWritable(false); // open in editor Display.getDefault().syncExec(new Runnable() { @Override public void run() { try { String fileName = tempFile.getName(); String fileExtension = EditorsHelper.getExtension(fileName); if (fileExtension.equals("wf")){ final IFileStore fileStore = EFS.getLocalFileSystem().getStore(new Path(tempFile.getAbsolutePath())); final IEditorInput editorInput = new FileStoreEditorInput(fileStore); final IEditorPart editor = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage() .openEditor(editorInput, "de.rcenvironment.rce.gui.workflow.editor.ReadOnlyWorkflowEditor"); if (editor != null) { // if internal editor PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage() .showView("org.eclipse.ui.views.PropertySheet"); // close editor on RCE shutdown as the file-property relation is gone after RCE is started again PlatformUI.getWorkbench().addWorkbenchListener(new IWorkbenchListener() { @Override public boolean preShutdown(IWorkbench workbench, boolean arg1) { editor.getSite().getPage().closeEditor(editor, false); return true; } @Override public void postShutdown(IWorkbench workbench) {} }); } } else { EditorsHelper.openExternalFileInEditor(tempFile); } } catch (final PartInitException e) { log.error("Failed to open datamanagement reference copied to local file in an editor.", e); } } }); } private void openInTigl(final File tempFile) { tempFile.setWritable(false); // open in TiGL Display.getDefault().syncExec(new Runnable() { @Override public void run() { try { String secondId = null; try { secondId = tempFile.getCanonicalPath(); secondId = secondId.replaceAll(":", "&"); PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage() .showView("de.rcenvironment.core.gui.tiglviewer.views.TIGLViewer", secondId, IWorkbenchPage.VIEW_ACTIVATE); } catch (IOException e) { log.error(e); } } catch (final PartInitException e) { log.error(e); log.error("Failed to open datamanagement reference copied to local file in the TiGL.", e); } } }); } }