IDEMPIERE-3220:read-only field can edit by development tool
This commit is contained in:
parent
67d46b541a
commit
ec1d6bdc00
|
@ -304,6 +304,8 @@ public class SessionContextListener implements ExecutionInit,
|
||||||
if(Executions.getCurrent()==null)
|
if(Executions.getCurrent()==null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
desktop.addListener(new ValidateReadonlyComponent());
|
||||||
|
|
||||||
if (ServerContext.getCurrentInstance().isEmpty() || !isContextValid())
|
if (ServerContext.getCurrentInstance().isEmpty() || !isContextValid())
|
||||||
{
|
{
|
||||||
setupExecutionContextFromSession(Executions.getCurrent());
|
setupExecutionContextFromSession(Executions.getCurrent());
|
||||||
|
|
|
@ -0,0 +1,116 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* Product: iDempiere ERP & CRM Smart Business Solution *
|
||||||
|
* Copyright (C) 2014 T.G.I. *
|
||||||
|
* This program is free software; you can redistribute it and/or modify it *
|
||||||
|
* under the terms version 2 of the GNU General Public License as published *
|
||||||
|
* by the Free Software Foundation. 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 General Public License for more details. *
|
||||||
|
* You should have received a copy of the GNU General Public License along *
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc., *
|
||||||
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
package org.adempiere.webui.session;
|
||||||
|
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
import org.compiere.util.CLogger;
|
||||||
|
import org.zkoss.zk.au.AuRequest;
|
||||||
|
import org.zkoss.zk.au.AuService;
|
||||||
|
import org.zkoss.zk.ui.Component;
|
||||||
|
import org.zkoss.zk.ui.WrongValueException;
|
||||||
|
import org.zkoss.zk.ui.event.Events;
|
||||||
|
import org.zkoss.zk.ui.ext.Disable;
|
||||||
|
import org.zkoss.zk.ui.ext.Readonly;
|
||||||
|
import org.zkoss.zul.Button;
|
||||||
|
import org.zkoss.zul.Checkbox;
|
||||||
|
import org.zkoss.zul.Combobox;
|
||||||
|
import org.zkoss.zul.impl.InputElement;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* this service is interception into desktop process,
|
||||||
|
* it will denied request to modify a readonly file or action on readonly button
|
||||||
|
* @author hieplq
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ValidateReadonlyComponent implements AuService {
|
||||||
|
private static CLogger log = CLogger.getCLogger (ValidateReadonlyComponent.class);
|
||||||
|
/**
|
||||||
|
* throw WrongValueException when denied request, other false
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean service(AuRequest request, boolean everError) {
|
||||||
|
String cmd = request.getCommand();
|
||||||
|
|
||||||
|
// event is reason change value of component
|
||||||
|
boolean considerEvent = Events.ON_CHANGE.equals(cmd) || Events.ON_CHECK.equals(cmd) ||
|
||||||
|
Events.ON_SELECT.equals(cmd) || Events.ON_OPEN.equals(cmd) ||
|
||||||
|
Events.ON_CLICK.equals(cmd) || Events.ON_DOUBLE_CLICK.equals(cmd) || Events.ON_OK.equals(cmd) || Events.ON_UPLOAD.equals(cmd);
|
||||||
|
|
||||||
|
if (!considerEvent){
|
||||||
|
return false; // don't denied
|
||||||
|
}
|
||||||
|
|
||||||
|
Component comp = request.getComponent();
|
||||||
|
|
||||||
|
// get necessary interface
|
||||||
|
Disable iDisable = null;
|
||||||
|
Readonly iReadonly = null;
|
||||||
|
|
||||||
|
if (comp instanceof Disable){
|
||||||
|
iDisable = (Disable)comp;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (comp instanceof Readonly){
|
||||||
|
iReadonly = (Readonly)comp;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isCannotEdit = (iDisable != null && iDisable.isDisabled()) || (iReadonly != null && iReadonly.isReadonly());
|
||||||
|
|
||||||
|
// don't care editable component
|
||||||
|
if (!isCannotEdit){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// detect kind of component raise event
|
||||||
|
InputElement inputComp = null;
|
||||||
|
Checkbox checkbox = null;
|
||||||
|
Combobox comb = null;
|
||||||
|
Button button = null;
|
||||||
|
|
||||||
|
if (comp instanceof Combobox){// have to check before InputElement
|
||||||
|
comb = (Combobox)comp;
|
||||||
|
}if (comp instanceof InputElement){
|
||||||
|
inputComp = (InputElement)comp;// textbox, datebox, numberbox,...
|
||||||
|
}else if (comp instanceof Checkbox){
|
||||||
|
checkbox = (Checkbox)comp;
|
||||||
|
}if (comp instanceof Button){// have to check latest
|
||||||
|
button = (Button)comp;
|
||||||
|
}else {//HtmlBasedComponent
|
||||||
|
log.log(Level.SEVERE, String.format("Consider to denied event of control %1$s when it's readonly on event %2$s", comp.getClass(), cmd));
|
||||||
|
return false;// just log to investigate don't lock process
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (isCannotEdit){
|
||||||
|
boolean editing = (inputComp != null && Events.ON_CHANGE.equals(cmd)) ||
|
||||||
|
(checkbox != null && Events.ON_CHECK.equals(cmd)) ||
|
||||||
|
(comb != null && (Events.ON_CHANGE.equals(cmd) || Events.ON_SELECT.equals(cmd) || Events.ON_OPEN.equals(cmd))) ||
|
||||||
|
(button != null && (Events.ON_CLICK.equals(cmd) || Events.ON_OK.equals(cmd) || Events.ON_UPLOAD.equals(cmd)));;
|
||||||
|
|
||||||
|
// for combobox each change have both event onchange and onselect, so will have dupplicate message
|
||||||
|
// dupplicate is acceptable for hack guy
|
||||||
|
if (editing){
|
||||||
|
comp.invalidate();
|
||||||
|
throw new WrongValueException ("I know you. Don't try to hack me");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue