/*
* Copyright (C) 2015 by Array Systems Computing Inc. http://www.array.ca
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 3 of the License, or (at your option)
* any later version.
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, see http://www.gnu.org/licenses/
*/
package org.esa.snap.raster.rcp.actions;
import org.esa.snap.core.datamodel.MetadataElement;
import org.esa.snap.core.datamodel.Product;
import org.esa.snap.core.datamodel.ProductNode;
import org.esa.snap.core.util.SystemUtils;
import org.esa.snap.engine_utilities.datamodel.AbstractMetadata;
import org.esa.snap.engine_utilities.datamodel.metadata.AbstractMetadataIO;
import org.esa.snap.raster.gpf.ReplaceMetadataOp;
import org.esa.snap.raster.rcp.dialogs.StringSelectorDialog;
import org.esa.snap.rcp.SnapApp;
import org.esa.snap.rcp.actions.AbstractSnapAction;
import org.esa.snap.rcp.util.Dialogs;
import org.openide.awt.ActionID;
import org.openide.awt.ActionReference;
import org.openide.awt.ActionRegistration;
import org.openide.util.ContextAwareAction;
import org.openide.util.Lookup;
import org.openide.util.LookupEvent;
import org.openide.util.LookupListener;
import org.openide.util.NbBundle;
import org.openide.util.Utilities;
import org.openide.util.WeakListeners;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
@ActionID(category = "Processing", id = "org.esa.snap.raster.rcp.actions.ReplaceMetadataAction")
@ActionRegistration(displayName = "#CTL_ReplaceMetadataAction_Text")
@ActionReference(path = "Menu/Tools/Metadata", position = 400)
@NbBundle.Messages({"CTL_ReplaceMetadataAction_Text=Replace Metadata"})
/**
* This action replaces the Metadata with that of another product
*
*/
public class ReplaceMetadataAction extends AbstractSnapAction implements ContextAwareAction, LookupListener {
private final Lookup lkp;
private Product product;
public ReplaceMetadataAction() {
this(Utilities.actionsGlobalContext());
}
public ReplaceMetadataAction(Lookup lkp) {
this.lkp = lkp;
Lookup.Result<ProductNode> lkpContext = lkp.lookupResult(ProductNode.class);
lkpContext.addLookupListener(WeakListeners.create(LookupListener.class, this, lkpContext));
setEnableState();
putValue(Action.NAME, Bundle.CTL_ReplaceMetadataAction_Text());
//putValue(Action.SHORT_DESCRIPTION, Bundle.CTL_SearchMetadataValueAction_ShortDescription());
}
@Override
public Action createContextAwareInstance(Lookup actionContext) {
return new ReplaceMetadataAction(actionContext);
}
@Override
public void resultChanged(LookupEvent ev) {
setEnableState();
}
private void setEnableState() {
ProductNode productNode = lkp.lookup(ProductNode.class);
boolean state = false;
if (productNode != null) {
product = productNode.getProduct();
state = product.getMetadataRoot() != null;
}
setEnabled(state);
}
@Override
public void actionPerformed(final ActionEvent event) {
final String[] compatibleProductNames = getCompatibleProducts(product);
if (compatibleProductNames.length == 0) {
Dialogs.showError("There are not any compatible products currently opened\nDimensions must be the same");
return;
}
final StringSelectorDialog dlg = new StringSelectorDialog("Replace Metadata with", compatibleProductNames);
dlg.show();
if (dlg.IsOK()) {
try {
final MetadataElement origAbsRoot = AbstractMetadata.getAbstractedMetadata(product);
final int isPolsar = origAbsRoot.getAttributeInt(AbstractMetadata.polsarData, 0);
final int isCalibrated = origAbsRoot.getAttributeInt(AbstractMetadata.abs_calibration_flag, 0);
final String srcProductName = dlg.getSelectedItem();
final Product[] products = SnapApp.getDefault().getProductManager().getProducts();
Product srcProduct = null;
for (Product prod : products) {
if (prod.getDisplayName().equals(srcProductName)) {
srcProduct = prod;
break;
}
}
final MetadataElement srcAbsRoot = AbstractMetadata.getAbstractedMetadata(srcProduct);
final File tmpMetadataFile = new File(SystemUtils.getCacheDir(),
srcProduct.getName() + "_metadata.xml");
AbstractMetadataIO.Save(srcProduct, srcAbsRoot, tmpMetadataFile);
clearProductMetadata(product);
SnapApp.getDefault().getProductManager().removeProduct(product);
final MetadataElement destAbsRoot = AbstractMetadata.getAbstractedMetadata(product);
AbstractMetadataIO.Load(product, destAbsRoot, tmpMetadataFile);
SnapApp.getDefault().getProductManager().addProduct(product);
ReplaceMetadataOp.resetPolarizations(AbstractMetadata.getAbstractedMetadata(product),
isPolsar, isCalibrated);
tmpMetadataFile.delete();
} catch (Exception e) {
Dialogs.showError("Unable to save or load metadata\n" + e.getMessage());
}
}
}
private static String[] getCompatibleProducts(final Product destProduct) {
final List<String> prodList = new ArrayList<>();
final Product[] products = SnapApp.getDefault().getProductManager().getProducts();
for (Product p : products) {
if (p != destProduct &&
p.getSceneRasterWidth() == destProduct.getSceneRasterWidth() &&
p.getSceneRasterHeight() == destProduct.getSceneRasterHeight()) {
prodList.add(p.getDisplayName());
}
}
return prodList.toArray(new String[prodList.size()]);
}
private static void clearProductMetadata(final Product product) {
final String[] tpgNames = product.getTiePointGridNames();
for (String tpg : tpgNames) {
product.removeTiePointGrid(product.getTiePointGrid(tpg));
}
final MetadataElement root = product.getMetadataRoot();
final MetadataElement[] elems = root.getElements();
for (MetadataElement e : elems) {
root.removeElement(e);
}
AbstractMetadata.addAbstractedMetadataHeader(product.getMetadataRoot());
}
}