GenericJDBCUtilities.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.generic_project.dao.jdbc.utils;


  21. import java.sql.Connection;
  22. import java.sql.Timestamp;
  23. import java.util.ArrayList;
  24. import java.util.Calendar;
  25. import java.util.Collection;
  26. import java.util.Date;
  27. import java.util.HashMap;
  28. import java.util.List;
  29. import java.util.Map;

  30. import org.openspcoop2.generic_project.beans.AliasField;
  31. import org.openspcoop2.generic_project.beans.ComplexField;
  32. import org.openspcoop2.generic_project.beans.Field;
  33. import org.openspcoop2.generic_project.beans.Function;
  34. import org.openspcoop2.generic_project.beans.FunctionField;
  35. import org.openspcoop2.generic_project.beans.IAliasTableField;
  36. import org.openspcoop2.generic_project.beans.IField;
  37. import org.openspcoop2.generic_project.beans.IModel;
  38. import org.openspcoop2.generic_project.beans.NonNegativeNumber;
  39. import org.openspcoop2.generic_project.beans.Union;
  40. import org.openspcoop2.generic_project.beans.UnionExpression;
  41. import org.openspcoop2.generic_project.beans.UnionOrderedColumn;
  42. import org.openspcoop2.generic_project.beans.UpdateField;
  43. import org.openspcoop2.generic_project.beans.UpdateModel;
  44. import org.openspcoop2.generic_project.dao.jdbc.IJDBCServiceSearchSingleObject;
  45. import org.openspcoop2.generic_project.dao.jdbc.IJDBCServiceSearchWithId;
  46. import org.openspcoop2.generic_project.dao.jdbc.IJDBCServiceSearchWithoutId;
  47. import org.openspcoop2.generic_project.dao.jdbc.JDBCExpression;
  48. import org.openspcoop2.generic_project.dao.jdbc.JDBCPaginatedExpression;
  49. import org.openspcoop2.generic_project.dao.jdbc.JDBCServiceManagerProperties;
  50. import org.openspcoop2.generic_project.exception.ExpressionException;
  51. import org.openspcoop2.generic_project.exception.ExpressionNotImplementedException;
  52. import org.openspcoop2.generic_project.exception.MultipleResultException;
  53. import org.openspcoop2.generic_project.exception.NotFoundException;
  54. import org.openspcoop2.generic_project.exception.NotImplementedException;
  55. import org.openspcoop2.generic_project.exception.ServiceException;
  56. import org.openspcoop2.generic_project.expression.IExpression;
  57. import org.openspcoop2.generic_project.expression.SortOrder;
  58. import org.openspcoop2.generic_project.expression.impl.OrderedField;
  59. import org.openspcoop2.generic_project.expression.impl.sql.ExpressionSQL;
  60. import org.openspcoop2.generic_project.expression.impl.sql.ISQLFieldConverter;
  61. import org.openspcoop2.utils.jdbc.JDBCAdapterException;
  62. import org.openspcoop2.utils.sql.ISQLQueryObject;
  63. import org.openspcoop2.utils.sql.SQLQueryObjectCore;
  64. import org.openspcoop2.utils.sql.SQLQueryObjectException;
  65. import org.slf4j.Logger;

  66. /**
  67.  * JDBCUtilities
  68.  *
  69.  * @author Poli Andrea (apoli@link.it)
  70.  * @author $Author$
  71.  * @version $Rev$, $Date$
  72.  */
  73. public class GenericJDBCUtilities {

  74.     /* *** OTHER *** */
  75.    
  76.     public static void setFields(ISQLQueryObject sqlQueryObject,JDBCPaginatedExpression paginatedExpression, List<String> aliasField, IField ... field) throws ExpressionException{
  77.         setFields(sqlQueryObject, paginatedExpression, aliasField, true, field);
  78.     }
  79.     public static void setFields(ISQLQueryObject sqlQueryObject,JDBCPaginatedExpression paginatedExpression, List<String> aliasField, boolean appendTablePrefix , IField ... field) throws ExpressionException{
  80.         if(field!=null){
  81.             for (int i = 0; i < field.length; i++) {
  82.                 paginatedExpression.addField(sqlQueryObject, field[i], aliasField.get(i), appendTablePrefix);
  83.             }
  84.         }
  85.     }
  86.     public static void setFields(ISQLQueryObject sqlQueryObject,JDBCExpression expression, List<String> aliasField, IField ... field) throws ExpressionException{
  87.         setFields(sqlQueryObject, expression, aliasField, true, field);
  88.     }
  89.     public static void setFields(ISQLQueryObject sqlQueryObject,JDBCExpression expression, List<String> aliasField, boolean appendTablePrefix, IField ... field) throws ExpressionException{
  90.         if(field!=null){
  91.             for (int i = 0; i < field.length; i++) {
  92.                 expression.addField(sqlQueryObject, field[i], aliasField.get(i), appendTablePrefix);
  93.             }
  94.         }
  95.     }
  96.    
  97.     public static void setFields(ISQLQueryObject sqlQueryObject,JDBCPaginatedExpression paginatedExpression, IField ... field) throws ExpressionException{
  98.         setFields(sqlQueryObject, paginatedExpression, true, field);
  99.     }
  100.     public static void setFields(ISQLQueryObject sqlQueryObject,JDBCPaginatedExpression paginatedExpression, boolean appendTablePrefix, IField ... field) throws ExpressionException{
  101.         if(field!=null){
  102.             for (int i = 0; i < field.length; i++) {
  103.                 paginatedExpression.addField(sqlQueryObject, field[i], appendTablePrefix);
  104.             }
  105.         }
  106.     }
  107.     public static void setFields(ISQLQueryObject sqlQueryObject,JDBCExpression expression, IField ... field) throws ExpressionException{
  108.         setFields(sqlQueryObject, expression, true, field);
  109.     }
  110.     public static void setFields(ISQLQueryObject sqlQueryObject,JDBCExpression expression, boolean appendTablePrefix, IField ... field) throws ExpressionException{
  111.         if(field!=null){
  112.             for (int i = 0; i < field.length; i++) {
  113.                 expression.addField(sqlQueryObject, field[i], appendTablePrefix);
  114.             }
  115.         }
  116.     }
  117.    
  118.     public static void setAliasFields(ISQLQueryObject sqlQueryObject,JDBCPaginatedExpression paginatedExpression, IField ... field) throws ExpressionException{
  119.         setAliasFields(sqlQueryObject, paginatedExpression, true, field);
  120.     }
  121.     public static void setAliasFields(ISQLQueryObject sqlQueryObject,JDBCPaginatedExpression paginatedExpression, boolean appendTablePrefix, IField ... field) throws ExpressionException{
  122.         if(field!=null){
  123.             for (int i = 0; i < field.length; i++) {
  124.                 paginatedExpression.addAliasField(sqlQueryObject, field[i], appendTablePrefix);
  125.             }
  126.         }
  127.     }
  128.     public static void setAliasFields(ISQLQueryObject sqlQueryObject,JDBCExpression expression, IField ... field) throws ExpressionException{
  129.         setAliasFields(sqlQueryObject, expression, true, field);
  130.     }
  131.     public static void setAliasFields(ISQLQueryObject sqlQueryObject,JDBCExpression expression, boolean appendTablePrefix, IField ... field) throws ExpressionException{
  132.         if(field!=null){
  133.             for (int i = 0; i < field.length; i++) {
  134.                 expression.addAliasField(sqlQueryObject, field[i], appendTablePrefix);
  135.             }
  136.         }
  137.     }
  138.    
  139.     public static void removeFields(ISQLQueryObject sqlQueryObject,JDBCPaginatedExpression paginatedExpression, IField ... field) throws ExpressionException{
  140.         if(field!=null){
  141.             for (int i = 0; i < field.length; i++) {
  142.                 paginatedExpression.removeFieldManuallyAdd(field[i]);
  143.             }
  144.         }
  145.     }
  146.     public static void removeFields(ISQLQueryObject sqlQueryObject,JDBCExpression expression, IField ... field) throws ExpressionException{
  147.         if(field!=null){
  148.             for (int i = 0; i < field.length; i++) {
  149.                 expression.removeFieldManuallyAdd(field[i]);
  150.             }
  151.         }
  152.     }
  153.    
  154.    
  155.     public static void setFields(ISQLQueryObject sqlQueryObject,JDBCPaginatedExpression paginatedExpression, FunctionField ... functionField) throws ExpressionException{
  156.         setFields(sqlQueryObject, paginatedExpression, true, functionField);
  157.     }
  158.     public static void setFields(ISQLQueryObject sqlQueryObject,JDBCPaginatedExpression paginatedExpression, boolean appendTablePrefix, FunctionField ... functionField) throws ExpressionException{
  159.         if(functionField!=null){
  160.             for (int i = 0; i < functionField.length; i++) {
  161.                 paginatedExpression.addField(sqlQueryObject, functionField[i], appendTablePrefix);
  162.             }
  163.         }
  164.     }
  165.     public static void setFields(ISQLQueryObject sqlQueryObject,JDBCExpression expression, FunctionField ... functionField) throws ExpressionException{
  166.         setFields(sqlQueryObject, expression, true, functionField);
  167.     }
  168.     public static void setFields(ISQLQueryObject sqlQueryObject,JDBCExpression expression, boolean appendTablePrefix, FunctionField ... functionField) throws ExpressionException{
  169.         if(functionField!=null){
  170.             for (int i = 0; i < functionField.length; i++) {
  171.                 expression.addField(sqlQueryObject, functionField[i], appendTablePrefix);
  172.             }
  173.         }
  174.     }
  175.    
  176.     public static void removeFields(ISQLQueryObject sqlQueryObject,JDBCPaginatedExpression paginatedExpression, FunctionField ... functionField) throws ExpressionException{
  177.         if(functionField!=null){
  178.             for (int i = 0; i < functionField.length; i++) {
  179.                 paginatedExpression.removeFieldManuallyAdd(functionField[i]);
  180.             }
  181.         }
  182.     }
  183.     public static void removeFields(ISQLQueryObject sqlQueryObject,JDBCExpression expression, FunctionField ... functionField) throws ExpressionException{
  184.         if(functionField!=null){
  185.             for (int i = 0; i < functionField.length; i++) {
  186.                 expression.removeFieldManuallyAdd(functionField[i]);
  187.             }
  188.         }
  189.     }
  190.    
  191.    
  192.    
  193.     private static List<OrderedField> getOrderedFields(IExpression expression){
  194.         List<OrderedField> listOrderedFields = null;
  195.         if(expression instanceof JDBCPaginatedExpression){
  196.             listOrderedFields = ((JDBCPaginatedExpression)expression).getOrderedFields();
  197.         }
  198.         else if(expression instanceof JDBCExpression){
  199.             listOrderedFields = ((JDBCExpression)expression).getOrderedFields();
  200.         }
  201.         return listOrderedFields;
  202.     }
  203.     private static SortOrder getSortOrder(IExpression expression){
  204.         SortOrder sortOrder = null;
  205.         if(expression instanceof JDBCPaginatedExpression){
  206.             sortOrder = ((JDBCPaginatedExpression)expression).getSortOrder();
  207.         }
  208.         else if(expression instanceof JDBCExpression){
  209.             sortOrder = ((JDBCExpression)expression).getSortOrder();
  210.         }
  211.         return sortOrder;
  212.     }
  213.    
  214.     private static List<IField> getGroupByFields(IExpression expression){
  215.         List<IField> listGroupByFields = null;
  216.         if(expression instanceof JDBCPaginatedExpression){
  217.             listGroupByFields = ((JDBCPaginatedExpression)expression).getGroupByFields();
  218.         }
  219.         else if(expression instanceof JDBCExpression){
  220.             listGroupByFields = ((JDBCExpression)expression).getGroupByFields();
  221.         }
  222.         return listGroupByFields;
  223.     }
  224.    
  225.     private static boolean isUsedForCountExpression(IExpression expression){
  226.         boolean isUsed = false;
  227.         if(expression instanceof JDBCPaginatedExpression){
  228.             isUsed = ((JDBCPaginatedExpression)expression).isUsedForCountExpression();
  229.         }
  230.         else if(expression instanceof JDBCExpression){
  231.             isUsed = ((JDBCExpression)expression).isUsedForCountExpression();
  232.         }
  233.         return isUsed;
  234.     }
  235.    
  236.     private static void setUsedForCountExpression(IExpression expression, boolean value){
  237.         if(expression instanceof JDBCPaginatedExpression){
  238.             ((JDBCPaginatedExpression)expression).setUsedForCountExpression(value);
  239.         }
  240.         else if(expression instanceof JDBCExpression){
  241.             ((JDBCExpression)expression).setUsedForCountExpression(value);
  242.         }
  243.     }
  244.    
  245.     private static void toSqlForPreparedStatementWithFromCondition(IExpression expression,ISQLQueryObject sqlQueryObject,List<Object> listaQuery,String table) throws ExpressionException, ExpressionNotImplementedException{
  246.         if(expression instanceof JDBCPaginatedExpression){
  247.             ((JDBCPaginatedExpression)expression).toSqlForPreparedStatementWithFromCondition(sqlQueryObject,listaQuery,table);
  248.         }
  249.         else if(expression instanceof JDBCExpression){
  250.             ((JDBCExpression)expression).toSqlForPreparedStatementWithFromCondition(sqlQueryObject,listaQuery,table);
  251.         }
  252.     }
  253.    
  254.     private static List<Object> getFieldsManuallyAdd(IExpression expression) {
  255.         List<Object> list = null;
  256.         if(expression instanceof JDBCPaginatedExpression){
  257.             list = ((JDBCPaginatedExpression)expression).getFieldsManuallyAdd();
  258.         }
  259.         else if(expression instanceof JDBCExpression){
  260.             list = ((JDBCExpression)expression).getFieldsManuallyAdd();
  261.         }
  262.         return list;
  263.     }
  264.    
  265.    
  266.     public static NotFoundException newNotFoundException(){
  267.         return new NotFoundException("Not Found");
  268.     }
  269.    
  270.     public static NotImplementedException newNotImplementedException(){
  271.         return new NotImplementedException("NotImplemented");
  272.     }

  273.    
  274.    
  275.    
  276.    
  277.    
  278.     /* *** COUNT *** */
  279.    
  280.     public static List<Object> prepareCount(JDBCServiceManagerProperties jdbcProperties, Logger log, Connection connection, ISQLQueryObject sqlQueryObject,IExpression expression,
  281.             ISQLFieldConverter sqlConverter,IModel<?> model) throws SQLQueryObjectException, JDBCAdapterException, ExpressionException, ExpressionNotImplementedException, ServiceException{
  282.    
  283.         List<OrderedField> listOrderedFields = getOrderedFields(expression);
  284.         SortOrder sortOrder = getSortOrder(expression);
  285.        
  286.         if(listOrderedFields!=null && listOrderedFields.size()>0 && sortOrder!=null && !sortOrder.equals(SortOrder.UNSORTED)){
  287.             throw new ServiceException("OrderBy conditions not allowed in count expression");
  288.         }
  289.    
  290.         List<Object> listaQuery = new ArrayList<>();
  291.    
  292.         boolean oldValue = isUsedForCountExpression(expression);
  293.         setUsedForCountExpression(expression,true);
  294.        
  295.         try{
  296.        
  297.             toSqlForPreparedStatementWithFromCondition(expression,sqlQueryObject,listaQuery,
  298.                     sqlConverter.toTable(model));
  299.            
  300.             return listaQuery;
  301.         }finally{
  302.             setUsedForCountExpression(expression,oldValue);
  303.         }
  304.     }
  305.    
  306.     public static NonNegativeNumber count(JDBCServiceManagerProperties jdbcProperties, Logger log, Connection connection, ISQLQueryObject sqlQueryObject,IExpression expression,
  307.             ISQLFieldConverter sqlConverter,IModel<?> model,List<Object> listaQuery) throws SQLQueryObjectException, JDBCAdapterException, ExpressionException, ExpressionNotImplementedException, ServiceException{
  308.         long totale = 0;

  309.         // check group by per creare una ulteriore select count(*) from ( sql originale )
  310.         String sql = null;
  311.         List<IField> listGroupByFields = getGroupByFields(expression);
  312.         if(listGroupByFields!=null && listGroupByFields.size()>0){
  313.            
  314.             // serve per far aggiungere le colonne di group by all'espressione sqlQueryObject
  315.             for (IField iField : listGroupByFields) {
  316.                 sqlQueryObject.addSelectField(sqlConverter.toColumn(iField,true));
  317.             }
  318.            
  319.             ISQLQueryObject sqlCountGroup = sqlQueryObject.newSQLQueryObject();
  320.             sqlCountGroup.addSelectCountField("groupCount");
  321.             sqlCountGroup.addFromTable(sqlQueryObject);
  322.            
  323.             sql = sqlCountGroup.createSQLQuery();
  324.         }
  325.         else{
  326.             sql = sqlQueryObject.createSQLQuery();
  327.         }
  328.        
  329.         org.openspcoop2.generic_project.dao.jdbc.utils.JDBCPreparedStatementUtilities jdbcUtilities =
  330.                 new org.openspcoop2.generic_project.dao.jdbc.utils.JDBCPreparedStatementUtilities(sqlQueryObject.getTipoDatabaseOpenSPCoop2(), log, connection);

  331.         JDBCObject[] params = new JDBCObject[listaQuery.size()];
  332.         int index = 0;
  333.         for (Object param : listaQuery) {
  334.             params[index++] = new JDBCObject(param, param.getClass());
  335.         }

  336.         totale = jdbcUtilities.count(sql, jdbcProperties.isShowSql(), params);

  337.         return new NonNegativeNumber(totale);
  338.     }
  339.    
  340.    
  341.     /* *** SELECT *** */
  342.    
  343.     public static List<Object> selectSingleObject(List<Map<String,Object>> map) throws NotFoundException {
  344.         if(map.size()<=0){
  345.             throw new NotFoundException("No result founds");
  346.         }
  347.         else{
  348.             List<Object> results = new ArrayList<>();
  349.             for(int i=0; i<map.size(); i++){
  350.                 results.add(map.get(i).values().iterator().next());    
  351.             }
  352.             return results;
  353.         }
  354.     }
  355.    
  356.    
  357.     /* *** AGGREGATE *** */
  358.    
  359.     public static Object selectAggregateObject(Map<String,Object> map,FunctionField functionField) throws NotFoundException {
  360.         if(map.size()<=0){
  361.             throw new NotFoundException("No result founds");
  362.         }
  363.         else{
  364.             return map.get(functionField.getAlias());
  365.         }
  366.     }
  367.    
  368.    
  369.     /* *** _SELECT *** */
  370.    
  371.     private static List<Object> toSqlForPreparedStatementFromCondition(IExpression expression,ISQLQueryObject sqlQueryObject,
  372.             List<Object> listaQuery,List<JDBCObject> params,ISQLFieldConverter sqlConverter,IModel<?> model) throws ExpressionException, ExpressionNotImplementedException{
  373.        
  374.         toSqlForPreparedStatementWithFromCondition(expression,sqlQueryObject,listaQuery,sqlConverter.toTable(model));
  375.         List<Object> returnField = getFieldsManuallyAdd(expression);
  376.         for (Object param : listaQuery) {
  377.             params.add( new JDBCObject(param, param.getClass()) );
  378.         }
  379.        
  380.         return returnField;
  381.     }
  382.    
  383.     private static List<Object> eliminaDuplicati(Collection<Object> returnField){
  384.         List<Object> listSenzaDuplicati = new ArrayList<>();
  385.         for (Object o : returnField) {
  386.             if(o instanceof IField){
  387.                 IField field = (IField) o;
  388.                
  389.                 boolean found = false;
  390.                 for (Object check : listSenzaDuplicati) {
  391.                     if(check instanceof IField){
  392.                         IField iFieldCheck = (IField) check;
  393.                         if(iFieldCheck.equals(field)){
  394.                             // gia esiste
  395.                             found = true;
  396.                             break;
  397.                         }
  398.                     }
  399.                 }
  400.                
  401.                 if(!found){
  402.                     listSenzaDuplicati.add(o);
  403.                 }
  404.             }
  405.             else if(o instanceof FunctionField){
  406.                
  407.                 FunctionField field = (FunctionField) o;
  408.                
  409.                 boolean found = false;
  410.                 for (Object check : listSenzaDuplicati) {
  411.                     if(check instanceof FunctionField){
  412.                         FunctionField functionFieldCheck = (FunctionField) check;
  413.                         if(functionFieldCheck.equals(field)){
  414.                             // gia esiste
  415.                             found = true;
  416.                             break;
  417.                         }
  418.                     }
  419.                 }
  420.                
  421.                 if(!found){
  422.                     listSenzaDuplicati.add(o);
  423.                 }
  424.            
  425.             }
  426.         }
  427.         return listSenzaDuplicati;
  428.     }
  429.    
  430.     private static List<Class<?>> readClassTypes(Collection<Object> returnField){
  431.         List<Class<?>> returnClassTypes = new ArrayList<Class<?>>();
  432.         for (Object o : returnField) {
  433.             if(o instanceof IField){
  434.                 IField field = (IField) o;
  435.                 returnClassTypes.add(field.getFieldType());
  436.             }
  437.             else if(o instanceof FunctionField){
  438.                 FunctionField field = (FunctionField) o;
  439.                 if(field.getFieldType().toString().equals(Date.class.toString()) ||
  440.                         field.getFieldType().toString().equals(java.sql.Date.class.toString()) ||
  441.                         field.getFieldType().toString().equals(Timestamp.class.toString()) ||
  442.                         field.getFieldType().toString().equals(Calendar.class.toString())){
  443.                     returnClassTypes.add(Long.class);
  444.                 }
  445.                 else{
  446.                     returnClassTypes.add(field.getFieldType());
  447.                 }          
  448.             }
  449.         }
  450.         return returnClassTypes;
  451.     }
  452.    
  453.     private static List<List<String>> readAliases(Collection<Object> returnField) throws ServiceException{
  454.        
  455.         // inizializzo
  456.         List<List<String>> returnClassAliases = new ArrayList<List<String>>();
  457.         for (int i = 0; i < returnField.size(); i++) {
  458.             returnClassAliases.add(new ArrayList<>());
  459.         }
  460.        
  461.         // aggiungo i field semplici (foglie, vale per Field,ConstantField,CustomField,NullConstantField)
  462.         List<String> returnClassAliases_simple = new ArrayList<>();
  463.         int index = 0;
  464.         for (Object o : returnField) {
  465.             if(o instanceof Field){
  466.                 IField field = (IField) o;
  467.                 String nome = field.getFieldName();
  468.                 returnClassAliases_simple.add(nome);
  469.                 returnClassAliases.get(index).add(nome);
  470.             }
  471.             index++;
  472.         }
  473.        
  474.         // gestisco tutti gli oggetti
  475.         index = 0;
  476.         for (Object o : returnField) {
  477.             if(o instanceof IField){
  478.                
  479.                 if(o instanceof AliasField){
  480.                     AliasField af = (AliasField) o;
  481.                    
  482.                     String nome = af.getAlias();
  483.                     if(returnClassAliases_simple.contains(nome)){
  484.                         throw new ServiceException("AliasField contains alias ["+nome+"] is already used for simple select field. Choose different alias name");
  485.                     }
  486.                     returnClassAliases.get(index).add(nome);
  487.                    
  488.                     IField field = af.getField();
  489.                     StringBuilder bf = new StringBuilder();
  490.                     buildAliasesPrefix(field,bf);
  491.                     String nomeField = bf.toString();
  492.                     if(!returnClassAliases_simple.contains(nome)){
  493.                         returnClassAliases.get(index).add(nomeField);
  494.                     }
  495.                 }
  496.                 else if(o instanceof IAliasTableField){
  497.                     StringBuilder bf = new StringBuilder();
  498.                     buildAliasesPrefix((IField)o,bf);
  499.                     returnClassAliases.get(index).add(bf.toString());
  500.                 }
  501.                 else if(o instanceof ComplexField){
  502.                     StringBuilder bf = new StringBuilder();
  503.                     buildAliasesPrefix((IField)o,bf);
  504.                     returnClassAliases.get(index).add(bf.toString());
  505.                 }

  506.             }
  507.             else if(o instanceof FunctionField){
  508.                 FunctionField field = (FunctionField) o;
  509.                 String nome = field.getAlias();
  510.                 if(returnClassAliases_simple.contains(nome)){
  511.                     throw new ServiceException("FunctionAliasName ["+nome+"] is already used for simple select field. Choose different alias name");
  512.                 }
  513.                 returnClassAliases.get(index).add(nome);
  514.             }
  515.             index++;
  516.         }

  517.         return returnClassAliases;
  518.     }
  519.    
  520.     public static String getAlias(Object object) throws ServiceException{
  521.         List<Object> l = new ArrayList<>();
  522.         l.add(object);
  523.         List<List<String>> ll = readAliases(l);
  524.         if( (ll==null) || ll.size()<=0){
  525.             throw new ServiceException("Build alias error");
  526.         }
  527.         if(ll.get(0)==null || ll.get(0).size()<=0){
  528.             throw new ServiceException("Build alias error (internal)");
  529.         }
  530.         return ll.get(0).get(0);
  531.     }
  532.    
  533.     private static void buildAliasesPrefix(IField field,StringBuilder prefix){
  534.        
  535.         if(field instanceof IAliasTableField){
  536.             prefix.append(((IAliasTableField)field).getAliasTable()).
  537.                 append(".").
  538.                 append(field.getFieldName());
  539.         }
  540.         else{
  541.        
  542.             if(field instanceof ComplexField){
  543.                 ComplexField c = (ComplexField) field;
  544.                 buildAliasesPrefix(c.getFather(), prefix);
  545.             }
  546.            
  547.             if(prefix.length()>0){
  548.                 prefix.append(".");
  549.             }
  550.             prefix.append(field.getFieldName());
  551.                
  552.         }
  553.     }

  554.     public static List<Object> prepareSelect(JDBCServiceManagerProperties jdbcProperties, Logger log, Connection connection, ISQLQueryObject sqlQueryObject,
  555.             IExpression expression,ISQLFieldConverter sqlConverter,IModel<?> model,
  556.             List<Object> listaQuery,List<JDBCObject> listaParams) throws NotFoundException, ServiceException, SQLQueryObjectException, JDBCAdapterException, ExpressionException, ExpressionNotImplementedException{
  557.        
  558.         List<Object> returnField =
  559.             org.openspcoop2.generic_project.dao.jdbc.utils.GenericJDBCUtilities.toSqlForPreparedStatementFromCondition(expression,sqlQueryObject,listaQuery,listaParams,
  560.                             sqlConverter,model);
  561.            
  562.         return returnField;
  563.     }
  564.        
  565.     public static ISQLQueryObject prepareSqlQueryObjectForSelectDistinct(boolean distinct, ISQLQueryObject sqlQueryObject, IExpression expression,
  566.             Logger log, ISQLFieldConverter sqlFieldConverter,IField ... field) throws SQLQueryObjectException, ExpressionException{
  567.         ISQLQueryObject sqlQueryObjectDistinct = null;
  568.         if(distinct){
  569.            
  570.             if(((SQLQueryObjectCore)sqlQueryObject).isSelectForUpdate()){
  571.                 throw new SQLQueryObjectException("Non è possibile abilitare il comando 'selectForUpdate' se viene utilizzata la clausola DISTINCT");
  572.             }
  573.            
  574.             sqlQueryObjectDistinct = sqlQueryObject.newSQLQueryObject();
  575.             JDBCPaginatedExpression paginatedExpressionTmp = new JDBCPaginatedExpression(sqlFieldConverter);
  576.             org.openspcoop2.generic_project.dao.jdbc.utils.GenericJDBCUtilities.setAliasFields(sqlQueryObjectDistinct,paginatedExpressionTmp,false,field);
  577.             sqlQueryObjectDistinct.setSelectDistinct(true);
  578.             List<OrderedField> listOrderedFields = getOrderedFields(expression);
  579.             SortOrder sortOrder = getSortOrder(expression);
  580.             if(listOrderedFields!=null &&  listOrderedFields.size()>0 &&
  581.                     sortOrder!=null &&
  582.                     !SortOrder.UNSORTED.equals(sortOrder)){
  583.                 boolean orderBy = false;
  584.                 for (OrderedField orderedFieldBean : listOrderedFields) {
  585.                     IField orderedField = orderedFieldBean.getField();
  586.                     boolean contains = false;
  587.                     for (int i = 0; i < field.length; i++) {
  588.                         if(orderedField.equals(field[i])){
  589.                             contains = true;
  590.                             break;
  591.                         }
  592.                     }
  593.                     if(contains){
  594.                         sqlQueryObjectDistinct.addOrderBy(sqlFieldConverter.toColumn(orderedField, false), SortOrder.ASC.equals(orderedFieldBean.getSortOrder()));
  595.                         orderBy = true;
  596.                     }
  597.                 }
  598.                 if(orderBy)
  599.                     sqlQueryObjectDistinct.setSortType(SortOrder.ASC.equals(sortOrder));
  600.             }
  601.         }
  602.         return sqlQueryObjectDistinct;
  603.     }
  604.    
  605.     public static ISQLQueryObject prepareSqlQueryObjectForSelectDistinct(ISQLQueryObject sqlQueryObject, ISQLQueryObject sqlQueryObjectDistinct) throws SQLQueryObjectException{
  606.         ISQLQueryObject sqlQueryObjectExecute = sqlQueryObject;
  607.         if(sqlQueryObjectDistinct!=null){
  608.             sqlQueryObjectDistinct.addFromTable(sqlQueryObject);
  609.             sqlQueryObjectExecute = sqlQueryObjectDistinct;
  610.         }
  611.         return sqlQueryObjectExecute;
  612.     }
  613.    
  614.     public static List<Map<String,Object>> select(JDBCServiceManagerProperties jdbcProperties, Logger log, Connection connection, ISQLQueryObject sqlQueryObject,
  615.             IExpression expression,ISQLFieldConverter sqlConverter,IModel<?> model,
  616.             List<Object> listaQuery,List<JDBCObject> listaParams, List<Object> returnField) throws NotFoundException, ServiceException, SQLQueryObjectException, JDBCAdapterException, ExpressionException, ExpressionNotImplementedException{
  617.        
  618.         // Se sono impostati groupBy, le condizioni di order by devono essere colonne definite anche nel group by
  619.         List<IField> listGroupByFields = getGroupByFields(expression);
  620.         if(listGroupByFields!=null && listGroupByFields.size()>0){
  621.             List<OrderedField> listOrderedFields = getOrderedFields(expression);
  622.             if(listOrderedFields!=null && listOrderedFields.size()>0){
  623.                 for (OrderedField orderedField : listOrderedFields) {
  624.                     IField iField = orderedField.getField();
  625.                     if(listGroupByFields.contains(iField)==false){
  626.                         throw new ServiceException("The field used for order by condition is invalid because it is not contained in GROUP BY clause. Field: ["+iField.toString()+"]");
  627.                     }
  628.                 }
  629.             }
  630.         }
  631.        
  632.         org.openspcoop2.generic_project.dao.jdbc.utils.JDBCPreparedStatementUtilities jdbcUtilities =
  633.                 new org.openspcoop2.generic_project.dao.jdbc.utils.JDBCPreparedStatementUtilities(sqlQueryObject.getTipoDatabaseOpenSPCoop2(), log, connection);
  634.                
  635.         String sql = sqlQueryObject.createSQLQuery();

  636.         JDBCObject[] params = null;
  637.         if(listaParams.size()>0){
  638.             params = listaParams.toArray(new JDBCObject[1]);
  639.         }
  640.        
  641.         returnField = eliminaDuplicati(returnField);
  642.        
  643.         List<Class<?>> returnClassTypes = org.openspcoop2.generic_project.dao.jdbc.utils.GenericJDBCUtilities.readClassTypes(returnField);
  644.         List<List<String>> returnClassAliases = org.openspcoop2.generic_project.dao.jdbc.utils.GenericJDBCUtilities.readAliases(returnField);
  645.                
  646.         List<Map<String,Object>> result = new ArrayList<Map<String,Object>>();
  647.        
  648.         List<List<Object>> resultExecuteQuery = jdbcUtilities.executeQuery(sql, jdbcProperties.isShowSql(), returnClassTypes ,params);
  649.         if(resultExecuteQuery.size()>0){            
  650.             for (int i = 0; i < resultExecuteQuery.size(); i++) {
  651.                 List<Object> lista = resultExecuteQuery.get(i);
  652.                 if(lista==null){
  653.                     throw new ServiceException("Result["+i+"] is null?");
  654.                 }
  655.                 if(lista.size()!=returnField.size()){
  656.                     throw new ServiceException("Result["+i+"] has wrong length (expected:"+returnField.size()+" founded:"+lista.size()+")");
  657.                 }
  658.                 Map<String,Object> resultList = new HashMap<>();
  659.                 for (int j = 0; j < lista.size(); j++) {
  660.                     Object object = lista.get(j);
  661.                     for (String key : returnClassAliases.get(j)) {
  662.                         if(object!=null)
  663.                             resultList.put(key, object);
  664.                         else
  665.                             resultList.put(key, org.apache.commons.lang.ObjectUtils.NULL);  
  666.                     }
  667.                 }
  668.                 result.add(resultList);
  669.             }      
  670.         }
  671.        
  672.         if(result.size()<=0){
  673.             throw new NotFoundException("No result founds");
  674.         }
  675.        
  676.         return result;
  677.     }
  678.    
  679.    
  680.     /* *** UNION *** */
  681.    
  682.     public static List<Class<?>> checkUnionExpression(UnionExpression ... expression) throws ServiceException{
  683.         if(expression==null || expression.length<=0){
  684.             throw new ServiceException("UnionExpression not found");
  685.         }
  686.         if(expression.length==1){
  687.             throw new ServiceException("At least two expressions are required");
  688.         }
  689.        
  690.         List<Class<?>> listClassReturnType = new ArrayList<Class<?>>();
  691.        
  692.         for (int i = 0; i < expression.length; i++) {
  693.            
  694.             UnionExpression ue = expression[i];
  695.             List<String> aliasUe = ue.getReturnFieldAliases();
  696.            
  697.             if(aliasUe.size()<=0){
  698.                 throw new ServiceException("The expression n."+(i+1)+" contains no select field");
  699.             }
  700.            
  701.             // check with other expression
  702.             for (int j = 0; j < expression.length; j++) {
  703.                 if(j==i){
  704.                     continue;
  705.                 }
  706.                 UnionExpression checkUe = expression[j];
  707.                 List<String> checkAliasUe = checkUe.getReturnFieldAliases();
  708.                
  709.                 if(checkAliasUe.size()<=0){
  710.                     throw new ServiceException("The expression n."+(j+1)+" contains no select field");
  711.                 }
  712.                
  713.                 String errorMsg = "All expressions must contain the same number of select field with the same alias in the same order. ";
  714.                
  715.                 if(checkAliasUe.size()!=aliasUe.size()){
  716.                     throw new ServiceException(errorMsg+"Found expression that contains a different number of select field ("+
  717.                                                 (i+1)+"-exp:"+aliasUe.size()+" "+(j+1)+"-exp:"+checkAliasUe.size()+")");
  718.                 }
  719.                
  720.                 int index = 0;
  721.                 for (String checkAlias : checkAliasUe) {
  722.                     int index_interno = 0;
  723.                     for (String ueAlias : aliasUe) {
  724.                         if(index==index_interno){
  725.                             if(checkAlias.equals(ueAlias)==false){
  726.                                 throw new ServiceException(errorMsg+"Found expression that contains a different alias for select field n."+index+" ("+
  727.                                         (i+1)+"-exp alias:"+ueAlias+" "+(j+1)+"-exp alias:"+checkAlias+")");
  728.                             }
  729.                         }
  730.                         index_interno++;
  731.                     }
  732.                     index++;
  733.                 }
  734.                
  735. //              index = 0;
  736. //              for (Object checkObject : checkObjectUe) {
  737. //                  int index_interno = 0;
  738. //                  for (Object ueObject : objectUe) {
  739. //                      if(index==index_interno){
  740.                            
  741.                             // TODO Eventuale check sui tipi, pero' non dovrebbe servire, e' il SQL stesso che darebbe errore.
  742. //                      }
  743. //                  }
  744. //              }
  745.                
  746.             }
  747.            
  748.             if(i==0){
  749.                 // Uso i tipi della prima espressione. Dovrebbero essere tutti compatibili tra loro
  750.                 List<Object> listaObject = new ArrayList<>();
  751.                 for (String alias : aliasUe) {
  752.                     listaObject.add(ue.getReturnField(alias));
  753.                 }
  754.                 listClassReturnType = readClassTypes(listaObject);
  755.             }
  756.         }
  757.         return listClassReturnType;
  758.     }
  759.    
  760.     public static void checkUnionExpression(Union union,UnionExpression expressionComparator,ISQLQueryObject sqlQueryObject) throws ServiceException, SQLQueryObjectException{
  761.        
  762.         // Check select field
  763.         List<String> listaFields = union.getFields();
  764.         if(listaFields!=null && listaFields.size()>0){
  765.            
  766.             for (String alias : listaFields) {
  767.                
  768.                 Function function = union.getFunction(alias);
  769.                 String paramAliasFunction = union.getParamAliasFunction(alias);
  770.                 String customFieldValue = union.getCustomFieldValue(alias);
  771.                 String aliasCheck = null;
  772.                
  773.                 if(paramAliasFunction==null){
  774.                     // selezionato direttamente una colonna risultato delle espressioni interne
  775.                     // quando arrivo in questo metodo mi viene garantito dal metodo checkUnionExpression(expression ... )
  776.                     // che ogni espressione interna possiede lo stesso alias
  777.                
  778.                     if(customFieldValue==null) {
  779.                         aliasCheck = alias;
  780.                     }
  781.                     //else non devo controllare l'alias poiche' potrebbe essere il risultato della combinazione degli elementi ritornati dalle espressioni union  
  782.                 }
  783.                 else{
  784.                     aliasCheck = paramAliasFunction;
  785.                 }
  786.                
  787.                 if(aliasCheck!=null) {
  788.                     if(expressionComparator.getReturnFieldAliases()==null || !expressionComparator.getReturnFieldAliases().contains(aliasCheck)){
  789.                         throw new ServiceException("The alias ["+aliasCheck+"] is unknown. Check the alias used in the internal union expression");
  790.                     }
  791.                 }
  792.                
  793.                 if(paramAliasFunction==null){
  794.                     if(customFieldValue==null) {
  795.                         sqlQueryObject.addSelectField(alias);
  796.                     }
  797.                     else {
  798.                         sqlQueryObject.addSelectAliasField(customFieldValue, alias);
  799.                     }
  800.                 }else{
  801.                     ExpressionSQL.setFunction(function, false, paramAliasFunction, alias, sqlQueryObject);
  802.                 }
  803.             }

  804.         }
  805.        
  806.         // Check eventuali group by siano alias che corrispondano ad alias reali
  807.         if(union.getGroupByList()!=null && union.getGroupByList().size()>0){
  808.             List<String> aliasExpression = expressionComparator.getReturnFieldAliases();
  809.             for (String aliasGroupBy : union.getGroupByList()) {
  810.                 if(aliasExpression.contains(aliasGroupBy)==false){
  811.                     throw new ServiceException("The alias used in the condition of group by the union must be one of the aliases used in internal expressions");
  812.                 }
  813.                 sqlQueryObject.addGroupBy(aliasGroupBy);
  814.             }
  815.         }
  816.        
  817.         // Check eventuali order by siano alias che corrispondano ad alias reali
  818.         if(union.getOrderByList()!=null && union.getOrderByList().size()>0){
  819.             SortOrder sortOrderUnion = null;
  820.             try{
  821.                 sortOrderUnion = union.getSortOrder();
  822.             }catch(Exception e){
  823.                 throw new ServiceException(e.getMessage(),e);
  824.             }
  825.             if(!SortOrder.UNSORTED.equals(sortOrderUnion)){
  826.                 List<String> aliasExpression = expressionComparator.getReturnFieldAliases();
  827.                 List<String> aliasExternalExpression = union.getFields();
  828.                 for (UnionOrderedColumn uoo : union.getOrderByList()) {
  829.                     String aliasOrderBy = uoo.getAlias();
  830.                     SortOrder sortOrder = uoo.getSortOrder();
  831.                     if(aliasExpression.contains(aliasOrderBy)==false && aliasExternalExpression.contains(aliasOrderBy)==false){
  832.                         throw new ServiceException("The alias '"+aliasOrderBy+"' used in the condition of order by the union must be one of the aliases used in internal or external expressions");
  833.                     }
  834.                     if(sortOrder==null){
  835.                         sqlQueryObject.addOrderBy(aliasOrderBy);
  836.                     }
  837.                     else{
  838.                         sqlQueryObject.addOrderBy(aliasOrderBy,SortOrder.ASC.equals(sortOrder));
  839.                     }
  840.                 }
  841.                 sqlQueryObject.setSortType(SortOrder.ASC.equals(sortOrderUnion));
  842.             }
  843.         }
  844.        
  845.         // Check Limit/Offset
  846.         if(union.getLimit()!=null){
  847.             sqlQueryObject.setLimit(union.getLimit());
  848.         }
  849.         if(union.getOffset()!=null){
  850.             sqlQueryObject.setOffset(union.getOffset());
  851.         }
  852.        
  853.     }
  854.    
  855.     protected static void setFields(List<ISQLQueryObject> sqlQueryObjectInnerList,UnionExpression ... unionExpression) throws ExpressionException, ServiceException{
  856.         manageFields(sqlQueryObjectInnerList, true, false, unionExpression);
  857.     }
  858.     protected static void removeFields(List<ISQLQueryObject> sqlQueryObjectInnerList,UnionExpression ... unionExpression) throws ExpressionException, ServiceException{
  859.         manageFields(sqlQueryObjectInnerList, false, true, unionExpression);
  860.     }
  861.     private static void manageFields(List<ISQLQueryObject> sqlQueryObjectInnerList,boolean set,boolean remove,UnionExpression ... unionExpression) throws ExpressionException, ServiceException{
  862.         if(unionExpression==null || unionExpression.length<=0){
  863.             throw new ServiceException("UnionExpression not found");
  864.         }
  865.         if(unionExpression.length==1){
  866.             throw new ServiceException("At least two expressions are required");
  867.         }
  868.        
  869.         for (int i = 0; i < unionExpression.length; i++) {
  870.            
  871.             ISQLQueryObject sqlQueryObject = sqlQueryObjectInnerList.get(i);
  872.            
  873.             UnionExpression ue = unionExpression[i];
  874.             IExpression exp = ue.getExpression();
  875. //          List<IField> listField = new ArrayList<IField>();
  876. //          List<FunctionField> listFunctionField = new ArrayList<FunctionField>();    
  877.             List<String> aliasUE = ue.getReturnFieldAliases();
  878.             for (String alias : aliasUE) {
  879.                 Object o = ue.getReturnField(alias);
  880.                 if(o instanceof IField){
  881.                     IField field = (IField) o;
  882.                     //listField.add(field);
  883.                    
  884.                     if(set){
  885.                         List<String> lAlias = new ArrayList<>();
  886.                         lAlias.add(alias);
  887.                         if(exp instanceof JDBCExpression){
  888.                             setFields(sqlQueryObject, ((JDBCExpression)exp), lAlias, field);
  889.                         }else{
  890.                             setFields(sqlQueryObject, ((JDBCPaginatedExpression)exp), lAlias, field);
  891.                         }
  892.                     }
  893.                     else{
  894.                         if(exp instanceof JDBCExpression){
  895.                             removeFields(sqlQueryObject, ((JDBCExpression)exp), field);
  896.                         }else{
  897.                             removeFields(sqlQueryObject, ((JDBCPaginatedExpression)exp), field);
  898.                         }
  899.                     }
  900.                    
  901.                 }
  902.                 else if(o instanceof FunctionField){
  903.                     FunctionField field = (FunctionField) o;
  904.                     //listFunctionField.add(field);    
  905.                    
  906.                     if(set){
  907.                         if(exp instanceof JDBCExpression){
  908.                             setFields(sqlQueryObject, ((JDBCExpression)exp), field);
  909.                         }else{
  910.                             setFields(sqlQueryObject, ((JDBCPaginatedExpression)exp), field);
  911.                         }
  912.                     }
  913.                     else{
  914.                         if(exp instanceof JDBCExpression){
  915.                             removeFields(sqlQueryObject, ((JDBCExpression)exp), field);
  916.                         }else{
  917.                             removeFields(sqlQueryObject, ((JDBCPaginatedExpression)exp), field);
  918.                         }
  919.                     }
  920.                 }
  921.             }
  922.            
  923.             /*
  924.             IField[] fields = null;
  925.             if(listField.size()>0){
  926.                 fields = listField.toArray(new IField[1]);
  927.             }
  928.             if(set){
  929.                 if(exp instanceof JDBCExpression){
  930.                     setFields(sqlQueryObject, ((JDBCExpression)exp), aliasUe, fields);
  931.                 }else{
  932.                     setFields(sqlQueryObject, ((JDBCPaginatedExpression)exp), aliasUe, fields);
  933.                 }
  934.             }
  935.             else{
  936.                 if(exp instanceof JDBCExpression){
  937.                     removeFields(sqlQueryObject, ((JDBCExpression)exp), fields);
  938.                 }else{
  939.                     removeFields(sqlQueryObject, ((JDBCPaginatedExpression)exp), fields);
  940.                 }
  941.             }
  942.            
  943.             FunctionField[] functionFields = null;
  944.             if(listFunctionField.size()>0){
  945.                 functionFields = listFunctionField.toArray(new FunctionField[1]);
  946.             }
  947.             if(set){
  948.                 if(exp instanceof JDBCExpression){
  949.                     setFields(sqlQueryObject, ((JDBCExpression)exp), functionFields);
  950.                 }else{
  951.                     setFields(sqlQueryObject, ((JDBCPaginatedExpression)exp), functionFields);
  952.                 }
  953.             }
  954.             else{
  955.                 if(exp instanceof JDBCExpression){
  956.                     removeFields(sqlQueryObject, ((JDBCExpression)exp), functionFields);
  957.                 }else{
  958.                     removeFields(sqlQueryObject, ((JDBCPaginatedExpression)exp), functionFields);
  959.                 }
  960.             }
  961.             */
  962.         }
  963.     }
  964.    
  965.     public static List<Class<?>> prepareUnion(JDBCServiceManagerProperties jdbcProperties, Logger log, Connection connection, ISQLQueryObject sqlQueryObject,
  966.             ISQLFieldConverter sqlConverter,IModel<?> model,
  967.             List<ISQLQueryObject> sqlQueryObjectInnerList,List<JDBCObject> jdbcObjects,
  968.             Union union,UnionExpression ... unionExpression) throws NotFoundException, ExpressionException, ExpressionNotImplementedException, SQLQueryObjectException, JDBCAdapterException, ServiceException{
  969.            
  970.         if(sqlQueryObject==null) {
  971.             throw new SQLQueryObjectException("sqlQueryObject parameter is null");
  972.         }
  973.         if(sqlConverter==null) {
  974.             throw new SQLQueryObjectException("sqlConverter parameter is null");
  975.         }
  976.         if(model==null) {
  977.             throw new SQLQueryObjectException("model parameter is null");
  978.         }
  979.         if(sqlQueryObjectInnerList==null) {
  980.             throw new SQLQueryObjectException("sqlQueryObjectInnerList parameter is null");
  981.         }
  982.         if(jdbcObjects==null) {
  983.             throw new SQLQueryObjectException("jdbcObjects parameter is null");
  984.         }
  985.         if(union==null) {
  986.             throw new SQLQueryObjectException("union parameter is null");
  987.         }
  988.         if(unionExpression==null) {
  989.             throw new SQLQueryObjectException("unionExpression parameter is null");
  990.         }
  991.        
  992.         // check expression
  993.         List<Class<?>> returnClassTypes = checkUnionExpression(unionExpression);
  994.    
  995.         // check union external expression
  996.         // quando arrivo in questo metodo mi viene garantito dal metodo checkUnionExpression(expression ... )
  997.         // che ogni espressione interna possiede lo stesso alias e che cmq esistano almeno 2 espressioni
  998.         checkUnionExpression(union,unionExpression[0],sqlQueryObject);
  999.        
  1000.         // set fields in expression
  1001.         for (int i = 0; i < unionExpression.length; i++) {
  1002.             ISQLQueryObject sqlQueryObjectInner = sqlQueryObject.newSQLQueryObject();
  1003.             sqlQueryObjectInner.setANDLogicOperator(true);
  1004.             sqlQueryObjectInnerList.add(sqlQueryObjectInner);
  1005.             //System.out.println("UE["+i+"]: "+unionExpression[i].getReturnFieldAliases());
  1006.         }
  1007.         setFields(sqlQueryObjectInnerList, unionExpression);
  1008. //      if(sqlQueryObjectInnerList.size()==2) {
  1009. //          System.out.println("SET FIELDS AAAAAAAAAAAAA: "+sqlQueryObjectInnerList.size());
  1010. //          System.out.println("SET FIELDS AAAAAAAAAAAAA [0]="+sqlQueryObjectInnerList.get(0).getFieldsName());
  1011. //          System.out.println("SET FIELDS AAAAAAAAAAAAA [1]="+sqlQueryObjectInnerList.get(1).getFieldsName());
  1012. //      }
  1013.         // non serve il remove,  SONO SQL FIELD CREATI INTERNAMENTE
  1014.        
  1015.         // Create sql query object
  1016.         for (int i = 0; i < unionExpression.length; i++) {

  1017.             IExpression expr = unionExpression[i].getExpression();
  1018.            
  1019.             ISQLQueryObject sqlQueryObjectInner = sqlQueryObjectInnerList.get(i);
  1020.            
  1021.             List<Object> listaQuery = new ArrayList<>();
  1022.             toSqlForPreparedStatementWithFromCondition(expr,sqlQueryObjectInner,listaQuery,sqlConverter.toTable(model));
  1023.             for (Object param : listaQuery) {
  1024.                 jdbcObjects.add(new JDBCObject(param, param.getClass()));
  1025.             }
  1026.            
  1027.         }
  1028.        
  1029. //      if(sqlQueryObjectInnerList.size()==2) {
  1030. //          System.out.println("DOPO AAAAAAAAAAAAA: "+sqlQueryObjectInnerList.size());
  1031. //          System.out.println("DOPO AAAAAAAAAAAAA [0]="+sqlQueryObjectInnerList.get(0).getFieldsName());
  1032. //          System.out.println("DOPO AAAAAAAAAAAAA [1]="+sqlQueryObjectInnerList.get(1).getFieldsName());
  1033. //      }
  1034.        
  1035.         return returnClassTypes;
  1036.     }
  1037.        
  1038.     public static List<Map<String,Object>> union(JDBCServiceManagerProperties jdbcProperties, Logger log, Connection connection, ISQLQueryObject sqlQueryObject,
  1039.             ISQLFieldConverter sqlConverter,IModel<?> model,
  1040.             List<ISQLQueryObject> sqlQueryObjectInnerList,List<JDBCObject> jdbcObjects, List<Class<?>> returnClassTypes,
  1041.             Union union,UnionExpression ... unionExpression) throws NotFoundException, ExpressionException, ExpressionNotImplementedException, SQLQueryObjectException, JDBCAdapterException, ServiceException{
  1042.                    
  1043.         if(jdbcProperties==null) {
  1044.             throw new ServiceException("jdbcProperties is null");
  1045.         }
  1046.         if(sqlQueryObject==null) {
  1047.             throw new ServiceException("sqlQueryObject is null");
  1048.         }
  1049.         if(sqlQueryObjectInnerList==null) {
  1050.             throw new ServiceException("sqlQueryObjectInnerList is null");
  1051.         }
  1052.         if(jdbcObjects==null) {
  1053.             throw new ServiceException("jdbcObjects is null");
  1054.         }
  1055.         if(returnClassTypes==null) {
  1056.             throw new ServiceException("returnClassTypes is null");
  1057.         }
  1058.         if(union==null) {
  1059.             throw new ServiceException("union is null");
  1060.         }
  1061.         if(unionExpression==null) {
  1062.             throw new ServiceException("unionExpression is null");
  1063.         }
  1064.        
  1065.         org.openspcoop2.generic_project.dao.jdbc.utils.JDBCPreparedStatementUtilities jdbcUtilities =
  1066.             new org.openspcoop2.generic_project.dao.jdbc.utils.JDBCPreparedStatementUtilities(sqlQueryObject.getTipoDatabaseOpenSPCoop2(), log, connection);
  1067.        
  1068.         // Aggiunto un livello intermedio agli inner sql, in modo da essere sicuro di avere gli alias nei select field.
  1069.         // !non serve!
  1070. //      List<ISQLQueryObject> sqlQueryObjectUnionExpression = new ArrayList<>();
  1071. //      for (int i = 0; i < unionExpression.length; i++) {
  1072. //          ISQLQueryObject sqlQueryObjectUnion = sqlQueryObject.newSQLQueryObject();
  1073. //          for (String alias : unionExpression[i].getReturnFieldAliases()) {
  1074. //              sqlQueryObjectUnion.addSelectField(alias);
  1075. //          }
  1076. //          sqlQueryObjectUnion.addFromTable(sqlQueryObjectInnerList.get(i));
  1077. //          sqlQueryObjectUnionExpression.add(sqlQueryObjectUnion);
  1078. //      }
  1079.        
  1080.         // Create and execute sql union
  1081.         //String sql = sqlQueryObject.createSQLUnion(union.isUnionAll(), sqlQueryObjectUnionExpression.toArray(new ISQLQueryObject[1]));
  1082.         String sql = sqlQueryObject.createSQLUnion(union.isUnionAll(), sqlQueryObjectInnerList.toArray(new ISQLQueryObject[1]));
  1083.                
  1084.         // Per gli alias uso quelli della prima espressione, tanto nel check ho verificato che siano identici a meno di non averli ridefiniti nella union esterna.
  1085.         List<String> returnClassAliases = unionExpression[0].getReturnFieldAliases();
  1086.         if(union.getFields()!=null && union.getFields().size()>0){
  1087.             returnClassAliases = union.getFields();
  1088.         }
  1089.        
  1090.         // Eseguo la query
  1091.         List<Map<String,Object>> result = new ArrayList<Map<String,Object>>();
  1092.        
  1093.         JDBCObject [] params = null;
  1094.         if(jdbcObjects.size()>0)
  1095.             params = jdbcObjects.toArray(new JDBCObject[1]);
  1096.         List<List<Object>> resultExecuteQuery = jdbcUtilities.executeQuery(sql, jdbcProperties.isShowSql(), returnClassTypes ,params);
  1097.         if(resultExecuteQuery.size()>0){            
  1098.             for (int i = 0; i < resultExecuteQuery.size(); i++) {
  1099.                 List<Object> lista = resultExecuteQuery.get(i);
  1100.                 if(lista==null){
  1101.                     throw new ServiceException("Result["+i+"] is null?");
  1102.                 }
  1103.                 if(lista.size()!=returnClassTypes.size()){
  1104.                     throw new ServiceException("Result["+i+"] has wrong length (expected:"+returnClassTypes.size()+" founded:"+lista.size()+")");
  1105.                 }
  1106.                 // controllo seguente non dovrebbe servire...
  1107.                 if(lista.size()!=returnClassAliases.size()){
  1108.                     throw new ServiceException("Result["+i+"] has wrong length (alias) (expected:"+returnClassAliases.size()+" founded:"+lista.size()+")");
  1109.                 }
  1110.                 Map<String,Object> resultList = new HashMap<>();
  1111.                 int j = 0;
  1112.                 for (String alias : returnClassAliases) {
  1113.                     Object object = lista.get(j);
  1114.                     if(object!=null)
  1115.                         resultList.put(alias, object);
  1116.                     else
  1117.                         resultList.put(alias, org.apache.commons.lang.ObjectUtils.NULL);
  1118.                     j++;
  1119.                 }
  1120.                 result.add(resultList);
  1121.             }      
  1122.         }
  1123.        
  1124.         if(result.size()<=0){
  1125.             throw new NotFoundException("No result founds");
  1126.         }
  1127.        
  1128.         return result;
  1129.            
  1130.     }
  1131.    
  1132.    
  1133.     /* *** UNION COUNT *** */
  1134.    
  1135.     public static List<Class<?>> prepareUnionCount(JDBCServiceManagerProperties jdbcProperties, Logger log, Connection connection, ISQLQueryObject sqlQueryObject,
  1136.             ISQLFieldConverter sqlConverter,IModel<?> model,
  1137.             List<ISQLQueryObject> sqlQueryObjectInnerList,List<JDBCObject> jdbcObjects,
  1138.             Union union,UnionExpression ... unionExpression) throws NotFoundException, ExpressionException, ExpressionNotImplementedException, SQLQueryObjectException, JDBCAdapterException, ServiceException{
  1139.    
  1140.         if(union.getOrderByList().size()>0 && union.getSortOrder()!=null && !union.getSortOrder().equals(SortOrder.UNSORTED)){
  1141.             throw new ServiceException("OrderBy conditions not allowed in count expression");
  1142.         }
  1143.         if(union.getOffset()!=null){
  1144.             throw new ServiceException("Offset condition not allowed in count expression");
  1145.         }
  1146.         if(union.getLimit()!=null){
  1147.             throw new ServiceException("Limit condition not allowed in count expression");
  1148.         }
  1149.        
  1150.         return prepareUnion(jdbcProperties, log, connection, sqlQueryObject, sqlConverter, model, sqlQueryObjectInnerList, jdbcObjects, union, unionExpression);
  1151.        
  1152.     }
  1153.    
  1154.     public static NonNegativeNumber unionCount(JDBCServiceManagerProperties jdbcProperties, Logger log, Connection connection, ISQLQueryObject sqlQueryObject,
  1155.             ISQLFieldConverter sqlConverter,IModel<?> model,
  1156.             List<ISQLQueryObject> sqlQueryObjectInnerList,List<JDBCObject> jdbcObjects, List<Class<?>> returnClassTypes,
  1157.             Union union,UnionExpression ... unionExpression) throws NotFoundException, ExpressionException, ExpressionNotImplementedException, SQLQueryObjectException, JDBCAdapterException, ServiceException{
  1158.                    
  1159.         long totale = 0;
  1160.        
  1161.         org.openspcoop2.generic_project.dao.jdbc.utils.JDBCPreparedStatementUtilities jdbcUtilities =
  1162.             new org.openspcoop2.generic_project.dao.jdbc.utils.JDBCPreparedStatementUtilities(sqlQueryObject.getTipoDatabaseOpenSPCoop2(), log, connection);
  1163.        
  1164.         // Create and execute sql union
  1165.         String sql = sqlQueryObject .createSQLUnionCount(union.isUnionAll(), "unionCount" , sqlQueryObjectInnerList.toArray(new ISQLQueryObject[1]));
  1166.        
  1167.         JDBCObject [] params = null;
  1168.         if(jdbcObjects.size()>0)
  1169.             params = jdbcObjects.toArray(new JDBCObject[1]);
  1170.        
  1171.         totale = jdbcUtilities.count(sql, jdbcProperties.isShowSql(), params);

  1172.         return new NonNegativeNumber(totale);
  1173.            
  1174.     }
  1175.    
  1176.    
  1177.     /* *** FIND ALL *** */
  1178.    
  1179.     public static List<Object> prepareFindAll(JDBCServiceManagerProperties jdbcProperties, Logger log, Connection connection, ISQLQueryObject sqlQueryObject,
  1180.             IExpression paginatedExpression,ISQLFieldConverter sqlConverter,IModel<?> model) throws SQLQueryObjectException, JDBCAdapterException, ExpressionException, ExpressionNotImplementedException, ServiceException{
  1181.    
  1182.         List<Object> listaQuery = new ArrayList<>();
  1183.        
  1184.         toSqlForPreparedStatementWithFromCondition(paginatedExpression,sqlQueryObject,listaQuery,
  1185.                 sqlConverter.toTable(model));
  1186.        
  1187.         return listaQuery;
  1188.     }
  1189.    
  1190.     public static List<Object> findAll(JDBCServiceManagerProperties jdbcProperties, Logger log, Connection connection, ISQLQueryObject sqlQueryObject,
  1191.             IExpression paginatedExpression,ISQLFieldConverter sqlConverter,IModel<?> model,Class<?> objectIdClass,List<Object> listaQuery) throws SQLQueryObjectException, JDBCAdapterException, ExpressionException, ExpressionNotImplementedException, ServiceException{
  1192.        
  1193.         org.openspcoop2.generic_project.dao.jdbc.utils.JDBCPreparedStatementUtilities jdbcUtilities =
  1194.                 new org.openspcoop2.generic_project.dao.jdbc.utils.JDBCPreparedStatementUtilities(sqlQueryObject.getTipoDatabaseOpenSPCoop2(), log, connection);

  1195.         JDBCObject[] params = new JDBCObject[listaQuery.size()];
  1196.         int index = 0;
  1197.         for (Object param : listaQuery) {
  1198.             params[index++] = new JDBCObject(param, param.getClass());
  1199.         }
  1200.        
  1201.         String sql = sqlQueryObject.createSQLQuery();

  1202.         return jdbcUtilities.executeQuery(sql, jdbcProperties.isShowSql(), objectIdClass, params);
  1203.     }
  1204.    
  1205.     public static List<List<Object>> findAll(JDBCServiceManagerProperties jdbcProperties, Logger log, Connection connection, ISQLQueryObject sqlQueryObject,
  1206.             IExpression paginatedExpression,ISQLFieldConverter sqlConverter,IModel<?> model,List<Class<?>> objectIdsClass,List<Object> listaQuery) throws SQLQueryObjectException, JDBCAdapterException, ExpressionException, ExpressionNotImplementedException, ServiceException{
  1207.        
  1208.         org.openspcoop2.generic_project.dao.jdbc.utils.JDBCPreparedStatementUtilities jdbcUtilities =
  1209.                 new org.openspcoop2.generic_project.dao.jdbc.utils.JDBCPreparedStatementUtilities(sqlQueryObject.getTipoDatabaseOpenSPCoop2(), log, connection);

  1210.         JDBCObject[] params = new JDBCObject[listaQuery.size()];
  1211.         int index = 0;
  1212.         for (Object param : listaQuery) {
  1213.             params[index++] = new JDBCObject(param, param.getClass());
  1214.         }
  1215.        
  1216.         String sql = sqlQueryObject.createSQLQuery();

  1217.         return jdbcUtilities.executeQuery(sql, jdbcProperties.isShowSql(), objectIdsClass, params);
  1218.     }
  1219.    
  1220.    
  1221.     /* *** FIND *** */
  1222.    
  1223.     public static List<Object> prepareFind(JDBCServiceManagerProperties jdbcProperties, Logger log, Connection connection, ISQLQueryObject sqlQueryObject,
  1224.             IExpression expression,ISQLFieldConverter sqlConverter,IModel<?> model) throws SQLQueryObjectException, JDBCAdapterException, ExpressionException, ExpressionNotImplementedException, ServiceException, MultipleResultException{
  1225.    
  1226.         List<Object> listaQuery = new ArrayList<>();
  1227.        
  1228.         toSqlForPreparedStatementWithFromCondition(expression,sqlQueryObject,listaQuery,
  1229.                 sqlConverter.toTable(model));
  1230.        
  1231.         return listaQuery;
  1232.     }
  1233.    
  1234.     public static Object find(JDBCServiceManagerProperties jdbcProperties, Logger log, Connection connection, ISQLQueryObject sqlQueryObject,
  1235.             IExpression expression,ISQLFieldConverter sqlConverter,IModel<?> model,Class<?> objectIdClass,List<Object> listaQuery) throws SQLQueryObjectException, JDBCAdapterException, ExpressionException, ExpressionNotImplementedException, NotFoundException, ServiceException, MultipleResultException{
  1236.        
  1237.         org.openspcoop2.generic_project.dao.jdbc.utils.JDBCPreparedStatementUtilities jdbcUtilities =
  1238.                 new org.openspcoop2.generic_project.dao.jdbc.utils.JDBCPreparedStatementUtilities(sqlQueryObject.getTipoDatabaseOpenSPCoop2(), log, connection);

  1239.         JDBCObject[] params = new JDBCObject[listaQuery.size()];
  1240.         int index = 0;
  1241.         for (Object param : listaQuery) {
  1242.             params[index++] = new JDBCObject(param, param.getClass());
  1243.         }
  1244.        
  1245.         String sql = sqlQueryObject.createSQLQuery();

  1246.         return jdbcUtilities.executeQuerySingleResult(sql, jdbcProperties.isShowSql(), objectIdClass, params);
  1247.     }
  1248.    
  1249.     public static List<Object> find(JDBCServiceManagerProperties jdbcProperties, Logger log, Connection connection, ISQLQueryObject sqlQueryObject,
  1250.             IExpression expression,ISQLFieldConverter sqlConverter,IModel<?> model,List<Class<?>> objectIdsClass,List<Object> listaQuery) throws SQLQueryObjectException, JDBCAdapterException, ExpressionException, ExpressionNotImplementedException, NotFoundException, ServiceException, MultipleResultException{
  1251.        
  1252.         org.openspcoop2.generic_project.dao.jdbc.utils.JDBCPreparedStatementUtilities jdbcUtilities =
  1253.                 new org.openspcoop2.generic_project.dao.jdbc.utils.JDBCPreparedStatementUtilities(sqlQueryObject.getTipoDatabaseOpenSPCoop2(), log, connection);

  1254.         JDBCObject[] params = new JDBCObject[listaQuery.size()];
  1255.         int index = 0;
  1256.         for (Object param : listaQuery) {
  1257.             params[index++] = new JDBCObject(param, param.getClass());
  1258.         }
  1259.        
  1260.         String sql = sqlQueryObject.createSQLQuery();

  1261.         return jdbcUtilities.executeQuerySingleResult(sql, jdbcProperties.isShowSql(), objectIdsClass, params);
  1262.     }
  1263.    
  1264.    
  1265.    
  1266.     /* *** UPDATE  ** */

  1267.     public static void updateFields(JDBCServiceManagerProperties jdbcProperties, Logger log, Connection connection, ISQLQueryObject sqlQueryObject,
  1268.             String rootTable, Map<String, List<IField>> mapTableToPKColumn, List<Object> rootTableIdValues,
  1269.             ISQLFieldConverter sqlConverter,
  1270.             IJDBCServiceSearchSingleObject<?, ?> serviceSingleObject,
  1271.             UpdateModel ... updateModels) throws ServiceException, NotImplementedException, Exception{
  1272.         updateFields(jdbcProperties, log, connection, sqlQueryObject, rootTable, mapTableToPKColumn, rootTableIdValues, sqlConverter,
  1273.                 serviceSingleObject, null, null, updateModels);
  1274.     }
  1275.     public static void updateFields(JDBCServiceManagerProperties jdbcProperties, Logger log, Connection connection, ISQLQueryObject sqlQueryObject,
  1276.             String rootTable, Map<String, List<IField>> mapTableToPKColumn, List<Object> rootTableIdValues,
  1277.             ISQLFieldConverter sqlConverter,
  1278.             IJDBCServiceSearchWithId<?, ?, ?> serviceWithId,
  1279.             UpdateModel ... updateModels) throws ServiceException, NotImplementedException, Exception{
  1280.         updateFields(jdbcProperties, log, connection, sqlQueryObject, rootTable, mapTableToPKColumn, rootTableIdValues, sqlConverter,
  1281.                 null, serviceWithId, null, updateModels);
  1282.     }
  1283.     public static void updateFields(JDBCServiceManagerProperties jdbcProperties, Logger log, Connection connection, ISQLQueryObject sqlQueryObject,
  1284.             String rootTable, Map<String, List<IField>> mapTableToPKColumn, List<Object> rootTableIdValues,
  1285.             ISQLFieldConverter sqlConverter,
  1286.             IJDBCServiceSearchWithoutId<?, ?> serviceWithoutId,
  1287.             UpdateModel ... updateModels) throws ServiceException, NotImplementedException, Exception{
  1288.         updateFields(jdbcProperties, log, connection, sqlQueryObject, rootTable, mapTableToPKColumn, rootTableIdValues, sqlConverter,
  1289.                 null, null, serviceWithoutId, updateModels);
  1290.     }
  1291.    
  1292.     private static void updateFields(JDBCServiceManagerProperties jdbcProperties, Logger log, Connection connection, ISQLQueryObject sqlQueryObject,
  1293.             String rootTable, Map<String, List<IField>> mapTableToPKColumn, List<Object> rootTableIdValues,
  1294.             ISQLFieldConverter sqlConverter,
  1295.             IJDBCServiceSearchSingleObject<?, ?> serviceSingleObject,
  1296.             IJDBCServiceSearchWithId<?, ?, ?> serviceWithId,
  1297.             IJDBCServiceSearchWithoutId<?, ?> serviceWithoutId,
  1298.             UpdateModel ... updateModels) throws ServiceException, NotImplementedException, Exception{
  1299.        
  1300.         if(updateModels==null || updateModels.length<=0){
  1301.             throw new ServiceException("Parameter updateModels is not defined");
  1302.         }
  1303.         List<String> tableUpdated = new ArrayList<>();
  1304.         for (UpdateModel updateModel : updateModels) {
  1305.            
  1306.             IModel<?> model = updateModel.getModel();
  1307.             IExpression condition = updateModel.getCondition();
  1308.             List<UpdateField> updateFields = updateModel.getUpdateFiels();
  1309.             if(updateFields==null || updateFields.size()<=0){
  1310.                 throw new ServiceException("Parameter updateFields of model ["+model+"] is not defined");
  1311.             }
  1312.             String table = sqlConverter.toTable(model);
  1313.             if(table==null){
  1314.                 throw new ServiceException("Model ["+model+"] is not defined in sql converter");
  1315.             }
  1316.             for (UpdateField updateField : updateFields) {
  1317.                 String tableField = sqlConverter.toTable(updateField.getField());
  1318.                 if(table.equals(tableField)==false){
  1319.                     throw new ServiceException("Different update table: UpdateField ["+updateField.getField().getFieldName()+" of "+updateField.getField().getClassName()+"] (table:"+tableField+") and Model ["+model+"] (table:"+table+") ");
  1320.                 }
  1321.             }
  1322.             if(tableUpdated.contains(table)==false){
  1323.                
  1324.                 _engineUpdateFields(jdbcProperties, log, connection, sqlQueryObject, sqlConverter, serviceSingleObject,
  1325.                         serviceWithId, serviceWithoutId, rootTable, mapTableToPKColumn, rootTableIdValues, table, condition, updateFields);
  1326.                 tableUpdated.add(table);
  1327.             }
  1328.                    
  1329.         }
  1330.        
  1331.     }
  1332.    
  1333.     public static void updateFields(JDBCServiceManagerProperties jdbcProperties, Logger log, Connection connection, ISQLQueryObject sqlQueryObject,
  1334.             String rootTable, Map<String, List<IField>> mapTableToPKColumn, List<Object> rootTableIdValues,
  1335.             ISQLFieldConverter sqlConverter,
  1336.             IJDBCServiceSearchSingleObject<?, ?> serviceSingleObject,
  1337.             IExpression condition, UpdateField ... updateFields) throws ServiceException, NotImplementedException, Exception{
  1338.         updateFields(jdbcProperties, log, connection, sqlQueryObject, rootTable, mapTableToPKColumn, rootTableIdValues, sqlConverter,
  1339.                 serviceSingleObject, null, null, condition, updateFields);
  1340.     }
  1341.     public static void updateFields(JDBCServiceManagerProperties jdbcProperties, Logger log, Connection connection, ISQLQueryObject sqlQueryObject,
  1342.             String rootTable, Map<String, List<IField>> mapTableToPKColumn, List<Object> rootTableIdValues,
  1343.             ISQLFieldConverter sqlConverter,
  1344.             IJDBCServiceSearchWithId<?, ?, ?> serviceWithId,
  1345.             IExpression condition, UpdateField ... updateFields) throws ServiceException, NotImplementedException, Exception{
  1346.         updateFields(jdbcProperties, log, connection, sqlQueryObject, rootTable, mapTableToPKColumn, rootTableIdValues, sqlConverter,
  1347.                 null, serviceWithId, null, condition, updateFields);
  1348.     }
  1349.     public static void updateFields(JDBCServiceManagerProperties jdbcProperties, Logger log, Connection connection, ISQLQueryObject sqlQueryObject,
  1350.             String rootTable, Map<String, List<IField>> mapTableToPKColumn, List<Object> rootTableIdValues,
  1351.             ISQLFieldConverter sqlConverter,
  1352.             IJDBCServiceSearchWithoutId<?, ?> serviceWithoutId,
  1353.             IExpression condition, UpdateField ... updateFields) throws ServiceException, NotImplementedException, Exception{
  1354.         updateFields(jdbcProperties, log, connection, sqlQueryObject, rootTable, mapTableToPKColumn, rootTableIdValues, sqlConverter,
  1355.                 null, null, serviceWithoutId, condition, updateFields);
  1356.     }
  1357.     private static void updateFields(JDBCServiceManagerProperties jdbcProperties, Logger log, Connection connection, ISQLQueryObject sqlQueryObject,
  1358.             String rootTable, Map<String, List<IField>> mapTableToPKColumn, List<Object> rootTableIdValues,
  1359.             ISQLFieldConverter sqlConverter,
  1360.             IJDBCServiceSearchSingleObject<?, ?> serviceSingleObject,
  1361.             IJDBCServiceSearchWithId<?, ?, ?> serviceWithId,
  1362.             IJDBCServiceSearchWithoutId<?, ?> serviceWithoutId,
  1363.             IExpression condition, UpdateField ... updateFields) throws ServiceException, NotImplementedException, Exception{
  1364.        
  1365.         if(updateFields==null || updateFields.length<=0){
  1366.             throw new ServiceException("Parameter updateFields is not defined");
  1367.         }
  1368.        
  1369.         // *** Suddivisione per tabella ***
  1370.        
  1371.         Map<String, List<UpdateField>> updateMap = new HashMap<String, List<UpdateField>>();
  1372.         for (int i = 0; i < updateFields.length; i++) {
  1373.             String tableName = sqlConverter.toTable(updateFields[i].getField());
  1374.             if(tableName==null){
  1375.                 throw new ServiceException("Field ["+updateFields[i].getField().getFieldName()+" of "+updateFields[i].getField().getClassName()+"] is not defined in sql converter");
  1376.             }
  1377.             List<UpdateField> list = updateMap.remove(tableName);
  1378.             if(list==null){
  1379.                 list = new ArrayList<UpdateField>();
  1380.             }
  1381.             list.add(updateFields[i]);
  1382.             updateMap.put(tableName, list);
  1383.         }
  1384.        
  1385.         for (String table : updateMap.keySet()) {
  1386.            
  1387.             _engineUpdateFields(jdbcProperties, log, connection, sqlQueryObject, sqlConverter, serviceSingleObject,
  1388.                     serviceWithId, serviceWithoutId, rootTable, mapTableToPKColumn, rootTableIdValues, table, condition, updateMap.get(table));
  1389.         }
  1390.     }
  1391.                
  1392.     private static void _engineUpdateFields(JDBCServiceManagerProperties jdbcProperties, Logger log, Connection connection, ISQLQueryObject sqlQueryObject,
  1393.             ISQLFieldConverter sqlConverter,
  1394.             IJDBCServiceSearchSingleObject<?, ?> serviceSingleObject,
  1395.             IJDBCServiceSearchWithId<?, ?, ?> serviceWithId,
  1396.             IJDBCServiceSearchWithoutId<?, ?> serviceWithoutId,
  1397.             String rootTable, Map<String, List<IField>> mapTableToPKColumn, List<Object> rootTableIdValues,
  1398.             String table, IExpression condition, List<UpdateField> updateFields) throws ServiceException, NotImplementedException, Exception{      
  1399.            
  1400.         org.openspcoop2.generic_project.dao.jdbc.utils.JDBCPreparedStatementUtilities jdbcUtilities =
  1401.                 new org.openspcoop2.generic_project.dao.jdbc.utils.JDBCPreparedStatementUtilities(sqlQueryObject.getTipoDatabaseOpenSPCoop2(), log, connection);
  1402.        
  1403.         // Una tabella può non avere una PK
  1404. //      if(mapTableToPKColumn.containsKey(table)==false){
  1405. //          throw new ServiceException("PrimaryKey columns not defined for table ["+table+"]");
  1406. //      }
  1407.        
  1408.        
  1409.         // *** Update per tabella ***
  1410.                    
  1411.         ISQLQueryObject sqlQueryObjectUpdate = sqlQueryObject.newSQLQueryObject();
  1412.         sqlQueryObjectUpdate.setANDLogicOperator(true);
  1413.         sqlQueryObjectUpdate.addUpdateTable(table);
  1414.        
  1415.         // update fields
  1416.         java.util.List<JDBCObject> lstObjectsUpdate = new java.util.ArrayList<>();
  1417.         for (UpdateField updateField : updateFields) {
  1418.             sqlQueryObjectUpdate.addUpdateField(sqlConverter.toColumn(updateField.getField(),false), "?");
  1419.             lstObjectsUpdate.add(new JDBCObject(updateField.getValue(), updateField.getField().getFieldType()));
  1420.         }
  1421.        
  1422.         boolean update = true;
  1423.        
  1424.         // rootTable pk fields
  1425.         JDBCPaginatedExpression rootTablePKExpresion = new JDBCPaginatedExpression(sqlConverter);
  1426.         rootTablePKExpresion.and();
  1427.         List<IField> rootTableListPKColumns = mapTableToPKColumn.get(rootTable);
  1428.         if(rootTableListPKColumns!=null && rootTableIdValues!=null){
  1429.             if(rootTableListPKColumns.size()!=rootTableIdValues.size()){
  1430.                 throw new ServiceException("Number of primary key column ("+rootTableListPKColumns.size()+") and numbero of column values ("+
  1431.                         rootTableIdValues.size()+") isn't equals");
  1432.             }
  1433.             for (int i = 0; i < rootTableListPKColumns.size(); i++) {
  1434.                 rootTablePKExpresion.equals(rootTableListPKColumns.get(i), rootTableIdValues.get(i));
  1435.             }
  1436.         }
  1437.         // where condition custom
  1438.         if(condition!=null){
  1439.             rootTablePKExpresion.and(condition);
  1440.         }
  1441.         // for generate join condition
  1442.         rootTablePKExpresion.sortOrder(SortOrder.ASC).addOrder(updateFields.get(0).getField());
  1443.        
  1444.         // column ids
  1445.         if(rootTable.equals(table) && condition==null){
  1446.            
  1447.             // Se sto aggiornando la root table, e non vi sono condizioni dinamiche (le quali possono riferire anche tabelle interne)
  1448.             // non serve effettuare una ulteriore query che identifica gli id, ma posso applicare direttamente il where delle root columns.
  1449.             if(rootTableListPKColumns!=null && rootTableIdValues!=null){
  1450.                 StringBuilder bfRowIdentification = new StringBuilder();
  1451.                 bfRowIdentification.append("( ");
  1452.                 for (int i = 0; i < rootTableListPKColumns.size(); i++) {
  1453.                     if(i>0){
  1454.                         bfRowIdentification.append(" AND ");
  1455.                     }
  1456.                     IField columnId = rootTableListPKColumns.get(i);
  1457.                     bfRowIdentification.append(sqlConverter.toColumn(columnId, true)).append("=?");
  1458.                     lstObjectsUpdate.add(new JDBCObject(rootTableIdValues.get(i), columnId.getFieldType()));
  1459.                 }
  1460.                 bfRowIdentification.append(" )");
  1461.                 sqlQueryObjectUpdate.addWhereCondition(bfRowIdentification.toString());
  1462.             }
  1463.         }
  1464.         else{
  1465.             ISQLQueryObject sqlQueryObjectSelect = sqlQueryObjectUpdate.newSQLQueryObject();
  1466.             sqlQueryObjectSelect.setANDLogicOperator(true);
  1467.             try{
  1468.                 List<IField> columnIds = mapTableToPKColumn.get(table);
  1469.                 if(columnIds!=null && columnIds.size()>0){
  1470.                     List<Map<String, Object>> valueIds = null;
  1471.                     if(serviceSingleObject!=null){
  1472.                         valueIds = serviceSingleObject.select(jdbcProperties, log, connection, sqlQueryObjectSelect, rootTablePKExpresion,
  1473.                                 true, columnIds.toArray(new IField[]{}));
  1474.                     }
  1475.                     else if(serviceWithoutId!=null){
  1476.                         valueIds = serviceWithoutId.select(jdbcProperties, log, connection, sqlQueryObjectSelect, rootTablePKExpresion,
  1477.                                 true, columnIds.toArray(new IField[]{}));
  1478.                     }
  1479.                     else if(serviceWithId!=null){
  1480.                         valueIds = serviceWithId.select(jdbcProperties, log, connection, sqlQueryObjectSelect, rootTablePKExpresion,
  1481.                                 true, columnIds.toArray(new IField[]{}));
  1482.                     }
  1483.                     if(valueIds!=null) {
  1484.                         // Questo controllo e' sbagliato. Devo poter aggiornare dei singoli campi su piu' righe di oggetti interni.
  1485.                         // Se voglio identificare esattamente una sola riga di un oggetto interno devo usare la condition
  1486.                         // Mentre l'oggetto "daoInterface" lo identifico esattamente (o grazie all'id, o grazie all'oggetto stesso e quindi l'id long, o grazie alla singola istanza)
  1487.         //              if(valueIds.size()>1){
  1488.         //                  throw new ServiceException("Cannot exists more columns with PK column ids (table:"+table+"), found: "+valueIds.size());
  1489.         //              }
  1490.                         StringBuilder bfRowIdentification = new StringBuilder();
  1491.                         bfRowIdentification.append("( ");
  1492.                         for (int i = 0; i < valueIds.size(); i++) {
  1493.                             if(i>0){
  1494.                                 bfRowIdentification.append(" OR ");
  1495.                             }
  1496.                             Map<String, Object> mapColumnValue = valueIds.get(i);
  1497.                             bfRowIdentification.append("( ");
  1498.                             for (int j = 0; j < columnIds.size(); j++) {
  1499.                                 if(j>0){
  1500.                                     bfRowIdentification.append(" AND ");
  1501.                                 }
  1502.                                 IField columnId = columnIds.get(j);
  1503.                                 bfRowIdentification.append(sqlConverter.toColumn(columnId, true)).append("=?");
  1504.                                 lstObjectsUpdate.add(new JDBCObject(mapColumnValue.get(columnId.getFieldName()), columnId.getFieldType()));
  1505.                             }  
  1506.                             bfRowIdentification.append(" )");
  1507.                         }
  1508.                         bfRowIdentification.append(" )");
  1509.                         sqlQueryObjectUpdate.addWhereCondition(bfRowIdentification.toString());
  1510.                     }
  1511.                 }
  1512.             }catch(NotFoundException notFound){
  1513.                 update = false;
  1514.                 log.debug("UpdateField["+table+"]: NotFound");
  1515.             }
  1516.         }
  1517.            
  1518.         if(update){
  1519.             int updateRow = jdbcUtilities.executeUpdate(sqlQueryObjectUpdate.createSQLUpdate(), jdbcProperties.isShowSql(),
  1520.                     lstObjectsUpdate.toArray(new JDBCObject[]{}));
  1521.             log.debug("UpdateField["+table+"]: "+updateRow +" rows");
  1522.         }
  1523.                
  1524.     }
  1525.    

  1526.    
  1527.     /* *** NATIVE ** */
  1528.    
  1529.     public static List<List<Object>> nativeQuery(JDBCServiceManagerProperties jdbcProperties, Logger log, Connection connection, ISQLQueryObject sqlQueryObject,
  1530.             String sql,List<Class<?>> returnClassTypes,Object ... param) throws SQLQueryObjectException, JDBCAdapterException, ServiceException{
  1531.        
  1532.         org.openspcoop2.generic_project.dao.jdbc.utils.JDBCPreparedStatementUtilities jdbcUtilities =
  1533.                 new org.openspcoop2.generic_project.dao.jdbc.utils.JDBCPreparedStatementUtilities(sqlQueryObject.getTipoDatabaseOpenSPCoop2(), log, connection);
  1534.                
  1535.         java.util.List<org.openspcoop2.generic_project.dao.jdbc.utils.JDBCObject> listParams =
  1536.             new java.util.ArrayList<org.openspcoop2.generic_project.dao.jdbc.utils.JDBCObject>();
  1537.         for (Object jdbcObject : param) {
  1538.             org.openspcoop2.generic_project.dao.jdbc.utils.JDBCObject jdbc =
  1539.                 new org.openspcoop2.generic_project.dao.jdbc.utils.JDBCObject(jdbcObject,jdbcObject.getClass());
  1540.             listParams.add(jdbc);
  1541.         }
  1542.         org.openspcoop2.generic_project.dao.jdbc.utils.JDBCObject [] paramArray = null;
  1543.         if(listParams.size()>0){
  1544.             paramArray = listParams.toArray(new org.openspcoop2.generic_project.dao.jdbc.utils.JDBCObject [1]);
  1545.         }
  1546.        
  1547.         return jdbcUtilities.executeQuery(sql, jdbcProperties.isShowSql(), returnClassTypes ,paramArray);
  1548.     }
  1549.    
  1550.     public static int nativeUpdate(JDBCServiceManagerProperties jdbcProperties, Logger log, Connection connection, ISQLQueryObject sqlQueryObject,
  1551.             String sql,Object ... param) throws SQLQueryObjectException, JDBCAdapterException, ServiceException{
  1552.        
  1553.         org.openspcoop2.generic_project.dao.jdbc.utils.JDBCPreparedStatementUtilities jdbcUtilities =
  1554.                 new org.openspcoop2.generic_project.dao.jdbc.utils.JDBCPreparedStatementUtilities(sqlQueryObject.getTipoDatabaseOpenSPCoop2(), log, connection);
  1555.                
  1556.         java.util.List<org.openspcoop2.generic_project.dao.jdbc.utils.JDBCObject> listParams =
  1557.             new java.util.ArrayList<org.openspcoop2.generic_project.dao.jdbc.utils.JDBCObject>();
  1558.         for (Object jdbcObject : param) {
  1559.             org.openspcoop2.generic_project.dao.jdbc.utils.JDBCObject jdbc =
  1560.                 new org.openspcoop2.generic_project.dao.jdbc.utils.JDBCObject(jdbcObject,jdbcObject.getClass());
  1561.             listParams.add(jdbc);
  1562.         }
  1563.         org.openspcoop2.generic_project.dao.jdbc.utils.JDBCObject [] paramArray = null;
  1564.         if(listParams.size()>0){
  1565.             paramArray = listParams.toArray(new org.openspcoop2.generic_project.dao.jdbc.utils.JDBCObject [1]);
  1566.         }
  1567.        
  1568.         return jdbcUtilities.executeUpdate(sql, jdbcProperties.isShowSql(), paramArray);
  1569.     }
  1570.    
  1571. }