| /** |
| ******************************************************************************** |
| * Copyright (c) 2021-2022 Robert Bosch GmbH and others. |
| * |
| * This program and the accompanying materials are made |
| * available under the terms of the Eclipse Public License 2.0 |
| * which is available at https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * Robert Bosch GmbH - initial API and implementation |
| ******************************************************************************** |
| */ |
| |
| package org.eclipse.app4mc.amalthea.model.editor.handler; |
| |
| import java.io.File; |
| import java.io.FileInputStream; |
| import java.io.FileOutputStream; |
| import java.io.IOException; |
| import java.nio.file.Files; |
| import java.util.zip.ZipEntry; |
| import java.util.zip.ZipOutputStream; |
| |
| import javax.inject.Named; |
| |
| import org.eclipse.app4mc.amalthea.model.editor.container.AmaltheaModelContainer; |
| import org.eclipse.app4mc.amalthea.model.editor.util.AmaltheaEditorUtil; |
| import org.eclipse.app4mc.amalthea.model.emf.AmaltheaResource; |
| import org.eclipse.app4mc.amalthea.model.io.AmaltheaFileHelper; |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.Platform; |
| import org.eclipse.e4.core.di.annotations.Execute; |
| import org.eclipse.e4.ui.services.IServiceConstants; |
| import org.eclipse.emf.ecore.resource.Resource; |
| import org.eclipse.emf.ecore.resource.ResourceSet; |
| import org.eclipse.jface.dialogs.MessageDialog; |
| import org.eclipse.jface.viewers.IStructuredSelection; |
| import org.eclipse.swt.widgets.Shell; |
| import org.eclipse.ui.IDecoratorManager; |
| |
| public class CompressHandler { |
| |
| private static final int BUFFER_SIZE = 2048; |
| private static final String COMPRESS_ERROR = "Compress error"; |
| |
| @Execute |
| public void execute(@Named(IServiceConstants.ACTIVE_SELECTION) IStructuredSelection selection, Shell shell, IDecoratorManager decoratorManager) { |
| Object firstElement = selection.getFirstElement(); |
| if (firstElement instanceof IFile |
| && AmaltheaFileHelper.isModelFileExtension(((IFile) firstElement).getFileExtension())) { |
| |
| IFile iFile = (IFile) firstElement; |
| AmaltheaModelContainer modelContainer = AmaltheaEditorUtil.getModelContainer(iFile); |
| |
| if (modelContainer != null && modelContainer.getInitialModelFiles().contains(iFile)) { |
| // Resource is available (model is in memory) |
| markResourceZipped(iFile, modelContainer); |
| } else { |
| // Zip model file |
| zipModelFile(iFile, shell, decoratorManager); |
| } |
| |
| } |
| } |
| |
| private void markResourceZipped(IFile iFile, AmaltheaModelContainer modelContainer) { |
| ResourceSet resourceSet = modelContainer.getResourceSet(); |
| if (resourceSet != null) { |
| for (Resource resource : resourceSet.getResources()) { |
| if (resource instanceof AmaltheaResource && resource.getURI().lastSegment().equals(iFile.getName())) { |
| // Modify zip flag of loaded resource |
| ((AmaltheaResource) resource).setUseZip(true); |
| // Mark resource as modified |
| resource.setModified(true); |
| // Mark editors dirty |
| modelContainer.updateDirtyStateOfEditors(); |
| break; |
| } |
| } |
| } |
| } |
| |
| /** |
| * Creates a Zip file (generic implementation based on java.util.zip package) |
| * |
| * @param iFile |
| * @param shell |
| * @param decoratorManager |
| */ |
| private void zipModelFile(IFile iFile, Shell shell, IDecoratorManager decoratorManager) { |
| File modelFile = new File(iFile.getLocationURI()); |
| File modelFileTmp = new File(modelFile.getParentFile(), modelFile.getName() + ".tmp"); |
| |
| // Zip model file (write to temporary file) |
| try ( FileInputStream inputStream = new FileInputStream(modelFile); |
| ZipOutputStream outputStream = new ZipOutputStream(new FileOutputStream(modelFileTmp));) |
| { |
| ZipEntry zipEntry = new ZipEntry("ResourceContents"); |
| outputStream.putNextEntry(zipEntry); |
| byte[] bytes = new byte[BUFFER_SIZE]; |
| int length; |
| while((length = inputStream.read(bytes)) >= 0) { |
| outputStream.write(bytes, 0, length); |
| } |
| } catch (IOException e) { |
| MessageDialog.openError(shell, COMPRESS_ERROR, "Failed to compress model file! " + e.getMessage()); |
| return; // stop further actions |
| } |
| |
| // Delete old model file and rename temporary file |
| try { |
| Files.delete(modelFile.toPath()); |
| Files.move(modelFileTmp.toPath(), modelFile.toPath()); |
| } catch (IOException e) { |
| MessageDialog.openError(shell, COMPRESS_ERROR, "Failed to replace model file! " + e.getMessage()); |
| } |
| |
| // Refresh file and decorators |
| try { |
| iFile.refreshLocal(IResource.DEPTH_INFINITE, null); |
| decoratorManager.update("org.eclipse.app4mc.amalthea.file.compressed.decorator"); |
| } catch (CoreException e) { |
| Platform.getLog(getClass()).error(e.getLocalizedMessage(), e); |
| } |
| } |
| |
| } |