diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000..c5f3f6b
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,3 @@
+{
+ "java.configuration.updateBuildConfiguration": "interactive"
+}
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index ed84c9b..1fa25be 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,7 +1,7 @@
+ 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">
4.0.0
io.zipcoder
@@ -11,12 +11,14 @@
org.springframework.boot
spring-boot-starter-parent
1.5.3.RELEASE
-
+
UTF-8
io.zipcoder.tc_spring_poll_application.QuickPollApplication
- 1.7
+ 11
+ 11
+ 11
@@ -43,7 +45,44 @@
javax.inject
1
+
+
+
+ javax.xml.bind
+ jaxb-api
+ 2.3.1
+
+
+ org.glassfish.jaxb
+ jaxb-runtime
+ 2.3.1
+
+
+
+
+ io.springfox
+ springfox-swagger2
+ 2.7.0
+
+
+ io.springfox
+ springfox-swagger-ui
+ 2.7.0
+
+
+ com.sun.activation
+ javax.activation
+ 1.2.0
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
-
+
\ No newline at end of file
diff --git a/src/main/java/io/zipcoder/tc_spring_poll_application/config/SwaggerConfig.java b/src/main/java/io/zipcoder/tc_spring_poll_application/config/SwaggerConfig.java
new file mode 100644
index 0000000..8ba7543
--- /dev/null
+++ b/src/main/java/io/zipcoder/tc_spring_poll_application/config/SwaggerConfig.java
@@ -0,0 +1,39 @@
+package io.zipcoder.tc_spring_poll_application.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import springfox.documentation.builders.PathSelectors;
+import springfox.documentation.builders.RequestHandlerSelectors;
+import springfox.documentation.service.ApiInfo;
+import springfox.documentation.service.Contact;
+import springfox.documentation.spi.DocumentationType;
+import springfox.documentation.spring.web.plugins.Docket;
+import springfox.documentation.swagger2.annotations.EnableSwagger2;
+
+import java.util.Collections;
+
+@Configuration
+@EnableSwagger2
+public class SwaggerConfig {
+
+ @Bean
+ public Docket api() {
+ return new Docket(DocumentationType.SWAGGER_2)
+ .host("localhost:8080")
+ .select()
+ .apis(RequestHandlerSelectors.basePackage("io.zipcoder.tc_spring_poll_application.controller"))
+ .paths(PathSelectors.any())
+ .build()
+ .apiInfo(apiInfo());
+ }
+
+ private ApiInfo apiInfo() {
+ return new ApiInfo(
+ "Quick Poll API",
+ "API for managing polls and votes",
+ "1.0",
+ "Terms of service",
+ new Contact("ZipCode Wilmington", "www.zipcodewilmington.com", "info@zipcodewilmington.com"),
+ "License of API", "API license URL", Collections.emptyList());
+ }
+}
\ No newline at end of file
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..9a6b984
--- /dev/null
+++ b/src/main/java/io/zipcoder/tc_spring_poll_application/controller/PollController.java
@@ -0,0 +1,85 @@
+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 java.net.URI;
+
+import javax.validation.Valid;
+
+@RestController
+public class PollController {
+
+ private final PollRepository pollRepository;
+
+ @Autowired
+ public PollController(PollRepository pollRepository) {
+ this.pollRepository = pollRepository;
+ }
+
+ // GET all polls
+ @RequestMapping(value="/polls", method=RequestMethod.GET)
+ public ResponseEntity> getAllPolls() {
+ Iterable allPolls = pollRepository.findAll();
+ return new ResponseEntity<>(allPolls, HttpStatus.OK);
+ }
+
+ // POST a new poll
+ @RequestMapping(value="/polls", method=RequestMethod.POST)
+ public ResponseEntity> createPoll(@Valid @RequestBody Poll poll) {
+
+ poll = pollRepository.save(poll);
+
+ // Build URI for the newly created poll
+ URI newPollUri = ServletUriComponentsBuilder
+ .fromCurrentRequest()
+ .path("/{id}")
+ .buildAndExpand(poll.getId())
+ .toUri();
+
+ HttpHeaders headers = new HttpHeaders();
+ headers.setLocation(newPollUri);
+
+ return new ResponseEntity<>(headers, HttpStatus.CREATED);
+ }
+
+ // GET a single poll by ID
+ @RequestMapping(value="/polls/{pollId}", method=RequestMethod.GET)
+ public ResponseEntity> getPoll(@PathVariable Long pollId) {
+ verifyPoll(pollId);
+ Poll p = pollRepository.findOne(pollId);
+ return new ResponseEntity<>(p, HttpStatus.OK);
+ }
+
+ // UPDATE a poll
+ @RequestMapping(value="/polls/{pollId}", method=RequestMethod.PUT)
+ public ResponseEntity> updatePoll(@Valid @RequestBody Poll poll, @PathVariable Long pollId) {
+ // Optionally, you could validate pollId matches poll.getId()
+ verifyPoll(pollId);
+ pollRepository.save(poll);
+ return new ResponseEntity<>(HttpStatus.OK);
+ }
+
+ // DELETE a poll
+ @RequestMapping(value="/polls/{pollId}", method=RequestMethod.DELETE)
+ public ResponseEntity> deletePoll(@PathVariable Long pollId) {
+ verifyPoll(pollId);
+ pollRepository.delete(pollId);
+ return new ResponseEntity<>(HttpStatus.OK);
+ }
+
+ private void verifyPoll(Long pollId) {
+ Poll poll = pollRepository.findOne(pollId);
+ if (poll == 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..4ab9ef6
--- /dev/null
+++ b/src/main/java/io/zipcoder/tc_spring_poll_application/controller/VoteController.java
@@ -0,0 +1,52 @@
+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 javax.validation.Valid;
+
+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;
+
+@RestController
+public class VoteController {
+
+ private final VoteRepository voteRepository;
+
+ @Autowired
+ public VoteController(VoteRepository voteRepository) {
+ this.voteRepository = voteRepository;
+ }
+
+ // POST a new vote for a specific poll
+ @RequestMapping(value = "/polls/{pollId}/votes", method = RequestMethod.POST)
+ public ResponseEntity> createVote(@PathVariable Long pollId, @Valid @RequestBody Vote vote) {
+ vote = voteRepository.save(vote);
+
+ // Build the location URI for the newly created vote
+ HttpHeaders responseHeaders = new HttpHeaders();
+ responseHeaders.setLocation(ServletUriComponentsBuilder
+ .fromCurrentRequest()
+ .path("/{id}")
+ .buildAndExpand(vote.getId())
+ .toUri());
+
+ return new ResponseEntity<>(null, responseHeaders, HttpStatus.CREATED);
+ }
+
+ // GET all votes
+ @RequestMapping(value="/polls/votes", method=RequestMethod.GET)
+ public Iterable getAllVotes() {
+ return voteRepository.findAll();
+ }
+
+ // GET all votes for a specific poll
+ @RequestMapping(value="/polls/{pollId}/votes", method=RequestMethod.GET)
+ public Iterable getVotesByPoll(@PathVariable Long pollId) {
+ return voteRepository.findVotesByPoll(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..77cd6f4
--- /dev/null
+++ b/src/main/java/io/zipcoder/tc_spring_poll_application/domain/Option.java
@@ -0,0 +1,37 @@
+package io.zipcoder.tc_spring_poll_application.domain;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+
+@Entity
+public class Option {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.AUTO)
+ @Column(name = "OPTION_ID")
+ private Long id;
+
+ @Column(name = "OPTION_VALUE")
+ private String value;
+
+ // Getter and Setter for id
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ // Getter and Setter for value
+ public String getValue() {
+ return value;
+ }
+
+ public void setValue(String value) {
+ this.value = value;
+ }
+}
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..5bb4bb6
--- /dev/null
+++ b/src/main/java/io/zipcoder/tc_spring_poll_application/domain/Poll.java
@@ -0,0 +1,57 @@
+package io.zipcoder.tc_spring_poll_application.domain;
+
+
+import java.util.Set;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.OneToMany;
+import javax.persistence.OrderBy;
+@Entity
+public class Poll {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.AUTO)
+ @Column(name = "POLL_ID")
+ private Long id;
+
+ @Column(name = "QUESTION")
+ private String question;
+
+ @OneToMany(cascade = CascadeType.ALL)
+ @JoinColumn(name = "POLL_ID")
+ @OrderBy
+ private Set