/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package org.esa.snap.rcp.actions.file; import org.esa.snap.core.dataio.ProductIO; import org.esa.snap.core.dataio.ProductReader; import org.esa.snap.core.dataio.dimap.DimapProductConstants; import org.esa.snap.core.dataio.dimap.DimapProductHelpers; import org.esa.snap.core.dataio.dimap.DimapProductReader; import org.esa.snap.core.datamodel.Band; import org.esa.snap.core.datamodel.Product; import org.esa.snap.core.datamodel.ProductNode; import org.esa.snap.core.image.BandOpImage; import org.esa.snap.rcp.SnapApp; import org.esa.snap.rcp.util.Dialogs; import org.openide.awt.ActionID; import org.openide.awt.ActionReference; import org.openide.awt.ActionReferences; import org.openide.awt.ActionRegistration; import org.openide.util.NbBundle; import javax.swing.AbstractAction; import java.awt.event.ActionEvent; import java.io.File; import java.io.IOException; import java.lang.ref.WeakReference; import java.text.MessageFormat; /** * Action which saves a selected product using a new name. * * @author Norman */ @ActionID(category = "File", id = "SaveProductAsAction") @ActionRegistration(displayName = "#CTL_SaveProductAsActionName") @ActionReferences({ @ActionReference(path = "Menu/File", position = 45, separatorAfter = 46), @ActionReference(path = "Context/Product/Product", position = 95, separatorAfter = 96) }) @NbBundle.Messages({"CTL_SaveProductAsActionName=Save Product As..."}) public final class SaveProductAsAction extends AbstractAction { public static final String PREFERENCES_KEY_PRODUCT_CONVERSION_REQUIRED = "product_conversion_required"; public static final String PREFERENCES_KEY_LAST_PRODUCT_DIR = "last_product_save_dir"; private final WeakReference<ProductNode> productNodeRef; public SaveProductAsAction(ProductNode productNode) { productNodeRef = new WeakReference<>(productNode); } @Override public void actionPerformed(ActionEvent e) { execute(); } /** * Executes the action command. * * @return {@code Boolean.TRUE} on success, {@code Boolean.FALSE} on failure, or {@code null} on cancellation. */ public Boolean execute() { ProductNode productNode = productNodeRef.get(); if (productNode != null && productNode.getProduct() != null) { return saveProductAs(productNode.getProduct()); } else { // reference was garbage collected, that's fine, no need to save. return true; } } private Boolean saveProductAs(Product product) { ProductReader reader = product.getProductReader(); if (reader != null && !(reader instanceof DimapProductReader)) { Dialogs.Answer answer = Dialogs.requestDecision("Save Product As", MessageFormat.format("In order to save the product\n" + " {0}\n" + "it has to be converted to the BEAM-DIMAP format.\n" + "Depending on the product size the conversion also may take a while.\n\n" + "Do you really want to convert the product now?\n", product.getDisplayName()), true, PREFERENCES_KEY_PRODUCT_CONVERSION_REQUIRED); if (answer == Dialogs.Answer.NO) { return false; } else if (answer == Dialogs.Answer.CANCELLED) { return null; } } String fileName; if (product.getFileLocation() != null) { fileName = product.getFileLocation().getName(); } else { fileName = product.getName(); } File newFile = Dialogs.requestFileForSave("Save Product As", false, DimapProductHelpers.createDimapFileFilter(), DimapProductConstants.DIMAP_HEADER_FILE_EXTENSION, fileName, null, OpenProductAction.PREFERENCES_KEY_LAST_PRODUCT_DIR); if (newFile == null) { // cancelled return null; } String oldProductName = product.getName(); File oldFile = product.getFileLocation(); // For DIMAP products, check if file path has really changed // if not, just save product if (reader instanceof DimapProductReader && newFile.equals(oldFile)) { return new SaveProductAction(product).execute(); } product.setFileLocation(newFile); Boolean status = SaveProductAction.saveProduct(product); if (Boolean.TRUE.equals(status)) { try { attachNewDimapReaderInstance(product, newFile); } catch (IOException e) { SnapApp.getDefault().handleError("Failed to reopen product", e); } } else { product.setFileLocation(oldFile); product.setName(oldProductName); } return status; } private void attachNewDimapReaderInstance(Product product, File newFile) throws IOException { DimapProductReader productReader = (DimapProductReader) ProductIO.getProductReader(DimapProductConstants.DIMAP_FORMAT_NAME); productReader.bindProduct(newFile, product); product.setProductReader(productReader); Band[] bands = product.getBands(); for (Band band : bands) { if (band.isSourceImageSet() && band.getSourceImage().getImage(0) instanceof BandOpImage) { band.setSourceImage(null); } } } }