From 14becf44aaa61b740d163bcb5d92a493bbd2e564 Mon Sep 17 00:00:00 2001 From: Orlando Becerra Date: Sun, 13 Apr 2014 17:25:30 +0100 Subject: [PATCH 1/3] adding the ability to evaluate groovy expressions --- .../abilities/RowManipulationAbility.groovy | 23 ++++++++++++++----- .../excel/export/XlsxExporterRowTest.groovy | 23 +++++++++++++++++++ 2 files changed, 40 insertions(+), 6 deletions(-) diff --git a/src/groovy/pl/touk/excel/export/abilities/RowManipulationAbility.groovy b/src/groovy/pl/touk/excel/export/abilities/RowManipulationAbility.groovy index c00ac94..ad4a471 100644 --- a/src/groovy/pl/touk/excel/export/abilities/RowManipulationAbility.groovy +++ b/src/groovy/pl/touk/excel/export/abilities/RowManipulationAbility.groovy @@ -31,19 +31,24 @@ class RowManipulationAbility { return this } - SheetManipulator add(List objects, List selectedProperties) { - add(objects, selectedProperties, 1) + SheetManipulator add(List objects, List selectedProperties, boolean evaluateAsExpressions = false) { + add(objects, selectedProperties, 1, evaluateAsExpressions) } - SheetManipulator add(List objects, List selectedProperties, int rowNumber) { + SheetManipulator add(List objects, List selectedProperties, int rowNumber, boolean evaluateAsExpressions = false) { objects.eachWithIndex() { Object object, int index -> - RowManipulationAbility.add(this, object, selectedProperties, rowNumber + index) + RowManipulationAbility.add(this, object, selectedProperties, rowNumber + index, evaluateAsExpressions) } return this } - SheetManipulator add(Object object, List selectedProperties, int rowNumber) { - List properties = RowManipulationAbility.getPropertiesFromObject(object, Formatters.convertSafelyToGetters(selectedProperties)) + SheetManipulator add(Object object, List selectedProperties, int rowNumber, boolean evaluateAsExpressions = false) { + List properties = null + if(evaluateAsExpressions){ + properties = RowManipulationAbility.evaluatePropertiesFromObject(object, selectedProperties) + } else { + properties = RowManipulationAbility.getPropertiesFromObject(object, Formatters.convertSafelyToGetters(selectedProperties)) + } fillRow(properties, rowNumber) } @@ -59,6 +64,12 @@ class RowManipulationAbility { selectedProperties.collect { it.getFormattedValue(object) } } + private static List evaluatePropertiesFromObject(Object object, List selectedProperties) { + selectedProperties.collect { expression -> + Eval.me('it', object, expression) + } + } + private static boolean verifyPropertyTypeCanBeHandled(Object property) { if(!(handledPropertyTypes.find {it.isAssignableFrom(property.getClass())} )) { return false diff --git a/test/unit/pl/touk/excel/export/XlsxExporterRowTest.groovy b/test/unit/pl/touk/excel/export/XlsxExporterRowTest.groovy index b2c75e4..fff5a95 100644 --- a/test/unit/pl/touk/excel/export/XlsxExporterRowTest.groovy +++ b/test/unit/pl/touk/excel/export/XlsxExporterRowTest.groovy @@ -73,6 +73,29 @@ class XlsxExporterRowTest extends XlsxExporterTest { testObject.verifyRowHasSelectedProperties(xlsxReporter.withDefaultSheet(), 3) } + @Test + void shouldFillRowEvaluatingPropertyList() { + //given + SampleObject testObject = new SampleObject() + def propertyExpressions = [ + '', + 'it.stringValue', + 'it.booleanValue?" it is true ":"it is false "', + 'it.shortValue + it.integerValue', + 'Math.sqrt(it.doubleValue)' + ] + + //when + xlsxReporter.add(testObject, propertyExpressions, 0, true) + + //then + assert xlsxReporter.getCellAt(0, 0).getStringCellValue() == '' + assert xlsxReporter.getCellAt(0, 1).getStringCellValue() == testObject.stringValue + assert xlsxReporter.getCellAt(0, 2).getStringCellValue() == testObject.booleanValue?" it is true ":"it is false " + assert xlsxReporter.getCellAt(0, 3).getNumericCellValue() == testObject.integerValue + testObject.shortValue + assert xlsxReporter.getCellAt(0, 4).getNumericCellValue() == Math.sqrt(testObject.doubleValue) + } + @Test void shouldFillRows() { //given From 1fa38cb221cfb2814eef4c82507ee6742de27224 Mon Sep 17 00:00:00 2001 From: Orlando Becerra Date: Sun, 13 Apr 2014 17:36:56 +0100 Subject: [PATCH 2/3] verifying that expression must be String and can be handled --- .../export/abilities/RowManipulationAbility.groovy | 13 ++++++++++++- .../pl/touk/excel/export/XlsxExporterRowTest.groovy | 12 ++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/groovy/pl/touk/excel/export/abilities/RowManipulationAbility.groovy b/src/groovy/pl/touk/excel/export/abilities/RowManipulationAbility.groovy index ad4a471..df5cd94 100644 --- a/src/groovy/pl/touk/excel/export/abilities/RowManipulationAbility.groovy +++ b/src/groovy/pl/touk/excel/export/abilities/RowManipulationAbility.groovy @@ -66,7 +66,18 @@ class RowManipulationAbility { private static List evaluatePropertiesFromObject(Object object, List selectedProperties) { selectedProperties.collect { expression -> - Eval.me('it', object, expression) + def expresionValue = null + if(!(expression instanceof String)) { + throw new IllegalArgumentException('List of properties, which should be String, when "evaluateAsClosure" is true. Found: ' + + expression?.toString() + ' of class ' + expression?.getClass()) + } + try { + expresionValue = Eval.me('it', object, expression) + } catch(Exception e) { + throw new IllegalArgumentException('List of properties, which should be a valid groovy expression, when "evaluateAsClosure" is true. Found: ' + + expression?.toString(), e) + } + expresionValue } } diff --git a/test/unit/pl/touk/excel/export/XlsxExporterRowTest.groovy b/test/unit/pl/touk/excel/export/XlsxExporterRowTest.groovy index fff5a95..cc53b81 100644 --- a/test/unit/pl/touk/excel/export/XlsxExporterRowTest.groovy +++ b/test/unit/pl/touk/excel/export/XlsxExporterRowTest.groovy @@ -96,6 +96,18 @@ class XlsxExporterRowTest extends XlsxExporterTest { assert xlsxReporter.getCellAt(0, 4).getNumericCellValue() == Math.sqrt(testObject.doubleValue) } + @Test(expected=IllegalArgumentException.class) + void shouldThrowExceptionWhenBadExpresionIsPassedAsArgument() { + //given + SampleObject testObject = new SampleObject() + def propertyExpressions = [ + 'stringValue', + ] + + //when + xlsxReporter.add(testObject, propertyExpressions, 0, true) + } + @Test void shouldFillRows() { //given From 7f2e9618676e9f93d8277bc9a8358a727d57ab9f Mon Sep 17 00:00:00 2001 From: Orlando Becerra Date: Mon, 14 Apr 2014 22:50:13 +0100 Subject: [PATCH 3/3] adding the ability to evaluate groovy closures --- .../pl/touk/excel/export/Formatters.groovy | 9 ++++- .../abilities/RowManipulationAbility.groovy | 34 ++++-------------- .../getters/AsClosurePropertyGetter.groovy | 19 ++++++++++ .../excel/export/XlsxExporterRowTest.groovy | 36 +++++++------------ 4 files changed, 46 insertions(+), 52 deletions(-) create mode 100644 src/groovy/pl/touk/excel/export/getters/AsClosurePropertyGetter.groovy diff --git a/src/groovy/pl/touk/excel/export/Formatters.groovy b/src/groovy/pl/touk/excel/export/Formatters.groovy index deb3587..14e899c 100644 --- a/src/groovy/pl/touk/excel/export/Formatters.groovy +++ b/src/groovy/pl/touk/excel/export/Formatters.groovy @@ -3,6 +3,7 @@ package pl.touk.excel.export import pl.touk.excel.export.getters.Getter import pl.touk.excel.export.getters.PropertyGetter import pl.touk.excel.export.getters.AsIsPropertyGetter +import pl.touk.excel.export.getters.AsClosurePropertyGetter import pl.touk.excel.export.getters.LongToDatePropertyGetter class Formatters { @@ -14,14 +15,20 @@ class Formatters { return new AsIsPropertyGetter(propertyName) } + static PropertyGetter asClosure(Closure closure) { + return new AsClosurePropertyGetter(closure) + } + static List convertSafelyToGetters(List properties) { properties.collect { if (it instanceof Getter) { return it } else if(it instanceof String) { return asIs(it) + } else if(it instanceof Closure) { + return asClosure(it) } else { - throw IllegalArgumentException('List of properties, which should be either String, a Getter. Found: ' + + throw IllegalArgumentException('List of properties, which should be either String, a Getter or a Groovy Closure. Found: ' + it?.toString() + ' of class ' + it?.getClass()) } } diff --git a/src/groovy/pl/touk/excel/export/abilities/RowManipulationAbility.groovy b/src/groovy/pl/touk/excel/export/abilities/RowManipulationAbility.groovy index df5cd94..c00ac94 100644 --- a/src/groovy/pl/touk/excel/export/abilities/RowManipulationAbility.groovy +++ b/src/groovy/pl/touk/excel/export/abilities/RowManipulationAbility.groovy @@ -31,24 +31,19 @@ class RowManipulationAbility { return this } - SheetManipulator add(List objects, List selectedProperties, boolean evaluateAsExpressions = false) { - add(objects, selectedProperties, 1, evaluateAsExpressions) + SheetManipulator add(List objects, List selectedProperties) { + add(objects, selectedProperties, 1) } - SheetManipulator add(List objects, List selectedProperties, int rowNumber, boolean evaluateAsExpressions = false) { + SheetManipulator add(List objects, List selectedProperties, int rowNumber) { objects.eachWithIndex() { Object object, int index -> - RowManipulationAbility.add(this, object, selectedProperties, rowNumber + index, evaluateAsExpressions) + RowManipulationAbility.add(this, object, selectedProperties, rowNumber + index) } return this } - SheetManipulator add(Object object, List selectedProperties, int rowNumber, boolean evaluateAsExpressions = false) { - List properties = null - if(evaluateAsExpressions){ - properties = RowManipulationAbility.evaluatePropertiesFromObject(object, selectedProperties) - } else { - properties = RowManipulationAbility.getPropertiesFromObject(object, Formatters.convertSafelyToGetters(selectedProperties)) - } + SheetManipulator add(Object object, List selectedProperties, int rowNumber) { + List properties = RowManipulationAbility.getPropertiesFromObject(object, Formatters.convertSafelyToGetters(selectedProperties)) fillRow(properties, rowNumber) } @@ -64,23 +59,6 @@ class RowManipulationAbility { selectedProperties.collect { it.getFormattedValue(object) } } - private static List evaluatePropertiesFromObject(Object object, List selectedProperties) { - selectedProperties.collect { expression -> - def expresionValue = null - if(!(expression instanceof String)) { - throw new IllegalArgumentException('List of properties, which should be String, when "evaluateAsClosure" is true. Found: ' + - expression?.toString() + ' of class ' + expression?.getClass()) - } - try { - expresionValue = Eval.me('it', object, expression) - } catch(Exception e) { - throw new IllegalArgumentException('List of properties, which should be a valid groovy expression, when "evaluateAsClosure" is true. Found: ' + - expression?.toString(), e) - } - expresionValue - } - } - private static boolean verifyPropertyTypeCanBeHandled(Object property) { if(!(handledPropertyTypes.find {it.isAssignableFrom(property.getClass())} )) { return false diff --git a/src/groovy/pl/touk/excel/export/getters/AsClosurePropertyGetter.groovy b/src/groovy/pl/touk/excel/export/getters/AsClosurePropertyGetter.groovy new file mode 100644 index 0000000..f9eb866 --- /dev/null +++ b/src/groovy/pl/touk/excel/export/getters/AsClosurePropertyGetter.groovy @@ -0,0 +1,19 @@ +package pl.touk.excel.export.getters + +class AsClosurePropertyGetter extends PropertyGetter { + + def closure + + AsClosurePropertyGetter(Closure closure) { + super(null) + this.closure = closure + } + + def getFormattedValue(Object object) { + closure.call(object) + } + + def format(Object value) { + null + } +} diff --git a/test/unit/pl/touk/excel/export/XlsxExporterRowTest.groovy b/test/unit/pl/touk/excel/export/XlsxExporterRowTest.groovy index cc53b81..220953c 100644 --- a/test/unit/pl/touk/excel/export/XlsxExporterRowTest.groovy +++ b/test/unit/pl/touk/excel/export/XlsxExporterRowTest.groovy @@ -78,36 +78,26 @@ class XlsxExporterRowTest extends XlsxExporterTest { //given SampleObject testObject = new SampleObject() def propertyExpressions = [ - '', - 'it.stringValue', - 'it.booleanValue?" it is true ":"it is false "', - 'it.shortValue + it.integerValue', - 'Math.sqrt(it.doubleValue)' + 'stringValue', + { it.stringValue }, + { it.child.stringValue.toUpperCase() }, + { it.booleanValue?" it is true ":"it is false " }, + { it.shortValue + it.integerValue }, + { Math.sqrt(it.doubleValue) } ] //when - xlsxReporter.add(testObject, propertyExpressions, 0, true) + xlsxReporter.add(testObject, propertyExpressions, 0) //then - assert xlsxReporter.getCellAt(0, 0).getStringCellValue() == '' + assert xlsxReporter.getCellAt(0, 0).getStringCellValue() == testObject.stringValue assert xlsxReporter.getCellAt(0, 1).getStringCellValue() == testObject.stringValue - assert xlsxReporter.getCellAt(0, 2).getStringCellValue() == testObject.booleanValue?" it is true ":"it is false " - assert xlsxReporter.getCellAt(0, 3).getNumericCellValue() == testObject.integerValue + testObject.shortValue - assert xlsxReporter.getCellAt(0, 4).getNumericCellValue() == Math.sqrt(testObject.doubleValue) - } - - @Test(expected=IllegalArgumentException.class) - void shouldThrowExceptionWhenBadExpresionIsPassedAsArgument() { - //given - SampleObject testObject = new SampleObject() - def propertyExpressions = [ - 'stringValue', - ] - - //when - xlsxReporter.add(testObject, propertyExpressions, 0, true) + assert xlsxReporter.getCellAt(0, 2).getStringCellValue() == testObject.child.stringValue.toUpperCase() + assert xlsxReporter.getCellAt(0, 3).getStringCellValue() == testObject.booleanValue?" it is true ":"it is false " + assert xlsxReporter.getCellAt(0, 4).getNumericCellValue() == testObject.integerValue + testObject.shortValue + assert xlsxReporter.getCellAt(0, 5).getNumericCellValue() == Math.sqrt(testObject.doubleValue) } - + @Test void shouldFillRows() { //given