Skip to content

Commit

Permalink
[5] First JPA Use Case Application
Browse files Browse the repository at this point in the history
  • Loading branch information
aslakknutsen authored and ALRubinger committed Feb 22, 2013
1 parent d81a265 commit acda558
Show file tree
Hide file tree
Showing 55 changed files with 1,800 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -3,3 +3,4 @@ target
.project
.settings
test-output
log.txt
37 changes: 37 additions & 0 deletions application/application/pom.xml
@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8"?>
<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/maven-v4_0_0.xsd">

<parent>
<groupId>org.continuous.enterprise</groupId>
<artifactId>continuous-enterprise</artifactId>
<version>1.0.0-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>

<modelVersion>4.0.0</modelVersion>
<groupId>org.continuous.enterprise.application</groupId>
<artifactId>application</artifactId>
<packaging>war</packaging>
<name>Continuous Enterprise Application</name>
<description></description>

<dependencies>
<dependency>
<groupId>org.continuous.enterprise.web</groupId>
<artifactId>web-conference</artifactId>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.2</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</build>
</project>
25 changes: 25 additions & 0 deletions application/domain/attachment/pom.xml
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<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/maven-v4_0_0.xsd">

<parent>
<groupId>org.continuous.enterprise.domain</groupId>
<artifactId>continuous-enterprise-domain</artifactId>
<version>1.0.0-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>

<modelVersion>4.0.0</modelVersion>
<artifactId>domain-attachment</artifactId>
<packaging>jar</packaging>
<name>Continuous Enterprise Domain: Attachment</name>
<description></description>

<dependencies>
<dependency>
<groupId>org.continuous.enterprise.domain</groupId>
<artifactId>domain-core</artifactId>
</dependency>
</dependencies>

</project>
@@ -0,0 +1,17 @@
package org.ced.domain.attachment;

import java.util.UUID;

import javax.persistence.Entity;
import javax.persistence.Id;

@Entity
public class Attachment {

@Id
public String id;

public Attachment() {
this.id = UUID.randomUUID().toString();
}
}
25 changes: 25 additions & 0 deletions application/domain/conference/pom.xml
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<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/maven-v4_0_0.xsd">

<parent>
<groupId>org.continuous.enterprise.domain</groupId>
<artifactId>continuous-enterprise-domain</artifactId>
<version>1.0.0-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>

<modelVersion>4.0.0</modelVersion>
<artifactId>domain-conference</artifactId>
<packaging>jar</packaging>
<name>Continuous Enterprise Domain: Conference</name>
<description></description>

<dependencies>
<dependency>
<groupId>org.continuous.enterprise.domain</groupId>
<artifactId>domain-core</artifactId>
</dependency>
</dependencies>

</project>
@@ -0,0 +1,14 @@
package org.ced.domain.conference;

import javax.ejb.Stateless;

import org.ced.domain.Repository;
import org.ced.domain.conference.model.Conference;

@Stateless
public class ConferenceRepository extends Repository<Conference> {

public ConferenceRepository() {
super(Conference.class);
}
}
@@ -0,0 +1,86 @@
package org.ced.domain.conference.model;

import java.io.Serializable;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;

import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;

import org.ced.domain.Identifiable;

@Entity
public class Conference implements Identifiable, Serializable {

private static final long serialVersionUID = 1L;

@Id
private String id;

@NotNull
private String name;

private String tagLine;

@Embedded @Valid @NotNull
private Duration duration;

@OneToMany(fetch = FetchType.EAGER, orphanRemoval = true) @Valid
private Set<Session> sessions;

public Conference() {
this.id = UUID.randomUUID().toString();
}

public String getId() {
return id;
}

public String getName() {
return name;
}

public Conference setName(String name) {
this.name = name;
return this;
}

public String getTagLine() {
return tagLine;
}

public Conference setTagLine(String tagLine) {
this.tagLine = tagLine;
return this;
}

public Conference setDuration(Duration duration) {
this.duration = duration;
return this;
}

public Duration getDuration() {
return duration;
}

public Set<Session> getSessions() {
return Collections.unmodifiableSet(sessions);
}

public Conference addSession(Session session) {
if(sessions == null) {
this.sessions = new HashSet<Session>();
}
if(!sessions.contains(session)) {
sessions.add(session);
}
return this;
}
}
@@ -0,0 +1,49 @@
package org.ced.domain.conference.model;

import java.util.Date;

import javax.validation.constraints.NotNull;

public class Duration {

@NotNull
private Date start;

@NotNull
private Date end;

// hidden constructor for Persistence
Duration() {
}

public Duration(Date start, Date end) {
if(start == null) {
throw new IllegalArgumentException("Start must be provided");
}
if(end == null) {
throw new IllegalArgumentException("End must be provided");
}
if(end.before(start)) {
throw new IllegalArgumentException("End can not be before Start");
}
this.start = start;
this.end = end;

}

public Date getEnd() {
return (Date)end.clone();
}

public Date getStart() {
return (Date)start.clone();
}

public Integer getNumberOfDays() {
return -1;
}

public Integer getNumberOfHours() {
return -1;
}
}
@@ -0,0 +1,58 @@
package org.ced.domain.conference.model;

import java.io.Serializable;
import java.util.UUID;

import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;

@Entity
public class Session implements Serializable {

private static final long serialVersionUID = 1L;

@Id
private String id;

@Embedded @NotNull @Valid
private Duration duration;

@NotNull
private String title;
private String outline;

public Session() {
this.id = UUID.randomUUID().toString();
}

public String getId() {
return id;
}

public Duration getDuration() {
return duration;
}

public void setDuration(Duration duration) {
this.duration = duration;
}

public String getTitle() {
return title;
}

public void setTitle(String title) {
this.title = title;
}

public String getOutline() {
return outline;
}

public void setOutline(String outline) {
this.outline = outline;
}
}
@@ -0,0 +1,66 @@
package org.ced.domain.conference;

import java.util.Date;
import java.util.Set;

import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;

import junit.framework.Assert;

import org.ced.domain.conference.model.Conference;
import org.ced.domain.conference.model.Duration;
import org.junit.Before;
import org.junit.Test;

public class DomainValidationTestCase {

private Validator validator;

@Before
public void setupValidationFactory() {
validator = Validation.buildDefaultValidatorFactory().getValidator();
}

@Test
public void shouldNotAllowNullName() {
Conference conference = new Conference();
assertValidationConsraint(conference, "NotNull", "name");
}

@Test
public void shouldNotAllowNullDuration() {
Conference conference = new Conference();
assertValidationConsraint(conference, "NotNull", "duration");
}

@Test(expected = IllegalArgumentException.class)
public void shouldNotAllowEndBeforeStart() {
new Duration(new Date(), new Date(System.currentTimeMillis()-1000));
}

private <T> void assertValidationConsraint(T object, String type, String... properties) {
Set<ConstraintViolation<T>> errors = validator.validate(object);

Assert.assertFalse("Expecting vaidation errors", errors.isEmpty());

for (String property : properties) {
ConstraintViolation<T> validationFound = null;
for (ConstraintViolation<T> cv : errors) {
if(property.equals(cv.getPropertyPath().toString())) {
validationFound = cv;
break;
}
}
if(validationFound == null) {
String msg = "Expected validation error on property [%s] but non found. Found errors [%s]";
Assert.fail(String.format(msg, property, errors));
} else if(!validationFound.getMessageTemplate().contains(type)) {
String msg = "Expected validation error on property [%s] of type [%s]. Found error [%s]";
Assert.fail(String.format(msg, property, type, validationFound));
}
}

}
}

0 comments on commit acda558

Please sign in to comment.