ItemBean.java
/*
* GovWay - A customizable API Gateway
* https://govway.org
*
* Copyright (c) 2005-2024 Link.it srl (https://link.it).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3, 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, see <http://www.gnu.org/licenses/>.
*
*/
package org.openspcoop2.web.lib.mvc.properties.beans;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.openspcoop2.core.mvc.properties.Conditions;
import org.openspcoop2.core.mvc.properties.Item;
import org.openspcoop2.core.mvc.properties.ItemValue;
import org.openspcoop2.core.mvc.properties.ItemValues;
import org.openspcoop2.core.mvc.properties.Property;
import org.openspcoop2.core.mvc.properties.constants.ItemType;
import org.openspcoop2.core.mvc.properties.provider.ExternalResources;
import org.openspcoop2.core.mvc.properties.provider.IProvider;
import org.openspcoop2.core.mvc.properties.provider.ProviderException;
import org.openspcoop2.core.mvc.properties.provider.ProviderInfo;
import org.openspcoop2.utils.regexp.RegularExpressionEngine;
import org.openspcoop2.web.lib.mvc.Costanti;
import org.openspcoop2.web.lib.mvc.DataElement;
import org.openspcoop2.web.lib.mvc.DataElementInfo;
import org.openspcoop2.web.lib.mvc.DataElementType;
import org.openspcoop2.web.lib.mvc.ServletUtils;
import org.openspcoop2.web.lib.mvc.byok.LockUtilities;
import org.openspcoop2.web.lib.mvc.properties.exception.UserInputValidationException;
/**
* Bean di tipo Item arricchito delle informazioni grafiche.
*
* @author Pintori Giuliano (pintori@link.it)
* @author $Author$
* @version $Rev$, $Date$
*
*/
public class ItemBean extends BaseItemBean<Item>{
public ItemBean(Item item, String name, IProvider provider) {
super(item, name, provider);
}
@Override
public void init(String value, ExternalResources externalResources) throws ProviderException {
/**Property saveProperty = this.getSaveProperty();*/
// caso value == null e non devo forzare con il valore letto dal db cerco un default
if(value == null) {
/**if(value == null && !saveProperty.isForce()) {*/
switch(this.getItem().getType()) {
case CHECKBOX:
this.value = this.getItem().getDefaultSelected() ? Costanti.CHECK_BOX_ENABLED : Costanti.CHECK_BOX_DISABLED;
break;
case HIDDEN:
case LOCK_HIDDEN:
this.value = this.getItem().getValue();
break;
case NUMBER:
case SELECT:
case TEXT:
case TEXTAREA:
case LOCK:
default:
if(StringUtils.isNotEmpty(this.getItem().getDefault())) {
this.value = this.getItem().getDefault();
}
else if(this.provider!=null) {
this.value = this.provider.getDefault(this.name, externalResources);
}
else {
this.value = null;
}
/**System.out.println("init default ["+this.name+"] value '"+this.value+"'");*/
break;
}
} else {
switch(this.getItem().getType()) {
case CHECKBOX:
this.value = this.getCheckBoxValue(value);
break;
case HIDDEN:
case NUMBER:
case SELECT:
case TEXT:
case TEXTAREA:
case LOCK:
case LOCK_HIDDEN:
default:
this.value = value;
/**System.out.println("init ["+this.name+"] value '"+this.value+"'");*/
break;
}
}
}
@Override
public DataElement toDataElement(ConfigBean config, Map<String, String> mapNameValue, ExternalResources externalResources,
LockUtilities lockUtilities) throws ProviderException {
if(this.provider!=null){
this.value = this.provider.dynamicUpdate(config.getListaItemSDK(), mapNameValue, this.getItem(), this.value, externalResources);
}
mapNameValue.put(this.name, this.value);
DataElement de = new DataElement();
de.setName(this.getName());
de.setLabel(this.getItem().getLabel());
/**de.setPostBack(this.getItem().getReloadOnChange());*/
de.setPostBack_viaPOST(true); // per la cifratura
de.setRequired(this.getItem().isRequired());
if(this.getItem().getNote()!=null && StringUtils.isNotEmpty(this.getItem().getNote())) {
de.setNote(this.getItem().getNote());
}
else if(this.provider!=null){
de.setNote(this.provider.getNote(this.name, this.value));
}
if(this.provider!=null){
addProviderInfo(de);
}
switch(this.getItem().getType()) {
case CHECKBOX:
de.setSelected(this.value);
de.setType(DataElementType.CHECKBOX);
break;
case HIDDEN:
de.setValue(this.value);
de.setType(DataElementType.HIDDEN);
break;
case NUMBER:
de.setValue(this.value);
de.setType(DataElementType.NUMBER);
de.setMinValue(this.getItem().getMin());
de.setMaxValue(this.getItem().getMax());
break;
case SELECT:
processSelectElement(de, externalResources);
break;
case TEXT:
de.setValue(this.value);
de.setType(DataElementType.TEXT_EDIT);
break;
case TEXTAREA:
de.setValue(this.value);
de.setType(DataElementType.TEXT_AREA);
if(this.getItem().getMax()!=null && this.getItem().getMax().intValue()>0) {
de.setRows(this.getItem().getMax().intValue());
}
else {
de.setRows(3);
}
break;
case LOCK_HIDDEN:
/**System.out.println("DATAELEMENT LOCK_HIDDEN ["+this.name+"] value '"+this.value+"'");*/
try {
lockUtilities.lockHidden(de, this.value);
}catch(Exception e) {
throw new ProviderException(e.getMessage(),e);
}
break;
case LOCK:
/**System.out.println("DATAELEMENT LOCK ["+this.name+"] value '"+this.value+"'");*/
try {
lockUtilities.lock(de, this.value);
}catch(Exception e) {
throw new ProviderException(e.getMessage(),e);
}
break;
default:
break;
}
return de;
}
private void addProviderInfo(DataElement de) throws ProviderException {
ProviderInfo pInfo = this.provider.getProviderInfo(this.name);
if(pInfo!=null) {
DataElementInfo dInfo = new DataElementInfo(pInfo.getHeaderFinestraModale()!=null ? pInfo.getHeaderFinestraModale() : this.getItem().getLabel());
dInfo.setBody(pInfo.getBody());
dInfo.setHeaderBody(pInfo.getHeaderBody());
dInfo.setListBody(pInfo.getListBody());
de.setInfo(dInfo);
}
}
private void processSelectElement(DataElement de, ExternalResources externalResources) throws ProviderException {
de.setSelected(this.value);
de.setType(DataElementType.SELECT);
List<String> valuesList = new ArrayList<>();
List<String> labelsList = new ArrayList<>();
ItemValues values = this.getItem().getValues();
if(values!=null && values.sizeValueList()>0) {
for (ItemValue itemValue : values.getValueList()) {
valuesList.add(itemValue.getValue());
labelsList.add(itemValue.getLabel() != null ? itemValue.getLabel() : itemValue.getValue());
}
}
else if(this.provider!=null){
List<String> tmp = this.provider.getValues(this.name, externalResources);
if(tmp!=null && !tmp.isEmpty()) {
valuesList.addAll(tmp);
}
tmp = this.provider.getLabels(this.name, externalResources);
if(tmp!=null && !tmp.isEmpty()) {
labelsList.addAll(tmp);
}
}
de.setValues(valuesList);
de.setLabels(labelsList);
}
@Override
public void setValueFromRequest(String parameterValue, ExternalResources externalResources, LockUtilities lockUtilities) throws ProviderException {
if(parameterValue == null && !this.isOldVisible()) {
setDefaultValueFromRequest(externalResources);
}
else {
switch(this.getItem().getType()) {
case HIDDEN:
case LOCK_HIDDEN:
this.value = (parameterValue == null && this.getSaveProperty().isForce()) ? this.getItem().getValue() : parameterValue;
break;
case CHECKBOX:
case NUMBER:
case SELECT:
case TEXT:
case TEXTAREA:
case LOCK:
default:
/**System.out.println("setValueFromRequest ["+this.name+"] value '"+parameterValue+"'");*/
this.value = parameterValue;
break;
}
}
if(ItemType.LOCK.equals(this.getItem().getType()) ||
ItemType.LOCK_HIDDEN.equals(this.getItem().getType())) {
try {
this.value = lockUtilities.getDriverBYOKUtilities().wrap(this.value);
}catch(Exception e) {
throw new ProviderException(e.getMessage(),e);
}
}
/**System.out.println("ITEM: ["+this.getName()+"] REQVALUE ["+parameterValue+"] NEW VALUE["+this.getValue()+"]");*/
}
private void setDefaultValueFromRequest(ExternalResources externalResources) throws ProviderException {
switch(this.getItem().getType()) {
case CHECKBOX:
this.value = this.getItem().getDefaultSelected() ? Costanti.CHECK_BOX_ENABLED : Costanti.CHECK_BOX_DISABLED;
break;
case HIDDEN:
case LOCK_HIDDEN:
this.value = this.getItem().getValue();
break;
case NUMBER:
case SELECT:
case TEXT:
case TEXTAREA:
case LOCK:
default:
if(StringUtils.isNotEmpty(this.getItem().getDefault())) {
this.value = this.getItem().getDefault();
}
else if(this.provider!=null) {
this.value = this.provider.getDefault(this.name, externalResources);
}
else {
this.value = null;
}
/**System.out.println("setDefaultValueFromRequest ["+this.name+"] value '"+this.value+"'");*/
break;
}
}
@Override
public Property getSaveProperty() {
return this.getItem().getProperty();
}
@Override
public String getPropertyValue() {
switch (this.getItem().getType()) {
case CHECKBOX:
return getCheckboxPropertyValue();
case HIDDEN:
case LOCK_HIDDEN:
return this.getSaveProperty().isForce() ? this.getItem().getValue() : this.value;
case NUMBER:
case SELECT:
case TEXT:
case TEXTAREA:
case LOCK:
default:
/**if(ItemType.LOCK.equals(this.getItem().getType())) {
System.out.println("getPropertyValue ["+this.name+"] value '"+this.value+"'");
}*/
return this.value;
}
}
private String getCheckboxPropertyValue() {
String valueToCheck = null;
if(ServletUtils.isCheckBoxEnabled(this.value)) {
valueToCheck = this.getSaveProperty().getSelectedValue() != null ? this.getSaveProperty().getSelectedValue() : null;
} else {
valueToCheck = this.getSaveProperty().getUnselectedValue() != null ? this.getSaveProperty().getUnselectedValue() :null;
}
if(valueToCheck == null) {
valueToCheck = ServletUtils.isCheckBoxEnabled(this.value) ? "true" : "false";
}
return valueToCheck;
}
public String getCheckBoxValue(String value) {
String valueToCheck = null;
if(this.getItem().getProperty().getSelectedValue() != null &&
value.equals(this.getSaveProperty().getSelectedValue())) {
valueToCheck = Costanti.CHECK_BOX_ENABLED;
}
if(valueToCheck == null &&
this.getItem().getProperty().getUnselectedValue() != null &&
value.equals(this.getSaveProperty().getUnselectedValue())) {
valueToCheck = Costanti.CHECK_BOX_DISABLED;
}
if(valueToCheck == null){
valueToCheck = ServletUtils.isCheckBoxEnabled(value) ? Costanti.CHECK_BOX_ENABLED : Costanti.CHECK_BOX_DISABLED;
}
/** if(valueToCheck == null){
// valueToCheck = this.getItem().getDefaultSelected() ? Costanti.CHECK_BOX_ENABLED : Costanti.CHECK_BOX_DISABLED;
// }*/
return valueToCheck;
}
@Override
public Conditions getConditions() {
return this.item.getConditions();
}
@Override
public ItemType getItemType() {
return this.item.getType();
}
@Override
public String getLabel() {
return this.item.getLabel();
}
@Override
public void validate(ExternalResources externalResources) throws UserInputValidationException {
String itemValue = this.getPropertyValue(); // valore della property
Property saveProperty = this.getSaveProperty();
/**System.out.println("VALIDATE -> Item: Name ["+this.getName()+"] Value ["+itemValue+"]...");*/
// un elemento e' salvabile se non e' visible o e' da forzare
boolean save =
(saveProperty != null)
&&
(saveProperty.isForce()
||
(
this.isVisible()
// in teoria gli hidden visibili dovrebbe essere salvabili
/**&&
!org.openspcoop2.core.mvc.properties.constants.ItemType.HIDDEN.equals(this.getItemType())*/
)
);
/**System.out.println("VALIDATE -> Item: Name ["+this.getName()+"] Value ["+itemValue+"] Validazione Abilitata ["+save+"]");*/
// validazione solo per gli elementi da salvare
if(save) {
String prefixIlCampo = "Il Campo "+this.getLabel();
// 1. Validazione campi obbligatori
if(this.getItem().isRequired() && StringUtils.isEmpty(itemValue)) {
throw new UserInputValidationException(prefixIlCampo+" è obbligatorio");
}
// 2. validazione generica basata sul tipo
switch(this.getItem().getType()) {
case NUMBER:
if(StringUtils.isNotEmpty(itemValue)) {
boolean numeric = NumberUtils.isParsable(itemValue);
if(!numeric) {
throw new UserInputValidationException(prefixIlCampo+" non contiene un valore di tipo numerico");
}
int number = -1;
try {
number = Integer.valueOf(itemValue);
}catch(Exception e) {
throw new UserInputValidationException(prefixIlCampo+" non contiene un valore di tipo numerico");
}
if(this.getItem().getMin()!=null &&
number<this.getItem().getMin().intValue()) {
throw new UserInputValidationException(prefixIlCampo+" deve contenere un valore >= "+this.getItem().getMin().intValue());
}
if(this.getItem().getMax()!=null &&
number>this.getItem().getMax().intValue()) {
throw new UserInputValidationException(prefixIlCampo+" deve contenere un valore <= "+this.getItem().getMax().intValue());
}
}
break;
case SELECT:
if(StringUtils.isNotEmpty(itemValue)) {
ItemValues values = this.getItem().getValues();
boolean found = false;
if(values!=null && values.sizeValueList()>0) {
for (ItemValue selectItemValue : values.getValueList()) {
if(selectItemValue.getValue().equals(itemValue)) {
found = true;
break;
}
}
}
else {
try {
List<String> tmp = this.provider.getValues(this.name, externalResources);
if(tmp.contains(itemValue)) {
found = true;
}
}catch(Exception e) {
throw new UserInputValidationException("Errore durante la validazione del Campo "+this.getLabel()+": "+e.getMessage(),e);
}
}
if(!found)
throw new UserInputValidationException(prefixIlCampo+" contiene un valore non previsto");
}
break;
case TEXT:
case TEXTAREA:
if(itemValue!=null && itemValue.length()>4000) {
throw new UserInputValidationException(prefixIlCampo+" non deve contenere più di 4000 caratteri");
}
if(itemValue!=null && (itemValue.startsWith(" ") || itemValue.startsWith("\t"))) {
throw new UserInputValidationException("Il valore inserito nel Campo "+this.getLabel()+" non può iniziare con uno spazio");
}
if(itemValue!=null && (itemValue.endsWith(" ") || itemValue.endsWith("\t"))) {
throw new UserInputValidationException("Il valore inserito nel Campo "+this.getLabel()+" non può terminare con uno spazio");
}
break;
case LOCK:
case LOCK_HIDDEN:
case CHECKBOX:
case HIDDEN:
break;
}
// 3. validazione basata sul pattern
if(this.getItem().getValidation() != null && StringUtils.isNotEmpty(itemValue)) {
try {
boolean match = RegularExpressionEngine.isMatch(itemValue, this.getItem().getValidation());
if(!match)
throw new UserInputValidationException(prefixIlCampo+" non rispetta il pattern di validazione previsto ("+this.getItem().getValidation()+")");
}catch(UserInputValidationException e) {
throw e;
}catch(Exception e) {
throw new UserInputValidationException("Impossibile validare il campo "+this.getLabel()+" secondo il pattern previsto nella configurazione ("+this.getItem().getValidation()+")",e);
}
}
}
}
}