IDEMPIERE-5688 Enhancement to WindowValidator API (#1799)

This commit is contained in:
hengsin 2023-04-28 19:16:56 +08:00 committed by GitHub
parent 7bd5e579ce
commit 60c0bf681f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 198 additions and 35 deletions

View File

@ -182,6 +182,9 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements
*/
private static final String ON_DEFER_SET_DETAILPANE_SELECTION_EVENT = "onDeferSetDetailpaneSelection";
/** ProcessModalDialog attribute to store reference for post process execution callback */
private static final String PROCESS_POST_CALLBACK_ATTRIBUTE = "processPostCallbackAttribute";
private static final CLogger logger;
static
@ -1476,6 +1479,13 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements
{
statusBar.setStatusLine(s, b, logs);
}
if (dialog.getAttribute(PROCESS_POST_CALLBACK_ATTRIBUTE) != null && dialog.getAttribute(PROCESS_POST_CALLBACK_ATTRIBUTE) instanceof Callback<?>)
{
@SuppressWarnings("unchecked")
Callback<Boolean> callback = (Callback<Boolean>) dialog.getAttribute(PROCESS_POST_CALLBACK_ATTRIBUTE);
callback.onCallback(dialog.getProcessInfo() != null && !dialog.getProcessInfo().isError());
}
}
else if (ADTabpanel.ON_DYNAMIC_DISPLAY_EVENT.equals(event.getName()))
{
@ -3639,9 +3649,29 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements
if (!win.isStartProcess()) {
return;
}
boolean startWOasking = true;
boolean isProcessMandatory = true;
executeButtonProcess(wButton, startWOasking, table_ID, recordIdParam, isProcessMandatory);
final Callback<Boolean> postCallback = new Callback<Boolean>() {
@Override
public void onCallback(Boolean result) {
if (result) {
WindowValidatorEvent event = new WindowValidatorEvent(adwindow, WindowValidatorEventType.AFTER_DOC_ACTION.getName());
WindowValidatorManager.getInstance().fireWindowValidatorEvent(event, null);
}
}
};
Callback<Boolean> preCallback = new Callback<Boolean>() {
@Override
public void onCallback(Boolean result) {
if (result) {
boolean startWOasking = true;
boolean isProcessMandatory = true;
executeButtonProcess(wButton, startWOasking, table_ID, recordIdParam, isProcessMandatory, postCallback);
}
}
};
WindowValidatorEvent validatorEvent = new WindowValidatorEvent(adwindow, WindowValidatorEventType.BEFORE_DOC_ACTION.getName(), wButton);
WindowValidatorManager.getInstance().fireWindowValidatorEvent(validatorEvent, preCallback);
}
});
getComponent().getParent().appendChild(win);
@ -3768,8 +3798,27 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements
return;
} // Posted
executeButtonProcess(wButton, startWOasking, table_ID, record_ID,
isProcessMandatory);
final int finalRecordId = record_ID;
final Callback<Boolean> postCallback = new Callback<Boolean>() {
@Override
public void onCallback(Boolean result) {
if (result) {
WindowValidatorEvent event = new WindowValidatorEvent(adwindow, WindowValidatorEventType.AFTER_PROCESS.getName());
WindowValidatorManager.getInstance().fireWindowValidatorEvent(event, null);
}
}
};
Callback<Boolean> preCallback = new Callback<Boolean>() {
@Override
public void onCallback(Boolean result) {
if (result) {
executeButtonProcess(wButton, startWOasking, table_ID, finalRecordId, isProcessMandatory, postCallback);
}
}
};
WindowValidatorEvent validatorEvent = new WindowValidatorEvent(adwindow, WindowValidatorEventType.BEFORE_PROCESS.getName(), wButton);
WindowValidatorManager.getInstance().fireWindowValidatorEvent(validatorEvent, preCallback);
} // actionButton
/**
@ -3865,10 +3914,11 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements
* @param table_ID
* @param record_ID
* @param isProcessMandatory
* @param callback
*/
public void executeButtonProcess(final IProcessButton wButton,
final boolean startWOasking, final int table_ID, final int record_ID,
boolean isProcessMandatory) {
boolean isProcessMandatory, Callback<Boolean> callback) {
/**
* Start Process ----
*/
@ -3896,7 +3946,7 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements
if (wButton.getInfoWindow_ID() > 0)
executionButtonInfoWindow0(wButton);
else
executeButtonProcess0(wButton, startWOasking, table_ID, record_ID);
executeButtonProcess0(wButton, startWOasking, table_ID, record_ID, callback);
}
}
});
@ -3906,7 +3956,7 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements
if (wButton.getInfoWindow_ID() > 0)
executionButtonInfoWindow0(wButton);
else
executeButtonProcess0(wButton, startWOasking, table_ID, record_ID);
executeButtonProcess0(wButton, startWOasking, table_ID, record_ID, callback);
}
}
@ -3916,9 +3966,10 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements
* @param startWOasking
* @param table_ID
* @param record_ID
* @param callback
*/
private void executeButtonProcess0(final IProcessButton wButton,
boolean startWOasking, int table_ID, int record_ID) {
boolean startWOasking, int table_ID, int record_ID, Callback<Boolean> callback) {
// call form
MProcess pr = new MProcess(ctx, wButton.getProcess_ID(), null);
int adFormID = pr.getAD_Form_ID();
@ -4001,6 +4052,8 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements
{
dialog.setBorder("normal");
getComponent().getParent().appendChild(dialog);
if (callback != null)
dialog.setAttribute(PROCESS_POST_CALLBACK_ATTRIBUTE, callback);
if (ClientInfo.isMobile())
{
dialog.doHighlighted();
@ -4012,6 +4065,21 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements
}
Executions.schedule(getComponent().getDesktop(), e -> dialog.focus(), new Event("onPostShowProcessModalDialog"));
}
else if (callback != null)
{
if (dialog.isCancel())
{
callback.onCallback(Boolean.FALSE);
}
else
{
pi = dialog.getProcessInfo();
if (pi == null || pi.isError())
callback.onCallback(Boolean.FALSE);
else
callback.onCallback(Boolean.TRUE);
}
}
}
}

View File

@ -27,6 +27,9 @@ package org.adempiere.webui.adwindow;
import java.util.List;
import org.adempiere.util.Callback;
import org.adempiere.webui.adwindow.validator.WindowValidatorEvent;
import org.adempiere.webui.adwindow.validator.WindowValidatorEventType;
import org.adempiere.webui.adwindow.validator.WindowValidatorManager;
import org.adempiere.webui.component.Menupopup;
import org.adempiere.webui.editor.IProcessButton;
import org.adempiere.webui.editor.WButtonEditor;
@ -140,7 +143,27 @@ public class ProcessButtonPopup extends Menupopup implements EventListener<Event
GridTab gridTab = pb.getADTabpanel().getGridTab();
ADWindow adwindow = ADWindow.get(gridTab.getWindowNo());
ADWindowContent windowContent = adwindow.getADWindowContent();
windowContent.executeButtonProcess(pb, true, gridTab.getAD_Table_ID(), gridTab.getRecord_ID(), true);
final Callback<Boolean> postCallback = new Callback<Boolean>() {
@Override
public void onCallback(Boolean result) {
if (result) {
WindowValidatorEvent event = new WindowValidatorEvent(adwindow, WindowValidatorEventType.AFTER_DOC_ACTION.getName());
WindowValidatorManager.getInstance().fireWindowValidatorEvent(event, null);
}
}
};
Callback<Boolean> preCallback = new Callback<Boolean>() {
@Override
public void onCallback(Boolean result) {
if (result) {
windowContent.executeButtonProcess(pb, true, gridTab.getAD_Table_ID(), gridTab.getRecord_ID(), true, postCallback);
}
}
};
WindowValidatorEvent validatorEvent = new WindowValidatorEvent(adwindow, WindowValidatorEventType.BEFORE_DOC_ACTION.getName(), pb);
WindowValidatorManager.getInstance().fireWindowValidatorEvent(validatorEvent, preCallback);
}
}
});

View File

@ -35,14 +35,26 @@ public class WindowValidatorEvent {
private ADWindow window;
/** Event name **/
private String name;
/** Event data **/
private Object data;
/**
* @param window
* @param name
*/
public WindowValidatorEvent(ADWindow window, String name) {
this(window, name, null);
}
/**
* @param window
* @param name
* @param data
*/
public WindowValidatorEvent(ADWindow window, String name, Object data) {
this.window = window;
this.name = name;
this.data = data;
}
/**
@ -58,4 +70,19 @@ public class WindowValidatorEvent {
public String getName() {
return this.name;
}
/**
* @return Event data
*/
public Object getData() {
return data;
}
/**
* Set event data
* @param data
*/
public void setData(Object data) {
this.data = data;
}
}

View File

@ -41,7 +41,11 @@ public enum WindowValidatorEventType {
BEFORE_SAVE("beforeSave"),
AFTER_SAVE("afterSave"),
BEFORE_COPY("beforeCopy"),
AFTER_COPY("afterCopy");
AFTER_COPY("afterCopy"),
BEFORE_DOC_ACTION("beforeDocAction"),
AFTER_DOC_ACTION("afterDocAction"),
BEFORE_PROCESS("beforeProcess"),
AFTER_PROCESS("afterProcess");
/** Event name **/
private String name;

View File

@ -31,6 +31,7 @@ import java.util.Map;
import org.adempiere.util.Callback;
import org.adempiere.webui.adwindow.ADWindow;
import org.compiere.util.Util;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
@ -50,10 +51,10 @@ public class WindowValidatorManager implements BundleActivator, ServiceTrackerCu
/** {@link BundleContext} instance **/
private BundleContext context;
/** AD_Window_UU:List<WindowValidator> **/
private Map<String, List<WindowValidator>> validatorMap = new HashMap<String, List<WindowValidator>>();
/** AD_Window_UU:List<WindowValidatorEntry> **/
private Map<String, List<WindowValidatorEntry>> validatorMap = new HashMap<>();
/** WindowValidator for all AD Window **/
private List<WindowValidator> globalValidators = new ArrayList<WindowValidator>();
private List<WindowValidatorEntry> globalValidators = new ArrayList<>();
/** WindowValidator osgi service tracker **/
private ServiceTracker<WindowValidator, WindowValidator> serviceTracker;
@ -67,16 +68,24 @@ public class WindowValidatorManager implements BundleActivator, ServiceTrackerCu
if (obj instanceof String) {
String uuid = (String) reference.getProperty("AD_Window_UU");
String events = (String) reference.getProperty("events");
if (uuid == null || "*".equals(uuid)) {
globalValidators.add(service);
String[] validatorEvents = null;
if (!Util.isEmpty(events, true) && !"*".equals(events.trim())) {
validatorEvents = events.split("[,]");
}
WindowValidatorEntry entry = new WindowValidatorEntry(service, validatorEvents);
globalValidators.add(entry);
return service;
}
addService(service, uuid);
addService(service, uuid, events);
}
else if (obj instanceof String []) {
String[] uuids = (String []) reference.getProperty("AD_Window_UU");
for (String uuid : uuids)
addService(service, uuid);
String events = (String) reference.getProperty("events");
for (String uuid : uuids) {
addService(service, uuid, events);
}
}
return service;
}
@ -85,14 +94,20 @@ public class WindowValidatorManager implements BundleActivator, ServiceTrackerCu
* Add {@link WindowValidator} service for an AD Window
* @param service
* @param uuid AD_Window_UU
* @param events
*/
protected void addService(WindowValidator service, String uuid) {
List<WindowValidator> list = validatorMap.get(uuid);
protected void addService(WindowValidator service, String uuid, String events) {
List<WindowValidatorEntry> list = validatorMap.get(uuid);
if (list == null) {
list = new ArrayList<WindowValidator>();
list = new ArrayList<WindowValidatorEntry>();
validatorMap.put(uuid, list);
}
list.add(service);
String[] validatorEvents = null;
if (!Util.isEmpty(events, true) && !"*".equals(events.trim())) {
validatorEvents = events.split("[,]");
}
WindowValidatorEntry entry = new WindowValidatorEntry(service, validatorEvents);
list.add(entry);
}
@Override
@ -109,7 +124,7 @@ public class WindowValidatorManager implements BundleActivator, ServiceTrackerCu
if (obj instanceof String) {
String uuid = (String) reference.getProperty("AD_Window_UU");
if (uuid == null || "*".equals(uuid)) {
globalValidators.remove(service);
globalValidators.removeIf(i -> i.validator.equals(service));
}
else
removeService(service, uuid);
@ -127,9 +142,9 @@ public class WindowValidatorManager implements BundleActivator, ServiceTrackerCu
* @param uuid
*/
protected void removeService(WindowValidator service, String uuid) {
List<WindowValidator> list = validatorMap.get(uuid);
List<WindowValidatorEntry> list = validatorMap.get(uuid);
if (list != null) {
list.remove(service);
list.removeIf(i -> i.validator.equals(service));
}
}
@ -171,21 +186,36 @@ public class WindowValidatorManager implements BundleActivator, ServiceTrackerCu
public void fireWindowValidatorEvent(WindowValidatorEvent event, Callback<Boolean> callback) {
ADWindow window = event.getWindow();
String uuid = window.getAD_Window_UU();
List<WindowValidator> list = validatorMap.get(uuid);
List<WindowValidatorEntry> list = validatorMap.get(uuid);
int listSize = list != null ? list.size() : 0;
WindowValidator[] validators = new WindowValidator[listSize+globalValidators.size()];
int index = -1;
List<WindowValidator> validators = new ArrayList<>();
if (listSize > 0) {
for(WindowValidator validator : list) {
index++;
validators[index] = validator;
for(WindowValidatorEntry validatorEntry : list) {
if (validatorEntry.events == null || validatorEntry.events.length == 0) {
validators.add(validatorEntry.validator);
} else {
for(String e : validatorEntry.events) {
if (e.trim().equalsIgnoreCase(event.getName())) {
validators.add(validatorEntry.validator);
break;
}
}
}
}
}
for(WindowValidator validator : globalValidators) {
index++;
validators[index] = validator;
for(WindowValidatorEntry validatorEntry : globalValidators) {
if (validatorEntry.events == null || validatorEntry.events.length == 0) {
validators.add(validatorEntry.validator);
} else {
for(String e : validatorEntry.events) {
if (e.trim().equalsIgnoreCase(event.getName())) {
validators.add(validatorEntry.validator);
break;
}
}
}
}
ChainCallback chain = new ChainCallback(event, validators, callback);
ChainCallback chain = new ChainCallback(event, validators.toArray(new WindowValidator[0]), callback);
chain.start();
}
@ -238,4 +268,15 @@ public class WindowValidatorManager implements BundleActivator, ServiceTrackerCu
}
}
private static class WindowValidatorEntry {
private WindowValidator validator;
private String[] events;
private WindowValidatorEntry(WindowValidator validator, String[] events) {
super();
this.validator = validator;
this.events = events;
}
}
}