BaseBean.java

  1. /*
  2.  * GovWay - A customizable API Gateway
  3.  * https://govway.org
  4.  *
  5.  * Copyright (c) 2005-2025 Link.it srl (https://link.it).
  6.  *
  7.  * This program is free software: you can redistribute it and/or modify
  8.  * it under the terms of the GNU General Public License version 3, as published by
  9.  * the Free Software Foundation.
  10.  *
  11.  * This program is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  * GNU General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU General Public License
  17.  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  18.  *
  19.  */
  20. package org.openspcoop2.utils.beans;

  21. import java.io.ByteArrayOutputStream;
  22. import java.io.OutputStream;
  23. import java.io.Serializable;
  24. import java.lang.reflect.InvocationTargetException;
  25. import java.lang.reflect.Method;
  26. import java.util.ArrayList;
  27. import java.util.List;

  28. import javax.xml.bind.annotation.XmlTransient;

  29. import org.apache.commons.lang.builder.ReflectionToStringBuilder;
  30. import org.apache.commons.lang.builder.ToStringStyle;
  31. import org.openspcoop2.utils.UtilsException;
  32. import org.openspcoop2.utils.UtilsRuntimeException;
  33. import org.openspcoop2.utils.date.DateUtils;
  34. import org.openspcoop2.utils.serialization.ISerializer;
  35. import org.openspcoop2.utils.serialization.JavaSerializer;
  36. import org.openspcoop2.utils.serialization.SerializationConfig;
  37. import org.openspcoop2.utils.serialization.SerializationFactory;
  38. import org.openspcoop2.utils.serialization.SerializationFactory.SERIALIZATION_TYPE;
  39. import org.openspcoop2.utils.xml.JaxbUtils;

  40. /**
  41.  * BaseBean
  42.  *
  43.  * @author Poli Andrea (apoli@link.it)
  44.  * @author $Author$
  45.  * @version $Rev$, $Date$
  46.  */
  47. @XmlTransient
  48. public abstract class BaseBean implements Serializable {

  49.     private static final long serialVersionUID = 1L;
  50.    
  51.     private static final String TO_STRING_METHOD = "toString";
  52.    
  53.     protected BaseBean(){
  54.         // nop
  55.     }
  56.    
  57.     private void logExceptionStackTrace(Exception e) {
  58.         e.printStackTrace(System.err);
  59.     }
  60.    
  61.     /* ********** GENERIC UTILS ********* */
  62.    
  63.     private Object getFieldValue(String fieldName,Object object) throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException{
  64.         Class<?> c = getClass();
  65.        
  66.         StringBuilder methodName = new StringBuilder("get");
  67.         String firstChar = fieldName.charAt(0)+"";
  68.         methodName.append(firstChar.toUpperCase());
  69.         if(fieldName.length()>1){
  70.             methodName.append(fieldName.substring(1));
  71.         }
  72.        
  73.         Method method = null;
  74.         try{
  75.             method = c.getMethod(methodName.toString());
  76.         }catch(java.lang.NoSuchMethodException nsme){
  77.             if("get_default".equals(methodName.toString())){
  78.                 // provo a recuperare getDefault
  79.                 try{
  80.                     method = c.getMethod("getDefault");
  81.                 }catch(Exception t){
  82.                     throw nsme; // rilancio eccezione originale
  83.                 }
  84.             }
  85.             else{
  86.                 throw nsme; // rilancio eccezione originale
  87.             }
  88.         }
  89.         return method.invoke(object);
  90.     }
  91.    
  92.     private Object setFieldValue(String fieldName,Object object,Class<?> parameterType,Object parameterValue) throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException{
  93.         Class<?> c = getClass();
  94.        
  95.         StringBuilder methodName = new StringBuilder("set");
  96.         String firstChar = fieldName.charAt(0)+"";
  97.         methodName.append(firstChar.toUpperCase());
  98.         if(fieldName.length()>1){
  99.             methodName.append(fieldName.substring(1));
  100.         }
  101.        
  102.         Method method = null;
  103.         try{
  104.             method = c.getMethod(methodName.toString(),parameterType);
  105.         }catch(java.lang.NoSuchMethodException nsme){
  106.             if("set_default".equals(methodName.toString())){
  107.                 // provo a recuperare setDefault
  108.                 try{
  109.                     method = c.getMethod("setDefault",parameterType);
  110.                 }catch(Exception t){
  111.                     throw nsme; // rilancio eccezione originale
  112.                 }
  113.             }
  114.             else{
  115.                 throw nsme; // rilancio eccezione originale
  116.             }
  117.         }
  118.         return method.invoke(object,parameterValue);
  119.     }
  120.    
  121.    
  122.    
  123.    
  124.    
  125.     // Non lo si vuole realizzare, si demanda eventualmente alla classe che lo implementa
  126.     // Se lo si aggiunge poi viene invocato l'equals e per alcuni field per cui non esiste il metodo get si ottiene errore (es. transazioneBean)
  127.     /**@Override
  128.     public int hashCode(){
  129.         return this.getClass().getName().hashCode();
  130.     }*/
  131.    
  132.     /* ********** EQUALS ********* */
  133.    
  134.     @Override
  135.     public boolean equals(Object object){
  136.         return this.equalsEngine(object,null);
  137.     }
  138.     public boolean equals(Object object,boolean checkLongId){
  139.         List<String> listFieldsNotCheck = new ArrayList<>();
  140.         if(!checkLongId){
  141.             listFieldsNotCheck.add("id");
  142.         }
  143.         return this.equalsEngine(object, listFieldsNotCheck);
  144.     }
  145.     public boolean equals(Object object,List<String> fieldsNotCheck){
  146.         return this.equalsEngine(object, fieldsNotCheck);
  147.     }
  148.     @SuppressWarnings("unchecked")
  149.     private boolean equalsEngine(Object object,List<String> fieldsNotCheck){
  150.         try{
  151.             if(object==null){
  152.                 return false;
  153.             }
  154.             java.lang.reflect.Field[] fields = getClass().getDeclaredFields();
  155.             for(int i=0; i<fields.length;i++){
  156.                
  157.                 /**System.out.println("["+fields[i].getName()+"]");*/
  158.                 if(java.lang.reflect.Modifier.isStatic(fields[i].getModifiers())){
  159.                     /**System.out.println("IS STATIC");*/
  160.                     continue;
  161.                 }
  162.                
  163.                 if(fields[i].getType().isAssignableFrom(org.openspcoop2.utils.jaxb.DecimalWrapper.class)){
  164.                     continue;
  165.                 }
  166.                
  167.                 // field id non controllato se in fieldsNotCheckList
  168.                 boolean ignoreField = false;
  169.                 if(fieldsNotCheck!=null && !fieldsNotCheck.isEmpty()){
  170.                     for (String fieldName : fieldsNotCheck) {
  171.                         if(fieldName.equals(fields[i].getName())){
  172.                             ignoreField = true;
  173.                             break;
  174.                         }
  175.                     }
  176.                 }
  177.                 if(ignoreField){
  178.                     continue;
  179.                 }
  180.                
  181.                 Object fieldValueThis = this.getFieldValue(fields[i].getName(),this);
  182.                 Object fieldValueObject = this.getFieldValue(fields[i].getName(),object);
  183.                 /**System.out.println("LETTO VALORE["+fieldValue+"]");*/
  184.                
  185.                 if(fieldValueThis==null){
  186.                     // FIELD
  187.                     if(fieldValueObject!=null){
  188.                         return false;
  189.                     }
  190.                 }else{
  191.                     // ARRAY_LIST
  192.                     if( (fields[i].getType().isAssignableFrom(java.util.ArrayList.class)) || (fields[i].getType().isAssignableFrom(java.util.List.class)) ){
  193.                         java.util.List<?> listaThis = (java.util.List<?>) fieldValueThis;
  194.                         java.util.List<?> listaParameter = (java.util.List<?>) fieldValueObject;
  195.                         if(listaParameter==null)
  196.                             return false;
  197.                         if(listaThis.size() != listaParameter.size())
  198.                             return false;
  199.                         for(int j=0; j<listaThis.size(); j++){
  200.                             if(listaThis.get(j)==null &&
  201.                                 listaParameter.get(j)!=null) {
  202.                                 return false;
  203.                             }
  204.                         }
  205.                         // SORT
  206.                         java.util.List<Object> listaThisSORT = new java.util.ArrayList<>();
  207.                         java.util.List<Object> listaParameterSORT = new java.util.ArrayList<>();
  208.                         try{
  209.                             java.util.List<String> listaThisTMP = new java.util.ArrayList<>();
  210.                             java.util.Map<String, Object> thisTmp = new java.util.HashMap<>();
  211.                             java.util.Map<String, Object> parameterTmp = new java.util.HashMap<>();
  212.                             for(int k=0; k<listaThis.size(); k++){
  213.                                 Object thisObject = listaThis.get(k);
  214.                                 Object paramObject = listaParameter.get(k);
  215.                                 if(thisObject==null && paramObject!=null)
  216.                                     throw new UtilsException("DIFF");
  217.                                 if(thisObject!=null && paramObject==null)
  218.                                     throw new UtilsException("DIFF");
  219.                                 if(thisObject!=null && paramObject!=null){
  220.                                     // THIS
  221.                                     String key = null;
  222.                                     if(thisObject.getClass().getName().startsWith(this.getClass().getPackage().getName())){
  223.                                         Class<?> c =  thisObject.getClass();
  224.                                         java.lang.reflect.Method method =  c.getMethod(TO_STRING_METHOD,boolean.class,boolean.class);
  225.                                         key = (String) method.invoke(thisObject,false,true);
  226.                                     }else{
  227.                                         key = thisObject.toString();
  228.                                     }
  229.                                     thisTmp.put(key, thisObject);
  230.                                     listaThisTMP.add(key);

  231.                                     // PARAM
  232.                                     if(paramObject.getClass().getName().startsWith(this.getClass().getPackage().getName())){
  233.                                         Class<?> c =  paramObject.getClass();
  234.                                         java.lang.reflect.Method method =  c.getMethod(TO_STRING_METHOD,boolean.class,boolean.class);
  235.                                         key = (String) method.invoke(paramObject,false,true);
  236.                                     }else{
  237.                                         key = paramObject.toString();
  238.                                     }
  239.                                     parameterTmp.put(key, paramObject);
  240.                                 }
  241.                             }
  242.                             java.util.Collections.sort(listaThisTMP);
  243.                             for(int k=0; k<listaThisTMP.size(); k++){
  244.                                 String key = listaThisTMP.get(k);
  245.                                 Object thisObject = thisTmp.get(key);
  246.                                 Object paramObject = parameterTmp.get(key);
  247.                                 if(thisObject==null || paramObject==null){
  248.                                     // significa che manca un elemento
  249.                                     return false;
  250.                                 }
  251.                                 listaThisSORT.add(thisObject);
  252.                                 listaParameterSORT.add(paramObject);
  253.                             }
  254.                         }
  255.                         catch(RuntimeException e){
  256.                             // By SpotBugs
  257.                             listaParameterSORT = (java.util.List<Object>) listaParameter;
  258.                             listaThisSORT = (java.util.List<Object>) listaThis;
  259.                         }
  260.                         catch(Exception e){
  261.                             listaThisSORT = (java.util.List<Object>) listaThis;
  262.                             listaParameterSORT = (java.util.List<Object>) listaParameter;
  263.                         }
  264.                         for(int j=0; j<listaThisSORT.size(); j++){
  265.                             Class<?> c =  listaThisSORT.get(j).getClass();
  266.                             boolean resultMethod = false;
  267.                             if(listaThis.get(j).getClass().getName().startsWith(this.getClass().getPackage().getName())){
  268.                                 java.lang.reflect.Method method =  c.getMethod("equals",Object.class,List.class);
  269.                                 resultMethod = (Boolean) method.invoke(listaThisSORT.get(j),listaParameterSORT.get(j),fieldsNotCheck);
  270.                             }else{
  271.                                 resultMethod = listaThisSORT.get(j).equals(listaParameterSORT.get(j));
  272.                             }
  273.                             if(!resultMethod)
  274.                                 return false;
  275.                         }
  276.                     }else{
  277.                         boolean resultMethod = false;
  278.                         if(fields[i].getType().getName().startsWith(this.getClass().getPackage().getName())){
  279.                             java.lang.reflect.Method method =  fields[i].getType().getMethod("equals",Object.class,List.class);
  280.                             resultMethod = (Boolean) method.invoke(fieldValueThis,fieldValueObject,fieldsNotCheck);
  281.                         }else{
  282.                             boolean checkUguaglianza = false;
  283.                             if(fields[i].getType().isAssignableFrom(byte[].class)){
  284.                                 if(fieldValueObject!=null){
  285.                                     byte[] origi = (byte[]) fieldValueThis;
  286.                                     byte[] dest = (byte[]) fieldValueObject;
  287.                                     checkUguaglianza = (origi.length == dest.length);
  288.                                     if(checkUguaglianza){
  289.                                         for(int k=0;k<origi.length;k++){
  290.                                             if(origi[k]!=dest[k]){
  291.                                                 checkUguaglianza = false;
  292.                                                 break;
  293.                                             }
  294.                                         }
  295.                                     }
  296.                                 }
  297.                             }else{
  298.                                 if(fields[i].getType().isAssignableFrom(java.util.Date.class)){
  299.                                     if(fieldValueObject==null) {
  300.                                         checkUguaglianza=false; // che fieldValue_this non sia null e' gia' stato controllato sopra
  301.                                     }
  302.                                     else {
  303.                                         java.util.Calendar calendarThis = new java.util.GregorianCalendar();
  304.                                         calendarThis.setTime((java.util.Date)fieldValueThis);
  305.                                         java.util.Calendar calendarObject = new java.util.GregorianCalendar();
  306.                                         calendarObject.setTime((java.util.Date)fieldValueObject);
  307.                                         checkUguaglianza = (  calendarThis.get(java.util.Calendar.YEAR) == calendarObject.get(java.util.Calendar.YEAR) ) &&
  308.                                                 ( calendarThis.get(java.util.Calendar.MONTH) == calendarObject.get(java.util.Calendar.MONTH) ) &&
  309.                                                 ( calendarThis.get(java.util.Calendar.DAY_OF_MONTH) == calendarObject.get(java.util.Calendar.DAY_OF_MONTH) ) &&
  310.                                                 ( calendarThis.get(java.util.Calendar.HOUR_OF_DAY) == calendarObject.get(java.util.Calendar.HOUR_OF_DAY) ) &&
  311.                                                 ( calendarThis.get(java.util.Calendar.MINUTE) == calendarObject.get(java.util.Calendar.MINUTE) ) &&
  312.                                                 ( calendarThis.get(java.util.Calendar.SECOND) == calendarObject.get(java.util.Calendar.SECOND) ) &&
  313.                                                 ( calendarThis.get(java.util.Calendar.MILLISECOND) == calendarObject.get(java.util.Calendar.MILLISECOND) ) ;
  314.                                     }
  315.                                 }else{
  316.                                     checkUguaglianza = fieldValueThis.equals(fieldValueObject);
  317.                                 }
  318.                             }
  319.                             resultMethod = checkUguaglianza;
  320.                         }
  321.                         if(!resultMethod)
  322.                             return false;
  323.                     }
  324.                 }
  325.             }
  326.             return true;
  327.         }catch(Exception e){
  328.             logExceptionStackTrace(e);
  329.             throw new UtilsRuntimeException(e.toString(),e);
  330.         }
  331.     }

  332.    
  333.    
  334.    
  335.    
  336.    
  337.    
  338.    
  339.     /* ********** WRITE TO ********* */
  340.    
  341.     public void writeTo(OutputStream out) throws UtilsException{
  342.         this.writeTo(out, WriteToSerializerType.XML_JAXB);
  343.     }
  344.     public void writeTo(OutputStream out,WriteToSerializerType type) throws UtilsException{
  345.         this.writeToEngine(out, type, null);
  346.     }
  347.     public void writeTo(OutputStream out,WriteToSerializerType type, boolean pretty) throws UtilsException{
  348.         this.writeToEngine(out, type, pretty);
  349.     }
  350.     private void writeToEngine(OutputStream out,WriteToSerializerType type, Boolean pretty) throws UtilsException{
  351.         try{
  352.             switch (type) {
  353.                 case XML_JAXB:
  354.                     boolean xmlPretty = true;  /** backward compatibility;*/
  355.                     if(pretty!=null) {
  356.                         xmlPretty = pretty.booleanValue();
  357.                     }
  358.                     JaxbUtils.objToXml(out, getClass(), this, xmlPretty);
  359.                     break;
  360.                 case JSON_JACKSON:
  361.                     SerializationConfig config = new SerializationConfig();
  362.                     if(pretty!=null) {
  363.                         config.setPrettyPrint(pretty.booleanValue());
  364.                     }
  365.                     ISerializer jsonJacksonSerializer = SerializationFactory.getSerializer(SERIALIZATION_TYPE.JSON_JACKSON, config);
  366.                     jsonJacksonSerializer.writeObject(this, out);
  367.                     break;
  368.                 case JAVA:
  369.                     JavaSerializer javaSerializer = new JavaSerializer();
  370.                     javaSerializer.writeObject(this, out);
  371.                     break;
  372.             }
  373.         }catch(Exception e){
  374.             throw new UtilsException(e.getMessage(), e);
  375.         }
  376.     }
  377.    
  378.    
  379.    
  380.    
  381.    
  382.     /* ********** serialize ********* */
  383.    
  384.     public String toXml() throws UtilsException{
  385.         return this.serialize(WriteToSerializerType.XML_JAXB);
  386.     }
  387.     public String toJson() throws UtilsException{
  388.         return this.serialize(WriteToSerializerType.JSON_JACKSON);
  389.     }
  390.     // Non è utile. Al massimo si usa sopra come writeTo
  391.     /**public String toJava() throws UtilsException{
  392.         return this.serialize(WriteToSerializerType.JAVA);
  393.     }*/
  394.     public String serialize(WriteToSerializerType type) throws UtilsException{
  395.         ByteArrayOutputStream bout = new ByteArrayOutputStream();
  396.         this.writeTo(bout, type);
  397.         return bout.toString();
  398.     }
  399.    
  400.    
  401.    
  402.    
  403.    
  404.    
  405.    
  406.    
  407.     /* ********** TO STRING ********* */
  408.    
  409.     private static ToStringStyle defaultToStringStyle =  ToStringStyle.MULTI_LINE_STYLE;
  410.     private static boolean defaultToStringOutputTransients =  false;
  411.     private static boolean defaultToStringOutputStatics =  false;
  412.     public static void setDefaultStyleToString(ToStringStyle style,boolean outputTransients,boolean outputStatics){
  413.         // Il default statico serve per impostare uno "stile" che viene ereditato da tutti gli oggetti che estendono il base bean.
  414.         // In questa maniera gli oggetti interni all'oggetto stesso vengono serializzati con lo stile impostato.
  415.         defaultToStringStyle = style;
  416.         defaultToStringOutputTransients = outputTransients;
  417.         defaultToStringOutputStatics = outputStatics;
  418.     }
  419.     @Override
  420.     public String toString(){
  421.         return this.toString(defaultToStringStyle, defaultToStringOutputTransients, defaultToStringOutputStatics, null);
  422.     }
  423.     public String toString(ToStringStyle style){
  424.         return this.toString(style, false, false, null);
  425.     }
  426.     public String toString(ToStringStyle style,boolean outputTransients,boolean outputStatics){
  427.         return this.toString(style, outputTransients, outputStatics, null);
  428.     }
  429.     public String toString(ToStringStyle style,boolean outputTransients,boolean outputStatics,Class<?>reflectUpToClass){
  430.         StringBuilder buffer = new StringBuilder();
  431.         this.toString(style, buffer, outputTransients, outputStatics, reflectUpToClass);
  432.         return buffer.toString();
  433.     }
  434.     public void toString(ToStringStyle style,StringBuilder buffer,boolean outputTransients,boolean outputStatics){
  435.         this.toString(style, buffer, outputTransients, outputStatics, null);
  436.     }
  437.     public void toString(ToStringStyle style,StringBuilder buffer,boolean outputTransients,boolean outputStatics,Class<?>reflectUpToClass){
  438.         StringBuffer bf = new StringBuffer();
  439.         ReflectionToStringBuilder builder = new ReflectionToStringBuilder(this, style, bf, reflectUpToClass, outputTransients, outputStatics);
  440.         builder.toString();
  441.         buffer.append(bf.toString());
  442.     }
  443.    
  444.    
  445.     // Old Method
  446.     public String toString_oldMethod(){
  447.         return toStringEngine(false, null);
  448.     }
  449.     public String toString(boolean reportHTML){
  450.         return toStringEngine(reportHTML,null);
  451.     }
  452.     public String toString(List<String> fieldsNotIncluded){
  453.         return toStringEngine(false,fieldsNotIncluded);
  454.     }
  455.     public String toString(boolean reportHTML,boolean includeLongId){
  456.         List<String> fieldsNotIncluded = new ArrayList<>();
  457.         if(!includeLongId){
  458.             fieldsNotIncluded.add("id");
  459.         }
  460.         return toStringEngine(reportHTML,fieldsNotIncluded);
  461.     }
  462.     public String toString(boolean reportHTML,List<String> fieldsNotIncluded){
  463.         return toStringEngine(reportHTML,fieldsNotIncluded);
  464.     }
  465.     private String toStringEngine(boolean reportHTML,List<String> fieldsNotIncluded){  
  466.         try{
  467.             StringBuilder bf = new StringBuilder();
  468.             java.lang.reflect.Field[] fields = getClass().getDeclaredFields();
  469.             for(int i=0; i<fields.length;i++){
  470.            
  471.                 /**System.out.println("["+fields[i].getName()+"]");*/
  472.                 if(java.lang.reflect.Modifier.isStatic(fields[i].getModifiers())){
  473.                     /**System.out.println("IS STATIC");*/
  474.                     continue;
  475.                 }
  476.                
  477.                 if(fields[i].getType().isAssignableFrom(org.openspcoop2.utils.jaxb.DecimalWrapper.class)){
  478.                     continue;
  479.                 }
  480.                
  481.                 // field id non controllato se in fieldsNotCheckList
  482.                 boolean ignoreField = false;
  483.                 if(fieldsNotIncluded!=null && !fieldsNotIncluded.isEmpty()){
  484.                     for (String fieldName : fieldsNotIncluded) {
  485.                         if(fieldName.equals(fields[i].getName())){
  486.                             ignoreField = true;
  487.                             break;
  488.                         }
  489.                     }
  490.                 }
  491.                 if(ignoreField){
  492.                     continue;
  493.                 }

  494.                 bf.append("---------- ");
  495.                 bf.append(this.getClass().getName());
  496.                 bf.append(".");
  497.                 bf.append(fields[i].getName());
  498.                 bf.append(" ----------");
  499.                 if(reportHTML) bf.append("<br>"); else bf.append("\n");
  500.                
  501.                 Object fieldValue = this.getFieldValue(fields[i].getName(),this);
  502.                 /**System.out.println("LETTO VALORE["+fieldValue+"]");*/
  503.                
  504.                 if(fieldValue==null){
  505.                     bf.append("null");
  506.                 }else{
  507.                     if(fields[i].getType().isAssignableFrom(java.util.ArrayList.class) || fields[i].getType().isAssignableFrom(java.util.List.class)){
  508.                         java.util.List<?> listaThis = (java.util.List<?>) fieldValue;
  509.                         bf.append("List size("+listaThis.size()+")");
  510.                         if(!listaThis.isEmpty()){
  511.                             if(reportHTML) bf.append("<br>"); else bf.append("\n");
  512.                         }
  513.                         java.util.List<String> sortLISTKEY = new java.util.ArrayList<>();
  514.                         for(int j=0; j<listaThis.size(); j++){
  515.                             String key = null;
  516.                             if(listaThis.get(j).getClass().getName().startsWith(this.getClass().getPackage().getName())){
  517.                                 Class<?> c =  listaThis.get(j).getClass();
  518.                                 java.lang.reflect.Method method =  c.getMethod(TO_STRING_METHOD,boolean.class,List.class);
  519.                                 key = (String) method.invoke(listaThis.get(j),reportHTML,fieldsNotIncluded);
  520.                             }else{
  521.                                 key =  listaThis.get(j).toString();
  522.                             }
  523.                             sortLISTKEY.add(key);
  524.                         }
  525.                         java.util.Collections.sort(sortLISTKEY);
  526.                         for(int j=0; j<sortLISTKEY.size(); j++){
  527.                             String key = sortLISTKEY.get(j);
  528.                             bf.append("---------- ");
  529.                             bf.append(this.getClass().getName());
  530.                             bf.append(".");
  531.                             bf.append(fields[i].getName());
  532.                             bf.append("[");
  533.                             bf.append(j);
  534.                             bf.append("] ----------");
  535.                             if(reportHTML) bf.append("<br>"); else bf.append("\n");
  536.                             bf.append(key);
  537.                             if(reportHTML) bf.append("<br>"); else bf.append("\n");
  538.                             bf.append("----end--- ");
  539.                             bf.append(this.getClass().getName());
  540.                             bf.append(".");
  541.                             bf.append(fields[i].getName());
  542.                             bf.append("[");
  543.                             bf.append(j);
  544.                             bf.append("] ----end---");
  545.                             if(reportHTML) bf.append("<br>"); else bf.append("\n");
  546.                         }
  547.                     }else{
  548.                         if(fieldValue.getClass().getName().startsWith(this.getClass().getPackage().getName())){
  549.                             Class<?> c =  fieldValue.getClass();
  550.                             java.lang.reflect.Method method =  c.getMethod(TO_STRING_METHOD,boolean.class,List.class);
  551.                             bf.append(method.invoke(fieldValue,reportHTML,fieldsNotIncluded));
  552.                         }else{
  553.                             if(fields[i].getType().isAssignableFrom(byte[].class)){
  554.                                 byte[] array = (byte[])fieldValue;
  555.                                 for(int k=0; k<array.length;k++){
  556.                                     bf.append(((char)array[k]));
  557.                                 }
  558.                             }else if(fields[i].getType().isAssignableFrom(java.util.Date.class)){
  559.                                 java.util.Date date = (java.util.Date) fieldValue;
  560.                                 bf.append(DateUtils.getSimpleDateFormatMs().format(date));
  561.                             }else{
  562.                                 bf.append(fieldValue.toString());
  563.                             }
  564.                         }
  565.                     }
  566.                 }
  567.                 if(reportHTML) bf.append("<br>"); else bf.append("\n");
  568.                 bf.append("---end---- ");
  569.                 bf.append(this.getClass().getName());
  570.                 bf.append(".");
  571.                 bf.append(fields[i].getName());
  572.                 bf.append(" ---end----");
  573.                 if(reportHTML) bf.append("<br>"); else bf.append("\n");
  574.             }
  575.             return bf.toString();
  576.         }catch(Exception e){
  577.             logExceptionStackTrace(e);
  578.             throw new UtilsRuntimeException(e.toString(),e);
  579.         }
  580.     }

  581.    
  582.    
  583.    
  584.    
  585.    
  586.     /* ********** DIFF ********* */
  587.    
  588.     public String diff(Object object,StringBuilder bf){
  589.         return diffEngine(object,bf,false, null);
  590.     }
  591.     public String diff(Object object,StringBuilder bf,boolean reportHTML){
  592.         return diffEngine(object,bf,reportHTML,null);
  593.     }
  594.     public String diff(Object object,StringBuilder bf,List<String> fieldsNotIncluded){
  595.         return diffEngine(object,bf,false,fieldsNotIncluded);
  596.     }
  597.     public String diff(Object object,StringBuilder bf,boolean reportHTML,boolean includeLongId){
  598.         List<String> fieldsNotIncluded = new ArrayList<>();
  599.         if(!includeLongId){
  600.             fieldsNotIncluded.add("id");
  601.         }
  602.         return diffEngine(object,bf,reportHTML,fieldsNotIncluded);
  603.     }
  604.     public String diff(Object object,StringBuilder bf,boolean reportHTML,List<String> fieldsNotIncluded){
  605.         return diffEngine(object,bf,reportHTML,fieldsNotIncluded);
  606.     }
  607.     @SuppressWarnings("unchecked")
  608.     private String diffEngine(Object object,StringBuilder bf,boolean reportHTML,List<String> fieldsNotIncluded){    
  609.    
  610.         try{
  611.             if(object==null){
  612.                 bf.append(this.getClass().getName());
  613.                 bf.append("this is not null, parameter is null");
  614.                 return bf.toString();
  615.             }
  616.             java.lang.reflect.Field[] fields = getClass().getDeclaredFields();
  617.             for(int i=0; i<fields.length;i++){
  618.                
  619.                 /**System.out.println("["+fields[i].getName()+"]");*/
  620.                 if(java.lang.reflect.Modifier.isStatic(fields[i].getModifiers())){
  621.                     /**System.out.println("IS STATIC");*/
  622.                     continue;
  623.                 }
  624.                
  625.                 if(fields[i].getType().isAssignableFrom(org.openspcoop2.utils.jaxb.DecimalWrapper.class)){
  626.                     continue;
  627.                 }
  628.                
  629.                 Object fieldValueThis = this.getFieldValue(fields[i].getName(),this);
  630.                 Object fieldValueObject = this.getFieldValue(fields[i].getName(),object);
  631.                
  632.                 if(fields[i].getType().isAssignableFrom(java.util.ArrayList.class) || fields[i].getType().isAssignableFrom(java.util.List.class)){
  633.                     // LISTA
  634.                     java.util.List<?> listaThis = (java.util.List<?>) fieldValueThis;
  635.                     java.util.List<?> listaParameter = (java.util.List<?>) fieldValueObject;
  636.                     if(listaThis==null){
  637.                         // this_list is null, parameter list is not null
  638.                         if(listaParameter!=null){
  639.                             bf.append(this.getClass().getName());
  640.                             bf.append(".");
  641.                             bf.append(fields[i].getName());
  642.                             bf.append(" this_list:is null, parameter_list: is not null");
  643.                             bf.append(" ,parameter_list_size:"+listaParameter.size());
  644.                             if(reportHTML) bf.append("<br>"); else bf.append("\n");
  645.                         }
  646.                     }else{
  647.                         // this_list is not null, parameter list is null
  648.                         if(listaParameter==null){
  649.                             bf.append(this.getClass().getName());
  650.                             bf.append(".");
  651.                             bf.append(fields[i].getName());
  652.                             bf.append(" this_list: is not null, parameter_list: is null");
  653.                             bf.append(" ,this_list_size:"+listaThis.size());
  654.                             if(reportHTML) bf.append("<br>"); else bf.append("\n");
  655.                         }
  656.                         // this_list different size from parameter_list
  657.                         else if(listaThis.size() != listaParameter.size()){
  658.                             bf.append(this.getClass().getName());
  659.                             bf.append(".");
  660.                             bf.append(fields[i].getName());
  661.                             bf.append(" this_list_size:"+listaThis.size()+", parameter_list_size:"+listaParameter.size());
  662.                             if(reportHTML) bf.append("<br>"); else bf.append("\n");
  663.                         }
  664.                         // Controllo elementi della lista
  665.                         else{
  666.                             // SORT
  667.                             java.util.List<Object> listaThisSORT = new java.util.ArrayList<>();
  668.                             java.util.List<Object> listaParameterSORT = new java.util.ArrayList<>();
  669.                             boolean listaNonCompleta = false;
  670.                             try{
  671.                                 java.util.List<String> listaThisTMP = new java.util.ArrayList<>();
  672.                                 java.util.Map<String, Object> thisTmp = new java.util.HashMap<>();
  673.                                 java.util.Map<String, Object> parameterTmp = new java.util.HashMap<>();
  674.                                 for(int k=0; k<listaThis.size(); k++){
  675.                                     Object thisObject = listaThis.get(k);
  676.                                     Object paramObject = listaParameter.get(k);
  677.                                     if(thisObject==null && paramObject!=null)
  678.                                         throw new UtilsException("DIFF");
  679.                                     if(thisObject!=null && paramObject==null)
  680.                                         throw new UtilsException("DIFF");
  681.                                     if(thisObject!=null && paramObject!=null){
  682.                                         // THIS
  683.                                         String key = null;
  684.                                         if(thisObject.getClass().getName().startsWith(this.getClass().getPackage().getName())){
  685.                                             Class<?> c =  thisObject.getClass();
  686.                                             java.lang.reflect.Method method =  c.getMethod(TO_STRING_METHOD,boolean.class,boolean.class);
  687.                                             key = (String) method.invoke(thisObject,false,true);
  688.                                         }else{
  689.                                             key = thisObject.toString();
  690.                                         }
  691.                                         thisTmp.put(key, thisObject);
  692.                                         listaThisTMP.add(key);

  693.                                         // PARAM
  694.                                         if(paramObject.getClass().getName().startsWith(this.getClass().getPackage().getName())){
  695.                                             Class<?> c =  paramObject.getClass();
  696.                                             java.lang.reflect.Method method =  c.getMethod(TO_STRING_METHOD,boolean.class,boolean.class);
  697.                                             key = (String) method.invoke(paramObject,false,true);
  698.                                         }else{
  699.                                             key = paramObject.toString();
  700.                                         }
  701.                                         parameterTmp.put(key, paramObject);
  702.                                     }
  703.                                 }
  704.                                 java.util.Collections.sort(listaThisTMP);
  705.                                 for(int k=0; k<listaThisTMP.size(); k++){
  706.                                     String key = listaThisTMP.get(k);
  707.                                     Object thisObject = thisTmp.get(key);
  708.                                     Object paramObject = parameterTmp.get(key);
  709.                                     if(thisObject==null){
  710.                                         // significa che manca un elemento
  711.                                         listaThisSORT = (java.util.List<Object>) listaThis;
  712.                                         listaParameterSORT = (java.util.List<Object>) listaParameter;
  713.                                         bf.append("["+this.getClass().getName());
  714.                                         bf.append(".");
  715.                                         bf.append(fields[i].getName()+"] ");
  716.                                         bf.append("Match non trovato in this(size:"+thisTmp.size()+") per l'elemento: "+key);
  717.                                         if(!thisTmp.isEmpty()) {
  718.                                             int j=0;
  719.                                             for (String keyJ : thisTmp.keySet()) {
  720.                                                 bf.append("ELEMENTO_THIS_["+j+"]=["+keyJ+"]");
  721.                                                 j++;
  722.                                             }
  723.                                         }
  724.                                         listaNonCompleta = true;
  725.                                         break;
  726.                                     }
  727.                                     if(paramObject==null){
  728.                                         // significa che manca un elemento
  729.                                         listaThisSORT = (java.util.List<Object>) listaThis;
  730.                                         listaParameterSORT = (java.util.List<Object>) listaParameter;
  731.                                         bf.append("["+this.getClass().getName());
  732.                                         bf.append(".");
  733.                                         bf.append(fields[i].getName()+"] ");
  734.                                         bf.append("Match non trovato in param(size:"+parameterTmp.size()+") per l'elemento: "+key);
  735.                                         if(!parameterTmp.isEmpty()) {
  736.                                             int j=0;
  737.                                             for (String keyJ : parameterTmp.keySet()) {
  738.                                                 bf.append("ELEMENTO_PARAM_["+j+"]=["+keyJ+"]");
  739.                                                 j++;
  740.                                             }
  741.                                         }
  742.                                         listaNonCompleta = true;
  743.                                         break;
  744.                                     }
  745.                                     listaThisSORT.add(thisObject);
  746.                                     listaParameterSORT.add(paramObject);
  747.                                 }
  748.                             }
  749.                             catch(RuntimeException e){
  750.                                 // By SpotBugs
  751.                                 listaParameterSORT = (java.util.List<Object>) listaParameter;
  752.                                 listaThisSORT = (java.util.List<Object>) listaThis;
  753.                             }
  754.                             catch(Exception e){
  755.                                 listaThisSORT = (java.util.List<Object>) listaThis;
  756.                                 listaParameterSORT = (java.util.List<Object>) listaParameter;
  757.                             }
  758.                             if(!listaNonCompleta){
  759.                                 for(int j=0; j<listaThisSORT.size(); j++){
  760.                                     if(listaThisSORT.get(j)==null){
  761.                                         bf.append(this.getClass().getName());
  762.                                         bf.append(".");
  763.                                         bf.append(fields[i].getName()+"["+j+"]");
  764.                                         bf.append(" this_list: is null, parameter: is not null");
  765.                                         bf.append(" parameter_value:");
  766.                                         if(reportHTML) bf.append("<br>"); else bf.append("\n");
  767.                                         if(listaParameterSORT.get(j).getClass().getName().startsWith(this.getClass().getPackage().getName())){
  768.                                             Class<?> c =  listaParameterSORT.get(j).getClass();
  769.                                             java.lang.reflect.Method method =  c.getMethod(TO_STRING_METHOD,boolean.class);
  770.                                             bf.append(method.invoke(listaParameterSORT.get(j),reportHTML));
  771.                                         }else{
  772.                                             bf.append(listaParameterSORT.get(j).toString());
  773.                                         }
  774.                                         if(reportHTML) bf.append("<br>"); else bf.append("\n");
  775.                                     }else{
  776.                                         if(listaThisSORT.get(j).getClass().getName().startsWith(this.getClass().getPackage().getName())){
  777.                                             Class<?> c =  listaThisSORT.get(j).getClass();
  778.                                             java.lang.reflect.Method method =  c.getMethod("diff",Object.class,bf.getClass(),boolean.class,List.class);
  779.                                             method.invoke(listaThisSORT.get(j),listaParameterSORT.get(j),bf,reportHTML,fieldsNotIncluded);
  780.                                         }else{
  781.                                             boolean checkUguaglianza = false;
  782.                                             if(listaThisSORT.get(j).getClass().isAssignableFrom(byte[].class)){
  783.                                                 if(listaParameterSORT.get(j)!=null){
  784.                                                     byte[] origi = (byte[]) listaThisSORT.get(j);
  785.                                                     byte[] dest = (byte[]) listaParameterSORT.get(j);
  786.                                                     checkUguaglianza = (origi.length == dest.length);
  787.                                                     if(checkUguaglianza){
  788.                                                         for(int k=0;k<origi.length;k++){
  789.                                                             if(origi[k]!=dest[k]){
  790.                                                                 checkUguaglianza = false;
  791.                                                                 break;
  792.                                                             }
  793.                                                         }
  794.                                                     }
  795.                                                 }
  796.                                             }else{
  797.                                                 checkUguaglianza = listaThisSORT.get(j).equals(listaParameterSORT.get(j));
  798.                                             }
  799.                                             if(!checkUguaglianza){
  800.                                                 bf.append(this.getClass().getName());
  801.                                                 bf.append(".");
  802.                                                 bf.append(fields[i].getName()+"["+j+"]");
  803.                                                
  804.                                                 bf.append(" this:");
  805.                                                 if(listaThisSORT.get(j).getClass().isAssignableFrom(byte[].class)){
  806.                                                     if(listaThisSORT.get(j)!=null){
  807.                                                         byte[] array = (byte[])listaThisSORT.get(j);
  808.                                                         for(int k=0; k<array.length;k++)
  809.                                                             bf.append(((char)array[k]));
  810.                                                     }
  811.                                                     else
  812.                                                         bf.append("null");
  813.                                                 }else if(listaThisSORT.get(j).getClass().isAssignableFrom(java.util.Date.class)){
  814.                                                     if(listaThisSORT.get(j)!=null){
  815.                                                         java.util.Date date = (java.util.Date) listaThisSORT.get(j);
  816.                                                         bf.append(DateUtils.getSimpleDateFormatMs().format(date));
  817.                                                     }
  818.                                                     else
  819.                                                         bf.append("null");
  820.                                                 }else{
  821.                                                     bf.append(listaThisSORT.get(j));
  822.                                                 }
  823.                                                
  824.                                                 bf.append(" parameter:");
  825.                                                 if(listaParameterSORT.get(j).getClass().isAssignableFrom(byte[].class)){
  826.                                                     if(listaParameterSORT.get(j)!=null){
  827.                                                         byte[] array = (byte[])listaParameterSORT.get(j);
  828.                                                         for(int k=0; k<array.length;k++)
  829.                                                             bf.append(((char)array[k]));
  830.                                                     }
  831.                                                     else
  832.                                                         bf.append("null");
  833.                                                 }else if(listaParameterSORT.get(j).getClass().isAssignableFrom(java.util.Date.class)){
  834.                                                     if(listaParameterSORT.get(j)!=null){
  835.                                                         java.util.Date date = (java.util.Date) listaParameterSORT.get(j);
  836.                                                         bf.append(DateUtils.getSimpleDateFormatMs().format(date));
  837.                                                     }
  838.                                                     else
  839.                                                         bf.append("null");
  840.                                                 }else{
  841.                                                     bf.append(listaParameterSORT.get(j));
  842.                                                 }
  843.                                                 if(reportHTML) bf.append("<br>"); else bf.append("\n");
  844.                                             }
  845.                                         }
  846.                                     }
  847.                                 }
  848.                             }
  849.                         }
  850.                     }
  851.                 }
  852.                 else{
  853.                     // field id non controllato se in fieldsNotCheckList
  854.                     boolean ignoreField = false;
  855.                     if(fieldsNotIncluded!=null && !fieldsNotIncluded.isEmpty()){
  856.                         for (String fieldName : fieldsNotIncluded) {
  857.                             if(fieldName.equals(fields[i].getName())){
  858.                                 ignoreField = true;
  859.                                 break;
  860.                             }
  861.                         }
  862.                     }
  863.                     if(ignoreField){
  864.                         continue;
  865.                     }

  866.                     // ELEMENTO SINGOLO
  867.                     if(fieldValueThis==null){
  868.                         // this is null, parameter is not null
  869.                         if(fieldValueObject!=null){
  870.                             bf.append(this.getClass().getName());
  871.                             bf.append(".");
  872.                             bf.append(fields[i].getName());
  873.                             bf.append(" this:is null, parameter: is not null");
  874.                             bf.append(" parameter_value:");
  875.                             if(reportHTML) bf.append("<br>"); else bf.append("\n");
  876.                             if(fieldValueObject.getClass().getName().startsWith(this.getClass().getPackage().getName())){
  877.                                 Class<?> c =  fieldValueObject.getClass();
  878.                                 java.lang.reflect.Method method =  c.getMethod(TO_STRING_METHOD,boolean.class);
  879.                                 bf.append(method.invoke(fieldValueObject,reportHTML));
  880.                             }else{
  881.                                 if(fields[i].getType().isAssignableFrom(byte[].class)){
  882.                                     byte[] array = (byte[])fieldValueObject;
  883.                                     for(int k=0; k<array.length;k++)
  884.                                         bf.append(array[k]);
  885.                                 }else if(fields[i].getType().isAssignableFrom(java.util.Date.class)){
  886.                                     java.util.Date date = (java.util.Date) fieldValueObject;
  887.                                     bf.append(DateUtils.getSimpleDateFormatMs().format(date));
  888.                                 }else{
  889.                                     bf.append(fieldValueObject);
  890.                                 }
  891.                             }
  892.                             if(reportHTML) bf.append("<br>"); else bf.append("\n");
  893.                         }
  894.                     }else{
  895.                         if(fields[i].getType().getName().startsWith(this.getClass().getPackage().getName())){
  896.                             java.lang.reflect.Method method =  fields[i].getType().getMethod("diff",Object.class,bf.getClass(),boolean.class,List.class);
  897.                             method.invoke(fieldValueThis,fieldValueObject,bf,reportHTML,fieldsNotIncluded);
  898.                         }else{
  899.                             boolean checkUguaglianza = false;
  900.                             if(fields[i].getType().isAssignableFrom(byte[].class)){
  901.                                 if(fieldValueObject!=null){
  902.                                     byte[] origi = (byte[]) fieldValueThis;
  903.                                     byte[] dest = (byte[]) fieldValueObject;
  904.                                     checkUguaglianza = (origi.length == dest.length);
  905.                                     if(checkUguaglianza){
  906.                                         for(int k=0;k<origi.length;k++){
  907.                                             if(origi[k]!=dest[k]){
  908.                                                 checkUguaglianza = false;
  909.                                                 break;
  910.                                             }
  911.                                         }
  912.                                     }
  913.                                 }
  914.                             }else{
  915.                                 if(fields[i].getType().isAssignableFrom(java.util.Date.class)){
  916.                                     if(fieldValueObject!=null){
  917.                                         java.util.Calendar calendarThis = new java.util.GregorianCalendar();
  918.                                         calendarThis.setTime((java.util.Date)fieldValueThis);
  919.                                         java.util.Calendar calendarObject = new java.util.GregorianCalendar();
  920.                                         calendarObject.setTime((java.util.Date)fieldValueObject);
  921.                                         checkUguaglianza = (  calendarThis.get(java.util.Calendar.YEAR) == calendarObject.get(java.util.Calendar.YEAR) ) &&
  922.                                                 ( calendarThis.get(java.util.Calendar.MONTH) == calendarObject.get(java.util.Calendar.MONTH) ) &&
  923.                                                 ( calendarThis.get(java.util.Calendar.DAY_OF_MONTH) == calendarObject.get(java.util.Calendar.DAY_OF_MONTH) ) &&
  924.                                                 ( calendarThis.get(java.util.Calendar.HOUR_OF_DAY) == calendarObject.get(java.util.Calendar.HOUR_OF_DAY) ) &&
  925.                                                 ( calendarThis.get(java.util.Calendar.MINUTE) == calendarObject.get(java.util.Calendar.MINUTE) ) &&
  926.                                                 ( calendarThis.get(java.util.Calendar.SECOND) == calendarObject.get(java.util.Calendar.SECOND) ) &&
  927.                                                 ( calendarThis.get(java.util.Calendar.MILLISECOND) == calendarObject.get(java.util.Calendar.MILLISECOND) );
  928.                                     }
  929.                                 }else{
  930.                                     checkUguaglianza = fieldValueThis.equals(fieldValueObject);
  931.                                 }
  932.                             }
  933.                             if(!checkUguaglianza){
  934.                                 bf.append(this.getClass().getName());
  935.                                 bf.append(".");
  936.                                 bf.append(fields[i].getName());
  937.                                
  938.                                 bf.append(" this:");
  939.                                 if(fields[i].getType().isAssignableFrom(byte[].class)){
  940.                                     byte[] array = (byte[])fieldValueThis;
  941.                                     for(int k=0; k<array.length;k++)
  942.                                         bf.append(((char)array[k]));
  943.                                 }else if(fields[i].getType().isAssignableFrom(java.util.Date.class)){
  944.                                     java.util.Date date = (java.util.Date) fieldValueThis;
  945.                                     bf.append(DateUtils.getSimpleDateFormatMs().format(date));
  946.                                 }else{
  947.                                     bf.append(fieldValueThis);
  948.                                 }
  949.                                
  950.                                 bf.append(" parameter:");
  951.                                 if(fields[i].getType().isAssignableFrom(byte[].class)){
  952.                                     if(fieldValueObject!=null){
  953.                                         byte[] array = (byte[])fieldValueObject;
  954.                                         for(int k=0; k<array.length;k++)
  955.                                             bf.append(((char)array[k]));
  956.                                     }
  957.                                     else
  958.                                         bf.append("null");
  959.                                 }else if(fields[i].getType().isAssignableFrom(java.util.Date.class)){
  960.                                     if(fieldValueObject!=null){
  961.                                         java.util.Date date = (java.util.Date) fieldValueObject;
  962.                                         bf.append(DateUtils.getSimpleDateFormatMs().format(date));
  963.                                     }else
  964.                                         bf.append("null");
  965.                                 }else{
  966.                                     bf.append(fieldValueObject);
  967.                                 }
  968.                                 if(reportHTML) bf.append("<br>"); else bf.append("\n");
  969.                             }
  970.                         }
  971.                     }
  972.                 }
  973.             }
  974.             return bf.toString();
  975.         }catch(Exception e){
  976.             logExceptionStackTrace(e);
  977.             throw new UtilsRuntimeException(e.toString(),e);
  978.         }
  979.     }

  980.    
  981.    
  982.    
  983.    
  984.    
  985.    
  986.    
  987.    
  988.     /* ********** CLONE ********* */
  989.    
  990.     @Override
  991.     public Object clone()  {
  992.         Object clone = null;
  993.         try{
  994.             //clono l'oggetto
  995.             clone = super.clone();
  996.             //clone = this.getClass().newInstance(); NON FUNZIONA NON VENGONO COPIATI I VARI FIELDS
  997.             /*
  998.              * Per ogni field se il field presente nella classe implementa
  999.              * l'interfaccia cloneable allora eseguo il metodo clone di quel field
  1000.              */
  1001.             java.lang.reflect.Field[] fields = this.getClass().getDeclaredFields();
  1002.             if(fields!=null && fields.length>0){
  1003.                 for (int i = 0; i < fields.length; i++) {
  1004.                    
  1005.                     /**System.out.println("["+fields[i].getName()+"]");*/
  1006.                     if(java.lang.reflect.Modifier.isStatic(fields[i].getModifiers())){
  1007.                         /**System.out.println("IS STATIC");*/
  1008.                         continue;
  1009.                     }
  1010.                    
  1011.                     if(fields[i].getType().isAssignableFrom(org.openspcoop2.utils.jaxb.DecimalWrapper.class)){
  1012.                         continue;
  1013.                     }
  1014.                    
  1015.                    
  1016.                     java.lang.reflect.Field field = fields[i];
  1017.                     Object fieldValue = this.getFieldValue(field.getName(), this);
  1018.                     if(fieldValue==null){
  1019.                         continue;
  1020.                     }
  1021.                    
  1022.                     /**System.out.println("ESAMINO FIELD ["+field.getName()+"] type["+field.getType().getName()+"] isEnum["+(field.getType().isEnum())+"]");*/
  1023.                    
  1024.                     if(field.getType().isAssignableFrom(byte[].class)){
  1025.                         //caso particolare arrya di byte
  1026.                         byte[] originale = (byte[]) fieldValue;
  1027.                         if(originale!=null){
  1028.                             byte[] arrayClone = new byte[originale.length];
  1029.                             for (int j = 0; j < arrayClone.length; j++) {
  1030.                                 arrayClone[j]=originale[j];
  1031.                             }
  1032.                             this.setFieldValue(field.getName(), clone, field.getType(), arrayClone);
  1033.                         }
  1034.                     }
  1035.                     else if(field.getType().isEnum()){
  1036.                         // Imposto nel nuovo oggetto il valore dell'enum
  1037.                         //setto il field clonato nel clone
  1038.                         this.setFieldValue(field.getName(), clone, field.getType(), fieldValue);
  1039.                     }
  1040.                     else if(isSupportedCloneList(field)){
  1041.                         List<?> listOriginale = (List<?>) fieldValue;
  1042.                         if(listOriginale!=null){
  1043.                             List<?> listClone  = this.cloneList(listOriginale);
  1044.                             //setto il field clonato nel clone
  1045.                             this.setFieldValue(field.getName(), clone, field.getType(), listClone);
  1046.                         }
  1047.                     }
  1048.                     else {
  1049.                         //recupero interfacce implementate da questo field
  1050.                         Class<?>[] interfacce = field.getType().getInterfaces();
  1051.                         for (int j = 0; j < interfacce.length; j++) {
  1052.                             //se il field che sto controllando implementa l'interfaccia cloneable e il field che voglio clonare non e' null
  1053.                             //richiamo il clone
  1054.                             if(interfacce[j].isAssignableFrom(java.lang.Cloneable.class) && fieldValue!=null ){
  1055.                                 //recupero il metodo clone dal field
  1056.                                 java.lang.reflect.Method method =  field.getType().getMethod("clone");
  1057.                                 //effettuo il clone del field
  1058.                                 java.lang.Cloneable ris =  (java.lang.Cloneable) method.invoke(fieldValue);
  1059.                                 //setto il field clonato nel clone
  1060.                                 this.setFieldValue(field.getName(), clone, field.getType(), ris);
  1061.                             }
  1062.                         }
  1063.                     }
  1064.                 }
  1065.             }

  1066.         }catch (Exception e) {
  1067.             logExceptionStackTrace(e);
  1068.             throw new UtilsRuntimeException(e.toString(),e);
  1069.         }
  1070.         return clone;
  1071.     }

  1072.     private boolean isSupportedCloneList(java.lang.reflect.Field field){
  1073.         return field.getType().isAssignableFrom(java.util.List.class) ||
  1074.                 field.getType().isAssignableFrom(java.util.ArrayList.class)  ||
  1075.                 field.getType().isAssignableFrom(java.util.Vector.class) ||
  1076.                 field.getType().isAssignableFrom(java.util.Stack.class) ||
  1077.                 field.getType().isAssignableFrom(java.util.LinkedList.class) ||
  1078.                 field.getType().isAssignableFrom(java.util.concurrent.CopyOnWriteArrayList.class);
  1079.     }
  1080.     @SuppressWarnings({ "rawtypes", "unchecked" })
  1081.     private List cloneList(List<?> listOriginale) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
  1082.         List listClone  = null;
  1083.         if(listOriginale.getClass().isAssignableFrom(java.util.ArrayList.class)){
  1084.             listClone = new java.util.ArrayList<>();
  1085.         }
  1086.         else if(listOriginale.getClass().isAssignableFrom(java.util.Vector.class)){
  1087.             listClone = new java.util.Vector<>();
  1088.         }
  1089.         else if(listOriginale.getClass().isAssignableFrom(java.util.Stack.class)){
  1090.             listClone = new java.util.Stack<>();
  1091.         }
  1092.         else if(listOriginale.getClass().isAssignableFrom(java.util.LinkedList.class)){
  1093.             listClone = new java.util.LinkedList<>();
  1094.         }
  1095.         else if(listOriginale.getClass().isAssignableFrom(java.util.concurrent.CopyOnWriteArrayList.class)){
  1096.             listClone = new java.util.concurrent.CopyOnWriteArrayList<>();
  1097.         }
  1098.         if(listClone!=null){
  1099.             for (int j = 0; j < listOriginale.size(); j++) {
  1100.                 Object oOriginale = listOriginale.get(j);
  1101.                 if(oOriginale!=null){
  1102.                     if(oOriginale instanceof java.lang.Cloneable){
  1103.                         //recupero il metodo clone dal field
  1104.                         java.lang.reflect.Method method =  oOriginale.getClass().getMethod("clone");
  1105.                         //effettuo il clone del field
  1106.                         java.lang.Cloneable oCloned =  (java.lang.Cloneable) method.invoke(oOriginale);
  1107.                         //aggiungo il field clonato nella lista
  1108.                         listClone.add(oCloned);
  1109.                     }
  1110.                     else if(oOriginale instanceof String) {
  1111.                         String sOriginale = (String) oOriginale;
  1112.                         String sCloned = new String(sOriginale.toCharArray());
  1113.                         //aggiungo il field clonato nella lista
  1114.                         listClone.add(sCloned);
  1115.                     }
  1116.                 }
  1117.                 else{
  1118.                     listClone.add(null);
  1119.                 }
  1120.             }
  1121.         }
  1122.         return listClone;
  1123.     }
  1124. }