Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added data/channels.ser
Binary file not shown.
Binary file added data/messages.ser
Binary file not shown.
Binary file added data/users.ser
Binary file not shown.
178 changes: 119 additions & 59 deletions src/main/java/com/sprint/mission/discodeit/JavaApplication.java

Large diffs are not rendered by default.

16 changes: 13 additions & 3 deletions src/main/java/com/sprint/mission/discodeit/entity/BaseEntity.java
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
package com.sprint.mission.discodeit.entity;

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

public class BaseEntity {
public class BaseEntity implements Serializable {

private UUID id;
private long createdAt;
private final long createdAt;
private long updatedAt;

@Serial
private static final long serialVersionUID = 1L; // base entity's version

public BaseEntity() {
this.id = UUID.randomUUID();
this.createdAt = System.currentTimeMillis();
Expand All @@ -22,11 +27,16 @@ public long getCreatedAt() {
return createdAt;
}

public void setUpdatedAt() {
public void updateTimeStamp() {
this.updatedAt = System.currentTimeMillis();
}

public long getUpdatedAt() {
return updatedAt;
}

// used only when we want to update user
public void setId(UUID id) {
this.id = id;
}
}
16 changes: 13 additions & 3 deletions src/main/java/com/sprint/mission/discodeit/entity/Channel.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.sprint.mission.discodeit.entity;

import java.io.Serial;
import java.io.Serializable;
import java.util.*;

public class Channel extends BaseEntity {
Expand All @@ -8,9 +10,11 @@ public class Channel extends BaseEntity {
private String channelName;

// extra fields
private List<User> users;
private final List<User> users;
private List<Message> messages;

@Serial
private static final long serialVersionUID = 1L; // channel's version

public Channel(String channelName) {
super();
Expand All @@ -25,9 +29,14 @@ public Channel(String channelName) {


// utility methods
private boolean containsUser(User user) {
return users.contains(user);
}


public void addUser(User user) {

if (!users.contains(user)) {
if (!containsUser(user)) {
users.add(user);

// extra safe checking
Expand All @@ -39,7 +48,8 @@ public void addUser(User user) {

public void deleteUser(User user) {

if (users.contains(user)) {
if (containsUser(user)) {

users.remove(user);
if (user.getChannels().contains(this)) {
user.deleteChannel(this);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
package com.sprint.mission.discodeit.entity;

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

public class Message extends BaseEntity {


// new fields
private User user;
private String message;
private Channel channel;

@Serial
private static final long serialVersionUID = 1L; // message's version

public Message(User user, String message, Channel channel) {
super();

Expand Down
34 changes: 30 additions & 4 deletions src/main/java/com/sprint/mission/discodeit/entity/User.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package com.sprint.mission.discodeit.entity;

import java.io.Serial;
import java.io.Serializable;
import java.util.*;
import java.util.regex.Pattern;

public class User extends BaseEntity {
public class User extends BaseEntity implements Serializable {

// new fields
private String email;
Expand All @@ -11,8 +14,11 @@ public class User extends BaseEntity {

// extra fields
private UserStatus userStatus;
private List<Channel> channels;
private List<Message> messages;
private final List<Channel> channels;
private final List<Message> messages;

@Serial
private static final long serialVersionUID = 1L; // user's version

/**
* member status (user statuc -> enum
Expand Down Expand Up @@ -126,7 +132,24 @@ public String getEmail() {
}

public void setEmail(String email) {
this.email = email;
if (email == null || email.isBlank()) {
throw new IllegalArgumentException("Email is null or blank");
}

// validating the format
// https://stackoverflow.com/questions/66934141/how-can-i-check-email-address-in-java
String emailRegex = "^[a-zA-Z0-9_+&*-]+(?:\\."+
"[a-zA-Z0-9_+&*-]+)*@" +
"(?:[a-zA-Z0-9-]+\\.)+[a-z" +
"A-Z]{2,7}$";

Pattern pat = Pattern.compile(emailRegex);
if (pat.matcher(email).matches()) {
this.email = email;
} else {
// ✅ ADD THIS LINE
throw new IllegalArgumentException("Invalid email format: " + email);
}
}

public String getPassword() {
Expand All @@ -141,6 +164,8 @@ public String getUserName() {
return userName;
}



public void setUserName(String userName) {
this.userName = userName;
}
Expand All @@ -154,6 +179,7 @@ public String toString() {
" email = " + this.email + ",\n" +
" password = " + this.password + "\n" +
" updatedAt = " + this.getUpdatedAt() + "\n" +
" channels = " + this.getChannels() + ",\n" +
"}";
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,60 +1,67 @@
package com.sprint.mission.discodeit.factory;

import com.sprint.mission.discodeit.repository.ChannelRepository;
import com.sprint.mission.discodeit.repository.MessageRepository;
import com.sprint.mission.discodeit.repository.UserRepository;
import com.sprint.mission.discodeit.repository.file.FileMessageRepository;
import com.sprint.mission.discodeit.service.ChannelService;
import com.sprint.mission.discodeit.service.MessageService;
import com.sprint.mission.discodeit.service.UserService;
import com.sprint.mission.discodeit.service.file.FileChannelService;
import com.sprint.mission.discodeit.service.file.FileMessageService;
import com.sprint.mission.discodeit.service.file.FileUserService;
import com.sprint.mission.discodeit.service.jcf.*;


public class ServiceFactory {

// 사용할 서비스 타입 (JCF_LIST 또는 JCF_MAP)
private final ServiceType type;

/**
* 생성자: 서비스 타입을 지정합니다.
*
* @param type 사용할 구현 방식 (JCF_LIST 또는 JCF_MAP)
* 이 클래스는 인스턴스화될 필요가 없습니다. 모든 서비스 생성 메서드는 static으로 제공됩니다.
*/
public ServiceFactory(ServiceType type) {
this.type = type;
public ServiceFactory() {
}

// MAP은 잠시 보류
/**
* 지정된 타입에 따라 UserService 인스턴스를 생성합니다.
*
* @param type 사용할 구현 방식 (JCF_LIST 또는 JCF_MAP)
* @return UserService 객체
*/

public UserService createUserService() {
public static UserService createUserService(String type, UserRepository repository) {
return switch (type) {
case JCF_LIST -> new JCFListUserService();
case JCF_MAP -> new JCFMapUserService();
case "JCF" -> new JCFListUserService(repository);
case "File" -> new FileUserService(repository);
default -> null;
};
}


/**
* 지정된 타입에 따라 ChannelService 인스턴스를 생성합니다.
*
* @param type 사용할 구현 방식 (JCF_LIST 또는 JCF_MAP)
* @return ChannelService 객체
*/

public ChannelService createChannelService() {
public static ChannelService createChannelService(String type, ChannelRepository repository) {
return switch (type) {
case JCF_LIST -> new JCFListChannelService();
case JCF_MAP -> new JCFMapChannelService();
case "JCF" -> new JCFListChannelService(repository);
case "File" -> new FileChannelService(repository);
default -> null;
};
}

/**
* 지정된 타입에 따라 MessageService 인스턴스를 생성합니다.
*
* @param type 사용할 구현 방식 (JCF_LIST 또는 JCF_MAP)
* @return MessageService 객체
*/
public MessageService createMessageService() {
public static MessageService createMessageService(String type, MessageRepository messageRepository, ChannelRepository channelRepository, UserRepository userRepository ) {
return switch (type) {
case JCF_LIST -> new JCFListMessageService();
case JCF_MAP -> new JCFMapMessageService();
case "JCF" -> new JCFListMessageService(messageRepository, channelRepository, userRepository);
case "File" -> new FileMessageService(messageRepository, channelRepository, userRepository);
default -> null;
};
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.sprint.mission.discodeit.repository;

import com.sprint.mission.discodeit.entity.Channel;
import java.util.List;
import java.util.Optional;
import java.util.UUID;

public interface ChannelRepository {

/**
* 채널 목록 전체를 저장합니다.
*
* @param channels 저장할 채널 목록
*/
void saveAll(List<Channel> channels);

/**
* 채널 목록 전체를 반환합니다.
*
* @return 전체 채널 목록
*/
List<Channel> findAll();

/**
* 주어진 ID에 해당하는 채널을 조회합니다.
*
* @param id 조회할 채널의 ID
* @return 해당 채널이 존재하면 Optional에 담아 반환, 없으면 빈 Optional 반환
*/
Optional<Channel> findVerifiedChannel(UUID id);

/**
* 채널을 저장합니다.
*
* @param channel 저장할 채널
*/
void save(Channel channel);

/**
* 채널을 삭제합니다.
*
* @param id 삭제할 채널의 ID
*/
void deleteChannel(UUID id);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package com.sprint.mission.discodeit.repository;

import com.sprint.mission.discodeit.entity.Channel;
import com.sprint.mission.discodeit.entity.Message;

import java.util.List;
import java.util.Optional;
import java.util.UUID;

public interface MessageRepository {

/**
* 메시지 목록 전체를 저장합니다.
*
* @param messages 저장할 메시지 목록
*/
void saveAll(List<Message> messages);

/**
* 모든 메시지를 반환합니다.
*
* @return 전체 메시지 목록
*/
List<Message> findAll();

/**
* 주어진 ID에 해당하는 메시지를 조회합니다.
*
* @param id 조회할 메시지의 ID
* @return 해당 ID의 메시지가 존재하면 Optional에 담아 반환, 없으면 빈 Optional 반환
*/
Optional<Message> findVerifiedMessage(UUID id);

/**
* 메세지를 저장합니다.
*
* @param message 저장할 채널
*/
void save(Message message);

/**
* 메세지를 삭제합니다.
*
* @param id 삭제할 메세지의 ID
*/
void deleteMessage(UUID id);
}
Loading