diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4f56dc1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,22 @@ +.DS_Store + +.idea +*.iml + +.gradle + +# Ignore Gradle GUI config +gradle-app.setting + +# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) +!gradle-wrapper.jar + +# Cache of project +.gradletasknamecache + +build +out +bin +.settings +.classpath +.project \ No newline at end of file diff --git a/Chapter_04/aop-aspectj/build.gradle b/Chapter_04/aop-aspectj/build.gradle new file mode 100644 index 0000000..4441039 --- /dev/null +++ b/Chapter_04/aop-aspectj/build.gradle @@ -0,0 +1,20 @@ +plugins { + id 'java' + id "aspectj.gradle" version "0.1.6" + id 'application' +} + +group 'com.whezh' +version '1.0-SNAPSHOT' + +sourceCompatibility = 1.8 + +repositories { + mavenCentral() +} + +dependencies { + compile "org.springframework:spring-context:${springVersion}" +} + +mainClassName = 'concert.Main' diff --git a/Chapter_04/aop-aspectj/gradle.properties b/Chapter_04/aop-aspectj/gradle.properties new file mode 100644 index 0000000..d51100e --- /dev/null +++ b/Chapter_04/aop-aspectj/gradle.properties @@ -0,0 +1,3 @@ +springVersion=4.0.7.RELEASE +systemRulesVersion=1.5.0 +aspectjVersion=1.8.5 \ No newline at end of file diff --git a/Chapter_04/aop-aspectj/gradle/wrapper/gradle-wrapper.jar b/Chapter_04/aop-aspectj/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..1948b90 Binary files /dev/null and b/Chapter_04/aop-aspectj/gradle/wrapper/gradle-wrapper.jar differ diff --git a/Chapter_04/aop-aspectj/gradle/wrapper/gradle-wrapper.properties b/Chapter_04/aop-aspectj/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..d2c45a4 --- /dev/null +++ b/Chapter_04/aop-aspectj/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.8-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/Chapter_04/aop-aspectj/gradlew b/Chapter_04/aop-aspectj/gradlew new file mode 100755 index 0000000..cccdd3d --- /dev/null +++ b/Chapter_04/aop-aspectj/gradlew @@ -0,0 +1,172 @@ +#!/usr/bin/env sh + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/Chapter_04/aop-aspectj/gradlew.bat b/Chapter_04/aop-aspectj/gradlew.bat new file mode 100644 index 0000000..f955316 --- /dev/null +++ b/Chapter_04/aop-aspectj/gradlew.bat @@ -0,0 +1,84 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/Chapter_04/aop-aspectj/settings.gradle b/Chapter_04/aop-aspectj/settings.gradle new file mode 100644 index 0000000..683c3ed --- /dev/null +++ b/Chapter_04/aop-aspectj/settings.gradle @@ -0,0 +1,2 @@ +rootProject.name = 'aop' + diff --git a/Chapter_04/aop-aspectj/src/main/java/concert/CriticAspect.aj b/Chapter_04/aop-aspectj/src/main/java/concert/CriticAspect.aj new file mode 100644 index 0000000..c51ce23 --- /dev/null +++ b/Chapter_04/aop-aspectj/src/main/java/concert/CriticAspect.aj @@ -0,0 +1,30 @@ +package concert; + +public aspect CriticAspect { + private CriticismEngine criticismEngine; + + pointcut performance():execution(* concert.Performance.perform(..)); + + pointcut construct():execution(concert.CriticismEngineImpl.new()); + + after():performance(){ + System.out.println(criticismEngine.getCriticism()); + } + + after():construct(){ + System.out.println("After Performance constructor"); + } + + + before():construct(){ + System.out.println("Before Performance constructor"); + } + + public CriticismEngine getCriticismEngine() { + return this.criticismEngine; + } + + public void setCriticismEngine(CriticismEngine criticismEngine) { + this.criticismEngine = criticismEngine; + } +} diff --git a/Chapter_04/aop-aspectj/src/main/java/concert/CriticismEngine.java b/Chapter_04/aop-aspectj/src/main/java/concert/CriticismEngine.java new file mode 100644 index 0000000..00ddc68 --- /dev/null +++ b/Chapter_04/aop-aspectj/src/main/java/concert/CriticismEngine.java @@ -0,0 +1,5 @@ +package concert; + +public interface CriticismEngine { + String getCriticism(); +} diff --git a/Chapter_04/aop-aspectj/src/main/java/concert/CriticismEngineImpl.java b/Chapter_04/aop-aspectj/src/main/java/concert/CriticismEngineImpl.java new file mode 100644 index 0000000..39ee348 --- /dev/null +++ b/Chapter_04/aop-aspectj/src/main/java/concert/CriticismEngineImpl.java @@ -0,0 +1,18 @@ +package concert; + +public class CriticismEngineImpl implements CriticismEngine { + private String[] criticismPool; + + public CriticismEngineImpl() { + } + + @Override + public String getCriticism() { + int i = (int) (Math.random() * criticismPool.length); + return criticismPool[i]; + } + + public void setCriticismPool(String[] criticismPool) { + this.criticismPool = criticismPool; + } +} diff --git a/Chapter_04/aop-aspectj/src/main/java/concert/Main.java b/Chapter_04/aop-aspectj/src/main/java/concert/Main.java new file mode 100644 index 0000000..4368b78 --- /dev/null +++ b/Chapter_04/aop-aspectj/src/main/java/concert/Main.java @@ -0,0 +1,13 @@ +package concert; + +import org.springframework.context.support.ClassPathXmlApplicationContext; + +public class Main { + public static void main(String[] args) { + ClassPathXmlApplicationContext context = + new ClassPathXmlApplicationContext("concert.xml"); + Performance performance = context.getBean(Performance.class); + performance.perform(); + context.close(); + } +} diff --git a/Chapter_04/aop-aspectj/src/main/java/concert/Music.java b/Chapter_04/aop-aspectj/src/main/java/concert/Music.java new file mode 100644 index 0000000..c1450bd --- /dev/null +++ b/Chapter_04/aop-aspectj/src/main/java/concert/Music.java @@ -0,0 +1,11 @@ +package concert; + +import org.springframework.stereotype.Component; + +@Component +public class Music implements Performance { + @Override + public void perform() { + System.out.println("Piano Solo"); + } +} diff --git a/Chapter_04/aop-aspectj/src/main/java/concert/Performance.java b/Chapter_04/aop-aspectj/src/main/java/concert/Performance.java new file mode 100644 index 0000000..19896c1 --- /dev/null +++ b/Chapter_04/aop-aspectj/src/main/java/concert/Performance.java @@ -0,0 +1,5 @@ +package concert; + +public interface Performance { + void perform(); +} diff --git a/Chapter_04/aop-aspectj/src/main/resources/concert.xml b/Chapter_04/aop-aspectj/src/main/resources/concert.xml new file mode 100644 index 0000000..ce98b19 --- /dev/null +++ b/Chapter_04/aop-aspectj/src/main/resources/concert.xml @@ -0,0 +1,21 @@ + + + + + + + + + Worst performance ever! + I laughed, I cried, then I realized I was at the wrong show. + A must see show! + + + + + + + + \ No newline at end of file diff --git a/Chapter_04/aop-xml/build.gradle b/Chapter_04/aop-xml/build.gradle new file mode 100644 index 0000000..02a6131 --- /dev/null +++ b/Chapter_04/aop-xml/build.gradle @@ -0,0 +1,20 @@ +plugins { + id 'java' +} + +group 'com.whezh' +version '1.0-SNAPSHOT' + +sourceCompatibility = 1.8 + +repositories { + mavenCentral() +} + +dependencies { + compile "org.springframework:spring-context:${springVersion}" + compile("org.aspectj:aspectjweaver:${aspectjVersion}") + + testCompile("org.springframework:spring-test:${springVersion}") + testCompile "com.github.stefanbirkner:system-rules:${systemRulesVersion}" +} diff --git a/Chapter_04/aop-xml/gradle.properties b/Chapter_04/aop-xml/gradle.properties new file mode 100644 index 0000000..d9d7004 --- /dev/null +++ b/Chapter_04/aop-xml/gradle.properties @@ -0,0 +1,3 @@ +springVersion=4.0.7.RELEASE +systemRulesVersion=1.5.0 +aspectjVersion=1.7.2 \ No newline at end of file diff --git a/Chapter_04/aop-xml/gradle/wrapper/gradle-wrapper.jar b/Chapter_04/aop-xml/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..1948b90 Binary files /dev/null and b/Chapter_04/aop-xml/gradle/wrapper/gradle-wrapper.jar differ diff --git a/Chapter_04/aop-xml/gradle/wrapper/gradle-wrapper.properties b/Chapter_04/aop-xml/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..d2c45a4 --- /dev/null +++ b/Chapter_04/aop-xml/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.8-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/Chapter_04/aop-xml/gradlew b/Chapter_04/aop-xml/gradlew new file mode 100755 index 0000000..cccdd3d --- /dev/null +++ b/Chapter_04/aop-xml/gradlew @@ -0,0 +1,172 @@ +#!/usr/bin/env sh + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/Chapter_04/aop-xml/gradlew.bat b/Chapter_04/aop-xml/gradlew.bat new file mode 100644 index 0000000..f955316 --- /dev/null +++ b/Chapter_04/aop-xml/gradlew.bat @@ -0,0 +1,84 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/Chapter_04/aop-xml/settings.gradle b/Chapter_04/aop-xml/settings.gradle new file mode 100644 index 0000000..683c3ed --- /dev/null +++ b/Chapter_04/aop-xml/settings.gradle @@ -0,0 +1,2 @@ +rootProject.name = 'aop' + diff --git a/Chapter_04/aop-xml/src/main/java/concert/Audience.java b/Chapter_04/aop-xml/src/main/java/concert/Audience.java new file mode 100644 index 0000000..3e3053e --- /dev/null +++ b/Chapter_04/aop-xml/src/main/java/concert/Audience.java @@ -0,0 +1,32 @@ +package concert; + +import org.aspectj.lang.ProceedingJoinPoint; + +public class Audience { + public void silenceCellPhone() { + System.out.println("Silencing cell phones"); + } + + public void takeSeats() { + System.out.println("Taking seats"); + } + + public void applause() { + System.out.println("CLAP CLAP CLAP!!!"); + } + + public void demandRefund() { + System.out.println("Demanding a refund"); + } + + public void watchPerformance(ProceedingJoinPoint jp) { + try { + System.out.println("Silencing cell phones"); + System.out.println("Taking seats"); + jp.proceed(); + System.out.println("CLAP CLAP CLAP!!!"); + } catch (Throwable e) { + System.out.println("Demanding a refund"); + } + } +} diff --git a/Chapter_04/aop-xml/src/main/java/concert/DefaultEncoreable.java b/Chapter_04/aop-xml/src/main/java/concert/DefaultEncoreable.java new file mode 100644 index 0000000..d06729e --- /dev/null +++ b/Chapter_04/aop-xml/src/main/java/concert/DefaultEncoreable.java @@ -0,0 +1,8 @@ +package concert; + +public class DefaultEncoreable implements Encoreable { + @Override + public void performEncore() { + System.out.println("Default encoreable"); + } +} diff --git a/Chapter_04/aop-xml/src/main/java/concert/Encoreable.java b/Chapter_04/aop-xml/src/main/java/concert/Encoreable.java new file mode 100644 index 0000000..822ad00 --- /dev/null +++ b/Chapter_04/aop-xml/src/main/java/concert/Encoreable.java @@ -0,0 +1,5 @@ +package concert; + +public interface Encoreable { + void performEncore(); +} diff --git a/Chapter_04/aop-xml/src/main/java/concert/Music.java b/Chapter_04/aop-xml/src/main/java/concert/Music.java new file mode 100644 index 0000000..719cf2c --- /dev/null +++ b/Chapter_04/aop-xml/src/main/java/concert/Music.java @@ -0,0 +1,8 @@ +package concert; + +public class Music implements Performance { + @Override + public void perform() { + System.out.println("Piano Solo"); + } +} diff --git a/Chapter_04/aop-xml/src/main/java/concert/Performance.java b/Chapter_04/aop-xml/src/main/java/concert/Performance.java new file mode 100644 index 0000000..19896c1 --- /dev/null +++ b/Chapter_04/aop-xml/src/main/java/concert/Performance.java @@ -0,0 +1,5 @@ +package concert; + +public interface Performance { + void perform(); +} diff --git a/Chapter_04/aop-xml/src/main/java/params/BlankDisc.java b/Chapter_04/aop-xml/src/main/java/params/BlankDisc.java new file mode 100644 index 0000000..8cf45f9 --- /dev/null +++ b/Chapter_04/aop-xml/src/main/java/params/BlankDisc.java @@ -0,0 +1,33 @@ +package params; + +import java.util.List; + +public class BlankDisc implements CompactDisc { + + private String title; + private String artist; + private List tracks; + + public void setTitle(String title) { + this.title = title; + } + + public void setArtist(String artist) { + this.artist = artist; + } + + public void setTracks(List tracks) { + this.tracks = tracks; + } + + public void play() { + System.out.println("Playing " + title + " by " + artist); + for (int i = 0; i < tracks.size(); i++) { + playTrack(i); + } + } + + public void playTrack(int track) { + System.out.println("-Track: " + tracks.get(track)); + } +} diff --git a/Chapter_04/aop-xml/src/main/java/params/CompactDisc.java b/Chapter_04/aop-xml/src/main/java/params/CompactDisc.java new file mode 100644 index 0000000..8bfab5f --- /dev/null +++ b/Chapter_04/aop-xml/src/main/java/params/CompactDisc.java @@ -0,0 +1,7 @@ +package params; + +public interface CompactDisc { + void play(); + + void playTrack(int track); +} diff --git a/Chapter_04/aop-xml/src/main/java/params/TrackCounter.java b/Chapter_04/aop-xml/src/main/java/params/TrackCounter.java new file mode 100644 index 0000000..8b8628b --- /dev/null +++ b/Chapter_04/aop-xml/src/main/java/params/TrackCounter.java @@ -0,0 +1,18 @@ +package params; + +import java.util.HashMap; +import java.util.Map; + +public class TrackCounter { + + private Map trackCounts = new HashMap<>(); + + public void countTrack(int trackNumber) { + int currentCount = getPlayCount(trackNumber); + trackCounts.put(trackNumber, currentCount + 1); + } + + public int getPlayCount(int trackNumber) { + return trackCounts.getOrDefault(trackNumber, 0); + } +} diff --git a/Chapter_04/aop-xml/src/main/resources/concert.xml b/Chapter_04/aop-xml/src/main/resources/concert.xml new file mode 100644 index 0000000..51364c6 --- /dev/null +++ b/Chapter_04/aop-xml/src/main/resources/concert.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Chapter_04/aop-xml/src/main/resources/params.xml b/Chapter_04/aop-xml/src/main/resources/params.xml new file mode 100644 index 0000000..9777a71 --- /dev/null +++ b/Chapter_04/aop-xml/src/main/resources/params.xml @@ -0,0 +1,40 @@ + + + + + + + Sgt. Pepper's Lonely Hearts Club Band + With a Little Help from My Friends + Lucy in the Sky with Diamonds + Getting Better + Fixing a Hole + She's Leaving Home + Being for the Benefit of Mr. Kite! + Within You Without You + When I'm Sixty-Four + Lovely Rita + Good Morning Good Morning + Sgt. Pepper's Lonely Hearts Club Band (Reprise) + A Day in the Life + + + + + + + + + + + + + \ No newline at end of file diff --git a/Chapter_04/aop-xml/src/test/java/concert/ConcertTest.java b/Chapter_04/aop-xml/src/test/java/concert/ConcertTest.java new file mode 100644 index 0000000..d777da1 --- /dev/null +++ b/Chapter_04/aop-xml/src/test/java/concert/ConcertTest.java @@ -0,0 +1,30 @@ +package concert; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.junit.contrib.java.lang.system.StandardOutputStreamLog; + +import static org.junit.Assert.assertEquals; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration("classpath:concert.xml") +public class ConcertTest { + @Rule + public final StandardOutputStreamLog log = new StandardOutputStreamLog(); + + @Autowired + private Performance performance; + + @Test + public void testPerformance() { + performance.perform(); + assertEquals("Silencing cell phones\n" + + "Taking seats\n" + + "Piano Solo\n" + + "CLAP CLAP CLAP!!!\n", log.getLog()); + } +} diff --git a/Chapter_04/aop-xml/src/test/java/concert/EncoreableTest.java b/Chapter_04/aop-xml/src/test/java/concert/EncoreableTest.java new file mode 100644 index 0000000..2b67902 --- /dev/null +++ b/Chapter_04/aop-xml/src/test/java/concert/EncoreableTest.java @@ -0,0 +1,27 @@ +package concert; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.contrib.java.lang.system.StandardOutputStreamLog; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import static org.junit.Assert.assertEquals; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration("classpath:concert.xml") +public class EncoreableTest { + @Rule + public final StandardOutputStreamLog log = new StandardOutputStreamLog(); + + @Autowired + private Encoreable performance; + + @Test + public void testPerformance() { + performance.performEncore(); + assertEquals("Default encoreable\n", log.getLog()); + } +} diff --git a/Chapter_04/aop-xml/src/test/java/params/TrackCountTest.java b/Chapter_04/aop-xml/src/test/java/params/TrackCountTest.java new file mode 100644 index 0000000..55fa56a --- /dev/null +++ b/Chapter_04/aop-xml/src/test/java/params/TrackCountTest.java @@ -0,0 +1,40 @@ +package params; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import static org.junit.Assert.assertEquals; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration("classpath:params.xml") +public class TrackCountTest { + @Autowired + private CompactDisc cd; + + @Autowired + private TrackCounter counter; + + @Test + public void testTrackCounter() { + cd.playTrack(1); + cd.playTrack(2); + cd.playTrack(3); + cd.playTrack(3); + cd.playTrack(3); + cd.playTrack(3); + cd.playTrack(6); + cd.playTrack(7); + cd.playTrack(7); + + assertEquals(1, counter.getPlayCount(1)); + assertEquals(1, counter.getPlayCount(2)); + assertEquals(4, counter.getPlayCount(3)); + assertEquals(0, counter.getPlayCount(4)); + assertEquals(0, counter.getPlayCount(5)); + assertEquals(1, counter.getPlayCount(6)); + assertEquals(2, counter.getPlayCount(7)); + } +} diff --git a/Chapter_04/aop/build.gradle b/Chapter_04/aop/build.gradle new file mode 100644 index 0000000..02a6131 --- /dev/null +++ b/Chapter_04/aop/build.gradle @@ -0,0 +1,20 @@ +plugins { + id 'java' +} + +group 'com.whezh' +version '1.0-SNAPSHOT' + +sourceCompatibility = 1.8 + +repositories { + mavenCentral() +} + +dependencies { + compile "org.springframework:spring-context:${springVersion}" + compile("org.aspectj:aspectjweaver:${aspectjVersion}") + + testCompile("org.springframework:spring-test:${springVersion}") + testCompile "com.github.stefanbirkner:system-rules:${systemRulesVersion}" +} diff --git a/Chapter_04/aop/gradle.properties b/Chapter_04/aop/gradle.properties new file mode 100644 index 0000000..d9d7004 --- /dev/null +++ b/Chapter_04/aop/gradle.properties @@ -0,0 +1,3 @@ +springVersion=4.0.7.RELEASE +systemRulesVersion=1.5.0 +aspectjVersion=1.7.2 \ No newline at end of file diff --git a/Chapter_04/aop/gradle/wrapper/gradle-wrapper.jar b/Chapter_04/aop/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..1948b90 Binary files /dev/null and b/Chapter_04/aop/gradle/wrapper/gradle-wrapper.jar differ diff --git a/Chapter_04/aop/gradle/wrapper/gradle-wrapper.properties b/Chapter_04/aop/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..d2c45a4 --- /dev/null +++ b/Chapter_04/aop/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.8-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/Chapter_04/aop/gradlew b/Chapter_04/aop/gradlew new file mode 100755 index 0000000..cccdd3d --- /dev/null +++ b/Chapter_04/aop/gradlew @@ -0,0 +1,172 @@ +#!/usr/bin/env sh + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/Chapter_04/aop/gradlew.bat b/Chapter_04/aop/gradlew.bat new file mode 100644 index 0000000..f955316 --- /dev/null +++ b/Chapter_04/aop/gradlew.bat @@ -0,0 +1,84 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/Chapter_04/aop/settings.gradle b/Chapter_04/aop/settings.gradle new file mode 100644 index 0000000..683c3ed --- /dev/null +++ b/Chapter_04/aop/settings.gradle @@ -0,0 +1,2 @@ +rootProject.name = 'aop' + diff --git a/Chapter_04/aop/src/main/java/concert/Audience.java b/Chapter_04/aop/src/main/java/concert/Audience.java new file mode 100644 index 0000000..4e43a4c --- /dev/null +++ b/Chapter_04/aop/src/main/java/concert/Audience.java @@ -0,0 +1,45 @@ +package concert; + +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Pointcut; + +@Aspect +public class Audience { + @Pointcut("execution(* concert.Performance.perform(..))") + public void performance() { + } + + @Around("performance()") + public void watchPerformance(ProceedingJoinPoint jp) { + try { + System.out.println("Silencing cell phones"); + System.out.println("Taking seats"); + jp.proceed(); + System.out.println("CLAP CLAP CLAP!!!"); + } catch (Throwable e) { + System.out.println("Demanding a refund"); + } + } + +// @Before("performance()") +// public void silenceCellPhone() { +// System.out.println("Silencing cell phones"); +// } +// +// @Before("performance()") +// public void takeSeats() { +// System.out.println("Taking seats"); +// } +// +// @Before("performance()") +// public void applause() { +// System.out.println("CLAP CLAP CLAP!!!"); +// } +// +// @Before("performance()") +// public void demandRefund() { +// System.out.println("Demanding a refund"); +// } +} diff --git a/Chapter_04/aop/src/main/java/concert/ConcertConfig.java b/Chapter_04/aop/src/main/java/concert/ConcertConfig.java new file mode 100644 index 0000000..e2220f6 --- /dev/null +++ b/Chapter_04/aop/src/main/java/concert/ConcertConfig.java @@ -0,0 +1,22 @@ +package concert; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.EnableAspectJAutoProxy; + +@Configuration +@EnableAspectJAutoProxy +@ComponentScan +public class ConcertConfig { + + @Bean + public Audience audience() { + return new Audience(); + } + + @Bean + public EncoreableIntroducer encoreableIntroducer() { + return new EncoreableIntroducer(); + } +} diff --git a/Chapter_04/aop/src/main/java/concert/DefaultEncoreable.java b/Chapter_04/aop/src/main/java/concert/DefaultEncoreable.java new file mode 100644 index 0000000..d06729e --- /dev/null +++ b/Chapter_04/aop/src/main/java/concert/DefaultEncoreable.java @@ -0,0 +1,8 @@ +package concert; + +public class DefaultEncoreable implements Encoreable { + @Override + public void performEncore() { + System.out.println("Default encoreable"); + } +} diff --git a/Chapter_04/aop/src/main/java/concert/Encoreable.java b/Chapter_04/aop/src/main/java/concert/Encoreable.java new file mode 100644 index 0000000..822ad00 --- /dev/null +++ b/Chapter_04/aop/src/main/java/concert/Encoreable.java @@ -0,0 +1,5 @@ +package concert; + +public interface Encoreable { + void performEncore(); +} diff --git a/Chapter_04/aop/src/main/java/concert/EncoreableIntroducer.java b/Chapter_04/aop/src/main/java/concert/EncoreableIntroducer.java new file mode 100644 index 0000000..d850a90 --- /dev/null +++ b/Chapter_04/aop/src/main/java/concert/EncoreableIntroducer.java @@ -0,0 +1,11 @@ +package concert; + +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.DeclareParents; + +@Aspect +public class EncoreableIntroducer { + + @DeclareParents(value = "concert.Performance+", defaultImpl = DefaultEncoreable.class) + public static Encoreable encoreable; +} diff --git a/Chapter_04/aop/src/main/java/concert/Music.java b/Chapter_04/aop/src/main/java/concert/Music.java new file mode 100644 index 0000000..c1450bd --- /dev/null +++ b/Chapter_04/aop/src/main/java/concert/Music.java @@ -0,0 +1,11 @@ +package concert; + +import org.springframework.stereotype.Component; + +@Component +public class Music implements Performance { + @Override + public void perform() { + System.out.println("Piano Solo"); + } +} diff --git a/Chapter_04/aop/src/main/java/concert/Performance.java b/Chapter_04/aop/src/main/java/concert/Performance.java new file mode 100644 index 0000000..7654ce3 --- /dev/null +++ b/Chapter_04/aop/src/main/java/concert/Performance.java @@ -0,0 +1,5 @@ +package concert; + +public interface Performance { + void perform(); +} \ No newline at end of file diff --git a/Chapter_04/aop/src/main/java/params/BlankDisc.java b/Chapter_04/aop/src/main/java/params/BlankDisc.java new file mode 100644 index 0000000..8cf45f9 --- /dev/null +++ b/Chapter_04/aop/src/main/java/params/BlankDisc.java @@ -0,0 +1,33 @@ +package params; + +import java.util.List; + +public class BlankDisc implements CompactDisc { + + private String title; + private String artist; + private List tracks; + + public void setTitle(String title) { + this.title = title; + } + + public void setArtist(String artist) { + this.artist = artist; + } + + public void setTracks(List tracks) { + this.tracks = tracks; + } + + public void play() { + System.out.println("Playing " + title + " by " + artist); + for (int i = 0; i < tracks.size(); i++) { + playTrack(i); + } + } + + public void playTrack(int track) { + System.out.println("-Track: " + tracks.get(track)); + } +} diff --git a/Chapter_04/aop/src/main/java/params/CompactDisc.java b/Chapter_04/aop/src/main/java/params/CompactDisc.java new file mode 100644 index 0000000..21bc2c3 --- /dev/null +++ b/Chapter_04/aop/src/main/java/params/CompactDisc.java @@ -0,0 +1,7 @@ +package params; + +public interface CompactDisc { + void play(); + + void playTrack(int track); +} \ No newline at end of file diff --git a/Chapter_04/aop/src/main/java/params/TrackCounter.java b/Chapter_04/aop/src/main/java/params/TrackCounter.java new file mode 100644 index 0000000..78b36bf --- /dev/null +++ b/Chapter_04/aop/src/main/java/params/TrackCounter.java @@ -0,0 +1,28 @@ +package params; + +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; +import org.aspectj.lang.annotation.Pointcut; + +import java.util.HashMap; +import java.util.Map; + +@Aspect +public class TrackCounter { + + private Map trackCounts = new HashMap<>(); + + @Pointcut("execution(* params.CompactDisc.playTrack(int)) && args(trackNumber)") + public void trackPlayed(int trackNumber) { + } + + @Before("trackPlayed(trackNumber)") + public void countTrack(int trackNumber) { + int currentCount = getPlayCount(trackNumber); + trackCounts.put(trackNumber, currentCount + 1); + } + + public int getPlayCount(int trackNumber) { + return trackCounts.containsKey(trackNumber) ? trackCounts.get(trackNumber) : 0; + } +} diff --git a/Chapter_04/aop/src/main/java/params/TrackCounterConfig.java b/Chapter_04/aop/src/main/java/params/TrackCounterConfig.java new file mode 100644 index 0000000..3bffef1 --- /dev/null +++ b/Chapter_04/aop/src/main/java/params/TrackCounterConfig.java @@ -0,0 +1,42 @@ +package params; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.EnableAspectJAutoProxy; + +import java.util.ArrayList; +import java.util.List; + +@Configuration +@EnableAspectJAutoProxy +public class TrackCounterConfig { + + @Bean + public CompactDisc blankDisc() { + BlankDisc cd = new BlankDisc(); + cd.setTitle("Sgt. Pepper's Lonely Hearts Club Band"); + cd.setArtist("The Beatles"); + + List tracks = new ArrayList<>(); + tracks.add("Sgt. Pepper's Lonely Hearts Club Band"); + tracks.add("With a Little Help from My Friends"); + tracks.add("Lucy in the Sky with Diamonds"); + tracks.add("Getting Better"); + tracks.add("Fixing a Hole"); + tracks.add("She's Leaving Home"); + tracks.add("Within You Without You"); + tracks.add("When I'm Sixty-Four"); + tracks.add("Lovely Rita"); + tracks.add("Good Morning Good Morning"); + tracks.add("A Day in the Life"); + + cd.setTracks(tracks); + + return cd; + } + + @Bean + public TrackCounter trackCounter() { + return new TrackCounter(); + } +} diff --git a/Chapter_04/aop/src/test/java/concert/ConcertTest.java b/Chapter_04/aop/src/test/java/concert/ConcertTest.java new file mode 100644 index 0000000..5bac278 --- /dev/null +++ b/Chapter_04/aop/src/test/java/concert/ConcertTest.java @@ -0,0 +1,30 @@ +package concert; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.junit.contrib.java.lang.system.StandardOutputStreamLog; + +import static org.junit.Assert.assertEquals; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = ConcertConfig.class) +public class ConcertTest { + @Rule + public final StandardOutputStreamLog log = new StandardOutputStreamLog(); + + @Autowired + private Performance performance; + + @Test + public void testPerformance() { + performance.perform(); + assertEquals("Silencing cell phones\n" + + "Taking seats\n" + + "Piano Solo\n" + + "CLAP CLAP CLAP!!!\n", log.getLog()); + } +} diff --git a/Chapter_04/aop/src/test/java/concert/EncoreableTest.java b/Chapter_04/aop/src/test/java/concert/EncoreableTest.java new file mode 100644 index 0000000..ec7513c --- /dev/null +++ b/Chapter_04/aop/src/test/java/concert/EncoreableTest.java @@ -0,0 +1,27 @@ +package concert; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.contrib.java.lang.system.StandardOutputStreamLog; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import static org.junit.Assert.assertEquals; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = ConcertConfig.class) +public class EncoreableTest { + @Rule + public final StandardOutputStreamLog log = new StandardOutputStreamLog(); + + @Autowired + private Encoreable performance; + + @Test + public void testPerformance() { + performance.performEncore(); + assertEquals("Default encoreable\n", log.getLog()); + } +} diff --git a/Chapter_04/aop/src/test/java/params/TrackCountTest.java b/Chapter_04/aop/src/test/java/params/TrackCountTest.java new file mode 100644 index 0000000..b677b2a --- /dev/null +++ b/Chapter_04/aop/src/test/java/params/TrackCountTest.java @@ -0,0 +1,40 @@ +package params; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import static org.junit.Assert.assertEquals; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = TrackCounterConfig.class) +public class TrackCountTest { + @Autowired + private CompactDisc cd; + + @Autowired + private TrackCounter counter; + + @Test + public void testTrackCounter() { + cd.playTrack(1); + cd.playTrack(2); + cd.playTrack(3); + cd.playTrack(3); + cd.playTrack(3); + cd.playTrack(3); + cd.playTrack(6); + cd.playTrack(7); + cd.playTrack(7); + + assertEquals(1, counter.getPlayCount(1)); + assertEquals(1, counter.getPlayCount(2)); + assertEquals(4, counter.getPlayCount(3)); + assertEquals(0, counter.getPlayCount(4)); + assertEquals(0, counter.getPlayCount(5)); + assertEquals(1, counter.getPlayCount(6)); + assertEquals(2, counter.getPlayCount(7)); + } +}