diff --git a/pom.xml b/pom.xml
index ed84c9b..7a54354 100644
--- a/pom.xml
+++ b/pom.xml
@@ -43,6 +43,11 @@
javax.inject
1
+
+ javax.xml.bind
+ jaxb-api
+ 2.3.0
+
diff --git a/src/main/Resources/import.sql b/src/main/Resources/import.sql
new file mode 100644
index 0000000..b6f5034
--- /dev/null
+++ b/src/main/Resources/import.sql
@@ -0,0 +1,75 @@
+insert into poll (poll_id, question) values (1, 'What is your favorite color?');
+insert into option (option_id, option_value, POLL_ID) values (1, 'Red', 1);
+insert into option (option_id, option_value, POLL_ID) values (2, 'Blue', 1);
+insert into option (option_id, option_value, POLL_ID) values (3, 'Green', 1);
+
+insert into poll (poll_id, question) values (2, 'What is your favorite band?');
+insert into option (option_id, option_value, poll_id) values (1, 'RCHP', 1);
+insert into option (option_id, option_value, poll_id) values (2, 'Beatles', 1);
+insert into option (option_id, option_value, poll_id) values (3, 'Rolling Stones', 1);
+
+insert into poll (poll_id, question) values (3, 'What is your favorite animal?');
+insert into option (option_id, option_value, poll_id) values (1, 'Monkey', 1);
+insert into option (option_id, option_value, poll_id) values (2, 'Frog', 1);
+insert into option (option_id, option_value, poll_id) values (3, 'Starfish', 1);
+
+insert into poll (poll_id, question) values (4, 'What is your favorite state?');
+insert into option (option_id, option_value, poll_id) values (1, 'Delaware', 1);
+insert into option (option_id, option_value, poll_id) values (2, 'Maryland', 1);
+insert into option (option_id, option_value, poll_id) values (3, 'New Jersey', 1);
+
+insert into poll (poll_id, question) values (5, 'What is your favorite Beatles song?');
+insert into option (option_id, option_value, poll_id) values (1, 'Let it Be', 1);
+insert into option (option_id, option_value, poll_id) values (2, 'Yellow Submarine', 1);
+insert into option (option_id, option_value, poll_id) values (3, '', 1);
+
+insert into poll (poll_id, question) values (6, 'What is your favorite color?');
+insert into option (option_id, option_value, poll_id) values (1, 'Red', 1);
+insert into option (option_id, option_value, poll_id) values (2, 'Blue', 1);
+insert into option (option_id, option_value, poll_id) values (3, 'Green', 1);
+
+insert into poll (poll_id, question) values (7, 'What is your favorite color?');
+insert into option (option_id, option_value, poll_id) values (1, 'Red', 1);
+insert into option (option_id, option_value, poll_id) values (2, 'Blue', 1);
+insert into option (option_id, option_value, poll_id) values (3, 'Green', 1);
+
+insert into poll (poll_id, question) values (8, 'What is your favorite color?');
+insert into option (option_id, option_value, poll_id) values (1, 'Red', 1);
+insert into option (option_id, option_value, poll_id) values (2, 'Blue', 1);
+insert into option (option_id, option_value, poll_id) values (3, 'Green', 1);
+
+insert into poll (poll_id, question) values (9, 'What is your favorite color?');
+insert into option (option_id, option_value, poll_id) values (1, 'Red', 1);
+insert into option (option_id, option_value, poll_id) values (2, 'Blue', 1);
+insert into option (option_id, option_value, poll_id) values (3, 'Green', 1);
+
+insert into poll (poll_id, question) values (10, 'What is your favorite color?');
+insert into option (option_id, option_value, poll_id) values (1, 'Red', 1);
+insert into option (option_id, option_value, poll_id) values (2, 'Blue', 1);
+insert into option (option_id, option_value, poll_id) values (3, 'Green', 1);
+
+insert into poll (poll_id, question) values (11, 'What is your favorite color?');
+insert into option (option_id, option_value, poll_id) values (1, 'Red', 1);
+insert into option (option_id, option_value, poll_id) values (2, 'Blue', 1);
+insert into option (option_id, option_value, poll_id) values (3, 'Green', 1);
+
+insert into poll (poll_id, question) values (12, 'What is your favorite color?');
+insert into option (option_id, option_value, poll_id) values (1, 'Red', 1);
+insert into option (option_id, option_value, poll_id) values (2, 'Blue', 1);
+insert into option (option_id, option_value, poll_id) values (3, 'Green', 1);
+
+insert into poll (poll_id, question) values (13, 'What is your favorite color?');
+insert into option (option_id, option_value, poll_id) values (1, 'Red', 1);
+insert into option (option_id, option_value, poll_id) values (2, 'Blue', 1);
+insert into option (option_id, option_value, poll_id) values (3, 'Green', 1);
+
+insert into poll (poll_id, question) values (14, 'What is your favorite color?');
+insert into option (option_id, option_value, poll_id) values (1, 'Red', 1);
+insert into option (option_id, option_value, poll_id) values (2, 'Blue', 1);
+insert into option (option_id, option_value, poll_id) values (3, 'Green', 1);
+
+insert into poll (poll_id, question) values (15, 'What is your favorite color?');
+insert into option (option_id, option_value, poll_id) values (1, 'Red', 1);
+insert into option (option_id, option_value, poll_id) values (2, 'Blue', 1);
+insert into option (option_id, option_value, poll_id) values (3, 'Green', 1);
+
diff --git a/src/main/Resources/messages.properties b/src/main/Resources/messages.properties
new file mode 100644
index 0000000..3f51f36
--- /dev/null
+++ b/src/main/Resources/messages.properties
@@ -0,0 +1,2 @@
+NotEmpty.poll.question=Question is a required field
+Size.poll.options=Options must be greater than {2} and less than {1}
\ No newline at end of file
diff --git a/src/main/java/io/zipcoder/tc_spring_poll_application/controller/ComputeResultController.java b/src/main/java/io/zipcoder/tc_spring_poll_application/controller/ComputeResultController.java
new file mode 100644
index 0000000..4e51e59
--- /dev/null
+++ b/src/main/java/io/zipcoder/tc_spring_poll_application/controller/ComputeResultController.java
@@ -0,0 +1,46 @@
+package io.zipcoder.tc_spring_poll_application.controller;
+
+import io.zipcoder.tc_spring_poll_application.domain.Vote;
+import io.zipcoder.tc_spring_poll_application.dto.OptionCount;
+import io.zipcoder.tc_spring_poll_application.dto.VoteResult;
+import io.zipcoder.tc_spring_poll_application.repositories.VoteRepository;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.inject.Inject;
+import java.util.HashMap;
+import java.util.Map;
+
+@RestController
+public class ComputeResultController {
+ @Inject
+ private VoteRepository voteRepository;
+
+ @RequestMapping(value = "/computeresult", method = RequestMethod.GET)
+ public ResponseEntity> computeResult(@RequestParam Long pollId) {
+ VoteResult voteResult = new VoteResult();
+ Iterable allVotes = voteRepository.findByPoll(pollId);
+
+ int totalVotes = 0;
+
+ Map tempMap = new HashMap();
+ for(Vote v : allVotes) {
+ totalVotes ++;
+ // Get the OptionCount corresponding to this Option
+ OptionCount optionCount = tempMap.get(v.getOption().getId());
+ if(optionCount == null) {
+ optionCount = new OptionCount();
+ optionCount.setOptionId(v.getOption().getId());
+ tempMap.put(v.getOption().getId(), optionCount);
+ }
+ optionCount.setCount(optionCount.getCount()+1);
+ }
+ voteResult.setTotalVotes(totalVotes);
+ voteResult.setResults(tempMap.values());
+ return new ResponseEntity(voteResult, HttpStatus.OK);
+ }
+}
diff --git a/src/main/java/io/zipcoder/tc_spring_poll_application/controller/PollController.java b/src/main/java/io/zipcoder/tc_spring_poll_application/controller/PollController.java
new file mode 100644
index 0000000..681607e
--- /dev/null
+++ b/src/main/java/io/zipcoder/tc_spring_poll_application/controller/PollController.java
@@ -0,0 +1,82 @@
+package io.zipcoder.tc_spring_poll_application.controller;
+
+import io.zipcoder.tc_spring_poll_application.domain.Poll;
+import io.zipcoder.tc_spring_poll_application.exception.ResourceNotFoundException;
+import io.zipcoder.tc_spring_poll_application.repositories.PollRepository;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
+
+import javax.inject.Inject;
+import javax.validation.Valid;
+import java.net.URI;
+
+@RestController
+public class PollController {
+
+ @Inject
+ private PollRepository pollRepository;
+
+ public PollRepository getPollRepository() {
+ return pollRepository;
+ }
+
+ public void setPollRepository(PollRepository pollRepository) {
+ this.pollRepository = pollRepository;
+ }
+
+
+ @RequestMapping(value="/polls", method= RequestMethod.GET)
+ public ResponseEntity> getAllPolls() {
+ Iterable allPolls = pollRepository.findAll();
+ return new ResponseEntity<>(allPolls, HttpStatus.OK);
+ }
+
+ @RequestMapping(value="/polls", method=RequestMethod.POST)
+ public ResponseEntity> createPoll(@RequestBody Poll poll) {
+ poll = pollRepository.save(poll);
+ HttpHeaders responseHeaders = new HttpHeaders();
+ URI newPollUri = ServletUriComponentsBuilder
+ .fromCurrentRequest()
+ .path("/{id}")
+ .buildAndExpand(poll.getId())
+ .toUri();
+ responseHeaders.setLocation(newPollUri);
+ return new ResponseEntity<>(null, HttpStatus.CREATED);
+ }
+
+ @Valid
+ @RequestMapping(value="/polls/{pollId}", method=RequestMethod.GET)
+ public ResponseEntity> getPoll(@PathVariable Long pollId) throws ResourceNotFoundException {
+ verifyPoll(pollId);
+ Poll p = pollRepository.findOne(pollId);
+ return new ResponseEntity<> (p, HttpStatus.OK);
+ }
+
+ @Valid
+ @RequestMapping(value="/polls/{pollId}", method=RequestMethod.PUT)
+ public ResponseEntity> updatePoll(@RequestBody Poll poll, @PathVariable Long pollId) throws ResourceNotFoundException {
+ // Save the entity
+ verifyPoll(pollId);
+ Poll p = pollRepository.save(poll);
+ return new ResponseEntity<>(HttpStatus.OK);
+ }
+
+ @RequestMapping(value="/polls/{pollId}", method=RequestMethod.DELETE)
+ public ResponseEntity> deletePoll(@PathVariable Long pollId) throws ResourceNotFoundException {
+ verifyPoll(pollId);
+ pollRepository.delete(pollId);
+ return new ResponseEntity<>(HttpStatus.OK);
+ }
+
+ public void verifyPoll(@PathVariable Long pollId) throws ResourceNotFoundException {
+ Poll p = pollRepository.findOne(pollId);
+ if (p == null) {
+ throw new ResourceNotFoundException("Poll with id " + pollId + " not found");
+
+ }
+ }
+}
diff --git a/src/main/java/io/zipcoder/tc_spring_poll_application/controller/VoteController.java b/src/main/java/io/zipcoder/tc_spring_poll_application/controller/VoteController.java
new file mode 100644
index 0000000..91c28da
--- /dev/null
+++ b/src/main/java/io/zipcoder/tc_spring_poll_application/controller/VoteController.java
@@ -0,0 +1,39 @@
+package io.zipcoder.tc_spring_poll_application.controller;
+
+import io.zipcoder.tc_spring_poll_application.domain.Vote;
+import io.zipcoder.tc_spring_poll_application.repositories.VoteRepository;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
+
+import javax.inject.Inject;
+
+ @RestController
+ public class VoteController {
+ @Inject
+ private VoteRepository voteRepository;
+
+ @RequestMapping(value = "/polls/{pollId}/votes", method = RequestMethod.POST)
+ public ResponseEntity> createVote(@PathVariable Long pollId, @RequestBody Vote
+ vote) {
+ vote = voteRepository.save(vote);
+ // Set the headers for the newly created resource
+ HttpHeaders responseHeaders = new HttpHeaders();
+ responseHeaders.setLocation(ServletUriComponentsBuilder.
+ fromCurrentRequest().path("/{id}").buildAndExpand(vote.getId()).toUri());
+ return new ResponseEntity<>(null, responseHeaders, HttpStatus.CREATED);
+ }
+
+ @RequestMapping(value="/polls/votes", method=RequestMethod.GET)
+ public Iterable getAllVotes() {
+ return voteRepository.findAll();
+ }
+
+ @RequestMapping(value="/polls/{pollId}/votes", method=RequestMethod.GET)
+ public Iterable getVote(@PathVariable Long pollId) {
+ return voteRepository.findByPoll(pollId);
+ }
+ }
+
diff --git a/src/main/java/io/zipcoder/tc_spring_poll_application/domain/Option.java b/src/main/java/io/zipcoder/tc_spring_poll_application/domain/Option.java
new file mode 100644
index 0000000..0da78c5
--- /dev/null
+++ b/src/main/java/io/zipcoder/tc_spring_poll_application/domain/Option.java
@@ -0,0 +1,45 @@
+package io.zipcoder.tc_spring_poll_application.domain;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+
+@Entity
+public class Option {
+
+ @Column(name = "OPTION_ID")
+ @GeneratedValue
+ @Id
+ private Long id;
+
+ @Column(name = "POLL_ID")
+ private Long pollId;
+
+ @Column(name = "OPTION_VALUE")
+ private String value;
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public void setValue(String value) {
+ this.value = value;
+ }
+
+ public Long getPollId() {
+ return pollId;
+ }
+
+ public void setPollId(Long pollId) {
+ this.pollId = pollId;
+ }
+}
diff --git a/src/main/java/io/zipcoder/tc_spring_poll_application/domain/Poll.java b/src/main/java/io/zipcoder/tc_spring_poll_application/domain/Poll.java
new file mode 100644
index 0000000..54c3ba2
--- /dev/null
+++ b/src/main/java/io/zipcoder/tc_spring_poll_application/domain/Poll.java
@@ -0,0 +1,50 @@
+package io.zipcoder.tc_spring_poll_application.domain;
+
+import org.hibernate.validator.constraints.NotEmpty;
+
+import javax.persistence.*;
+import javax.validation.constraints.Size;
+import java.util.Set;
+
+@Entity
+public class Poll {
+
+ @Column(name = "POLL_ID")
+ @GeneratedValue
+ @Id
+ private Long id;
+
+ @Column(name = "QUESTION")
+ @NotEmpty
+ private String question;
+
+ @OrderBy
+ @JoinColumn(name = "OPTION_ID")
+ @OneToMany(cascade = CascadeType.ALL)
+ @Size(min=2, max=6)
+ private Set