package org.esa.snap.rcp.scripting;
import com.bc.ceres.core.Assert;
import org.esa.snap.core.util.SystemUtils;
import javax.swing.Action;
import java.awt.event.ActionEvent;
import java.beans.PropertyChangeListener;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
/**
* A proxy action which can be used to programmatically register delegate actions which will *not* be serialized
* into the NetBeans filesystem.
* The proxy protects the delegate action from being serialized/deserialized by the NetBeans Platform
* by putting the delegate into a static hash table. On serialisation request only the file system path is serialized
* and used to look up the delegate action later on deserialisation request.
*
* @author Norman Fomferra
*/
public class TransientAction implements Action, Serializable {
private static final long serialVersionUID = 3069372659219673560L;
private static final Map<String, Action> DELEGATES = new HashMap<>();
private String path;
private Action delegate;
TransientAction(Action delegate, String path) {
Assert.notNull(delegate, "delegate");
Assert.notNull(path, "path");
Assert.argument(path.endsWith(".instance"), "path");
Assert.argument(path.contains("/"), "path");
this.path = path;
this.delegate = delegate;
Action oldDelegate = DELEGATES.put(path, delegate);
if (oldDelegate != null) {
SystemUtils.LOG.info(String.format("Proxy action %s registered once more. Replacing the old action.%n", this.path));
}
SystemUtils.LOG.info(String.format("Proxy action added as %s%n", this.path));
}
static Action getAction(String path1) {
return DELEGATES.get(path1);
}
static boolean hasAction(String path) {
return DELEGATES.containsKey(path);
}
static Action removeAction(String path1) {
return DELEGATES.remove(path1);
}
public Action getDelegate() {
return delegate;
}
public String getPath() {
return path;
}
@Override
public Object getValue(String key) {
return delegate.getValue(key);
}
@Override
public void putValue(String key, Object value) {
delegate.putValue(key, value);
}
@Override
public void setEnabled(boolean b) {
delegate.setEnabled(b);
}
@Override
public boolean isEnabled() {
return delegate.isEnabled();
}
@Override
public void addPropertyChangeListener(PropertyChangeListener listener) {
delegate.addPropertyChangeListener(listener);
}
@Override
public void removePropertyChangeListener(PropertyChangeListener listener) {
delegate.removePropertyChangeListener(listener);
}
@Override
public void actionPerformed(ActionEvent e) {
delegate.actionPerformed(e);
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
String path = in.readUTF();
Action delegate = DELEGATES.get(path);
if (delegate == null) {
throw new IOException(String.format("Action delegate not found for file %s.\n" +
"Please make sure to call removeAction() before SNAP shuts down.", path));
}
this.path = path;
this.delegate = delegate;
SystemUtils.LOG.info(String.format("Deserialized proxy action %s%n", this.path));
}
private void writeObject(ObjectOutputStream out) throws IOException {
out.writeUTF(path);
SystemUtils.LOG.info(String.format("Serialized proxy action %s%n", this.path));
}
}