XMLDeserializer.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.serialization;

  21. import java.io.ByteArrayOutputStream;
  22. import java.io.InputStream;
  23. import java.io.Reader;
  24. import java.io.StringWriter;
  25. import java.lang.reflect.Method;
  26. import java.util.ArrayList;
  27. import java.util.Iterator;
  28. import java.util.List;
  29. import java.util.Set;

  30. import org.openspcoop2.utils.CopyCharStream;
  31. import org.openspcoop2.utils.CopyStream;
  32. import org.openspcoop2.utils.UtilsException;
  33. import org.openspcoop2.utils.resources.ClassLoaderUtilities;

  34. import net.sf.ezmorph.MorpherRegistry;
  35. import net.sf.json.JSONArray;
  36. import net.sf.json.JSONObject;
  37. import net.sf.json.JsonConfig;
  38. import net.sf.json.util.JSONUtils;

  39. /**
  40.  * Contiene utility per effettuare la de-serializzazione di un oggetto
  41.  *
  42.  * @author Poli Andrea (apoli@link.it)
  43.  * @author $Author$
  44.  * @version $Rev$, $Date$
  45.  */

  46. public class XMLDeserializer implements IDeserializer{

  47.     private net.sf.json.xml.XMLSerializer xmlSerializer;
  48.     private JsonConfig jsonConfig;
  49.     private List<String> morpherPackage = new ArrayList<>();
  50.     private boolean throwExceptionMorpherFailed = true;
  51.    
  52.     public XMLDeserializer(){
  53.         this(new SerializationConfig());
  54.     }
  55.     public XMLDeserializer(SerializationConfig config) {
  56.         this.xmlSerializer = new net.sf.json.xml.XMLSerializer();
  57.         JsonConfig jsonConfig = new JsonConfig();
  58.         if(config.getExcludes()!=null){
  59.             //jsonConfig.setExcludes(excludes); non funziona l'exclude durante la deserializzazione, uso un filtro
  60.             jsonConfig.setJavaPropertyFilter(new ExclusionPropertyFilter(config.getExcludes()));
  61.         }
  62.         this.jsonConfig = jsonConfig;
  63.         this.addMorpherPackage("org.openspcoop2");
  64.     }
  65.    
  66.     public void addMorpherPackage(String p){
  67.         this.morpherPackage.add(p);
  68.     }
  69.    
  70.     public boolean isThrowExceptionMorpherFailed() {
  71.         return this.throwExceptionMorpherFailed;
  72.     }
  73.     public void setThrowExceptionMorpherFailed(boolean throwExceptionMorpherFailed) {
  74.         this.throwExceptionMorpherFailed = throwExceptionMorpherFailed;
  75.     }
  76.    
  77.    
  78.     @Override
  79.     public Object getObject(String s, Class<?> classType) throws IOException{
  80.         return getObject(s, classType, null);
  81.     }
  82.     public Object getListObject(String s, Class<?> listType, Class<?> elementsTypes) throws IOException{
  83.         Object o = getObject(s, listType, elementsTypes);
  84.         if( !(o instanceof List) ){
  85.             throw new IOException("Object de-serializzato di tipo non java.util.List: "+o.getClass().getName());
  86.         }
  87.         return o;
  88.     }
  89.     public Object getSetObject(String s, Class<?> setType, Class<?> elementsTypes) throws IOException{
  90.         Object o = getObject(s, setType, elementsTypes);
  91.         if( !(o instanceof Set) ){
  92.             throw new IOException("Object de-serializzato di tipo non java.util.Set: "+o.getClass().getName());
  93.         }
  94.         return o;
  95.     }
  96.     private Object getObject(String s, Class<?> classType, Class<?> elementsTypes ) throws IOException{
  97.         try{
  98.             return readObject_engine(s, classType, elementsTypes);  
  99.         }catch(Exception e){
  100.             throw new IOException("Trasformazione in oggetto non riuscita: "+e.getMessage(),e);
  101.         }
  102.     }
  103.    
  104.    
  105.    
  106.     @Override
  107.     public Object readObject(InputStream is, Class<?> classType) throws IOException{
  108.         return readObject(is, classType, null);
  109.     }
  110.     public Object readListObject(InputStream is, Class<?> listType, Class<?> elementsTypes) throws IOException{
  111.         Object o = readObject(is, listType, elementsTypes);
  112.         if( !(o instanceof List) ){
  113.             throw new IOException("Object de-serializzato di tipo non java.util.List: "+o.getClass().getName());
  114.         }
  115.         return o;
  116.     }
  117.     public Object readSetObject(InputStream is, Class<?> setType, Class<?> elementsTypes) throws IOException{
  118.         Object o = readObject(is, setType, elementsTypes);
  119.         if( !(o instanceof Set) ){
  120.             throw new IOException("Object de-serializzato di tipo non java.util.Set: "+o.getClass().getName());
  121.         }
  122.         return o;
  123.     }
  124.     private Object readObject(InputStream is, Class<?> classType, Class<?> elementsTypes) throws IOException{
  125.         try{
  126.             ByteArrayOutputStream bout = new ByteArrayOutputStream();
  127. //          byte [] reads = new byte[Utilities.DIMENSIONE_BUFFER];
  128. //          int letti = 0;
  129. //          while( (letti=is.read(reads)) != -1 ){
  130. //              bout.write(reads, 0, letti);
  131. //          }
  132.             CopyStream.copy(is, bout);
  133.             bout.flush();
  134.             bout.close();
  135.            
  136.             return readObject_engine(bout.toString(), classType, elementsTypes);    
  137.            
  138.         }catch(Exception e){
  139.             throw new IOException("Trasformazione in oggetto non riuscita: "+e.getMessage(),e);
  140.         }
  141.     }
  142.    
  143.    
  144.    
  145.     @Override
  146.     public Object readObject(Reader reader, Class<?> classType) throws IOException{
  147.         return readObject(reader, classType, null);
  148.     }
  149.     public Object readListObject(Reader reader, Class<?> listType, Class<?> elementsTypes) throws IOException{
  150.         Object o = readObject(reader, listType, elementsTypes);
  151.         if( !(o instanceof List) ){
  152.             throw new IOException("Object de-serializzato di tipo non java.util.List: "+o.getClass().getName());
  153.         }
  154.         return o;
  155.     }
  156.     public Object readSetObject(Reader reader, Class<?> setType, Class<?> elementsTypes) throws IOException{
  157.         Object o = readObject(reader, setType, elementsTypes);
  158.         if( !(o instanceof Set) ){
  159.             throw new IOException("Object de-serializzato di tipo non java.util.Set: "+o.getClass().getName());
  160.         }
  161.         return o;
  162.     }
  163.     private Object readObject(Reader reader, Class<?> classType, Class<?> elementsTypes) throws IOException{
  164.         try{
  165. //          char [] reads = new char[Utilities.DIMENSIONE_BUFFER];
  166. //          int letti = 0;
  167. //          StringBuilder bf = new StringBuilder();
  168. //          while( (letti=reader.read(reads)) != -1 ){
  169. //              bf.append(reads, 0, letti);
  170. //          }
  171.             StringWriter writer = new StringWriter();
  172.             CopyCharStream.copy(reader, writer);
  173.                        
  174.             return readObject_engine(writer.toString(), classType, elementsTypes);  
  175.            
  176.         }catch(Exception e){
  177.             throw new IOException("Trasformazione in oggetto non riuscita: "+e.getMessage(),e);
  178.         }
  179.     }

  180.    
  181.    
  182.     private Object readObject_engine(String object,Class<?> classType, Class<?> elementsTypes) throws Exception{
  183.        
  184.         boolean list = false;
  185.         try{
  186.             classType.asSubclass(List.class);
  187.             list = true;
  188.         }catch(ClassCastException cc){}
  189.        
  190.         boolean set = false;
  191.         try{
  192.             classType.asSubclass(Set.class);
  193.             set = true;
  194.         }catch(ClassCastException cc){}
  195.        
  196.         //System.out.println("CLASS: "+classType.getName() +" ENUM["+classType.isEnum()+"] ARRAY["+classType.isArray()+"] LISTCAST["+list+"] SETCAST["+set+"]");
  197.        
  198.         if(classType.isEnum()){
  199.            
  200.             Object oResult = this.xmlSerializer.read( object );
  201.             Object en = null;
  202.             if(oResult instanceof JSONObject){
  203.                 JSONObject jsonObject = (JSONObject)  oResult;
  204.                 en = jsonObject.get(jsonObject.keys().next());
  205.             }else{
  206.                 JSONArray jsonArray = (JSONArray)  oResult;
  207.                 en = jsonArray.toArray()[0];
  208.             }
  209.             //System.out.println("TIPO ["+en.getClass().getName()+"]");
  210.             Object [] o = classType.getEnumConstants();
  211.             Class<?> enumeration = o[0].getClass();
  212.             //System.out.println("OO ["+enumeration+"]");
  213.             Method method = enumeration.getMethod("valueOf", String.class);
  214.             Object value = method.invoke(enumeration, en);
  215.             return value;
  216.         }
  217.        
  218.         else if(classType.isArray()){

  219.             Object oResult = this.xmlSerializer.read( object );
  220.             if(oResult instanceof JSONObject){
  221.                 JSONObject jsonObject = (JSONObject)  oResult;
  222.                 Iterator<?> it = jsonObject.keys();
  223.                 Object[] array = new Object[jsonObject.values().size()];
  224.                 int i=0;
  225.                 while(it.hasNext()){
  226.                     Object key = it.next();
  227.                     Object value = jsonObject.get(key);
  228.                     JSONObject json = (JSONObject) value;
  229.                     array[i] =  fromJSONObjectToOriginalObject(classType.getComponentType(), json);
  230.                     i++;
  231.                 }
  232.                 return array;
  233.             }else{
  234.                 JSONArray jsonArray = (JSONArray)  oResult;
  235.                 Object[] oarray = jsonArray.toArray();
  236.                 Object[] array = new Object[oarray.length];
  237.                 for(int i=0; i<oarray.length;i++){
  238.                     JSONObject json = (JSONObject) oarray[i];
  239.                     array[i] =  fromJSONObjectToOriginalObject(classType.getComponentType(), json);
  240.                 }
  241.                 return array;
  242.             }

  243.         }
  244.        
  245.         else if(list){
  246.            
  247.             if(elementsTypes==null){
  248.                 throw new Exception("elementsTypes non definito, e' obbligatorio per il tipo che si desidera de-serializzare: "+classType.getName());
  249.             }
  250.            
  251.             Object oResult = this.xmlSerializer.read( object );
  252.             if(oResult instanceof JSONObject){
  253.                 JSONObject jsonObject = (JSONObject)  oResult;
  254.                 Iterator<?> it = jsonObject.keys();
  255.                 @SuppressWarnings("unchecked")
  256.                 List<Object> listReturn = (List<Object>) ClassLoaderUtilities.newInstance(classType);      
  257.                 while(it.hasNext()){
  258.                     Object key = it.next();
  259.                     Object value = jsonObject.get(key);
  260.                     JSONObject json = (JSONObject) value;
  261.                     Object o =  fromJSONObjectToOriginalObject(elementsTypes, json);
  262.                     listReturn.add(o);
  263.                 }
  264.                 return listReturn;
  265.             }else{
  266.                 JSONArray jsonArray = (JSONArray)  oResult;
  267.                 Object[] oarray = jsonArray.toArray();
  268.                 @SuppressWarnings("unchecked")
  269.                 List<Object> listReturn = (List<Object>) ClassLoaderUtilities.newInstance(classType);      
  270.                 for(int i=0; i<oarray.length;i++){
  271.                     JSONObject json = (JSONObject) oarray[i];
  272.                     Object o =  fromJSONObjectToOriginalObject(elementsTypes, json);
  273.                     listReturn.add(o);
  274.                 }
  275.                 return listReturn;
  276.             }
  277.            
  278.         }
  279.        
  280.         else if(set){
  281.            
  282.             if(elementsTypes==null){
  283.                 throw new Exception("elementsTypes non definito, e' obbligatorio per il tipo che si desidera de-serializzare: "+classType.getName());
  284.             }
  285.            
  286.             Object oResult = this.xmlSerializer.read( object );
  287.             if(oResult instanceof JSONObject){
  288.                 JSONObject jsonObject = (JSONObject)  oResult;
  289.                 Iterator<?> it = jsonObject.keys();
  290.                 @SuppressWarnings("unchecked")
  291.                 Set<Object> setReturn = (Set<Object>) ClassLoaderUtilities.newInstance(classType);      
  292.                 while(it.hasNext()){
  293.                     Object key = it.next();
  294.                     Object value = jsonObject.get(key);
  295.                     JSONObject json = (JSONObject) value;
  296.                     Object o =  fromJSONObjectToOriginalObject(elementsTypes, json);
  297.                     setReturn.add(o);
  298.                 }
  299.                 return setReturn;
  300.             }else{
  301.                 JSONArray jsonArray = (JSONArray)  oResult;
  302.                 Object[] oarray = jsonArray.toArray();
  303.                 @SuppressWarnings("unchecked")
  304.                 Set<Object> setReturn = (Set<Object>) ClassLoaderUtilities.newInstance(classType);          
  305.                 for(int i=0; i<oarray.length;i++){
  306.                     JSONObject json = (JSONObject) oarray[i];
  307.                     Object o =  fromJSONObjectToOriginalObject(elementsTypes, json);
  308.                     setReturn.add(o);
  309.                 }
  310.                 return setReturn;
  311.             }
  312.            
  313.         }
  314.        
  315.         else{
  316.             JSONObject jsonObject = (JSONObject) this.xmlSerializer.read( object );
  317.             return fromJSONObjectToOriginalObject(classType, jsonObject);
  318.         }
  319.     }
  320.    
  321.     private Object fromJSONObjectToOriginalObject(Class<?> classType, JSONObject jsonObject) throws UtilsException{
  322.         this.jsonConfig.setRootClass(classType);
  323.        
  324.         MorpherRegistry morpherRegistry = JSONUtils.getMorpherRegistry();
  325.         org.openspcoop2.utils.serialization.Utilities.registerMorpher(classType, morpherRegistry, new ArrayList<>(), this.morpherPackage);
  326.        
  327.         Object o = JSONObject.toBean( jsonObject, this.jsonConfig );

  328.         org.openspcoop2.utils.serialization.Utilities.morpher(o, morpherRegistry, this.morpherPackage, this.throwExceptionMorpherFailed);
  329.        
  330.         return o;
  331.     }
  332. }