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"; 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; private static final CLogger logger;
static static
@ -1476,6 +1479,13 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements
{ {
statusBar.setStatusLine(s, b, logs); 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())) else if (ADTabpanel.ON_DYNAMIC_DISPLAY_EVENT.equals(event.getName()))
{ {
@ -3639,9 +3649,29 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements
if (!win.isStartProcess()) { if (!win.isStartProcess()) {
return; return;
} }
boolean startWOasking = true;
boolean isProcessMandatory = true; final Callback<Boolean> postCallback = new Callback<Boolean>() {
executeButtonProcess(wButton, startWOasking, table_ID, recordIdParam, isProcessMandatory); @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); getComponent().getParent().appendChild(win);
@ -3768,8 +3798,27 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements
return; return;
} // Posted } // Posted
executeButtonProcess(wButton, startWOasking, table_ID, record_ID, final int finalRecordId = record_ID;
isProcessMandatory); 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 } // actionButton
/** /**
@ -3865,10 +3914,11 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements
* @param table_ID * @param table_ID
* @param record_ID * @param record_ID
* @param isProcessMandatory * @param isProcessMandatory
* @param callback
*/ */
public void executeButtonProcess(final IProcessButton wButton, public void executeButtonProcess(final IProcessButton wButton,
final boolean startWOasking, final int table_ID, final int record_ID, final boolean startWOasking, final int table_ID, final int record_ID,
boolean isProcessMandatory) { boolean isProcessMandatory, Callback<Boolean> callback) {
/** /**
* Start Process ---- * Start Process ----
*/ */
@ -3896,7 +3946,7 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements
if (wButton.getInfoWindow_ID() > 0) if (wButton.getInfoWindow_ID() > 0)
executionButtonInfoWindow0(wButton); executionButtonInfoWindow0(wButton);
else 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) if (wButton.getInfoWindow_ID() > 0)
executionButtonInfoWindow0(wButton); executionButtonInfoWindow0(wButton);
else 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 startWOasking
* @param table_ID * @param table_ID
* @param record_ID * @param record_ID
* @param callback
*/ */
private void executeButtonProcess0(final IProcessButton wButton, 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 // call form
MProcess pr = new MProcess(ctx, wButton.getProcess_ID(), null); MProcess pr = new MProcess(ctx, wButton.getProcess_ID(), null);
int adFormID = pr.getAD_Form_ID(); int adFormID = pr.getAD_Form_ID();
@ -4001,6 +4052,8 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements
{ {
dialog.setBorder("normal"); dialog.setBorder("normal");
getComponent().getParent().appendChild(dialog); getComponent().getParent().appendChild(dialog);
if (callback != null)
dialog.setAttribute(PROCESS_POST_CALLBACK_ATTRIBUTE, callback);
if (ClientInfo.isMobile()) if (ClientInfo.isMobile())
{ {
dialog.doHighlighted(); dialog.doHighlighted();
@ -4012,6 +4065,21 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements
} }
Executions.schedule(getComponent().getDesktop(), e -> dialog.focus(), new Event("onPostShowProcessModalDialog")); 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 java.util.List;
import org.adempiere.util.Callback; 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.component.Menupopup;
import org.adempiere.webui.editor.IProcessButton; import org.adempiere.webui.editor.IProcessButton;
import org.adempiere.webui.editor.WButtonEditor; import org.adempiere.webui.editor.WButtonEditor;
@ -140,7 +143,27 @@ public class ProcessButtonPopup extends Menupopup implements EventListener<Event
GridTab gridTab = pb.getADTabpanel().getGridTab(); GridTab gridTab = pb.getADTabpanel().getGridTab();
ADWindow adwindow = ADWindow.get(gridTab.getWindowNo()); ADWindow adwindow = ADWindow.get(gridTab.getWindowNo());
ADWindowContent windowContent = adwindow.getADWindowContent(); 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; private ADWindow window;
/** Event name **/ /** Event name **/
private String name; private String name;
/** Event data **/
private Object data;
/** /**
* @param window * @param window
* @param name * @param name
*/ */
public WindowValidatorEvent(ADWindow window, String 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.window = window;
this.name = name; this.name = name;
this.data = data;
} }
/** /**
@ -58,4 +70,19 @@ public class WindowValidatorEvent {
public String getName() { public String getName() {
return this.name; 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"), BEFORE_SAVE("beforeSave"),
AFTER_SAVE("afterSave"), AFTER_SAVE("afterSave"),
BEFORE_COPY("beforeCopy"), 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 **/ /** Event name **/
private String name; private String name;

View File

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