Skip to content
Merged
2 changes: 1 addition & 1 deletion src/main/java/codesquad/ImsApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public static void main(String[] args) {


/**
* Todo
* Todo : Step4 ~ing
* 1. html 자원들 중복 제거하면서 스타일이 제대로 안나오는 부분이 있다, 추후 중복 제거 다시해서 레이아웃이 제대로 나오도록
* 2. 회원가입/가입정보수정 시 유효하지 않은 값 입력하고 submit 시 어떤 경우에 alert, 어떤 경우에 오류페이지 나오는지 확인 후 개선
*/
2 changes: 1 addition & 1 deletion src/main/java/codesquad/WebMvcConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void addFormatters(FormatterRegistry registry) {
registry.addConverter(new LocalDateConverter("yyyy-MM-dd"));
registry.addConverter(new LocalDateTimeConverter("yyyy-MM-dd HH:mm:ss.SSS"));
registry.addConverter(new LocalDateTimeConverter("yyyy-MM-dd'T'HH:mm"));
}

@Bean
Expand Down
24 changes: 24 additions & 0 deletions src/main/java/codesquad/converter/LocalDateTimeConverter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package codesquad.converter;

import org.springframework.core.convert.converter.Converter;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public final class LocalDateTimeConverter implements Converter<String, LocalDateTime> {

private final DateTimeFormatter formatter;

public LocalDateTimeConverter(String dateFormat) {
this.formatter = DateTimeFormatter.ofPattern(dateFormat, Locale.ENGLISH);
}

@Override
public LocalDateTime convert(String source) {
if (source == null || source.isEmpty()) {
return null;
}
return LocalDateTime.parse(source, formatter);
}
}
50 changes: 47 additions & 3 deletions src/main/java/codesquad/domain/Issue.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import codesquad.CannotDeleteException;
import codesquad.UnAuthorizedException;
import codesquad.dto.IssueDto;
import support.domain.AbstractEntity;

import javax.persistence.*;
Expand All @@ -25,8 +24,21 @@ public class Issue extends AbstractEntity {
@JoinColumn(foreignKey = @ForeignKey(name = "fk_issue_writer"))
private User writer;

@ManyToOne
@JoinColumn(foreignKey = @ForeignKey(name = "fk_issue_assignee"))
private User assignee;

@ManyToOne
@JoinColumn(foreignKey = @ForeignKey(name = "fk_issue_to_milestone"))
private Milestone milestone;

@ManyToMany
private List<Label> labels = new ArrayList<>();

private boolean deleted = false;

private boolean closed = false;

public Issue() {

}
Expand All @@ -41,6 +53,10 @@ public boolean isMatchWriter(User loginUser) {
return this.writer.equals(loginUser);
}

public boolean isClosed() {
return this.closed;
}

public void update(User loginUser, Issue target) {
if (!isMatchWriter(loginUser)) {
throw new UnAuthorizedException();
Expand All @@ -61,6 +77,30 @@ public List<DeleteHistory> delete(User loginUser) {
return temp;
}

public void toMilestone(User loginUser, Milestone milestone) {
if(!isMatchWriter(loginUser)) {
throw new UnAuthorizedException();
}

this.milestone = milestone;
}

public void assignedBy(User loginUser, User assignee) {
if (!isMatchWriter(loginUser)) {
throw new UnAuthorizedException();
}

this.assignee = assignee;
}

public void addLabel(User loginUser, Label label) {
if(!isMatchWriter(loginUser)) {
throw new UnAuthorizedException();
}

this.labels.add(label);
}

public String getSubject() {
return subject;
}
Expand All @@ -85,8 +125,12 @@ public void writeBy(User loginUser) {
this.writer = loginUser;
}

public IssueDto _toIssueDto() {
return new IssueDto(this.subject, this.comment, this.writer);
public Milestone getMilestone() {
return milestone;
}

public void setMilestone(Milestone milestone) {
this.milestone = milestone;
}

@Override
Expand Down
21 changes: 21 additions & 0 deletions src/main/java/codesquad/domain/Label.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package codesquad.domain;

import support.domain.AbstractEntity;
import javax.persistence.Entity;

@Entity
public class Label extends AbstractEntity {
private String name;

public Label() {

}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}
}
6 changes: 6 additions & 0 deletions src/main/java/codesquad/domain/LabelRepository.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package codesquad.domain;

import org.springframework.data.jpa.repository.JpaRepository;

public interface LabelRepository extends JpaRepository<Label, Long> {
}
90 changes: 90 additions & 0 deletions src/main/java/codesquad/domain/Milestone.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package codesquad.domain;

import org.hibernate.annotations.Where;
import support.domain.AbstractEntity;

import javax.persistence.*;
import javax.validation.constraints.Size;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

@Entity
public class Milestone extends AbstractEntity {
@Size(min = 1, max = 20)
@Column(nullable = false, length = 20)
private String subject;

@Column(nullable = false)
private LocalDateTime startDate;

@Column(nullable = false)
private LocalDateTime endDate;

@OneToMany(mappedBy = "milestone", cascade = CascadeType.ALL)
@Where(clause = "deleted = false")
@OrderBy("id ASC")
private List<Issue> issues = new ArrayList<>();

public Milestone() {

}

public Milestone(String subject, LocalDateTime startDate, LocalDateTime endDate) {
this.subject = subject;
this.startDate = startDate;
this.endDate = endDate;
}

public void addIssue(User loginUser, Issue issue) {
issue.toMilestone(loginUser, this);
issues.add(issue);
}

public int getCountOfClosedIssue() {
int count = 0;
for (Issue issue : issues) {
if(issue.isClosed()) {
count ++;
}
}
return count;
}

public int getCountOfOpenedIssue() {
return issues.size() - getCountOfClosedIssue();
}

public String getSubject() {
return subject;
}

public void setSubject(String subject) {
this.subject = subject;
}

public LocalDateTime getStartDate() {
return startDate;
}

public void setStartDate(LocalDateTime startDate) {
this.startDate = startDate;
}

public LocalDateTime getEndDate() {
return endDate;
}

public void setEndDate(LocalDateTime endDate) {
this.endDate = endDate;
}

public String getFormattedDueDate() {
if (endDate == null) {
return "";
}
return endDate.format(DateTimeFormatter.ofPattern("MMMM dd, yyyy", Locale.US));
}
}
6 changes: 6 additions & 0 deletions src/main/java/codesquad/domain/MilestoneRepository.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package codesquad.domain;

import org.springframework.data.jpa.repository.JpaRepository;

public interface MilestoneRepository extends JpaRepository<Milestone, Long> {
}
64 changes: 0 additions & 64 deletions src/main/java/codesquad/dto/IssueDto.java

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package codesquad.security;

import codesquad.UnAuthenticationException;
import codesquad.UnAuthorizedException;
import codesquad.domain.User;
import org.springframework.core.MethodParameter;
Expand All @@ -24,7 +25,7 @@ public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer m

LoginUser loginUser = parameter.getParameterAnnotation(LoginUser.class);
if (loginUser.required()) {
throw new UnAuthorizedException("You're required Login!");
throw new UnAuthenticationException("You're required Login!");
}
return user;
}
Expand Down
18 changes: 14 additions & 4 deletions src/main/java/codesquad/security/SecurityControllerAdvice.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package codesquad.security;

import codesquad.CannotDeleteException;
import codesquad.UnAuthenticationException;
import codesquad.UnAuthorizedException;
import org.slf4j.Logger;
Expand All @@ -8,6 +9,7 @@
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.persistence.EntityNotFoundException;

Expand All @@ -21,15 +23,23 @@ public void emptyResultData() {
log.debug("EntityNotFoundException is happened!");
}

@ExceptionHandler(UnAuthenticationException.class)
@ResponseStatus(value = HttpStatus.FOUND)
public String unAuthentication(UnAuthenticationException e, RedirectAttributes redirectAttributes) {
log.debug("UnAuthenticationException is happened! And redirect to /users/login");
redirectAttributes.addFlashAttribute("error", e.getMessage());
return "redirect:/users/login";
}

@ExceptionHandler(UnAuthorizedException.class)
@ResponseStatus(value = HttpStatus.FORBIDDEN)
public void unAuthorized() {
log.debug("UnAuthorizedException is happened!");
}

@ExceptionHandler(UnAuthenticationException.class)
@ResponseStatus(value = HttpStatus.UNAUTHORIZED)
public void unAuthentication() {
log.debug("UnAuthenticationException is happened!");
@ExceptionHandler(CannotDeleteException.class)
@ResponseStatus(value = HttpStatus.FORBIDDEN)
public void canNotDelete() {
log.debug("CannotDeleteException is happened!");
}
}
Loading