From 85b3775a9a82a36d94a0b254776fc031c2ef9b46 Mon Sep 17 00:00:00 2001 From: Yavuz Tas Date: Thu, 1 Aug 2019 14:25:02 +0200 Subject: [PATCH 01/12] implement hexagonal architecture pattern --- .../hexagonal/AccountApplication.java | 21 ++++++++ .../com/baeldung/hexagonal/IOCContainer.java | 54 +++++++++++++++++++ .../hexagonal/central/domain/Account.java | 42 +++++++++++++++ .../hexagonal/central/domain/AccountType.java | 7 +++ .../repository/IAccountRepository.java | 9 ++++ .../central/service/AccountService.java | 32 +++++++++++ .../central/service/IAccountService.java | 7 +++ .../hexagonal/central/ui/IAccountUI.java | 9 ++++ .../baeldung/hexagonal/input/ConsoleUI.java | 54 +++++++++++++++++++ .../output/InMemoryAccountRepository.java | 23 ++++++++ 10 files changed, 258 insertions(+) create mode 100644 patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/AccountApplication.java create mode 100644 patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/IOCContainer.java create mode 100644 patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/central/domain/Account.java create mode 100644 patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/central/domain/AccountType.java create mode 100644 patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/central/repository/IAccountRepository.java create mode 100644 patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/central/service/AccountService.java create mode 100644 patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/central/service/IAccountService.java create mode 100644 patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/central/ui/IAccountUI.java create mode 100644 patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/input/ConsoleUI.java create mode 100644 patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/output/InMemoryAccountRepository.java diff --git a/patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/AccountApplication.java b/patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/AccountApplication.java new file mode 100644 index 0000000000..d4dd34312d --- /dev/null +++ b/patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/AccountApplication.java @@ -0,0 +1,21 @@ +package com.baeldung.hexagonal; + +import java.util.Map; + +import com.baeldung.hexagonal.input.ConsoleUI; + +public class AccountApplication extends IOCContainer { + + public static void main(String[] args) { + + AccountApplication app = new AccountApplication(); + + ConsoleUI console = app.get(ConsoleUI.class); + console.printWelcomeMessage(); + + Map parameters = console.readParameters(); + console.create(parameters); + + } + +} diff --git a/patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/IOCContainer.java b/patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/IOCContainer.java new file mode 100644 index 0000000000..49ff1955ee --- /dev/null +++ b/patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/IOCContainer.java @@ -0,0 +1,54 @@ +package com.baeldung.hexagonal; + +import com.baeldung.hexagonal.central.service.AccountService; +import com.baeldung.hexagonal.central.service.IAccountService; +import com.baeldung.hexagonal.input.ConsoleUI; +import com.baeldung.hexagonal.output.InMemoryAccountRepository; + +public class IOCContainer { + + private ConsoleUI consoleAdapter; + private AccountService accountService; + private InMemoryAccountRepository inMemoryAccountRepository; + + public T get(Class clazz) { + + if (ConsoleUI.class.isAssignableFrom(clazz)) { + return (T) getConsoleAdapter(); + } + + if (IAccountService.class.isAssignableFrom(clazz)) { + return (T) getAccountService(); + } + + if (InMemoryAccountRepository.class.isAssignableFrom(clazz)) { + return (T) getInMemoryAccountRepository(); + } + + return null; + } + + private ConsoleUI getConsoleAdapter() { + if (consoleAdapter == null) { + consoleAdapter = new ConsoleUI(); + consoleAdapter.setAccountService(getAccountService()); + } + return consoleAdapter; + } + + private IAccountService getAccountService() { + if (accountService == null) { + accountService = new AccountService(); + accountService.setAccountRepository(getInMemoryAccountRepository()); + } + return accountService; + } + + private InMemoryAccountRepository getInMemoryAccountRepository() { + if (inMemoryAccountRepository == null) { + inMemoryAccountRepository = new InMemoryAccountRepository(); + } + return inMemoryAccountRepository; + } + +} diff --git a/patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/central/domain/Account.java b/patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/central/domain/Account.java new file mode 100644 index 0000000000..2ecb602690 --- /dev/null +++ b/patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/central/domain/Account.java @@ -0,0 +1,42 @@ +package com.baeldung.hexagonal.central.domain; + +import java.util.UUID; + +public class Account { + + private UUID id; + + private String name; + + private AccountType type; + + public UUID getId() { + return id; + } + + public void setId(UUID id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public AccountType getType() { + return type; + } + + public void setType(AccountType type) { + this.type = type; + } + + @Override + public String toString() { + return "Account [name=" + name + ", type=" + type + "]"; + } + +} diff --git a/patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/central/domain/AccountType.java b/patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/central/domain/AccountType.java new file mode 100644 index 0000000000..a0ec54ce7f --- /dev/null +++ b/patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/central/domain/AccountType.java @@ -0,0 +1,7 @@ +package com.baeldung.hexagonal.central.domain; + +public enum AccountType { + + USER, MODERATOR, ADMIN + +} diff --git a/patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/central/repository/IAccountRepository.java b/patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/central/repository/IAccountRepository.java new file mode 100644 index 0000000000..6863d04740 --- /dev/null +++ b/patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/central/repository/IAccountRepository.java @@ -0,0 +1,9 @@ +package com.baeldung.hexagonal.central.repository; + +import com.baeldung.hexagonal.central.domain.Account; + +public interface IAccountRepository { + + public void save(Account account); + +} diff --git a/patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/central/service/AccountService.java b/patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/central/service/AccountService.java new file mode 100644 index 0000000000..97fa1fd7f9 --- /dev/null +++ b/patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/central/service/AccountService.java @@ -0,0 +1,32 @@ +package com.baeldung.hexagonal.central.service; + +import com.baeldung.hexagonal.central.domain.Account; +import com.baeldung.hexagonal.central.domain.AccountType; +import com.baeldung.hexagonal.central.repository.IAccountRepository; + +public class AccountService implements IAccountService { + + private IAccountRepository accountRepository; + + public void setAccountRepository(IAccountRepository accountRepository) { + this.accountRepository = accountRepository; + } + + @Override + public void createAccount(String name, String type) { + + Account account = new Account(); + account.setName(name); + + if ("user".equals(type)) { + account.setType(AccountType.USER); + } + if ("mod".equals(type)) { + account.setType(AccountType.MODERATOR); + } + + accountRepository.save(account); + + } + +} diff --git a/patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/central/service/IAccountService.java b/patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/central/service/IAccountService.java new file mode 100644 index 0000000000..1df98ef49e --- /dev/null +++ b/patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/central/service/IAccountService.java @@ -0,0 +1,7 @@ +package com.baeldung.hexagonal.central.service; + +public interface IAccountService { + + public void createAccount(String name, String type); + +} diff --git a/patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/central/ui/IAccountUI.java b/patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/central/ui/IAccountUI.java new file mode 100644 index 0000000000..fbb7cef914 --- /dev/null +++ b/patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/central/ui/IAccountUI.java @@ -0,0 +1,9 @@ +package com.baeldung.hexagonal.central.ui; + +import java.util.Map; + +public interface IAccountUI { + + public void create(Map parameters); + +} diff --git a/patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/input/ConsoleUI.java b/patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/input/ConsoleUI.java new file mode 100644 index 0000000000..7c1bacfac3 --- /dev/null +++ b/patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/input/ConsoleUI.java @@ -0,0 +1,54 @@ +package com.baeldung.hexagonal.input; + +import java.util.HashMap; +import java.util.Map; +import java.util.Scanner; + +import com.baeldung.hexagonal.central.service.IAccountService; +import com.baeldung.hexagonal.central.ui.IAccountUI; + +public class ConsoleUI implements IAccountUI { + + private IAccountService accountService; + + public void setAccountService(IAccountService accountService) { + this.accountService = accountService; + } + + public void printWelcomeMessage() { + + StringBuilder sb = new StringBuilder(); + sb.append("Welcome to Account Application!"); + sb.append("\n"); + sb.append("Usage:"); + sb.append("* new account:"); + sb.append("\tcreate "); + + System.out.println(sb.toString()); + } + + public Map readParameters() { + + Scanner scanner = new Scanner(System.in); + + Map params = new HashMap<>(); + + String name = scanner.next(); + String type = scanner.next(); + + params.put("name", name); + params.put("type", type); + + return params; + } + + @Override + public void create(Map parameters) { + + String name = parameters.get("name"); + String type = parameters.get("type"); + + accountService.createAccount(name, type); + } + +} diff --git a/patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/output/InMemoryAccountRepository.java b/patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/output/InMemoryAccountRepository.java new file mode 100644 index 0000000000..22924e6b23 --- /dev/null +++ b/patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/output/InMemoryAccountRepository.java @@ -0,0 +1,23 @@ +package com.baeldung.hexagonal.output; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +import com.baeldung.hexagonal.central.domain.Account; +import com.baeldung.hexagonal.central.repository.IAccountRepository; + +public class InMemoryAccountRepository implements IAccountRepository { + + private List accountList = new ArrayList<>(); + + @Override + public void save(Account account) { + + account.setId(UUID.randomUUID()); + + accountList.add(account); + + } + +} From f17b11fd6821abaf632da8a7114bd8fa058676f0 Mon Sep 17 00:00:00 2001 From: Yavuz Tas Date: Fri, 9 Aug 2019 21:13:10 +0200 Subject: [PATCH 02/12] Add source code for article BAEL-2463 --- .../com/baeldung/jackson/entities/File.java | 25 +++ .../com/baeldung/jackson/entities/Folder.java | 82 +++++++++ .../FolderBeanSerializerModifier.java | 21 +++ .../custom/serializer/FolderSerializer.java | 36 ++++ ...derSerializerWithCallingOwnSerializer.java | 30 ++++ ...SerializerWithDefaultSerializerStored.java | 35 ++++ ...derSerializerWithInternalObjectMapper.java | 34 ++++ ...olderSerializerWithSerializerProvider.java | 29 +++ .../CallingDefaultSerializerUnitTest.java | 166 ++++++++++++++++++ 9 files changed, 458 insertions(+) create mode 100644 jackson-2/src/main/java/com/baeldung/jackson/entities/File.java create mode 100644 jackson-2/src/main/java/com/baeldung/jackson/entities/Folder.java create mode 100644 jackson-2/src/main/java/com/baeldung/jackson/serialization/custom/serializer/FolderBeanSerializerModifier.java create mode 100644 jackson-2/src/main/java/com/baeldung/jackson/serialization/custom/serializer/FolderSerializer.java create mode 100644 jackson-2/src/main/java/com/baeldung/jackson/serialization/custom/serializer/FolderSerializerWithCallingOwnSerializer.java create mode 100644 jackson-2/src/main/java/com/baeldung/jackson/serialization/custom/serializer/FolderSerializerWithDefaultSerializerStored.java create mode 100644 jackson-2/src/main/java/com/baeldung/jackson/serialization/custom/serializer/FolderSerializerWithInternalObjectMapper.java create mode 100644 jackson-2/src/main/java/com/baeldung/jackson/serialization/custom/serializer/FolderSerializerWithSerializerProvider.java create mode 100644 jackson-2/src/test/java/com/baeldung/jackson/serialization/custom/serializer/CallingDefaultSerializerUnitTest.java diff --git a/jackson-2/src/main/java/com/baeldung/jackson/entities/File.java b/jackson-2/src/main/java/com/baeldung/jackson/entities/File.java new file mode 100644 index 0000000000..0e8829e927 --- /dev/null +++ b/jackson-2/src/main/java/com/baeldung/jackson/entities/File.java @@ -0,0 +1,25 @@ +package com.baeldung.jackson.entities; + +public class File { + + private Long id; + + private String name; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + +} \ No newline at end of file diff --git a/jackson-2/src/main/java/com/baeldung/jackson/entities/Folder.java b/jackson-2/src/main/java/com/baeldung/jackson/entities/Folder.java new file mode 100644 index 0000000000..c49e46b204 --- /dev/null +++ b/jackson-2/src/main/java/com/baeldung/jackson/entities/Folder.java @@ -0,0 +1,82 @@ +package com.baeldung.jackson.entities; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import com.fasterxml.jackson.annotation.JsonIgnore; + +public class Folder { + + private Long id; + + private String name; + + private String owner; + + private Date created; + + private Date modified; + + private Date lastAccess; + + @JsonIgnore + private List files = new ArrayList<>(); + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getOwner() { + return owner; + } + + public void setOwner(String owner) { + this.owner = owner; + } + + public Date getCreated() { + return created; + } + + public void setCreated(Date created) { + this.created = created; + } + + public Date getModified() { + return modified; + } + + public void setModified(Date modified) { + this.modified = modified; + } + + public Date getLastAccess() { + return lastAccess; + } + + public void setLastAccess(Date lastAccess) { + this.lastAccess = lastAccess; + } + + public List getFiles() { + return files; + } + + public void setFiles(List files) { + this.files = files; + } + +} \ No newline at end of file diff --git a/jackson-2/src/main/java/com/baeldung/jackson/serialization/custom/serializer/FolderBeanSerializerModifier.java b/jackson-2/src/main/java/com/baeldung/jackson/serialization/custom/serializer/FolderBeanSerializerModifier.java new file mode 100644 index 0000000000..a3add58dc4 --- /dev/null +++ b/jackson-2/src/main/java/com/baeldung/jackson/serialization/custom/serializer/FolderBeanSerializerModifier.java @@ -0,0 +1,21 @@ +package com.baeldung.jackson.serialization.custom.serializer; + +import com.baeldung.jackson.entities.Folder; +import com.fasterxml.jackson.databind.BeanDescription; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializationConfig; +import com.fasterxml.jackson.databind.ser.BeanSerializerModifier; + +public class FolderBeanSerializerModifier extends BeanSerializerModifier { + + @Override + public JsonSerializer modifySerializer(SerializationConfig config, BeanDescription beanDesc, JsonSerializer serializer) { + + if (beanDesc.getBeanClass().equals(Folder.class)) { + return new FolderSerializerWithDefaultSerializerStored((JsonSerializer) serializer); + } + + return serializer; + } + +} diff --git a/jackson-2/src/main/java/com/baeldung/jackson/serialization/custom/serializer/FolderSerializer.java b/jackson-2/src/main/java/com/baeldung/jackson/serialization/custom/serializer/FolderSerializer.java new file mode 100644 index 0000000000..f385e63e09 --- /dev/null +++ b/jackson-2/src/main/java/com/baeldung/jackson/serialization/custom/serializer/FolderSerializer.java @@ -0,0 +1,36 @@ +package com.baeldung.jackson.serialization.custom.serializer; + +import java.io.IOException; + +import com.baeldung.jackson.entities.File; +import com.baeldung.jackson.entities.Folder; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.ser.std.StdSerializer; + +public class FolderSerializer extends StdSerializer { + + public FolderSerializer() { + super(Folder.class); + } + + @Override + public void serialize(Folder value, JsonGenerator gen, SerializerProvider provider) throws IOException { + + gen.writeStartObject(); + gen.writeStringField("name", value.getName()); + + gen.writeArrayFieldStart("files"); + for (File file : value.getFiles()) { + gen.writeStartObject(); + gen.writeNumberField("id", file.getId()); + gen.writeStringField("name", file.getName()); + gen.writeEndObject(); + } + gen.writeEndArray(); + + gen.writeEndObject(); + + } + +} diff --git a/jackson-2/src/main/java/com/baeldung/jackson/serialization/custom/serializer/FolderSerializerWithCallingOwnSerializer.java b/jackson-2/src/main/java/com/baeldung/jackson/serialization/custom/serializer/FolderSerializerWithCallingOwnSerializer.java new file mode 100644 index 0000000000..ed5d9fffb8 --- /dev/null +++ b/jackson-2/src/main/java/com/baeldung/jackson/serialization/custom/serializer/FolderSerializerWithCallingOwnSerializer.java @@ -0,0 +1,30 @@ +package com.baeldung.jackson.serialization.custom.serializer; + +import java.io.IOException; + +import com.baeldung.jackson.entities.Folder; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.ser.std.StdSerializer; + +public class FolderSerializerWithCallingOwnSerializer extends StdSerializer { + + public FolderSerializerWithCallingOwnSerializer() { + super(Folder.class); + } + + @Override + public void serialize(Folder value, JsonGenerator gen, SerializerProvider provider) throws IOException { + + gen.writeStartObject(); + gen.writeStringField("name", value.getName()); + + provider.defaultSerializeField("files", value.getFiles(), gen); + + provider.defaultSerializeField("details", value, gen); + + gen.writeEndObject(); + + } + +} diff --git a/jackson-2/src/main/java/com/baeldung/jackson/serialization/custom/serializer/FolderSerializerWithDefaultSerializerStored.java b/jackson-2/src/main/java/com/baeldung/jackson/serialization/custom/serializer/FolderSerializerWithDefaultSerializerStored.java new file mode 100644 index 0000000000..d4a95cd939 --- /dev/null +++ b/jackson-2/src/main/java/com/baeldung/jackson/serialization/custom/serializer/FolderSerializerWithDefaultSerializerStored.java @@ -0,0 +1,35 @@ +package com.baeldung.jackson.serialization.custom.serializer; + +import java.io.IOException; + +import com.baeldung.jackson.entities.Folder; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.ser.std.StdSerializer; + +public class FolderSerializerWithDefaultSerializerStored extends StdSerializer { + + private final JsonSerializer defaultSerializer; + + public FolderSerializerWithDefaultSerializerStored(JsonSerializer defaultSerializer) { + super(Folder.class); + this.defaultSerializer = defaultSerializer; + } + + @Override + public void serialize(Folder value, JsonGenerator gen, SerializerProvider provider) throws IOException { + + gen.writeStartObject(); + gen.writeStringField("name", value.getName()); + + provider.defaultSerializeField("files", value.getFiles(), gen); + + gen.writeFieldName("details"); + defaultSerializer.serialize(value, gen, provider); + + gen.writeEndObject(); + + } + +} diff --git a/jackson-2/src/main/java/com/baeldung/jackson/serialization/custom/serializer/FolderSerializerWithInternalObjectMapper.java b/jackson-2/src/main/java/com/baeldung/jackson/serialization/custom/serializer/FolderSerializerWithInternalObjectMapper.java new file mode 100644 index 0000000000..b23dc32205 --- /dev/null +++ b/jackson-2/src/main/java/com/baeldung/jackson/serialization/custom/serializer/FolderSerializerWithInternalObjectMapper.java @@ -0,0 +1,34 @@ +package com.baeldung.jackson.serialization.custom.serializer; + +import java.io.IOException; + +import com.baeldung.jackson.entities.Folder; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.ser.std.StdSerializer; + +public class FolderSerializerWithInternalObjectMapper extends StdSerializer { + + public FolderSerializerWithInternalObjectMapper() { + super(Folder.class); + } + + @Override + public void serialize(Folder value, JsonGenerator gen, SerializerProvider provider) throws IOException { + + gen.writeStartObject(); + gen.writeStringField("name", value.getName()); + + // we access internal mapper to delegate the serialization of File list + ObjectMapper mapper = (ObjectMapper) gen.getCodec(); + + gen.writeFieldName("files"); + String stringValue = mapper.writeValueAsString(value.getFiles()); + gen.writeRawValue(stringValue); + + gen.writeEndObject(); + + } + +} diff --git a/jackson-2/src/main/java/com/baeldung/jackson/serialization/custom/serializer/FolderSerializerWithSerializerProvider.java b/jackson-2/src/main/java/com/baeldung/jackson/serialization/custom/serializer/FolderSerializerWithSerializerProvider.java new file mode 100644 index 0000000000..81990a084d --- /dev/null +++ b/jackson-2/src/main/java/com/baeldung/jackson/serialization/custom/serializer/FolderSerializerWithSerializerProvider.java @@ -0,0 +1,29 @@ +package com.baeldung.jackson.serialization.custom.serializer; + +import java.io.IOException; + +import com.baeldung.jackson.entities.Folder; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.ser.std.StdSerializer; + +public class FolderSerializerWithSerializerProvider extends StdSerializer { + + public FolderSerializerWithSerializerProvider() { + super(Folder.class); + } + + @Override + public void serialize(Folder value, JsonGenerator gen, SerializerProvider provider) throws IOException { + + gen.writeStartObject(); + gen.writeStringField("name", value.getName()); + + // we delegate the File list serialization to its default serializer + provider.defaultSerializeField("files", value.getFiles(), gen); + + gen.writeEndObject(); + + } + +} \ No newline at end of file diff --git a/jackson-2/src/test/java/com/baeldung/jackson/serialization/custom/serializer/CallingDefaultSerializerUnitTest.java b/jackson-2/src/test/java/com/baeldung/jackson/serialization/custom/serializer/CallingDefaultSerializerUnitTest.java new file mode 100644 index 0000000000..b067e7b501 --- /dev/null +++ b/jackson-2/src/test/java/com/baeldung/jackson/serialization/custom/serializer/CallingDefaultSerializerUnitTest.java @@ -0,0 +1,166 @@ +package com.baeldung.jackson.serialization.custom.serializer; + +import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.io.IOException; +import java.time.Instant; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.junit.Before; +import org.junit.Test; + +import com.baeldung.jackson.entities.File; +import com.baeldung.jackson.entities.Folder; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.module.SimpleModule; + +public class CallingDefaultSerializerUnitTest { + + private ObjectMapper mapper; + private Folder mockFolder; + private TypeReference> mapType; + + @Before + public void setup() { + + mapType = new TypeReference>() { + }; + + mapper = new ObjectMapper(); + + mockFolder = new Folder(); + mockFolder.setId(1L); + mockFolder.setName("Root Folder"); + mockFolder.setOwner("root"); + mockFolder.setCreated(Date.from(Instant.now().minusSeconds(60))); + mockFolder.setModified(Date.from(Instant.now().minusSeconds(30))); + mockFolder.setLastAccess(Date.from(Instant.now())); + + File file1 = new File(); + file1.setId(1L); + file1.setName("File 1"); + + File file2 = new File(); + file2.setId(2L); + file2.setName("File 2"); + + List files = new ArrayList<>(); + files.add(file1); + files.add(file2); + mockFolder.setFiles(files); + + } + + @Test + public void givenFolder_whenSerialized_onlyNameAndFilesFieldsSerialized() throws IOException { + + SimpleModule module = new SimpleModule(); + module.addSerializer(new FolderSerializer()); + mapper.registerModule(module); + + String json = mapper.writeValueAsString(mockFolder); + + HashMap actual = mapper.readValue(json, mapType); + + assertTrue(actual.containsKey("name")); + assertTrue(actual.containsKey("files")); + assertEquals(mockFolder.getName(), actual.get("name")); + + List actualFiles = (List) actual.get("files"); + assertEquals(mockFolder.getFiles().size(), actualFiles.size()); + + } + + @Test + public void givenFolder_whenSerializedWithSerializerProvider_onlyNameAndFilesFieldsSerialized() throws IOException { + + SimpleModule module = new SimpleModule(); + module.addSerializer(new FolderSerializerWithSerializerProvider()); + mapper.registerModule(module); + + String json = mapper.writeValueAsString(mockFolder); + + HashMap actual = mapper.readValue(json, mapType); + + assertTrue(actual.containsKey("name")); + assertTrue(actual.containsKey("files")); + assertEquals(mockFolder.getName(), actual.get("name")); + + List actualFiles = (List) actual.get("files"); + assertEquals(mockFolder.getFiles().size(), actualFiles.size()); + + } + + @Test + public void givenFolder_whenSerializedWithInternalObjectMapper_onlyNameAndFilesFieldsSerialized() throws IOException { + + SimpleModule module = new SimpleModule(); + module.addSerializer(new FolderSerializerWithInternalObjectMapper()); + mapper.registerModule(module); + + String json = mapper.writeValueAsString(mockFolder); + + HashMap actual = mapper.readValue(json, mapType); + + assertTrue(actual.containsKey("name")); + assertTrue(actual.containsKey("files")); + assertEquals(mockFolder.getName(), actual.get("name")); + + List actualFiles = (List) actual.get("files"); + assertEquals(mockFolder.getFiles().size(), actualFiles.size()); + + } + + @Test(expected = StackOverflowError.class) + public void givenFolder_whenSerializedWithCallingOwnSerializer_exceptionOccured() throws IOException { + + SimpleModule module = new SimpleModule(); + module.addSerializer(new FolderSerializerWithCallingOwnSerializer()); + mapper.registerModule(module); + + mapper.writeValueAsString(mockFolder); + + } + + @Test + public void givenFolder_whenSerializedWithDefaultSerializerStored_NameAndFilesAndDetailsFieldsSerialized() throws IOException { + + SimpleModule module = new SimpleModule(); + module.setSerializerModifier(new FolderBeanSerializerModifier()); + mapper.registerModule(module); + + String json = mapper.writeValueAsString(mockFolder); + + HashMap actual = mapper.readValue(json, mapType); + + assertTrue(actual.containsKey("name")); + assertTrue(actual.containsKey("files")); + assertEquals(mockFolder.getName(), actual.get("name")); + + List actualFiles = (List) actual.get("files"); + assertEquals(mockFolder.getFiles().size(), actualFiles.size()); + + Map actualDetails = (Map) actual.get("details"); + assertTrue(actualDetails.containsKey("id")); + assertTrue(actualDetails.containsKey("name")); + assertTrue(actualDetails.containsKey("owner")); + assertTrue(actualDetails.containsKey("created")); + assertTrue(actualDetails.containsKey("modified")); + assertTrue(actualDetails.containsKey("lastAccess")); + + assertEquals(mockFolder.getId().longValue(), ((Number)actualDetails.get("id")).longValue()); + assertEquals(mockFolder.getName(), actualDetails.get("name")); + assertEquals(mockFolder.getOwner(), actualDetails.get("owner")); + assertEquals(mockFolder.getCreated(), new Date((long) actualDetails.get("created"))); + assertEquals(mockFolder.getModified(), new Date((long) actualDetails.get("modified"))); + assertEquals(mockFolder.getLastAccess(), new Date((long) actualDetails.get("lastAccess"))); + + } + +} From b47497cfc2d8619be3a18d46044fe1032c8293c8 Mon Sep 17 00:00:00 2001 From: Yavuz Tas Date: Sat, 12 Oct 2019 12:41:48 +0200 Subject: [PATCH 03/12] remove evaluation article codes --- .../hexagonal/AccountApplication.java | 21 -------- .../com/baeldung/hexagonal/IOCContainer.java | 54 ------------------- .../hexagonal/central/domain/Account.java | 42 --------------- .../hexagonal/central/domain/AccountType.java | 7 --- .../repository/IAccountRepository.java | 9 ---- .../central/service/AccountService.java | 32 ----------- .../central/service/IAccountService.java | 7 --- .../hexagonal/central/ui/IAccountUI.java | 9 ---- .../baeldung/hexagonal/input/ConsoleUI.java | 54 ------------------- .../output/InMemoryAccountRepository.java | 23 -------- 10 files changed, 258 deletions(-) delete mode 100644 patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/AccountApplication.java delete mode 100644 patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/IOCContainer.java delete mode 100644 patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/central/domain/Account.java delete mode 100644 patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/central/domain/AccountType.java delete mode 100644 patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/central/repository/IAccountRepository.java delete mode 100644 patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/central/service/AccountService.java delete mode 100644 patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/central/service/IAccountService.java delete mode 100644 patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/central/ui/IAccountUI.java delete mode 100644 patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/input/ConsoleUI.java delete mode 100644 patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/output/InMemoryAccountRepository.java diff --git a/patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/AccountApplication.java b/patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/AccountApplication.java deleted file mode 100644 index d4dd34312d..0000000000 --- a/patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/AccountApplication.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.baeldung.hexagonal; - -import java.util.Map; - -import com.baeldung.hexagonal.input.ConsoleUI; - -public class AccountApplication extends IOCContainer { - - public static void main(String[] args) { - - AccountApplication app = new AccountApplication(); - - ConsoleUI console = app.get(ConsoleUI.class); - console.printWelcomeMessage(); - - Map parameters = console.readParameters(); - console.create(parameters); - - } - -} diff --git a/patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/IOCContainer.java b/patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/IOCContainer.java deleted file mode 100644 index 49ff1955ee..0000000000 --- a/patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/IOCContainer.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.baeldung.hexagonal; - -import com.baeldung.hexagonal.central.service.AccountService; -import com.baeldung.hexagonal.central.service.IAccountService; -import com.baeldung.hexagonal.input.ConsoleUI; -import com.baeldung.hexagonal.output.InMemoryAccountRepository; - -public class IOCContainer { - - private ConsoleUI consoleAdapter; - private AccountService accountService; - private InMemoryAccountRepository inMemoryAccountRepository; - - public T get(Class clazz) { - - if (ConsoleUI.class.isAssignableFrom(clazz)) { - return (T) getConsoleAdapter(); - } - - if (IAccountService.class.isAssignableFrom(clazz)) { - return (T) getAccountService(); - } - - if (InMemoryAccountRepository.class.isAssignableFrom(clazz)) { - return (T) getInMemoryAccountRepository(); - } - - return null; - } - - private ConsoleUI getConsoleAdapter() { - if (consoleAdapter == null) { - consoleAdapter = new ConsoleUI(); - consoleAdapter.setAccountService(getAccountService()); - } - return consoleAdapter; - } - - private IAccountService getAccountService() { - if (accountService == null) { - accountService = new AccountService(); - accountService.setAccountRepository(getInMemoryAccountRepository()); - } - return accountService; - } - - private InMemoryAccountRepository getInMemoryAccountRepository() { - if (inMemoryAccountRepository == null) { - inMemoryAccountRepository = new InMemoryAccountRepository(); - } - return inMemoryAccountRepository; - } - -} diff --git a/patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/central/domain/Account.java b/patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/central/domain/Account.java deleted file mode 100644 index 2ecb602690..0000000000 --- a/patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/central/domain/Account.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.baeldung.hexagonal.central.domain; - -import java.util.UUID; - -public class Account { - - private UUID id; - - private String name; - - private AccountType type; - - public UUID getId() { - return id; - } - - public void setId(UUID id) { - this.id = id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public AccountType getType() { - return type; - } - - public void setType(AccountType type) { - this.type = type; - } - - @Override - public String toString() { - return "Account [name=" + name + ", type=" + type + "]"; - } - -} diff --git a/patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/central/domain/AccountType.java b/patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/central/domain/AccountType.java deleted file mode 100644 index a0ec54ce7f..0000000000 --- a/patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/central/domain/AccountType.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.baeldung.hexagonal.central.domain; - -public enum AccountType { - - USER, MODERATOR, ADMIN - -} diff --git a/patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/central/repository/IAccountRepository.java b/patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/central/repository/IAccountRepository.java deleted file mode 100644 index 6863d04740..0000000000 --- a/patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/central/repository/IAccountRepository.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.baeldung.hexagonal.central.repository; - -import com.baeldung.hexagonal.central.domain.Account; - -public interface IAccountRepository { - - public void save(Account account); - -} diff --git a/patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/central/service/AccountService.java b/patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/central/service/AccountService.java deleted file mode 100644 index 97fa1fd7f9..0000000000 --- a/patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/central/service/AccountService.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.baeldung.hexagonal.central.service; - -import com.baeldung.hexagonal.central.domain.Account; -import com.baeldung.hexagonal.central.domain.AccountType; -import com.baeldung.hexagonal.central.repository.IAccountRepository; - -public class AccountService implements IAccountService { - - private IAccountRepository accountRepository; - - public void setAccountRepository(IAccountRepository accountRepository) { - this.accountRepository = accountRepository; - } - - @Override - public void createAccount(String name, String type) { - - Account account = new Account(); - account.setName(name); - - if ("user".equals(type)) { - account.setType(AccountType.USER); - } - if ("mod".equals(type)) { - account.setType(AccountType.MODERATOR); - } - - accountRepository.save(account); - - } - -} diff --git a/patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/central/service/IAccountService.java b/patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/central/service/IAccountService.java deleted file mode 100644 index 1df98ef49e..0000000000 --- a/patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/central/service/IAccountService.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.baeldung.hexagonal.central.service; - -public interface IAccountService { - - public void createAccount(String name, String type); - -} diff --git a/patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/central/ui/IAccountUI.java b/patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/central/ui/IAccountUI.java deleted file mode 100644 index fbb7cef914..0000000000 --- a/patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/central/ui/IAccountUI.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.baeldung.hexagonal.central.ui; - -import java.util.Map; - -public interface IAccountUI { - - public void create(Map parameters); - -} diff --git a/patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/input/ConsoleUI.java b/patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/input/ConsoleUI.java deleted file mode 100644 index 7c1bacfac3..0000000000 --- a/patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/input/ConsoleUI.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.baeldung.hexagonal.input; - -import java.util.HashMap; -import java.util.Map; -import java.util.Scanner; - -import com.baeldung.hexagonal.central.service.IAccountService; -import com.baeldung.hexagonal.central.ui.IAccountUI; - -public class ConsoleUI implements IAccountUI { - - private IAccountService accountService; - - public void setAccountService(IAccountService accountService) { - this.accountService = accountService; - } - - public void printWelcomeMessage() { - - StringBuilder sb = new StringBuilder(); - sb.append("Welcome to Account Application!"); - sb.append("\n"); - sb.append("Usage:"); - sb.append("* new account:"); - sb.append("\tcreate "); - - System.out.println(sb.toString()); - } - - public Map readParameters() { - - Scanner scanner = new Scanner(System.in); - - Map params = new HashMap<>(); - - String name = scanner.next(); - String type = scanner.next(); - - params.put("name", name); - params.put("type", type); - - return params; - } - - @Override - public void create(Map parameters) { - - String name = parameters.get("name"); - String type = parameters.get("type"); - - accountService.createAccount(name, type); - } - -} diff --git a/patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/output/InMemoryAccountRepository.java b/patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/output/InMemoryAccountRepository.java deleted file mode 100644 index 22924e6b23..0000000000 --- a/patterns/design-patterns-2/src/main/java/com/baeldung/hexagonal/output/InMemoryAccountRepository.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.baeldung.hexagonal.output; - -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; - -import com.baeldung.hexagonal.central.domain.Account; -import com.baeldung.hexagonal.central.repository.IAccountRepository; - -public class InMemoryAccountRepository implements IAccountRepository { - - private List accountList = new ArrayList<>(); - - @Override - public void save(Account account) { - - account.setId(UUID.randomUUID()); - - accountList.add(account); - - } - -} From 6ad475d93fc9b67dd0b933a7827e76382d2f30f6 Mon Sep 17 00:00:00 2001 From: Yavuz Tas Date: Sat, 12 Oct 2019 13:28:35 +0200 Subject: [PATCH 04/12] fix name clash --- annotations/{readme.md => README.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename annotations/{readme.md => README.md} (100%) diff --git a/annotations/readme.md b/annotations/README.md similarity index 100% rename from annotations/readme.md rename to annotations/README.md From 641548b00fa5fb77857dc4e24629b8cccb472572 Mon Sep 17 00:00:00 2001 From: Yavuz Tas Date: Sat, 12 Oct 2019 13:33:41 +0200 Subject: [PATCH 05/12] fix name clash --- core-java-modules/core-java-arrays-2/README.MD | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 core-java-modules/core-java-arrays-2/README.MD diff --git a/core-java-modules/core-java-arrays-2/README.MD b/core-java-modules/core-java-arrays-2/README.MD deleted file mode 100644 index f272f4d299..0000000000 --- a/core-java-modules/core-java-arrays-2/README.MD +++ /dev/null @@ -1,5 +0,0 @@ -## Relevant Articles - -- [Extending an Array’s Length](https://www.baeldung.com/java-array-add-element-at-the-end) -- [Checking If an Array Is Sorted in Java](https://www.baeldung.com/java-check-sorted-array) -- [Looping Diagonally Through a 2d Java Array](https://www.baeldung.com/java-loop-diagonal-array) From e08fce79d893bf512df4c76dd1bb3d5a333dff47 Mon Sep 17 00:00:00 2001 From: Yavuz Tas Date: Sat, 12 Oct 2019 13:36:04 +0200 Subject: [PATCH 06/12] fix name clash --- osgi/README.md | 94 +++++++++++++++++++ spring-boot-autoconfiguration/README.MD | 7 -- spring-boot-libraries/README.MD | 7 -- spring-boot-testing/README.MD | 9 -- spring-cloud-data-flow/README.MD | 2 - spring-cloud/spring-cloud-bootstrap/README.MD | 15 --- spring-cloud/spring-cloud-gateway/README.MD | 2 - spring-security-mvc-boot/README.MD | 15 --- 8 files changed, 94 insertions(+), 57 deletions(-) create mode 100644 osgi/README.md delete mode 100644 spring-boot-autoconfiguration/README.MD delete mode 100644 spring-boot-libraries/README.MD delete mode 100644 spring-boot-testing/README.MD delete mode 100644 spring-cloud-data-flow/README.MD delete mode 100644 spring-cloud/spring-cloud-bootstrap/README.MD delete mode 100644 spring-cloud/spring-cloud-gateway/README.MD delete mode 100644 spring-security-mvc-boot/README.MD diff --git a/osgi/README.md b/osgi/README.md new file mode 100644 index 0000000000..e380ae06c3 --- /dev/null +++ b/osgi/README.md @@ -0,0 +1,94 @@ +OSGi +==== + +Info +--- + +com.baeldung.osgi +com.baeldung.osgi.sample.activator + +Apache Felix +--- + + +### Start + +Download Apache Felix Framework Distribution +from +org.apache.felix.main.distribution-5.6.8 + +No! The Apache Karaf container is best. +Download it from: + +Download a binary distribution and unzip wherever you prefer. + +Then run + + bin\karaf.bat start + + +Unzip, pay attention to the files not being clipped(!). + + system:exit + +exit! + + shutdown -h + +or `^D` + +### clean start + +full clean, remove "data directory " + +or... + + bin\karaf.bat clean + + bin\start.bat clean + +### run mode + +can be launched in + +- the "regular" mode starts Apache Karaf in foreground, including the shell console. +- the "server" mode starts Apache Karaf in foreground, without the shell console. +- the "background" mode starts Apache Karaf in background. + +### Logging + +https://karaf.apache.org/manual/latest/#_log + +can be logged to console + + +### Bundle deploy + + bundle:install mvn:com.baeldung/osgi-intro-sample-activator/1.0-SNAPSHOT + + install mvn:com.baeldung/osgi-intro-sample-service/1.0-SNAPSHOT + install mvn:com.baeldung/osgi-intro-sample-client/1.0-SNAPSHOT + +Eclipse's Equinox +==== + +Eclipse's OSGi platform +http://www.eclipse.org/equinox/ + +http://www.eclipse.org/equinox/documents/quickstart-framework.php + +click on "download" + +Latest Release +Oxygen.1 Wed, 6 Sep 2017 -- 17:00 (-0400) + +org.eclipse.osgi_3.12.1.v20170821-1548.jar + + = = NOT GOOD = = + + ## Relevant articles: + - [Introduction to OSGi](http://www.baeldung.com/osgi) + + + + diff --git a/spring-boot-autoconfiguration/README.MD b/spring-boot-autoconfiguration/README.MD deleted file mode 100644 index dc9cad539a..0000000000 --- a/spring-boot-autoconfiguration/README.MD +++ /dev/null @@ -1,7 +0,0 @@ -### The Course -The "REST With Spring" Classes: http://bit.ly/restwithspring - -### Relevant Articles: - -- [Create a Custom Auto-Configuration with Spring Boot](http://www.baeldung.com/spring-boot-custom-auto-configuration) -- [Guide to ApplicationContextRunner in Spring Boot](https://www.baeldung.com/spring-boot-context-runner) diff --git a/spring-boot-libraries/README.MD b/spring-boot-libraries/README.MD deleted file mode 100644 index f3706e0fa4..0000000000 --- a/spring-boot-libraries/README.MD +++ /dev/null @@ -1,7 +0,0 @@ -### The Course -The "REST With Spring" Classes: http://bit.ly/restwithspring - -### Relevant Articles: - -- [Guide to ShedLock with Spring](https://www.baeldung.com/shedlock-spring) -- [A Guide to the Problem Spring Web Library](https://www.baeldung.com/problem-spring-web) diff --git a/spring-boot-testing/README.MD b/spring-boot-testing/README.MD deleted file mode 100644 index 7a4c4f53a1..0000000000 --- a/spring-boot-testing/README.MD +++ /dev/null @@ -1,9 +0,0 @@ -### The Course -The "REST With Spring" Classes: http://bit.ly/restwithspring - -### Relevant Articles: - -- [Testing with Spring and Spock](https://www.baeldung.com/spring-spock-testing) -- [Exclude Auto-Configuration Classes in Spring Boot Tests](https://www.baeldung.com/spring-boot-exclude-auto-configuration-test) -- [Setting the Log Level in Spring Boot when Testing](https://www.baeldung.com/spring-boot-testing-log-level) -- [Embedded Redis Server with Spring Boot Test](https://www.baeldung.com/spring-embedded-redis) diff --git a/spring-cloud-data-flow/README.MD b/spring-cloud-data-flow/README.MD deleted file mode 100644 index f2ab96de2c..0000000000 --- a/spring-cloud-data-flow/README.MD +++ /dev/null @@ -1,2 +0,0 @@ - -This is an aggregator module for Spring Cloud Data Flow modules. diff --git a/spring-cloud/spring-cloud-bootstrap/README.MD b/spring-cloud/spring-cloud-bootstrap/README.MD deleted file mode 100644 index 7a3a94c8e3..0000000000 --- a/spring-cloud/spring-cloud-bootstrap/README.MD +++ /dev/null @@ -1,15 +0,0 @@ -### Relevant Articles: -- [Spring Cloud – Bootstrapping](http://www.baeldung.com/spring-cloud-bootstrapping) -- [Spring Cloud – Securing Services](http://www.baeldung.com/spring-cloud-securing-services) -- [Spring Cloud – Tracing Services with Zipkin](http://www.baeldung.com/tracing-services-with-zipkin) -- [Spring Cloud Series – The Gateway Pattern](http://www.baeldung.com/spring-cloud-gateway-pattern) -- [Spring Cloud – Adding Angular 4](http://www.baeldung.com/spring-cloud-angular) - -- To run the project: - - copy the appliction-config folder to c:\Users\{username}\ on Windows or /home/{username}/ on *nix. Then open a git bash terminal in application-config and run: - - git init - - git add . - - git commit -m "First commit" - - start the config server - - start the discovery server - - start all the other servers in any order (gateway, svc-book, svc-rating, zipkin) diff --git a/spring-cloud/spring-cloud-gateway/README.MD b/spring-cloud/spring-cloud-gateway/README.MD deleted file mode 100644 index d945ae949c..0000000000 --- a/spring-cloud/spring-cloud-gateway/README.MD +++ /dev/null @@ -1,2 +0,0 @@ -### Relevant Articles: -- [Exploring the new Spring Cloud Gateway](http://www.baeldung.com/spring-cloud-gateway) diff --git a/spring-security-mvc-boot/README.MD b/spring-security-mvc-boot/README.MD deleted file mode 100644 index 20036283a3..0000000000 --- a/spring-security-mvc-boot/README.MD +++ /dev/null @@ -1,15 +0,0 @@ -### The Course -The "REST With Spring" Classes: http://github.learnspringsecurity.com - -### Relevant Articles: -- [A Custom Security Expression with Spring Security](http://www.baeldung.com/spring-security-create-new-custom-security-expression) -- [Custom AccessDecisionVoters in Spring Security](http://www.baeldung.com/spring-security-custom-voter) -- [Spring Security: Authentication with a Database-backed UserDetailsService](http://www.baeldung.com/spring-security-authentication-with-a-database) -- [Two Login Pages with Spring Security](http://www.baeldung.com/spring-security-two-login-pages) -- [Multiple Entry Points in Spring Security](http://www.baeldung.com/spring-security-multiple-entry-points) -- [Multiple Authentication Providers in Spring Security](http://www.baeldung.com/spring-security-multiple-auth-providers) -- [Granted Authority Versus Role in Spring Security](http://www.baeldung.com/spring-security-granted-authority-vs-role) -- [Spring Data with Spring Security](https://www.baeldung.com/spring-data-security) -- [Spring Security – Whitelist IP Range](https://www.baeldung.com/spring-security-whitelist-ip-range) -- [Find the Registered Spring Security Filters](https://www.baeldung.com/spring-security-registered-filters) -- [HTTPS using Self-Signed Certificate in Spring Boot](https://www.baeldung.com/spring-boot-https-self-signed-certificate) From f89232dd213d8ed73d4ce409b17d560ee20ff1eb Mon Sep 17 00:00:00 2001 From: Yavuz Tas Date: Mon, 21 Oct 2019 15:31:19 +0200 Subject: [PATCH 07/12] sync with upstream/master --- annotations/README.md | 7 ++++++- osgi/README.md | 17 ++++++++++------- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/annotations/README.md b/annotations/README.md index 2b052803e6..ec4005fc5e 100644 --- a/annotations/README.md +++ b/annotations/README.md @@ -1,2 +1,7 @@ +## Annotations + +This module contains articles about Java annotations + ### Relevant Articles: -- [Java Annotation Processing and Creating a Builder](http://www.baeldung.com/java-annotation-processing-builder) + +- [Java Annotation Processing and Creating a Builder](https://www.baeldung.com/java-annotation-processing-builder) diff --git a/osgi/README.md b/osgi/README.md index ec355c9773..732f624302 100644 --- a/osgi/README.md +++ b/osgi/README.md @@ -17,9 +17,9 @@ Apache Felix ### Start -Download Apache Felix Framework Distribution +Download Apache Felix Framework Distribution from -org.apache.felix.main.distribution-5.6.8 +org.apache.felix.main.distribution-5.6.8 No! The Apache Karaf container is best. Download it from: @@ -33,12 +33,12 @@ Then run Unzip, pay attention to the files not being clipped(!). - system:exit - + system:exit + exit! shutdown -h - + or `^D` ### clean start @@ -69,7 +69,7 @@ can be logged to console ### Bundle deploy bundle:install mvn:com.baeldung/osgi-intro-sample-activator/1.0-SNAPSHOT - + install mvn:com.baeldung/osgi-intro-sample-service/1.0-SNAPSHOT install mvn:com.baeldung/osgi-intro-sample-client/1.0-SNAPSHOT @@ -88,4 +88,7 @@ Oxygen.1 Wed, 6 Sep 2017 -- 17:00 (-0400) org.eclipse.osgi_3.12.1.v20170821-1548.jar - = = NOT GOOD = = + = = NOT GOOD = = + + + From b03aa3f99feefb099c20b3bb2395c6a7548df8fc Mon Sep 17 00:00:00 2001 From: Yavuz Tas Date: Mon, 21 Oct 2019 15:36:54 +0200 Subject: [PATCH 08/12] Add source code for article BAEL-3379 --- .../javaxval/messageinterpolator/Person.java | 30 ++++++++++ ...terMessageInterpolaterIntegrationTest.java | 58 +++++++++++++++++++ 2 files changed, 88 insertions(+) create mode 100644 javaxval/src/main/java/org/baeldung/javaxval/messageinterpolator/Person.java create mode 100644 javaxval/src/test/java/org/baeldung/javaxval/messageinterpolator/ParameterMessageInterpolaterIntegrationTest.java diff --git a/javaxval/src/main/java/org/baeldung/javaxval/messageinterpolator/Person.java b/javaxval/src/main/java/org/baeldung/javaxval/messageinterpolator/Person.java new file mode 100644 index 0000000000..1b6f598b60 --- /dev/null +++ b/javaxval/src/main/java/org/baeldung/javaxval/messageinterpolator/Person.java @@ -0,0 +1,30 @@ +package org.baeldung.javaxval.messageinterpolator; + +import javax.validation.constraints.Min; +import javax.validation.constraints.Size; + +public class Person { + + @Size(min = 10, max = 200, message = "Name should be in-between {min} and {max} characters") + private String name; + + @Min(value = 18, message = "Age should not be less than {value} but it is ${validatedValue}") + private int age; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + +} diff --git a/javaxval/src/test/java/org/baeldung/javaxval/messageinterpolator/ParameterMessageInterpolaterIntegrationTest.java b/javaxval/src/test/java/org/baeldung/javaxval/messageinterpolator/ParameterMessageInterpolaterIntegrationTest.java new file mode 100644 index 0000000000..877f8348d2 --- /dev/null +++ b/javaxval/src/test/java/org/baeldung/javaxval/messageinterpolator/ParameterMessageInterpolaterIntegrationTest.java @@ -0,0 +1,58 @@ +package org.baeldung.javaxval.messageinterpolator; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.Set; + +import javax.validation.ConstraintViolation; +import javax.validation.Validation; +import javax.validation.Validator; +import javax.validation.ValidatorFactory; + +import org.hibernate.validator.messageinterpolation.ParameterMessageInterpolator; +import org.junit.BeforeClass; +import org.junit.Test; + +public class ParameterMessageInterpolaterIntegrationTest { + + private static Validator validator; + + @BeforeClass + public static void beforeClass() { + ValidatorFactory validatorFactory = Validation.byDefaultProvider() + .configure() + .messageInterpolator(new ParameterMessageInterpolator()) + .buildValidatorFactory(); + + validator = validatorFactory.getValidator(); + } + + @Test + public void ifNameLengthIsLess_nameValidationFails() { + Person person = new Person(); + person.setName("John Doe"); + person.setAge(18); + + Set> violations = validator.validate(person); + assertEquals(1, violations.size()); + + ConstraintViolation violation = violations.iterator().next(); + assertEquals("Name should be in-between 10 and 200 characters", violation.getMessage()); + } + + @Test + public void ifAgeIsLess_ageMinValidationFails() { + Person person = new Person(); + person.setName("John Stephaner Doe"); + person.setAge(16); + + Set> violations = validator.validate(person); + assertEquals(1, violations.size()); + + ConstraintViolation violation = violations.iterator().next(); + assertEquals("Age should not be less than 18 but it is ${validatedValue}", violation.getMessage()); + } + +} + + From f2a06c7c34c7ae787b30af4af3332cdf93dd8a36 Mon Sep 17 00:00:00 2001 From: Yavuz Tas Date: Fri, 25 Oct 2019 14:50:02 +0200 Subject: [PATCH 09/12] Multpile issues resolved - fix formatting issues - add email field to Person - add email validation test --- .../javaxval/messageinterpolator/Person.java | 44 +++++++---- ...terMessageInterpolaterIntegrationTest.java | 76 +++++++++++-------- 2 files changed, 72 insertions(+), 48 deletions(-) diff --git a/javaxval/src/main/java/org/baeldung/javaxval/messageinterpolator/Person.java b/javaxval/src/main/java/org/baeldung/javaxval/messageinterpolator/Person.java index 1b6f598b60..b9fcfdf4d4 100644 --- a/javaxval/src/main/java/org/baeldung/javaxval/messageinterpolator/Person.java +++ b/javaxval/src/main/java/org/baeldung/javaxval/messageinterpolator/Person.java @@ -1,30 +1,42 @@ package org.baeldung.javaxval.messageinterpolator; +import javax.validation.constraints.Email; import javax.validation.constraints.Min; import javax.validation.constraints.Size; public class Person { - @Size(min = 10, max = 200, message = "Name should be in-between {min} and {max} characters") - private String name; + @Size(min = 10, max = 100, message = "Name should be between {min} and {max} characters") + private String name; - @Min(value = 18, message = "Age should not be less than {value} but it is ${validatedValue}") - private int age; + @Min(value = 18, message = "Age should not be less than {value}") + private int age; + + @Email(message = "Email address should be in a correct format: ${validatedValue}") + private String email; - public String getName() { - return name; - } + public String getName() { + return name; + } - public void setName(String name) { - this.name = name; - } + public void setName(String name) { + this.name = name; + } - public int getAge() { - return age; - } + public int getAge() { + return age; + } - public void setAge(int age) { - this.age = age; - } + public void setAge(int age) { + this.age = age; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } } diff --git a/javaxval/src/test/java/org/baeldung/javaxval/messageinterpolator/ParameterMessageInterpolaterIntegrationTest.java b/javaxval/src/test/java/org/baeldung/javaxval/messageinterpolator/ParameterMessageInterpolaterIntegrationTest.java index 877f8348d2..9badd5d5a4 100644 --- a/javaxval/src/test/java/org/baeldung/javaxval/messageinterpolator/ParameterMessageInterpolaterIntegrationTest.java +++ b/javaxval/src/test/java/org/baeldung/javaxval/messageinterpolator/ParameterMessageInterpolaterIntegrationTest.java @@ -15,44 +15,56 @@ import org.junit.Test; public class ParameterMessageInterpolaterIntegrationTest { - private static Validator validator; + private static Validator validator; - @BeforeClass - public static void beforeClass() { - ValidatorFactory validatorFactory = Validation.byDefaultProvider() - .configure() - .messageInterpolator(new ParameterMessageInterpolator()) - .buildValidatorFactory(); - - validator = validatorFactory.getValidator(); - } + @BeforeClass + public static void beforeClass() { + ValidatorFactory validatorFactory = Validation.byDefaultProvider() + .configure() + .messageInterpolator(new ParameterMessageInterpolator()) + .buildValidatorFactory(); - @Test - public void ifNameLengthIsLess_nameValidationFails() { - Person person = new Person(); - person.setName("John Doe"); - person.setAge(18); + validator = validatorFactory.getValidator(); + } - Set> violations = validator.validate(person); - assertEquals(1, violations.size()); + @Test + public void ifNameLengthIsLess_nameValidationFails() { + Person person = new Person(); + person.setName("John Doe"); + person.setAge(18); - ConstraintViolation violation = violations.iterator().next(); - assertEquals("Name should be in-between 10 and 200 characters", violation.getMessage()); - } - - @Test - public void ifAgeIsLess_ageMinValidationFails() { - Person person = new Person(); - person.setName("John Stephaner Doe"); - person.setAge(16); + Set> violations = validator.validate(person); + assertEquals(1, violations.size()); - Set> violations = validator.validate(person); - assertEquals(1, violations.size()); + ConstraintViolation violation = violations.iterator().next(); + assertEquals("Name should be between 10 and 100 characters", violation.getMessage()); + } - ConstraintViolation violation = violations.iterator().next(); - assertEquals("Age should not be less than 18 but it is ${validatedValue}", violation.getMessage()); - } + @Test + public void ifAgeIsLess_ageMinValidationFails() { + Person person = new Person(); + person.setName("John Stephaner Doe"); + person.setAge(16); -} + Set> violations = validator.validate(person); + assertEquals(1, violations.size()); + ConstraintViolation violation = violations.iterator().next(); + assertEquals("Age should not be less than 18", violation.getMessage()); + } + + @Test + public void ifEmailIsMalformed_emailFormatValidationFails() { + Person person = new Person(); + person.setName("John Stephaner Doe"); + person.setAge(18); + person.setEmail("johndoe.dev"); + + Set> violations = validator.validate(person); + assertEquals(1, violations.size()); + + ConstraintViolation violation = violations.iterator().next(); + assertEquals("Email address should be in a correct format: ${validatedValue}", violation.getMessage()); + } +} \ No newline at end of file From c8d8972a56ced8b22b9bbeba74fc6e395cb45b58 Mon Sep 17 00:00:00 2001 From: Yavuz Tas <12643010+yavuztas@users.noreply.github.com> Date: Tue, 29 Oct 2019 10:01:58 +0100 Subject: [PATCH 10/12] Update javaxval/src/test/java/org/baeldung/javaxval/messageinterpolator/ParameterMessageInterpolaterIntegrationTest.java update to use the givenX_whenY_thenZ naming convention for tests Co-Authored-By: KevinGilmore --- .../ParameterMessageInterpolaterIntegrationTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/javaxval/src/test/java/org/baeldung/javaxval/messageinterpolator/ParameterMessageInterpolaterIntegrationTest.java b/javaxval/src/test/java/org/baeldung/javaxval/messageinterpolator/ParameterMessageInterpolaterIntegrationTest.java index 9badd5d5a4..bd2f508784 100644 --- a/javaxval/src/test/java/org/baeldung/javaxval/messageinterpolator/ParameterMessageInterpolaterIntegrationTest.java +++ b/javaxval/src/test/java/org/baeldung/javaxval/messageinterpolator/ParameterMessageInterpolaterIntegrationTest.java @@ -28,7 +28,7 @@ public class ParameterMessageInterpolaterIntegrationTest { } @Test - public void ifNameLengthIsLess_nameValidationFails() { + public void givenNameLengthLessThanMin_whenValidate_thenValidationFails() { Person person = new Person(); person.setName("John Doe"); person.setAge(18); @@ -67,4 +67,4 @@ public class ParameterMessageInterpolaterIntegrationTest { assertEquals("Email address should be in a correct format: ${validatedValue}", violation.getMessage()); } -} \ No newline at end of file +} From 2f989fb4354469ca28aece46b91429018c782dfe Mon Sep 17 00:00:00 2001 From: Yavuz Tas <12643010+yavuztas@users.noreply.github.com> Date: Tue, 29 Oct 2019 10:02:16 +0100 Subject: [PATCH 11/12] Update javaxval/src/test/java/org/baeldung/javaxval/messageinterpolator/ParameterMessageInterpolaterIntegrationTest.java update to use the givenX_whenY_thenZ naming convention for tests Co-Authored-By: KevinGilmore --- .../ParameterMessageInterpolaterIntegrationTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javaxval/src/test/java/org/baeldung/javaxval/messageinterpolator/ParameterMessageInterpolaterIntegrationTest.java b/javaxval/src/test/java/org/baeldung/javaxval/messageinterpolator/ParameterMessageInterpolaterIntegrationTest.java index bd2f508784..15c451348e 100644 --- a/javaxval/src/test/java/org/baeldung/javaxval/messageinterpolator/ParameterMessageInterpolaterIntegrationTest.java +++ b/javaxval/src/test/java/org/baeldung/javaxval/messageinterpolator/ParameterMessageInterpolaterIntegrationTest.java @@ -41,7 +41,7 @@ public class ParameterMessageInterpolaterIntegrationTest { } @Test - public void ifAgeIsLess_ageMinValidationFails() { + public void givenAgeIsLessThanMin_whenValidate_thenValidationFails() { Person person = new Person(); person.setName("John Stephaner Doe"); person.setAge(16); From 8582a17ca369f8ee8590805d540ad9456ee0ca5e Mon Sep 17 00:00:00 2001 From: Yavuz Tas <12643010+yavuztas@users.noreply.github.com> Date: Tue, 29 Oct 2019 10:02:27 +0100 Subject: [PATCH 12/12] Update javaxval/src/test/java/org/baeldung/javaxval/messageinterpolator/ParameterMessageInterpolaterIntegrationTest.java update to use the givenX_whenY_thenZ naming convention for tests Co-Authored-By: KevinGilmore --- .../ParameterMessageInterpolaterIntegrationTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javaxval/src/test/java/org/baeldung/javaxval/messageinterpolator/ParameterMessageInterpolaterIntegrationTest.java b/javaxval/src/test/java/org/baeldung/javaxval/messageinterpolator/ParameterMessageInterpolaterIntegrationTest.java index 15c451348e..6ecb916ab4 100644 --- a/javaxval/src/test/java/org/baeldung/javaxval/messageinterpolator/ParameterMessageInterpolaterIntegrationTest.java +++ b/javaxval/src/test/java/org/baeldung/javaxval/messageinterpolator/ParameterMessageInterpolaterIntegrationTest.java @@ -54,7 +54,7 @@ public class ParameterMessageInterpolaterIntegrationTest { } @Test - public void ifEmailIsMalformed_emailFormatValidationFails() { + public void givenEmailIsMalformed_whenValidate_thenValidationFails() { Person person = new Person(); person.setName("John Stephaner Doe"); person.setAge(18);