package org.openlca.app.rcp.plugins;
import java.io.File;
import java.net.URL;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.forms.FormDialog;
import org.eclipse.ui.forms.IManagedForm;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.ScrolledForm;
import org.openlca.app.App;
import org.openlca.app.components.FileChooser;
import org.openlca.app.rcp.RcpActivator;
import org.openlca.app.rcp.html.HtmlFolder;
import org.openlca.app.rcp.html.WebPage;
import org.openlca.app.util.Controls;
import org.openlca.app.util.Info;
import org.openlca.app.util.UI;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import javafx.scene.web.WebEngine;
import netscape.javascript.JSObject;
public class PluginManager extends FormDialog implements WebPage {
private final static Gson mapper = new GsonBuilder().serializeNulls()
.create();
private final static PluginService service = new PluginService();
private final static BundleService bundleService = new BundleService();
private static Map<String, Plugin> plugins;
private WebEngine webkit;
public PluginManager() {
super(UI.shell());
}
@Override
protected Point getInitialSize() {
return new Point(800, 650);
}
@Override
protected void createFormContent(IManagedForm managedForm) {
FormToolkit toolkit = managedForm.getToolkit();
ScrolledForm form = UI
.formHeader(managedForm, "openLCA Plugin Manager");
Composite body = form.getBody();
body.getParent().getParent().setLayout(createNoSpacingLayout());
body.getParent().setLayout(createNoSpacingLayout());
body.setLayout(new FillLayout());
toolkit.paintBordersFor(body);
UI.createWebView(body, this);
form.reflow(true);
}
@Override
protected void createButtonsForButtonBar(Composite parent) {
Button b = createButton(parent, 22, "Install local file", false);
Controls.onSelect(b, e -> installLocalFile());
createButton(parent, IDialogConstants.CANCEL_ID,
IDialogConstants.CLOSE_LABEL, true);
}
private GridLayout createNoSpacingLayout() {
GridLayout layout = new GridLayout();
layout.marginRight = 0;
layout.marginLeft = 0;
layout.horizontalSpacing = 0;
layout.marginBottom = 0;
layout.marginTop = 0;
layout.verticalSpacing = 0;
layout.numColumns = 1;
return layout;
}
@Override
public String getUrl() {
return HtmlFolder.getUrl(RcpActivator.getDefault().getBundle(),
"plugin_manager.html");
}
@Override
public void onLoaded(WebEngine webkit) {
this.webkit = webkit;
JSObject window = (JSObject) webkit.executeScript("window");
window.setMember("java", new JsHandler());
refresh();
}
// after installing/uninstalling the new versions won't be recognized by the
// plugin service/bundle service until the application is restarted
// therefore only fetch once and store in memory, otherwise the changes
// could not be reflected in the UI after any action was taken
private static void loadPlugins() {
if (plugins == null) {
plugins = new HashMap<String, Plugin>();
List<Plugin> available = service.getAvailablePlugins();
for (Plugin plugin : available)
plugins.put(plugin.getSymbolicName(), plugin);
}
}
private void refresh() {
loadPlugins();
String data = mapper.toJson(plugins.values());
boolean online = isOnline();
webkit.executeScript("setData(" + data + ", " + online + ")");
}
private boolean isOnline() {
try {
URL url = new URL(PluginService.BASE_URL);
url.openConnection().connect();
return true;
} catch (Exception e) {
return false;
}
}
private void installLocalFile() {
File file = FileChooser.forImport("*.jar");
if (file == null)
return;
Plugin plugin = getPlugin(file, plugins.values());
if (plugin == null) {
Info.showBox("The file you selected isn't a valid openLCA plugin");
return;
}
App.run("Installing " + plugin.getFullDisplayName(), () -> {
service.copyLocalFile(file.toPath(), plugin);
}, this::refresh);
}
private Plugin getPlugin(File jar, Collection<Plugin> plugins) {
String[] nameAndVersion = bundleService.getSymbolicNameAndVersion(jar);
for (Plugin plugin : plugins)
if (plugin.getSymbolicName().equals(nameAndVersion[0]))
if (plugin.getVersion().equals(nameAndVersion[1]))
return plugin;
return null;
}
public class JsHandler {
public void install(String name) {
Plugin plugin = plugins.get(name);
String title = "Installing " + plugin.getFullDisplayName();
App.runWithProgress(title, () -> service.install(plugin));
refresh();
}
public void update(String name) {
Plugin plugin = plugins.get(name);
String title = "Updating to " + plugin.getFullDisplayName();
App.runWithProgress(title, () -> {
service.update(plugin);
refresh();
});
}
public void uninstall(String name) {
Plugin plugin = plugins.get(name);
String title = "Uninstalling " + plugin.getFullDisplayName();
App.runWithProgress(title, () -> {
service.uninstall(plugin);
refresh();
});
}
}
}