Skip to content
Snippets Groups Projects
Commit 0e221b90 authored by Marnuri Nitish -'s avatar Marnuri Nitish -
Browse files

Resolve merge conflict and fix edit issue

parents 17431505 1d8aecc4
No related branches found
No related tags found
No related merge requests found
Showing
with 384 additions and 31 deletions
package polish_community_group_11.polish_community.comments.controllers;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestParam;
import polish_community_group_11.polish_community.comments.models.Comment;
import polish_community_group_11.polish_community.comments.models.NewComment;
import polish_community_group_11.polish_community.comments.services.CommentService;
import polish_community_group_11.polish_community.feed.models.Feed;
import polish_community_group_11.polish_community.feed.services.FeedService;
import java.lang.invoke.MethodHandles;
@RestController
@RequestMapping("/feed/comments")
//@RequiredArgsConstructor
public class CommentController {
private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
private final CommentService commentService;
private final FeedService feedService;
@Autowired
public CommentController(CommentService commentService, FeedService feedService) {
this.commentService = commentService;
this.feedService = feedService;
}
@PostMapping("/comments/publish")
public ResponseEntity<Comment> publishComment(@RequestBody NewComment newComment) {
LOG.info("Received new comment {}", newComment);
Feed feed = feedService.getFeedById(newComment.getPostId());
Comment comment = commentService.publishComment(feed, newComment.getContent());
return ResponseEntity.ok(comment);
}
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteComment(@PathVariable Integer id) {
commentService.deleteComment(id);
return ResponseEntity.noContent().build();
}
}
package polish_community_group_11.polish_community.comments.controllers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.servlet.ModelAndView;
import polish_community_group_11.polish_community.comments.services.CommentService;
import polish_community_group_11.polish_community.feed.repository.FeedRepositoryImpl;
@Controller
public class FeedWithCommentsController {
private FeedRepositoryImpl feedRepository;
private CommentService commentService;
@Autowired
public FeedWithCommentsController(FeedRepositoryImpl feedRepository, CommentService commentService){
this.feedRepository = feedRepository;
this.commentService = commentService;
}
@GetMapping("/feed-with-comments")
public ModelAndView getFeed(){
ModelAndView modelAndView = new ModelAndView("feed/feedWithComments");
modelAndView.addObject("posts" , feedRepository.getAllPosts());
// Fetch comments for each post and add to model
modelAndView.addObject("commentService", commentService);
return modelAndView;
}
}
package polish_community_group_11.polish_community.comments.dao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;
import polish_community_group_11.polish_community.comments.models.Comment;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
@Repository
public class CommentJdbcRepository implements CommentRepository {
private final JdbcTemplate jdbcTemplate;
@Autowired
public CommentJdbcRepository(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
@Override
public Comment save(Comment comment) {
String sql = "INSERT INTO comment (comment_content, user_id, post_id, created_date) VALUES (?, ?, ?, ?)";
jdbcTemplate.update(sql,
comment.getContent(),
comment.getUserId(),
comment.getPostId(),
comment.getCreatedDate()
);
// Retrieve the last inserted ID
Integer commentId = jdbcTemplate.queryForObject("SELECT LAST_INSERT_ID()", Integer.class);
comment.setId(commentId);
return comment;
}
@Override
public List<Comment> findByPostId(int postId) {
String sql = "SELECT c.id, c.comment_content, c.user_id, c.post_id, c.created_date, " +
"u.fullname as username, u.email as user_email " +
"FROM comment c " +
"JOIN users u ON c.user_id = u.id " +
"WHERE c.post_id = ?";
return jdbcTemplate.query(sql, new CommentRowMapper(), postId);
}
private static class CommentRowMapper implements RowMapper<Comment> {
@Override
public Comment mapRow(ResultSet rs, int rowNum) throws SQLException {
Comment comment = new Comment();
comment.setId(rs.getInt("id"));
comment.setContent(rs.getString("comment_content"));
comment.setUserId(rs.getInt("user_id"));
comment.setPostId(rs.getInt("post_id"));
comment.setCreatedDate(rs.getTimestamp("created_date").toLocalDateTime());
comment.setUsername(rs.getString("username"));
comment.setUserEmail(rs.getString("user_email"));
return comment;
}
}
@Override
public void deleteById(Integer id) {
String sql = "DELETE FROM comment WHERE id = ?";
jdbcTemplate.update(sql, id);
}
}
\ No newline at end of file
package polish_community_group_11.polish_community.comments.dao;
import polish_community_group_11.polish_community.comments.models.Comment;
import java.util.List;
public interface CommentRepository {
Comment save(Comment comment);
List<Comment> findByPostId(int postId);
void deleteById(Integer id);
}
package polish_community_group_11.polish_community.comments.models;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDateTime;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Comment {
private Integer id;
private String content;
private int userId;
private int postId;
private String userEmail;
private String username;
private LocalDateTime createdDate;
// Constructor without id for creating new comments
public Comment(String content, int userId, int postId, String userEmail, String username, LocalDateTime createdDate) {
this.content = content;
this.userId = userId;
this.postId = postId;
this.userEmail = userEmail;
this.username = username;
this.createdDate = createdDate;
}
}
package polish_community_group_11.polish_community.comments.models;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class CommentResponse {
private String content;
private String postTitle;
private String createdDate;
private String username;
}
\ No newline at end of file
package polish_community_group_11.polish_community.comments.models;
import jakarta.persistence.Column;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class NewComment {
private String content;
private int postId;
}
package polish_community_group_11.polish_community.comments.services;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import polish_community_group_11.polish_community.comments.dao.CommentRepository;
import polish_community_group_11.polish_community.comments.models.Comment;
import polish_community_group_11.polish_community.feed.models.Feed;
import polish_community_group_11.polish_community.register.models.User;
import polish_community_group_11.polish_community.register.dao.UserRepository;
import java.lang.invoke.MethodHandles;
import java.time.LocalDateTime;
import java.util.List;
@Service
public class CommentService {
private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
private CommentRepository commentRepository;
private UserRepository userRepository;
@Autowired
public CommentService(CommentRepository commentRepository, UserRepository userRepository) {
this.commentRepository = commentRepository;
this.userRepository = userRepository;
}
public List<Comment> findAllCommentsByPostId(int postId) {
LOG.info("Finding comments for: {}", postId);
return commentRepository.findByPostId(postId);
}
public Comment publishComment(Feed feed, String content) {
String userEmail = SecurityContextHolder.getContext().getAuthentication().getName();
User user = userRepository.findByEmail(userEmail);
Comment comment = new Comment(
content,
user.getId(),
feed.getPostId(),
userEmail,
user.getFullname(),
LocalDateTime.now()
);
return commentRepository.save(comment);
}
public void deleteComment(Integer id) {
commentRepository.deleteById(id);
}
}
......@@ -11,6 +11,9 @@ import org.springframework.web.servlet.ModelAndView;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import polish_community_group_11.polish_community.event.models.viewmodel.EventForm;
import org.springframework.web.bind.annotation.*;
import polish_community_group_11.polish_community.event.models.Event;
import polish_community_group_11.polish_community.event.models.EventImpl;
import polish_community_group_11.polish_community.event.services.EventService;
import java.sql.SQLException;
......@@ -18,8 +21,7 @@ import java.sql.SQLException;
@Controller
public class EventController {
// Inject the EventRepository service to handle event-related data operations
private final EventService eventService;
private EventService eventService;
@Autowired
// Constructor-based dependency injection for EventRepository
......@@ -64,22 +66,46 @@ public class EventController {
@GetMapping("event/add")
public ModelAndView addEvent() {
ModelAndView modelAndView = new ModelAndView("event/add-event");
modelAndView.addObject("newEvent", new EventForm());
modelAndView.addObject("event", new EventForm());
modelAndView.addObject("formAction", "/event/add");
return modelAndView;
}
@PostMapping("event/add")
public ModelAndView addEvent(@Valid @ModelAttribute("newEvent") EventForm newEvent,
public ModelAndView addEvent(@Valid @ModelAttribute("event") EventForm event,
BindingResult bindingResult, Model model) throws SQLException {
ModelAndView modelAndView = new ModelAndView("event/add-event");
if(bindingResult.hasErrors()) {
modelAndView.addObject(model.asMap());
}
else{
if(newEvent==null){
if(event==null){
throw new NullPointerException("New event is empty or null");
}
eventService.addNewEvent(newEvent.processEventForm(newEvent));
eventService.addNewEvent(event.processEventForm());
modelAndView.setViewName("redirect:/event");
}
return modelAndView;
}
//Update Events
@GetMapping("event/edit/{id}")
public ModelAndView editEvent(@PathVariable int id) {
EventForm event = eventService.getEventById(id).processEventToEventForm();
ModelAndView modelAndView = new ModelAndView("event/add-event");
modelAndView.addObject("event", event);
modelAndView.addObject("formAction", "/event/edit");
return modelAndView;
}
@PostMapping("/event/edit")
public ModelAndView editEvent(@ModelAttribute("event") EventForm event, BindingResult bindingResult, Model model) throws SQLException {
ModelAndView modelAndView = new ModelAndView("event/add-event");
if (bindingResult.hasErrors()) {
modelAndView.addObject(model.asMap());
} else {
int id = event.getEvent_id();
eventService.getEditEvent(event.processEventForm());
modelAndView.setViewName("redirect:/event");
}
return modelAndView;
......
......@@ -11,4 +11,5 @@ public interface EventRepository {
Event getEventById(int id);
void addNewEvent(Event newEvent) throws SQLException;
Event editEvent(Event event)throws SQLException;
}
......@@ -6,12 +6,8 @@ import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;
import polish_community_group_11.polish_community.event.models.Event;
import polish_community_group_11.polish_community.event.models.EventImpl;
import polish_community_group_11.polish_community.information.models.DBInfo;
import java.sql.SQLException;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
@Repository // Marks this class as a Spring Data repository for database interaction
......@@ -107,4 +103,38 @@ public class EventRepositoryImpl implements EventRepository {
throw new SQLException("Failed to insert new information record", e);
}
}
// Updates selected record with new updated information
public Event editEvent(Event event)throws SQLException {
String updateSql = "UPDATE event " +
"SET event_title = ?, event_description = ?, " +
"event_date = ?, event_time = ?, " +
"location = ?, user_id = ?, event_poster_url = ?, " +
"whyJoin = ?, benefits = ? " +
"WHERE event_id = ?";
try {
// jdbc.update() is a method that will execute the sql query
// replaces the ? with the actual values from the news object
int rowsAffected = jdbc.update(updateSql,
event.getEvent_title(),
event.getDescription(),
event.getEvent_date(),
event.getEvent_time(),
event.getLocation(),
event.getUser_id(),
event.getImageUrl(),
event.getWhyJoin(),
event.getBenefits(),
event.getEvent_id()
);
// error handling
if (rowsAffected == 0) {
throw new SQLException("No event item was updated. Check the ID provided.");
}
} catch (DataAccessException e) {
throw new SQLException("Error updating event with ID: " + event.getEvent_id(), e);
}
return event;
}
}
package polish_community_group_11.polish_community.event.models;
import polish_community_group_11.polish_community.event.models.viewmodel.EventForm;
import java.time.LocalDate;
import java.time.LocalTime;
......@@ -27,4 +29,5 @@ public interface Event {
public String getBenefits();
public void setBenefits(String benefits);
EventForm processEventToEventForm();
}
package polish_community_group_11.polish_community.event.models;
import jakarta.validation.constraints.FutureOrPresent;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Pattern;
import lombok.AllArgsConstructor;
import lombok.Data;
import org.hibernate.validator.constraints.URL;
import polish_community_group_11.polish_community.event.models.viewmodel.EventForm;
import java.time.LocalDate;
import java.time.LocalTime;
......@@ -19,4 +25,13 @@ public class EventImpl implements Event{
private String imageUrl;
private String whyJoin;
private String benefits;
public EventForm processEventToEventForm(){
EventForm eventForm = new EventForm(
event_id, event_title, description, event_date, event_time,
location, user_id, imageUrl, whyJoin, benefits
);
return eventForm;
}
}
......@@ -38,32 +38,24 @@ public class EventForm {
private String whyJoin;
private String benefits;
public Event processEventForm(EventForm eventForm){
public Event processEventForm(){
if (eventForm.getEvent_title() == null || eventForm.getEvent_title().isEmpty()) {
if (event_title == null || event_title.isEmpty()) {
throw new IllegalArgumentException("Event title is required");
}
if (eventForm.getEvent_date() == null) {
if (event_date == null) {
throw new IllegalArgumentException("Event date is required");
}
if (eventForm.getEvent_time() == null) {
if (event_time == null) {
throw new IllegalArgumentException("Event time is required");
}
if (eventForm.getLocation() == null || eventForm.getLocation().isEmpty()) {
if (location == null || location.isEmpty()) {
throw new IllegalArgumentException("Location is required");
}
Event event = new EventImpl(
eventForm.getEvent_id(),
eventForm.getEvent_title(),
eventForm.getDescription(),
eventForm.getEvent_date(),
eventForm.getEvent_time(),
eventForm.getLocation(),
eventForm.getUser_id(),
eventForm.getImageUrl(),
eventForm.getWhyJoin(),
eventForm.getBenefits()
event_id, event_title, description, event_date, event_time,
location, user_id, imageUrl, whyJoin, benefits
);
return event;
}
......
package polish_community_group_11.polish_community.event.services;
import polish_community_group_11.polish_community.event.models.Event;
import polish_community_group_11.polish_community.event.models.viewmodel.EventForm;
import java.sql.SQLException;
import java.util.List;
public interface EventService {
List<Event> getAllEvents();
Event getEventById(int id);
void addNewEvent(Event newEvent) throws SQLException;
Event getEditEvent(Event event) throws SQLException;
}
\ No newline at end of file
package polish_community_group_11.polish_community.event.services;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import polish_community_group_11.polish_community.event.dao.EventRepository;
import polish_community_group_11.polish_community.event.models.Event;
import polish_community_group_11.polish_community.event.models.viewmodel.EventForm;
import polish_community_group_11.polish_community.event.models.EventImpl;
import java.sql.SQLException;
import java.util.List;
@Service
public class EventServiceImpl implements EventService {
private final EventRepository eventRepository;
@Autowired
public EventServiceImpl(EventRepository eventRepository){
this.eventRepository = eventRepository;
}
public List<Event> getAllEvents(){
return eventRepository.getAllEvents();
}
......@@ -26,4 +27,8 @@ public class EventServiceImpl implements EventService {
public void addNewEvent(Event newEvent) throws SQLException {
eventRepository.addNewEvent(newEvent);
}
public Event getEditEvent(Event event) throws SQLException {
return eventRepository.editEvent(event);
}
}
package polish_community_group_11.polish_community.exception;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import java.lang.invoke.MethodHandles;
import java.time.ZoneId;
import java.time.ZonedDateTime;
@ControllerAdvice
public class ApiExceptionHandler {
private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
@ExceptionHandler(value = {EmptyResultDataAccessException.class})
public ResponseEntity<Object> handleEmptyResultDataAccessException(EmptyResultDataAccessException e) {
return buildResponse(e, HttpStatus.NOT_FOUND);
......@@ -45,6 +50,7 @@ public class ApiExceptionHandler {
// Generic method to build the response entity
private ResponseEntity<Object> buildResponse(Exception e, HttpStatus status) {
LOG.error("Returning {} status for error {}", status, e.getMessage(), e);
ApiException apiException = new ApiException(
e.getMessage(),
status,
......
......@@ -30,5 +30,6 @@ public interface Feed {
int getLikesCount();
void setLikesCount(int likesCount);
int getPostId();
}
\ No newline at end of file
package polish_community_group_11.polish_community.feed.repository;
import polish_community_group_11.polish_community.feed.models.Feed;
import polish_community_group_11.polish_community.feed.models.FeedImpl;
import java.util.List;
......
......@@ -3,6 +3,7 @@ package polish_community_group_11.polish_community.feed.repository;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;
import polish_community_group_11.polish_community.feed.models.Feed;
import polish_community_group_11.polish_community.feed.models.FeedImpl;
import java.util.List;
......@@ -16,6 +17,7 @@ public class FeedRepositoryImpl implements FeedRepository {
this.jdbcTemplate = jdbcTemplate;
this.feedMapper = (rs, rowNum) -> {
FeedImpl feed = new FeedImpl();
feed.setPostId(rs.getInt("post_id"));
feed.setPostImageUrl(rs.getString("post_image_url"));
feed.setPostTitle(rs.getString("post_title"));
feed.setPostDescription(rs.getString("post_description"));
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment