Author: tchemit Date: 2012-02-20 14:27:33 +0100 (Mon, 20 Feb 2012) New Revision: 2407 Url: http://nuiton.org/repositories/revision/topia/2407 Log: Anomalie #1976: Can not pass a list parameter in aTopiaQuery Evolution #1931: Improve TopiaQuery (Where, order by and group by parts as List) - reformat TopiaContextImpl (i18n sentences must be on same line thant the _( invocation)) Modified: trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/TopiaContextImpl.java trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/TopiaQuery.java trunk/topia-persistence/src/test/java/org/nuiton/topia/framework/TopiaQueryTest.java Modified: trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/TopiaContextImpl.java =================================================================== --- trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/TopiaContextImpl.java 2012-02-15 14:15:11 UTC (rev 2406) +++ trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/TopiaContextImpl.java 2012-02-20 13:27:33 UTC (rev 2407) @@ -819,12 +819,10 @@ @Override public void commitTransaction() throws TopiaException { if (equals(getRootContext())) { - throw new TopiaException(_( - "topia.persistence.error.unsupported.operation.on.root.context", + throw new TopiaException(_("topia.persistence.error.unsupported.operation.on.root.context", "commit")); } - checkClosed(_( - "topia.persistence.error.unsupported.operation.on.closed.context", + checkClosed(_("topia.persistence.error.unsupported.operation.on.closed.context", "commit")); try { @@ -859,12 +857,10 @@ @Override public void rollbackTransaction() throws TopiaException { if (equals(getRootContext())) { - throw new TopiaException(_( - "topia.persistence.error.unsupported.operation.on.root.context", + throw new TopiaException(_("topia.persistence.error.unsupported.operation.on.root.context", "rollback")); } - checkClosed(_( - "topia.persistence.error.unsupported.operation.on.closed.context", + checkClosed(_("topia.persistence.error.unsupported.operation.on.closed.context", "rollback")); try { // for (TopiaDAO<? extends TopiaEntity> dao : daoCache.values()) { @@ -971,8 +967,7 @@ @SuppressWarnings({"unchecked"}) @Override public TopiaEntity findByTopiaId(String id) throws TopiaException { - checkClosed(_( - "topia.persistence.error.unsupported.operation.on.closed.context", + checkClosed(_("topia.persistence.error.unsupported.operation.on.closed.context", "findById")); Class<TopiaEntity> entityClass = TopiaId.getClassName(id); @@ -994,8 +989,7 @@ @Override public List<?> find(String hql, Object... args) throws TopiaException { - checkClosed(_( - "topia.persistence.error.unsupported.operation.on.closed.context", + checkClosed(_("topia.persistence.error.unsupported.operation.on.closed.context", "find")); try { @@ -1005,6 +999,8 @@ Object value = args[j + 1]; if (value.getClass().isArray()) { query.setParameterList(name, (Object[]) value); + } else if (value instanceof Collection<?>) { + query.setParameterList(name, (Collection<?>) value); } else { query.setParameter(name, value); } @@ -1025,8 +1021,7 @@ @Override public List<?> find(String hql, int startIndex, int endIndex, Object... args) throws TopiaException { - checkClosed(_( - "topia.persistence.error.unsupported.operation.on.closed.context", + checkClosed(_("topia.persistence.error.unsupported.operation.on.closed.context", "find")); try { @@ -1065,8 +1060,7 @@ */ @Override public int execute(String hql, Object... args) throws TopiaException { - checkClosed(_( - "topia.persistence.error.unsupported.operation.on.closed.context", + checkClosed(_("topia.persistence.error.unsupported.operation.on.closed.context", "find")); try { @@ -1084,8 +1078,7 @@ @Override public void add(TopiaEntity e) throws TopiaException { - checkClosed(_( - "topia.persistence.error.unsupported.operation.on.closed.context", + checkClosed(_("topia.persistence.error.unsupported.operation.on.closed.context", "add")); String id = e.getTopiaId(); @@ -1096,8 +1089,7 @@ @Override public void importXML(Reader xml) throws TopiaException { - checkClosed(_( - "topia.persistence.error.unsupported.operation.on.closed.context", + checkClosed(_("topia.persistence.error.unsupported.operation.on.closed.context", "importXML")); Document doc; @@ -1138,8 +1130,7 @@ @Override public void exportXML(Writer xml, Object... entityAndcondition) throws TopiaException { - checkClosed(_( - "topia.persistence.error.unsupported.operation.on.closed.context", + checkClosed(_("topia.persistence.error.unsupported.operation.on.closed.context", "exportXML")); String[] queries = buildQueries(entityAndcondition); @@ -1208,8 +1199,7 @@ @Override public void replicate(TopiaContext dstCtxt, Object... entityAndCondition) throws TopiaException, IllegalArgumentException { - checkClosed(_( - "topia.persistence.error.unsupported.operation.on.closed.context", + checkClosed(_("topia.persistence.error.unsupported.operation.on.closed.context", "replicate")); TopiaContextImpl dstContextImpl = (TopiaContextImpl) dstCtxt; @@ -1246,13 +1236,11 @@ public <T extends TopiaEntity> void replicateEntity(TopiaContext dstCtxt, T entity) throws TopiaException, IllegalArgumentException { - checkClosed(_( - "topia.persistence.error.unsupported.operation.on.closed.context", + checkClosed(_("topia.persistence.error.unsupported.operation.on.closed.context", "replicateEntity")); TopiaContextImpl dstContextImpl = (TopiaContextImpl) dstCtxt; - dstContextImpl.checkClosed(_( - "topia.persistence.error.unsupported.operation.on.closed.context", + dstContextImpl.checkClosed(_("topia.persistence.error.unsupported.operation.on.closed.context", "replicateEntity")); if (getRootContext().equals(dstContextImpl.getRootContext())) { @@ -1266,18 +1254,15 @@ public <T extends TopiaEntity> void replicateEntities(TopiaContext dstCtxt, List<T> entities) throws TopiaException, IllegalArgumentException { - checkClosed(_( - "topia.persistence.error.unsupported.operation.on.closed.context", + checkClosed(_("topia.persistence.error.unsupported.operation.on.closed.context", "replicateEntities")); TopiaContextImpl dstContextImpl = (TopiaContextImpl) dstCtxt; - dstContextImpl.checkClosed(_( - "topia.persistence.error.unsupported.operation.on.closed.context", + dstContextImpl.checkClosed(_("topia.persistence.error.unsupported.operation.on.closed.context", "replicateEntities")); if (getRootContext().equals(dstContextImpl.getRootContext())) { - throw new IllegalArgumentException(_( - "topia.persistence.error.replicate.on.same.context")); + throw new IllegalArgumentException(_("topia.persistence.error.replicate.on.same.context")); } replicate0(dstContextImpl, entities.toArray()); } @@ -1298,8 +1283,7 @@ */ @Override public void backup(File file, boolean compress) throws TopiaException { - checkClosed(_( - "topia.persistence.error.unsupported.operation.on.closed.context", + checkClosed(_("topia.persistence.error.unsupported.operation.on.closed.context", "backup")); try { String options = ""; @@ -1329,8 +1313,7 @@ public void restore(File file) throws TopiaException { // send event getFiresSupport().firePreRestoreSchema(this); - checkClosed(_( - "topia.persistence.error.unsupported.operation.on.closed.context", + checkClosed(_("topia.persistence.error.unsupported.operation.on.closed.context", "restore")); String sql = null; @@ -1389,8 +1372,8 @@ tx.closeContext(); root.finalize(); } catch (Throwable eee) { - throw new TopiaException(_( - "topia.persistence.error.on.clear", eee.getMessage()), eee); + throw new TopiaException( + _("topia.persistence.error.on.clear", eee.getMessage()), eee); } } @@ -1402,8 +1385,7 @@ @Override public boolean isSchemaExist(Class<?> clazz) throws TopiaException { - checkClosed(_( - "topia.persistence.error.unsupported.operation.on.closed.context", + checkClosed(_("topia.persistence.error.unsupported.operation.on.closed.context", "replicateEntity")); boolean result = TopiaUtil.isSchemaExist(this, clazz.getName()); return result; Modified: trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/TopiaQuery.java =================================================================== --- trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/TopiaQuery.java 2012-02-15 14:15:11 UTC (rev 2406) +++ trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/TopiaQuery.java 2012-02-20 13:27:33 UTC (rev 2407) @@ -41,6 +41,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; @@ -239,69 +240,92 @@ public static final String FROM_SEPARATOR_LEFT_JOIN = "LEFT JOIN"; - /** Params for HQL query * */ + /** Params for HQL query. */ protected List<Object> params; // /** Select part of the query * */ // protected StringBuilder select; /** - * To keep select part of the query filled by user. + * To keep SELECT part of the query filled by user. * * @since 2.6.7 */ protected List<String> userSelects; + /** + * To keep GROUP BY part of the query filled by user. + * + * @since 2.6.7 + */ + protected List<String> groupBys; + + /** + * To keep ORDER BY part of the query filled by user. + * + * @since 2.6.7 + */ + protected List<String> orderBys; + + /** + * To keep WHERE part of the query filled by user. + * + * @since 2.6.7 + */ + protected List<String> wheres; + protected boolean distinct; //TODO tchemit-2012-02-01 Remove this (see Evol #1931) - /** From part of the query * */ + /** From part of the query. */ protected StringBuilder from; //TODO tchemit-2012-02-01 Remove this (see Evol #1931) - /** Where part of the query * */ - protected StringBuilder where; +// /** Where part of the query. */ +// protected StringBuilder where; - //TODO tchemit-2012-02-01 Remove this (see Evol #1931) - /** Order By part of the query * */ - protected StringBuilder orderBy; +// /** Order By part of the query. */ +// protected StringBuilder orderBy; - //TODO tchemit-2012-02-01 Remove this (see Evol #1931) - /** Group By part of the query * */ - protected StringBuilder groupBy; +// /** Group By part of the query. */ +// protected StringBuilder groupBy; protected Integer startIndex; protected Integer endIndex; - /** Used to determine if parentheses are needed for Where statement * */ - protected boolean parentheses; +// /** Used to determine if parentheses are needed for Where statement. */ +// protected boolean parentheses; protected List<String> propertiesToLoad; protected String mainAlias; - /** Enum to simmplify using operation in query */ + /** Enum to simmplify using operation in query. */ public enum Op { - /** EQUALS */ + /** EQUALS. */ EQ("="), - /** GREATER THAN */ + /** GREATER THAN. */ GT(">"), - /** GREATER OR EQUALS */ + /** GREATER OR EQUALS. */ GE(">="), - /** LIKE for String manipulation */ + /** LIKE for String manipulation. */ LIKE("LIKE"), - /** LESS THAN */ + /** LESS THAN. */ LT("<"), - /** LESS OR EQUALS */ + /** LESS OR EQUALS. */ LE("<="), - /** IS NOT NULL */ + /** IS NOT NULL. */ NOT_NULL("IS NOT NULL"), - /** IS NULL */ + /** IS NULL. */ NULL("IS NULL"), - /** NOT EQUAL */ - NEQ("!="); + /** NOT EQUAL. */ + NEQ("!="), + /** IN. */ + IN("IN"), + /** NOT IN. */ + NOT_IN("NOT IN"); protected String value; @@ -321,7 +345,7 @@ } public TopiaQuery() { - parentheses = true; +// parentheses = true; } /** @@ -499,7 +523,8 @@ } if (CollectionUtils.isNotEmpty(userSelects)) { - result.append(selectStatement).append(StringUtils.join(userSelects, ',')); + result.append(selectStatement); + result.append(StringUtils.join(userSelects, ',')); } else if (StringUtils.contains(from.toString(), ',') && StringUtils.isNotEmpty(mainAlias)) { // Set default select if there is more than one table in from @@ -518,15 +543,40 @@ // result.append(selectStatement).append(mainAlias); // } result.append(from); - if (where != null) { - result.append(where); + + if (CollectionUtils.isNotEmpty(wheres)) { + result.append(" WHERE "); + boolean first = true; + boolean moreThanOne = wheres.size() > 1; + for (String where : wheres) { + if (!first) { + result.append(" AND "); + } + if (moreThanOne) { + result.append('('); + } + result.append(where); + if (moreThanOne) { + result.append(')'); + } + first = false; + } } - if (groupBy != null) { - result.append(groupBy); + if (CollectionUtils.isNotEmpty(groupBys)) { + result.append(" GROUP BY ").append(StringUtils.join(groupBys, ',')); } - if (orderBy != null) { - result.append(orderBy); + if (CollectionUtils.isNotEmpty(orderBys)) { + result.append(" ORDER BY ").append(StringUtils.join(orderBys, ',')); } +// if (where != null) { +// result.append(where); +// } +// if (groupBy != null) { +// result.append(groupBy); +// } +// if (orderBy != null) { +// result.append(orderBy); +// } return StringUtils.trim(result.toString()); } @@ -689,23 +739,28 @@ * @since 2.3.4 */ public TopiaQuery addWhere(String where) { - if (StringUtils.isEmpty(where)) { - return this; + if (StringUtils.isNotEmpty(where)) { + if (wheres == null) { + wheres = new ArrayList<String>(); + } + wheres.add(where); +// // Reinitialize parentheses boolean for next add call +// parentheses = true; } - if (this.where == null) { - this.where = new StringBuilder(" WHERE "); - } else { - this.where.append(" AND "); - } - if (parentheses) { - this.where.append('('); - } - this.where.append(where); - if (parentheses) { - this.where.append(')'); - } - // Reinitialize parentheses boolean for next add call - parentheses = true; +// if (this.where == null) { +// this.where = new StringBuilder(" WHERE "); +// } else { +// this.where.append(" AND "); +// } +// if (parentheses) { +// this.where.append('('); +// } +// this.where.append(where); +// if (parentheses) { +// this.where.append(')'); +// } +// // Reinitialize parentheses boolean for next add call +// parentheses = true; return this; } @@ -750,7 +805,7 @@ result.append(operator).append(" :").append(valueName); addParam(valueName, paramValue); } - parentheses = false; +// parentheses = false; return addWhere(result.toString()); } @@ -780,6 +835,7 @@ * @since 2.3.1 * @deprecated since 2.3.4, use {@link #addEquals(String, Object...)} instead */ + @Deprecated public TopiaQuery add(String paramName, Object... paramValue) { return addEquals(paramName, paramValue); } @@ -843,8 +899,8 @@ buffer.append(" OR "). append(paramName).append(' ').append(Op.NULL.toString()); } else { - // no parentheses needed in this case (no OR statement) - parentheses = false; +// // no parentheses needed in this case (no OR statement) +// parentheses = false; } return addWhere(buffer.toString()); } @@ -885,9 +941,9 @@ public TopiaQuery addNotNull(String paramName) { StringBuilder result = new StringBuilder(paramName).append(' ').append(Op.NOT_NULL); - parentheses = false; +// parentheses = false; addWhere(result.toString()); - parentheses = true; +// parentheses = true; return this; } @@ -951,9 +1007,9 @@ append(" AND "). append(':').append(valueName2); - parentheses = false; +// parentheses = false; addWhere(builder.toString()); - parentheses = true; +// parentheses = true; return this; } @@ -972,9 +1028,9 @@ public TopiaQuery addInElements(String elementProperty, String containerProperty) { StringBuilder builder = new StringBuilder(elementProperty). append(" IN elements(").append(containerProperty).append(')'); - parentheses = false; +// parentheses = false; addWhere(builder.toString()); - parentheses = true; +// parentheses = true; return this; } @@ -1122,12 +1178,16 @@ * @return the TopiaQuery */ public TopiaQuery addOrder(String... order) { - if (orderBy == null) { - orderBy = new StringBuilder(" ORDER BY "); - } else { - orderBy.append(", "); + if (orderBys==null) { + orderBys = new ArrayList<String>(); } - orderBy.append(convertStringArray(order)); + Collections.addAll(orderBys, order); +// if (orderBy == null) { +// orderBy = new StringBuilder(" ORDER BY "); +// } else { +// orderBy.append(", "); +// } +// orderBy.append(convertStringArray(order)); return this; } @@ -1143,33 +1203,37 @@ * @return the TopiaQuery */ public TopiaQuery addGroup(String... group) { - if (groupBy == null) { - groupBy = new StringBuilder(" GROUP BY "); - } else { - groupBy.append(", "); + if (groupBys==null) { + groupBys = new ArrayList<String>(); } - groupBy.append(convertStringArray(group)); + Collections.addAll(groupBys, group); +// if (groupBy == null) { +// groupBy = new StringBuilder(" GROUP BY "); +// } else { +// groupBy.append(", "); +// } +// groupBy.append(convertStringArray(group)); return this; } - /** - * Helper method for array type. Each value will be separated by a comma. - * TODO-fdesbois-2010-05-25 : replace this algo by StringUtil.join() - * - * @param array of String - * @return a String with values of the array separated by a comma - */ - protected String convertStringArray(String... array) { - StringBuilder result = new StringBuilder(); - for (String value : array) { - result.append(", ").append(value); - } - String str = ""; - if (result.length() > 0) { - str = result.substring(2); - } - return str; - } +// /** +// * Helper method for array type. Each value will be separated by a comma. +// * TODO-fdesbois-2010-05-25 : replace this algo by StringUtil.join() +// * +// * @param array of String +// * @return a String with values of the array separated by a comma +// */ +// protected String convertStringArray(String... array) { +// StringBuilder result = new StringBuilder(); +// for (String value : array) { +// result.append(", ").append(value); +// } +// String str = ""; +// if (result.length() > 0) { +// str = result.substring(2); +// } +// return str; +// } /** * Limit the result of the query with startIndex and endIndex. @@ -1312,11 +1376,14 @@ if (log.isDebugEnabled()) { log.debug(this); } + List result; if (startIndex != null && endIndex != null) { - return transaction.find(query, startIndex, endIndex, + result = transaction.find(query, startIndex, endIndex, getParams().toArray()); + } else { + result = transaction.find(query, getParams().toArray()); } - return transaction.find(query, getParams().toArray()); + return result; } /** @@ -1514,8 +1581,10 @@ * @throws TopiaException for error on query execution */ public int executeCount(TopiaContext transaction) throws TopiaException { - StringBuilder oldOrder = orderBy; - orderBy = null; + List<String> oldOrderBys = orderBys; + orderBys=null; +// StringBuilder oldOrder = orderBy; +// orderBy = null; StringBuilder count = new StringBuilder("COUNT("); // Ano #560 : manage distinct case when the alias is set (otherwise // no need the distinct keyword because the entity type in query is @@ -1559,7 +1628,8 @@ } count.append(')'); int result = executeToInteger(transaction, count.toString()); - orderBy = oldOrder; + orderBys = oldOrderBys; +// orderBy = oldOrder; return result; } @@ -1705,9 +1775,9 @@ // Clean StringBuilder statements // select = null; from = null; - where = null; - orderBy = null; - groupBy = null; +// where = null; +// orderBy = null; +// groupBy = null; super.finalize(); } Modified: trunk/topia-persistence/src/test/java/org/nuiton/topia/framework/TopiaQueryTest.java =================================================================== --- trunk/topia-persistence/src/test/java/org/nuiton/topia/framework/TopiaQueryTest.java 2012-02-15 14:15:11 UTC (rev 2406) +++ trunk/topia-persistence/src/test/java/org/nuiton/topia/framework/TopiaQueryTest.java 2012-02-20 13:27:33 UTC (rev 2407) @@ -72,7 +72,7 @@ query.addEquals(QueriedEntity.PROPERTY_TEST_ADD, value, value2, null); Assert.assertEquals( "FROM org.nuiton.topiatest.QueriedEntity " + - "WHERE (testAdd IN (:testAdd1, :testAdd2) OR testAdd IS NULL)", + "WHERE testAdd IN (:testAdd1, :testAdd2) OR testAdd IS NULL", query.fullQuery()); }