Changeset 2614


Ignore:
Timestamp:
02/02/10 17:23:13 (2 years ago)
Author:
jlops
Message:

JPA criteria API first phase and J2EE6

Location:
maven_sequence_lims/molgenis3_4_maven
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • maven_sequence_lims/molgenis3_4_maven/pom.xml

    r2586 r2614  
    99  <url>http://maven.apache.org</url> 
    1010  <dependencies> 
     11        <dependency> 
     12            <groupId>javax</groupId> 
     13            <artifactId>javaee-web-api</artifactId> 
     14            <version>6.0</version> 
     15            <scope>provided</scope> 
     16        </dependency> 
    1117    <dependency> 
    1218      <groupId>junit</groupId> 
     
    5561      <version>1.6.5</version> 
    5662    </dependency> 
    57     <dependency> 
     63<!--    <dependency> 
    5864      <groupId>javax.persistence</groupId> 
    5965      <artifactId>persistence-api</artifactId> 
    6066      <version>1.0</version> 
    61     </dependency> 
     67    </dependency>--> 
    6268    <dependency> 
    6369      <groupId>log4j</groupId> 
  • maven_sequence_lims/molgenis3_4_maven/src/main/java/org/molgenis/framework/data/jdbc/JDBCConnectionHelper.java

    r2582 r2614  
    398398                                // where_clause.append(tablePrefix + rule.getField() + " " + 
    399399                                // operator + " '" + value + "'"); 
    400                                 if (rule.getOperator().equals(Operator.JOIN)) where_clause.append(rule.getField() + " " + operator 
    401                                                 + " " + value + ""); 
     400                                if (rule.getOperator().equals(Operator.JOIN))  
     401                                    where_clause.append(rule.getField() + " " + operator + " " + value + ""); 
    402402                                else 
    403403                                {                
  • maven_sequence_lims/molgenis3_4_maven/src/main/java/org/molgenis/framework/data/jpa/JPAQueryGeneratorUtil.java

    r2582 r2614  
    22 
    33import java.util.List; 
     4import javax.persistence.EntityManager; 
     5import javax.persistence.criteria.CriteriaBuilder; 
     6import javax.persistence.criteria.CriteriaQuery; 
     7import javax.persistence.criteria.Expression; 
     8import javax.persistence.criteria.Predicate; 
     9import javax.persistence.criteria.Root; 
     10import javax.persistence.metamodel.EntityType; 
     11import javax.persistence.metamodel.Metamodel; 
    412 
    513import org.apache.commons.lang.StringEscapeUtils; 
     
    816import org.molgenis.framework.data.QueryRule.Operator; 
    917import org.molgenis.framework.data.jdbc.ColumnInfo.Type; 
     18import org.molgenis.util.Entity; 
    1019 
    1120/** 
    12  * Fixme: dit moet vervangen worden de creteria look-a-like api die in JPA 2.0 
    13  * komt! 
    14  * Fixme: testen! aangezien dit gemaakt was voor SQL en niet voor JPA-Query-Language 
    15  * @author Morris Swertz 
    1621 * @author jorislops 
    1722 */ 
    1823 
    19 public class JPAQueryGeneratorUtil 
    20 { 
    21         public static String createWhereSql(JpaMapper mapper, boolean isNested, boolean withOffset,  
    22                         Integer[] limitOffset,  QueryRule... rules) throws DatabaseException 
    23         { 
    24                 StringBuffer where_clause = new StringBuffer(""); 
    25                 for (QueryRule r : rules) 
    26                 {                                
    27                         QueryRule rule = new QueryRule(r); //copy because of side effects 
    28                         //logger.debug(rule); 
    29                          
    30                         //String tablePrefix = ""; 
    31                         if(mapper != null) 
    32                                 rule.setField(mapper.getTableFieldName(rule.getField())); 
    33  
    34                         if (rule.getOperator() == Operator.LAST || rule.getOperator() == Operator.LIMIT 
    35                                         || rule.getOperator() == Operator.OFFSET || rule.getOperator() == Operator.SORTASC 
    36                                         || rule.getOperator() == Operator.SORTDESC) 
    37                         { 
    38  
    39                         } 
    40                         else if (rule.getOperator() == QueryRule.Operator.NESTED) 
    41                         { 
    42                                 QueryRule[] nestedrules = rule.getNestedRules(); 
    43                                 if (nestedrules.length > 0) 
    44                                 { 
    45                                         if (where_clause.length() > 0) 
    46                                         { 
    47                                                 if (rule.isOr()) 
    48                                                         where_clause.append(" OR "); 
    49                                                 else 
    50                                                         where_clause.append(" AND "); 
    51                                         } 
    52                                         where_clause.append("("); 
    53                                         where_clause.append(createWhereSql(mapper, true, false, null, nestedrules)); 
    54                                         where_clause.append(")"); 
    55                                 } 
    56                         } 
    57                         else if (rule.getOperator() == QueryRule.Operator.IN) 
    58                         { 
    59                                 if (where_clause.length() > 0) 
    60                                 { 
    61                                         if (rule.isOr()) 
    62                                                 where_clause.append(" OR "); 
    63                                         else 
    64                                                 where_clause.append(" AND "); 
    65                                 } 
    66  
    67                                 //where_clause.append(tablePrefix + rule.getField() + " IN("); 
    68                                 where_clause.append(rule.getField() + " IN("); 
    69  
    70                                 Object[] values = new Object[0]; 
    71                                 if (rule.getValue() instanceof List) 
    72                                 { 
    73                                         values = ((List<Object>) rule.getValue()).toArray(); 
    74                                 } 
    75                                 else 
    76                                 { 
    77                                         values = (Object[]) rule.getValue(); 
    78                                 } 
    79  
    80                                 for (int i = 0; i < values.length; i++) 
    81                                 { 
    82                                         if (i > 0) where_clause.append(","); 
    83                                         if (mapper != null && omitQuotes(mapper.getFieldType(rule.getField())))  
    84                                         { 
    85                                                 //where_clause.append(values[i] 
    86                                                 //      .toString()); 
    87                                                 where_clause.append("'" + escapeSql(values[i]) + "'"); 
    88                                         } 
    89                                         else 
    90                                         { 
    91                                                 where_clause.append("'" + escapeSql(values[i]) + "'"); 
    92                                         } 
    93                                 } 
    94                                 where_clause.append(") "); 
    95                         } 
    96                         else 
    97                         // where clause 
    98                         { 
    99                                 // check validity of the rule 
    100                                 //if(rule.getField() == null || columnInfoMap.get(rule.getField()) == null ) 
    101                                 //{ 
    102                                 //      throw new DatabaseException("Invalid rule: field '"+ rule.getField() + "' not known."); 
    103                                 //} 
    104                                  
    105                                 String operator = ""; 
    106                                 switch (rule.getOperator()) 
    107                                 { 
    108                                         case EQUALS: 
    109                                                 operator = "="; 
    110                                                 break; 
    111                                         case NOT: 
    112                                                 operator = "!="; 
    113                                                 break; 
    114                                         case LIKE: 
    115                                                 operator = "LIKE"; 
    116                                                 break; 
    117                                         case LESS: 
    118                                                 operator = "<"; 
    119                                                 break; 
    120                                         case GREATER: 
    121                                                 operator = ">"; 
    122                                                 break; 
    123                                         case LESS_EQUAL: 
    124                                                 operator = "<="; 
    125                                                 break; 
    126                                         case GREATER_EQUAL: 
    127                                                 operator = ">="; 
    128                                                 break; 
    129                                 } 
    130                                 // if (rule.getField() != "" && operator != "" && 
    131                                 // rule.getValue() != "") 
    132                                 // { 
    133                                 if (where_clause.length() > 0) 
    134                                 { 
    135                                         if (rule.isOr()) where_clause.append(" OR "); 
    136                                         else 
    137                                                 where_clause.append(" AND "); 
    138                                 } 
    139                                 if(new Boolean(true).equals(rule.getValue())) rule.setValue("1"); 
    140                                 if(new Boolean(false).equals(rule.getValue())) rule.setValue("0"); 
    141                                 Object value = rule.getValue() == null ? "NULL" : escapeSql(rule.getValue()); 
    142                                 if (!value.equals("NULL") && rule.getOperator() == Operator.LIKE && mapper != null && !omitQuotes(mapper.getFieldType(rule.getField()))) 
    143                                 { 
    144                                         if( !value.toString().trim().startsWith("%") && !value.toString().trim().endsWith("%") ) 
    145                                         { 
    146                                                 value = "%"+value+"%"; 
    147                                         } 
    148                                 } 
    149                                  
    150                                 //if (omitQuotes(columnInfoMap.get(rule.getField()).getType()))  
    151                                 //              where_clause.append(tablePrefix + rule.getField() + " " + operator + " " + value + ""); 
    152                                 //else 
    153                                         //where_clause.append(tablePrefix + rule.getField() + " " + operator + " '" + value + "'"); 
    154                                 where_clause.append(rule.getField() + " " + operator + " '" + value + "'"); 
    155                                 // } 
    156                         } 
    157                 } 
    158  
    159                 String result = where_clause.toString(); 
    160                 if (!isNested && where_clause.length() > 0) result = " WHERE " + result; 
    161                 createLimitSql(withOffset, rules, limitOffset); 
    162                 return result + createSortSql(mapper, rules); 
    163         } 
    164  
    165         /** Helper method for creating a sort clause */ 
    166         private static String createSortSql(JpaMapper mapper, QueryRule... rules) 
    167         { 
    168                 return createSortSql(mapper, false, rules); 
    169         } 
    170  
    171         private static boolean omitQuotes(Type t) 
    172         { 
    173                 return t == Type.LONG || t == Type.INT || t == Type.DECIMAL; 
    174  
    175         } 
    176  
    177         /** 
    178          * Helper method for creating a sort clause 
    179          *  
    180          * @param tableName 
    181          *            name of the table that is used to prefix column names. 
    182          * @param reverseSorting 
    183          *            to reverese sorting order. This is used when trying to find 
    184          *            the "last records" in a sorted list by instead finding the 
    185          *            "first records" in the reversly ordered list. 
    186          * @param rules 
    187          *            query rules to be translated into sql order by clause. 
    188          * @return sql with sort clause 
    189          */ 
    190         public static String createSortSql(JpaMapper mapper, boolean reverseSorting, QueryRule rules[]) 
    191         { 
    192  
    193                 for (QueryRule rule : rules) 
    194                 { 
    195                         if (rule.getOperator() == Operator.LAST) 
    196                         { 
    197                                 reverseSorting = !reverseSorting; 
    198                                 break; 
    199                         } 
    200                 } 
    201  
    202                 String sort_clause = ""; 
    203                 for (QueryRule r : rules) 
    204                 { 
    205                         QueryRule rule = new QueryRule(r); //copy because of sideeffects 
    206                                  
    207                         // limit clause 
    208                         if ((rule.getOperator() == Operator.SORTASC && !reverseSorting) 
    209                                         || (reverseSorting && rule.getOperator() == Operator.SORTDESC)) 
    210                         { 
    211                                 if(mapper != null) rule.setValue(mapper.getTableFieldName(rule.getValue().toString())); 
    212                                 sort_clause += rule.getValue().toString() + " ASC,"; 
    213                         } 
    214                         else if ((rule.getOperator() == QueryRule.Operator.SORTDESC && !reverseSorting) 
    215                                         || (reverseSorting && rule.getOperator() == Operator.SORTASC)) 
    216                         { 
    217                                 if(mapper != null) rule.setValue(mapper.getTableFieldName(rule.getValue().toString())); 
    218                                 sort_clause += rule.getValue().toString()  + " DESC,"; 
    219                         } 
    220                 } 
    221                 if(sort_clause.length() > 0) 
    222                         return " ORDER BY "+sort_clause.substring(0,sort_clause.lastIndexOf(","));  
    223                 return sort_clause; 
    224         } 
    225  
    226         /** 
    227          * Helper method for creating a limit clause 
    228          *  
    229          * @param withOffset 
    230          *            Indicate whether offset is to be used. If false the limit 
    231          *            clause is kept empty. 
    232          * @param rules 
    233          *            query rules to be translated into SQL order by clause. 
    234          * @param limit  
    235          *                        out: limit count of the query (returns null if no limit is found in the rules)        
    236          * @param offset            
    237          *            out: offset of the query (returns null if no offset is found in the rules);  
    238          * @return limit,offset as output parameters 
    239          */ 
    240         public static void createLimitSql(boolean withOffset, QueryRule[] rules, Integer[] limitOffset) { 
    241                 boolean limitFound = false; 
    242                 boolean offsetFound = false; 
    243                 for (QueryRule rule : rules) { 
    244                         if (rule.getOperator() == QueryRule.Operator.LIMIT) { 
    245                                 limitOffset[0] = new Integer((Integer)rule.getValue()); 
    246                                 limitFound = true; 
    247                         } else if (rule.getOperator() == QueryRule.Operator.OFFSET) { 
    248                                 limitOffset[1] = new Integer((Integer)rule.getValue()); 
    249                                 offsetFound = true; 
    250                         } 
    251                 } 
    252         } 
    253  
    254         /** 
    255          * Helper method for creating an escaped sql string for a value. 
    256          * <p> 
    257          * This can be used by createXXXsql methods to prevend sql-injection in data 
    258          * values. 
    259          *  
    260          * @param value 
    261          *            to be escaped 
    262          */ 
    263         public static String escapeSql(Object value) 
    264         { 
    265                 return StringEscapeUtils.escapeSql(value.toString()); 
    266                 // return sql.toString().replace("'", "''"); 
    267         } 
     24public class JPAQueryGeneratorUtil { 
     25 
     26    public static <E extends Entity> Predicate createWhere( 
     27            Class<E> klass, JpaMapper mapper, EntityManager em, Root<E> root, 
     28            CriteriaQuery cq, CriteriaBuilder cb, QueryRule... rules) { 
     29        Predicate whereClause = null; 
     30 
     31        for (QueryRule r : rules) { 
     32            QueryRule rule = new QueryRule(r); 
     33            if (mapper != null) { 
     34                rule.setField(mapper.getTableFieldName(rule.getField())); 
     35 
     36                boolean whereConditon = !(rule.getOperator() == Operator.LAST || rule.getOperator() == Operator.LIMIT 
     37                        || rule.getOperator() == Operator.OFFSET || rule.getOperator() == Operator.SORTASC 
     38                        || rule.getOperator() == Operator.SORTDESC || rule.getOperator() == QueryRule.Operator.NESTED 
     39                        || rule.getOperator() == QueryRule.Operator.IN); 
     40                if (whereConditon) { 
     41                    Predicate predicate = null; 
     42 
     43                    String field = rule.getField(); 
     44 
     45                    if(rule.getValue() == null) { 
     46                        predicate = root.get(field).isNull(); 
     47                    } else {      
     48                        switch (rule.getOperator()) { 
     49                            case EQUALS: 
     50                                predicate = cb.equal(root.get(field), rule.getValue()); 
     51                                break; 
     52                            case NOT: 
     53                                predicate = cb.notEqual(root.get(field), rule.getValue()); 
     54                                break; 
     55                            case LIKE: 
     56                                predicate = cb.like(root.get(field).as(String.class), (String)rule.getValue()); 
     57                                break; 
     58                            case LESS: 
     59                                predicate = cb.lessThan(root.get(field).as(String.class), (Comparable)rule.getValue() ); 
     60                                break; 
     61                            case GREATER: 
     62                                predicate = cb.greaterThan(root.get(field).as(String.class), (Comparable)rule.getValue() ); 
     63                                break; 
     64                            case LESS_EQUAL: 
     65                                predicate = cb.lessThanOrEqualTo(root.get(field).as(String.class), (Comparable)rule.getValue() ); 
     66                                break; 
     67                            case GREATER_EQUAL: 
     68                                predicate = cb.greaterThanOrEqualTo(root.get(field).as(String.class), (Comparable)rule.getValue() ); 
     69                                break; 
     70                        } 
     71                    } 
     72 
     73                    //compound coundition (and & or) 
     74                    if(whereClause != null) { 
     75                        assert predicate != null : rule.getOperator(); 
     76 
     77                        if(rule.isOr()) { 
     78                            whereClause = cb.or(whereClause, predicate); 
     79                        } else { 
     80                            whereClause = cb.and(whereClause, predicate); 
     81                        } 
     82                    } else { 
     83                        whereClause = predicate; 
     84                    } 
     85                } 
     86            } 
     87        } 
     88        return whereClause; 
     89    } 
     90 
     91    public static void createSort() { 
     92    } 
     93 
     94    public static String createWhereSql(JpaMapper mapper, boolean isNested, boolean withOffset, 
     95            Integer[] limitOffset, QueryRule... rules) throws DatabaseException { 
     96        StringBuffer where_clause = new StringBuffer(""); 
     97        for (QueryRule r : rules) { 
     98            QueryRule rule = new QueryRule(r); //copy because of side effects 
     99            //logger.debug(rule); 
     100 
     101            //String tablePrefix = ""; 
     102            if (mapper != null) { 
     103                rule.setField(mapper.getTableFieldName(rule.getField())); 
     104            } 
     105 
     106            if (rule.getOperator() == Operator.LAST || rule.getOperator() == Operator.LIMIT 
     107                    || rule.getOperator() == Operator.OFFSET || rule.getOperator() == Operator.SORTASC 
     108                    || rule.getOperator() == Operator.SORTDESC) { 
     109            } else if (rule.getOperator() == QueryRule.Operator.NESTED) { 
     110                QueryRule[] nestedrules = rule.getNestedRules(); 
     111                if (nestedrules.length > 0) { 
     112                    if (where_clause.length() > 0) { 
     113                        if (rule.isOr()) { 
     114                            where_clause.append(" OR "); 
     115                        } else { 
     116                            where_clause.append(" AND "); 
     117                        } 
     118                    } 
     119                    where_clause.append("("); 
     120                    where_clause.append(createWhereSql(mapper, true, false, null, nestedrules)); 
     121                    where_clause.append(")"); 
     122                } 
     123            } else if (rule.getOperator() == QueryRule.Operator.IN) { 
     124                if (where_clause.length() > 0) { 
     125                    if (rule.isOr()) { 
     126                        where_clause.append(" OR "); 
     127                    } else { 
     128                        where_clause.append(" AND "); 
     129                    } 
     130                } 
     131 
     132                //where_clause.append(tablePrefix + rule.getField() + " IN("); 
     133                where_clause.append(rule.getField() + " IN("); 
     134 
     135                Object[] values = new Object[0]; 
     136                if (rule.getValue() instanceof List) { 
     137                    values = ((List<Object>) rule.getValue()).toArray(); 
     138                } else { 
     139                    values = (Object[]) rule.getValue(); 
     140                } 
     141 
     142                for (int i = 0; i < values.length; i++) { 
     143                    if (i > 0) { 
     144                        where_clause.append(","); 
     145                    } 
     146                    if (mapper != null && omitQuotes(mapper.getFieldType(rule.getField()))) { 
     147                        //where_clause.append(values[i] 
     148                        //      .toString()); 
     149                        where_clause.append("'" + escapeSql(values[i]) + "'"); 
     150                    } else { 
     151                        where_clause.append("'" + escapeSql(values[i]) + "'"); 
     152                    } 
     153                } 
     154                where_clause.append(") "); 
     155            } else // where clause 
     156            { 
     157                // check validity of the rule 
     158                //if(rule.getField() == null || columnInfoMap.get(rule.getField()) == null ) 
     159                //{ 
     160                //      throw new DatabaseException("Invalid rule: field '"+ rule.getField() + "' not known."); 
     161                //} 
     162 
     163                String operator = ""; 
     164                switch (rule.getOperator()) { 
     165                    case EQUALS: 
     166                        operator = "="; 
     167                        break; 
     168                    case NOT: 
     169                        operator = "!="; 
     170                        break; 
     171                    case LIKE: 
     172                        operator = "LIKE"; 
     173                        break; 
     174                    case LESS: 
     175                        operator = "<"; 
     176                        break; 
     177                    case GREATER: 
     178                        operator = ">"; 
     179                        break; 
     180                    case LESS_EQUAL: 
     181                        operator = "<="; 
     182                        break; 
     183                    case GREATER_EQUAL: 
     184                        operator = ">="; 
     185                        break; 
     186                } 
     187                // if (rule.getField() != "" && operator != "" && 
     188                // rule.getValue() != "") 
     189                // { 
     190                if (where_clause.length() > 0) { 
     191                    if (rule.isOr()) { 
     192                        where_clause.append(" OR "); 
     193                    } else { 
     194                        where_clause.append(" AND "); 
     195                    } 
     196                } 
     197                if (new Boolean(true).equals(rule.getValue())) { 
     198                    rule.setValue("1"); 
     199                } 
     200                if (new Boolean(false).equals(rule.getValue())) { 
     201                    rule.setValue("0"); 
     202                } 
     203                Object value = rule.getValue() == null ? "NULL" : escapeSql(rule.getValue()); 
     204                if (!value.equals("NULL") && rule.getOperator() == Operator.LIKE && mapper != null && !omitQuotes(mapper.getFieldType(rule.getField()))) { 
     205                    if (!value.toString().trim().startsWith("%") && !value.toString().trim().endsWith("%")) { 
     206                        value = "%" + value + "%"; 
     207                    } 
     208                } 
     209 
     210                //if (omitQuotes(columnInfoMap.get(rule.getField()).getType())) 
     211                //              where_clause.append(tablePrefix + rule.getField() + " " + operator + " " + value + ""); 
     212                //else 
     213                //where_clause.append(tablePrefix + rule.getField() + " " + operator + " '" + value + "'"); 
     214                where_clause.append(rule.getField() + " " + operator + " '" + value + "'"); 
     215                // } 
     216            } 
     217        } 
     218 
     219        String result = where_clause.toString(); 
     220        if (!isNested && where_clause.length() > 0) { 
     221            result = " WHERE " + result; 
     222        } 
     223        createLimitSql(withOffset, rules, limitOffset); 
     224        return result + createSortSql(mapper, rules); 
     225    } 
     226 
     227    /** Helper method for creating a sort clause */ 
     228    private static String createSortSql(JpaMapper mapper, QueryRule... rules) { 
     229        return createSortSql(mapper, false, rules); 
     230    } 
     231 
     232    private static boolean omitQuotes(Type t) { 
     233        return t == Type.LONG || t == Type.INT || t == Type.DECIMAL; 
     234 
     235    } 
     236 
     237    /** 
     238     * Helper method for creating a sort clause 
     239     * 
     240     * @param tableName 
     241     *            name of the table that is used to prefix column names. 
     242     * @param reverseSorting 
     243     *            to reverese sorting order. This is used when trying to find 
     244     *            the "last records" in a sorted list by instead finding the 
     245     *            "first records" in the reversly ordered list. 
     246     * @param rules 
     247     *            query rules to be translated into sql order by clause. 
     248     * @return sql with sort clause 
     249     */ 
     250    public static String createSortSql(JpaMapper mapper, boolean reverseSorting, QueryRule rules[]) { 
     251 
     252        for (QueryRule rule : rules) { 
     253            if (rule.getOperator() == Operator.LAST) { 
     254                reverseSorting = !reverseSorting; 
     255                break; 
     256            } 
     257        } 
     258 
     259        String sort_clause = ""; 
     260        for (QueryRule r : rules) { 
     261            QueryRule rule = new QueryRule(r); //copy because of sideeffects 
     262 
     263            // limit clause 
     264            if ((rule.getOperator() == Operator.SORTASC && !reverseSorting) 
     265                    || (reverseSorting && rule.getOperator() == Operator.SORTDESC)) { 
     266                if (mapper != null) { 
     267                    rule.setValue(mapper.getTableFieldName(rule.getValue().toString())); 
     268                } 
     269                sort_clause += rule.getValue().toString() + " ASC,"; 
     270            } else if ((rule.getOperator() == QueryRule.Operator.SORTDESC && !reverseSorting) 
     271                    || (reverseSorting && rule.getOperator() == Operator.SORTASC)) { 
     272                if (mapper != null) { 
     273                    rule.setValue(mapper.getTableFieldName(rule.getValue().toString())); 
     274                } 
     275                sort_clause += rule.getValue().toString() + " DESC,"; 
     276            } 
     277        } 
     278        if (sort_clause.length() > 0) { 
     279            return " ORDER BY " + sort_clause.substring(0, sort_clause.lastIndexOf(",")); 
     280        } 
     281        return sort_clause; 
     282    } 
     283 
     284    /** 
     285     * Helper method for creating a limit clause 
     286     * 
     287     * @param withOffset 
     288     *            Indicate whether offset is to be used. If false the limit 
     289     *            clause is kept empty. 
     290     * @param rules 
     291     *            query rules to be translated into SQL order by clause. 
     292     * @param limit 
     293     *                    out: limit count of the query (returns null if no limit is found in the rules) 
     294     * @param offset 
     295     *            out: offset of the query (returns null if no offset is found in the rules); 
     296     * @return limit,offset as output parameters 
     297     */ 
     298    public static void createLimitSql(boolean withOffset, QueryRule[] rules, Integer[] limitOffset) { 
     299        boolean limitFound = false; 
     300        boolean offsetFound = false; 
     301        for (QueryRule rule : rules) { 
     302            if (rule.getOperator() == QueryRule.Operator.LIMIT) { 
     303                limitOffset[0] = new Integer((Integer) rule.getValue()); 
     304                limitFound = true; 
     305            } else if (rule.getOperator() == QueryRule.Operator.OFFSET) { 
     306                limitOffset[1] = new Integer((Integer) rule.getValue()); 
     307                offsetFound = true; 
     308            } 
     309        } 
     310    } 
     311 
     312    /** 
     313     * Helper method for creating an escaped sql string for a value. 
     314     * <p> 
     315     * This can be used by createXXXsql methods to prevend sql-injection in data 
     316     * values. 
     317     * 
     318     * @param value 
     319     *            to be escaped 
     320     */ 
     321    public static String escapeSql(Object value) { 
     322        return StringEscapeUtils.escapeSql(value.toString()); 
     323        // return sql.toString().replace("'", "''"); 
     324    } 
    268325} 
  • maven_sequence_lims/molgenis3_4_maven/src/main/java/org/molgenis/framework/data/jpa/JpaDatabase.java

    r2582 r2614  
    1313import javax.persistence.EntityManager; 
    1414import javax.persistence.RollbackException; 
     15import javax.persistence.criteria.CriteriaBuilder; 
     16import javax.persistence.criteria.CriteriaQuery; 
     17import javax.persistence.criteria.Predicate; 
     18import javax.persistence.criteria.Root; 
     19import javax.persistence.metamodel.EntityType; 
     20import javax.persistence.metamodel.Metamodel; 
    1521 
    1622import org.apache.log4j.Logger; 
     
    5460 */ 
    5561public abstract class JpaDatabase implements Database { 
    56         enum Action { 
    57                 ADD, UPDATE, REMOVE 
    58                 // remov(e) because of pretty printing. 
    59         }; 
    60          
    61         Security login;  
    62  
    63         /** batch size */ 
    64         static final int BATCH_SIZE = 5000; 
    65         /** List of mappers, mapping entities to a JDBC connection */ 
    66         static Map<String, JpaMapper> mappers = new TreeMap<String, JpaMapper>(); 
    67         /** The filesource associated to this database: takes care of "file" fields */ 
    68         File fileSource; 
    69         /** Logger for this database */ 
    70         static Logger logger = Logger.getLogger(JpaDatabase.class.getSimpleName()); 
    71         /** Current JPA entity manager */ 
    72         EntityManager em; 
    73         /**in transaction*/ 
    74         boolean inTransaction; 
    75          
    76         public JpaDatabase(EntityManager em) { 
    77                 this.em = em; 
    78         } 
    79          
    80          
    81  
    82         public List<Object[]> query(String qlQuery, QueryRule... rules ) throws DatabaseException { 
    83  
    84                 Integer[] limitOffset = new Integer[2]; 
    85                 qlQuery += JPAQueryGeneratorUtil.createWhereSql(null, false, true, limitOffset, rules); 
    86                 Integer limit = limitOffset[0]; 
    87                 Integer offset = limitOffset[1];                 
    88                  
    89                 javax.persistence.Query query = em.createQuery(qlQuery); 
    90                  
    91                 if(limit != null)       { 
    92                         query.setMaxResults(limit); 
    93                 }  
    94                 if(offset != null) { 
    95                         query.setFirstResult(offset); 
    96                 }                
    97                 return (List<Object[]>)query.getResultList();            
    98         } 
    99  
    100         @Override 
    101         public <E extends Entity> int count(Class<E> klazz, QueryRule... rules) 
    102                         throws DatabaseException { 
    103                 JpaMapper<E> mapper = getMapperFor(klazz); 
    104                 String where = JPAQueryGeneratorUtil.createWhereSql(mapper, false, 
    105                                 true, null, rules); 
    106                 return getMapperFor(klazz).count(where, em); 
    107         } 
    108  
    109         @Override 
    110         public <E extends Entity> List<E> findByExample(E example) 
    111                         throws DatabaseException { 
    112                 try { 
    113                         Query<E> q = (Query<E>) this.query(example.getClass()); 
    114                         for (String field : example.getFields()) { 
    115                                 if (example.get(field) != null) { 
    116                                         if (example.get(field) instanceof List) { 
    117                                                 if (((List) example.get(field)).size() > 0) 
    118                                                         q.in(field, (List) example.get(field)); 
    119                                         } else 
    120                                                 q.equals(field, example.get(field)); 
    121                                 } 
    122                         } 
    123  
    124                         return q.find(); 
    125                 } catch (ParseException pe) { 
    126                         // should never happen... 
    127                         pe.printStackTrace(); 
    128                 } 
    129                 return null; 
    130         } 
    131          
     62 
     63    enum Action { 
     64 
     65        ADD, UPDATE, REMOVE 
     66        // remov(e) because of pretty printing. 
     67    }; 
     68    Security login; 
     69    /** batch size */ 
     70    static final int BATCH_SIZE = 5000; 
     71    /** List of mappers, mapping entities to a JDBC connection */ 
     72    static Map<String, JpaMapper> mappers = new TreeMap<String, JpaMapper>(); 
     73    /** The filesource associated to this database: takes care of "file" fields */ 
     74    File fileSource; 
     75    /** Logger for this database */ 
     76    static Logger logger = Logger.getLogger(JpaDatabase.class.getSimpleName()); 
     77    /** Current JPA entity manager */ 
     78    EntityManager em; 
     79    /**in transaction*/ 
     80    boolean inTransaction; 
     81 
     82    public JpaDatabase(EntityManager em) { 
     83        this.em = em; 
     84    } 
     85 
     86    public List<Object[]> query(String qlQuery, QueryRule... rules) throws DatabaseException { 
     87        Integer[] limitOffset = new Integer[2]; 
     88        qlQuery += JPAQueryGeneratorUtil.createWhereSql(null, false, true, limitOffset, rules); 
     89        Integer limit = limitOffset[0]; 
     90        Integer offset = limitOffset[1]; 
     91 
     92        javax.persistence.Query query = em.createQuery(qlQuery); 
     93 
     94        if (limit != null) { 
     95            query.setMaxResults(limit); 
     96        } 
     97        if (offset != null) { 
     98            query.setFirstResult(offset); 
     99        } 
     100        return (List<Object[]>) query.getResultList(); 
     101    } 
     102 
     103    @Override 
     104    public <E extends Entity> int count(Class<E> klazz, QueryRule... rules) 
     105            throws DatabaseException { 
     106        CriteriaBuilder cb = em.getCriteriaBuilder(); 
     107        CriteriaQuery<Long> cq = cb.createQuery(Long.class); 
     108        Metamodel m = em.getMetamodel(); 
     109        Root<E> root = cq.from(klazz); 
     110 
     111        cq.select(cb.count(root.get("id"))); 
     112 
     113        JpaMapper<E> mapper = mappers.get(klazz.getName()); 
     114        Predicate whereClause = JPAQueryGeneratorUtil.createWhere(klazz, mapper, em, root, cq, cb, rules); 
     115        if(whereClause != null) 
     116            cq.where(whereClause); 
     117 
     118        if(!inTransaction) { 
     119                em.getTransaction().begin(); 
     120        } 
     121        //dit moet anders 
     122        int count = em.createQuery(cq).getSingleResult().intValue(); 
     123        if(!inTransaction) { 
     124                em.getTransaction().commit(); 
     125        } 
     126        return count; 
     127    } 
     128 
     129    @Override 
     130    public <E extends Entity> List<E> findByExample(E example) 
     131            throws DatabaseException { 
     132        try { 
     133            Query<E> q = (Query<E>) this.query(example.getClass()); 
     134            for (String field : example.getFields()) { 
     135                if (example.get(field) != null) { 
     136                    if (example.get(field) instanceof List) { 
     137                        if (((List) example.get(field)).size() > 0) { 
     138                            q.in(field, (List) example.get(field)); 
     139                        } 
     140                    } else { 
     141                        q.equals(field, example.get(field)); 
     142                    } 
     143                } 
     144            } 
     145 
     146            return q.find(); 
     147        } catch (ParseException pe) { 
     148            // should never happen... 
     149            pe.printStackTrace(); 
     150        } 
     151        return null; 
     152    } 
     153 
    132154//      @Override 
    133         public <E extends Entity> E findById(Class<E> klazz, Object id) { 
    134                 return (E)em.find(klazz, id); 
    135         } 
    136  
    137         @Override 
    138         public <E extends Entity> List<E> find(Class<E> klazz, QueryRule... rules) 
    139                         throws DatabaseException { 
    140                  
    141                 List<E> entities = null; 
    142                 JpaMapper<E> mapper = this.getMapperFor(klazz); 
    143                  
    144                 Integer[] limitOffset = new Integer[2]; 
    145                 String qlWhereClause = JPAQueryGeneratorUtil.createWhereSql(mapper, 
    146                                 false, true, limitOffset, rules); 
    147                 Integer limit = limitOffset[0]; 
    148                 Integer offset = limitOffset[1]; 
    149                  
    150                 //if(!inTransaction) em.getTransaction().begin(); 
    151                 entities = (List<E>) mapper.find(qlWhereClause, limit, offset, em); 
    152                 //if(!inTransaction) em.getTransaction().commit(); 
    153                  
    154                 logger.info(entities.size() + " " + klazz.getSimpleName() 
    155                                 + " objects found"); 
    156                  
    157                 return entities; 
    158         }        
    159  
    160         @Override 
    161         public <E extends Entity> void find(Class<E> klazz, CsvWriter writer, 
    162                         QueryRule... rules) throws DatabaseException { 
    163                 try { 
    164                         JpaMapper<E> mapper = this.getMapperFor(klazz); 
    165                         List<E> rs = executeSelect(klazz, rules); 
    166                         // transform result set in writer 
    167                         E entity = mapper.create(); 
    168                         writer.writeHeader(entity); 
    169                         int i = 0; 
    170                         List<E> entityBatch = new ArrayList<E>(); 
    171                         Iterator<E> iter = rs.iterator(); 
    172                         while (iter.hasNext()) { 
    173                                 entity = iter.next(); 
    174  
    175                                 // JDBCTuple row = new JDBCTuple(rs); 
    176                                 // entity = mapper.create(); 
    177                                 // entity.set(row); 
    178                                 entityBatch.add(entity); 
    179                                 i++; 
    180  
    181                                 // write batch 
    182                                 if (i % BATCH_SIZE == 0) { 
    183                                         // load mrefs 
    184                                         // mapper.mapMrefs(this, entityBatch); 
    185                                         for (E e : entityBatch) { 
    186                                                 writer.writeRow(entity); 
    187                                         } 
    188                                         entityBatch.clear(); 
    189                                 } 
    190                         } 
    191                         // write remaining 
    192                         // load mrefs 
    193                         // mapper.mapMrefs(this, entityBatch); 
    194                         for (E e : entityBatch) { 
    195                                 writer.writeRow(e); 
    196                         } 
    197                         entityBatch.clear(); 
    198  
    199                         logger.debug("find(" + klazz + ", CsvWriter, " 
    200                                         + Arrays.asList(rules) + "): wrote " + i + " lines."); 
    201                 } catch (Exception e) { 
    202                         throw new DatabaseException(e); 
    203                 } 
    204         } 
    205  
    206         @Override 
    207         public <E extends Entity> Query<E> query(Class<E> klazz) { 
    208                 return new QueryImp<E>(this, klazz); 
    209         } 
    210  
    211         @Override 
    212         public <E extends Entity> int add(E entity) throws DatabaseException, 
    213                         IOException { 
    214                 List<E> entityList = new ArrayList<E>(); 
    215                 entityList.add(entity); 
    216                 return this.add(entityList); 
    217         } 
    218  
    219         @Override 
    220         public <E extends Entity> int add(List<E> entities) 
    221                         throws DatabaseException, IOException { 
    222                 int count = 0; 
    223                 if (entities.size() > 0) { 
    224                         if(!inTransaction) { //vraag me af of dit echt nodig is? En zo ja in add, edit update? 
    225                                 em.getTransaction().begin(); 
    226                         } 
    227                         count = getMapperFor(entities).add(entities,em); 
    228                         if(!inTransaction) { 
    229                                 em.getTransaction().commit(); 
    230                         } 
    231                 } 
    232                 return count; 
    233         } 
    234  
    235         @Override 
    236         public <E extends Entity> int add(Class<E> klazz, CsvReader reader, 
    237                         CsvWriter writer) throws Exception { 
    238                 return executeUpdate(Action.ADD, klazz, reader, writer); 
    239         } 
    240  
    241         @Override 
    242         public <E extends Entity> int update(E entity) throws DatabaseException, 
    243                         IOException { 
    244                 List<E> entityList = new ArrayList<E>(); 
    245                 entityList.add(entity); 
    246                 return this.update(entityList); 
    247         } 
    248  
    249         @Override 
    250         public <E extends Entity> int update(List<E> entities) 
    251                         throws DatabaseException, IOException { 
    252                 int count = 0; 
    253                 if (entities.size() > 0) 
    254                 { 
    255                         if(!inTransaction) { //vraag me af of dit echt nodig is? En zo ja in add, edit update? 
    256                                 em.getTransaction().begin(); 
    257                         } 
    258                         count = getMapperFor(entities).update(entities,em); 
    259                         if(!inTransaction) { 
    260                                 em.getTransaction().commit(); 
    261                         }                        
    262                 } 
    263                 return count; 
    264         } 
    265  
    266         @Override 
    267         public <E extends Entity> int update(Class<E> klazz, CsvReader reader) 
    268                         throws Exception { 
    269                 throw new UnsupportedOperationException(); 
     155    public <E extends Entity> E findById(Class<E> klazz, Object id) { 
     156        return (E) em.find(klazz, id); 
     157    } 
     158 
     159    @Override 
     160    public <E extends Entity> List<E> find(Class<E> klazz, 
     161            QueryRule... rules) throws DatabaseException { 
     162 
     163        CriteriaBuilder cb = em.getCriteriaBuilder(); 
     164        CriteriaQuery<E> cq = cb.createQuery(klazz); 
     165        Root<E> root = cq.from(klazz); 
     166        cq.select(root); 
     167 
     168        JpaMapper<E> mapper = mappers.get(klazz.getName()); 
     169        Predicate whereClause = 
     170                JPAQueryGeneratorUtil.createWhere(klazz, mapper, em, root, cq, cb, rules); 
     171        if (whereClause != null) { 
     172            cq.where(whereClause); 
     173        } 
     174 
     175        if (!inTransaction) { 
     176            em.getTransaction().begin(); 
     177        } 
     178        List<E> entities = em.createQuery(cq).getResultList(); 
     179        if (!inTransaction) { 
     180            em.getTransaction().commit(); 
     181        } 
     182 
     183        return entities; 
     184    } 
     185 
     186    @Override 
     187    public <E extends Entity> void find(Class<E> klazz, CsvWriter writer, 
     188            QueryRule... rules) throws DatabaseException { 
     189        try { 
     190            JpaMapper<E> mapper = this.getMapperFor(klazz); 
     191            List<E> rs = executeSelect(klazz, rules); 
     192            // transform result set in writer 
     193            E entity = mapper.create(); 
     194            writer.writeHeader(entity); 
     195            int i = 0; 
     196            List<E> entityBatch = new ArrayList<E>(); 
     197            Iterator<E> iter = rs.iterator(); 
     198            while (iter.hasNext()) { 
     199                entity = iter.next(); 
     200 
     201                // JDBCTuple row = new JDBCTuple(rs); 
     202                // entity = mapper.create(); 
     203                // entity.set(row); 
     204                entityBatch.add(entity); 
     205                i++; 
     206 
     207                // write batch 
     208                if (i % BATCH_SIZE == 0) { 
     209                    // load mrefs 
     210                    // mapper.mapMrefs(this, entityBatch); 
     211                    for (E e : entityBatch) { 
     212                        writer.writeRow(entity); 
     213                    } 
     214                    entityBatch.clear(); 
     215                } 
     216            } 
     217            // write remaining 
     218            // load mrefs 
     219            // mapper.mapMrefs(this, entityBatch); 
     220            for (E e : entityBatch) { 
     221                writer.writeRow(e); 
     222            } 
     223            entityBatch.clear(); 
     224 
     225            logger.debug("find(" + klazz + ", CsvWriter, " 
     226                    + Arrays.asList(rules) + "): wrote " + i + " lines."); 
     227        } catch (Exception e) { 
     228            throw new DatabaseException(e); 
     229        } 
     230    } 
     231 
     232    @Override 
     233    public <E extends Entity> Query<E> query(Class<E> klazz) { 
     234        return new QueryImp<E>(this, klazz); 
     235    } 
     236 
     237    @Override 
     238    public <E extends Entity> int add(E entity) throws DatabaseException, 
     239            IOException { 
     240        List<E> entityList = new ArrayList<E>(); 
     241        entityList.add(entity); 
     242        return this.add(entityList); 
     243    } 
     244 
     245    @Override 
     246    public <E extends Entity> int add(List<E> entities) 
     247            throws DatabaseException, IOException { 
     248        int count = 0; 
     249        if (entities.size() > 0) { 
     250            if (!inTransaction) { //vraag me af of dit echt nodig is? En zo ja in add, edit update? 
     251                em.getTransaction().begin(); 
     252            } 
     253            count = getMapperFor(entities).add(entities, em); 
     254            if (!inTransaction) { 
     255                em.getTransaction().commit(); 
     256            } 
     257        } 
     258        return count; 
     259    } 
     260 
     261    @Override 
     262    public <E extends Entity> int add(Class<E> klazz, CsvReader reader, 
     263            CsvWriter writer) throws Exception { 
     264        return executeUpdate(Action.ADD, klazz, reader, writer); 
     265    } 
     266 
     267    @Override 
     268    public <E extends Entity> int update(E entity) throws DatabaseException, 
     269            IOException { 
     270        List<E> entityList = new ArrayList<E>(); 
     271        entityList.add(entity); 
     272        return this.update(entityList); 
     273    } 
     274 
     275    @Override 
     276    public <E extends Entity> int update(List<E> entities) 
     277            throws DatabaseException, IOException { 
     278        int count = 0; 
     279        if (entities.size() > 0) { 
     280            if (!inTransaction) { //vraag me af of dit echt nodig is? En zo ja in add, edit update? 
     281                em.getTransaction().begin(); 
     282            } 
     283            count = getMapperFor(entities).update(entities, em); 
     284            if (!inTransaction) { 
     285                em.getTransaction().commit(); 
     286            } 
     287        } 
     288        return count; 
     289    } 
     290 
     291    @Override 
     292    public <E extends Entity> int update(Class<E> klazz, CsvReader reader) 
     293            throws Exception { 
     294        throw new UnsupportedOperationException(); 
    270295//              return executeUpdate(Action.UPDATE, klazz, reader, null); 
    271         } 
    272  
    273         @Override 
    274         public <E extends Entity> int remove(E entity) throws DatabaseException, 
    275                         IOException { 
    276                 List<E> entityList = new ArrayList<E>(); 
    277                 entityList.add(entity); 
    278                 return this.remove(entityList); 
    279         } 
    280  
    281         @Override 
    282         public <E extends Entity> int remove(List<E> entities) 
    283                         throws DatabaseException, IOException { 
    284                 int count = 0; 
    285                 try 
    286                 {        
    287                         if (entities.size() > 0) 
    288                         { 
    289                                 if(!inTransaction) { //vraag me af of dit echt nodig is? En zo ja in add, edit update? 
    290                                         em.getTransaction().begin(); 
    291                                 } 
    292                                 count = getMapperFor(entities).remove(entities,em); 
    293                                 if(!inTransaction) { 
    294                                         em.getTransaction().commit(); 
    295                                 }                                        
    296                         }                                                
    297                 } catch (RollbackException ex) { 
    298                         throw new DatabaseException(ex.getCause().getMessage()); 
    299                 }        
    300                 return count; 
    301         } 
    302  
    303         @Override 
    304         public <E extends Entity> int remove(Class<E> klazz, CsvReader reader) 
    305                         throws Exception { 
    306                 return executeUpdate(Action.REMOVE, klazz, reader, null); 
    307         } 
    308  
    309         @Override 
    310         public File getFilesource() { 
    311                 return this.fileSource; 
    312         } 
    313  
    314         /** 
    315          * Find the mapper from this.mappers 
    316          *  
    317          * @param klazz 
    318          *            the entity class to get the mapper from 
    319          * @return a mapper or a exception 
    320          * @throws DatabaseException 
    321          */ 
    322         public <E extends Entity> JpaMapper<E> getMapperFor(Class<E> klazz) 
    323                         throws DatabaseException { 
    324                 // transform to generic exception 
    325                 JpaMapper<E> mapper = mappers.get(klazz.getName()); 
    326                 if (mapper == null) 
    327                         throw new DatabaseException( 
    328                                         "getMapperFor failed because no mapper available for " 
    329                                                         + klazz.getName()); 
    330                 return mapper; 
    331         } 
    332  
    333         /** 
    334          * Assign a mapper for a certain class. 
    335          *  
    336          * <pre> 
    337          * putMapper(Example.class, new ExampleMapper()); 
    338          * </pre> 
    339          *  
    340          * @param klazz 
    341          *            the class of this Entity 
    342          * @param mapper 
    343          */ 
    344         protected static <E extends Entity> void putMapper(Class<E> klazz, 
    345                         JpaMapper<E> mapper) { 
    346                 mappers.put(klazz.getName(), mapper); 
    347                 logger.debug("added mapper for klazz " + klazz.getName()); 
    348         } 
    349  
    350         @Override 
    351         public List<String> getEntityNames() { 
    352                 List<String> entities = new ArrayList<String>(); 
    353                 entities.addAll(mappers.keySet()); 
    354                 return entities; 
    355         } 
    356  
    357         @Override 
    358         public <E extends Entity> List<E> toList(Class<E> klazz, CsvReader reader, 
    359                         int limit) throws Exception { 
    360                 final JpaMapper<E> mapper = this.getMapperFor(klazz); 
    361                 final List<E> entities = new ArrayList<E>(10); 
    362                 reader.parse(limit, new CsvReaderListener() { 
    363                         @Override 
    364                         public void handleLine(int line_number, Tuple line) 
    365                                         throws Exception { 
    366                                 E e = mapper.create(); 
    367                                 e.set(line, false); // parse the tuple 
    368                                 entities.add(e); 
    369                         } 
    370                 }); 
    371                 return entities; 
    372         } 
    373  
    374         /** 
    375          * Local helper to find mappers for lists. 
    376          *  
    377          * @param entities 
    378          *            list of entities to find this mapper for. 
    379          * @return a mapper or a exception 
    380          * @throws DatabaseException 
    381          */ 
    382         private <E extends Entity> JpaMapper<E> getMapperFor(List<E> entities) 
    383                         throws DatabaseException { 
    384                 try { 
    385                         Class klazz = entities.get(0).getClass(); 
    386                         return getMapperFor(klazz); 
    387                 } catch (NullPointerException e) { 
    388                         // transform to generic exception 
    389                         logger.error("trying to store empty list"); 
    390                         throw new DatabaseException( 
    391                                         "getMapperFor failed because of empty list"); 
    392                 } 
    393         } 
    394  
    395         private <E extends Entity> int executeUpdate(Action action, 
    396                         JpaMapper<E> mapper, List<E> entities) throws DatabaseException { 
    397                 return this.executeUpdate(action, mapper, entities, true); 
    398         } 
    399  
    400         private <E extends Entity> int executeUpdate(Action action, 
    401                         JpaMapper<E> mapper, List<E> entities, boolean skipFiles) 
    402                         throws DatabaseException { 
    403                 int updatedRows = 0; 
    404                 try { 
    405                         // prepare file attachments 
    406                         mapper.prepareFileAttachements(entities, fileSource); 
    407  
    408                         // insert/update/delete 
    409                         for (int i = 0; i < entities.size(); i += BATCH_SIZE) { 
    410                                 // logger.debug("steekproef: "+entities.get(i)); 
    411                                 int endindex = Math.min(i + BATCH_SIZE, entities.size()); 
    412                                 List<E> sublist = entities.subList(i, endindex); 
    413  
    414                                 // get the right statement 
    415                                 switch (action) { 
    416                                 case ADD: 
    417                                         updatedRows += mapper.add(sublist, em); 
    418                                         break; 
    419                                 case UPDATE: 
    420                                         updatedRows += mapper.update(sublist, em); 
    421                                         break; 
    422                                 case REMOVE: 
    423                                         updatedRows += mapper.remove(sublist, em); 
    424                                         break; 
    425                                 } 
    426  
    427                                 // rename file attachments with right name and update database 
    428                                 if (!action.equals(Action.REMOVE)) { 
    429                                         if (mapper.saveFileAttachements(entities, this.fileSource)) { 
    430                                                 mapper.update(sublist, em); 
    431                                         } 
    432                                 } 
    433                         } 
    434  
    435                         logger.info(updatedRows + " " 
    436                                         + mapper.create().getClass().getSimpleName() + " objects " 
    437                                         + action.toString().toLowerCase() + "ed"); 
    438                         return updatedRows; 
    439                 } catch (Exception sqle) { 
    440                         throw new DatabaseException(sqle); 
    441                 } 
    442         } 
    443  
    444         /** 
    445          * Helper function of various find functions. 
    446          *  
    447          * @param <E> 
    448          * @param klazz 
    449          * @param rules 
    450          * @return 
    451          * @throws DatabaseException 
    452          */ 
    453         private <E extends Entity> List<E> executeSelect(Class<E> klazz, 
    454                         QueryRule... rules) throws DatabaseException { 
    455                 JpaMapper<E> mapper = this.getMapperFor(klazz); 
    456                  
    457                 Integer[] limitOffset = new Integer[2]; 
    458                 String qlWhereClause = JPAQueryGeneratorUtil.createWhereSql(mapper, 
    459                                 false, true, limitOffset,  rules); 
    460                 Integer limit = limitOffset[0]; 
    461                 Integer offset = limitOffset[1]; 
    462                 List<E> result = mapper.find(qlWhereClause, limit, offset, em); 
    463                 return result; 
    464         } 
    465  
    466         /** 
    467          *  
    468          * @param <E> 
    469          * @param action 
    470          * @param klazz 
    471          * @param reader 
    472          * @param writer 
    473          * @return 
    474          * @throws DatabaseException 
    475          */ 
    476         private <E extends Entity> int executeUpdate(Action action, Class<E> klazz, 
    477                         CsvReader reader, CsvWriter writer) throws DatabaseException { 
    478                 int rowsAffected = 0; 
    479                 try { 
    480                         List<E> entities = toList(klazz, reader, BATCH_SIZE); 
    481  
    482                         if (writer != null) 
    483                                 writer.writeHeader(entities.get(0)); 
    484  
    485                         JpaMapper<E> mapper = getMapperFor(klazz); 
    486                         while (entities.size() > 0) { 
    487                                 // add to the database 
    488                                 rowsAffected += this.executeUpdate(action, mapper, entities); 
    489                                 if (writer != null) { 
    490                                         for (E entity : entities) { 
    491                                                 writer.writeRow(entity); 
    492                                         } 
    493                                 } 
    494                                 entities = toList(klazz, reader, BATCH_SIZE); 
    495                         } 
    496                 } catch (Exception e) { 
    497                         throw new DatabaseException(e); 
    498                 } 
    499                 return rowsAffected; 
    500         } 
    501  
    502         @Override 
    503         public List<Class> getEntityClasses() { 
    504  
    505                 List<Class> classes = new ArrayList<Class>(); 
    506                 try { 
    507                         for (String klazz : this.getEntityNames()) { 
    508                                 classes.add(Class.forName(klazz)); 
    509                         } 
    510                 } catch (Exception e) { 
    511                         e.printStackTrace(); 
    512                 } 
    513                 return classes; 
    514         } 
    515  
    516         @Override 
    517         public void beginTx() throws DatabaseException { 
    518                 em.getTransaction().begin(); 
    519                 inTransaction = true; 
    520         } 
    521  
    522         @Override 
    523         public void close() throws DatabaseException { 
    524                 throw new UnsupportedOperationException(); 
    525  
    526         } 
    527  
    528         @Override 
    529         public void commitTx() throws DatabaseException { 
    530                 em.getTransaction().commit(); 
    531                 inTransaction = false; 
    532  
    533         } 
    534  
    535         @Override 
    536         public Class<Entity> getClassForName(String name) { 
    537                 throw new UnsupportedOperationException(); 
    538         } 
    539  
    540  
    541         @Override 
    542         public Security getSecurity() { 
    543                 return login; 
    544         } 
    545  
    546         @Override 
    547         public boolean inTx() { 
    548                 return inTransaction; 
    549         } 
    550  
    551         @Override 
    552         public CustomQuery query(List<String> fields) throws DatabaseException { 
    553                 return (CustomQuery)new JpaCustomQuery(this, fields); 
    554         } 
    555  
    556         @Override 
    557         public void rollbackTx() throws DatabaseException { 
    558                 em.getTransaction().rollback(); 
    559         } 
    560  
    561         @Override 
    562         public void setLogin(Security login) { 
    563                 this.login = login; 
    564         } 
    565          
     296    } 
     297 
     298    @Override 
     299    public <E extends Entity> int remove(E entity) throws DatabaseException, 
     300            IOException { 
     301        List<E> entityList = new ArrayList<E>(); 
     302        entityList.add(entity); 
     303        return this.remove(entityList); 
     304    } 
     305 
     306    @Override 
     307    public <E extends Entity> int remove(List<E> entities) 
     308            throws DatabaseException, IOException { 
     309        int count = 0; 
     310        try { 
     311            if (entities.size() > 0) { 
     312                if (!inTransaction) { //vraag me af of dit echt nodig is? En zo ja in add, edit update? 
     313                    em.getTransaction().begin(); 
     314                } 
     315                count = getMapperFor(entities).remove(entities, em); 
     316                if (!inTransaction) { 
     317                    em.getTransaction().commit(); 
     318                } 
     319            } 
     320        } catch (RollbackException ex) { 
     321            throw new DatabaseException(ex.getCause().getMessage()); 
     322        } 
     323        return count; 
     324    } 
     325 
     326    @Override 
     327    public <E extends Entity> int remove(Class<E> klazz, CsvReader reader) 
     328            throws Exception { 
     329        return executeUpdate(Action.REMOVE, klazz, reader, null); 
     330    } 
     331 
     332    @Override 
     333    public File getFilesource() { 
     334        return this.fileSource; 
     335    } 
     336 
     337    /** 
     338     * Find the mapper from this.mappers 
     339     * 
     340     * @param klazz 
     341     *            the entity class to get the mapper from 
     342     * @return a mapper or a exception 
     343     * @throws DatabaseException 
     344     */ 
     345    public <E extends Entity> JpaMapper<E> getMapperFor(Class<E> klazz) 
     346            throws DatabaseException { 
     347        // transform to generic exception 
     348        JpaMapper<E> mapper = mappers.get(klazz.getName()); 
     349        if (mapper == null) { 
     350            throw new DatabaseException( 
     351                    "getMapperFor failed because no mapper available for " 
     352                    + klazz.getName()); 
     353        } 
     354        return mapper; 
     355    } 
     356 
     357    /** 
     358     * Assign a mapper for a certain class. 
     359     * 
     360     * <pre> 
     361     * putMapper(Example.class, new ExampleMapper()); 
     362     * </pre> 
     363     * 
     364     * @param klazz 
     365     *            the class of this Entity 
     366     * @param mapper 
     367     */ 
     368    protected static <E extends Entity> void putMapper(Class<E> klazz, 
     369            JpaMapper<E> mapper) { 
     370        mappers.put(klazz.getName(), mapper); 
     371        logger.debug("added mapper for klazz " + klazz.getName()); 
     372    } 
     373 
     374    @Override 
     375    public List<String> getEntityNames() { 
     376        List<String> entities = new ArrayList<String>(); 
     377        entities.addAll(mappers.keySet()); 
     378        return entities; 
     379    } 
     380 
     381    @Override 
     382    public <E extends Entity> List<E> toList(Class<E> klazz, CsvReader reader, 
     383            int limit) throws Exception { 
     384        final JpaMapper<E> mapper = this.getMapperFor(klazz); 
     385        final List<E> entities = new ArrayList<E>(10); 
     386        reader.parse(limit, new CsvReaderListener() { 
     387 
     388            @Override 
     389            public void handleLine(int line_number, Tuple line) 
     390                    throws Exception { 
     391                E e = mapper.create(); 
     392                e.set(line, false); // parse the tuple 
     393                entities.add(e); 
     394            } 
     395        }); 
     396        return entities; 
     397    } 
     398 
     399    /** 
     400     * Local helper to find mappers for lists. 
     401     * 
     402     * @param entities 
     403     *            list of entities to find this mapper for. 
     404     * @return a mapper or a exception 
     405     * @throws DatabaseException 
     406     */ 
     407    private <E extends Entity> JpaMapper<E> getMapperFor(List<E> entities) 
     408            throws DatabaseException { 
     409        try { 
     410            Class klazz = entities.get(0).getClass(); 
     411            return getMapperFor(klazz); 
     412        } catch (NullPointerException e) { 
     413            // transform to generic exception 
     414            logger.error("trying to store empty list"); 
     415            throw new DatabaseException( 
     416                    "getMapperFor failed because of empty list"); 
     417        } 
     418    } 
     419 
     420    private <E extends Entity> int executeUpdate(Action action, 
     421            JpaMapper<E> mapper, List<E> entities) throws DatabaseException { 
     422        return this.executeUpdate(action, mapper, entities, true); 
     423    } 
     424 
     425    private <E extends Entity> int executeUpdate(Action action, 
     426            JpaMapper<E> mapper, List<E> entities, boolean skipFiles) 
     427            throws DatabaseException { 
     428        int updatedRows = 0; 
     429        try { 
     430            // prepare file attachments 
     431            mapper.prepareFileAttachements(entities, fileSource); 
     432 
     433            // insert/update/delete 
     434            for (int i = 0; i < entities.size(); i += BATCH_SIZE) { 
     435                // logger.debug("steekproef: "+entities.get(i)); 
     436                int endindex = Math.min(i + BATCH_SIZE, entities.size()); 
     437                List<E> sublist = entities.subList(i, endindex); 
     438 
     439                // get the right statement 
     440                switch (action) { 
     441                    case ADD: 
     442                        updatedRows += mapper.add(sublist, em); 
     443                        break; 
     444                    case UPDATE: 
     445                        updatedRows += mapper.update(sublist, em); 
     446                        break; 
     447                    case REMOVE: 
     448                        updatedRows += mapper.remove(sublist, em); 
     449                        break; 
     450                } 
     451 
     452                // rename file attachments with right name and update database 
     453                if (!action.equals(Action.REMOVE)) { 
     454                    if (mapper.saveFileAttachements(entities, this.fileSource)) { 
     455                        mapper.update(sublist, em); 
     456                    } 
     457                } 
     458            } 
     459 
     460            logger.info(updatedRows + " " 
     461                    + mapper.create().getClass().getSimpleName() + " objects " 
     462                    + action.toString().toLowerCase() + "ed"); 
     463            return updatedRows; 
     464        } catch (Exception sqle) { 
     465            throw new DatabaseException(sqle); 
     466        } 
     467    } 
     468 
     469    /** 
     470     * Helper function of various find functions. 
     471     * 
     472     * @param <E> 
     473     * @param klazz 
     474     * @param rules 
     475     * @return 
     476     * @throws DatabaseException 
     477     */ 
     478    private <E extends Entity> List<E> executeSelect(Class<E> klazz, 
     479            QueryRule... rules) throws DatabaseException { 
     480        JpaMapper<E> mapper = this.getMapperFor(klazz); 
     481 
     482        Integer[] limitOffset = new Integer[2]; 
     483        String qlWhereClause = JPAQueryGeneratorUtil.createWhereSql(mapper, 
     484                false, true, limitOffset, rules); 
     485        Integer limit = limitOffset[0]; 
     486        Integer offset = limitOffset[1]; 
     487 
     488 
     489 
     490 
     491        List<E> result = mapper.find(qlWhereClause, limit, offset, em); 
     492        return result; 
     493    } 
     494 
     495    /** 
     496     * 
     497     * @param <E> 
     498     * @param action 
     499     * @param klazz 
     500     * @param reader 
     501     * @param writer 
     502     * @return 
     503     * @throws DatabaseException 
     504     */ 
     505    private <E extends Entity> int executeUpdate(Action action, Class<E> klazz, 
     506            CsvReader reader, CsvWriter writer) throws DatabaseException { 
     507        int rowsAffected = 0; 
     508        try { 
     509            List<E> entities = toList(klazz, reader, BATCH_SIZE); 
     510 
     511            if (writer != null) { 
     512                writer.writeHeader(entities.get(0)); 
     513            } 
     514 
     515            JpaMapper<E> mapper = getMapperFor(klazz); 
     516            while (entities.size() > 0) { 
     517                // add to the database 
     518                rowsAffected += this.executeUpdate(action, mapper, entities); 
     519                if (writer != null) { 
     520                    for (E entity : entities) { 
     521                        writer.writeRow(entity); 
     522                    } 
     523                } 
     524                entities = toList(klazz, reader, BATCH_SIZE); 
     525            } 
     526        } catch (Exception e) { 
     527            throw new DatabaseException(e); 
     528        } 
     529        return rowsAffected; 
     530    } 
     531 
     532    @Override 
     533    public List<Class> getEntityClasses() { 
     534 
     535        List<Class> classes = new ArrayList<Class>(); 
     536        try { 
     537            for (String klazz : this.getEntityNames()) { 
     538                classes.add(Class.forName(klazz)); 
     539            } 
     540        } catch (Exception e) { 
     541            e.printStackTrace(); 
     542        } 
     543        return classes; 
     544    } 
     545 
     546    @Override 
     547    public void beginTx() throws DatabaseException { 
     548        em.getTransaction().begin(); 
     549        inTransaction = true; 
     550    } 
     551 
     552    @Override 
     553    public void close() throws DatabaseException { 
     554        throw new UnsupportedOperationException(); 
     555 
     556    } 
     557 
     558    @Override 
     559    public void commitTx() throws DatabaseException { 
     560        em.getTransaction().commit(); 
     561        inTransaction = false; 
     562 
     563    } 
     564 
     565    @Override 
     566    public Class<Entity> getClassForName(String name) { 
     567        throw new UnsupportedOperationException(); 
     568    } 
     569 
     570    @Override 
     571    public Security getSecurity() { 
     572        return login; 
     573    } 
     574 
     575    @Override 
     576    public boolean inTx() { 
     577        return inTransaction; 
     578    } 
     579 
     580    @Override 
     581    public CustomQuery query(List<String> fields) throws DatabaseException { 
     582        return (CustomQuery) new JpaCustomQuery(this, fields); 
     583    } 
     584 
     585    @Override 
     586    public void rollbackTx() throws DatabaseException { 
     587        em.getTransaction().rollback(); 
     588    } 
     589 
     590    @Override 
     591    public void setLogin(Security login) { 
     592        this.login = login; 
     593    } 
    566594//      public void finalize() throws Throwable 
    567595//      { 
  • maven_sequence_lims/molgenis3_4_maven/src/main/java/org/molgenis/framework/data/jpa/JpaMapper.java

    r2582 r2614  
    88 
    99import org.molgenis.framework.data.DatabaseException; 
     10import org.molgenis.framework.data.QueryRule; 
    1011import org.molgenis.framework.data.jdbc.ColumnInfo.Type; 
    1112import org.molgenis.util.Entity; 
    1213 
    1314/** 
    14  * Interface for (Database) Access Object ((DB)AO), hernoemen? (IDBOA) 
    15  * DBAO is de J2EE naamgeving! Maar DAO is ook gebruikerlijk! 
    16  * 
    1715 * @author Morris Swertz 
    1816 * @author Joris Lops 
     
    2321        public List<E> find(String jpaQlWhereClause, Integer limit, Integer offset, EntityManager em); 
    2422        public int count(String jpaQlWhereClause, EntityManager em); 
     23//        public int count(EntityManager em, QueryRule... rules); 
    2524 
    2625        /** 
  • maven_sequence_lims/molgenis3_4_maven/src/main/java/org/molgenis/framework/data/paging/AbstractPager.java

    r2582 r2614  
    259259        protected void reloadPage(Database db, QueryRule... rules) throws DatabaseException 
    260260        { 
    261                 setPage(db.find(klazz, rules)); 
     261            setPage(db.find(klazz, rules)); 
    262262        } 
    263263 
  • maven_sequence_lims/molgenis3_4_maven/src/main/java/org/molgenis/generators/data/types/DataTypeGen.java.ftl

    r2582 r2614  
    125125        //${field.name}[type=${field.type}] 
    126126        <#if field.type == "xref"> 
    127         private  ${JavaName(field.getXRefEntity())} _${name(field)} = null; 
     127        private  ${JavaName(field.getXRefEntity())} _${name(field)}; 
    128128        //xref_field             
    129129        private ${type(field)} _${name(field)}_${name(field.XRefField)} = ${default(field)}; 
    130130        <#if field.XRefField != field.XRefLabelString>//xref_label 
    131         private String _${name(field)}_${name(field.XRefLabelString)} = null; 
     131        private String _${name(field)}_${name(field.XRefLabelString)}; 
    132132        </#if><#elseif field.type == "mref"> 
    133133        private java.util.List<${JavaName(field.getXRefEntity())}> _${name(field)} = new ArrayList<${JavaName(field.getXRefEntity())}>();        
     
    139139        private ${type(field)} _${name(field)} = ${default(field)}; 
    140140                <#if field.type == "enum"> 
    141         private String _${name(field)}_label = null;             
     141        private String _${name(field)}_label; 
    142142        private java.util.List<ValueLabel> _${name(field)}_options = new ArrayList<ValueLabel>(); 
    143143                </#if> 
    144144                <#if field.type == "file" || field.type=="image" > 
    145         private File _${name(field)}_file = null; 
     145        private File _${name(field)}_file; 
    146146                </#if> 
    147147        </#if> 
  • maven_sequence_lims/molgenis3_4_maven/src/main/java/org/molgenis/generators/data/types/JpaDataTypeGen.java.ftl

    r2582 r2614  
    201201                </#if> 
    202202                </#if> 
    203                 <#if field.type == "date"> 
     203        <#if field.type == "date"> 
    204204    @Temporal(TemporalType.DATE) 
    205         </#if>           
     205        </#if> 
     206        <#if field.type == "datetime"> 
     207    @Temporal(TemporalType.TIMESTAMP) 
     208        </#if> 
     209 
    206210                <#if field.type == "xref"> 
    207211    @ManyToOne(cascade={CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH}) 
Note: See TracChangeset for help on using the changeset viewer.