LibTableView.java
/*
** Module : LibTableView.java
** Abstract : Libraries table widget.
**
** Copyright (c) 2017, Golden Code Development Corporation.
**
** -#- -I- --Date-- --------------------------------Description-----------------------------------
** 001 HC 20170612 Initial version.
*/
/*
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU Affero 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 Affero General Public License for more details.
**
** You may find a copy of the GNU Affero GPL version 3 at the following
** location: https://www.gnu.org/licenses/agpl-3.0.en.html
**
** Additional terms under GNU Affero GPL version 3 section 7:
**
** Under Section 7 of the GNU Affero GPL version 3, the following additional
** terms apply to the works covered under the License. These additional terms
** are non-permissive additional terms allowed under Section 7 of the GNU
** Affero GPL version 3 and may not be removed by you.
**
** 0. Attribution Requirement.
**
** You must preserve all legal notices or author attributions in the covered
** work or Appropriate Legal Notices displayed by works containing the covered
** work. You may not remove from the covered work any author or developer
** credit already included within the covered work.
**
** 1. No License To Use Trademarks.
**
** This license does not grant any license or rights to use the trademarks
** Golden Code, FWD, any Golden Code or FWD logo, or any other trademarks
** of Golden Code Development Corporation. You are not authorized to use the
** name Golden Code, FWD, or the names of any author or contributor, for
** publicity purposes without written authorization.
**
** 2. No Misrepresentation of Affiliation.
**
** You may not represent yourself as Golden Code Development Corporation or FWD.
**
** You may not represent yourself for publicity purposes as associated with
** Golden Code Development Corporation, FWD, or any author or contributor to
** the covered work, without written authorization.
**
** 3. No Misrepresentation of Source or Origin.
**
** You may not represent the covered work as solely your work. All modified
** versions of the covered work must be marked in a reasonable way to make it
** clear that the modified work is not originating from Golden Code Development
** Corporation or FWD. All modified versions must contain the notices of
** attribution required in this license.
*/
package com.goldencode.p2j.admin.client.application.home.runtime.customlib;
import com.goldencode.p2j.admin.*;
import com.goldencode.p2j.admin.client.*;
import com.goldencode.p2j.admin.client.application.*;
import com.goldencode.p2j.admin.client.widget.*;
import com.goldencode.p2j.admin.client.widget.dialog.*;
import com.goldencode.p2j.admin.shared.*;
import com.google.gwt.event.dom.client.*;
import com.google.gwt.uibinder.client.*;
import com.google.gwt.user.client.rpc.*;
import com.google.gwt.user.client.ui.*;
import com.google.inject.*;
import com.gwtplatform.mvp.client.*;
import org.gwtbootstrap3.client.ui.Button;
import org.gwtbootstrap3.client.ui.*;
import org.gwtbootstrap3.client.ui.constants.*;
import org.gwtbootstrap3.client.ui.gwt.*;
import java.util.*;
/**
* Libraries table widget.
*/
public class LibTableView
extends ViewImpl
implements LibTablePresenter.MyView
{
/**
* GWT binder.
*/
interface Binder extends UiBinder<Row, LibTableView>
{}
/** jars grid */
@UiField(provided = true)
DataGrid<TaggedName> jarGrid = new DataGrid<>(Integer.MAX_VALUE);
/** apis grid */
@UiField(provided = true)
DataGrid<TaggedName> apisGrid = new DataGrid<>(Integer.MAX_VALUE);
/** widget */
@UiField
Button jarRefresh;
/** widget */
@UiField
Button jarReg;
/** widget */
@UiField
Button jarDereg;
/** widget */
@UiField
Button jarReload;
/** widget */
@UiField
Button jarEditHook;
/** widget */
@UiField
Button regAPI;
/** widget */
@UiField
Button deregAPI;
/** widget */
@UiField
SimplePanel listSelect;
/** widget */
@UiField
SimplePanel terminateSessions;
/** jars grid handle */
private GridHandle<TaggedName> jarGridHandle;
/** jars grid handle */
private GridHandle<TaggedName> apisGridHandle;
/** list select dialog provider */
private Provider<ListSelect> listSelectProvider;
/** terminate session dialog provider */
private Provider<TerminateSessions> termSessionsProvider;
/** Admin service reference */
private final AdminServiceAsync adm;
/** Modal dialogs */
private final ModalDialogs dialogs;
/** Alarm provider */
private Provider<Alarm> alarmProvider;
/**
* Ctor.
*
* @param binder
* GWT binder.
* @param adm
* Admin service reference.
* @param dialogs
* Modal dialogs.
* @param alarmProvider
* Alarm provider.
* @param listSelectProvider
* List select dialog provider.
* @param termSessionsProvider
* Terminate session dialog provider.
*/
@Inject
LibTableView(Binder binder,
com.goldencode.p2j.admin.shared.AdminServiceAsync adm,
ModalDialogs dialogs,
Provider<Alarm> alarmProvider,
Provider<ListSelect> listSelectProvider,
Provider<TerminateSessions> termSessionsProvider)
{
this.adm = adm;
this.dialogs = dialogs;
this.alarmProvider = alarmProvider;
this.listSelectProvider = listSelectProvider;
this.termSessionsProvider = termSessionsProvider;
initWidget(binder.createAndBindUi(this));
initView();
}
/**
* Called when the view is about to be revealed.
*/
@Override
public void onReveal()
{
refreshJarList(false);
}
/**
* Initializes the view.
*/
private void initView()
{
//noinspection NonJREEmulationClassesInClientCode
jarGridHandle = GridHelper.initListGrid(jarGrid,
new GridHelper.ColumnInfo<TaggedName>("Jar File Name", tn -> tn.get(0), (tn1, tn2) -> tn1.get(0).compareTo(tn2.get(0))),
new GridHelper.ColumnInfo<TaggedName>("Active Hook", tn -> tn.get(1), (tn1, tn2) -> tn1.get(1).compareTo(tn2.get(1)))
);
jarGridHandle.getSelectionModel().addSelectionChangeHandler(event ->
{
refreshApiList();
refreshJarButtonsState();
refreshApiButtonsState();
});
//noinspection NonJREEmulationClassesInClientCode
apisGridHandle = GridHelper.initListGrid(apisGrid,
new GridHelper.ColumnInfo<TaggedName>("Interface", tn -> tn.get(0), (tn1, tn2) -> tn1.get(0).compareTo(tn2.get(0))),
new GridHelper.ColumnInfo<TaggedName>("Implementation Class", tn -> tn.get(1), (tn1, tn2) -> tn1.get(1).compareTo(tn2.get(1)))
);
apisGridHandle.getSelectionModel().addSelectionChangeHandler(event ->
{
refreshApiButtonsState();
});
}
/**
* Click handler.
*
* @param e
* Click event.
*/
@UiHandler("jarRefresh")
protected void jarRefreshClicked(ClickEvent e)
{
refreshJarList(true);
}
/**
* Click handler.
*
* @param e
* Click event.
*/
@UiHandler("jarReg")
protected void jarRegClicked(ClickEvent e)
{
handleRegJarStep1();
}
/**
* Click handler.
*
* @param e
* Click event.
*/
@UiHandler("regAPI")
protected void apiRegClicked(ClickEvent e)
{
handleRegAPIStep1();
}
/**
* Click handler.
*
* @param e
* Click event.
*/
@UiHandler("jarDereg")
public void jarDeregClick(ClickEvent e)
{
handleDeregisterJar();
}
/**
* Click handler.
*
* @param e
* Click event.
*/
@UiHandler("deregAPI")
public void deregAPIClick(ClickEvent e)
{
handleDeregisterAPI();
}
/**
* Click handler.
*
* @param e
* Click event.
*/
@UiHandler("jarReload")
public void jarReloadClick(ClickEvent e)
{
handleReloadJarStep1();
}
/**
* Click handler.
*
* @param e
* Click event.
*/
@UiHandler("jarEditHook")
public void jarEditHookClick(ClickEvent e)
{
handleEditHooks();
}
/**
* Step one of the register jar wizard.
*/
private void handleRegJarStep1()
{
adm.getUnregisteredJars(new AsyncCallback<String[]>()
{
@Override
public void onFailure(Throwable caught)
{
dialogs.showError(
"Cannot get the list of unregistered jars.");
return;
}
@Override
public void onSuccess(String[] jars)
{
String targetJar = null;
if (jars != null)
{
if (jars.length == 0)
{
adm.getManagedLibsDirInformation(new AsyncCallback<TaggedName>()
{
@Override
public void onFailure(Throwable caught)
{
dialogs.showError("Cannot get managed libraries directory information.");
}
@Override
public void onSuccess(TaggedName dirInfo)
{
if (dirInfo == null)
{
dialogs.showError(
"Cannot get managed libraries directory information.");
return;
}
StringBuilder sb = new StringBuilder();
if (dirInfo.getName() == null)
{
sb.append("<span style=\"color:red\">Customer libraries directory is not specified!</span><br>");
sb.append("You can set the directory by specifying the <i>-Dmanaged.libs.dir=some/path/</i> java option or<br>");
sb.append("by setting the <i>/server/default/managed-libs-dir</i> parameter in the configuration directory.<br>");
}
else
{
sb.append("There are no unregistered customer libraries in the managed customer libraries directory!<br>");
sb.append("The current path to the directory is <i>");
sb.append(dirInfo.getName());
sb.append("true".equals(dirInfo.getTag()) ? "</i>.<br>" :
"</i>, but it <span style=\"color:red\"> does not exist or is inaccessible</span>!<br>");
sb.append("You can change the directory by specifying the <i>-Dmanaged.libs.dir=some/path/</i> java option or<br>");
sb.append("by setting the <i>/server/default/managed-libs-dir</i> parameter in the configuration directory.<br>");
}
sb.append("Also, managed customer libraries should not be present in the server class path.");
dialogs.showInfo("No Unregistered Libraries", sb.toString(), null);
return;
}
});
}
else
{
TaggedName[] data = toTaggedNames(jars);
ListSelect ls = listSelectProvider.get();
ls.show(listSelect, data,
"Register New Customer Library (Step 1 / 2)",
"Customer libraries that can be registered",
new String[]{"Jar file name"},
"Select the appropriate customer library. If you are not seeing the " +
"expected library then it may be already registered or presents in " +
"the server class path.",
taggedName ->
{
if (taggedName == null || taggedName.getName() == null)
{
// dialog canceled
return;
}
handleRegJarStep2(taggedName.getName());
}
);
}
}
}
});
}
/**
* Step two of the register jar wizard.
*
* @param targetJar
* Target jar.
*/
private void handleRegJarStep2(String targetJar)
{
adm.getAvailableJarHookClasses(targetJar, new AsyncCallback<String[]>()
{
@Override
public void onFailure(Throwable caught)
{
dialogs.showError("Cannot get the list of jar hook classes.");
}
@Override
public void onSuccess(String[] hooks)
{
if (hooks != null)
{
if (hooks.length == 0)
{
dialogs.showInfo("No Hook Classes Found for the Selected Jar",
"There are no classes in the selected library that can serve" +
" as a hook class which performs jar initialization. No " +
"hook class will be defined for this library.",
null);
}
else
{
TaggedName[] data = toTaggedNames(hooks);
ListSelect ls = listSelectProvider.get();
ls.show(listSelect, data,
"Register New Customer Library (Step 2 / 2)",
"Hook classes availible in the selected jar",
new String[]{"Hook class name"},
"Select an appropriate hook class. This class will be used for jar " +
"initialization. Note that you can skip this step.",
taggedName ->
{
if (taggedName == null || taggedName.getName() == null)
{
// dialog canceled
return;
}
registerJar(targetJar, taggedName.getName());
}
);
}
}
}
});
}
/**
* Handles API deregistration.
*/
private void handleDeregisterAPI()
{
String targetJar = getSelectedJar();
TaggedName targetApi = getSelectedApi();
if (targetJar == null || targetApi == null)
return;
String errDereg = "An error occured while deregistering the API.";
dialogs.showYesNo("Deregister API", "Are you sure you want to deregister the selected " +
"API?", MessageType.QUESTION, res ->
{
if (res == 0)
{
adm.deregisterJarAPI(targetJar, targetApi.getName(), false, new
AsyncCallback<JarOpErrorCode>()
{
@Override
public void onFailure(Throwable caught)
{
dialogs.showError(errDereg);
}
@Override
public void onSuccess(JarOpErrorCode result)
{
if (result == JarOpErrorCode.ACTIVE_SESSIONS_PRESENT)
{
// there are active session related to the selected API, display
// the "terminate sessions" dialog.
TerminateSessions ts = termSessionsProvider.get();
ts.show(terminateSessions,
TerminateSessions.JarActionType.API_DEREGISTER,
targetJar, targetApi.getName(), res -> refreshApiList());
}
else if (result != JarOpErrorCode.SUCCESS)
{
dialogs.showError(errDereg + " " + result);
}
else
{
refreshApiList();
}
}
});
}
});
}
/**
* Handle "reload customer library" button.
*/
private void handleReloadJarStep1()
{
String targetJar = getSelectedJar();
if (targetJar == null)
{
return;
}
String err = "An error occured while deregistering customer library.";
dialogs.showYesNo("Reload Customer Library",
"Are you sure you want to reload the selected customer library?<br> " +
"Note that you should replace the customer library on the disk only " +
"when you will be asked for it on the next step.",
MessageType.QUESTION, res ->
{
if (res == 0)
{
adm.getStoredJarHookClass(targetJar, new AdminCallback<String>(adm, alarmProvider.get())
{
@Override
public void onDone(String storedHookClass)
{
if (!isSuccess())
{
return;
}
adm.deregisterJar(targetJar, false, false, new
AdminCallback<JarOpErrorCode>(adm, alarmProvider.get())
{
@Override
public void onDone(JarOpErrorCode result)
{
if (!isSuccess())
{
refreshJarList(true);
return;
}
if (result == JarOpErrorCode.ACTIVE_SESSIONS_PRESENT)
{
TerminateSessions ts = termSessionsProvider.get();
ts.show(terminateSessions,
TerminateSessions.JarActionType.JAR_RELOAD,
targetJar,
null, res ->
{
if (res)
{
handleReloadJarStep2(targetJar,
storedHookClass);
}
else
{
refreshJarList(true);
}
});
}
else if (result != JarOpErrorCode.SUCCESS)
{
dialogs.showError(err);
refreshJarList(true);
}
else
{
handleReloadJarStep2(targetJar, storedHookClass);
}
}
});
}
});
}
}
);
}
/**
* Second step of the reload jar wizard.
*
* @param targetJar
* Target jar.
* @param hookClass
* Hook class.
*/
private void handleReloadJarStep2(String targetJar, String hookClass)
{
String regErr = "An error occured while registering customer library.";
String deregErr = "An error occured while deregistering customer library after re-registration error.";
dialogs.showMessage(
"Replace Customer Library",
"Now you can replace the customer library on the disk (unless you " +
"just want to reload the hook).",
MessageType.DEFAULT,
new String[]{"Continue"},
new ButtonType[]{ButtonType.PRIMARY},
res ->
{
adm.registerJar(targetJar, hookClass, false, new AdminCallback<JarOpErrorCode>(adm, alarmProvider.get())
{
@Override
public void onDone(JarOpErrorCode result)
{
if (!isSuccess())
{
refreshJarList(true);
return;
}
if (result == JarOpErrorCode.SUCCESS)
{
dialogs.showInfo(
"Operation Completed",
"The customer library was successfully reloaded.",
null);
refreshJarList(true);
}
else
{
dialogs.showError("An error occured while registering customer library.", () ->
{
adm.deregisterJarFromDirectory(targetJar, hookClass, new
AdminCallback<JarOpErrorCode>(adm, alarmProvider.get())
{
@Override
public void onDone(JarOpErrorCode result)
{
if (!isSuccess())
{
refreshJarList(true);
return;
}
if (result == JarOpErrorCode.SUCCESS)
{
StringBuilder sb = new StringBuilder();
sb.append("Because of re-registration error, registration has ");
sb.append("been removed for customer library ");
sb.append(targetJar);
if (hookClass == null)
sb.append(" (no hook class).");
else
{
sb.append(" (hook class ");
sb.append(hookClass);
sb.append(").");
}
dialogs.showWarning("Operation Completed", sb.toString(), null);
}
else
{
dialogs.showError(deregErr + " " + result);
}
refreshJarList(true);
}
});
});
}
}
});
});
}
/**
* Handle "edit hook class" button.
*/
private void handleEditHooks()
{
final String targetJar = getSelectedJar();
if (targetJar == null)
{
return;
}
adm.getStoredJarHookClass(targetJar, new AsyncCallback<String>()
{
@Override
public void onFailure(Throwable caught)
{
}
@Override
public void onSuccess(String hookClass)
{
dialogs.showMessage(
"Edit Customer Library Hook Class",
"You are editing the hook class specified in the directory, so it may" +
" not match the active hook class displayed in the customer libraries" +
" table. Hook is reinitialized when the customer library is reloaded.",
MessageType.DEFAULT,
new String[]{"Edit", "Remove", "Close"},
new ButtonType[]{ButtonType.PRIMARY, ButtonType.PRIMARY,
ButtonType.DEFAULT},
res ->
{
if (res == 0)
{
handleEditHookClass(hookClass, targetJar);
}
else if (res == 1)
{
handleRemoveHookClass(targetJar);
}
});
}
});
}
/**
* Handle "edit hook class" buttons.
*
* @param currentHook
* Current hook class (server-wide or global) for the target jar
* file.
* @param targetJar
* Target jar file.
*/
private void handleEditHookClass(String currentHook, String targetJar)
{
String err = "Cannot get available hook classes.";
// get hook classes available for selection
adm.getAvailableJarHookClasses(targetJar, new AsyncCallback<String[]>()
{
@Override
public void onFailure(Throwable caught)
{
dialogs.showError(err);
}
@Override
public void onSuccess(String[] availHooks)
{
if (availHooks == null)
{
dialogs.showError(err);
}
else if (availHooks.length == 0)
{
dialogs.showInfo("No Hook Classes Found for the Selected Jar", "There are no " +
"classes in the selected jar that can serve as a hook class which performs jar " +
"initialization.", null);
}
else
{
TaggedName[] data = toTaggedNames(availHooks);
ListSelect ls = listSelectProvider.get();
ls.show(listSelect, data,
"Edit hook class",
"Hook classes availible in the selected jar",
new String[]{"Hook class name"},
"Select an appropriate hook class. This class will be used for jar " +
"initialization.",
currentHook == null ? null : new TaggedName(currentHook, null),
taggedName ->
{
if (taggedName == null || taggedName.getName() == null)
{
// dialog canceled
return;
}
changeJarHookClass(targetJar, taggedName.getName());
}
);
}
}
});
}
/**
* Implements remove hook class.
*
* @param targetJar
* Target jar.
*/
private void handleRemoveHookClass(String targetJar)
{
String err = "Cannot change hook class.";
dialogs.showYesNo(
"Remove Hook",
"Are you sure you want to remove the hook?",
MessageType.QUESTION, res ->
{
if (res == 0)
{
adm.changeJarHookClass(targetJar, null, new AsyncCallback<JarOpErrorCode>()
{
@Override
public void onFailure(Throwable caught)
{
dialogs.showError(err);
}
@Override
public void onSuccess(JarOpErrorCode result)
{
if (result != JarOpErrorCode.SUCCESS)
{
dialogs.showError(err + " " + result);
}
else
{
refreshJarList(true);
}
}
});
}
});
}
/**
* Implements register jar.
*
* @param targetJar
* Target jar.
* @param targetHook
* Target hook.
*/
private void registerJar(String targetJar, String targetHook)
{
String err = "An error occured while registering the customer library.";
adm.registerJar(targetJar, targetHook, true, new AsyncCallback<JarOpErrorCode>()
{
@Override
public void onFailure(Throwable caught)
{
dialogs.showError(err);
}
@Override
public void onSuccess(JarOpErrorCode result)
{
refreshJarList(false);
if (result == JarOpErrorCode.SUCCESS)
{
dialogs.showInfo("The customer library was successfully registered.",
"Operation Completed",
null);
}
else
{
dialogs.showError(err + " " + result);
}
}
});
}
/**
* Implements change jar hook class.
*
* @param targetJar
* Target jar.
* @param targetHook
* Target hook.
*/
private void changeJarHookClass(String targetJar, String targetHook)
{
String err = "Cannot change hook class.";
adm.changeJarHookClass(targetJar, targetHook, new AsyncCallback<JarOpErrorCode>()
{
@Override
public void onFailure(Throwable caught)
{
dialogs.showError(err);
}
@Override
public void onSuccess(JarOpErrorCode result)
{
if (result != JarOpErrorCode.SUCCESS)
{
dialogs.showError(err + " " + result);
}
else
{
refreshJarList(true);
}
}
});
}
/**
* First step of the register api wizard.
*/
private void handleRegAPIStep1()
{
String targetJar = getSelectedJar();
if (targetJar == null)
{
return;
}
String errAvailFaces = "Cannot get the list of interfaces.";
adm.getAvailableJarAPIInterfaces(targetJar, false, new AsyncCallback<String[]>()
{
@Override
public void onFailure(Throwable caught)
{
dialogs.showError(errAvailFaces);
}
@Override
public void onSuccess(String[] interfaces)
{
if (interfaces != null)
{
if (interfaces.length == 0)
{
dialogs.showInfo("No Interfaces Were Found",
"In the selected jar there are no unregistered interfaces " +
"which can define an API.", null);
}
else
{
TaggedName[] data = toTaggedNames(interfaces);
ListSelect ls = listSelectProvider.get();
ls.show(listSelect, data, "Register New API (Step 1 / 2)",
"Interfaces",
new String[]{"Interface name"},
"Select the interface which defines the API you want to register " +
"(this list contains only unregistered interfaces).",
taggedName ->
{
String targetInterface = taggedName.getName();
if (targetInterface != null)
{
handleRegAPIStep2(targetJar, targetInterface);
}
}
);
}
}
else
{
dialogs.showError(errAvailFaces);
}
}
});
}
/**
* Second step of the register api wizard.
*
* @param targetJar
* Target jar.
* @param targetInterface
* Target interface.
*/
private void handleRegAPIStep2(String targetJar, String targetInterface)
{
String errAvailClasses = "Cannot get the list of implementation classes.";
adm.getAvailableJarAPIImplClasses(targetJar, targetInterface, new AsyncCallback<String[]>()
{
@Override
public void onFailure(Throwable caught)
{
dialogs.showError(errAvailClasses);
}
@Override
public void onSuccess(String[] implementations)
{
if (implementations != null)
{
if (implementations.length == 0)
{
dialogs.showInfo("No Implementation Classes Were Found", "In the selected " +
"customer library there are no classes which statically implement the " +
"selected interface. API registration was cancelled.", null);
}
else
{
TaggedName[] data = toTaggedNames(implementations);
ListSelect ls = listSelectProvider.get();
ls.show(listSelect, data, "Register New API (Step 2 / 2)",
"Implementation classes",
new String[]{"Class name"},
"Select the class which implements the API you want to register.",
taggedName ->
{
String targetImplementation = taggedName.getName();
if (targetImplementation != null)
{
registerJarAPI(targetInterface, targetImplementation);
}
}
);
}
}
else
{
dialogs.showError(errAvailClasses);
}
}
});
}
/**
* Handle "deregister jar" button.
*/
private void handleDeregisterJar()
{
String targetJar = getSelectedJar();
if (targetJar == null)
{
return;
}
String errDereg = "An error occured while deregistering the jar.";
dialogs.showYesNo("Deregister Customer Library", "Are you sure you want to deregister the" +
" selected customer library?", MessageType.QUESTION, res ->
{
// YES
if (res == 0)
{
adm.deregisterJar(targetJar, false, true, new AsyncCallback<JarOpErrorCode>()
{
@Override
public void onFailure(Throwable caught)
{
dialogs.showError(errDereg);
}
@Override
public void onSuccess(JarOpErrorCode result)
{
if (result == JarOpErrorCode.ACTIVE_SESSIONS_PRESENT)
{
// there are active session related to the selected jar, display
// the "terminate sessions" dialog.
TerminateSessions ts = termSessionsProvider.get();
ts.show(terminateSessions,
TerminateSessions.JarActionType.JAR_DEREGISTER,
targetJar, null, res -> refreshJarList(false));
}
else if (result != JarOpErrorCode.SUCCESS)
{
dialogs.showError(errDereg + " " + result);
}
else
{
refreshJarList(false);
}
}
});
}
});
}
/**
* Implements register jar API.
*
* @param targetInterface
* Target interface.
* @param targetImplementation
* Target implementation.
*/
private void registerJarAPI(String targetInterface, String targetImplementation)
{
String err = "An error occured while registering the API.";
adm.registerJarAPI(targetInterface, targetImplementation, new AsyncCallback<JarOpErrorCode>()
{
@Override
public void onFailure(Throwable caught)
{
dialogs.showError(err);
}
@Override
public void onSuccess(JarOpErrorCode result)
{
if (result == JarOpErrorCode.SUCCESS)
{
refreshApiList();
dialogs.showInfo("Operation Completed", "The API was successfully added.", null);
}
else
{
dialogs.showError(err + " " + result);
}
}
});
}
/**
* Refresh the list of jars.
*
* @param preserveSelection
* <code>true</code> if current selection should be preserved.
*/
private void refreshJarList(boolean preserveSelection)
{
TaggedName selected = preserveSelection ? jarGridHandle.getSelectedSingle() : null;
adm.getRegisteredJars(new AsyncCallback<TaggedName[]>()
{
@Override
public void onFailure(Throwable caught)
{
dialogs.showError("Error loading registered libraries.");
}
@Override
public void onSuccess(TaggedName[] result)
{
jarGridHandle.clearGrid();
List<TaggedName> list = jarGridHandle.getDataProvider().getList();
if (list != null)
{
list.addAll(Arrays.asList(result));
}
refreshJarButtonsState();
refreshApiButtonsState();
if (selected != null && jarGridHandle.getDataProvider().getList().contains(selected))
{
jarGridHandle.getSelectionModel().setSelected(selected, true);
}
}
});
}
/**
* Refresh API list.
*/
private void refreshApiList()
{
String selectedJar = getSelectedJar();
if (selectedJar == null)
{
apisGridHandle.clearGrid();
return;
}
adm.getRegisteredJarAPIs(selectedJar, new AsyncCallback<TaggedName[]>()
{
@Override
public void onFailure(Throwable caught)
{
dialogs.showError("Error loading registered APIs.");
}
@Override
public void onSuccess(TaggedName[] result)
{
apisGridHandle.clearGrid();
if (result != null)
{
apisGridHandle.getDataProvider().getList().addAll(Arrays.asList(result));
}
}
});
}
/**
* Update the state of jar handling buttons.
*/
private void refreshJarButtonsState()
{
boolean selected = getSelectedJar() != null;
jarDereg.setEnabled(selected);
jarReload.setEnabled(selected);
jarEditHook.setEnabled(selected);
}
/**
* Update the state of API handling buttons.
*/
private void refreshApiButtonsState()
{
if (getSelectedJar() == null)
{
regAPI.setEnabled(false);
deregAPI.setEnabled(false);
}
else
{
regAPI.setEnabled(true);
deregAPI.setEnabled(getSelectedApi() != null);
}
}
/**
* Get selected jar.
*
* @return the name of the selected jar or <code>null</code> if there is
* no selected jar.
*/
private String getSelectedJar()
{
Set<TaggedName> jar = jarGridHandle.getSelected();
return jar.isEmpty() ? null : jar.iterator().next().get(0);
}
/**
* Get selected API.
*
* @return the TaggedName which represents the selected API or
* <code>null</code> if there is no selected API.
*/
private TaggedName getSelectedApi()
{
Set<TaggedName> api = apisGridHandle.getSelected();
return api.isEmpty() ? null : api.iterator().next();
}
/**
* Convert an array of strings to the array of TaggedNames objects which
* names match the specified strings.
*
* @param strings
* Source array of strings.
* @return array of TaggedNames objects which names match the specified
* strings.
*/
private TaggedName[] toTaggedNames(String[] strings)
{
TaggedName[] dest = new TaggedName[strings.length];
for (int i = 0; i < strings.length; i++)
{
dest[i] = new TaggedName(strings[i]);
}
return dest;
}
}