├── .github ├── dependabot.yml └── workflows │ └── gradle.yml ├── .gitignore ├── GroovyNotes.zip ├── README.md ├── build.gradle ├── cats.json ├── flickr_key.txt ├── gradle.properties ├── gradle ├── libs.versions.toml └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle └── src ├── main └── groovy │ ├── Precision.java │ ├── Task.groovy │ ├── ast │ ├── delegate │ │ └── phone_delegate.groovy │ ├── immutable │ │ └── Point.groovy │ ├── singleton │ │ └── SingletonPoint.groovy │ ├── sortable │ │ ├── Golfer.groovy │ │ └── use_golfers.groovy │ └── tostring │ │ └── tostring_and_equals.groovy │ ├── astro │ └── astronauts_in_space.groovy │ ├── builders │ ├── antbuilder.groovy │ ├── department.html │ ├── htmlBuilder.groovy │ ├── markupBuilder.groovy │ └── swingBuilder.groovy │ ├── closurespackage │ └── closures.groovy │ ├── collections │ ├── Circle.java │ ├── Shape.java │ ├── SortingLists.java │ ├── WordCountGroovy.groovy │ ├── lists.groovy │ ├── maps.groovy │ ├── passage.txt │ └── ranges.groovy │ ├── conditionals │ ├── conditionals.groovy │ └── loops.groovy │ ├── datetime │ └── groundhogday.groovy │ ├── db │ ├── Product.java │ ├── ProductDAO.java │ ├── products.groovy │ └── products2xml.groovy │ ├── filter │ ├── FilterNumbers.groovy │ └── UseFilterNumbers.java │ ├── flickr │ ├── cat_pictures.groovy │ └── cats.json │ ├── geocoder │ ├── Geocoder.groovy │ ├── GeocoderJSON.groovy │ ├── Stadium.groovy │ └── populate_stadium_data.groovy │ ├── groovystrings │ └── strings.groovy │ ├── hello_world.groovy │ ├── intro │ ├── hello_world.groovy │ └── numbers.groovy │ ├── io │ ├── SumNumbers.java │ ├── data.txt │ ├── files.groovy │ ├── sum_numbers.groovy │ └── sum_numbers_loop.groovy │ ├── json │ ├── Model.groovy │ ├── chuck_norris.groovy │ ├── cn_ratpack.groovy │ └── gson_demo.groovy │ ├── metaprogramming │ ├── CustomLevel.groovy │ ├── LocalDate_demo.groovy │ ├── complex_numbers.groovy │ ├── currency_category.groovy │ ├── expando_demo.groovy │ ├── print_currency.groovy │ ├── use_emc.groovy │ ├── use_slang_category.groovy │ └── without_custom_levels.groovy │ ├── misc │ └── Jumble.groovy │ ├── pogos │ ├── groovy │ │ └── Task.groovy │ └── java │ │ └── Task.java │ ├── precision_groovy.groovy │ ├── regex │ └── regular_expressions.groovy │ ├── sort_strings.groovy │ ├── strategy │ ├── groovy │ │ └── Multiplier.groovy │ └── java │ │ ├── AddStrategy.java │ │ ├── Multiplier.java │ │ ├── Multiply.java │ │ └── TimesStrategy.java │ ├── strings.groovy │ └── xml │ ├── books.xml │ ├── books.xsd │ ├── booksNS.xml │ ├── booksWithDTD.xml │ ├── library.dtd │ ├── namespaces.groovy │ ├── parsing.groovy │ ├── sample_weather.xml │ ├── validate.groovy │ └── weather.groovy └── test └── groovy ├── TaskTests.groovy ├── ast ├── immutable │ └── ImmutablePointSpec.groovy └── singleton │ └── SingletonPointSpec.groovy ├── collections ├── RangeSpec.groovy └── WordCountGroovyTest.groovy ├── db └── ProductDAOTest.java ├── filter └── FilterNumbersTest.groovy ├── geocoder ├── GeocoderIntegrationSpec.groovy ├── GeocoderUnitSpec.groovy └── StadiumLocationsSpec.groovy ├── json └── ChuckNorrisScriptTests.groovy ├── metaprogramming ├── ComplexSpec.groovy └── LoggingTests.groovy ├── misc └── JumbleSpec.groovy ├── pogos └── TaskTest.groovy ├── scripts └── ScriptTests.groovy ├── simple └── SimpleSpec.groovy └── strategy ├── groovy └── MultiplierTest.groovy └── java └── MultiplierTest.java /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: gradle 4 | directory: "/" 5 | schedule: 6 | interval: daily 7 | time: "10:00" 8 | open-pull-requests-limit: 10 9 | ignore: 10 | - dependency-name: org.junit.vintage:junit-vintage-engine 11 | versions: 12 | - 5.7.1 13 | - dependency-name: org.junit.jupiter:junit-jupiter 14 | versions: 15 | - 5.7.1 16 | - dependency-name: org.codehaus.groovy:groovy-all 17 | versions: 18 | - 3.0.7 19 | -------------------------------------------------------------------------------- /.github/workflows/gradle.yml: -------------------------------------------------------------------------------- 1 | name: Java CI 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | build: 7 | 8 | runs-on: ubuntu-latest 9 | 10 | steps: 11 | - uses: actions/checkout@v1 12 | - name: Set up JDK 17 13 | uses: actions/setup-java@v1 14 | with: 15 | java-version: 17 16 | - name: Build with Gradle 17 | run: ./gradlew build 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | bin 3 | classes 4 | .idea 5 | .gradle 6 | .project 7 | .classpath 8 | .settings 9 | .vscode 10 | out 11 | *.iml 12 | *.ipr 13 | *.iws 14 | src/main/groovy/flickr/cats.json 15 | src/main/groovy/flickr/flickr_key.txt 16 | cats.json 17 | .DS_Store -------------------------------------------------------------------------------- /GroovyNotes.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kousen/IntroGroovy/aa15f50cd916a8fd70247b001ba99743639b219c/GroovyNotes.zip -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Source code for the IntroGroovy workshop, based on the book 2 | [Making Java Groovy](http://manning.com/kousen) by Ken Kousen 3 | 4 | To build the project: 5 | If you have [gradle](http://gradle.org) installed, run 6 | > gradle build 7 | 8 | If not, use the supplied gradlew script: 9 | > ./gradlew build 10 | 11 | If you plan to use Eclipse (or any Eclipse-based tool, like 12 | SpringSource Tool Suite), then run: 13 | > ./gradlew cleanEclipse eclipse 14 | 15 | If you plan to use IntelliJ IDEA, run: 16 | > ./gradlew cleanIdea idea 17 | 18 | The test output is in 19 | build/reports/tests/index.html 20 | 21 | Please send any questions or comments to: 22 | 23 | Ken Kousen ([email](mailto:ken.kousen@kousenit.com)) 24 | [Kousen IT, Inc.](http://www.kousenit.com) 25 | [@kenkousen](http://twitter.com/kenkousen) 26 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'groovy' 3 | id 'eclipse' 4 | id 'application' 5 | alias(libs.plugins.versions) 6 | alias(libs.plugins.version.catalog.update) 7 | } 8 | 9 | mainClassName = 'astro.astronauts_in_space' 10 | 11 | repositories { 12 | mavenCentral() 13 | } 14 | 15 | //project.ext.db = file("$buildDir/baseball.mv.db") 16 | // 17 | //task generateTestDb(dependsOn:classes, type:JavaExec) { 18 | // onlyIf { !db.exists() } 19 | // main = 'geocoder.populate_stadium_data' 20 | // classpath sourceSets.main.runtimeClasspath 21 | //} 22 | // 23 | //compileTestGroovy.dependsOn generateTestDb 24 | 25 | tasks.named('test') { 26 | useJUnitPlatform() 27 | } 28 | 29 | dependencies { 30 | implementation(platform(libs.groovy.bom)) 31 | implementation libs.groovy.ant 32 | implementation libs.groovy.console 33 | implementation libs.groovy.datetime 34 | implementation libs.groovy.json 35 | implementation libs.groovy.sql 36 | implementation libs.groovy.swing 37 | implementation libs.groovy.test 38 | implementation libs.groovy.xml 39 | 40 | implementation libs.ant 41 | implementation libs.commons.math 42 | implementation libs.gson 43 | 44 | testImplementation(libs.spock.core) { 45 | exclude group: 'org.codehaus.groovy' 46 | } 47 | testImplementation libs.bundles.junit 48 | 49 | runtimeOnly libs.h2 50 | } 51 | -------------------------------------------------------------------------------- /cats.json: -------------------------------------------------------------------------------- 1 | {"photos":{"page":1,"pages":2098,"perpage":6,"total":"12586","photo":[{"id":"21808524389","owner":"136485307@N06","secret":"de2cd3253d","server":"582","farm":1,"title":"AS16-120-19267","ispublic":1,"isfriend":0,"isfamily":0},{"id":"21995428605","owner":"136485307@N06","secret":"47f4986956","server":"5671","farm":6,"title":"AS16-120-19268","ispublic":1,"isfriend":0,"isfamily":0},{"id":"21808523479","owner":"136485307@N06","secret":"8620bc6a5c","server":"5821","farm":6,"title":"AS16-120-19269","ispublic":1,"isfriend":0,"isfamily":0},{"id":"21995427355","owner":"136485307@N06","secret":"7e92b0477d","server":"573","farm":1,"title":"AS16-120-19271","ispublic":1,"isfriend":0,"isfamily":0},{"id":"21372658574","owner":"136485307@N06","secret":"5a2677928f","server":"570","farm":1,"title":"AS16-120-19270","ispublic":1,"isfriend":0,"isfamily":0},{"id":"21969243416","owner":"136485307@N06","secret":"a4511502cd","server":"641","farm":1,"title":"AS16-120-19272","ispublic":1,"isfriend":0,"isfamily":0}]},"stat":"ok"} -------------------------------------------------------------------------------- /flickr_key.txt: -------------------------------------------------------------------------------- 1 | 70df4e6184f7e0e398a7e7acb59c8ce1 -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | systemProp.net.bytebuddy.experimental=true -------------------------------------------------------------------------------- /gradle/libs.versions.toml: -------------------------------------------------------------------------------- 1 | [versions] 2 | ant = "1.10.15" 3 | commons-math = "3.6.1" 4 | groovy-bom = "4.0.27" 5 | gson = "2.13.1" 6 | h2 = "2.3.232" 7 | junit = "5.13.0" 8 | spock = "2.4-M5-groovy-4.0" 9 | 10 | [libraries] 11 | ant = { module = "org.apache.ant:ant", version.ref = "ant" } 12 | commons-math = { module = "org.apache.commons:commons-math3", version.ref = "commons-math" } 13 | groovy-ant = { module = "org.apache.groovy:groovy-ant" } 14 | groovy-bom = { module = "org.apache.groovy:groovy-bom", version.ref = "groovy-bom" } 15 | groovy-console = { module = "org.apache.groovy:groovy-console" } 16 | groovy-datetime = { module = "org.apache.groovy:groovy-datetime" } 17 | groovy-json = { module = "org.apache.groovy:groovy-json" } 18 | groovy-sql = { module = "org.apache.groovy:groovy-sql" } 19 | groovy-swing = { module = "org.apache.groovy:groovy-swing" } 20 | groovy-test = { module = "org.apache.groovy:groovy-test" } 21 | groovy-xml = { module = "org.apache.groovy:groovy-xml" } 22 | gson = { module = "com.google.code.gson:gson", version.ref = "gson" } 23 | h2 = { module = "com.h2database:h2", version.ref = "h2" } 24 | junit-jupiter = { module = "org.junit.jupiter:junit-jupiter", version.ref = "junit" } 25 | junit-vintage = { module = "org.junit.vintage:junit-vintage-engine", version.ref = "junit" } 26 | spock-core = { module = "org.spockframework:spock-core", version.ref = "spock" } 27 | 28 | [bundles] 29 | junit = [ 30 | "junit-jupiter", 31 | "junit-vintage", 32 | ] 33 | 34 | [plugins] 35 | version-catalog-update = "nl.littlerobots.version-catalog-update:1.0.0" 36 | versions = "com.github.ben-manes.versions:0.52.0" 37 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kousen/IntroGroovy/aa15f50cd916a8fd70247b001ba99743639b219c/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-all.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # 4 | # Copyright 2015 the original author or authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | ## 21 | ## Gradle start up script for UN*X 22 | ## 23 | ############################################################################## 24 | 25 | # Attempt to set APP_HOME 26 | # Resolve links: $0 may be a link 27 | PRG="$0" 28 | # Need this for relative symlinks. 29 | while [ -h "$PRG" ] ; do 30 | ls=`ls -ld "$PRG"` 31 | link=`expr "$ls" : '.*-> \(.*\)$'` 32 | if expr "$link" : '/.*' > /dev/null; then 33 | PRG="$link" 34 | else 35 | PRG=`dirname "$PRG"`"/$link" 36 | fi 37 | done 38 | SAVED="`pwd`" 39 | cd "`dirname \"$PRG\"`/" >/dev/null 40 | APP_HOME="`pwd -P`" 41 | cd "$SAVED" >/dev/null 42 | 43 | APP_NAME="Gradle" 44 | APP_BASE_NAME=`basename "$0"` 45 | 46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 48 | 49 | # Use the maximum available, or set MAX_FD != -1 to use that value. 50 | MAX_FD="maximum" 51 | 52 | warn () { 53 | echo "$*" 54 | } 55 | 56 | die () { 57 | echo 58 | echo "$*" 59 | echo 60 | exit 1 61 | } 62 | 63 | # OS specific support (must be 'true' or 'false'). 64 | cygwin=false 65 | msys=false 66 | darwin=false 67 | nonstop=false 68 | case "`uname`" in 69 | CYGWIN* ) 70 | cygwin=true 71 | ;; 72 | Darwin* ) 73 | darwin=true 74 | ;; 75 | MINGW* ) 76 | msys=true 77 | ;; 78 | NONSTOP* ) 79 | nonstop=true 80 | ;; 81 | esac 82 | 83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 84 | 85 | 86 | # Determine the Java command to use to start the JVM. 87 | if [ -n "$JAVA_HOME" ] ; then 88 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 89 | # IBM's JDK on AIX uses strange locations for the executables 90 | JAVACMD="$JAVA_HOME/jre/sh/java" 91 | else 92 | JAVACMD="$JAVA_HOME/bin/java" 93 | fi 94 | if [ ! -x "$JAVACMD" ] ; then 95 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 96 | 97 | Please set the JAVA_HOME variable in your environment to match the 98 | location of your Java installation." 99 | fi 100 | else 101 | JAVACMD="java" 102 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 103 | 104 | Please set the JAVA_HOME variable in your environment to match the 105 | location of your Java installation." 106 | fi 107 | 108 | # Increase the maximum file descriptors if we can. 109 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 110 | MAX_FD_LIMIT=`ulimit -H -n` 111 | if [ $? -eq 0 ] ; then 112 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 113 | MAX_FD="$MAX_FD_LIMIT" 114 | fi 115 | ulimit -n $MAX_FD 116 | if [ $? -ne 0 ] ; then 117 | warn "Could not set maximum file descriptor limit: $MAX_FD" 118 | fi 119 | else 120 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 121 | fi 122 | fi 123 | 124 | # For Darwin, add options to specify how the application appears in the dock 125 | if $darwin; then 126 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 127 | fi 128 | 129 | # For Cygwin or MSYS, switch paths to Windows format before running java 130 | if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then 131 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 132 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 133 | 134 | JAVACMD=`cygpath --unix "$JAVACMD"` 135 | 136 | # We build the pattern for arguments to be converted via cygpath 137 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 138 | SEP="" 139 | for dir in $ROOTDIRSRAW ; do 140 | ROOTDIRS="$ROOTDIRS$SEP$dir" 141 | SEP="|" 142 | done 143 | OURCYGPATTERN="(^($ROOTDIRS))" 144 | # Add a user-defined pattern to the cygpath arguments 145 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 146 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 147 | fi 148 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 149 | i=0 150 | for arg in "$@" ; do 151 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 152 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 153 | 154 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 155 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 156 | else 157 | eval `echo args$i`="\"$arg\"" 158 | fi 159 | i=`expr $i + 1` 160 | done 161 | case $i in 162 | 0) set -- ;; 163 | 1) set -- "$args0" ;; 164 | 2) set -- "$args0" "$args1" ;; 165 | 3) set -- "$args0" "$args1" "$args2" ;; 166 | 4) set -- "$args0" "$args1" "$args2" "$args3" ;; 167 | 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 168 | 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 169 | 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 170 | 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 171 | 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 172 | esac 173 | fi 174 | 175 | # Escape application args 176 | save () { 177 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 178 | echo " " 179 | } 180 | APP_ARGS=`save "$@"` 181 | 182 | # Collect all arguments for the java command, following the shell quoting and substitution rules 183 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 184 | 185 | exec "$JAVACMD" "$@" 186 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto init 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto init 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :init 68 | @rem Get command-line arguments, handling Windows variants 69 | 70 | if not "%OS%" == "Windows_NT" goto win9xME_args 71 | 72 | :win9xME_args 73 | @rem Slurp the command line arguments. 74 | set CMD_LINE_ARGS= 75 | set _SKIP=2 76 | 77 | :win9xME_args_slurp 78 | if "x%~1" == "x" goto execute 79 | 80 | set CMD_LINE_ARGS=%* 81 | 82 | :execute 83 | @rem Setup the command line 84 | 85 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 86 | 87 | 88 | @rem Execute Gradle 89 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 90 | 91 | :end 92 | @rem End local scope for the variables with windows NT shell 93 | if "%ERRORLEVEL%"=="0" goto mainEnd 94 | 95 | :fail 96 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 97 | rem the _cmd.exe /c_ return code! 98 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 99 | exit /b 1 100 | 101 | :mainEnd 102 | if "%OS%"=="Windows_NT" endlocal 103 | 104 | :omega 105 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'IntroGroovy' 2 | -------------------------------------------------------------------------------- /src/main/groovy/Precision.java: -------------------------------------------------------------------------------- 1 | /* =================================================== 2 | * Copyright 2012 Kousen IT, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * ========================================================== */ 16 | 17 | public class Precision { 18 | public static void main(String[] args) { 19 | double total = 0.0; 20 | for (int i = 0; i < 10; i++) { 21 | total += 0.1; 22 | } 23 | System.out.println("total = " + total); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/groovy/Task.groovy: -------------------------------------------------------------------------------- 1 | import groovy.transform.Canonical 2 | 3 | import java.time.LocalDate 4 | 5 | @Canonical 6 | class Task { 7 | String name 8 | int priority 9 | LocalDate startDate 10 | LocalDate endDate 11 | boolean completed 12 | 13 | String toString() { 14 | "Task [name=$name, priority=$priority, startDate=$startDate, " + 15 | "endDate=$endDate, completed=$completed]" 16 | } 17 | } -------------------------------------------------------------------------------- /src/main/groovy/ast/delegate/phone_delegate.groovy: -------------------------------------------------------------------------------- 1 | package ast.delegate 2 | 3 | class Phone { 4 | String vendor = 'Samsung' 5 | String dial(String number) { "dialing $number" } 6 | } 7 | 8 | class Camera { 9 | String vendor = 'Nikon' 10 | String takePicture() { "taking picture" } 11 | } 12 | 13 | class SmartPhone { 14 | @Delegate Phone phone = new Phone() 15 | @Delegate Camera camera = new Camera() 16 | 17 | String getVendor() { 18 | "Phone: ${phone.vendor}, Camera: ${camera.vendor}" 19 | } 20 | } 21 | 22 | SmartPhone sp = new SmartPhone() 23 | assert sp.dial('555-1234') == 'dialing 555-1234' 24 | assert sp.takePicture() == 'taking picture' 25 | println sp.vendor -------------------------------------------------------------------------------- /src/main/groovy/ast/immutable/Point.groovy: -------------------------------------------------------------------------------- 1 | package ast.immutable 2 | 3 | import groovy.transform.Immutable 4 | 5 | @Immutable 6 | class Point { 7 | double x 8 | double y 9 | } 10 | -------------------------------------------------------------------------------- /src/main/groovy/ast/singleton/SingletonPoint.groovy: -------------------------------------------------------------------------------- 1 | /* =================================================== 2 | * Copyright 2012 Kousen IT, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * ========================================================== */ 16 | package ast.singleton 17 | 18 | @Singleton 19 | class SingletonPoint { 20 | BigDecimal x 21 | BigDecimal y 22 | } 23 | -------------------------------------------------------------------------------- /src/main/groovy/ast/sortable/Golfer.groovy: -------------------------------------------------------------------------------- 1 | package ast.sortable 2 | 3 | import groovy.transform.Canonical 4 | import groovy.transform.Sortable 5 | 6 | @Sortable(includes = ['score', 'last', 'first']) 7 | class Golfer { 8 | int score 9 | String first 10 | String last 11 | 12 | String toString() { "$first $last ($score)" } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/groovy/ast/sortable/use_golfers.groovy: -------------------------------------------------------------------------------- 1 | package ast.sortable 2 | 3 | List golfers = [ 4 | new Golfer(score: 70, first: 'Tiger', last: 'Woods'), 5 | new Golfer(score: 68, first: 'Tom', last: 'Watson'), 6 | new Golfer(score: 68, first: 'Bubba', last: 'Watson'), 7 | new Golfer(score: 69, first: 'Ty', last: 'Webb') 8 | ] 9 | 10 | println golfers.sort() // score, then last, then first -------------------------------------------------------------------------------- /src/main/groovy/ast/tostring/tostring_and_equals.groovy: -------------------------------------------------------------------------------- 1 | /* =================================================== 2 | * Copyright 2012 Kousen IT, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * ========================================================== */ 16 | package ast.tostring 17 | 18 | import groovy.transform.Canonical; 19 | import groovy.transform.EqualsAndHashCode; 20 | import groovy.transform.ToString; 21 | import groovy.transform.TupleConstructor; 22 | 23 | @EqualsAndHashCode 24 | @ToString 25 | @TupleConstructor 26 | //@Canonical 27 | class Product { 28 | int id 29 | String name 30 | def price 31 | } 32 | 33 | Product p_orig = new Product(id:1,name:'name',price:9.99) 34 | Product p_copy = new Product(id:1,name:'name',price:9.99) 35 | Product p_diff = new Product(id:2,name:'other',price:5) 36 | Product p2 = new Product(3, 'abc', 10) 37 | 38 | assert p_orig == p_copy 39 | assert !p_orig.is(p_copy) 40 | assert p_orig != p_diff 41 | assert p_orig.toString() == 'ast.tostring.Product(1, name, 9.99)' 42 | 43 | Set products = [p_orig, p_copy, p_diff] 44 | assert products.size() == 2 -------------------------------------------------------------------------------- /src/main/groovy/astro/astronauts_in_space.groovy: -------------------------------------------------------------------------------- 1 | package astro 2 | 3 | import groovy.json.* 4 | import groovy.sql.* 5 | import groovy.transform.* 6 | import com.google.gson.Gson 7 | 8 | @Canonical 9 | class Assignment { 10 | String name 11 | String craft 12 | } 13 | 14 | @Canonical 15 | class AstroResponse { 16 | String message 17 | int number 18 | Assignment[] people 19 | } 20 | 21 | AstroResponse getAndParseJSON() { 22 | String jsonTxt = 'http://api.open-notify.org/astros.json'.toURL().text 23 | def json = new JsonSlurper().parseText(jsonTxt) 24 | println "There are ${json.number} people in space" 25 | return new Gson().fromJson(jsonTxt, AstroResponse) 26 | } 27 | 28 | void saveAstronautsInDB(AstroResponse response) { 29 | Sql sql = Sql.newInstance(url: 'jdbc:h2:~/astro', driver: 'org.h2.Driver') 30 | sql.execute ''' 31 | create table if not exists ASTRONAUTS( 32 | id int auto_increment primary key, 33 | name varchar(50), 34 | craft varchar(50) 35 | ) 36 | ''' 37 | 38 | response.people.each { 39 | sql.execute "insert into ASTRONAUTS(name, craft) values ($it.name, $it.craft)" 40 | } 41 | sql.close() 42 | } 43 | 44 | void printAstronautsFromDB() { 45 | Sql sql = Sql.newInstance(url: 'jdbc:h2:~/astro', driver: 'org.h2.Driver') 46 | assert sql.rows('select * from ASTRONAUTS').size() >= 3 47 | 48 | sql.eachRow('select * from ASTRONAUTS') { row -> 49 | println "${row.name.padRight(20)} aboard ${row.craft}" 50 | } 51 | sql.close() 52 | } 53 | 54 | getAndParseJSON().people.each { 55 | println it 56 | } 57 | 58 | saveAstronautsInDB(getAndParseJSON()) 59 | printAstronautsFromDB() 60 | -------------------------------------------------------------------------------- /src/main/groovy/builders/antbuilder.groovy: -------------------------------------------------------------------------------- 1 | /* =================================================== 2 | * Copyright 2012 Kousen IT, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * ========================================================== */ 16 | package builders 17 | 18 | import groovy.ant.AntBuilder 19 | 20 | AntBuilder ant = new AntBuilder() 21 | String dir = '.' 22 | 23 | assert !(new File("$dir/antbuildercopy.groovy").exists()) 24 | 25 | ant.echo 'about to copy the source code' 26 | ant.copy file:"$dir/antbuilder.groovy", 27 | tofile:"$dir/antbuildercopy.groovy" 28 | 29 | assert (new File("$dir/antbuildercopy.groovy").exists()) 30 | 31 | ant.echo 'deleting the copied file' 32 | ant.delete file:"$dir/antbuildercopy.groovy" 33 | 34 | // simpler syntax 35 | ant.with { 36 | echo 'about to copy the source code' 37 | copy file:"$dir/antbuilder.groovy", tofile:"$dir/antbuildercopy.groovy" 38 | echo 'deleting the copied file' 39 | delete file:"$dir/antbuildercopy.groovy" 40 | } -------------------------------------------------------------------------------- /src/main/groovy/builders/department.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | IT Employees 4 | 5 | 6 |

IT

7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 |
0Employee 0
1Employee 1
2Employee 2
3Employee 3
25 | 26 | -------------------------------------------------------------------------------- /src/main/groovy/builders/htmlBuilder.groovy: -------------------------------------------------------------------------------- 1 | package builders 2 | 3 | import groovy.xml.MarkupBuilder 4 | 5 | def writer = new FileWriter('department.html') 6 | def builder = new MarkupBuilder(writer) 7 | builder.html { 8 | head { 9 | title "IT Employees" 10 | } 11 | body { 12 | h2 "IT" 13 | table (border:1) { 14 | (0..3).each { num -> 15 | tr { 16 | td num 17 | td "Employee $num" 18 | } 19 | } 20 | } 21 | } 22 | } 23 | 24 | println new File('department.html').text -------------------------------------------------------------------------------- /src/main/groovy/builders/markupBuilder.groovy: -------------------------------------------------------------------------------- 1 | /* =================================================== 2 | * Copyright 2012 Kousen IT, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * ========================================================== */ 16 | package builders 17 | 18 | import groovy.xml.MarkupBuilder; 19 | 20 | def writer = new StringWriter() 21 | def builder = new MarkupBuilder(writer) 22 | def department = builder.department { 23 | deptName "Construction" 24 | employee(id:1) { 25 | empName "Fred" 26 | } 27 | employee(id:2) { 28 | empName "Barney" 29 | } 30 | } 31 | println writer 32 | 33 | builder = new MarkupBuilder() 34 | builder.numbers { 35 | (0..5).each { 36 | num it 37 | } 38 | } -------------------------------------------------------------------------------- /src/main/groovy/builders/swingBuilder.groovy: -------------------------------------------------------------------------------- 1 | package builders 2 | 3 | import groovy.swing.SwingBuilder 4 | import java.awt.BorderLayout as BL 5 | import javax.swing.WindowConstants as WC 6 | 7 | SwingBuilder builder = new SwingBuilder() 8 | def frame = builder.frame(title:'Hello, Groovy!', visible: true, 9 | size:[200,100], defaultCloseOperation:WC.EXIT_ON_CLOSE) { 10 | panel(layout:new BL()) { 11 | def txt = textField(constraints:BL.NORTH,'Enter text here') 12 | def lab = label(constraints:BL.CENTER,'Text') 13 | button(constraints: BL.SOUTH, 'Move Text', 14 | actionPerformed: { lab.text = txt.text }) 15 | txt.actionPerformed = { lab.text = txt.text } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/groovy/closurespackage/closures.groovy: -------------------------------------------------------------------------------- 1 | /* =================================================== 2 | * Copyright 2012 Kousen IT, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * ========================================================== */ 16 | package closurespackage 17 | 18 | // supplying closure to each 19 | def total = 0 20 | (1..10).each { num -> total += num } 21 | assert (1..10).sum() == total 22 | total = 0 23 | (1..10).each { total += it } 24 | assert (1..10).sum() == total 25 | 26 | // calling a closure 27 | def echo = { it } 28 | assert "Hello" == echo('Hello') 29 | assert "Hello" == echo.call('Hello') 30 | 31 | // currying closures 32 | def sumN = { n,list -> list[0..n-1].sum() } 33 | assert sumN(1, [1,2,3]) == 1 34 | assert sumN(2, [1,2,3]) == 3 35 | assert sumN(3, [1,2,3]) == 6 36 | 37 | def sum3 = sumN.curry(3) 38 | assert sum3([1,2,3,4,5]) == 6 -------------------------------------------------------------------------------- /src/main/groovy/collections/Circle.java: -------------------------------------------------------------------------------- 1 | /* =================================================== 2 | * Copyright 2012 Kousen IT, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * ========================================================== */ 16 | package collections; 17 | 18 | public class Circle extends Shape implements Comparable { 19 | private double radius; 20 | 21 | public Circle(double radius) { 22 | this.radius = radius; 23 | } 24 | 25 | public void setRadius(double radius) { 26 | this.radius = radius; 27 | } 28 | 29 | public double getRadius() { 30 | return radius; 31 | } 32 | 33 | public int compareTo(Circle o) { 34 | return (int) (this.radius - o.radius); 35 | } 36 | 37 | @Override 38 | public double getArea() { 39 | return Math.PI*radius*radius; 40 | } 41 | 42 | @Override 43 | public String toString() { 44 | return "Circle [radius=" + radius + "]"; 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/main/groovy/collections/Shape.java: -------------------------------------------------------------------------------- 1 | /* =================================================== 2 | * Copyright 2012 Kousen IT, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * ========================================================== */ 16 | package collections; 17 | 18 | public abstract class Shape { 19 | public abstract double getArea(); 20 | } 21 | -------------------------------------------------------------------------------- /src/main/groovy/collections/SortingLists.java: -------------------------------------------------------------------------------- 1 | /* =================================================== 2 | * Copyright 2012 Kousen IT, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * ========================================================== */ 16 | package collections; 17 | 18 | import java.util.ArrayList; 19 | import java.util.Collections; 20 | import java.util.List; 21 | 22 | public class SortingLists { 23 | public static void main(String[] args) { 24 | List circles = new ArrayList(); 25 | circles.add(new Circle(3)); 26 | circles.add(new Circle(1)); 27 | circles.add(new Circle(4)); 28 | circles.add(new Circle(5)); 29 | circles.add(new Circle(9)); 30 | circles.add(new Circle(2)); 31 | System.out.println(circles); 32 | Collections.sort(circles); 33 | System.out.println(circles); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/groovy/collections/WordCountGroovy.groovy: -------------------------------------------------------------------------------- 1 | /* =================================================== 2 | * Copyright 2012 Kousen IT, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * ========================================================== */ 16 | package collections 17 | 18 | class WordCountGroovy { 19 | def wordCount = [:] 20 | 21 | void countWords() { 22 | def file = new File('src/main/groovy/collections/passage.txt') 23 | file.eachLine { line -> 24 | List words = line.tokenize() 25 | words.each { word -> 26 | wordCount[word] = wordCount.get(word,0) + 1 27 | } 28 | } 29 | } 30 | 31 | Map getMostFrequent() { 32 | def sorted = [:] 33 | def sortedKeys = wordCount.keySet().sort { wordCount[it] } 34 | sortedKeys[-1..-5].each { word -> 35 | sorted[word] = wordCount[word] 36 | } 37 | return sorted 38 | } 39 | } -------------------------------------------------------------------------------- /src/main/groovy/collections/lists.groovy: -------------------------------------------------------------------------------- 1 | /* =================================================== 2 | * Copyright 2012 Kousen IT, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * ========================================================== */ 16 | package collections 17 | 18 | def teams = ["Red Sox","Yankees"] 19 | assert teams.class == ArrayList 20 | 21 | def names = teams as String[] 22 | assert names.class == String[] 23 | def set = teams as Set 24 | assert(set instanceof Set) 25 | 26 | def strings = ['hello','world','how','are','you','hello'] 27 | assert strings.size() == 6 28 | def stringSet = strings as Set 29 | println stringSet 30 | println strings[-1..-3] 31 | println strings[-3..-1] 32 | println strings[1,3,5] 33 | 34 | 35 | teams << "Orioles" 36 | assert teams == ["Red Sox","Yankees","Orioles"] 37 | teams << ["Rays","Blue Jays"] 38 | assert teams == ["Red Sox","Yankees","Orioles",["Rays","Blue Jays"]] 39 | assert teams.flatten() == ["Red Sox","Yankees","Orioles","Rays","Blue Jays"] 40 | assert teams + "Angels" - "Orioles" == 41 | ["Red Sox", "Yankees", ["Rays", "Blue Jays"], "Angels"] 42 | 43 | assert teams[0] == 'Red Sox' 44 | assert teams[1] == 'Yankees' 45 | assert teams[-1] == ['Rays','Blue Jays'] 46 | 47 | //teams = ["Red Sox","Yankees","Rays"] 48 | //def popped = teams.pop() 49 | //assert popped == "Rays" 50 | 51 | assert ["Yankees","Mets"].reverse() == ["Mets","Yankees"] 52 | 53 | def ALCentral = ["Indians","Tigers"] 54 | assert ['Blue Jays','Indians','Mets'].intersect(ALCentral) == ["Indians"] 55 | 56 | def cities = ["New York","Boston","Cleveland","Seattle"] 57 | assert ['Boston','Cleveland'] == cities[1..2] 58 | // Reversed 59 | cities = cities.reverse() 60 | assert cities == ["Seattle", "Cleveland", "Boston", "New York"] 61 | 62 | // Natural ordering 63 | cities = cities.sort() 64 | assert cities == ["Boston", "Cleveland", "New York", "Seattle"] 65 | cities = cities.sort { it.size() } 66 | cities == ['Boston', 'Seattle', 'New York', 'Cleveland'] 67 | 68 | // Order by length of city name 69 | cities = cities.sort { a,b -> a.size() <=> b.size() } 70 | assert cities == ["Boston", "Seattle", "New York", "Cleveland"] 71 | assert cities*.substring(0,3) == ["Bos","Sea","New","Cle"] 72 | assert cities.collect { it.substring(0,3) } == ["Bos","Sea","New","Cle"] 73 | 74 | // Collect applies closure to each element 75 | def abbrev = cities.collect { city -> city[0..2].toLowerCase() } 76 | assert abbrev == ["bos", "sea", "new", "cle"] 77 | 78 | assert cities.collect { it.size() } == [6, 7, 8, 9] 79 | 80 | //inject accumulates 81 | int total = cities.inject(0) { nameLength, city -> 82 | nameLength += city.size() 83 | } 84 | assert 30 == total 85 | 86 | assert ['a','b','c'].join('&') == 'a&b&c' 87 | 88 | // any and every 89 | assert cities.any { it.size() < 7 } 90 | assert cities.every { it.size() < 10 } 91 | 92 | assert 'New Hampshire' == 93 | ['New Hampshire','New Jersey','New York'].find { it =~ /New/ } 94 | 95 | //findAll returns cities satisfying closure 96 | def withE = cities.findAll { city -> city =~ /e/ } 97 | assert withE == ["Seattle", "New York", "Cleveland"] 98 | 99 | // join concatenates entries 100 | assert cities.join(',') == "Boston,Seattle,New York,Cleveland" 101 | 102 | -------------------------------------------------------------------------------- /src/main/groovy/collections/maps.groovy: -------------------------------------------------------------------------------- 1 | /* =================================================== 2 | * Copyright 2012 Kousen IT, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * ========================================================== */ 16 | package collections 17 | 18 | // Start with an empty map 19 | def ALEast = [:] 20 | assert ALEast instanceof HashMap 21 | 22 | // Java put and get methods 23 | ALEast.put('Boston','Red Sox') 24 | assert 'Red Sox' == ALEast.get('Boston') 25 | assert ALEast == [Boston:'Red Sox'] 26 | 27 | // Overridden putAt method 28 | ALEast['New York'] = 'Yankees' 29 | 30 | // Size method and dot access 31 | assert 2 == ALEast.size() 32 | assert 'Red Sox' == ALEast.Boston 33 | assert 'Yankees' == ALEast.'New York' 34 | 35 | assert ALEast == [Boston:'Red Sox','New York':'Yankees'] 36 | assert ALEast['Boston'] == 'Red Sox' 37 | 38 | // Initialized map 39 | Map ALCentral = [Cleveland:'Indians', 40 | Chicago:'White Sox',Detroit:'Tigers'] 41 | assert 3 == ALCentral.size() 42 | assert ALCentral.Cleveland == 'Indians' 43 | 44 | // Overridden plus method 45 | def both = ALEast + ALCentral 46 | assert 5 == both.size() 47 | assert both == [Boston:'Red Sox','New York':'Yankees', 48 | Cleveland:'Indians', Chicago:'White Sox',Detroit:'Tigers'] 49 | 50 | // keySet method 51 | assert ALEast.keySet() == ['Boston','New York'] as Set 52 | 53 | // Get method with a default 54 | assert !ALEast.get('Toronto') 55 | assert 'Blue Jays' == ALEast.get('Toronto','Blue Jays') 56 | assert 'Blue Jays' == ALEast['Toronto'] 57 | 58 | def map = [x:1, y:2, z:3] 59 | 60 | // each iterator 61 | String keys1 = '' 62 | List values1 = [] 63 | both.each { key,val -> 64 | keys1 += '|' + key 65 | values1 << val 66 | } 67 | 68 | String keys2 = '' 69 | List values2 = [] 70 | both.each { entry -> 71 | keys2 += '|' + entry.key 72 | values2 << entry.value 73 | } 74 | assert keys1 == keys2 75 | assert values1 == values2 76 | -------------------------------------------------------------------------------- /src/main/groovy/collections/passage.txt: -------------------------------------------------------------------------------- 1 | Groovy... 2 | 3 | * is an agile and dynamic language for the Java Virtual Machine 4 | * builds upon the strengths of Java but has additional power features inspired by languages like Python, Ruby and Smalltalk 5 | * makes modern programming features available to Java developers with almost-zero learning curve 6 | * supports Domain-Specific Languages and other compact syntax so your code becomes easy to read and maintain 7 | * makes writing shell and build scripts easy with its powerful processing primitives, OO abilities and an Ant DSL 8 | * increases developer productivity by reducing scaffolding code when developing web, GUI, database or console applications 9 | * simplifies testing by supporting unit testing and mocking out-of-the-box 10 | * seamlessly integrates with all existing Java objects and libraries 11 | * compiles straight to Java bytecode so you can use it anywhere you can use Java 12 | -------------------------------------------------------------------------------- /src/main/groovy/collections/ranges.groovy: -------------------------------------------------------------------------------- 1 | /* =================================================== 2 | * Copyright 2012 Kousen IT, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * ========================================================== */ 16 | package collections 17 | 18 | 19 | import java.time.LocalDate 20 | import java.time.Month 21 | import java.time.format.DateTimeFormatter 22 | 23 | Range bothEnds = 5..8 24 | assert bothEnds.contains(5) 25 | assert bothEnds.contains(8) 26 | assert bothEnds.from == 5 27 | // equivalent to bothEnds.getFrom() 28 | assert bothEnds.to == 8 29 | assert bothEnds == [5, 6, 7, 8] 30 | 31 | Range noUpper = 5..<8 32 | assert noUpper.contains(5) 33 | assert !noUpper.contains(8) 34 | assert noUpper.from == 5 35 | assert noUpper.to == 7 36 | assert noUpper == [5, 6, 7] 37 | assert "Range: $noUpper: from ${noUpper.from} to ${noUpper.to}" == 38 | 'Range: [5, 6, 7]: from 5 to 7' 39 | 40 | assert 1..5 == [1, 2, 3, 4, 5] 41 | assert 'A'..'E' == ["A", "B", "C", "D", "E"] 42 | 43 | def total = ('A'..'Z') + ('a'..'z') + (0..9) 44 | println total 45 | println total.class.name 46 | [5,10,15,20].each { println "$it: ${total[it]}" } 47 | 48 | LocalDate now = LocalDate.of(2011, Month.FEBRUARY, 27) 49 | LocalDate then = LocalDate.of(2011, Month.MARCH, 2) 50 | 51 | def days = (now..then).collect { day -> 52 | day.format(DateTimeFormatter.ISO_LOCAL_DATE) 53 | } 54 | println days 55 | assert days == [ 56 | '2011-02-27', 57 | '2011-02-28', 58 | '2011-03-01', 59 | '2011-03-02' 60 | ] 61 | -------------------------------------------------------------------------------- /src/main/groovy/conditionals/conditionals.groovy: -------------------------------------------------------------------------------- 1 | /* =================================================== 2 | * Copyright 2012 Kousen IT, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * ========================================================== */ 16 | package conditionals 17 | 18 | if (true) assert true 19 | 20 | if (1) 21 | assert true 22 | else 23 | assert false 24 | 25 | def result = 5 > 3 ? 'x' : 'y' 26 | assert result == 'x' 27 | 28 | // name supplied as a parameter, or not 29 | 30 | // result = name ? name : 'Elvis' 31 | // like nvl(varname,literal) in SQL 32 | 33 | def greet(name) { "${name ?: 'Elvis'} has left the building" } 34 | assert greet() == 'Elvis has left the building' 35 | assert greet(null) == 'Elvis has left the building' 36 | assert greet('Priscilla') == 'Priscilla has left the building' 37 | 38 | def hello(name = 'World') { "Hello, $name!" } 39 | assert hello() == 'Hello, World!' 40 | assert hello(null) == 'Hello, null!' 41 | assert hello('Dolly') == 'Hello, Dolly!' 42 | 43 | // 'reused' from Groovy In Action -- buy it! 44 | switch (10) { 45 | case 0: assert false; break 46 | case 0..9: assert false; break 47 | case [8,9,11]: assert false; break 48 | case Float: assert false; break 49 | case { it%3 == 0 }: assert false; break 50 | case ~/../: assert true; break 51 | default: assert false 52 | } 53 | 54 | def val 55 | def a, b, c 56 | // long form (Java like) 57 | if (a != null) { 58 | if (a.b != null) { 59 | val = a.b.c 60 | } else { 61 | val = null 62 | } 63 | } else { 64 | val = null 65 | } 66 | 67 | // easier way (Groovy) 68 | val = a?.b?.c 69 | -------------------------------------------------------------------------------- /src/main/groovy/conditionals/loops.groovy: -------------------------------------------------------------------------------- 1 | /* =================================================== 2 | * Copyright 2012 Kousen IT, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * ========================================================== */ 16 | package conditionals 17 | 18 | def strings = ['how','are','you'] 19 | def results = [] 20 | strings.eachWithIndex { s,i -> results << "$i:$s" } 21 | assert results == ["0:how","1:are","2:you"] 22 | 23 | def words = "I'm a Groovy coder".tokenize() 24 | def capitalized = '' 25 | for (word in words) { 26 | capitalized += word.capitalize() + ' ' 27 | } 28 | assert capitalized == "I'm A Groovy Coder " 29 | 30 | // traditional Java for loop 31 | for (int i = 0; i < words.size(); i++) { 32 | println "$i -- ${words[i]}" 33 | } 34 | 35 | // traditional Java while loop 36 | int x = 1000 37 | while (x > 1) { 38 | println x 39 | x = x/2 40 | } -------------------------------------------------------------------------------- /src/main/groovy/datetime/groundhogday.groovy: -------------------------------------------------------------------------------- 1 | package datetime 2 | 3 | import groovy.time.TimeCategory 4 | 5 | import java.time.LocalDate 6 | import java.time.temporal.ChronoUnit 7 | 8 | import static java.time.Month.* 9 | 10 | def ghday = LocalDate.of(2023, FEBRUARY, 2) 11 | def spring = LocalDate.of(2023, MARCH, 20) 12 | long days = spring - ghday 13 | long weeks = ghday.until(spring, ChronoUnit.WEEKS) 14 | println "There are $days between Groundhog Day and the 1st day of Spring" 15 | println "Thats $weeks weeks and ${days - 7 * weeks} days" 16 | 17 | // From Paul King (see https://groovy.apache.org/blog/groundhog-day): 18 | var groundHogDay = LocalDate.of(2023, FEBRUARY, 2) 19 | var springEquinoxNorthernHemisphere = LocalDate.of(2023, MARCH, 20) 20 | var expected = use(TimeCategory) { 6.weeks + 4.days }.days 21 | assert springEquinoxNorthernHemisphere - groundHogDay == expected 22 | -------------------------------------------------------------------------------- /src/main/groovy/db/Product.java: -------------------------------------------------------------------------------- 1 | /* =================================================== 2 | * Copyright 2012 Kousen IT, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * ========================================================== */ 16 | package db; 17 | 18 | public class Product { 19 | private int id; 20 | private String name; 21 | private double price; 22 | 23 | public Product() {} 24 | 25 | public Product(int id, String name, double price) { 26 | this.id = id; 27 | this.name = name; 28 | this.price = price; 29 | } 30 | 31 | public int getId() { 32 | return id; 33 | } 34 | 35 | public void setId(int id) { 36 | this.id = id; 37 | } 38 | 39 | public String getName() { 40 | return name; 41 | } 42 | 43 | public void setName(String name) { 44 | this.name = name; 45 | } 46 | 47 | public double getPrice() { 48 | return price; 49 | } 50 | 51 | public void setPrice(double price) { 52 | this.price = price; 53 | } 54 | 55 | @Override 56 | public String toString() { 57 | return "ProductJava [id=" + id + ", name=" + name + ", price=" + price 58 | + "]"; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/main/groovy/db/ProductDAO.java: -------------------------------------------------------------------------------- 1 | /* =================================================== 2 | * Copyright 2012 Kousen IT, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * ========================================================== */ 16 | package db; 17 | 18 | import java.sql.Connection; 19 | import java.sql.DriverManager; 20 | import java.sql.PreparedStatement; 21 | import java.sql.ResultSet; 22 | import java.sql.SQLException; 23 | import java.sql.Statement; 24 | import java.util.ArrayList; 25 | import java.util.List; 26 | 27 | public class ProductDAO { 28 | private static final String URL = "jdbc:h2:./build/test"; 29 | private static final String DRIVER = "org.h2.Driver"; 30 | 31 | public ProductDAO() { 32 | try { 33 | Class.forName(DRIVER); 34 | } catch (ClassNotFoundException e) { 35 | e.printStackTrace(); 36 | return; 37 | } 38 | createAndPopulateTable(); 39 | } 40 | 41 | private void createAndPopulateTable() { 42 | Connection conn = null; 43 | Statement stmt = null; 44 | try { 45 | conn = DriverManager.getConnection(URL); 46 | stmt = conn.createStatement(); 47 | stmt.execute("drop table if exists product;"); 48 | stmt.execute("create table product (id int primary key, name varchar(25), price double);"); 49 | stmt.executeUpdate("insert into product values (1,'baseball',4.99),(2,'football',14.95),(3,'basketball',14.99)"); 50 | } catch (SQLException e) { 51 | e.printStackTrace(); 52 | } finally { 53 | try { 54 | if (stmt != null) stmt.close(); 55 | if (conn != null) conn.close(); 56 | } catch (SQLException e) { 57 | e.printStackTrace(); 58 | } 59 | } 60 | } 61 | 62 | public List getAllProducts() { 63 | Connection conn = null; 64 | PreparedStatement pst = null; 65 | List results = new ArrayList<>(); 66 | try { 67 | conn = DriverManager.getConnection(URL); 68 | pst = conn.prepareStatement("select * from product"); 69 | ResultSet rs = pst.executeQuery(); 70 | while (rs.next()) { 71 | Product p = new Product(); 72 | p.setId(rs.getInt("id")); 73 | p.setName(rs.getString("name")); 74 | p.setPrice(rs.getDouble("price")); 75 | results.add(p); 76 | } 77 | rs.close(); 78 | } catch (SQLException e) { 79 | e.printStackTrace(); 80 | } finally { 81 | try { 82 | if (pst != null) pst.close(); 83 | if (conn != null) conn.close(); 84 | } catch (SQLException e) { 85 | e.printStackTrace(); 86 | } 87 | } 88 | return results; 89 | } 90 | 91 | public Product findProductById(int id) { 92 | Product p = null; 93 | Connection conn = null; 94 | PreparedStatement pst = null; 95 | try { 96 | conn = DriverManager.getConnection(URL); 97 | pst = conn.prepareStatement("select * from product where id = ?"); 98 | pst.setInt(1, id); 99 | ResultSet rs = pst.executeQuery(); 100 | if (rs.next()) { 101 | p = new Product(); 102 | p.setId(rs.getInt("id")); 103 | p.setName(rs.getString("name")); 104 | p.setPrice(rs.getDouble("price")); 105 | } 106 | rs.close(); 107 | } catch (SQLException e) { 108 | e.printStackTrace(); 109 | } finally { 110 | try { 111 | if (pst != null) pst.close(); 112 | if (conn != null) conn.close(); 113 | } catch (SQLException e) { 114 | e.printStackTrace(); 115 | } 116 | } 117 | return p; 118 | } 119 | 120 | public void insertProduct(Product p) { 121 | Connection conn = null; 122 | PreparedStatement pst = null; 123 | try { 124 | conn = DriverManager.getConnection(URL); 125 | pst = conn.prepareStatement("insert into product (id,name,price) values (?,?,?)"); 126 | pst.setInt(1, p.getId()); 127 | pst.setString(2, p.getName()); 128 | pst.setDouble(3, p.getPrice()); 129 | int uc = pst.executeUpdate(); 130 | if (uc != 1) throw new SQLException("insert of product failed"); 131 | } catch (SQLException e) { 132 | e.printStackTrace(); 133 | } finally { 134 | try { 135 | if (pst != null) pst.close(); 136 | if (conn != null) conn.close(); 137 | } catch (SQLException e) { 138 | e.printStackTrace(); 139 | } 140 | } 141 | } 142 | 143 | public void deleteProduct(int id) { 144 | Connection conn = null; 145 | PreparedStatement pst = null; 146 | try { 147 | conn = DriverManager.getConnection(URL); 148 | pst = conn.prepareStatement("delete from product where id=?"); 149 | pst.setInt(1, id); 150 | int uc = pst.executeUpdate(); 151 | if (uc != 1) throw new SQLException("delete of product failed"); 152 | } catch (SQLException e) { 153 | e.printStackTrace(); 154 | } finally { 155 | try { 156 | if (pst != null) pst.close(); 157 | if (conn != null) conn.close(); 158 | } catch (SQLException e) { 159 | e.printStackTrace(); 160 | } 161 | } 162 | } 163 | } 164 | -------------------------------------------------------------------------------- /src/main/groovy/db/products.groovy: -------------------------------------------------------------------------------- 1 | /* =================================================== 2 | * Copyright 2012 Kousen IT, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * ========================================================== */ 16 | package db 17 | 18 | import groovy.sql.Sql 19 | 20 | Sql sql = Sql.newInstance(url:'jdbc:h2:mem:',driver:'org.h2.Driver') 21 | 22 | sql.execute ''' 23 | create table product ( 24 | id int primary key, 25 | name varchar(25), 26 | price double 27 | ) 28 | ''' 29 | 30 | sql.execute ''' 31 | insert into product values 32 | (1,'baseball',4.99),(2,'football',14.95),(3,'basketball',14.99) 33 | ''' 34 | 35 | assert sql.rows('select * from product').size() == 3 36 | 37 | List products = sql.rows('select * from product') 38 | .collect { row -> new Product(id:row.id, name:row.name, price:row.price) } 39 | 40 | products.each { println it } 41 | 42 | products = [] 43 | sql.eachRow('select * from product') { row -> 44 | products << new Product(id:row.id, name:row.name, price:row.price) 45 | } 46 | assert products.size() == 3 47 | 48 | def params = [4,'soccer ball',16.99] 49 | sql.execute('insert into product(id,name,price) values(?,?,?)', params) 50 | 51 | def row = sql.firstRow('select * from product where id=?', 4) 52 | assert row.id == 4 53 | assert row.name == 'soccer ball' 54 | assert row.price == 16.99 55 | 56 | sql.close() -------------------------------------------------------------------------------- /src/main/groovy/db/products2xml.groovy: -------------------------------------------------------------------------------- 1 | /* =================================================== 2 | * Copyright 2012 Kousen IT, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * ========================================================== */ 16 | package db 17 | 18 | import groovy.sql.Sql 19 | import groovy.xml.MarkupBuilder; 20 | 21 | Sql sql = Sql.newInstance(url:'jdbc:h2:mem:',driver:'org.h2.Driver') 22 | 23 | sql.execute ''' 24 | create table product ( 25 | id int primary key, 26 | name varchar(25), 27 | price double 28 | ) 29 | ''' 30 | 31 | sql.execute """ 32 | insert into product values 33 | (1,'baseball',4.99),(2,'football',14.95),(3,'basketball',14.99) 34 | """ 35 | def builder = new MarkupBuilder() 36 | 37 | builder.products { 38 | sql.eachRow("select * from product") { row -> 39 | product(id:row.id) { 40 | name row.name 41 | price row.price 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/groovy/filter/FilterNumbers.groovy: -------------------------------------------------------------------------------- 1 | package filter 2 | 3 | class FilterNumbers { 4 | Collection findPositives(Number... numbers) { 5 | numbers.findAll { it > 0 } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/main/groovy/filter/UseFilterNumbers.java: -------------------------------------------------------------------------------- 1 | package filter; 2 | 3 | public class UseFilterNumbers { 4 | public static void main(String[] args) { 5 | FilterNumbers filterNumbers = new FilterNumbers(); 6 | System.out.println(filterNumbers.findPositives(-1, -2, 1, 2, 3)); 7 | System.out.println(filterNumbers.findPositives(1, 2, 3)); 8 | System.out.println(filterNumbers.findPositives(-1, -2, -3, -4)); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/main/groovy/flickr/cat_pictures.groovy: -------------------------------------------------------------------------------- 1 | package flickr 2 | 3 | import groovy.json.* 4 | import groovy.swing.SwingBuilder 5 | 6 | import java.awt.GridLayout 7 | import javax.swing.ImageIcon 8 | import javax.swing.WindowConstants as WC 9 | 10 | String key = new File('flickr_key.txt').text 11 | String endPoint = 'https://api.flickr.com/services/rest?' 12 | def params = [method: 'flickr.photos.search', 13 | api_key: key, 14 | format: 'json', 15 | tags: 'kitties', 16 | nojsoncallback: 1, 17 | media: 'photos', 18 | per_page: 6] 19 | 20 | // Build URL and download JSON data 21 | def qs = params.collect { it }.join('&') 22 | // def qs = params.collect { k,v -> "$k=$v" }.join('&') 23 | // def qs = params*.toString().join('&') 24 | println "$endPoint$qs" 25 | String jsonTxt = "$endPoint$qs".toURL().text 26 | 27 | // write formatted JSON data to file 28 | File f = new File('cats.json') 29 | if (f) f.delete() 30 | f << JsonOutput.prettyPrint(jsonTxt) 31 | println JsonOutput.prettyPrint(jsonTxt) 32 | 33 | // parse JSON data and build URL for pictures 34 | def json = new JsonSlurper().parseText(jsonTxt) 35 | def photos = json.photos.photo 36 | 37 | // build UI using Swing 38 | new SwingBuilder().edt { 39 | frame(title:'Cat pictures', visible: true, pack: true, 40 | defaultCloseOperation: WC.EXIT_ON_CLOSE, 41 | layout:new GridLayout(0, 2, 2, 2)) { 42 | photos.each { p -> 43 | String url = "https://farm${p.farm}.staticflickr.com/${p.server}/${p.id}_${p.secret}.jpg" 44 | String title = p.title 45 | label(icon: new ImageIcon(url.toURL()), toolTipText: title) 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/groovy/flickr/cats.json: -------------------------------------------------------------------------------- 1 | { 2 | "photos": { 3 | "page": 1, 4 | "pages": 25641, 5 | "perpage": 6, 6 | "total": "153845", 7 | "photo": [ 8 | { 9 | "id": "50567327821", 10 | "owner": "190886361@N04", 11 | "secret": "ffda1babb0", 12 | "server": "65535", 13 | "farm": 66, 14 | "title": "The way these kitties are asleep", 15 | "ispublic": 1, 16 | "isfriend": 0, 17 | "isfamily": 0 18 | }, 19 | { 20 | "id": "50564201218", 21 | "owner": "49271313@N00", 22 | "secret": "925c7ec3ed", 23 | "server": "65535", 24 | "farm": 66, 25 | "title": "\u85af\u6ce2 & \u5c0f\u67cf", 26 | "ispublic": 1, 27 | "isfriend": 0, 28 | "isfamily": 0 29 | }, 30 | { 31 | "id": "50565084482", 32 | "owner": "49271313@N00", 33 | "secret": "c03ffb1b60", 34 | "server": "65535", 35 | "farm": 66, 36 | "title": "\u85af\u76ae", 37 | "ispublic": 1, 38 | "isfriend": 0, 39 | "isfamily": 0 40 | }, 41 | { 42 | "id": "50565084392", 43 | "owner": "49271313@N00", 44 | "secret": "44be6928b6", 45 | "server": "65535", 46 | "farm": 66, 47 | "title": "\u5c0f\u67cf & \u56db\u5c0f\u85af", 48 | "ispublic": 1, 49 | "isfriend": 0, 50 | "isfamily": 0 51 | }, 52 | { 53 | "id": "50562536208", 54 | "owner": "10185705@N04", 55 | "secret": "c77f3e08cb", 56 | "server": "65535", 57 | "farm": 66, 58 | "title": "Gracie 11 September 2020 5484", 59 | "ispublic": 1, 60 | "isfriend": 0, 61 | "isfamily": 0 62 | }, 63 | { 64 | "id": "50563410237", 65 | "owner": "10185705@N04", 66 | "secret": "804237e186", 67 | "server": "65535", 68 | "farm": 66, 69 | "title": "Millie 9 September 2020 5481", 70 | "ispublic": 1, 71 | "isfriend": 0, 72 | "isfamily": 0 73 | } 74 | ] 75 | }, 76 | "stat": "ok" 77 | } -------------------------------------------------------------------------------- /src/main/groovy/geocoder/Geocoder.groovy: -------------------------------------------------------------------------------- 1 | /* =================================================== 2 | * Copyright 2012 Kousen IT, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * ========================================================== */ 16 | package geocoder 17 | 18 | import groovy.xml.XmlSlurper 19 | 20 | class Geocoder { 21 | public static final String BASE = 22 | 'https://maps.google.com/maps/api/geocode/xml?' 23 | private static final String KEY = 'AIzaSyDw_d6dfxDEI7MAvqfGXEIsEMwjC1PWRno' 24 | 25 | void fillInLatLng(Stadium stadium) { 26 | String encoded = 27 | [stadium.street, stadium.city, stadium.state].collect { 28 | URLEncoder.encode(it,'UTF-8') 29 | }.join(',') 30 | String qs = "address=$encoded&key=$KEY" 31 | String url = "$BASE$qs" 32 | println url 33 | def response = new XmlSlurper().parse(url) 34 | def loc = response.result[0].geometry.location 35 | stadium.latitude = loc.lat.toDouble() 36 | stadium.longitude = loc.lng.toDouble() 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/groovy/geocoder/GeocoderJSON.groovy: -------------------------------------------------------------------------------- 1 | /* =================================================== 2 | * Copyright 2012 Kousen IT, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * ========================================================== */ 16 | package geocoder 17 | 18 | import groovy.json.JsonSlurper 19 | 20 | class GeocoderJSON { 21 | String base = 'https://maps.google.com/maps/api/geocode/json?' 22 | private static final String KEY = 'AIzaSyDw_d6dfxDEI7MAvqfGXEIsEMwjC1PWRno' 23 | 24 | void fillInLatLng(Stadium stadium) { 25 | String encoded = 26 | [stadium.street, stadium.city, stadium.state].collect { 27 | URLEncoder.encode(it,'UTF-8') 28 | }.join(',') 29 | String qs = "address=$encoded&key=$KEY" 30 | String url = "$base$qs" 31 | println url 32 | def response = new JsonSlurper().parseText(url.toURL().text) 33 | stadium.latitude = response.results[0].geometry.location.lat.toDouble() 34 | stadium.longitude = response.results[0].geometry.location.lng.toDouble() 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/groovy/geocoder/Stadium.groovy: -------------------------------------------------------------------------------- 1 | /* =================================================== 2 | * Copyright 2012 Kousen IT, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * ========================================================== */ 16 | package geocoder 17 | 18 | import groovy.transform.Canonical 19 | 20 | @Canonical 21 | class Stadium { 22 | Integer id 23 | 24 | String name 25 | String street 26 | String city 27 | String state 28 | String team 29 | 30 | double latitude 31 | double longitude 32 | 33 | // String toString() { "($team,$name,$latitude,$longitude)" } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/groovy/geocoder/populate_stadium_data.groovy: -------------------------------------------------------------------------------- 1 | package geocoder 2 | 3 | import groovy.sql.Sql 4 | 5 | def stadiums = [] 6 | stadiums << new Stadium(name:'Angel Stadium',street:'2000 Gene Autry Way',city:'Anaheim',state:'CA',team:'ana') 7 | stadiums << new Stadium(name:'Chase Field',street:'401 East Jefferson Street',city:'Phoenix',state:'AZ',team:'ari') 8 | stadiums << new Stadium(name:'Turner Field',street:'755 Hank Aaron Drive',city:'Atlanta',state:'GA',team:'atl') 9 | stadiums << new Stadium(name:'Oriole Park',street:'333 West Camden Street',city:'Baltimore',state:'MD',team:'bal') 10 | stadiums << new Stadium(name:'Fenway Park',street:'4 Yawkey Way',city:'Boston',state:'MA',team:'bos') 11 | stadiums << new Stadium(name:'U.S. Cellular Field',street:'333 West 35th Street',city:'Chicago',state:'IL',team:'cha') 12 | stadiums << new Stadium(name:'Wrigley Field',street:'1060 West Addison Street',city:'Chicago',state:'IL',team:'chn') 13 | stadiums << new Stadium(name:'Great American Ball Park',street:'100 Joe Nuxhall Way',city:'Cincinnati',state:'OH',team:'cin') 14 | stadiums << new Stadium(name:'Progressive Field',street:'2401 Ontario Street',city:'Cleveland',state:'OH',team:'cle') 15 | stadiums << new Stadium(name:'Coors Field',street:'2001 Blake Street',city:'Denver',state:'CO',team:'col') 16 | stadiums << new Stadium(name:'Comerica Park',street:'2100 Woodward Avenue',city:'Detroit',state:'MI',team:'det') 17 | stadiums << new Stadium(name:'Sun Life Stadium',street:'2267 NW 199th Street',city:'Miami Gardens',state:'FL',team:'flo') 18 | stadiums << new Stadium(name:'Minute Maid Park',street:'501 Crawford Street',city:'Houston',state:'TX',team:'hou') 19 | stadiums << new Stadium(name:'Kauffman Stadium',street:'One Royal Way',city:'Kansas City',state:'MO',team:'kca') 20 | stadiums << new Stadium(name:'Dodger Stadium',street:'1000 Elysian Park Avenue',city:'Dodgertown',state:'CA',team:'lan') 21 | stadiums << new Stadium(name:'Miller Park',street:'One Brewers Way',city:'Milwaukee',state:'WI',team:'mil') 22 | stadiums << new Stadium(name:'Target Field',street:'1 Twins Way',city:'Minneapolis',state:'MN',team:'min') 23 | stadiums << new Stadium(name:'Yankee Stadium',street:'East 161st Street & River Avenue',city:'New York',state:'NY',team:'nya') 24 | stadiums << new Stadium(name:'Citi Field',street:'126th St. and Roosevelt Ave',city:'Flushing',state:'NY',team:'nyn') 25 | stadiums << new Stadium(name:'O.co Coliseum',street:'7000 Coliseum Way',city:'Oakland',state:'CA',team:'oak') 26 | stadiums << new Stadium(name:'Citizens Bank Park',street:'One Citizens Bank Way',city:'Philadelphia',state:'PA',team:'phi') 27 | stadiums << new Stadium(name:'PNC Park',street:'115 Federal Street',city:'Pittsburgh',state:'PA',team:'pit') 28 | stadiums << new Stadium(name:'PETCO Park',street:'19 Tony Gwynn Drive',city:'San Diego',state:'CA',team:'sdn') 29 | stadiums << new Stadium(name:'Safeco Field',street:'1516 First Avenue S',city:'Seattle',state:'WA',team:'sea') 30 | stadiums << new Stadium(name:'AT&T Park',street:'24 Willie Mays Plaza',city:'San Francisco',state:'CA',team:'sfn') 31 | stadiums << new Stadium(name:'Busch Stadium',street:'700 Clark Avenue',city:'St. Louis',state:'MO',team:'sln') 32 | stadiums << new Stadium(name:'Tropicana Field',street:'One Tropicana Drive',city:'St. Petersburg',state:'FL',team:'tba') 33 | stadiums << new Stadium(name:'Rangers Ballpark in Arlington',street:'Ballpark Way',city:'Arlington',state:'TX',team:'tex') 34 | stadiums << new Stadium(name:'Rogers Centre',street:'One Blue Jays Way',city:'Toronto',state:'ON',team:'tor') 35 | stadiums << new Stadium(name:'Nationals Park',street:'1500 South Capitol Street SE',city:'Washington',state:'DC',team:'was') 36 | 37 | Sql db = Sql.newInstance( 38 | url:'jdbc:h2:./build/baseball',driver:'org.h2.Driver') 39 | 40 | db.execute "drop table if exists stadium;" 41 | db.execute ''' 42 | create table stadium( 43 | id int not null auto_increment, 44 | name varchar(200) not null, 45 | team char(3) not null, 46 | latitude double, 47 | longitude double, 48 | primary key(id) 49 | ); 50 | ''' 51 | 52 | Geocoder geo = new Geocoder() 53 | stadiums.each { s -> 54 | geo.fillInLatLng(s) 55 | sleep(50) 56 | println s 57 | db.execute """ 58 | insert into stadium(name,team,latitude,longitude) 59 | values(${s.name},${s.team},${s.latitude},${s.longitude}); 60 | """ 61 | } 62 | 63 | assert db.rows('select * from stadium').size() == stadiums.size() 64 | db.eachRow('select latitude,longitude from stadium') { row -> 65 | assert row.latitude > 25 && row.latitude < 48 66 | assert row.longitude > -123 && row.longitude < -71 67 | } 68 | 69 | db.close() 70 | -------------------------------------------------------------------------------- /src/main/groovy/groovystrings/strings.groovy: -------------------------------------------------------------------------------- 1 | /* =================================================== 2 | * Copyright 2012 Kousen IT, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * ========================================================== */ 16 | package groovystrings 17 | 18 | def s = 'this is a string' 19 | assert s.class == java.lang.String 20 | 21 | def gs = "this might be a GString" 22 | assert gs.class == java.lang.String 23 | assert !(gs instanceof GString) 24 | 25 | gs = "If I put in a placeholder, this really is a GString: ${1+1}" 26 | assert gs instanceof GString 27 | 28 | def ss = /This is a slashy string/ 29 | assert ss.class == java.lang.String 30 | 31 | def picard = ''' 32 | (to the tune of Let It Snow) 33 | Oh the vacuum outside is endless 34 | Unforgiving, cold, and friendless 35 | But still we must boldly go 36 | Make it so, make it so, make it so! 37 | ''' 38 | 39 | String x = 'Hello' 40 | String y = x << ', World!' 41 | assert y == 'Hello, World!' 42 | 43 | def palindromes = 44 | '''Madam, in Eden, I'm Adam 45 | Sex at noon taxes 46 | Flee to me, remote elf!''' 47 | 48 | palindromes.eachLine { 49 | String str = it.replaceAll(/\W/,'').toLowerCase() 50 | // println str 51 | assert str.reverse() == str 52 | } 53 | 54 | def quote = """ 55 | There are ${Integer.toBinaryString(2)} kinds of people in the world: 56 | Those who know binary, and those who don't 57 | """ 58 | assert quote == ''' 59 | There are 10 kinds of people in the world: 60 | Those who know binary, and those who don't 61 | ''' -------------------------------------------------------------------------------- /src/main/groovy/hello_world.groovy: -------------------------------------------------------------------------------- 1 | /* =================================================== 2 | * Copyright 2012 Kousen IT, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * ========================================================== */ 16 | println 'Hello, World!' -------------------------------------------------------------------------------- /src/main/groovy/intro/hello_world.groovy: -------------------------------------------------------------------------------- 1 | package intro 2 | 3 | println 'Hello, World!' 4 | println('Hello, World!') 5 | 6 | assert 5 == Math.max(3,5) 7 | assert(5 == Math.max(3,5)) 8 | -------------------------------------------------------------------------------- /src/main/groovy/intro/numbers.groovy: -------------------------------------------------------------------------------- 1 | /* =================================================== 2 | * Copyright 2012 Kousen IT, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * ========================================================== */ 16 | package intro 17 | 18 | assert(1 + 2 == 3) 19 | assert(3 - 2 == 1) 20 | assert 4 * 5 == 20 21 | assert 10/2 == 5 22 | assert 10/4 == 2.5 23 | assert 2**3 == 8 24 | assert 2**-2 == 0.25 // i.e., 1/(2*2) = 1/4 25 | 26 | assert 3 == 1.plus(2) 27 | assert 1 == 3.minus(2) 28 | assert 20 == 4.multiply(5) 29 | assert 5 == 10.div(2) 30 | assert 1 == 10.mod(3) 31 | 32 | assert 5 > 3 33 | assert 4 >= 4 34 | assert 3 < 5 35 | assert 3 <= 6 36 | assert 7 == 7 37 | assert 7 != 8 38 | 39 | def i = 1 40 | assert 1 == i++ 41 | assert 3 == ++i 42 | 43 | def x = "" 44 | // x += "Hello" same as x = x + "Hello" 45 | 3.times { x += "Hello" } 46 | assert x == "HelloHelloHello" 47 | 48 | 3.times({x += "Hello"}) 49 | 3.times() { x += "Hello" } 50 | 51 | def total = 0 52 | 1.upto(3) { total += it } 53 | assert total == 1 + 2 + 3 54 | 55 | def countDown = [] 56 | 5.downto 1, { countDown << "$it ..." } 57 | assert countDown == ['5 ...', '4 ...', '3 ...', '2 ...', '1 ...'] 58 | 59 | def odds = [] 60 | (1..10).step(2) { odds << it } 61 | assert odds == [1, 3, 5, 7, 9] 62 | -------------------------------------------------------------------------------- /src/main/groovy/io/SumNumbers.java: -------------------------------------------------------------------------------- 1 | /* =================================================== 2 | * Copyright 2012 Kousen IT, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * ========================================================== */ 16 | package io; 17 | 18 | import java.io.BufferedReader; 19 | import java.io.IOException; 20 | import java.io.InputStreamReader; 21 | 22 | public class SumNumbers { 23 | public static void main(String[] args) { 24 | System.out.println("Please enter numbers to sum"); 25 | BufferedReader br = 26 | new BufferedReader(new InputStreamReader(System.in)); 27 | String line = ""; 28 | try { 29 | line = br.readLine(); 30 | } catch (IOException e) { 31 | e.printStackTrace(); 32 | } 33 | String[] inputs = line.split(" "); 34 | double total = 0.0; 35 | for (String s : inputs) { 36 | total += Double.parseDouble(s); 37 | } 38 | System.out.println("The sum is " + total); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/groovy/io/data.txt: -------------------------------------------------------------------------------- 1 | 1,2,3 2 | a,b,c 3 | -------------------------------------------------------------------------------- /src/main/groovy/io/files.groovy: -------------------------------------------------------------------------------- 1 | /* =================================================== 2 | * Copyright 2012 Kousen IT, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * ========================================================== */ 16 | package io 17 | 18 | def files = [] 19 | new File('.').eachFileRecurse { file -> 20 | if (file.name.endsWith('.groovy')) { 21 | files << file 22 | } 23 | } 24 | assert files 25 | println "There are ${files.size()} groovy files" 26 | 27 | def base = 'src/main/groovy/io' 28 | 29 | String data = new File(base + '/files.groovy').text 30 | assert data.contains('text') 31 | 32 | List lines = new File("$base/files.groovy").readLines()*.trim() 33 | assert lines[15] == "package io" 34 | 35 | lines.reverse().each { println it } 36 | 37 | List dataLines = [] 38 | new File("$base/data.txt").splitEachLine(',') { 39 | dataLines << it 40 | } 41 | assert dataLines == [['1','2','3'],['a','b','c']] 42 | 43 | 44 | File f = new File("$base/output.dat") 45 | f.write('Hello, Groovy!') 46 | 47 | assert f.text == 'Hello, Groovy!' 48 | f.delete() 49 | 50 | File temp = new File("$base/temp.txt") 51 | 52 | // Don't really need parens here, so why use them? 53 | temp.write 'Groovy Kind of Love' 54 | assert temp.readLines().size() == 1 55 | 56 | // Need to start with a carriage return 57 | temp.append "\nGroovin', on a Sunday afternoon..." 58 | 59 | // Note use of overloaded << operator 60 | temp << "\nFeelin' Groovy" 61 | assert temp.readLines().size() == 3 62 | temp.delete() -------------------------------------------------------------------------------- /src/main/groovy/io/sum_numbers.groovy: -------------------------------------------------------------------------------- 1 | /* =================================================== 2 | * Copyright 2012 Kousen IT, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * ========================================================== */ 16 | package io 17 | 18 | println 'Please enter some numbers' 19 | System.in.withReader { br -> 20 | println br.readLine().tokenize()*.toBigDecimal().sum() 21 | } 22 | -------------------------------------------------------------------------------- /src/main/groovy/io/sum_numbers_loop.groovy: -------------------------------------------------------------------------------- 1 | /* =================================================== 2 | * Copyright 2012 Kousen IT, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * ========================================================== */ 16 | package io 17 | 18 | println 'Sum numbers with looping' 19 | System.in.eachLine { line -> 20 | if (!line) System.exit(0) 21 | println line.split(' ')*.toBigDecimal().sum() 22 | } 23 | 24 | -------------------------------------------------------------------------------- /src/main/groovy/json/Model.groovy: -------------------------------------------------------------------------------- 1 | package json 2 | 3 | import groovy.transform.Canonical 4 | 5 | @Canonical 6 | class Model { 7 | String type 8 | Value value 9 | } 10 | 11 | @Canonical 12 | class Value { 13 | int id 14 | String joke 15 | String[] categories 16 | } 17 | -------------------------------------------------------------------------------- /src/main/groovy/json/chuck_norris.groovy: -------------------------------------------------------------------------------- 1 | package json 2 | 3 | import groovy.json.JsonSlurper 4 | 5 | String base = 'http://api.icndb.com/jokes/random?' 6 | String qs = 7 | [limitTo: ['nerdy'], firstName: 'Bobbi', lastName: 'Lucas'] 8 | .collect { k,v -> "$k=$v" } 9 | .join('&') 10 | String jsonTxt = "$base$qs".toURL().text 11 | def json = new JsonSlurper().parseText(jsonTxt) 12 | println json?.value?.joke 13 | -------------------------------------------------------------------------------- /src/main/groovy/json/cn_ratpack.groovy: -------------------------------------------------------------------------------- 1 | /* =================================================== 2 | * Copyright 2012 Kousen IT, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * ========================================================== */ 16 | package json 17 | 18 | import groovy.json.JsonSlurper 19 | 20 | def url = 'http://localhost:5050' 21 | 22 | def json = new JsonSlurper().parseText(url.toURL().text) 23 | println json?.joke 24 | -------------------------------------------------------------------------------- /src/main/groovy/json/gson_demo.groovy: -------------------------------------------------------------------------------- 1 | package json 2 | 3 | import com.google.gson.Gson 4 | 5 | String base = 'http://api.icndb.com/jokes/random?' 6 | def qs = [limitTo: ['nerdy'], firstName: 'Guillaume', 7 | lastName: 'Laforge'].collect { k,v -> "$k=$v" }.join('&') 8 | String jsonTxt = "$base$qs".toURL().text 9 | 10 | Gson gson = new Gson() 11 | Model model = gson.fromJson(jsonTxt, Model) 12 | println model 13 | println model.value.joke -------------------------------------------------------------------------------- /src/main/groovy/metaprogramming/CustomLevel.groovy: -------------------------------------------------------------------------------- 1 | /* =================================================== 2 | * Copyright 2012 Kousen IT, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * ========================================================== */ 16 | package metaprogramming 17 | 18 | import groovy.transform.InheritConstructors; 19 | 20 | import java.util.logging.Level; 21 | 22 | @InheritConstructors 23 | class CustomLevel extends Level { 24 | } 25 | -------------------------------------------------------------------------------- /src/main/groovy/metaprogramming/LocalDate_demo.groovy: -------------------------------------------------------------------------------- 1 | package metaprogramming 2 | 3 | import java.time.LocalDate 4 | import java.time.Month 5 | import java.time.temporal.ChronoUnit 6 | 7 | LocalDate.metaClass.minus = { LocalDate date -> 8 | date.until(delegate, ChronoUnit.DAYS) 9 | } 10 | 11 | LocalDate electionDay = LocalDate.of(2016, Month.NOVEMBER, 8) 12 | LocalDate today = LocalDate.now() 13 | 14 | println "${electionDay - today} days to go" -------------------------------------------------------------------------------- /src/main/groovy/metaprogramming/complex_numbers.groovy: -------------------------------------------------------------------------------- 1 | package metaprogramming 2 | 3 | import static org.apache.commons.math3.complex.Complex.* 4 | import static java.lang.Math.* 5 | 6 | import org.apache.commons.math3.complex.* 7 | 8 | Complex lhs = new Complex(1.0, 3.0); 9 | Complex rhs = new Complex(2.0, 5.0); 10 | 11 | assert lhs.multiply(rhs) == lhs * rhs 12 | println lhs * rhs 13 | println "$lhs == ($lhs.real, $lhs.imaginary)" 14 | 15 | ComplexFormat fmt = new ComplexFormat() 16 | println fmt.format(lhs) 17 | println fmt.format(rhs) 18 | 19 | Complex.metaClass.plus = { Complex c -> delegate.add c } 20 | Complex.metaClass.minus = { Complex c -> delegate.subtract c } 21 | Complex.metaClass.div = { Complex c -> delegate.divide c } 22 | Complex.metaClass.power = { Complex c -> delegate.pow c } 23 | Complex.metaClass.negative = { delegate.negate() } 24 | assert new Complex(3.0, 8.0) == lhs + rhs 25 | assert new Complex(1.0, 2.0) == rhs - lhs 26 | assert new Complex(0.5862068965517241, 0.03448275862068969) == lhs / rhs 27 | assert new Complex(-0.007563724861696302, 0.01786136835085382) == lhs ** rhs 28 | assert new Complex(-1.0, -3.0) == -lhs 29 | 30 | Double.metaClass.power = { Complex c -> (new Complex(delegate,0)).pow(c) } 31 | 32 | println fmt.format( ( I * PI ).exp() ) 33 | println fmt.format( new Complex(E, 0) ** (I * PI) ) 34 | println fmt.format( E ** (I * PI) ) 35 | assert (E ** (I * PI)).real == -1 36 | assert (E ** (I * PI)).imaginary < 1.0e-15 -------------------------------------------------------------------------------- /src/main/groovy/metaprogramming/currency_category.groovy: -------------------------------------------------------------------------------- 1 | package metaprogramming 2 | 3 | import java.text.NumberFormat; 4 | 5 | class CurrencyCategory { 6 | static String asCurrency(Number amount) { 7 | NumberFormat.currencyInstance.format(amount) 8 | } 9 | 10 | static String asCurrency(Number amount, Locale loc) { 11 | NumberFormat.getCurrencyInstance(loc).format(amount) 12 | } 13 | } 14 | 15 | use(CurrencyCategory) { 16 | def amount = 1234567.890123 17 | println amount.asCurrency() 18 | println amount.asCurrency(Locale.FRANCE) 19 | println amount.asCurrency(new Locale('hin','IN')) 20 | println amount.asCurrency(new Locale('da','DK')) 21 | } 22 | 23 | //12345.asCurrency() 24 | -------------------------------------------------------------------------------- /src/main/groovy/metaprogramming/expando_demo.groovy: -------------------------------------------------------------------------------- 1 | package metaprogramming 2 | 3 | Expando ex = new Expando() 4 | ex.name = 'Fido' 5 | ex.speak = { println "$name says Woof!" } 6 | ex.speak() 7 | 8 | class Cat {} 9 | Cat.metaClass.name = 'Garfield' 10 | Cat.metaClass.says = 'wants lasagna' 11 | Cat.metaClass.speak { println "$name $says" } 12 | Cat c = new Cat() 13 | c.speak() 14 | 15 | c.name = 'Fluffy' 16 | c.says = 'meow' 17 | c.speak() -------------------------------------------------------------------------------- /src/main/groovy/metaprogramming/print_currency.groovy: -------------------------------------------------------------------------------- 1 | package metaprogramming 2 | 3 | import java.text.NumberFormat; 4 | 5 | Number.metaClass.asCurrency = { -> 6 | NumberFormat nf = NumberFormat.getCurrencyInstance() 7 | nf.format(delegate) 8 | } 9 | 10 | Number.metaClass.asCurrency = { Locale loc -> 11 | NumberFormat nf = NumberFormat.getCurrencyInstance(loc) 12 | nf.format(delegate) 13 | } 14 | 15 | 16 | def amount = 123456.7890 17 | Locale.default = Locale.US 18 | assert amount.asCurrency() == '$123,456.79' 19 | assert amount.asCurrency(Locale.FRANCE) == 20 | NumberFormat.getCurrencyInstance(Locale.FRANCE).format(amount) 21 | println amount.asCurrency() 22 | println amount.asCurrency(Locale.FRANCE) -------------------------------------------------------------------------------- /src/main/groovy/metaprogramming/use_emc.groovy: -------------------------------------------------------------------------------- 1 | package metaprogramming 2 | 3 | import java.util.logging.* 4 | 5 | // Intercept (using methodMissing) 6 | Logger.metaClass.methodMissing = { String name, args -> 7 | println "inside methodMissing with $name" 8 | int val = Level.WARNING.intValue() + 9 | (Level.SEVERE.intValue() - Level.WARNING.intValue()) * Math.random() 10 | def level = new CustomLevel(name.toUpperCase(),val) 11 | def impl = { Object... varArgs -> 12 | delegate.log(level,varArgs[0]) 13 | } 14 | // Cache the implementation on the metaClass 15 | Logger.metaClass."$name" = impl 16 | 17 | // Invoke the new implementation 18 | impl(args) 19 | } 20 | 21 | 22 | Logger log = Logger.getLogger(this.class.name) 23 | log.wtf 'no effin way' 24 | log.whoa 'dude, seriously' 25 | log.rofl "you're kidding, right?" 26 | log.rofl 'rolling on the floor laughing' 27 | log.whatever 'heavy sigh' 28 | log.sleeping('goodnight') -------------------------------------------------------------------------------- /src/main/groovy/metaprogramming/use_slang_category.groovy: -------------------------------------------------------------------------------- 1 | package metaprogramming 2 | 3 | import java.util.logging.Level; 4 | import java.util.logging.Logger 5 | 6 | class SlangCategory { 7 | static String fyi(Logger self, String msg) { 8 | return self.log(new CustomLevel('FYI',Level.INFO.intValue()),msg) 9 | } 10 | static String lol(Logger self, String msg) { 11 | return self.log(new CustomLevel('LOL',Level.WARNING.intValue()),msg) 12 | } 13 | } 14 | 15 | Logger log = Logger.getLogger(this.class.name) 16 | use(SlangCategory) { 17 | log.fyi 'this seems okay' 18 | log.lol('snicker') 19 | } -------------------------------------------------------------------------------- /src/main/groovy/metaprogramming/without_custom_levels.groovy: -------------------------------------------------------------------------------- 1 | package metaprogramming 2 | 3 | import java.util.logging.Logger 4 | 5 | Logger.metaClass.fyi = { msg -> delegate.info msg } 6 | Logger.metaClass.omg = { msg -> delegate.severe msg } 7 | 8 | Logger log = Logger.getLogger(this.class.name) 9 | log.fyi 'for your information' 10 | log.omg 'oh my goodness' 11 | -------------------------------------------------------------------------------- /src/main/groovy/misc/Jumble.groovy: -------------------------------------------------------------------------------- 1 | package misc 2 | 3 | import groovy.transform.CompileStatic 4 | 5 | @CompileStatic 6 | class Jumble1 { 7 | private List wordList = 8 | new File('/usr/share/dict/words').readLines() 9 | .findAll { it.size() == 5 || it.size() == 6 } 10 | 11 | String solve(String clue) { 12 | List letters = clue.split('').toList() 13 | letters.permutations() 14 | .collect { it.join('') } 15 | .find { wordList.contains(it) } 16 | } 17 | } 18 | 19 | @CompileStatic 20 | class Jumble2 { 21 | private Map> wordMap = 22 | new File('/usr/share/dict/words').readLines() 23 | .findAll {it.size() == 5 || it.size() == 6 } 24 | .groupBy { it.toList().sort().join('') } 25 | 26 | String solve(String clue) { 27 | def key = clue.toList().sort().join('') 28 | wordMap[key].head() 29 | } 30 | } 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /src/main/groovy/pogos/groovy/Task.groovy: -------------------------------------------------------------------------------- 1 | package pogos.groovy 2 | 3 | import groovy.transform.Canonical 4 | 5 | import java.time.LocalDate 6 | 7 | @Canonical 8 | class Task { 9 | String name 10 | int priority 11 | LocalDate startDate 12 | LocalDate endDate 13 | boolean completed 14 | } 15 | -------------------------------------------------------------------------------- /src/main/groovy/pogos/java/Task.java: -------------------------------------------------------------------------------- 1 | package pogos.java; 2 | 3 | import java.time.LocalDate; 4 | 5 | public class Task { 6 | private String name; 7 | private int priority; 8 | private LocalDate startDate; 9 | private LocalDate endDate; 10 | private boolean completed; 11 | 12 | public String getName() { 13 | return name; 14 | } 15 | 16 | public void setName(String name) { 17 | this.name = name; 18 | } 19 | 20 | public int getPriority() { 21 | return priority; 22 | } 23 | 24 | public void setPriority(int priority) { 25 | this.priority = priority; 26 | } 27 | 28 | public LocalDate getStartDate() { 29 | return startDate; 30 | } 31 | 32 | public void setStartDate(LocalDate startDate) { 33 | this.startDate = startDate; 34 | } 35 | 36 | public LocalDate getEndDate() { 37 | return endDate; 38 | } 39 | 40 | public void setEndDate(LocalDate endDate) { 41 | this.endDate = endDate; 42 | } 43 | 44 | public boolean isCompleted() { 45 | return completed; 46 | } 47 | 48 | public void setCompleted(boolean completed) { 49 | this.completed = completed; 50 | } 51 | 52 | @Override 53 | public boolean equals(Object o) { 54 | if (this == o) return true; 55 | if (o == null || getClass() != o.getClass()) return false; 56 | 57 | Task task = (Task) o; 58 | 59 | if (priority != task.priority) return false; 60 | if (completed != task.completed) return false; 61 | if (name != null ? !name.equals(task.name) : task.name != null) return false; 62 | if (startDate != null ? !startDate.equals(task.startDate) : task.startDate != null) return false; 63 | return !(endDate != null ? !endDate.equals(task.endDate) : task.endDate != null); 64 | 65 | } 66 | 67 | @Override 68 | public int hashCode() { 69 | int result = name != null ? name.hashCode() : 0; 70 | result = 31 * result + priority; 71 | result = 31 * result + (startDate != null ? startDate.hashCode() : 0); 72 | result = 31 * result + (endDate != null ? endDate.hashCode() : 0); 73 | result = 31 * result + (completed ? 1 : 0); 74 | return result; 75 | } 76 | 77 | @Override 78 | public String toString() { 79 | return "Task{" + 80 | "name='" + name + '\'' + 81 | ", priority=" + priority + 82 | ", startDate=" + startDate + 83 | ", endDate=" + endDate + 84 | ", completed=" + completed + 85 | '}'; 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/main/groovy/precision_groovy.groovy: -------------------------------------------------------------------------------- 1 | /* =================================================== 2 | * Copyright 2012 Kousen IT, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * ========================================================== */ 16 | total = 0.0 17 | (0..9).each { total += 0.1 } 18 | assert total == 1.0 -------------------------------------------------------------------------------- /src/main/groovy/regex/regular_expressions.groovy: -------------------------------------------------------------------------------- 1 | /* =================================================== 2 | * Copyright 2012 Kousen IT, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * ========================================================== */ 16 | package regex 17 | 18 | ['bab','bcb','bdb'].each { assert it ==~ /b.b/ } 19 | ['bab','bcb','bdb'].each { assert it ==~ /b[acd]b/ } 20 | 21 | ['bbb','bcb','bdb'].each { assert it ==~ /b[^aeiou]b/ } 22 | 23 | def pattern = /[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]/ 24 | (-10..<0).each { assert !(it ==~ pattern) } 25 | (0..255).each { assert it ==~ pattern } 26 | (256..300).each { assert !(it ==~ pattern) } 27 | 28 | 29 | // yyyy-MM-dd, yyyy/MM/dd s.t. 30 | // yyyy is 19xx or 20xx 31 | // MM is 01..12 32 | // dd is 01..31 33 | pattern = /(19|20)\d{2}[-\/](0[0-9]|1[0-2])[-\/](0[1-9]|[12]\d|3[01])/ 34 | def c = Calendar.instance 35 | c.set(1899,10,30) 36 | Date testStart = c.time 37 | c.set(2100,1,1) 38 | Date testEnd = c.time 39 | c.set(1900,0,1) 40 | Date rangeStart = c.time 41 | c.set(2099,11,31) 42 | Date rangeEnd = c.time 43 | def sdf1 = new java.text.SimpleDateFormat("yyyy-MM-dd") 44 | def sdf2 = new java.text.SimpleDateFormat("yyyy/MM/dd") 45 | (testStart..testEnd).each { date -> 46 | if (date < rangeStart || date > rangeEnd) { 47 | assert !(sdf1.format(date) ==~ pattern) 48 | assert !(sdf2.format(date) ==~ pattern) 49 | } else { 50 | assert sdf1.format(date) ==~ pattern 51 | assert sdf2.format(date) ==~ pattern 52 | } 53 | } 54 | 55 | 56 | def s = "now is is the the time" 57 | def match = s =~ /\b(\w+)\s\1\b/ 58 | (0.. println match[line][0] } 59 | s = 'aba abc abba baab' 60 | match = s =~ /\b(a)\w*\1\b/ 61 | (0.. println match[line][0] } 62 | -------------------------------------------------------------------------------- /src/main/groovy/sort_strings.groovy: -------------------------------------------------------------------------------- 1 | import java.util.stream.Collectors 2 | 3 | List strings = 'this is a list of strings'.split() 4 | println strings 5 | 6 | // Java has Collections.sort(list) (natural order) 7 | Collections.sort(strings) 8 | println strings 9 | 10 | // Java 8 has sorted() on Stream 11 | List sorted = strings.stream() 12 | .sorted() 13 | .collect(Collectors.toList()) 14 | println sorted 15 | 16 | sorted = strings.sort(false) 17 | println sorted 18 | 19 | // Two-param Groovy length sort 20 | sorted = strings.sort(false) { s1, s2 -> s1.size() - s2.size() } 21 | println sorted 22 | assert sorted*.size() == [1, 2, 2, 4, 4, 7] 23 | 24 | // One-param Groovy reverse length sort 25 | sorted = strings.sort(false) { -it.size() } 26 | println sorted 27 | assert sorted*.size() == [7, 4, 4, 2, 2, 1] 28 | 29 | // Java 8 30 | sorted = strings.stream() 31 | .sorted(Comparator.comparingInt({ it.size() }) 32 | .thenComparing(Comparator.naturalOrder())) 33 | .collect(Collectors.toList()) 34 | println sorted 35 | 36 | // Groovy sort by length, then equal lengths alphabetically 37 | sorted = strings.sort { s1, s2 -> 38 | s1.size() <=> s2.size() ?: s2 <=> s1 39 | } 40 | println sorted -------------------------------------------------------------------------------- /src/main/groovy/strategy/groovy/Multiplier.groovy: -------------------------------------------------------------------------------- 1 | /* =================================================== 2 | * Copyright 2012 Kousen IT, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * ========================================================== */ 16 | package strategy.groovy 17 | 18 | class Multiplier { 19 | def adder = { x,y -> 20 | def total = 0 21 | y.times { total += x } 22 | total 23 | } 24 | 25 | def multiplier = { x,y -> x*y } 26 | 27 | int multiply(x,y,Closure strategy) { 28 | strategy(x,y) 29 | } 30 | } -------------------------------------------------------------------------------- /src/main/groovy/strategy/java/AddStrategy.java: -------------------------------------------------------------------------------- 1 | /* =================================================== 2 | * Copyright 2012 Kousen IT, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * ========================================================== */ 16 | package strategy.java; 17 | 18 | 19 | public class AddStrategy implements Multiply { 20 | 21 | public int multiply(int x, int y) { 22 | int total = 0; 23 | for (int i = 0; i < y; i++) { 24 | total += x; 25 | } 26 | return total; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/main/groovy/strategy/java/Multiplier.java: -------------------------------------------------------------------------------- 1 | /* =================================================== 2 | * Copyright 2012 Kousen IT, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * ========================================================== */ 16 | package strategy.java; 17 | 18 | 19 | public class Multiplier { 20 | private Multiply strategy; 21 | 22 | public void setStrategy(Multiply strategy) { 23 | this.strategy = strategy; 24 | } 25 | 26 | public int multiply(int x, int y) { 27 | return strategy.multiply(x, y); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/groovy/strategy/java/Multiply.java: -------------------------------------------------------------------------------- 1 | /* =================================================== 2 | * Copyright 2012 Kousen IT, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * ========================================================== */ 16 | package strategy.java; 17 | 18 | public interface Multiply { 19 | int multiply(int x, int y); 20 | } 21 | -------------------------------------------------------------------------------- /src/main/groovy/strategy/java/TimesStrategy.java: -------------------------------------------------------------------------------- 1 | /* =================================================== 2 | * Copyright 2012 Kousen IT, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * ========================================================== */ 16 | package strategy.java; 17 | 18 | 19 | public class TimesStrategy implements Multiply { 20 | 21 | public int multiply(int x, int y) { 22 | return x*y; 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/main/groovy/strings.groovy: -------------------------------------------------------------------------------- 1 | String s = 'this is a sentence' 2 | println s.length() 3 | println s.size() 4 | assert s.length() == s.size() 5 | 6 | println s[0..3] // getAt(Range) 7 | println s[3..0] 8 | println s[-1..0] 9 | assert s[-1..0] == s.reverse() 10 | 11 | println s - 'is' - 'is' 12 | 13 | println 'abc' * 3 14 | // println 3 * 'abc' 15 | 16 | Date now = new Date() 17 | Date then = now + 3 18 | (now..then).each { 19 | println it.format('EEEE, MMMM dd, yyyy') 20 | } 21 | 22 | List strings = 'this is a list of strings'.split() 23 | println strings 24 | println strings.size() 25 | println strings*.size() 26 | println strings.collect { it.size() } 27 | println strings.collect { String str -> str.size() } -------------------------------------------------------------------------------- /src/main/groovy/xml/books.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | Groovy in Action 10 | Dierk Koenig 11 | 39.99 12 | 13 | 14 | Making Java Groovy 15 | Ken Kousen 16 | 35.99 17 | 18 | 19 | Griffon in Action 20 | Andres Almiray 21 | 35.99 22 | 23 | 24 | Grails in Action 25 | Glen Smith 26 | 27.50 27 | 28 | -------------------------------------------------------------------------------- /src/main/groovy/xml/books.xsd: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /src/main/groovy/xml/booksNS.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | Making Java Groovy 5 | Ken Kousen 6 | 35.99 7 | 8 | 9 | Groovy Recipes 10 | Scott Davis 11 | 34.95 12 | 13 | -------------------------------------------------------------------------------- /src/main/groovy/xml/booksWithDTD.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Groovy in Action 6 | Dierk Koenig 7 | 39.999 8 | 9 | 10 | Making Java Groovy 11 | Ken Kousen 12 | 35.99 13 | 14 | 15 | Griffon in Action 16 | Andres Almiray 17 | 35.99 18 | 19 | 20 | Grails in Action 21 | Glen Smith 22 | 27.50 23 | 24 | -------------------------------------------------------------------------------- /src/main/groovy/xml/library.dtd: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/main/groovy/xml/namespaces.groovy: -------------------------------------------------------------------------------- 1 | /* =================================================== 2 | * Copyright 2012 Kousen IT, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * ========================================================== */ 16 | package xml 17 | 18 | import groovy.xml.XmlParser 19 | import groovy.xml.XmlSlurper 20 | 21 | String fileName = 'src/main/groovy/xml/booksNS.xml' 22 | 23 | // XmlParser first 24 | def books = new XmlParser().parse(fileName) 25 | 26 | // Declare the namespaces 27 | def m = new groovy.xml.Namespace('urn:manning') 28 | def p = new groovy.xml.Namespace('urn:pragprog') 29 | 30 | // Access the titles with the namespace prefixes 31 | assert books.book[p.title].text() == "Groovy Recipes" 32 | assert books.book[m.title].text() == "Making Java Groovy" 33 | 34 | // Now the XmlSlurper 35 | books = new XmlSlurper().parse(fileName) 36 | 37 | // Can get something right away 38 | assert books.book.title == "Making Java GroovyGroovy Recipes" 39 | 40 | // Create a map of prefixes to namespaces 41 | def ns = [:] 42 | ns.m = "urn:manning" 43 | ns.p = "urn:pragprog" 44 | 45 | // equivalent to def ns = [m:'urn:manning',p:'urn:pragprog'] 46 | 47 | // Declare the map 48 | books.declareNamespace(ns) 49 | 50 | // Now access uses the prefix, but the colon 51 | // means we need quotes around the element names 52 | assert books.book['p:title'] == "Groovy Recipes" 53 | assert books.book['m:title'] == "Making Java Groovy" -------------------------------------------------------------------------------- /src/main/groovy/xml/parsing.groovy: -------------------------------------------------------------------------------- 1 | /* =================================================== 2 | * Copyright 2012 Kousen IT, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * ========================================================== */ 16 | package xml 17 | 18 | import groovy.xml.XmlParser 19 | import groovy.xml.XmlSlurper 20 | 21 | String fileName = 'src/main/groovy/xml/books.xml' 22 | def booksWithParser = new XmlParser().parse(fileName) 23 | def booksWithSlurper = new XmlSlurper().parse(fileName) 24 | 25 | assert booksWithParser.book.size() == 4 26 | assert booksWithSlurper.book.size() == 4 27 | 28 | assert booksWithParser.book[0].title.text() == "Groovy in Action" 29 | assert booksWithSlurper.book[0].title == "Groovy in Action" 30 | 31 | 32 | assert booksWithParser.book.find { 33 | it.@isbn == "9781935182948" 34 | }.title.text() == "Making Java Groovy" 35 | 36 | 37 | assert booksWithSlurper.book.find { 38 | it.@isbn == "9781935182948" 39 | }.title == "Making Java Groovy" 40 | 41 | 42 | def prices = [] 43 | booksWithParser.book.price.each { 44 | prices << it.text().toDouble() 45 | } 46 | assert prices == [39.99, 35.99, 35.99, 27.50] 47 | assert prices.sum() == 139.47 48 | 49 | prices = [] 50 | booksWithSlurper.book.price.each { 51 | prices << it.toDouble() 52 | } 53 | assert prices == [39.99, 35.99, 35.99, 27.50] 54 | assert prices.sum() == 139.47 55 | -------------------------------------------------------------------------------- /src/main/groovy/xml/sample_weather.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Yahoo! Weather - Sunnyvale, CA 5 | http://us.rd.yahoo.com/dailynews/rss/weather/Sunnyvale__CA/*http://weather.yahoo.com/forecast/USCA1116_f.html 6 | Yahoo! Weather for Sunnyvale, CA 7 | en-us 8 | Fri, 18 Dec 2009 9:38 am PST 9 | 60 10 | 11 | 12 | 13 | 14 | 15 | 16 | Yahoo! Weather 17 | 142 18 | 18 19 | http://weather.yahoo.com 20 | http://l.yimg.com/a/i/us/nws/th/main_142b.gif 21 | 22 | 23 | Conditions for Sunnyvale, CA at 9:38 am PST 24 | 37.37 25 | -122.04 26 | http://us.rd.yahoo.com/dailynews/rss/weather/Sunnyvale__CA/*http://weather.yahoo.com/forecast/USCA1116_f.html 27 | Fri, 18 Dec 2009 9:38 am PST 28 | 29 |
31 | Current Conditions:
32 | Mostly Cloudy, 50 F
33 |
Forecast:
34 | Fri - Partly Cloudy. High: 62 Low: 49
35 | Sat - Partly Cloudy. High: 65 Low: 49
36 |
37 | Full Forecast at Yahoo! Weather

38 | (provided by The Weather Channel)
39 | ]]>
40 | 41 | 42 | USCA1116_2009_12_18_9_38_PST 43 |
44 |
45 |
-------------------------------------------------------------------------------- /src/main/groovy/xml/validate.groovy: -------------------------------------------------------------------------------- 1 | /* =================================================== 2 | * Copyright 2012 Kousen IT, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * ========================================================== */ 16 | package xml 17 | 18 | import groovy.xml.XmlSlurper 19 | 20 | import javax.xml.XMLConstants 21 | import javax.xml.transform.stream.StreamSource 22 | import javax.xml.validation.Schema 23 | import javax.xml.validation.SchemaFactory 24 | import javax.xml.validation.Validator 25 | 26 | String base = 'src/main/groovy/xml' 27 | 28 | // validates against a DTD 29 | String fileName = "$base/booksWithDTD.xml" 30 | def root = new XmlSlurper(true,true).parse(fileName) 31 | 32 | // validates against a schema 33 | String file = "$base/books.xml" 34 | String xsd = "$base/books.xsd" 35 | SchemaFactory factory = 36 | SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI) 37 | Schema schema = factory.newSchema(new File(xsd)) 38 | Validator validator = schema.newValidator() 39 | validator.validate(new StreamSource(new FileReader(file))) -------------------------------------------------------------------------------- /src/main/groovy/xml/weather.groovy: -------------------------------------------------------------------------------- 1 | /* =================================================== 2 | * Copyright 2012 Kousen IT, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * ========================================================== */ 16 | package xml 17 | 18 | import groovy.xml.XmlSlurper 19 | 20 | url = 'http://weather.yahooapis.com/forecastrss?w=2480318' 21 | def root = new XmlSlurper().parse(url) 22 | println( root.channel.location.@city ) 23 | -------------------------------------------------------------------------------- /src/test/groovy/TaskTests.groovy: -------------------------------------------------------------------------------- 1 | import org.junit.Test 2 | 3 | import java.time.LocalDate 4 | 5 | class TaskTests { 6 | LocalDate now = LocalDate.now() 7 | Task t = new Task(name:'name', priority:3, 8 | startDate:now, endDate: now + 1, completed: true) 9 | 10 | @Test 11 | void testToString() { 12 | assert t.toString() == 13 | "Task [name=${t.name}, priority=${t.priority}, " + 14 | "startDate=$now, endDate=${now+1}, completed=${t.completed}]" 15 | } 16 | 17 | @Test 18 | void testGetAndSetName() { 19 | assert t.name == 'name' 20 | t.name = 'other' 21 | assert t.name == 'other' 22 | } 23 | 24 | @Test 25 | void testGetAndSetPriority() { 26 | assert t.priority == 3 27 | t.priority = 4 28 | assert t.priority == 4 29 | } 30 | 31 | @Test 32 | void testGetAndSetStartDate() { 33 | LocalDate now = LocalDate.now() 34 | assert (now >> t.startDate).days == 0 35 | t.startDate = now + 1 36 | assert (now >> t.startDate).days == 1 37 | } 38 | 39 | @Test 40 | void testGetAndSetEndDate() { 41 | LocalDate now = LocalDate.now() 42 | assert (now >> t.endDate).days == 1 43 | t.endDate = now + 2 44 | assert (now >> t.endDate).days == 2 45 | } 46 | 47 | @Test 48 | void testIsAndSetCompleted() { 49 | assert t.completed 50 | t.completed = false 51 | assert !t.completed 52 | } 53 | } -------------------------------------------------------------------------------- /src/test/groovy/ast/immutable/ImmutablePointSpec.groovy: -------------------------------------------------------------------------------- 1 | package ast.immutable 2 | 3 | import spock.lang.Specification 4 | 5 | class ImmutablePointSpec extends Specification { 6 | Point p = new Point(3, 4) 7 | 8 | def "can not change x"() { 9 | when: 10 | p.x = 5 11 | 12 | then: 13 | thrown(ReadOnlyPropertyException) 14 | } 15 | 16 | def "can not change y"() { 17 | when: 18 | p.y = 5 19 | 20 | then: 21 | thrown(ReadOnlyPropertyException) 22 | } 23 | 24 | def "can not change x directly"() { 25 | when: 26 | p.@x = 5 27 | 28 | then: 29 | def e = thrown(GroovyRuntimeException) 30 | e.message == "Cannot set the property 'x' because the backing field is final." 31 | } 32 | 33 | } 34 | 35 | -------------------------------------------------------------------------------- /src/test/groovy/ast/singleton/SingletonPointSpec.groovy: -------------------------------------------------------------------------------- 1 | /* =================================================== 2 | * Copyright 2012 Kousen IT, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * ========================================================== */ 16 | package ast.singleton 17 | 18 | import spock.lang.Specification; 19 | 20 | class SingletonPointSpec extends Specification { 21 | def "can't instantiate"() { 22 | when: new SingletonPoint(x:3,y:4) 23 | then: thrown(RuntimeException) 24 | } 25 | 26 | def "instance is not null"() { 27 | expect: SingletonPoint.instance 28 | } 29 | 30 | def "can change values"() { 31 | when: 32 | SingletonPoint.instance.x = 3 33 | SingletonPoint.instance.y = 4 34 | 35 | then: 36 | SingletonPoint.instance.x == 3 37 | SingletonPoint.instance.y == 4 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/test/groovy/collections/RangeSpec.groovy: -------------------------------------------------------------------------------- 1 | package collections 2 | 3 | import spock.lang.Specification 4 | import spock.lang.Unroll 5 | 6 | class RangeSpec extends Specification { 7 | private final static int MIN = 1 8 | private final static int MAX = 5 9 | 10 | @Unroll 11 | def 'value of #n between MIN and MAX'() { 12 | expect: 13 | new MyClass(p:n).validate() 14 | 15 | where: 16 | //n << new IntRange(MIN, MAX) 17 | //n << MIN..MAX 18 | n << (MIN..MAX) 19 | } 20 | 21 | class MyClass { 22 | int p 23 | 24 | boolean validate() { 25 | p in MIN..MAX 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/test/groovy/collections/WordCountGroovyTest.groovy: -------------------------------------------------------------------------------- 1 | /* =================================================== 2 | * Copyright 2012 Kousen IT, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * ========================================================== */ 16 | package collections 17 | 18 | class WordCountGroovyTest { 19 | def wcg = new WordCountGroovy() 20 | 21 | void testCountWords() { 22 | wcg.countWords() 23 | def count = wcg.getWordCount(); 24 | assert 2, count.get("an") 25 | assert 3, count.get("with") 26 | assert 8, count.get("and") 27 | 28 | println wcg.mostFrequent 29 | } 30 | } -------------------------------------------------------------------------------- /src/test/groovy/db/ProductDAOTest.java: -------------------------------------------------------------------------------- 1 | /* =================================================== 2 | * Copyright 2012 Kousen IT, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * ========================================================== */ 16 | package db; 17 | 18 | import org.junit.jupiter.api.BeforeEach; 19 | import org.junit.jupiter.api.Test; 20 | 21 | import static org.junit.jupiter.api.Assertions.assertAll; 22 | import static org.junit.jupiter.api.Assertions.assertEquals; 23 | 24 | public class ProductDAOTest { 25 | private ProductDAO dao; 26 | 27 | @BeforeEach 28 | public void setUpDatabase() { 29 | dao = new ProductDAO(); 30 | } 31 | 32 | @Test 33 | public void testGetAllProducts() { 34 | assertEquals(3, dao.getAllProducts().size()); 35 | } 36 | 37 | @Test 38 | public void testFindProductById() { 39 | Product p = dao.findProductById(1); 40 | assertAll( 41 | () -> assertEquals(1, p.getId()), 42 | () -> assertEquals("baseball", p.getName()) 43 | ); 44 | } 45 | 46 | @Test 47 | public void testInsertAndDeleteProduct() { 48 | assertEquals(3, dao.getAllProducts().size()); 49 | Product p = new Product(4,"soccer ball",16.99); 50 | dao.insertProduct(p); 51 | assertEquals(4, dao.getAllProducts().size()); 52 | dao.deleteProduct(4); 53 | assertEquals(3, dao.getAllProducts().size()); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/test/groovy/filter/FilterNumbersTest.groovy: -------------------------------------------------------------------------------- 1 | package filter 2 | 3 | import spock.lang.Specification 4 | 5 | class FilterNumbersTest extends Specification { 6 | FilterNumbers app = new FilterNumbers() 7 | 8 | def "find all positives out of a list of only positives"() { 9 | when: 10 | Collection positives = app.findPositives(3, 1, 4, 1, 5, 9) 11 | 12 | then: 13 | positives.every { it > 0 } 14 | } 15 | 16 | def "find all positives out of a list of only negatives"() { 17 | when: 18 | Collection positives = app.findPositives(-10..-1 as Integer[]) 19 | 20 | then: 21 | positives.every { it > 0 } 22 | } 23 | 24 | def "find all positives out of a list of positives and negatives"() { 25 | when: 26 | Collection positives = app.findPositives(-5..5 as Integer[]) 27 | 28 | then: 29 | positives.every { it > 0 } 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/test/groovy/geocoder/GeocoderIntegrationSpec.groovy: -------------------------------------------------------------------------------- 1 | /* =================================================== 2 | * Copyright 2012 Kousen IT, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * ========================================================== */ 16 | package geocoder 17 | 18 | import spock.lang.Ignore 19 | import spock.lang.Specification 20 | 21 | @Ignore("Must enable Billing on Google Cloud Platform") 22 | class GeocoderIntegrationSpec extends Specification { 23 | Stadium stadium 24 | Geocoder geocoderXml 25 | GeocoderJSON geocoderJson 26 | 27 | def setup() { 28 | stadium = new Stadium(street:'1600 Ampitheatre Parkway', 29 | city:'Mountain View',state:'CA') 30 | geocoderXml = new Geocoder() 31 | geocoderJson = new GeocoderJSON() 32 | } 33 | 34 | def "fill in lat,lng using XML parsing"() { 35 | given: 36 | def google_lat = 37.422 37 | def google_lng = -122.083 38 | 39 | when: 40 | geocoderXml.fillInLatLng(stadium) 41 | 42 | then: 43 | (stadium.latitude - google_lat).abs() < 0.01 44 | (stadium.longitude - google_lng).abs() < 0.01 45 | } 46 | 47 | def "fill in lat,lng using JSON parsing"() { 48 | given: 49 | def google_lat = 37.422 50 | def google_lng = -122.083 51 | 52 | when: 53 | geocoderJson.fillInLatLng(stadium) 54 | 55 | then: 56 | (stadium.latitude - google_lat).abs() < 0.01 57 | (stadium.longitude - google_lng).abs() < 0.01 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /src/test/groovy/geocoder/GeocoderUnitSpec.groovy: -------------------------------------------------------------------------------- 1 | /* =================================================== 2 | * Copyright 2012 Kousen IT, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * ========================================================== */ 16 | package geocoder 17 | 18 | import groovy.mock.interceptor.StubFor 19 | import groovy.xml.XmlSlurper 20 | import spock.lang.Specification 21 | 22 | class GeocoderUnitSpec extends Specification { 23 | Stadium stadium 24 | Geocoder geocoder 25 | String xml = ''' 26 | 27 | 28 | 37.422 29 | -122.083 30 | 31 | ''' 32 | 33 | 34 | def setup() { 35 | stadium = new Stadium(street:'1313 Mockingbird Lane', 36 | city:'New York',state:'NY') 37 | geocoder = new Geocoder() 38 | } 39 | 40 | def "check with stubbed XmlSlurper"() { 41 | given: 42 | // parse the text given above 43 | def root = new XmlSlurper().parseText(xml) 44 | 45 | // mock the slurper for the geocoder 46 | def stub = new StubFor(XmlSlurper) 47 | stub.demand.parse { root } 48 | 49 | when: 50 | stub.use { geocoder.fillInLatLng(stadium) } 51 | 52 | then: 53 | Math.abs(stadium.latitude - 37.422) < 0.01 54 | Math.abs(stadium.longitude - -122.083) < 0.01 55 | stub.verify() 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/test/groovy/geocoder/StadiumLocationsSpec.groovy: -------------------------------------------------------------------------------- 1 | /* =================================================== 2 | * Copyright 2012 Kousen IT, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * ========================================================== */ 16 | package geocoder 17 | 18 | import spock.lang.Ignore 19 | import spock.lang.Shared; 20 | import spock.lang.Specification; 21 | import spock.lang.Unroll; 22 | import groovy.sql.Sql 23 | 24 | @Ignore 25 | class StadiumLocationsSpec extends Specification { 26 | @Shared Sql db 27 | 28 | def setupSpec() { 29 | db = Sql.newInstance( 30 | 'jdbc:h2:./build/baseball;IFEXISTS=TRUE', 31 | 'org.h2.Driver') 32 | } 33 | 34 | @Unroll 35 | def "#name: #lat and #lng in range"() { 36 | expect: 37 | lat > 25 && lat < 48 38 | lng > -123 && lng < -71 39 | 40 | where: 41 | [name,lat,lng] << db.rows('select name,latitude,longitude from stadium') 42 | } 43 | 44 | def cleanupSpec() { 45 | db?.close() 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/test/groovy/json/ChuckNorrisScriptTests.groovy: -------------------------------------------------------------------------------- 1 | /* =================================================== 2 | * Copyright 2012 Kousen IT, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * ========================================================== */ 16 | package json 17 | 18 | import groovy.mock.interceptor.StubFor 19 | import org.junit.jupiter.api.Disabled 20 | import org.junit.jupiter.api.Test 21 | 22 | class ChuckNorrisScriptTests { 23 | String base = 'src/main/groovy' 24 | 25 | @Test @Disabled("Site may not be available") 26 | void testChuckNorrisOnline() { 27 | GroovyShell shell = new GroovyShell() 28 | shell.evaluate(new File("$base/json/chuck_norris.groovy")) 29 | } 30 | 31 | @Test 32 | void testChuckNorrisOffline() { 33 | def result = ''' 34 | { 35 | "value" : { 36 | "joke" : "Chuck Norris can make a method abstract AND final" 37 | } 38 | } 39 | ''' 40 | 41 | StubFor stub = new StubFor(URL) 42 | stub.demand.getText { result } 43 | 44 | stub.use { 45 | GroovyShell shell = new GroovyShell() 46 | shell.evaluate(new File("$base/json/chuck_norris.groovy")) 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/test/groovy/metaprogramming/ComplexSpec.groovy: -------------------------------------------------------------------------------- 1 | /* =================================================== 2 | * Copyright 2012 Kousen IT, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * ========================================================== */ 16 | package metaprogramming 17 | 18 | import static org.apache.commons.math3.complex.Complex.* 19 | import static java.lang.Math.* 20 | 21 | import org.apache.commons.math3.complex.* 22 | import spock.lang.Specification 23 | 24 | class ComplexSpec extends Specification { 25 | 26 | def setupSpec() { 27 | Complex.metaClass.plus = { Complex c -> delegate.add(c) } 28 | Complex.metaClass.minus = { Complex c -> delegate.subtract c } 29 | Complex.metaClass.div = { Complex c -> delegate.divide c } 30 | Complex.metaClass.power = { Complex c -> delegate.pow c } 31 | Complex.metaClass.negative = { delegate.negate() } 32 | Double.metaClass.power = { Complex c -> (new Complex(delegate,0)).pow(c) } 33 | } 34 | 35 | def "plus method aliased to add"() { 36 | given: 37 | Complex first = new Complex(1.0, 3.0); 38 | Complex second = new Complex(2.0, 5.0); 39 | 40 | expect: 41 | new Complex(3.0, 8.0) == first + second 42 | } 43 | 44 | def "minus method aliased to subtract"() { 45 | given: 46 | Complex first = new Complex(1.0, 3.0); 47 | Complex second = new Complex(2.0, 5.0); 48 | 49 | expect: 50 | new Complex(1.0, 2.0) == second - first 51 | } 52 | 53 | def "negative method negates complex"() { 54 | given: 55 | Complex minus1 = -ONE 56 | 57 | expect: 58 | minus1.real == -1 59 | minus1.imaginary.abs() == 0 60 | } 61 | 62 | def "Euler's formula still works"() { 63 | when: 64 | Complex result = E ** (I * PI) 65 | 66 | then: 67 | result.real == -1 68 | result.imaginary.abs() < 1e-15 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/test/groovy/metaprogramming/LoggingTests.groovy: -------------------------------------------------------------------------------- 1 | /* =================================================== 2 | * Copyright 2012 Kousen IT, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * ========================================================== */ 16 | package metaprogramming 17 | 18 | import groovy.test.GroovyLogTestCase; 19 | import metaprogramming.without_custom_levels 20 | import metaprogramming.use_slang_category 21 | import metaprogramming.use_emc 22 | 23 | import java.util.logging.Level; 24 | import java.util.logging.Logger; 25 | 26 | class LoggingTests extends GroovyLogTestCase { 27 | String baseDir = 'src/main/groovy/metaprogramming' 28 | 29 | void testWithoutCustomLevel() { 30 | def result = stringLog(Level.INFO, without_custom_levels.class.name) { 31 | GroovyShell shell = new GroovyShell() 32 | shell.evaluate(new File("$baseDir/without_custom_levels.groovy")) 33 | } 34 | assert result.contains('INFO: for your information') 35 | assert result.contains('SEVERE: oh my goodness') 36 | } 37 | 38 | void testSlangCategory() { 39 | def result = stringLog(Level.INFO, use_slang_category.class.name) { 40 | GroovyShell shell = new GroovyShell() 41 | shell.evaluate(new File("$baseDir/use_slang_category.groovy")) 42 | } 43 | assert result.contains('FYI: this seems okay') 44 | assert result.contains('LOL: snicker') 45 | } 46 | 47 | void testEMC() { 48 | def result = stringLog(Level.INFO, use_emc.class.name) { 49 | GroovyShell shell = new GroovyShell() 50 | shell.evaluate(new File("$baseDir/use_emc.groovy")) 51 | } 52 | assert result.contains('WTF: no effin way') 53 | assert result.contains('WHOA: dude, seriously') 54 | assert result.contains("ROFL: you're kidding, right?") 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /src/test/groovy/misc/JumbleSpec.groovy: -------------------------------------------------------------------------------- 1 | package misc 2 | 3 | 4 | import spock.lang.Requires 5 | import spock.lang.Specification 6 | import spock.lang.Unroll 7 | 8 | @Requires({ os.macOs }) 9 | class JumbleSpec extends Specification { 10 | 11 | @Unroll 12 | void "unscramble #scrambled to get #word"() { 13 | given: 14 | Jumble1 jumble1 = new Jumble1() 15 | Jumble2 jumble2 = new Jumble2() 16 | 17 | expect: 18 | jumble1.solve(scrambled) == word 19 | jumble2.solve(scrambled) == word 20 | 21 | where: 22 | scrambled || word 23 | 'cautla' || 'actual' 24 | 'agileo' || 'goalie' 25 | 'mmlueb' || 'mumble' 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/test/groovy/pogos/TaskTest.groovy: -------------------------------------------------------------------------------- 1 | package pogos 2 | 3 | import org.junit.jupiter.api.Test 4 | import pogos.groovy.Task 5 | 6 | import java.time.LocalDate 7 | 8 | class TaskTest { 9 | LocalDate now = LocalDate.now() 10 | LocalDate then = now + 1 // now.plus(1) 11 | Task t = new Task(name: 'name', priority: 3, 12 | startDate: now, endDate: then) 13 | 14 | @Test 15 | void testGetAndSetName() { 16 | assert t.name == 'name' 17 | t.name = 'other' 18 | assert t.name == 'other' 19 | } 20 | 21 | @Test 22 | void testGetAndSetPriority() { 23 | assert t.priority == 3 24 | t.priority = 4 25 | assert t.priority == 4 26 | } 27 | 28 | @Test 29 | void testEquality() { 30 | Task t1 = new Task(name: 'name', priority: 3, 31 | startDate: now, endDate: then) 32 | assert t == t1 33 | t1.completed = true 34 | assert !(t == t1) 35 | } 36 | 37 | @Test 38 | void testEqualsAndHashCode() { 39 | Task t1 = new Task(name: 'name', priority: 3, 40 | startDate: now, endDate: then) 41 | Set tasks = [t, t1] 42 | assert tasks.size() == 1 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/test/groovy/scripts/ScriptTests.groovy: -------------------------------------------------------------------------------- 1 | /* =================================================== 2 | * Copyright 2012 Kousen IT, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * ========================================================== */ 16 | package scripts 17 | 18 | import org.junit.jupiter.api.Test 19 | 20 | class ScriptTests { 21 | String baseDir = 'src/main/groovy/' 22 | GroovyShell shell = new GroovyShell() 23 | 24 | @Test 25 | void testClosures() { 26 | shell.evaluate(new File("$baseDir/closurespackage/closures.groovy")) 27 | } 28 | 29 | @Test 30 | void testCollections() { 31 | shell.evaluate(new File("$baseDir/collections/lists.groovy")) 32 | shell.evaluate(new File("$baseDir/collections/maps.groovy")) 33 | shell.evaluate(new File("$baseDir/collections/ranges.groovy")) 34 | } 35 | 36 | @Test 37 | void testConditionals() { 38 | shell.evaluate(new File("$baseDir/conditionals/conditionals.groovy")) 39 | shell.evaluate(new File("$baseDir/conditionals/loops.groovy")) 40 | } 41 | 42 | @Test 43 | void testNumbers() { 44 | shell.evaluate(new File("$baseDir/intro/numbers.groovy")) 45 | } 46 | 47 | @Test 48 | void testIo() { 49 | shell.evaluate(new File("$baseDir/io/files.groovy")) 50 | } 51 | 52 | @Test 53 | void testDb() { 54 | shell.evaluate(new File("$baseDir/db/products.groovy")) 55 | } 56 | 57 | @Test 58 | void testStrings() { 59 | shell.evaluate(new File("$baseDir/groovystrings/strings.groovy")) 60 | } 61 | 62 | @Test 63 | void testMetaprogramming() { 64 | shell.evaluate(new File("$baseDir/metaprogramming/print_currency.groovy")) 65 | } 66 | 67 | @Test 68 | void testXml() { 69 | shell.evaluate(new File("$baseDir/xml/parsing.groovy")) 70 | shell.evaluate(new File("$baseDir/xml/namespaces.groovy")) 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /src/test/groovy/simple/SimpleSpec.groovy: -------------------------------------------------------------------------------- 1 | package simple 2 | 3 | import spock.lang.Specification 4 | 5 | class SimpleSpec extends Specification { 6 | 7 | def 'there are four lights'() { 8 | expect: 9 | 2 + 2 == 4 10 | } 11 | 12 | def 'when I append to a list, the number of items goes up by 1'() { 13 | given: 14 | def list = [1, 2, 3] 15 | // def originalSize = list.size() 16 | 17 | when: 18 | list << 4 19 | 20 | then: 21 | list.size() == old(list.size()) + 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/test/groovy/strategy/groovy/MultiplierTest.groovy: -------------------------------------------------------------------------------- 1 | /* =================================================== 2 | * Copyright 2012 Kousen IT, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * ========================================================== */ 16 | package strategy.groovy 17 | 18 | import groovy.test.GroovyTestCase 19 | import strategy.groovy.Multiplier; 20 | 21 | class MultiplierTest extends GroovyTestCase { 22 | Multiplier m 23 | 24 | void setUp() { 25 | m = new Multiplier() 26 | } 27 | 28 | void testAddStrategy() { 29 | def result = m.multiply(2,3,m.adder) 30 | assertEquals 6, result 31 | } 32 | 33 | void testTimesStrategy() { 34 | def result = m.multiply(2,3,m.multiplier) 35 | assertEquals 6, result 36 | } 37 | 38 | void testAlternativeTimesStrategy() { 39 | assertEquals 6, m.multiply(2, 3) { x,y -> 40 | def total = 0 41 | x.times { total += y} 42 | total 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /src/test/groovy/strategy/java/MultiplierTest.java: -------------------------------------------------------------------------------- 1 | /* =================================================== 2 | * Copyright 2012 Kousen IT, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * ========================================================== */ 16 | package strategy.java; 17 | 18 | import strategy.java.AddStrategy; 19 | import strategy.java.Multiplier; 20 | import strategy.java.TimesStrategy; 21 | import junit.framework.TestCase; 22 | 23 | public class MultiplierTest extends TestCase { 24 | 25 | private Multiplier m; 26 | 27 | @Override 28 | protected void setUp() { 29 | m = new Multiplier(); 30 | } 31 | 32 | public void testAddMultiplier() { 33 | m.setStrategy(new AddStrategy()); 34 | assertEquals(6, m.multiply(2, 3)); 35 | } 36 | 37 | public void testTimesMultiplier() { 38 | m.setStrategy(new TimesStrategy()); 39 | assertEquals(6, m.multiply(2, 3)); 40 | } 41 | 42 | } 43 | --------------------------------------------------------------------------------