Commits

Marcin Grzejszczak  committed 6c9b91a

Spring Primary - Initial commit

  • Participants
  • Parent commits c1b602a

Comments (0)

Files changed (11)

File Spring/Primary/build.gradle

+apply plugin: "java"
+apply plugin: "groovy"
+
+group = "com.blogspot.toomuchcoding"
+version = "0.0.1-SNAPSHOT"
+
+repositories {
+    mavenCentral()
+}
+
+ext {
+	GROOVY_VERSION="2.1.9"
+	SPRING_VERSION="3.2.4.RELEASE"
+	SPOCK_VERSION="0.7-groovy-2.0"
+	CGLIB_VERSION="2.2.2"
+	OBJENESIS_VERSION="1.3"
+}
+
+dependencies {
+    compile "org.codehaus.groovy:groovy-all:$GROOVY_VERSION"    
+    compile "org.springframework:spring-beans:$SPRING_VERSION"
+    compile "org.springframework:spring-core:$SPRING_VERSION"
+    compile "org.springframework:spring-context:$SPRING_VERSION"
+    compile "commons-lang:commons-lang:2.6"
+    compile "org.slf4j:slf4j-log4j12:1.7.5"
+
+    testCompile group: "junit", name: "junit", version: "4.+"
+    testCompile "org.springframework:spring-test:$SPRING_VERSION"
+    testCompile "org.spockframework:spock-core:$SPOCK_VERSION"
+    testCompile "org.spockframework:spock-spring:$SPOCK_VERSION"
+    testCompile "cglib:cglib-nodep:$CGLIB_VERSION"
+    testCompile "org.objenesis:objenesis:$OBJENESIS_VERSION"
+}

File Spring/Primary/pom.xml

+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<groupId>com.blogspot.toomuchcoding</groupId>
+	<artifactId>spring-primary</artifactId>
+	<version>0.0.1-SNAPSHOT</version>
+
+	<properties>
+		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+		<maven.compiler.source>1.6</maven.compiler.source>
+		<maven.compiler.target>1.6</maven.compiler.target>
+        <cglib.version>2.2.2</cglib.version>
+        <groovy.version>2.1.3</groovy.version>
+        <groovy.eclipse.compiler.version>2.7.0-01</groovy.eclipse.compiler.version>
+        <java.version>1.6</java.version>
+        <objenesis.version>1.3</objenesis.version>
+        <spock.version>0.7-groovy-2.0</spock.version>
+        <spring.version>3.2.4.RELEASE</spring.version>
+        <project.build.sourceEncoding>utf-8</project.build.sourceEncoding>
+    </properties>
+
+	<dependencies>
+		<!-- Spring -->
+		<dependency>
+			<groupId>org.springframework</groupId>
+			<artifactId>spring-beans</artifactId>
+			<version>${spring.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>org.springframework</groupId>
+			<artifactId>spring-core</artifactId>
+			<version>${spring.version}</version>
+		</dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-context</artifactId>
+            <version>${spring.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.codehaus.groovy</groupId>
+            <artifactId>groovy-all</artifactId>
+            <version>${groovy.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.spockframework</groupId>
+            <artifactId>spock-core</artifactId>
+            <version>${spock.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <!-- keep these two dependencies if you would like to use Spring within Spock tests -->
+        <dependency>
+            <groupId>org.spockframework</groupId>
+            <artifactId>spock-spring</artifactId>
+            <version>${spock.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-test</artifactId>
+            <version>${spring.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <!-- keep this dependency if you would like to mock concrete classes within Spock -->
+        <dependency>
+            <groupId>cglib</groupId>
+            <artifactId>cglib-nodep</artifactId>
+            <version>${cglib.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <!-- keep this dependency if you would like to mock classes without a constructor within Spock -->
+        <dependency>
+            <groupId>org.objenesis</groupId>
+            <artifactId>objenesis</artifactId>
+            <version>${objenesis.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-log4j12</artifactId>
+            <version>1.7.5</version>
+        </dependency>
+        <dependency>
+            <groupId>commons-lang</groupId>
+            <artifactId>commons-lang</artifactId>
+            <version>2.6</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>3.1</version>
+                <configuration>
+                    <compilerId>groovy-eclipse-compiler</compilerId>
+                    <verbose>false</verbose>
+                    <source>${java.version}</source>
+                    <target>${java.version}</target>
+                    <encoding>${project.build.sourceEncoding}</encoding>
+                </configuration>
+                <dependencies>
+                    <dependency>
+                        <groupId>org.codehaus.groovy</groupId>
+                        <artifactId>groovy-eclipse-compiler</artifactId>
+                        <version>${groovy.eclipse.compiler.version}</version>
+                    </dependency>
+                </dependencies>
+            </plugin>
+            <!-- at this time Spock does not support Maven 3, this is the workaround, later we can use the Spock plugin -->
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <version>2.14.1</version>
+                <configuration>
+                    <includes>
+                        <include>**/*Test.java</include>
+                        <include>**/*Spec.java</include>
+                        <include>**/*Test.groovy</include>
+                        <include>**/*Spec.groovy</include>
+                    </includes>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>build-helper-maven-plugin</artifactId>
+                <version>1.2</version>
+                <executions>
+                    <execution>
+                        <id>add-source</id>
+                        <phase>generate-sources</phase>
+                        <goals>
+                            <goal>add-source</goal>
+                        </goals>
+                        <configuration>
+                            <sources>
+                                <source>${basedir}/src/main/groovy</source>
+                            </sources>
+                        </configuration>
+                    </execution>
+                    <execution>
+                        <id>add-test-source</id>
+                        <phase>generate-test-sources</phase>
+                        <goals>
+                            <goal>add-test-source</goal>
+                        </goals>
+                        <configuration>
+                            <sources>
+                                <source>${basedir}/src/test/groovy</source>
+                            </sources>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>

File Spring/Primary/src/main/java/com/blogspot/toomuchcoding/configuration/SpringConfiguration.java

+package com.blogspot.toomuchcoding.configuration;
+
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+@ComponentScan("com.blogspot.toomuchcoding")
+public class SpringConfiguration {
+
+}

File Spring/Primary/src/main/java/com/blogspot/toomuchcoding/person/domain/Person.java

+package com.blogspot.toomuchcoding.person.domain;
+
+public final class Person {
+	private final String name;
+	private final int age;
+	private final boolean stupid;
+
+	public Person(String name, int age, boolean stupid) {
+		this.name = name;
+		this.age = age;
+		this.stupid = stupid;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public int getAge() {
+		return age;
+	}
+
+	public boolean isStupid() {
+		return stupid;
+	}
+}

File Spring/Primary/src/main/java/com/blogspot/toomuchcoding/person/service/AgePersonProcessingService.java

+package com.blogspot.toomuchcoding.person.service;
+
+import org.springframework.stereotype.Component;
+
+import com.blogspot.toomuchcoding.person.domain.Person;
+
+@Component
+class AgePersonProcessingService implements PersonProcessingService {
+
+	@Override
+	public boolean isApplicableFor(Person person) {
+		return person.getAge() >= 18;
+	}
+
+	@Override
+	public String process(Person person) {
+		return String.format("Person's AGE is [%s] so we could process him", person.getAge());
+	}
+}

File Spring/Primary/src/main/java/com/blogspot/toomuchcoding/person/service/IntelligencePersonProcessingService.java

+package com.blogspot.toomuchcoding.person.service;
+
+import org.springframework.stereotype.Component;
+
+import com.blogspot.toomuchcoding.person.domain.Person;
+
+@Component
+class IntelligencePersonProcessingService implements PersonProcessingService {
+
+	@Override
+	public boolean isApplicableFor(Person person) {
+		return person.isStupid();
+	}
+
+	@Override
+	public String process(Person person) {
+		return "Person's STUPID so can process him";
+	}
+}

File Spring/Primary/src/main/java/com/blogspot/toomuchcoding/person/service/NamePersonProcessingService.java

+package com.blogspot.toomuchcoding.person.service;
+
+import org.apache.commons.lang.StringUtils;
+import org.springframework.stereotype.Component;
+
+import com.blogspot.toomuchcoding.person.domain.Person;
+
+@Component
+class NamePersonProcessingService implements PersonProcessingService {
+
+	@Override
+	public boolean isApplicableFor(Person person) {
+		return StringUtils.isNotBlank(person.getName());
+	}
+
+	@Override
+	public String process(Person person) {
+		return String.format("Person with NAME [%s] has been processed", person.getName());
+	}
+}

File Spring/Primary/src/main/java/com/blogspot/toomuchcoding/person/service/PersonProcessingService.java

+package com.blogspot.toomuchcoding.person.service;
+
+import com.blogspot.toomuchcoding.person.domain.Person;
+
+public interface PersonProcessingService {
+	boolean isApplicableFor(Person person);
+	String process(Person person);
+}

File Spring/Primary/src/main/java/com/blogspot/toomuchcoding/person/service/PersonProcessingServiceContainer.java

+package com.blogspot.toomuchcoding.person.service;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Primary;
+import org.springframework.stereotype.Component;
+
+import com.blogspot.toomuchcoding.person.domain.Person;
+
+@Component
+@Primary
+class PersonProcessingServiceContainer implements PersonProcessingService {
+
+	private static final Logger LOGGER = LoggerFactory.getLogger(PersonProcessingServiceContainer.class);
+	
+	@Autowired
+	private List<PersonProcessingService> personProcessingServices = new ArrayList<PersonProcessingService>();
+	
+	@Override
+	public boolean isApplicableFor(Person person) {
+		return person != null;
+	}
+
+	@Override
+	public String process(Person person) {
+		List<String> output = new ArrayList<String>();
+		for(PersonProcessingService personProcessingService : personProcessingServices){
+			if(personProcessingService.isApplicableFor(person)){
+				output.add(personProcessingService.process(person));
+			}
+		}
+		String result = StringUtils.join(output, ",");
+		LOGGER.info(result);
+		return result;
+	}
+
+	public List<PersonProcessingService> getPersonProcessingServices() {
+		return personProcessingServices;
+	}
+}

File Spring/Primary/src/main/resources/log4j.xml

+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
+
+	<!-- Appenders -->
+	<appender name="console" class="org.apache.log4j.ConsoleAppender">
+		<param name="Target" value="System.out" />
+		<layout class="org.apache.log4j.PatternLayout">
+			<param name="ConversionPattern" value="%d %-5p [%t] %c:%L %m%n" />
+		</layout>
+	</appender>
+	
+	
+
+	<!-- Root Logger -->
+	<root>
+		<priority value="INFO" />       
+		<appender-ref ref="console" />
+	</root>
+	
+</log4j:configuration>

File Spring/Primary/src/test/groovy/com/blogspot/toomuchcoding/person/service/PersonProcessingServiceContainerIntegrationSpec.groovy

+package com.blogspot.toomuchcoding.person.service
+import com.blogspot.toomuchcoding.configuration.SpringConfiguration
+import com.blogspot.toomuchcoding.person.domain.Person
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.test.context.ContextConfiguration
+import spock.lang.Specification
+import spock.lang.Unroll
+
+import static org.hamcrest.CoreMatchers.notNullValue
+
+@ContextConfiguration(classes = [SpringConfiguration])
+class PersonProcessingServiceContainerIntegrationSpec extends Specification {
+
+    @Autowired
+    PersonProcessingService personProcessingService
+    
+    def "should autowire container even though there are many implementations of service"(){       
+        expect: 
+            personProcessingService instanceof PersonProcessingServiceContainer
+    }
+    
+    def "the autowired container should not have itself in the list of autowired services"(){       
+        expect: 
+            personProcessingService instanceof PersonProcessingServiceContainer
+        and:
+            !(personProcessingService as PersonProcessingServiceContainer).personProcessingServices.findResult {
+                it instanceof PersonProcessingServiceContainer
+            }
+    }
+    
+    def "should not be applicable for processing if a person doesn't exist"(){
+        given:
+            Person person = null
+        expect:
+            !personProcessingService.isApplicableFor(person)
+    }
+    
+    def "should return an empty result for a person not applicable for anything"(){
+        given:
+            Person person = new Person("", 17, false)
+        when:
+            def result = personProcessingService.process(person)
+        then:
+            result notNullValue()
+            result.isEmpty()
+    }
+
+    @Unroll("For name [#name], age [#age] and being stupid [#stupid] the result should contain keywords #keywords")
+    def "should perform different processing depending on input"(){
+        given:
+            Person person = new Person(name, age, stupid)
+        when:
+            def result = personProcessingService.process(person)        
+        then:
+            keywords.every {
+                result.contains(it)    
+            }
+        where:
+            name  | age | stupid || keywords
+            "jan" | 20  | true   || ['NAME', 'AGE', 'STUPID']
+            ""    | 20  | true   || ['AGE', 'STUPID']
+            ""    | 20  | false  || ['AGE']
+            null  | 17  | true   || ['STUPID']
+            "jan" | 17  | true   || ['NAME']
+    }
+}