Author: bleny Date: 2013-12-10 21:26:55 +0100 (Tue, 10 Dec 2013) New Revision: 2920 Url: http://nuiton.org/projects/topia/repository/revisions/2920 Log: refs #2894 fixes some TODO in HqlAndParametersBuilder ; move HqlAndParametersBuilderTest back to its place (its not legacy and its not an IT) Added: trunk/topia-persistence/src/test/java/org/nuiton/topia/persistence/ trunk/topia-persistence/src/test/java/org/nuiton/topia/persistence/HqlAndParametersBuilderTest.java Removed: trunk/topia-it/src/test/java/org/nuiton/topia/it/legacy/persistence/HqlAndParametersBuilderTest.java Modified: trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/HqlAndParametersBuilder.java Deleted: trunk/topia-it/src/test/java/org/nuiton/topia/it/legacy/persistence/HqlAndParametersBuilderTest.java =================================================================== --- trunk/topia-it/src/test/java/org/nuiton/topia/it/legacy/persistence/HqlAndParametersBuilderTest.java 2013-12-09 17:08:02 UTC (rev 2919) +++ trunk/topia-it/src/test/java/org/nuiton/topia/it/legacy/persistence/HqlAndParametersBuilderTest.java 2013-12-10 20:26:55 UTC (rev 2920) @@ -1,161 +0,0 @@ -package org.nuiton.topia.it.legacy.persistence; - -/* - * #%L - * ToPIA :: Persistence - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2004 - 2013 CodeLutin - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Lesser Public License for more details. - * - * You should have received a copy of the GNU General Lesser Public - * License along with this program. If not, see - * <http://www.gnu.org/licenses/lgpl-3.0.html>. - * #L% - */ - -import com.google.common.collect.Lists; -import org.junit.Assert; -import org.junit.Test; -import org.nuiton.topia.persistence.HqlAndParametersBuilder; -import org.nuiton.topia.persistence.TopiaEntity; - -import java.util.Collection; -import java.util.Collections; - -public class HqlAndParametersBuilderTest { - - protected class MyHqlAndParametersBuilder extends HqlAndParametersBuilder { - - public MyHqlAndParametersBuilder(Class entityClass) { - super(entityClass); - } - - @Override - public String putHqlParameterWithAvailableName(String propertyName, Object value) { - return super.putHqlParameterWithAvailableName(propertyName, value); - } - - } - - protected MyHqlAndParametersBuilder hqlAndParametersBuilder = - new MyHqlAndParametersBuilder(TopiaEntity.class); - - protected static final Collection<String> SOME_VALUES = - Lists.newArrayList("value1", "value2", "value3"); - - protected static final Collection<String> SOME_VALUES_WITH_NULL = - Lists.newArrayList("value1", "value2", null, "value3"); - - @Test - public void testFindAvailableHqlParameterName() { - - String availableHqlParameterName1 = hqlAndParametersBuilder.putHqlParameterWithAvailableName("survey.topiaId", "topiaId1"); - String availableHqlParameterName2 = hqlAndParametersBuilder.putHqlParameterWithAvailableName("survey.topiaId", "topiaId1"); - - Assert.assertNotEquals(availableHqlParameterName1, availableHqlParameterName2); - Assert.assertFalse(availableHqlParameterName1.contains(".")); - Assert.assertFalse(availableHqlParameterName2.contains(".")); - - } - - @Test - public void testEqualsNull() { - - hqlAndParametersBuilder.addEquals("myProp", null); - - String actualHql = hqlAndParametersBuilder.getHql(); - - Assert.assertFalse(actualHql.contains("myProp = null")); - Assert.assertTrue(actualHql.contains("myProp is null")); - - } - - @Test - public void testAddInWithNull() { - - hqlAndParametersBuilder.addIn("myProp", SOME_VALUES_WITH_NULL); - - String actualHql = hqlAndParametersBuilder.getHql(); - - Assert.assertTrue(actualHql.contains("myProp is null or topiaEntity_.myProp in (")); - Assert.assertEquals( - SOME_VALUES_WITH_NULL.size() - 1, // there should be as many argument as in collection minus 1 because null is removed - hqlAndParametersBuilder.getHqlParameters().size()); - - } - - @Test - public void testAddNotEqualsToValue() { - - hqlAndParametersBuilder.addNotEquals("myProp", "value"); - - String actualHql = hqlAndParametersBuilder.getHql(); - - Assert.assertTrue(actualHql.contains("myProp != ")); - Assert.assertFalse(actualHql.contains("myProp = ")); - - } - - @Test - public void testAddNotEqualsToNull() { - - hqlAndParametersBuilder.addNotEquals("myProp", null); - - String actualHql = hqlAndParametersBuilder.getHql(); - - Assert.assertTrue(actualHql.contains("myProp is not null")); - - } - - @Test - public void testAddNotInWithNull() { - - hqlAndParametersBuilder.addNotIn("myProp", SOME_VALUES_WITH_NULL); - - String actualHql = hqlAndParametersBuilder.getHql(); - - Assert.assertTrue(actualHql.contains("myProp is not null and ")); - - } - - @Test - public void testAddInWithEmptyValues() { - - hqlAndParametersBuilder.addIn("myProp", Collections.emptyList()); - - String actualHql = hqlAndParametersBuilder.getHql(); - - Assert.assertFalse(actualHql.contains("myProp in (:)")); - Assert.assertTrue(actualHql.contains("myProp in ()")); - - } - - /** - * Check that the final joining on where clauses (with "and") isn't - * broken by a where clause containing a "or". - */ - @Test - public void testPreventOrKillsAnd() { - - hqlAndParametersBuilder.addEquals("myProp1", "myValue1"); - hqlAndParametersBuilder.addIn("myProp2", SOME_VALUES_WITH_NULL); - - String actualHql = hqlAndParametersBuilder.getHql(); - - Assert.assertFalse(actualHql.contains("topiaEntity_.myProp1 = :myProp1 and topiaEntity_.myProp2 is null or topiaEntity_.myProp2 in (:myProp2, :myProp21, :myProp22)")); - Assert.assertTrue(actualHql.contains("(topiaEntity_.myProp1 = :myProp1) and (topiaEntity_.myProp2 is null or topiaEntity_.myProp2 in (:myProp2, :myProp21, :myProp22))")); - - } - -} Modified: trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/HqlAndParametersBuilder.java =================================================================== --- trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/HqlAndParametersBuilder.java 2013-12-09 17:08:02 UTC (rev 2919) +++ trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/HqlAndParametersBuilder.java 2013-12-10 20:26:55 UTC (rev 2920) @@ -30,6 +30,7 @@ import com.google.common.collect.Sets; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.text.WordUtils; import java.util.Arrays; import java.util.Map; @@ -202,12 +203,15 @@ } public void addWhereClause(String whereClause) { + Preconditions.checkArgument(StringUtils.isNotBlank(whereClause)); whereClauses.add(whereClause); } public void addWhereClause(String whereClause, Map<String, Object> hqlParameters) { - whereClauses.add(whereClause); - // TODO brendan 02/10/13 check parameters names are not already used + Preconditions.checkNotNull(hqlParameters); + boolean noCollision = Sets.intersection(parameters.keySet(), hqlParameters.keySet()).isEmpty(); + Preconditions.checkArgument(noCollision, "given arguments " + hqlParameters.keySet() + " contains a conflicting name with the already defined parameters of the query (" + parameters.keySet() + "). You should changes the names of given arguments."); + addWhereClause(whereClause); parameters.putAll(hqlParameters); } @@ -224,6 +228,23 @@ return hql; } + /** Converts a (nested) property name to an HQL argument name. + * + * For example getParameterName("yearlyDeclaration.survey.topiaId") → "yearlyDeclarationSurveyTopiaId" + * + * @param propertyName the name of a property, can be a path to a + * nested property + * @return a string that can syntactically be used as an HQL parameter + * name, not prefixed by ':' + */ + protected String getParameterName(String propertyName) { + Preconditions.checkArgument(StringUtils.isNotBlank(propertyName)); + String capitalize = WordUtils.capitalize(propertyName, '.'); + String withoutDots = capitalize.replaceAll("\\.", ""); + String parameterName = StringUtils.uncapitalize(withoutDots); + return parameterName; + } + /** * Add a parameter in the parameters map searching with the suitable parameter name * in order to prevent conflicts. @@ -231,8 +252,7 @@ * @return the found key where the parameter has been added, suitable to use in the where clause */ protected String putHqlParameterWithAvailableName(String propertyName, Object value) { - // TODO brendan 01/10/13 replace survey.topiaId by surveyTopiaId - String parameterNamePrefix = propertyName.replaceAll("\\.", ""); + String parameterNamePrefix = getParameterName(propertyName); int suffix = 0; String parameterName = parameterNamePrefix; while (parameters.containsKey(parameterName)) { Copied: trunk/topia-persistence/src/test/java/org/nuiton/topia/persistence/HqlAndParametersBuilderTest.java (from rev 2919, trunk/topia-it/src/test/java/org/nuiton/topia/it/legacy/persistence/HqlAndParametersBuilderTest.java) =================================================================== --- trunk/topia-persistence/src/test/java/org/nuiton/topia/persistence/HqlAndParametersBuilderTest.java (rev 0) +++ trunk/topia-persistence/src/test/java/org/nuiton/topia/persistence/HqlAndParametersBuilderTest.java 2013-12-10 20:26:55 UTC (rev 2920) @@ -0,0 +1,192 @@ +package org.nuiton.topia.persistence; +/* + * #%L + * ToPIA :: Persistence + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2004 - 2013 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Lists; +import org.junit.Assert; +import org.junit.Test; + +import java.util.Collection; +import java.util.Collections; + +public class HqlAndParametersBuilderTest { + + protected class MyHqlAndParametersBuilder extends HqlAndParametersBuilder { + + public MyHqlAndParametersBuilder(Class entityClass) { + super(entityClass); + } + + @Override + public String putHqlParameterWithAvailableName(String propertyName, Object value) { + return super.putHqlParameterWithAvailableName(propertyName, value); + } + + } + + protected MyHqlAndParametersBuilder hqlAndParametersBuilder = + new MyHqlAndParametersBuilder(TopiaEntity.class); + + protected static final Collection<String> SOME_VALUES = + Lists.newArrayList("value1", "value2", "value3"); + + protected static final Collection<String> SOME_VALUES_WITH_NULL = + Lists.newArrayList("value1", "value2", null, "value3"); + + @Test + public void testFindAvailableHqlParameterName() { + + String availableHqlParameterName1 = hqlAndParametersBuilder.putHqlParameterWithAvailableName("survey.topiaId", "topiaId1"); + String availableHqlParameterName2 = hqlAndParametersBuilder.putHqlParameterWithAvailableName("survey.topiaId", "topiaId1"); + + Assert.assertNotEquals(availableHqlParameterName1, availableHqlParameterName2); + Assert.assertFalse(availableHqlParameterName1.contains(".")); + Assert.assertFalse(availableHqlParameterName2.contains(".")); + + } + + @Test + public void testEqualsNull() { + + hqlAndParametersBuilder.addEquals("myProp", null); + + String actualHql = hqlAndParametersBuilder.getHql(); + + Assert.assertFalse(actualHql.contains("myProp = null")); + Assert.assertTrue(actualHql.contains("myProp is null")); + + } + + @Test + public void testAddInWithNull() { + + hqlAndParametersBuilder.addIn("myProp", SOME_VALUES_WITH_NULL); + + String actualHql = hqlAndParametersBuilder.getHql(); + + Assert.assertTrue(actualHql.contains("myProp is null or topiaEntity_.myProp in (")); + Assert.assertEquals( + SOME_VALUES_WITH_NULL.size() - 1, // there should be as many argument as in collection minus 1 because null is removed + hqlAndParametersBuilder.getHqlParameters().size()); + + } + + @Test + public void testAddNotEqualsToValue() { + + hqlAndParametersBuilder.addNotEquals("myProp", "value"); + + String actualHql = hqlAndParametersBuilder.getHql(); + + Assert.assertTrue(actualHql.contains("myProp != ")); + Assert.assertFalse(actualHql.contains("myProp = ")); + + } + + @Test + public void testAddNotEqualsToNull() { + + hqlAndParametersBuilder.addNotEquals("myProp", null); + + String actualHql = hqlAndParametersBuilder.getHql(); + + Assert.assertTrue(actualHql.contains("myProp is not null")); + + } + + @Test + public void testAddNotInWithNull() { + + hqlAndParametersBuilder.addNotIn("myProp", SOME_VALUES_WITH_NULL); + + String actualHql = hqlAndParametersBuilder.getHql(); + + Assert.assertTrue(actualHql.contains("myProp is not null and ")); + + } + + @Test + public void testAddInWithEmptyValues() { + + hqlAndParametersBuilder.addIn("myProp", Collections.emptyList()); + + String actualHql = hqlAndParametersBuilder.getHql(); + + Assert.assertFalse(actualHql.contains("myProp in (:)")); + Assert.assertTrue(actualHql.contains("myProp in ()")); + + } + + /** + * Check that the final joining on where clauses (with "and") isn't + * broken by a where clause containing a "or". + */ + @Test + public void testPreventOrKillsAnd() { + + hqlAndParametersBuilder.addEquals("myProp1", "myValue1"); + hqlAndParametersBuilder.addIn("myProp2", SOME_VALUES_WITH_NULL); + + String actualHql = hqlAndParametersBuilder.getHql(); + + Assert.assertFalse(actualHql.contains("topiaEntity_.myProp1 = :myProp1 and topiaEntity_.myProp2 is null or topiaEntity_.myProp2 in (:myProp2, :myProp21, :myProp22)")); + Assert.assertTrue(actualHql.contains("(topiaEntity_.myProp1 = :myProp1) and (topiaEntity_.myProp2 is null or topiaEntity_.myProp2 in (:myProp2, :myProp21, :myProp22))")); + + } + + @Test + public void testGetParameterName() { + + String actualParameterName = hqlAndParametersBuilder.getParameterName("yearlyDeclaration.survey.topiaId"); + + Assert.assertFalse("an hql argument name must not contains '.'", actualParameterName.contains(".")); + Assert.assertFalse("an hql argument name must not contains ' '", actualParameterName.contains(" ")); + Assert.assertFalse("an hql argument name must not contains ':'", actualParameterName.contains(":")); + + Assert.assertEquals("yearlyDeclarationSurveyTopiaId", actualParameterName); + + } + @Test + public void testPreventRemoveParameters() { + + ImmutableMap<String, String> hqlParameters = + ImmutableMap.of("myParameter1", "aRandomValue"); + + ImmutableMap<String, String> conflictingHqlParameters = + ImmutableMap.of("myParameter1", "anotherRandomValue"); + + hqlAndParametersBuilder.addWhereClause("myProperty = :myParameter1", hqlParameters); + + try { + hqlAndParametersBuilder.addWhereClause("myOtherProperty = :myParameter1", conflictingHqlParameters); + Assert.fail("an exception should have been raised"); + } catch (IllegalArgumentException e) { + Assert.assertTrue( + "the exception message must contains the conflicting argument name", + e.getMessage().contains("myParameter1")); + } + + } +}