blob: 42e7863c36e4852cfb9e38efafe8487d390d46c3 [file] [log] [blame]
/**
********************************************************************************
* 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);
}
}
}