Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
55d29ff
[Refactor] Fix on Assignment 05
mikeleo03 Jun 24, 2024
77f0bea
[Refactor] Fix on Assignment 06
mikeleo03 Jun 24, 2024
05d249e
Merge pull request #1 from affandyfandy/Week_02
mikeleo03 Jul 8, 2024
2fbcaf5
[Feat] Finishing Assignment 01
mikeleo03 Jul 29, 2024
e4569e1
[Init] Initiate SpringBoot project
mikeleo03 Jul 29, 2024
f49a043
[Feat] Basic Customer CRUD
mikeleo03 Jul 29, 2024
59184c1
[Feat] Implementation done
mikeleo03 Jul 29, 2024
41c874c
[Feat] README Assignment 02
mikeleo03 Jul 29, 2024
ab5637b
[Init] Copying Assignment 02 to 03
mikeleo03 Jul 29, 2024
76e55be
[Feat] Assignment 03 done (need to add detail)
mikeleo03 Jul 30, 2024
75561e2
[Feat] Add some code documentation
mikeleo03 Jul 30, 2024
07ac8a3
[Feat] Update some commentaries and SQL data
mikeleo03 Jul 30, 2024
ea8f8db
[Feat] Update documentation
mikeleo03 Jul 30, 2024
78a99c4
[Refactor] README from Assignment 02
mikeleo03 Jul 30, 2024
c289ced
[Feat] Implementation for README from assignment 03
mikeleo03 Jul 30, 2024
128127a
[Refactor] README image redirection
mikeleo03 Jul 30, 2024
2740532
[Feat] Swagger documentation
mikeleo03 Jul 30, 2024
f9db9b2
[Init] Initiate FeignClient demo project
mikeleo03 Jul 31, 2024
aeb50e7
[Feat] FeignClient Demo done
mikeleo03 Jul 31, 2024
1274368
[Feat] Implementation of Rest Template Demo 1
mikeleo03 Jul 31, 2024
56bebcf
[Feat] Implementation of Rest Template 2
mikeleo03 Jul 31, 2024
39f535e
[Feat] Implementation of WebClient
mikeleo03 Aug 1, 2024
0f48e99
[Fix] Redirection and renaming
mikeleo03 Aug 1, 2024
0c5ee6d
[Feat] README documentation
mikeleo03 Aug 1, 2024
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
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
target
target
HELP.md
14 changes: 9 additions & 5 deletions Week 02/Lecture 03/Assignment 05/ListToMap.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.TreeMap;

// Assume Employee class with fields: int employeeID, String name, String department
class Employee {
Expand Down Expand Up @@ -46,11 +46,15 @@ public static void main(String[] args) {
new Employee(3, "Charlie", "Finance")
);

// Convert List to Map using employeeID as key
Map<Integer, Employee> employeeMap = employees.stream()
.collect(Collectors.toMap(Employee::getEmployeeID, emp -> emp));
// Creating employeeMap using TreeMap
Map<Integer, String> employeesMap = new TreeMap<>();

// Convert List to Map
for (Employee emp : employees){
employeesMap.put(emp.getEmployeeID(), emp.getName());
}

// Print the resulting Map
employeeMap.forEach((id, emp) -> System.out.println("Employee ID: " + id + ", Employee: " + emp));
employeesMap.forEach((id, emp) -> System.out.println("Employee ID: " + id + ", Employee: " + emp));
}
}
14 changes: 12 additions & 2 deletions Week 02/Lecture 03/Assignment 05/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ To remove duplicate lines from a file:
4. **Writing Unique Lines**: Write only those lines to a new file that haven't been seen before (not in the `HashSet`).

#### 📋 Case CSV Content
In this program, i use CSV file [`input.csv`](/Week%2002%20-%20Jun%2017-21/Lecture%2003/Assignment%205/data/input.csv) with content like this.
In this program, i use CSV file [`input.csv`](/Week%2002/Lecture%2003/Assignment%2005/RemoveDuplicates.java) with content like this.
```csv
employeeID,name,department
1,Alice,HR
Expand All @@ -106,6 +106,16 @@ Detail implementation is written on [this code](/Week%2002%20-%20Jun%2017-21/Lec

The output of the program shows on this [`output.csv`](/Week%2002%20-%20Jun%2017-21/Lecture%2003/Assignment%205/data/output.csv)

Here is how to run the updated code of program
```bash
$ java RemoveDuplicates <inputFile> <outputFile> <keyFieldIndex>
```

for example.
```bash
java RemoveDuplicates data/input.csv data/output.csv 0
```

<br>

### 🖨️ Task 4 - Get a Shallow Copy of a `HashMap`
Expand Down Expand Up @@ -166,7 +176,7 @@ Here i implement class `BankAccount` and `BankAccountDemo`.
3. **Use Java Streams for Transformation**: Utilize Java Streams API to transform the `List` into a `Map`.
4. **Collect into Map**: Use the `Collectors.toMap()` method to collect elements of the `List` into a `Map` using the specified key and value mappings.

Detail implementation is written on [this code](/Week%2002%20-%20Jun%2017-21/Lecture%2003/Assignment%205/ListToMap.java), and the output of the program shows like this.
Detail implementation is written on [this code](/Week%2002/Lecture%2003/Assignment%2005/ListToMap.java), and the output of the program shows like this (updated based on comment).

![Screenshot](img/Task5.png)

Expand Down
70 changes: 56 additions & 14 deletions Week 02/Lecture 03/Assignment 05/RemoveDuplicates.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,42 @@
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class RemoveDuplicates {
public static void main(String[] args) {
String inputFileName = "data/input.csv";
String outputFileName = "data/output.csv";
String delimiter = ","; // Parse CSV format

// Set to store unique keys (employeeID in this case)
if (args.length < 3) {
System.out.println("Usage: java RemoveDuplicates <inputFile> <outputFile> <keyFieldIndex>");
return;
}

String inputFileName = args[0];
String outputFileName = args[1];
int keyFieldIndex;
try {
keyFieldIndex = Integer.parseInt(args[2]);
} catch (NumberFormatException e) {
System.out.println("Invalid keyFieldIndex. It must be an integer.");
return;
}

// Set to store unique keys
Set<String> seenKeys = new HashSet<>();

try (BufferedReader reader = new BufferedReader(new FileReader(inputFileName));
PrintWriter writer = new PrintWriter(new FileWriter(outputFileName))) {

String line;
while ((line = reader.readLine()) != null) {
// Split the line into fields
String[] fields = line.split(delimiter);
// Ensure there are enough fields and key field is valid
if (fields.length > 1) {
String key = fields[0]; // Assuming employeeID is the first field
// Properly split the line respecting quoted commas
String[] fields = parseCsvLine(line);

// Ensure key field index is valid
if (fields.length > keyFieldIndex) {
String key = fields[keyFieldIndex];
if (!seenKeys.contains(key)) {
seenKeys.add(key); // Add the key to set (marks as seen)
writer.println(line); // Write the line to output
Expand All @@ -36,7 +49,36 @@ public static void main(String[] args) {
System.out.println("Duplicates removed successfully. Output written to " + outputFileName);

} catch (IOException e) {
System.out.println("I/O Error occured:" + e);
System.out.println("I/O Error occurred: " + e);
}
}
}

// Function to parse CSV line while handling commas within quotes
private static String[] parseCsvLine(String line) {
boolean inQuotes = false;
StringBuilder field = new StringBuilder();
List<String> fields = new ArrayList<>();

for (char c : line.toCharArray()) {
switch (c) {
case '"':
inQuotes = !inQuotes; // Toggle the inQuotes flag
break;
case ',':
if (inQuotes) {
field.append(c); // Inside quotes, include comma
} else {
fields.add(field.toString());
field.setLength(0); // Reset the field buffer
}
break;
default:
field.append(c); // Add character to field buffer
break;
}
}
fields.add(field.toString()); // Add last field

return fields.toArray(new String[0]);
}
}
Binary file modified Week 02/Lecture 03/Assignment 05/img/Task5.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
21 changes: 16 additions & 5 deletions Week 02/Lecture 04/Assignment 06/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,11 +119,22 @@ Here’s a detailed process on how to remove duplicate lines from files based on
4. **Write the Output**: Write the processed, duplicate-free data to a new file.

#### 👨🏻‍💻 Implementation
Detail implementation is written on [this code](/Week%2002%20-%20Jun%2017-21/Lecture%2004/Assignment%206/RemoveDuplicatesCSV.java). Here’s what the program actually done.
1. **Read All Lines**: `Files.readAllLines(Paths.get(inputFilePath))` reads the CSV file into a list of strings.
2. **Extract Header**: The first line is treated as the header to determine the key field's index.
3. **Stream Processing**: The stream skips the header, then collects lines into a map using the key field (`id`). If a duplicate key is found, the first occurrence is retained.
4. **Write Results**: The header is re-added, and the list is written to the new file.
Detail implementation is written on [this code](/Week%2002/Lecture%2004/Assignment%2006/RemoveDuplicatesCSV.java). Here’s what the program actually done (updated based on comment).
1. **Initialize Readers and Writers**
- `BufferedReader` is used to read the input CSV file line by line.
- `BufferedWriter` is used to write the unique lines to the output CSV file.
2. **Extract and Write Header**
- The first line, which is the header, is read using `reader.readLine()`.
- This header is written immediately to the output file using `writer.write(header)`.
3. **Determine Key Field Index**
- The header is split to determine the index of the key field (`id`).
- This is done by iterating through the headers to find the matching field.
4. **Stream Processing and Duplicate Removal**
- A `Set<String>` is used to keep track of the keys that have already been processed.
- For each subsequent line, the key field's value is checked against the `Set`. If the key is unique, the line is written to the output file.
5. **Read and Write Lines**
- The program continues to read each line from the input file, splits it to get the key field, and checks the key against the `Set`.
- If the key is not in the `Set`, the line is written to the output file and the key is added to the `Set`.

**Best Practices Highlighted**
1. **`BufferedReader` for Large Files**: Using `BufferedReader` with `lines()` streams data efficiently.
Expand Down
65 changes: 37 additions & 28 deletions Week 02/Lecture 04/Assignment 06/RemoveDuplicatesCSV.java
Original file line number Diff line number Diff line change
@@ -1,46 +1,55 @@
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.HashSet;
import java.util.Set;

public class RemoveDuplicatesCSV {
public static void main(String[] args) {
String inputFilePath = "data/data.csv";
String outputFilePath = "data/unique.csv";
String keyFieldName = "id";

try (BufferedReader reader = Files.newBufferedReader(Paths.get(inputFilePath))) {
List<String> lines = reader.lines().collect(Collectors.toList());
if (lines.isEmpty()) return;
try (BufferedReader reader = Files.newBufferedReader(Paths.get(inputFilePath));
BufferedWriter writer = Files.newBufferedWriter(Paths.get(outputFilePath))) {

String header = reader.readLine();
if (header == null) return;

// Extract header and determine the key field index
String header = lines.get(0);
List<String> headers = Arrays.asList(header.split(","));
int keyIndex = headers.indexOf(keyFieldName);
if (keyIndex == -1) throw new IllegalArgumentException("Invalid key field name");
// Write header to the output file
writer.write(header);
writer.newLine();

// Process lines and remove duplicates based on the key field
List<String> uniqueLines = lines.stream()
.skip(1) // Skip header
.collect(Collectors.toMap(
line -> line.split(",")[keyIndex], // Use the key field
line -> line, // Use the line as value
(existing, replacement) -> existing // Keep the first occurrence
))
.values()
.stream()
.collect(Collectors.toList());
// Determine the key field index
String[] headers = header.split(",");
int keyIndex = -1;
for (int i = 0; i < headers.length; i++) {
if (headers[i].trim().equals(keyFieldName)) {
keyIndex = i;
break;
}
}
if (keyIndex == -1) throw new IllegalArgumentException("Invalid key field name");

// Add header back to the list
uniqueLines.add(0, header);
// Use a Set to track unique keys
Set<String> seenKeys = new HashSet<>();

// Write the results to a new file
Files.write(Paths.get(outputFilePath), uniqueLines);
// Read and process each line
String line;
while ((line = reader.readLine()) != null) {
String[] fields = line.split(",");
if (fields.length > keyIndex) {
String key = fields[keyIndex];
if (seenKeys.add(key)) { // Add returns false if the key was already present
writer.write(line);
writer.newLine();
}
}
}
} catch (IOException e) {
System.out.println("I/O Error occured:" + e);
System.out.println("I/O Error occurred: " + e);
}
}
}
}
111 changes: 111 additions & 0 deletions Week 08/Lecture 13/Assignment 01/README.md

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The looks great explaination about onceperrequestfilter with example Authentication filter. Great job leon

Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
# 👨🏻‍🏫 Lecture 13 - Spring Advance Feature: Filter and Spring Interceptor
> This repository is created as a part of assignment for Lecture 13 - Spring Advance Feature: Filter and Spring Interceptor

## 🔍 Assignment 01 - Research about `onceperrequestfilter`

### 🧐 Detailed Overview

#### **What is a Filter?**
In the context of a Java web application, a filter is a component that performs tasks before or after a request is processed by a servlet. Filters can modify request and response objects, and they are useful for cross-cutting concerns like logging, authentication, and response modification.

#### **Purpose of `OncePerRequestFilter`**
The `OncePerRequestFilter` class is designed to handle cases where filters might be executed multiple times for a single request due to forwarding or including requests. This ensures that a filter’s logic is only executed once per request, preventing redundant processing and potential performance issues.

#### **How `OncePerRequestFilter` Works**

1. **Filter Lifecycle**

Filters in a web application are managed by the servlet container (e.g., Tomcat). The `OncePerRequestFilter` ensures that the `doFilterInternal` method is called only once per request.

2. **Request Wrapping**

When a request is forwarded or included, it might be wrapped in additional `ServletRequest` objects. `OncePerRequestFilter` ensures that the filtering logic is applied only once, even if the request has been wrapped multiple times.

3. **Thread Safety**

The `OncePerRequestFilter` class is designed to be thread-safe, meaning that its instance can be safely used across multiple threads handling different requests.

### 👨🏻‍💻 **Advanced Example: Authentication Filter**

Let’s create an advanced example of a filter that checks for a specific header in requests to enforce custom authentication. This example will include detailed aspects, such as handling exceptions and configuring the filter in a Spring Boot application.

#### **Authentication Filter Example**

1. **Create the Filter Class**

```java
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class CustomAuthenticationFilter extends OncePerRequestFilter {

private static final String AUTH_HEADER = "X-Custom-Auth";

@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
// Check for the custom authentication header
String authHeader = request.getHeader(AUTH_HEADER);
if (authHeader == null || !authHeader.equals("expectedValue")) {
// If the header is missing or incorrect, respond with an unauthorized status
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized");
return;
}

// Continue the request-response chain if authentication is successful
filterChain.doFilter(request, response);
}
}
```

2. **Register the Filter in Spring Boot Configuration**

In Spring Boot, we can configure the filter either by using `FilterRegistrationBean` or by annotating a configuration class.

```java
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class FilterConfig {

@Bean
public FilterRegistrationBean<CustomAuthenticationFilter> customAuthenticationFilter() {
FilterRegistrationBean<CustomAuthenticationFilter> registrationBean = new FilterRegistrationBean<>();
registrationBean.setFilter(new CustomAuthenticationFilter());
registrationBean.addUrlPatterns("/api/*"); // Apply filter to specific URL patterns
return registrationBean;
}
}
```

### 🚀 **Explanation**
Here is the explanation on what i already made on the previous segment.

1. **Filter Logic (`doFilterInternal` Method)**
- **Header Check**: The filter checks if the custom header `X-Custom-Auth` is present and has the expected value.
- **Unauthorized Response**: If the header is missing or incorrect, it sends a `401 Unauthorized` response and halts further processing.
- **Continue Chain**: If the header is valid, the request is passed down the filter chain.

2. **Filter Registration**
- **FilterRegistrationBean**: This bean registers the filter with the Spring context.
- **addUrlPatterns("/api/*")**: Specifies that the filter should be applied to URLs that start with `/api/`.

### 🔑 **Key Points**

1. **Execution Control**: `OncePerRequestFilter` ensures the filter logic is applied once per request even if the request is forwarded or included multiple times.

2. **Thread Safety**: You should be cautious about mutable state within your filter. Since filters are often accessed by multiple threads, any mutable state should be handled carefully.

3. **Exception Handling**: It’s essential to handle exceptions gracefully within filters, especially when dealing with authentication or authorization, to avoid exposing sensitive information.

4. **Configuration**: Filters can be configured to apply to specific URL patterns or to all requests, depending on your needs.
Loading