diff --git a/README.md b/README.md index 7f78cf1515..4cad075cc3 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,16 @@ -The "REST with Spring" Classes +The Courses ============================== -Here's the Master Class of REST With Spring (along with the newly announced Boot 2 material):
-**[>> THE REST WITH SPRING - MASTER CLASS](http://www.baeldung.com/rest-with-spring-course?utm_source=github&utm_medium=social&utm_content=tutorials&utm_campaign=rws#master-class)** -And here's the Master Class of Learn Spring Security:
-**[>> LEARN SPRING SECURITY - MASTER CLASS](http://www.baeldung.com/learn-spring-security-course?utm_source=github&utm_medium=social&utm_content=tutorials&utm_campaign=lss#master-class)** +Here's the new "Learn Spring" course:
+**[>> LEARN SPRING - THE MASTER CLASS](https://www.baeldung.com/learn-spring-course?utm_source=github&utm_medium=social&utm_content=tutorials&utm_campaign=ls#master-class)** + +Here's the Master Class of "REST With Spring" (along with the new announced Boot 2 material):
+**[>> THE REST WITH SPRING - MASTER CLASS](https://www.baeldung.com/rest-with-spring-course?utm_source=github&utm_medium=social&utm_content=tutorials&utm_campaign=rws#master-class)** + +And here's the Master Class of "Learn Spring Security":
+**[>> LEARN SPRING SECURITY - MASTER CLASS](https://www.baeldung.com/learn-spring-security-course?utm_source=github&utm_medium=social&utm_content=tutorials&utm_campaign=lss#master-class)** @@ -15,7 +19,7 @@ Java and Spring Tutorials This project is **a collection of small and focused tutorials** - each covering a single and well defined area of development in the Java ecosystem. A strong focus of these is, of course, the Spring Framework - Spring, Spring Boot and Spring Security. -In additional to Spring, the following technologies are in focus: `core Java`, `Jackson`, `HttpClient`, `Guava`. +In additional to Spring, the modules here are covering a number of aspects in Java. Building the project @@ -32,8 +36,15 @@ Running a Spring Boot module ==================== To run a Spring Boot module run the command: `mvn spring-boot:run` in the module directory -###Running Tests +Working with the IDE +==================== +This repo contains a large number of modules. +When you're working with an individual module, there's no need to import all of them (or build all of them) - you can simply import that particular module in either Eclipse or IntelliJ. + + +Running Tests +============= The command `mvn clean install` will run the unit tests in a module. To run the integration tests, use the command `mvn clean install -Pintegration-lite-first` diff --git a/algorithms-miscellaneous-3/README.md b/algorithms-miscellaneous-3/README.md index cd3711d573..6a38df484a 100644 --- a/algorithms-miscellaneous-3/README.md +++ b/algorithms-miscellaneous-3/README.md @@ -1,4 +1,4 @@ -## Relevant articles: +## Relevant Articles: - [Java Two Pointer Technique](https://www.baeldung.com/java-two-pointer-technique) - [Implementing Simple State Machines with Java Enums](https://www.baeldung.com/java-enum-simple-state-machine) diff --git a/algorithms-miscellaneous-3/pom.xml b/algorithms-miscellaneous-3/pom.xml index 3cebdd09ac..5999d33c86 100644 --- a/algorithms-miscellaneous-3/pom.xml +++ b/algorithms-miscellaneous-3/pom.xml @@ -1,5 +1,5 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 algorithms-miscellaneous-3 0.0.1-SNAPSHOT @@ -18,17 +18,41 @@ ${org.assertj.core.version} test - + - org.apache.commons - commons-collections4 - ${commons-collections4.version} + org.apache.commons + commons-collections4 + ${commons-collections4.version} - + - com.google.guava - guava - ${guava.version} + com.google.guava + guava + ${guava.version} + + + + com.squareup.retrofit2 + retrofit + ${retrofit.version} + + + com.squareup.retrofit2 + converter-jackson + ${retrofit.version} + + + + org.apache.commons + commons-lang3 + 3.8.1 + + + + pl.pragmatists + JUnitParams + 1.1.0 + test @@ -48,5 +72,6 @@ 3.9.0 4.3 28.0-jre + 2.6.0 \ No newline at end of file diff --git a/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/interpolationsearch/InterpolationSearch.java b/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/interpolationsearch/InterpolationSearch.java new file mode 100644 index 0000000000..91423eeaa8 --- /dev/null +++ b/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/interpolationsearch/InterpolationSearch.java @@ -0,0 +1,35 @@ +package com.baeldung.algorithms.interpolationsearch; + +public class InterpolationSearch { + + public static int interpolationSearch(int[] data, int item) { + + int highEnd = (data.length - 1); + int lowEnd = 0; + + while (item >= data[lowEnd] && item <= data[highEnd] && lowEnd <= highEnd) { + + int probe = lowEnd + (highEnd - lowEnd) * (item - data[lowEnd]) / (data[highEnd] - data[lowEnd]); + + if (highEnd == lowEnd) { + if (data[lowEnd] == item) { + return lowEnd; + } else { + return -1; + } + } + + if (data[probe] == item) { + return probe; + } + + if (data[probe] < item) { + lowEnd = probe + 1; + } else { + highEnd = probe - 1; + } + } + return -1; + } + +} diff --git a/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/kmeans/Centroid.java b/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/kmeans/Centroid.java new file mode 100644 index 0000000000..523d5b56a5 --- /dev/null +++ b/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/kmeans/Centroid.java @@ -0,0 +1,45 @@ +package com.baeldung.algorithms.kmeans; + +import java.util.Map; +import java.util.Objects; + +/** + * Encapsulates all coordinates for a particular cluster centroid. + */ +public class Centroid { + + /** + * The centroid coordinates. + */ + private final Map coordinates; + + public Centroid(Map coordinates) { + this.coordinates = coordinates; + } + + public Map getCoordinates() { + return coordinates; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Centroid centroid = (Centroid) o; + return Objects.equals(getCoordinates(), centroid.getCoordinates()); + } + + @Override + public int hashCode() { + return Objects.hash(getCoordinates()); + } + + @Override + public String toString() { + return "Centroid " + coordinates; + } +} diff --git a/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/kmeans/Distance.java b/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/kmeans/Distance.java new file mode 100644 index 0000000000..30723cb6b3 --- /dev/null +++ b/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/kmeans/Distance.java @@ -0,0 +1,20 @@ +package com.baeldung.algorithms.kmeans; + +import java.util.Map; + +/** + * Defines a contract to calculate distance between two feature vectors. The less the + * calculated distance, the more two items are similar to each other. + */ +public interface Distance { + + /** + * Calculates the distance between two feature vectors. + * + * @param f1 The first set of features. + * @param f2 The second set of features. + * @return Calculated distance. + * @throws IllegalArgumentException If the given feature vectors are invalid. + */ + double calculate(Map f1, Map f2); +} diff --git a/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/kmeans/Errors.java b/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/kmeans/Errors.java new file mode 100644 index 0000000000..3228876051 --- /dev/null +++ b/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/kmeans/Errors.java @@ -0,0 +1,23 @@ +package com.baeldung.algorithms.kmeans; + +import java.util.List; +import java.util.Map; + +/** + * Encapsulates methods to calculates errors between centroid and the cluster members. + */ +public class Errors { + + public static double sse(Map> clustered, Distance distance) { + double sum = 0; + for (Map.Entry> entry : clustered.entrySet()) { + Centroid centroid = entry.getKey(); + for (Record record : entry.getValue()) { + double d = distance.calculate(centroid.getCoordinates(), record.getFeatures()); + sum += Math.pow(d, 2); + } + } + + return sum; + } +} diff --git a/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/kmeans/EuclideanDistance.java b/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/kmeans/EuclideanDistance.java new file mode 100644 index 0000000000..193d9afed1 --- /dev/null +++ b/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/kmeans/EuclideanDistance.java @@ -0,0 +1,26 @@ +package com.baeldung.algorithms.kmeans; + +import java.util.Map; + +/** + * Calculates the distance between two items using the Euclidean formula. + */ +public class EuclideanDistance implements Distance { + + @Override + public double calculate(Map f1, Map f2) { + if (f1 == null || f2 == null) { + throw new IllegalArgumentException("Feature vectors can't be null"); + } + + double sum = 0; + for (String key : f1.keySet()) { + Double v1 = f1.get(key); + Double v2 = f2.get(key); + + if (v1 != null && v2 != null) sum += Math.pow(v1 - v2, 2); + } + + return Math.sqrt(sum); + } +} diff --git a/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/kmeans/KMeans.java b/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/kmeans/KMeans.java new file mode 100644 index 0000000000..1fb8541ff9 --- /dev/null +++ b/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/kmeans/KMeans.java @@ -0,0 +1,236 @@ +package com.baeldung.algorithms.kmeans; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Random; +import java.util.Set; + +import static java.util.stream.Collectors.toList; +import static java.util.stream.Collectors.toSet; + +/** + * Encapsulates an implementation of KMeans clustering algorithm. + * + * @author Ali Dehghani + */ +public class KMeans { + + private KMeans() { + throw new IllegalAccessError("You shouldn't call this constructor"); + } + + /** + * Will be used to generate random numbers. + */ + private static final Random random = new Random(); + + /** + * Performs the K-Means clustering algorithm on the given dataset. + * + * @param records The dataset. + * @param k Number of Clusters. + * @param distance To calculate the distance between two items. + * @param maxIterations Upper bound for the number of iterations. + * @return K clusters along with their features. + */ + public static Map> fit(List records, int k, Distance distance, int maxIterations) { + applyPreconditions(records, k, distance, maxIterations); + + List centroids = randomCentroids(records, k); + Map> clusters = new HashMap<>(); + Map> lastState = new HashMap<>(); + + // iterate for a pre-defined number of times + for (int i = 0; i < maxIterations; i++) { + boolean isLastIteration = i == maxIterations - 1; + + // in each iteration we should find the nearest centroid for each record + for (Record record : records) { + Centroid centroid = nearestCentroid(record, centroids, distance); + assignToCluster(clusters, record, centroid); + } + + // if the assignment does not change, then the algorithm terminates + boolean shouldTerminate = isLastIteration || clusters.equals(lastState); + lastState = clusters; + if (shouldTerminate) { + break; + } + + // at the end of each iteration we should relocate the centroids + centroids = relocateCentroids(clusters); + clusters = new HashMap<>(); + } + + return lastState; + } + + /** + * Move all cluster centroids to the average of all assigned features. + * + * @param clusters The current cluster configuration. + * @return Collection of new and relocated centroids. + */ + private static List relocateCentroids(Map> clusters) { + return clusters + .entrySet() + .stream() + .map(e -> average(e.getKey(), e.getValue())) + .collect(toList()); + } + + /** + * Moves the given centroid to the average position of all assigned features. If + * the centroid has no feature in its cluster, then there would be no need for a + * relocation. Otherwise, for each entry we calculate the average of all records + * first by summing all the entries and then dividing the final summation value by + * the number of records. + * + * @param centroid The centroid to move. + * @param records The assigned features. + * @return The moved centroid. + */ + private static Centroid average(Centroid centroid, List records) { + // if this cluster is empty, then we shouldn't move the centroid + if (records == null || records.isEmpty()) { + return centroid; + } + + // Since some records don't have all possible attributes, we initialize + // average coordinates equal to current centroid coordinates + Map average = centroid.getCoordinates(); + + // The average function works correctly if we clear all coordinates corresponding + // to present record attributes + records + .stream() + .flatMap(e -> e + .getFeatures() + .keySet() + .stream()) + .forEach(k -> average.put(k, 0.0)); + + for (Record record : records) { + record + .getFeatures() + .forEach((k, v) -> average.compute(k, (k1, currentValue) -> v + currentValue)); + } + + average.forEach((k, v) -> average.put(k, v / records.size())); + + return new Centroid(average); + } + + /** + * Assigns a feature vector to the given centroid. If this is the first assignment for this centroid, + * first we should create the list. + * + * @param clusters The current cluster configuration. + * @param record The feature vector. + * @param centroid The centroid. + */ + private static void assignToCluster(Map> clusters, Record record, Centroid centroid) { + clusters.compute(centroid, (key, list) -> { + if (list == null) { + list = new ArrayList<>(); + } + + list.add(record); + return list; + }); + } + + /** + * With the help of the given distance calculator, iterates through centroids and finds the + * nearest one to the given record. + * + * @param record The feature vector to find a centroid for. + * @param centroids Collection of all centroids. + * @param distance To calculate the distance between two items. + * @return The nearest centroid to the given feature vector. + */ + private static Centroid nearestCentroid(Record record, List centroids, Distance distance) { + double minimumDistance = Double.MAX_VALUE; + Centroid nearest = null; + + for (Centroid centroid : centroids) { + double currentDistance = distance.calculate(record.getFeatures(), centroid.getCoordinates()); + + if (currentDistance < minimumDistance) { + minimumDistance = currentDistance; + nearest = centroid; + } + } + + return nearest; + } + + /** + * Generates k random centroids. Before kicking-off the centroid generation process, + * first we calculate the possible value range for each attribute. Then when + * we're going to generate the centroids, we generate random coordinates in + * the [min, max] range for each attribute. + * + * @param records The dataset which helps to calculate the [min, max] range for + * each attribute. + * @param k Number of clusters. + * @return Collections of randomly generated centroids. + */ + private static List randomCentroids(List records, int k) { + List centroids = new ArrayList<>(); + Map maxs = new HashMap<>(); + Map mins = new HashMap<>(); + + for (Record record : records) { + record + .getFeatures() + .forEach((key, value) -> { + // compares the value with the current max and choose the bigger value between them + maxs.compute(key, (k1, max) -> max == null || value > max ? value : max); + + // compare the value with the current min and choose the smaller value between them + mins.compute(key, (k1, min) -> min == null || value < min ? value : min); + }); + } + + Set attributes = records + .stream() + .flatMap(e -> e + .getFeatures() + .keySet() + .stream()) + .collect(toSet()); + for (int i = 0; i < k; i++) { + Map coordinates = new HashMap<>(); + for (String attribute : attributes) { + double max = maxs.get(attribute); + double min = mins.get(attribute); + coordinates.put(attribute, random.nextDouble() * (max - min) + min); + } + + centroids.add(new Centroid(coordinates)); + } + + return centroids; + } + + private static void applyPreconditions(List records, int k, Distance distance, int maxIterations) { + if (records == null || records.isEmpty()) { + throw new IllegalArgumentException("The dataset can't be empty"); + } + + if (k <= 1) { + throw new IllegalArgumentException("It doesn't make sense to have less than or equal to 1 cluster"); + } + + if (distance == null) { + throw new IllegalArgumentException("The distance calculator is required"); + } + + if (maxIterations <= 0) { + throw new IllegalArgumentException("Max iterations should be a positive number"); + } + } +} diff --git a/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/kmeans/LastFm.java b/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/kmeans/LastFm.java new file mode 100644 index 0000000000..4694a845af --- /dev/null +++ b/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/kmeans/LastFm.java @@ -0,0 +1,144 @@ +package com.baeldung.algorithms.kmeans; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +import com.fasterxml.jackson.databind.ObjectMapper; +import okhttp3.OkHttpClient; +import retrofit2.Retrofit; +import retrofit2.converter.jackson.JacksonConverterFactory; + +import static java.util.stream.Collectors.toSet; + +public class LastFm { + + private static OkHttpClient okHttp = new OkHttpClient.Builder() + .addInterceptor(new LastFmService.Authenticator("put your API key here")) + .build(); + + private static Retrofit retrofit = new Retrofit.Builder() + .client(okHttp) + .addConverterFactory(JacksonConverterFactory.create()) + .baseUrl("http://ws.audioscrobbler.com/") + .build(); + + private static LastFmService lastFm = retrofit.create(LastFmService.class); + + private static ObjectMapper mapper = new ObjectMapper(); + + public static void main(String[] args) throws IOException { + List artists = getTop100Artists(); + Set tags = getTop100Tags(); + List records = datasetWithTaggedArtists(artists, tags); + + Map> clusters = KMeans.fit(records, 7, new EuclideanDistance(), 1000); + // Print the cluster configuration + clusters.forEach((key, value) -> { + System.out.println("------------------------------ CLUSTER -----------------------------------"); + + System.out.println(sortedCentroid(key)); + String members = String.join(", ", value + .stream() + .map(Record::getDescription) + .collect(toSet())); + System.out.print(members); + + System.out.println(); + System.out.println(); + }); + + Map json = convertToD3CompatibleMap(clusters); + System.out.println(mapper.writeValueAsString(json)); + } + + private static Map convertToD3CompatibleMap(Map> clusters) { + Map json = new HashMap<>(); + json.put("name", "Musicians"); + List> children = new ArrayList<>(); + clusters.forEach((key, value) -> { + Map child = new HashMap<>(); + child.put("name", dominantGenre(sortedCentroid(key))); + List> nested = new ArrayList<>(); + for (Record record : value) { + nested.add(Collections.singletonMap("name", record.getDescription())); + } + child.put("children", nested); + + children.add(child); + }); + json.put("children", children); + return json; + } + + private static String dominantGenre(Centroid centroid) { + return centroid + .getCoordinates() + .keySet() + .stream() + .limit(2) + .collect(Collectors.joining(", ")); + } + + private static Centroid sortedCentroid(Centroid key) { + List> entries = new ArrayList<>(key + .getCoordinates() + .entrySet()); + entries.sort((e1, e2) -> e2 + .getValue() + .compareTo(e1.getValue())); + + Map sorted = new LinkedHashMap<>(); + for (Map.Entry entry : entries) { + sorted.put(entry.getKey(), entry.getValue()); + } + + return new Centroid(sorted); + } + + private static List datasetWithTaggedArtists(List artists, Set topTags) throws IOException { + List records = new ArrayList<>(); + for (String artist : artists) { + Map tags = lastFm + .topTagsFor(artist) + .execute() + .body() + .all(); + + // Only keep popular tags. + tags + .entrySet() + .removeIf(e -> !topTags.contains(e.getKey())); + + records.add(new Record(artist, tags)); + } + return records; + } + + private static Set getTop100Tags() throws IOException { + return lastFm + .topTags() + .execute() + .body() + .all(); + } + + private static List getTop100Artists() throws IOException { + List artists = new ArrayList<>(); + for (int i = 1; i <= 2; i++) { + artists.addAll(lastFm + .topArtists(i) + .execute() + .body() + .all()); + } + + return artists; + } +} diff --git a/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/kmeans/LastFmService.java b/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/kmeans/LastFmService.java new file mode 100644 index 0000000000..db57deb888 --- /dev/null +++ b/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/kmeans/LastFmService.java @@ -0,0 +1,118 @@ +package com.baeldung.algorithms.kmeans; + +import java.io.IOException; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +import com.fasterxml.jackson.annotation.JsonAutoDetect; +import com.fasterxml.jackson.annotation.JsonProperty; +import okhttp3.HttpUrl; +import okhttp3.Interceptor; +import okhttp3.Request; +import okhttp3.Response; +import retrofit2.Call; +import retrofit2.http.GET; +import retrofit2.http.Query; + +import static com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.ANY; +import static java.util.stream.Collectors.toList; + +public interface LastFmService { + + @GET("/2.0/?method=chart.gettopartists&format=json&limit=50") + Call topArtists(@Query("page") int page); + + @GET("/2.0/?method=artist.gettoptags&format=json&limit=20&autocorrect=1") + Call topTagsFor(@Query("artist") String artist); + + @GET("/2.0/?method=chart.gettoptags&format=json&limit=100") + Call topTags(); + + /** + * HTTP interceptor to intercept all HTTP requests and add the API key to them. + */ + class Authenticator implements Interceptor { + + private final String apiKey; + + Authenticator(String apiKey) { + this.apiKey = apiKey; + } + + @Override + public Response intercept(Chain chain) throws IOException { + HttpUrl url = chain + .request() + .url() + .newBuilder() + .addQueryParameter("api_key", apiKey) + .build(); + Request request = chain + .request() + .newBuilder() + .url(url) + .build(); + + return chain.proceed(request); + } + } + + @JsonAutoDetect(fieldVisibility = ANY) + class TopTags { + + private Map tags; + + @SuppressWarnings("unchecked") + public Set all() { + List> topTags = (List>) tags.get("tag"); + return topTags + .stream() + .map(e -> ((String) e.get("name"))) + .collect(Collectors.toSet()); + } + } + + @JsonAutoDetect(fieldVisibility = ANY) + class Tags { + + @JsonProperty("toptags") private Map topTags; + + @SuppressWarnings("unchecked") + public Map all() { + try { + Map all = new HashMap<>(); + List> tags = (List>) topTags.get("tag"); + for (Map tag : tags) { + all.put(((String) tag.get("name")), ((Integer) tag.get("count")).doubleValue()); + } + + return all; + } catch (Exception e) { + return Collections.emptyMap(); + } + } + } + + @JsonAutoDetect(fieldVisibility = ANY) + class Artists { + + private Map artists; + + @SuppressWarnings("unchecked") + public List all() { + try { + List> artists = (List>) this.artists.get("artist"); + return artists + .stream() + .map(e -> ((String) e.get("name"))) + .collect(toList()); + } catch (Exception e) { + return Collections.emptyList(); + } + } + } +} diff --git a/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/kmeans/Record.java b/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/kmeans/Record.java new file mode 100644 index 0000000000..d2a7b61c62 --- /dev/null +++ b/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/kmeans/Record.java @@ -0,0 +1,65 @@ +package com.baeldung.algorithms.kmeans; + +import java.util.Map; +import java.util.Objects; + +/** + * Encapsulates all feature values for a few attributes. Optionally each record + * can be described with the {@link #description} field. + */ +public class Record { + + /** + * The record description. For example, this can be the artist name for the famous musician + * example. + */ + private final String description; + + /** + * Encapsulates all attributes and their corresponding values, i.e. features. + */ + private final Map features; + + public Record(String description, Map features) { + this.description = description; + this.features = features; + } + + public Record(Map features) { + this("", features); + } + + public String getDescription() { + return description; + } + + public Map getFeatures() { + return features; + } + + @Override + public String toString() { + String prefix = description == null || description + .trim() + .isEmpty() ? "Record" : description; + + return prefix + ": " + features; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Record record = (Record) o; + return Objects.equals(getDescription(), record.getDescription()) && Objects.equals(getFeatures(), record.getFeatures()); + } + + @Override + public int hashCode() { + return Objects.hash(getDescription(), getFeatures()); + } +} diff --git a/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/printtriangles/PrintTriangleExamples.java b/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/printtriangles/PrintTriangleExamples.java new file mode 100644 index 0000000000..a67c54a922 --- /dev/null +++ b/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/printtriangles/PrintTriangleExamples.java @@ -0,0 +1,49 @@ +package com.baeldung.algorithms.printtriangles; + +import org.apache.commons.lang3.StringUtils; + +public class PrintTriangleExamples { + + public static String printARightAngledTriangle(int N) { + StringBuilder result = new StringBuilder(); + for (int r = 1; r <= N; r++) { + for (int j = 1; j <= r; j++) { + result.append("*"); + } + result.append(System.lineSeparator()); + } + return result.toString(); + } + + public static String printAnIsoscelesTriangle(int N) { + StringBuilder result = new StringBuilder(); + for (int r = 1; r <= N; r++) { + for (int sp = 1; sp <= N - r; sp++) { + result.append(" "); + } + for (int c = 1; c <= (r * 2) - 1; c++) { + result.append("*"); + } + result.append(System.lineSeparator()); + } + return result.toString(); + } + + public static String printAnIsoscelesTriangleUsingSubstring(int N) { + StringBuilder result = new StringBuilder(); + String helperString = StringUtils.repeat(' ', N - 1) + StringUtils.repeat('*', N * 2 - 1); + + for (int r = 0; r < N; r++) { + result.append(helperString.substring(r, N + 2 * r)); + result.append(System.lineSeparator()); + } + return result.toString(); + } + + public static void main(String[] args) { + System.out.println(printARightAngledTriangle(5)); + System.out.println(printAnIsoscelesTriangle(5)); + System.out.println(printAnIsoscelesTriangleUsingSubstring(5)); + } + +} \ No newline at end of file diff --git a/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/stringsortingbynumber/NaturalOrderComparators.java b/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/stringsortingbynumber/NaturalOrderComparators.java new file mode 100644 index 0000000000..376b196aa1 --- /dev/null +++ b/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/stringsortingbynumber/NaturalOrderComparators.java @@ -0,0 +1,30 @@ +package com.baeldung.algorithms.stringsortingbynumber; + +import java.util.Comparator; + +public final class NaturalOrderComparators { + + private static final String DIGIT_AND_DECIMAL_REGEX = "[^\\d.]"; + + private NaturalOrderComparators() { + throw new AssertionError("Let's keep this static"); + } + + public static Comparator createNaturalOrderRegexComparator() { + return Comparator.comparingDouble(NaturalOrderComparators::parseStringToNumber); + } + + private static double parseStringToNumber(String input){ + + final String digitsOnly = input.replaceAll(DIGIT_AND_DECIMAL_REGEX, ""); + + if("".equals(digitsOnly)) return 0; + + try{ + return Double.parseDouble(digitsOnly); + }catch (NumberFormatException nfe){ + return 0; + } + } + +} diff --git a/algorithms-miscellaneous-3/src/main/resources/kmeans/artists.json b/algorithms-miscellaneous-3/src/main/resources/kmeans/artists.json new file mode 100644 index 0000000000..6cee0d1de2 --- /dev/null +++ b/algorithms-miscellaneous-3/src/main/resources/kmeans/artists.json @@ -0,0 +1,3384 @@ +[ + { + "description": "Billie Eilish", + "features": { + "singer-songwriter": 3.0, + "american": 23.0, + "british": 3.0, + "experimental": 3.0, + "rnb": 3.0, + "female vocalists": 49.0, + "indie": 58.0, + "chillout": 12.0, + "ambient": 3.0, + "pop": 100.0, + "synthpop": 3.0, + "electronic": 58.0, + "indie pop": 83.0, + "seen live": 18.0, + "alternative": 40.0, + "female vocalist": 9.0 + } + }, + { + "description": "Ed Sheeran", + "features": { + "indie": 12.0, + "singer-songwriter": 78.0, + "male vocalists": 13.0, + "soul": 3.0, + "chillout": 2.0, + "Mellow": 2.0, + "british": 82.0, + "pop": 23.0, + "rock": 4.0, + "rap": 2.0, + "indie pop": 3.0, + "seen live": 21.0, + "Hip-Hop": 4.0, + "acoustic": 100.0, + "alternative": 8.0, + "guitar": 2.0, + "00s": 2.0, + "Soundtrack": 1.0, + "Love": 2.0, + "folk": 12.0 + } + }, + { + "description": "Lil Nas X", + "features": { + "country": 54.0, + "male vocalists": 8.0, + "american": 24.0, + "rock": 16.0, + "pop": 8.0, + "hip hop": 47.0, + "rap": 62.0, + "Hip-Hop": 100.0, + "alternative": 24.0 + } + }, + { + "description": "Queen", + "features": { + "favorites": 2.0, + "male vocalists": 3.0, + "british": 17.0, + "classic rock": 100.0, + "rock": 81.0, + "pop": 7.0, + "heavy metal": 2.0, + "oldies": 2.0, + "seen live": 2.0, + "alternative": 4.0, + "metal": 2.0, + "Progressive rock": 6.0, + "alternative rock": 1.0, + "hard rock": 38.0, + "70s": 8.0, + "80s": 41.0, + "90s": 2.0 + } + }, + { + "description": "Ariana Grande", + "features": { + "american": 13.0, + "beautiful": 2.0, + "dance": 11.0, + "House": 2.0, + "Soundtrack": 3.0, + "chillout": 3.0, + "pop": 100.0, + "rock": 2.0, + "electronic": 3.0, + "seen live": 3.0, + "female vocalist": 3.0, + "singer-songwriter": 5.0, + "rnb": 51.0, + "female vocalists": 54.0, + "soul": 10.0, + "synthpop": 2.0, + "hip hop": 3.0, + "Hip-Hop": 3.0 + } + }, + { + "description": "Post Malone", + "features": { + "american": 8.0, + "rap": 72.0, + "rnb": 14.0, + "pop": 8.0, + "synthpop": 3.0, + "hip hop": 35.0, + "seen live": 19.0, + "Hip-Hop": 100.0 + } + }, + { + "description": "Drake", + "features": { + "indie": 4.0, + "male vocalists": 5.0, + "soul": 2.0, + "pop": 6.0, + "hip hop": 37.0, + "rap": 72.0, + "seen live": 8.0, + "Hip-Hop": 100.0, + "rnb": 50.0, + "00s": 1.0 + } + }, + { + "description": "Kanye West", + "features": { + "indie": 2.0, + "male vocalists": 3.0, + "soul": 4.0, + "american": 6.0, + "experimental": 2.0, + "pop": 6.0, + "rock": 2.0, + "electronica": 1.0, + "hip hop": 40.0, + "electronic": 3.0, + "dance": 2.0, + "rap": 69.0, + "seen live": 22.0, + "Hip-Hop": 100.0, + "rnb": 31.0, + "alternative": 3.0, + "00s": 3.0 + } + }, + { + "description": "The Beatles", + "features": { + "indie": 3.0, + "favorites": 2.0, + "male vocalists": 2.0, + "singer-songwriter": 2.0, + "Psychedelic Rock": 6.0, + "british": 58.0, + "experimental": 2.0, + "classic rock": 100.0, + "rock": 71.0, + "pop": 41.0, + "psychedelic": 13.0, + "indie rock": 2.0, + "oldies": 10.0, + "britpop": 4.0, + "alternative": 4.0, + "Progressive rock": 2.0, + "alternative rock": 1.0, + "Love": 2.0, + "folk": 1.0, + "60s": 56.0, + "70s": 3.0 + } + }, + { + "description": "Taylor Swift", + "features": { + "country": 100.0, + "singer-songwriter": 42.0, + "chillout": 2.0, + "american": 8.0, + "pop": 71.0, + "rock": 2.0, + "beautiful": 2.0, + "synthpop": 2.0, + "seen live": 4.0, + "acoustic": 31.0, + "female vocalist": 3.0, + "00s": 3.0, + "female vocalists": 60.0, + "Love": 3.0, + "folk": 2.0 + } + }, + { + "description": "Radiohead", + "features": { + "indie": 59.0, + "favorites": 2.0, + "male vocalists": 2.0, + "emo": 1.0, + "chillout": 2.0, + "british": 22.0, + "experimental": 14.0, + "ambient": 2.0, + "classic rock": 1.0, + "rock": 73.0, + "electronica": 5.0, + "psychedelic": 3.0, + "pop": 2.0, + "beautiful": 1.0, + "post-rock": 3.0, + "indie rock": 15.0, + "electronic": 48.0, + "trip-hop": 1.0, + "britpop": 17.0, + "indie pop": 1.0, + "seen live": 27.0, + "alternative": 100.0, + "Progressive rock": 6.0, + "alternative rock": 81.0, + "00s": 2.0, + "idm": 1.0, + "90s": 5.0 + } + }, + { + "description": "Beyoncé", + "features": { + "singer-songwriter": 3.0, + "jazz": 2.0, + "american": 9.0, + "beautiful": 2.0, + "dance": 13.0, + "rap": 2.0, + "rnb": 100.0, + "female vocalists": 70.0, + "Love": 3.0, + "soul": 56.0, + "pop": 91.0, + "hip hop": 5.0, + "electronic": 2.0, + "seen live": 6.0, + "Hip-Hop": 45.0, + "alternative": 1.0, + "female vocalist": 4.0, + "00s": 3.0, + "funk": 2.0 + } + }, + { + "description": "Shawn Mendes", + "features": { + "male vocalists": 28.0, + "singer-songwriter": 13.0, + "british": 7.0, + "rnb": 7.0, + "acoustic": 37.0, + "metal": 4.0, + "folk": 37.0, + "indie": 10.0, + "soul": 4.0, + "pop": 100.0, + "seen live": 13.0, + "alternative": 4.0, + "alternative rock": 4.0 + } + }, + { + "description": "David Bowie", + "features": { + "singer-songwriter": 11.0, + "male vocalists": 4.0, + "Psychedelic Rock": 2.0, + "british": 23.0, + "experimental": 9.0, + "classic rock": 86.0, + "psychedelic": 3.0, + "electronica": 2.0, + "indie rock": 2.0, + "dance": 2.0, + "post-punk": 2.0, + "punk": 2.0, + "hard rock": 3.0, + "folk": 2.0, + "70s": 15.0, + "90s": 4.0, + "indie": 6.0, + "favorites": 2.0, + "soul": 2.0, + "ambient": 2.0, + "rock": 100.0, + "pop": 19.0, + "new wave": 7.0, + "electronic": 4.0, + "oldies": 2.0, + "britpop": 2.0, + "seen live": 11.0, + "alternative": 43.0, + "Progressive rock": 4.0, + "alternative rock": 6.0, + "industrial": 2.0, + "00s": 2.0, + "60s": 3.0, + "80s": 48.0, + "funk": 2.0 + } + }, + { + "description": "Kendrick Lamar", + "features": { + "male vocalists": 2.0, + "american": 7.0, + "hip hop": 17.0, + "rap": 70.0, + "seen live": 38.0, + "Hip-Hop": 100.0, + "funk": 2.0 + } + }, + { + "description": "Rihanna", + "features": { + "american": 4.0, + "beautiful": 2.0, + "dance": 56.0, + "rap": 2.0, + "rnb": 89.0, + "House": 1.0, + "female vocalists": 63.0, + "Love": 2.0, + "soul": 4.0, + "pop": 100.0, + "rock": 2.0, + "hip hop": 6.0, + "electronic": 3.0, + "seen live": 7.0, + "Hip-Hop": 41.0, + "alternative": 1.0, + "female vocalist": 4.0, + "00s": 3.0, + "reggae": 6.0 + } + }, + { + "description": "Arctic Monkeys", + "features": { + "indie": 98.0, + "male vocalists": 2.0, + "Psychedelic Rock": 1.0, + "british": 75.0, + "rock": 63.0, + "pop": 2.0, + "punk rock": 1.0, + "indie rock": 100.0, + "britpop": 16.0, + "indie pop": 2.0, + "seen live": 45.0, + "alternative": 60.0, + "post-punk": 3.0, + "alternative rock": 19.0, + "00s": 3.0, + "punk": 2.0 + } + }, + { + "description": "Tyler, the Creator", + "features": { + "experimental": 4.0, + "american": 4.0, + "hip hop": 12.0, + "rap": 55.0, + "seen live": 15.0, + "Hip-Hop": 100.0, + "alternative": 2.0 + } + }, + { + "description": "Lana Del Rey", + "features": { + "singer-songwriter": 10.0, + "jazz": 2.0, + "american": 14.0, + "beautiful": 2.0, + "indie rock": 2.0, + "female vocalists": 100.0, + "folk": 2.0, + "indie": 93.0, + "soul": 3.0, + "chillout": 3.0, + "blues": 2.0, + "pop": 80.0, + "rock": 2.0, + "electronic": 2.0, + "trip-hop": 10.0, + "indie pop": 88.0, + "seen live": 12.0, + "alternative": 67.0, + "female vocalist": 4.0, + "alternative rock": 2.0 + } + }, + { + "description": "Katy Perry", + "features": { + "indie": 25.0, + "singer-songwriter": 4.0, + "american": 9.0, + "pop": 100.0, + "rock": 24.0, + "beautiful": 2.0, + "indie rock": 1.0, + "electronic": 4.0, + "dance": 9.0, + "indie pop": 1.0, + "seen live": 7.0, + "rnb": 1.0, + "alternative": 3.0, + "female vocalist": 5.0, + "00s": 3.0, + "female vocalists": 62.0, + "Love": 2.0 + } + }, + { + "description": "Lady Gaga", + "features": { + "singer-songwriter": 4.0, + "american": 7.0, + "pop": 100.0, + "electronica": 3.0, + "rock": 2.0, + "electro": 2.0, + "synthpop": 2.0, + "electronic": 53.0, + "dance": 73.0, + "seen live": 8.0, + "techno": 1.0, + "rnb": 1.0, + "alternative": 1.0, + "female vocalist": 21.0, + "00s": 3.0, + "female vocalists": 43.0, + "Love": 2.0 + } + }, + { + "description": "Tame Impala", + "features": { + "indie": 21.0, + "male vocalists": 1.0, + "Psychedelic Rock": 100.0, + "experimental": 4.0, + "psychedelic": 92.0, + "rock": 41.0, + "indie rock": 60.0, + "electronic": 3.0, + "indie pop": 2.0, + "seen live": 53.0, + "alternative": 7.0, + "Progressive rock": 3.0, + "alternative rock": 3.0, + "00s": 3.0 + } + }, + { + "description": "Calvin Harris", + "features": { + "indie": 8.0, + "male vocalists": 3.0, + "singer-songwriter": 1.0, + "british": 15.0, + "electronica": 34.0, + "pop": 8.0, + "electro": 53.0, + "synthpop": 4.0, + "electronic": 100.0, + "dance": 75.0, + "indie pop": 2.0, + "seen live": 36.0, + "techno": 1.0, + "alternative": 1.0, + "House": 9.0, + "00s": 3.0, + "80s": 1.0 + } + }, + { + "description": "Red Hot Chili Peppers", + "features": { + "indie": 5.0, + "favorites": 1.0, + "male vocalists": 1.0, + "american": 5.0, + "classic rock": 3.0, + "rock": 100.0, + "pop": 2.0, + "punk rock": 2.0, + "indie rock": 2.0, + "seen live": 23.0, + "Grunge": 2.0, + "alternative": 54.0, + "metal": 2.0, + "alternative rock": 59.0, + "00s": 2.0, + "punk": 6.0, + "hard rock": 2.0, + "80s": 2.0, + "funk": 50.0, + "90s": 5.0 + } + }, + { + "description": "Coldplay", + "features": { + "indie": 55.0, + "favorites": 2.0, + "male vocalists": 3.0, + "singer-songwriter": 2.0, + "emo": 2.0, + "Mellow": 3.0, + "chillout": 3.0, + "british": 28.0, + "classic rock": 2.0, + "rock": 100.0, + "pop": 18.0, + "piano": 3.0, + "indie rock": 11.0, + "electronic": 2.0, + "britpop": 81.0, + "indie pop": 2.0, + "seen live": 22.0, + "alternative": 87.0, + "acoustic": 2.0, + "alternative rock": 68.0, + "00s": 2.0, + "Love": 2.0, + "90s": 2.0 + } + }, + { + "description": "Miley Cyrus", + "features": { + "country": 3.0, + "singer-songwriter": 1.0, + "american": 12.0, + "beautiful": 2.0, + "grindcore": 1.0, + "dance": 42.0, + "rnb": 4.0, + "Soundtrack": 2.0, + "female vocalists": 55.0, + "Love": 2.0, + "death metal": 2.0, + "pop": 100.0, + "rock": 8.0, + "electronic": 5.0, + "seen live": 3.0, + "Hip-Hop": 4.0, + "alternative": 2.0, + "female vocalist": 4.0, + "00s": 2.0 + } + }, + { + "description": "Mark Ronson", + "features": { + "singer-songwriter": 1.0, + "jazz": 7.0, + "british": 68.0, + "experimental": 2.0, + "american": 1.0, + "cover": 4.0, + "electronica": 2.0, + "dance": 5.0, + "rap": 4.0, + "rnb": 2.0, + "House": 1.0, + "indie": 3.0, + "soul": 17.0, + "chillout": 2.0, + "pop": 68.0, + "rock": 3.0, + "electro": 2.0, + "hip hop": 11.0, + "electronic": 9.0, + "trip-hop": 1.0, + "britpop": 4.0, + "seen live": 31.0, + "Hip-Hop": 57.0, + "alternative": 9.0, + "00s": 7.0, + "funk": 100.0 + } + }, + { + "description": "Imagine Dragons", + "features": { + "indie": 100.0, + "male vocalists": 6.0, + "american": 12.0, + "rock": 64.0, + "pop": 10.0, + "indie rock": 96.0, + "electronic": 4.0, + "new wave": 2.0, + "indie pop": 57.0, + "seen live": 29.0, + "alternative": 86.0, + "alternative rock": 21.0, + "folk": 2.0 + } + }, + { + "description": "The Weeknd", + "features": { + "indie": 6.0, + "male vocalists": 5.0, + "soul": 9.0, + "chillout": 2.0, + "Mellow": 2.0, + "experimental": 6.0, + "ambient": 3.0, + "pop": 10.0, + "electronica": 5.0, + "electro": 1.0, + "downtempo": 7.0, + "hip hop": 2.0, + "electronic": 78.0, + "trip-hop": 3.0, + "rap": 2.0, + "indie pop": 2.0, + "seen live": 16.0, + "Hip-Hop": 8.0, + "rnb": 100.0, + "alternative": 5.0 + } + }, + { + "description": "Eminem", + "features": { + "male vocalists": 3.0, + "singer-songwriter": 2.0, + "emo": 1.0, + "american": 6.0, + "pop": 16.0, + "rock": 3.0, + "hip hop": 33.0, + "dance": 1.0, + "rap": 100.0, + "seen live": 4.0, + "Hip-Hop": 79.0, + "alternative": 3.0, + "00s": 2.0, + "90s": 2.0 + } + }, + { + "description": "Nirvana", + "features": { + "indie": 4.0, + "favorites": 1.0, + "male vocalists": 2.0, + "Grunge": 100.0, + "alternative": 35.0, + "metal": 3.0, + "american": 4.0, + "classic rock": 2.0, + "rock": 52.0, + "alternative rock": 34.0, + "punk rock": 3.0, + "punk": 7.0, + "indie rock": 2.0, + "hard rock": 3.0, + "90s": 28.0 + } + }, + { + "description": "Fleetwood Mac", + "features": { + "favorites": 2.0, + "male vocalists": 2.0, + "singer-songwriter": 2.0, + "british": 10.0, + "american": 3.0, + "classic rock": 100.0, + "blues": 41.0, + "rock": 67.0, + "pop": 33.0, + "oldies": 3.0, + "seen live": 7.0, + "alternative": 1.0, + "acoustic": 1.0, + "female vocalist": 2.0, + "guitar": 1.0, + "Progressive rock": 2.0, + "female vocalists": 10.0, + "folk": 2.0, + "60s": 5.0, + "70s": 48.0, + "80s": 12.0, + "90s": 2.0 + } + }, + { + "description": "Childish Gambino", + "features": { + "indie": 35.0, + "male vocalists": 1.0, + "soul": 5.0, + "american": 8.0, + "experimental": 3.0, + "pop": 3.0, + "psychedelic": 2.0, + "hip hop": 31.0, + "electronic": 2.0, + "dance": 1.0, + "rap": 70.0, + "seen live": 37.0, + "Hip-Hop": 100.0, + "rnb": 6.0, + "alternative": 4.0, + "funk": 8.0 + } + }, + { + "description": "Pink Floyd", + "features": { + "favorites": 1.0, + "indie": 1.0, + "Psychedelic Rock": 72.0, + "british": 13.0, + "experimental": 6.0, + "ambient": 1.0, + "classic rock": 79.0, + "rock": 53.0, + "psychedelic": 44.0, + "oldies": 1.0, + "seen live": 3.0, + "alternative": 6.0, + "Progressive rock": 100.0, + "alternative rock": 2.0, + "hard rock": 2.0, + "60s": 5.0, + "70s": 8.0, + "80s": 3.0 + } + }, + { + "description": "The Killers", + "features": { + "indie": 100.0, + "favorites": 2.0, + "male vocalists": 3.0, + "emo": 2.0, + "american": 9.0, + "british": 2.0, + "classic rock": 1.0, + "rock": 93.0, + "pop": 10.0, + "electronica": 1.0, + "punk rock": 1.0, + "indie rock": 90.0, + "new wave": 4.0, + "electronic": 3.0, + "dance": 1.0, + "britpop": 4.0, + "indie pop": 4.0, + "seen live": 39.0, + "alternative": 75.0, + "post-punk": 3.0, + "alternative rock": 64.0, + "00s": 3.0, + "punk": 4.0 + } + }, + { + "description": "The Rolling Stones", + "features": { + "indie": 2.0, + "male vocalists": 1.0, + "Psychedelic Rock": 2.0, + "british": 43.0, + "classic rock": 100.0, + "blues": 31.0, + "rock": 80.0, + "psychedelic": 3.0, + "pop": 2.0, + "oldies": 3.0, + "seen live": 14.0, + "alternative": 4.0, + "guitar": 1.0, + "hard rock": 8.0, + "60s": 41.0, + "70s": 8.0, + "80s": 4.0, + "90s": 2.0 + } + }, + { + "description": "Gorillaz", + "features": { + "indie": 46.0, + "favorites": 1.0, + "chillout": 3.0, + "british": 12.0, + "experimental": 6.0, + "rock": 58.0, + "electronica": 13.0, + "pop": 13.0, + "electro": 2.0, + "downtempo": 1.0, + "punk rock": 1.0, + "indie rock": 4.0, + "hip hop": 7.0, + "electronic": 88.0, + "trip-hop": 20.0, + "dance": 4.0, + "britpop": 4.0, + "rap": 4.0, + "indie pop": 2.0, + "seen live": 5.0, + "Hip-Hop": 63.0, + "alternative": 100.0, + "metal": 2.0, + "alternative rock": 11.0, + "00s": 3.0, + "punk": 2.0, + "funk": 3.0 + } + }, + { + "description": "Frank Ocean", + "features": { + "indie": 3.0, + "male vocalists": 6.0, + "singer-songwriter": 4.0, + "soul": 93.0, + "american": 8.0, + "experimental": 2.0, + "pop": 6.0, + "electronica": 1.0, + "hip hop": 8.0, + "electronic": 3.0, + "rap": 4.0, + "seen live": 14.0, + "Hip-Hop": 82.0, + "rnb": 100.0, + "alternative": 3.0, + "funk": 2.0 + } + }, + { + "description": "Panic! at the Disco", + "features": { + "male vocalists": 3.0, + "american": 8.0, + "electronica": 2.0, + "punk rock": 6.0, + "indie rock": 21.0, + "dance": 20.0, + "metal": 2.0, + "screamo": 2.0, + "punk": 21.0, + "Love": 2.0, + "indie": 68.0, + "favorites": 4.0, + "emo": 97.0, + "rock": 100.0, + "pop": 9.0, + "electronic": 4.0, + "indie pop": 2.0, + "seen live": 51.0, + "hardcore": 2.0, + "techno": 1.0, + "alternative": 99.0, + "alternative rock": 21.0, + "00s": 2.0 + } + }, + { + "description": "The Cure", + "features": { + "indie": 14.0, + "favorites": 2.0, + "male vocalists": 2.0, + "emo": 1.0, + "british": 16.0, + "classic rock": 3.0, + "rock": 52.0, + "pop": 6.0, + "psychedelic": 1.0, + "synthpop": 1.0, + "punk rock": 1.0, + "indie rock": 3.0, + "new wave": 100.0, + "electronic": 2.0, + "britpop": 2.0, + "indie pop": 1.0, + "seen live": 24.0, + "alternative": 68.0, + "Gothic": 10.0, + "post-punk": 100.0, + "alternative rock": 23.0, + "punk": 4.0, + "Love": 2.0, + "70s": 2.0, + "80s": 65.0, + "90s": 3.0 + } + }, + { + "description": "Madonna", + "features": { + "singer-songwriter": 3.0, + "american": 8.0, + "pop": 100.0, + "rock": 5.0, + "electronica": 3.0, + "electronic": 29.0, + "dance": 50.0, + "seen live": 9.0, + "rnb": 1.0, + "alternative": 2.0, + "female vocalist": 4.0, + "00s": 4.0, + "female vocalists": 50.0, + "Love": 1.0, + "80s": 35.0, + "90s": 8.0 + } + }, + { + "description": "The Chainsmokers", + "features": { + "male vocalists": 6.0, + "american": 28.0, + "electronica": 3.0, + "dance": 33.0, + "House": 63.0, + "pop": 79.0, + "electro": 6.0, + "electronic": 100.0, + "seen live": 17.0, + "techno": 3.0, + "alternative": 3.0 + } + }, + { + "description": "Linkin Park", + "features": { + "favorites": 2.0, + "indie": 1.0, + "male vocalists": 3.0, + "emo": 3.0, + "american": 6.0, + "rock": 100.0, + "pop": 3.0, + "punk rock": 2.0, + "electronic": 4.0, + "rap": 3.0, + "seen live": 21.0, + "Hip-Hop": 2.0, + "alternative": 67.0, + "metal": 37.0, + "Nu Metal": 92.0, + "alternative rock": 74.0, + "00s": 2.0, + "punk": 4.0, + "hard rock": 5.0 + } + }, + { + "description": "Lorde", + "features": { + "indie": 72.0, + "singer-songwriter": 7.0, + "soul": 1.0, + "experimental": 2.0, + "pop": 100.0, + "electronica": 5.0, + "rock": 1.0, + "synthpop": 7.0, + "electronic": 81.0, + "trip-hop": 2.0, + "indie pop": 92.0, + "seen live": 20.0, + "alternative": 17.0, + "female vocalist": 4.0, + "female vocalists": 28.0, + "folk": 2.0 + } + }, + { + "description": "The Black Keys", + "features": { + "indie": 50.0, + "male vocalists": 2.0, + "soul": 2.0, + "Psychedelic Rock": 2.0, + "american": 8.0, + "blues": 68.0, + "classic rock": 2.0, + "rock": 63.0, + "psychedelic": 2.0, + "indie rock": 48.0, + "seen live": 37.0, + "alternative": 11.0, + "alternative rock": 7.0, + "00s": 3.0, + "hard rock": 2.0 + } + }, + { + "description": "Daft Punk", + "features": { + "indie": 2.0, + "chillout": 2.0, + "experimental": 2.0, + "electronica": 37.0, + "rock": 3.0, + "pop": 2.0, + "electro": 11.0, + "synthpop": 1.0, + "electronic": 100.0, + "dance": 54.0, + "french": 19.0, + "seen live": 7.0, + "techno": 36.0, + "alternative": 6.0, + "House": 54.0, + "trance": 2.0, + "00s": 2.0, + "Soundtrack": 2.0, + "funk": 4.0, + "90s": 3.0 + } + }, + { + "description": "Led Zeppelin", + "features": { + "favorites": 1.0, + "indie": 1.0, + "Psychedelic Rock": 3.0, + "british": 9.0, + "classic rock": 100.0, + "blues": 9.0, + "rock": 64.0, + "psychedelic": 4.0, + "heavy metal": 8.0, + "oldies": 1.0, + "metal": 4.0, + "alternative": 4.0, + "guitar": 2.0, + "Progressive rock": 33.0, + "alternative rock": 1.0, + "hard rock": 63.0, + "folk": 1.0, + "60s": 3.0, + "70s": 36.0, + "80s": 1.0 + } + }, + { + "description": "Marshmello", + "features": { + "emo": 10.0, + "pop": 28.0, + "electronic": 91.0, + "dance": 100.0, + "rap": 28.0, + "seen live": 19.0, + "rnb": 19.0, + "House": 10.0 + } + }, + { + "description": "Khalid", + "features": { + "indie": 7.0, + "male vocalists": 7.0, + "soul": 88.0, + "american": 19.0, + "pop": 100.0, + "synthpop": 7.0, + "electronic": 13.0, + "seen live": 25.0, + "rnb": 75.0, + "alternative": 63.0, + "folk": 7.0 + } + }, + { + "description": "David Guetta", + "features": { + "chillout": 1.0, + "electronica": 7.0, + "pop": 6.0, + "electro": 6.0, + "electronic": 76.0, + "dance": 82.0, + "french": 11.0, + "seen live": 9.0, + "techno": 39.0, + "House": 100.0, + "trance": 4.0, + "00s": 2.0 + } + }, + { + "description": "Billie Eilish", + "features": { + "singer-songwriter": 3.0, + "american": 23.0, + "british": 3.0, + "experimental": 3.0, + "rnb": 3.0, + "female vocalists": 49.0, + "indie": 58.0, + "chillout": 12.0, + "ambient": 3.0, + "pop": 100.0, + "synthpop": 3.0, + "electronic": 58.0, + "indie pop": 83.0, + "seen live": 18.0, + "alternative": 40.0, + "female vocalist": 9.0 + } + }, + { + "description": "Ed Sheeran", + "features": { + "indie": 12.0, + "singer-songwriter": 78.0, + "male vocalists": 13.0, + "soul": 3.0, + "chillout": 2.0, + "Mellow": 2.0, + "british": 82.0, + "pop": 23.0, + "rock": 4.0, + "rap": 2.0, + "indie pop": 3.0, + "seen live": 21.0, + "Hip-Hop": 4.0, + "acoustic": 100.0, + "alternative": 8.0, + "guitar": 2.0, + "00s": 2.0, + "Soundtrack": 1.0, + "Love": 2.0, + "folk": 12.0 + } + }, + { + "description": "Lil Nas X", + "features": { + "country": 54.0, + "male vocalists": 8.0, + "american": 24.0, + "rock": 16.0, + "pop": 8.0, + "hip hop": 47.0, + "rap": 62.0, + "Hip-Hop": 100.0, + "alternative": 24.0 + } + }, + { + "description": "Queen", + "features": { + "favorites": 2.0, + "male vocalists": 3.0, + "british": 17.0, + "classic rock": 100.0, + "rock": 81.0, + "pop": 7.0, + "heavy metal": 2.0, + "oldies": 2.0, + "seen live": 2.0, + "alternative": 4.0, + "metal": 2.0, + "Progressive rock": 6.0, + "alternative rock": 1.0, + "hard rock": 38.0, + "70s": 8.0, + "80s": 41.0, + "90s": 2.0 + } + }, + { + "description": "Ariana Grande", + "features": { + "american": 13.0, + "beautiful": 2.0, + "dance": 11.0, + "House": 2.0, + "Soundtrack": 3.0, + "chillout": 3.0, + "pop": 100.0, + "rock": 2.0, + "electronic": 3.0, + "seen live": 3.0, + "female vocalist": 3.0, + "singer-songwriter": 5.0, + "rnb": 51.0, + "female vocalists": 54.0, + "soul": 10.0, + "synthpop": 2.0, + "hip hop": 3.0, + "Hip-Hop": 3.0 + } + }, + { + "description": "Post Malone", + "features": { + "american": 8.0, + "rap": 72.0, + "rnb": 14.0, + "pop": 8.0, + "synthpop": 3.0, + "hip hop": 35.0, + "seen live": 19.0, + "Hip-Hop": 100.0 + } + }, + { + "description": "Drake", + "features": { + "indie": 4.0, + "male vocalists": 5.0, + "soul": 2.0, + "pop": 6.0, + "hip hop": 37.0, + "rap": 72.0, + "seen live": 8.0, + "Hip-Hop": 100.0, + "rnb": 50.0, + "00s": 1.0 + } + }, + { + "description": "Kanye West", + "features": { + "indie": 2.0, + "male vocalists": 3.0, + "soul": 4.0, + "american": 6.0, + "experimental": 2.0, + "pop": 6.0, + "rock": 2.0, + "electronica": 1.0, + "hip hop": 40.0, + "electronic": 3.0, + "dance": 2.0, + "rap": 69.0, + "seen live": 22.0, + "Hip-Hop": 100.0, + "rnb": 31.0, + "alternative": 3.0, + "00s": 3.0 + } + }, + { + "description": "The Beatles", + "features": { + "indie": 3.0, + "favorites": 2.0, + "male vocalists": 2.0, + "singer-songwriter": 2.0, + "Psychedelic Rock": 6.0, + "british": 58.0, + "experimental": 2.0, + "classic rock": 100.0, + "rock": 71.0, + "pop": 41.0, + "psychedelic": 13.0, + "indie rock": 2.0, + "oldies": 10.0, + "britpop": 4.0, + "alternative": 4.0, + "Progressive rock": 2.0, + "alternative rock": 1.0, + "Love": 2.0, + "folk": 1.0, + "60s": 56.0, + "70s": 3.0 + } + }, + { + "description": "Taylor Swift", + "features": { + "country": 100.0, + "singer-songwriter": 42.0, + "chillout": 2.0, + "american": 8.0, + "pop": 71.0, + "rock": 2.0, + "beautiful": 2.0, + "synthpop": 2.0, + "seen live": 4.0, + "acoustic": 31.0, + "female vocalist": 3.0, + "00s": 3.0, + "female vocalists": 60.0, + "Love": 3.0, + "folk": 2.0 + } + }, + { + "description": "Radiohead", + "features": { + "indie": 59.0, + "favorites": 2.0, + "male vocalists": 2.0, + "emo": 1.0, + "chillout": 2.0, + "british": 22.0, + "experimental": 14.0, + "ambient": 2.0, + "classic rock": 1.0, + "rock": 73.0, + "electronica": 5.0, + "psychedelic": 3.0, + "pop": 2.0, + "beautiful": 1.0, + "post-rock": 3.0, + "indie rock": 15.0, + "electronic": 48.0, + "trip-hop": 1.0, + "britpop": 17.0, + "indie pop": 1.0, + "seen live": 27.0, + "alternative": 100.0, + "Progressive rock": 6.0, + "alternative rock": 81.0, + "00s": 2.0, + "idm": 1.0, + "90s": 5.0 + } + }, + { + "description": "Beyoncé", + "features": { + "singer-songwriter": 3.0, + "jazz": 2.0, + "american": 9.0, + "beautiful": 2.0, + "dance": 13.0, + "rap": 2.0, + "rnb": 100.0, + "female vocalists": 70.0, + "Love": 3.0, + "soul": 56.0, + "pop": 91.0, + "hip hop": 5.0, + "electronic": 2.0, + "seen live": 6.0, + "Hip-Hop": 45.0, + "alternative": 1.0, + "female vocalist": 4.0, + "00s": 3.0, + "funk": 2.0 + } + }, + { + "description": "Shawn Mendes", + "features": { + "male vocalists": 28.0, + "singer-songwriter": 13.0, + "british": 7.0, + "rnb": 7.0, + "acoustic": 37.0, + "metal": 4.0, + "folk": 37.0, + "indie": 10.0, + "soul": 4.0, + "pop": 100.0, + "seen live": 13.0, + "alternative": 4.0, + "alternative rock": 4.0 + } + }, + { + "description": "David Bowie", + "features": { + "singer-songwriter": 11.0, + "male vocalists": 4.0, + "Psychedelic Rock": 2.0, + "british": 23.0, + "experimental": 9.0, + "classic rock": 86.0, + "psychedelic": 3.0, + "electronica": 2.0, + "indie rock": 2.0, + "dance": 2.0, + "post-punk": 2.0, + "punk": 2.0, + "hard rock": 3.0, + "folk": 2.0, + "70s": 15.0, + "90s": 4.0, + "indie": 6.0, + "favorites": 2.0, + "soul": 2.0, + "ambient": 2.0, + "rock": 100.0, + "pop": 19.0, + "new wave": 7.0, + "electronic": 4.0, + "oldies": 2.0, + "britpop": 2.0, + "seen live": 11.0, + "alternative": 43.0, + "Progressive rock": 4.0, + "alternative rock": 6.0, + "industrial": 2.0, + "00s": 2.0, + "60s": 3.0, + "80s": 48.0, + "funk": 2.0 + } + }, + { + "description": "Kendrick Lamar", + "features": { + "male vocalists": 2.0, + "american": 7.0, + "hip hop": 17.0, + "rap": 70.0, + "seen live": 38.0, + "Hip-Hop": 100.0, + "funk": 2.0 + } + }, + { + "description": "Rihanna", + "features": { + "american": 4.0, + "beautiful": 2.0, + "dance": 56.0, + "rap": 2.0, + "rnb": 89.0, + "House": 1.0, + "female vocalists": 63.0, + "Love": 2.0, + "soul": 4.0, + "pop": 100.0, + "rock": 2.0, + "hip hop": 6.0, + "electronic": 3.0, + "seen live": 7.0, + "Hip-Hop": 41.0, + "alternative": 1.0, + "female vocalist": 4.0, + "00s": 3.0, + "reggae": 6.0 + } + }, + { + "description": "Arctic Monkeys", + "features": { + "indie": 98.0, + "male vocalists": 2.0, + "Psychedelic Rock": 1.0, + "british": 75.0, + "rock": 63.0, + "pop": 2.0, + "punk rock": 1.0, + "indie rock": 100.0, + "britpop": 16.0, + "indie pop": 2.0, + "seen live": 45.0, + "alternative": 60.0, + "post-punk": 3.0, + "alternative rock": 19.0, + "00s": 3.0, + "punk": 2.0 + } + }, + { + "description": "Tyler, the Creator", + "features": { + "experimental": 4.0, + "american": 4.0, + "hip hop": 12.0, + "rap": 55.0, + "seen live": 15.0, + "Hip-Hop": 100.0, + "alternative": 2.0 + } + }, + { + "description": "Lana Del Rey", + "features": { + "singer-songwriter": 10.0, + "jazz": 2.0, + "american": 14.0, + "beautiful": 2.0, + "indie rock": 2.0, + "female vocalists": 100.0, + "folk": 2.0, + "indie": 93.0, + "soul": 3.0, + "chillout": 3.0, + "blues": 2.0, + "pop": 80.0, + "rock": 2.0, + "electronic": 2.0, + "trip-hop": 10.0, + "indie pop": 88.0, + "seen live": 12.0, + "alternative": 67.0, + "female vocalist": 4.0, + "alternative rock": 2.0 + } + }, + { + "description": "Katy Perry", + "features": { + "indie": 25.0, + "singer-songwriter": 4.0, + "american": 9.0, + "pop": 100.0, + "rock": 24.0, + "beautiful": 2.0, + "indie rock": 1.0, + "electronic": 4.0, + "dance": 9.0, + "indie pop": 1.0, + "seen live": 7.0, + "rnb": 1.0, + "alternative": 3.0, + "female vocalist": 5.0, + "00s": 3.0, + "female vocalists": 62.0, + "Love": 2.0 + } + }, + { + "description": "Lady Gaga", + "features": { + "singer-songwriter": 4.0, + "american": 7.0, + "pop": 100.0, + "electronica": 3.0, + "rock": 2.0, + "electro": 2.0, + "synthpop": 2.0, + "electronic": 53.0, + "dance": 73.0, + "seen live": 8.0, + "techno": 1.0, + "rnb": 1.0, + "alternative": 1.0, + "female vocalist": 21.0, + "00s": 3.0, + "female vocalists": 43.0, + "Love": 2.0 + } + }, + { + "description": "Tame Impala", + "features": { + "indie": 21.0, + "male vocalists": 1.0, + "Psychedelic Rock": 100.0, + "experimental": 4.0, + "psychedelic": 92.0, + "rock": 41.0, + "indie rock": 60.0, + "electronic": 3.0, + "indie pop": 2.0, + "seen live": 53.0, + "alternative": 7.0, + "Progressive rock": 3.0, + "alternative rock": 3.0, + "00s": 3.0 + } + }, + { + "description": "Calvin Harris", + "features": { + "indie": 8.0, + "male vocalists": 3.0, + "singer-songwriter": 1.0, + "british": 15.0, + "electronica": 34.0, + "pop": 8.0, + "electro": 53.0, + "synthpop": 4.0, + "electronic": 100.0, + "dance": 75.0, + "indie pop": 2.0, + "seen live": 36.0, + "techno": 1.0, + "alternative": 1.0, + "House": 9.0, + "00s": 3.0, + "80s": 1.0 + } + }, + { + "description": "Red Hot Chili Peppers", + "features": { + "indie": 5.0, + "favorites": 1.0, + "male vocalists": 1.0, + "american": 5.0, + "classic rock": 3.0, + "rock": 100.0, + "pop": 2.0, + "punk rock": 2.0, + "indie rock": 2.0, + "seen live": 23.0, + "Grunge": 2.0, + "alternative": 54.0, + "metal": 2.0, + "alternative rock": 59.0, + "00s": 2.0, + "punk": 6.0, + "hard rock": 2.0, + "80s": 2.0, + "funk": 50.0, + "90s": 5.0 + } + }, + { + "description": "Coldplay", + "features": { + "indie": 55.0, + "favorites": 2.0, + "male vocalists": 3.0, + "singer-songwriter": 2.0, + "emo": 2.0, + "Mellow": 3.0, + "chillout": 3.0, + "british": 28.0, + "classic rock": 2.0, + "rock": 100.0, + "pop": 18.0, + "piano": 3.0, + "indie rock": 11.0, + "electronic": 2.0, + "britpop": 81.0, + "indie pop": 2.0, + "seen live": 22.0, + "alternative": 87.0, + "acoustic": 2.0, + "alternative rock": 68.0, + "00s": 2.0, + "Love": 2.0, + "90s": 2.0 + } + }, + { + "description": "Miley Cyrus", + "features": { + "country": 3.0, + "singer-songwriter": 1.0, + "american": 12.0, + "beautiful": 2.0, + "grindcore": 1.0, + "dance": 42.0, + "rnb": 4.0, + "Soundtrack": 2.0, + "female vocalists": 55.0, + "Love": 2.0, + "death metal": 2.0, + "pop": 100.0, + "rock": 8.0, + "electronic": 5.0, + "seen live": 3.0, + "Hip-Hop": 4.0, + "alternative": 2.0, + "female vocalist": 4.0, + "00s": 2.0 + } + }, + { + "description": "Mark Ronson", + "features": { + "singer-songwriter": 1.0, + "jazz": 7.0, + "british": 68.0, + "experimental": 2.0, + "american": 1.0, + "cover": 4.0, + "electronica": 2.0, + "dance": 5.0, + "rap": 4.0, + "rnb": 2.0, + "House": 1.0, + "indie": 3.0, + "soul": 17.0, + "chillout": 2.0, + "pop": 68.0, + "rock": 3.0, + "electro": 2.0, + "hip hop": 11.0, + "electronic": 9.0, + "trip-hop": 1.0, + "britpop": 4.0, + "seen live": 31.0, + "Hip-Hop": 57.0, + "alternative": 9.0, + "00s": 7.0, + "funk": 100.0 + } + }, + { + "description": "Imagine Dragons", + "features": { + "indie": 100.0, + "male vocalists": 6.0, + "american": 12.0, + "rock": 64.0, + "pop": 10.0, + "indie rock": 96.0, + "electronic": 4.0, + "new wave": 2.0, + "indie pop": 57.0, + "seen live": 29.0, + "alternative": 86.0, + "alternative rock": 21.0, + "folk": 2.0 + } + }, + { + "description": "The Weeknd", + "features": { + "indie": 6.0, + "male vocalists": 5.0, + "soul": 9.0, + "chillout": 2.0, + "Mellow": 2.0, + "experimental": 6.0, + "ambient": 3.0, + "pop": 10.0, + "electronica": 5.0, + "electro": 1.0, + "downtempo": 7.0, + "hip hop": 2.0, + "electronic": 78.0, + "trip-hop": 3.0, + "rap": 2.0, + "indie pop": 2.0, + "seen live": 16.0, + "Hip-Hop": 8.0, + "rnb": 100.0, + "alternative": 5.0 + } + }, + { + "description": "Eminem", + "features": { + "male vocalists": 3.0, + "singer-songwriter": 2.0, + "emo": 1.0, + "american": 6.0, + "pop": 16.0, + "rock": 3.0, + "hip hop": 33.0, + "dance": 1.0, + "rap": 100.0, + "seen live": 4.0, + "Hip-Hop": 79.0, + "alternative": 3.0, + "00s": 2.0, + "90s": 2.0 + } + }, + { + "description": "Nirvana", + "features": { + "indie": 4.0, + "favorites": 1.0, + "male vocalists": 2.0, + "Grunge": 100.0, + "alternative": 35.0, + "metal": 3.0, + "american": 4.0, + "classic rock": 2.0, + "rock": 52.0, + "alternative rock": 34.0, + "punk rock": 3.0, + "punk": 7.0, + "indie rock": 2.0, + "hard rock": 3.0, + "90s": 28.0 + } + }, + { + "description": "Fleetwood Mac", + "features": { + "favorites": 2.0, + "male vocalists": 2.0, + "singer-songwriter": 2.0, + "british": 10.0, + "american": 3.0, + "classic rock": 100.0, + "blues": 41.0, + "rock": 67.0, + "pop": 33.0, + "oldies": 3.0, + "seen live": 7.0, + "alternative": 1.0, + "acoustic": 1.0, + "female vocalist": 2.0, + "guitar": 1.0, + "Progressive rock": 2.0, + "female vocalists": 10.0, + "folk": 2.0, + "60s": 5.0, + "70s": 48.0, + "80s": 12.0, + "90s": 2.0 + } + }, + { + "description": "Childish Gambino", + "features": { + "indie": 35.0, + "male vocalists": 1.0, + "soul": 5.0, + "american": 8.0, + "experimental": 3.0, + "pop": 3.0, + "psychedelic": 2.0, + "hip hop": 31.0, + "electronic": 2.0, + "dance": 1.0, + "rap": 70.0, + "seen live": 37.0, + "Hip-Hop": 100.0, + "rnb": 6.0, + "alternative": 4.0, + "funk": 8.0 + } + }, + { + "description": "Pink Floyd", + "features": { + "favorites": 1.0, + "indie": 1.0, + "Psychedelic Rock": 72.0, + "british": 13.0, + "experimental": 6.0, + "ambient": 1.0, + "classic rock": 79.0, + "rock": 53.0, + "psychedelic": 44.0, + "oldies": 1.0, + "seen live": 3.0, + "alternative": 6.0, + "Progressive rock": 100.0, + "alternative rock": 2.0, + "hard rock": 2.0, + "60s": 5.0, + "70s": 8.0, + "80s": 3.0 + } + }, + { + "description": "The Killers", + "features": { + "indie": 100.0, + "favorites": 2.0, + "male vocalists": 3.0, + "emo": 2.0, + "american": 9.0, + "british": 2.0, + "classic rock": 1.0, + "rock": 93.0, + "pop": 10.0, + "electronica": 1.0, + "punk rock": 1.0, + "indie rock": 90.0, + "new wave": 4.0, + "electronic": 3.0, + "dance": 1.0, + "britpop": 4.0, + "indie pop": 4.0, + "seen live": 39.0, + "alternative": 75.0, + "post-punk": 3.0, + "alternative rock": 64.0, + "00s": 3.0, + "punk": 4.0 + } + }, + { + "description": "The Rolling Stones", + "features": { + "indie": 2.0, + "male vocalists": 1.0, + "Psychedelic Rock": 2.0, + "british": 43.0, + "classic rock": 100.0, + "blues": 31.0, + "rock": 80.0, + "psychedelic": 3.0, + "pop": 2.0, + "oldies": 3.0, + "seen live": 14.0, + "alternative": 4.0, + "guitar": 1.0, + "hard rock": 8.0, + "60s": 41.0, + "70s": 8.0, + "80s": 4.0, + "90s": 2.0 + } + }, + { + "description": "Gorillaz", + "features": { + "indie": 46.0, + "favorites": 1.0, + "chillout": 3.0, + "british": 12.0, + "experimental": 6.0, + "rock": 58.0, + "electronica": 13.0, + "pop": 13.0, + "electro": 2.0, + "downtempo": 1.0, + "punk rock": 1.0, + "indie rock": 4.0, + "hip hop": 7.0, + "electronic": 88.0, + "trip-hop": 20.0, + "dance": 4.0, + "britpop": 4.0, + "rap": 4.0, + "indie pop": 2.0, + "seen live": 5.0, + "Hip-Hop": 63.0, + "alternative": 100.0, + "metal": 2.0, + "alternative rock": 11.0, + "00s": 3.0, + "punk": 2.0, + "funk": 3.0 + } + }, + { + "description": "Frank Ocean", + "features": { + "indie": 3.0, + "male vocalists": 6.0, + "singer-songwriter": 4.0, + "soul": 93.0, + "american": 8.0, + "experimental": 2.0, + "pop": 6.0, + "electronica": 1.0, + "hip hop": 8.0, + "electronic": 3.0, + "rap": 4.0, + "seen live": 14.0, + "Hip-Hop": 82.0, + "rnb": 100.0, + "alternative": 3.0, + "funk": 2.0 + } + }, + { + "description": "Panic! at the Disco", + "features": { + "male vocalists": 3.0, + "american": 8.0, + "electronica": 2.0, + "punk rock": 6.0, + "indie rock": 21.0, + "dance": 20.0, + "metal": 2.0, + "screamo": 2.0, + "punk": 21.0, + "Love": 2.0, + "indie": 68.0, + "favorites": 4.0, + "emo": 97.0, + "rock": 100.0, + "pop": 9.0, + "electronic": 4.0, + "indie pop": 2.0, + "seen live": 51.0, + "hardcore": 2.0, + "techno": 1.0, + "alternative": 99.0, + "alternative rock": 21.0, + "00s": 2.0 + } + }, + { + "description": "The Cure", + "features": { + "indie": 14.0, + "favorites": 2.0, + "male vocalists": 2.0, + "emo": 1.0, + "british": 16.0, + "classic rock": 3.0, + "rock": 52.0, + "pop": 6.0, + "psychedelic": 1.0, + "synthpop": 1.0, + "punk rock": 1.0, + "indie rock": 3.0, + "new wave": 100.0, + "electronic": 2.0, + "britpop": 2.0, + "indie pop": 1.0, + "seen live": 24.0, + "alternative": 68.0, + "Gothic": 10.0, + "post-punk": 100.0, + "alternative rock": 23.0, + "punk": 4.0, + "Love": 2.0, + "70s": 2.0, + "80s": 65.0, + "90s": 3.0 + } + }, + { + "description": "Madonna", + "features": { + "singer-songwriter": 3.0, + "american": 8.0, + "pop": 100.0, + "rock": 5.0, + "electronica": 3.0, + "electronic": 29.0, + "dance": 50.0, + "seen live": 9.0, + "rnb": 1.0, + "alternative": 2.0, + "female vocalist": 4.0, + "00s": 4.0, + "female vocalists": 50.0, + "Love": 1.0, + "80s": 35.0, + "90s": 8.0 + } + }, + { + "description": "The Chainsmokers", + "features": { + "male vocalists": 6.0, + "american": 28.0, + "electronica": 3.0, + "dance": 33.0, + "House": 63.0, + "pop": 79.0, + "electro": 6.0, + "electronic": 100.0, + "seen live": 17.0, + "techno": 3.0, + "alternative": 3.0 + } + }, + { + "description": "Linkin Park", + "features": { + "favorites": 2.0, + "indie": 1.0, + "male vocalists": 3.0, + "emo": 3.0, + "american": 6.0, + "rock": 100.0, + "pop": 3.0, + "punk rock": 2.0, + "electronic": 4.0, + "rap": 3.0, + "seen live": 21.0, + "Hip-Hop": 2.0, + "alternative": 67.0, + "metal": 37.0, + "Nu Metal": 92.0, + "alternative rock": 74.0, + "00s": 2.0, + "punk": 4.0, + "hard rock": 5.0 + } + }, + { + "description": "Lorde", + "features": { + "indie": 72.0, + "singer-songwriter": 7.0, + "soul": 1.0, + "experimental": 2.0, + "pop": 100.0, + "electronica": 5.0, + "rock": 1.0, + "synthpop": 7.0, + "electronic": 81.0, + "trip-hop": 2.0, + "indie pop": 92.0, + "seen live": 20.0, + "alternative": 17.0, + "female vocalist": 4.0, + "female vocalists": 28.0, + "folk": 2.0 + } + }, + { + "description": "The Black Keys", + "features": { + "indie": 50.0, + "male vocalists": 2.0, + "soul": 2.0, + "Psychedelic Rock": 2.0, + "american": 8.0, + "blues": 68.0, + "classic rock": 2.0, + "rock": 63.0, + "psychedelic": 2.0, + "indie rock": 48.0, + "seen live": 37.0, + "alternative": 11.0, + "alternative rock": 7.0, + "00s": 3.0, + "hard rock": 2.0 + } + }, + { + "description": "Daft Punk", + "features": { + "indie": 2.0, + "chillout": 2.0, + "experimental": 2.0, + "electronica": 37.0, + "rock": 3.0, + "pop": 2.0, + "electro": 11.0, + "synthpop": 1.0, + "electronic": 100.0, + "dance": 54.0, + "french": 19.0, + "seen live": 7.0, + "techno": 36.0, + "alternative": 6.0, + "House": 54.0, + "trance": 2.0, + "00s": 2.0, + "Soundtrack": 2.0, + "funk": 4.0, + "90s": 3.0 + } + }, + { + "description": "Led Zeppelin", + "features": { + "favorites": 1.0, + "indie": 1.0, + "Psychedelic Rock": 3.0, + "british": 9.0, + "classic rock": 100.0, + "blues": 9.0, + "rock": 64.0, + "psychedelic": 4.0, + "heavy metal": 8.0, + "oldies": 1.0, + "metal": 4.0, + "alternative": 4.0, + "guitar": 2.0, + "Progressive rock": 33.0, + "alternative rock": 1.0, + "hard rock": 63.0, + "folk": 1.0, + "60s": 3.0, + "70s": 36.0, + "80s": 1.0 + } + }, + { + "description": "Marshmello", + "features": { + "emo": 10.0, + "pop": 28.0, + "electronic": 91.0, + "dance": 100.0, + "rap": 28.0, + "seen live": 19.0, + "rnb": 19.0, + "House": 10.0 + } + }, + { + "description": "Khalid", + "features": { + "indie": 7.0, + "male vocalists": 7.0, + "soul": 88.0, + "american": 19.0, + "pop": 100.0, + "synthpop": 7.0, + "electronic": 13.0, + "seen live": 25.0, + "rnb": 75.0, + "alternative": 63.0, + "folk": 7.0 + } + }, + { + "description": "David Guetta", + "features": { + "chillout": 1.0, + "electronica": 7.0, + "pop": 6.0, + "electro": 6.0, + "electronic": 76.0, + "dance": 82.0, + "french": 11.0, + "seen live": 9.0, + "techno": 39.0, + "House": 100.0, + "trance": 4.0, + "00s": 2.0 + } + }, + { + "description": "Lizzo", + "features": { + "american": 16.0, + "dance": 8.0, + "rap": 47.0, + "rnb": 54.0, + "female vocalists": 24.0, + "pop": 16.0, + "hip hop": 47.0, + "seen live": 93.0, + "Hip-Hop": 100.0, + "alternative": 8.0 + } + }, + { + "description": "Sia", + "features": { + "indie": 70.0, + "favorites": 1.0, + "singer-songwriter": 18.0, + "soul": 3.0, + "jazz": 2.0, + "chillout": 76.0, + "Mellow": 4.0, + "ambient": 2.0, + "pop": 20.0, + "electronica": 4.0, + "rock": 2.0, + "beautiful": 4.0, + "piano": 1.0, + "downtempo": 57.0, + "indie rock": 1.0, + "electronic": 16.0, + "trip-hop": 57.0, + "dance": 2.0, + "indie pop": 8.0, + "lounge": 2.0, + "seen live": 7.0, + "alternative": 9.0, + "acoustic": 2.0, + "female vocalist": 7.0, + "alternative rock": 1.0, + "00s": 2.0, + "female vocalists": 100.0, + "Love": 2.0 + } + }, + { + "description": "Elton John", + "features": { + "favorites": 2.0, + "indie": 1.0, + "singer-songwriter": 64.0, + "male vocalists": 9.0, + "soul": 2.0, + "british": 28.0, + "classic rock": 87.0, + "blues": 1.0, + "pop": 100.0, + "rock": 59.0, + "piano": 54.0, + "oldies": 4.0, + "britpop": 2.0, + "seen live": 19.0, + "alternative": 2.0, + "Soundtrack": 3.0, + "00s": 2.0, + "Love": 2.0, + "60s": 2.0, + "70s": 16.0, + "80s": 16.0, + "90s": 5.0 + } + }, + { + "description": "Twenty One Pilots", + "features": { + "american": 15.0, + "experimental": 6.0, + "electronica": 1.0, + "piano": 1.0, + "indie rock": 12.0, + "rap": 48.0, + "pop": 17.0, + "rock": 11.0, + "electronic": 100.0, + "noise": 1.0, + "indie pop": 71.0, + "seen live": 50.0, + "male vocalists": 4.0, + "punk": 1.0, + "Love": 1.0, + "indie": 84.0, + "emo": 5.0, + "electro": 1.0, + "synthpop": 1.0, + "hip hop": 7.0, + "Hip-Hop": 27.0, + "alternative": 84.0, + "alternative rock": 23.0 + } + }, + { + "description": "Avicii", + "features": { + "swedish": 20.0, + "seen live": 14.0, + "techno": 2.0, + "House": 100.0, + "trance": 3.0, + "electronica": 6.0, + "pop": 3.0, + "electro": 5.0, + "electronic": 83.0, + "dance": 66.0 + } + }, + { + "description": "Ellie Goulding", + "features": { + "indie": 85.0, + "singer-songwriter": 11.0, + "chillout": 3.0, + "british": 89.0, + "pop": 36.0, + "electronica": 3.0, + "rock": 1.0, + "electro": 2.0, + "synthpop": 9.0, + "electronic": 98.0, + "dance": 5.0, + "britpop": 2.0, + "indie pop": 78.0, + "seen live": 27.0, + "alternative": 6.0, + "acoustic": 2.0, + "female vocalist": 5.0, + "00s": 2.0, + "female vocalists": 100.0, + "folk": 4.0 + } + }, + { + "description": "Muse", + "features": { + "indie": 43.0, + "favorites": 2.0, + "male vocalists": 3.0, + "emo": 2.0, + "british": 21.0, + "experimental": 3.0, + "rock": 83.0, + "pop": 2.0, + "piano": 1.0, + "indie rock": 12.0, + "electronic": 4.0, + "britpop": 10.0, + "seen live": 46.0, + "alternative": 70.0, + "metal": 1.0, + "Progressive rock": 57.0, + "alternative rock": 100.0, + "00s": 2.0, + "hard rock": 2.0, + "90s": 2.0 + } + }, + { + "description": "Green Day", + "features": { + "indie": 3.0, + "favorites": 2.0, + "male vocalists": 2.0, + "emo": 4.0, + "american": 7.0, + "classic rock": 2.0, + "rock": 75.0, + "pop": 6.0, + "punk rock": 100.0, + "indie rock": 2.0, + "seen live": 26.0, + "Grunge": 1.0, + "alternative": 47.0, + "metal": 2.0, + "alternative rock": 17.0, + "00s": 2.0, + "punk": 69.0, + "hard rock": 2.0, + "90s": 5.0 + } + }, + { + "description": "Metallica", + "features": { + "seen live": 31.0, + "emo": 2.0, + "metal": 91.0, + "alternative": 2.0, + "american": 6.0, + "Power metal": 1.0, + "classic rock": 6.0, + "rock": 34.0, + "alternative rock": 2.0, + "hard rock": 41.0, + "heavy metal": 74.0, + "80s": 4.0, + "thrash metal": 100.0, + "90s": 3.0, + "Progressive metal": 2.0 + } + }, + { + "description": "Sam Smith", + "features": { + "indie": 3.0, + "male vocalists": 9.0, + "singer-songwriter": 8.0, + "soul": 100.0, + "british": 55.0, + "pop": 87.0, + "electronic": 45.0, + "dance": 32.0, + "seen live": 30.0, + "rnb": 7.0, + "alternative": 3.0, + "folk": 2.0 + } + }, + { + "description": "Kygo", + "features": { + "electronica": 7.0, + "downtempo": 49.0, + "dance": 5.0, + "House": 74.0, + "chillout": 65.0, + "pop": 5.0, + "synthpop": 3.0, + "electronic": 100.0, + "seen live": 36.0 + } + }, + { + "description": "Halsey", + "features": { + "american": 34.0, + "classic rock": 2.0, + "beautiful": 4.0, + "black metal": 4.0, + "pop": 100.0, + "electronic": 38.0, + "noise": 2.0, + "heavy metal": 2.0, + "indie pop": 44.0, + "seen live": 32.0, + "female vocalist": 4.0, + "singer-songwriter": 8.0, + "british": 4.0, + "rnb": 4.0, + "trance": 2.0, + "female vocalists": 44.0, + "indie": 68.0, + "soul": 4.0, + "emo": 4.0, + "synthpop": 12.0, + "alternative": 32.0 + } + }, + { + "description": "Michael Jackson", + "features": { + "male vocalists": 5.0, + "singer-songwriter": 2.0, + "soul": 36.0, + "american": 6.0, + "classic rock": 2.0, + "pop": 100.0, + "rock": 8.0, + "electronic": 1.0, + "dance": 41.0, + "seen live": 3.0, + "rnb": 7.0, + "70s": 3.0, + "80s": 50.0, + "funk": 34.0, + "90s": 5.0 + } + }, + { + "description": "Maroon 5", + "features": { + "indie": 12.0, + "favorites": 3.0, + "male vocalists": 9.0, + "singer-songwriter": 2.0, + "soul": 3.0, + "emo": 2.0, + "jazz": 2.0, + "american": 11.0, + "classic rock": 2.0, + "rock": 100.0, + "pop": 96.0, + "punk rock": 2.0, + "indie rock": 3.0, + "electronic": 1.0, + "dance": 2.0, + "britpop": 1.0, + "indie pop": 2.0, + "seen live": 16.0, + "alternative": 69.0, + "acoustic": 2.0, + "metal": 1.0, + "alternative rock": 52.0, + "00s": 4.0, + "punk": 3.0, + "Love": 2.0, + "funk": 5.0 + } + }, + { + "description": "Charli XCX", + "features": { + "singer-songwriter": 5.0, + "british": 26.0, + "experimental": 2.0, + "electronica": 5.0, + "dance": 4.0, + "female vocalists": 56.0, + "indie": 7.0, + "chillout": 11.0, + "pop": 98.0, + "rock": 2.0, + "electro": 4.0, + "synthpop": 100.0, + "electronic": 99.0, + "new wave": 4.0, + "britpop": 2.0, + "indie pop": 7.0, + "seen live": 63.0, + "Hip-Hop": 2.0, + "alternative": 5.0, + "female vocalist": 2.0, + "00s": 2.0 + } + }, + { + "description": "Foo Fighters", + "features": { + "indie": 7.0, + "favorites": 2.0, + "male vocalists": 2.0, + "emo": 1.0, + "american": 5.0, + "classic rock": 1.0, + "rock": 100.0, + "pop": 2.0, + "punk rock": 2.0, + "indie rock": 3.0, + "seen live": 35.0, + "Grunge": 48.0, + "alternative": 47.0, + "metal": 2.0, + "alternative rock": 69.0, + "00s": 2.0, + "punk": 5.0, + "hard rock": 30.0, + "90s": 4.0 + } + }, + { + "description": "Florence + the Machine", + "features": { + "indie": 100.0, + "singer-songwriter": 7.0, + "soul": 5.0, + "british": 72.0, + "experimental": 2.0, + "pop": 10.0, + "rock": 5.0, + "beautiful": 1.0, + "indie rock": 8.0, + "electronic": 2.0, + "britpop": 2.0, + "indie pop": 61.0, + "seen live": 29.0, + "alternative": 72.0, + "female vocalist": 3.0, + "alternative rock": 5.0, + "00s": 2.0, + "female vocalists": 86.0, + "Love": 2.0, + "folk": 6.0 + } + }, + { + "description": "blink-182", + "features": { + "indie": 3.0, + "favorites": 2.0, + "male vocalists": 2.0, + "emo": 8.0, + "american": 6.0, + "rock": 56.0, + "pop": 5.0, + "punk rock": 100.0, + "indie rock": 2.0, + "seen live": 23.0, + "hardcore": 2.0, + "alternative": 42.0, + "metal": 2.0, + "alternative rock": 10.0, + "00s": 1.0, + "punk": 72.0, + "hard rock": 1.0, + "90s": 4.0 + } + }, + { + "description": "Vampire Weekend", + "features": { + "indie": 100.0, + "male vocalists": 3.0, + "american": 11.0, + "experimental": 6.0, + "rock": 37.0, + "pop": 9.0, + "indie rock": 82.0, + "electronic": 2.0, + "indie pop": 63.0, + "seen live": 58.0, + "alternative": 57.0, + "alternative rock": 7.0, + "00s": 4.0, + "folk": 1.0 + } + }, + { + "description": "Martin Garrix", + "features": { + "german": 2.0, + "experimental": 2.0, + "american": 2.0, + "electronica": 5.0, + "dance": 57.0, + "House": 100.0, + "Soundtrack": 2.0, + "black metal": 2.0, + "Power metal": 2.0, + "pop": 30.0, + "electronic": 80.0, + "noise": 2.0, + "seen live": 38.0, + "Grunge": 2.0, + "techno": 2.0, + "trance": 3.0, + "electro": 5.0 + } + }, + { + "description": "Paramore", + "features": { + "indie": 9.0, + "favorites": 2.0, + "emo": 35.0, + "american": 7.0, + "rock": 100.0, + "pop": 6.0, + "punk rock": 8.0, + "indie rock": 4.0, + "seen live": 34.0, + "alternative": 79.0, + "female vocalist": 6.0, + "alternative rock": 22.0, + "screamo": 1.0, + "00s": 2.0, + "female vocalists": 72.0, + "punk": 13.0, + "Love": 2.0 + } + }, + { + "description": "Britney Spears", + "features": { + "singer-songwriter": 2.0, + "american": 9.0, + "electronica": 1.0, + "beautiful": 2.0, + "dance": 44.0, + "rnb": 3.0, + "House": 1.0, + "trance": 1.0, + "female vocalists": 44.0, + "Love": 2.0, + "black metal": 2.0, + "90s": 6.0, + "indie": 1.0, + "death metal": 1.0, + "emo": 2.0, + "pop": 100.0, + "rock": 3.0, + "electro": 2.0, + "electronic": 5.0, + "seen live": 7.0, + "Hip-Hop": 2.0, + "alternative": 2.0, + "female vocalist": 4.0, + "00s": 4.0 + } + }, + { + "description": "Travi$ Scott", + "features": { + "male vocalists": 2.0, + "american": 10.0, + "experimental": 4.0, + "electronica": 2.0, + "rap": 62.0, + "rnb": 4.0, + "soul": 4.0, + "electro": 4.0, + "hip hop": 20.0, + "seen live": 24.0, + "Hip-Hop": 100.0, + "alternative": 2.0 + } + }, + { + "description": "Oasis", + "features": { + "indie": 45.0, + "favorites": 1.0, + "male vocalists": 2.0, + "british": 61.0, + "classic rock": 3.0, + "rock": 89.0, + "pop": 7.0, + "indie rock": 12.0, + "britpop": 100.0, + "seen live": 21.0, + "alternative": 53.0, + "alternative rock": 20.0, + "00s": 2.0, + "punk": 1.0, + "hard rock": 2.0, + "90s": 10.0 + } + }, + { + "description": "A$AP Rocky", + "features": { + "male vocalists": 3.0, + "american": 9.0, + "experimental": 2.0, + "hip hop": 12.0, + "rap": 61.0, + "seen live": 30.0, + "Hip-Hop": 100.0 + } + }, + { + "description": "Nicki Minaj", + "features": { + "singer-songwriter": 2.0, + "american": 7.0, + "dance": 9.0, + "rap": 84.0, + "rnb": 51.0, + "female vocalists": 25.0, + "Love": 2.0, + "chillout": 1.0, + "pop": 44.0, + "hip hop": 39.0, + "electronic": 3.0, + "seen live": 4.0, + "Hip-Hop": 100.0, + "alternative": 2.0, + "female vocalist": 3.0 + } + }, + { + "description": "The Smiths", + "features": { + "indie": 100.0, + "favorites": 3.0, + "male vocalists": 3.0, + "singer-songwriter": 2.0, + "emo": 2.0, + "british": 32.0, + "classic rock": 4.0, + "rock": 32.0, + "pop": 10.0, + "indie rock": 22.0, + "new wave": 85.0, + "electronic": 1.0, + "britpop": 10.0, + "indie pop": 10.0, + "seen live": 2.0, + "alternative": 77.0, + "post-punk": 85.0, + "alternative rock": 21.0, + "punk": 2.0, + "Love": 2.0, + "80s": 96.0 + } + }, + { + "description": "The Strokes", + "features": { + "indie": 97.0, + "favorites": 2.0, + "male vocalists": 2.0, + "emo": 1.0, + "american": 10.0, + "british": 2.0, + "classic rock": 2.0, + "rock": 98.0, + "pop": 2.0, + "punk rock": 2.0, + "indie rock": 100.0, + "new wave": 1.0, + "britpop": 2.0, + "indie pop": 3.0, + "seen live": 42.0, + "alternative": 71.0, + "post-punk": 5.0, + "alternative rock": 59.0, + "00s": 4.0, + "punk": 4.0, + "Love": 1.0 + } + }, + { + "description": "MGMT", + "features": { + "indie": 90.0, + "male vocalists": 2.0, + "Psychedelic Rock": 4.0, + "american": 8.0, + "experimental": 5.0, + "psychedelic": 68.0, + "pop": 7.0, + "rock": 5.0, + "electronica": 5.0, + "electro": 3.0, + "synthpop": 10.0, + "indie rock": 10.0, + "electronic": 100.0, + "dance": 3.0, + "indie pop": 51.0, + "seen live": 35.0, + "alternative": 53.0, + "post-punk": 1.0, + "alternative rock": 3.0, + "00s": 3.0 + } + }, + { + "description": "Fall Out Boy", + "features": { + "indie": 14.0, + "favorites": 3.0, + "male vocalists": 3.0, + "emo": 86.0, + "american": 7.0, + "rock": 91.0, + "pop": 9.0, + "punk rock": 28.0, + "indie rock": 4.0, + "dance": 1.0, + "seen live": 39.0, + "hardcore": 3.0, + "alternative": 69.0, + "metal": 2.0, + "alternative rock": 16.0, + "screamo": 3.0, + "00s": 2.0, + "punk": 55.0, + "Love": 2.0 + } + }, + { + "description": "Dua Lipa", + "features": { + "beautiful": 8.0, + "dance": 11.0, + "pop": 100.0, + "electronic": 11.0, + "indie pop": 16.0, + "seen live": 28.0, + "british": 29.0, + "japanese": 6.0, + "rnb": 12.0, + "female vocalists": 31.0, + "indie": 9.0, + "emo": 9.0, + "synthpop": 35.0 + } + }, + { + "description": "Jonas Brothers", + "features": { + "american": 9.0, + "grindcore": 3.0, + "punk rock": 2.0, + "dance": 2.0, + "metal": 3.0, + "House": 2.0, + "Soundtrack": 2.0, + "black metal": 3.0, + "Power metal": 2.0, + "pop": 100.0, + "rock": 56.0, + "Melodic Death Metal": 3.0, + "seen live": 17.0, + "00s": 4.0, + "male vocalists": 10.0, + "female vocalists": 2.0, + "punk": 3.0, + "Love": 3.0, + "indie": 2.0, + "death metal": 4.0, + "emo": 3.0, + "metalcore": 2.0, + "hardcore": 2.0, + "alternative": 2.0, + "alternative rock": 2.0 + } + }, + { + "description": "Foster the People", + "features": { + "indie": 100.0, + "male vocalists": 4.0, + "american": 36.0, + "pop": 10.0, + "rock": 7.0, + "indie rock": 12.0, + "electronic": 8.0, + "dance": 2.0, + "indie pop": 83.0, + "seen live": 23.0, + "alternative": 65.0, + "alternative rock": 7.0, + "00s": 1.0 + } + }, + { + "description": "Bon Iver", + "features": { + "indie": 75.0, + "singer-songwriter": 70.0, + "male vocalists": 4.0, + "Mellow": 3.0, + "chillout": 2.0, + "american": 7.0, + "experimental": 2.0, + "ambient": 2.0, + "rock": 2.0, + "beautiful": 3.0, + "indie rock": 5.0, + "indie pop": 2.0, + "seen live": 36.0, + "acoustic": 59.0, + "alternative": 6.0, + "00s": 2.0, + "folk": 100.0 + } + }, + { + "description": "Major Lazer", + "features": { + "indie": 2.0, + "american": 4.0, + "experimental": 3.0, + "british": 2.0, + "electronica": 5.0, + "pop": 2.0, + "electro": 37.0, + "hip hop": 2.0, + "electronic": 85.0, + "dance": 12.0, + "seen live": 100.0, + "Hip-Hop": 4.0, + "alternative": 2.0, + "House": 3.0, + "00s": 2.0, + "funk": 4.0, + "reggae": 66.0 + } + }, + { + "description": "Two Door Cinema Club", + "features": { + "indie": 100.0, + "male vocalists": 2.0, + "british": 63.0, + "rock": 6.0, + "pop": 3.0, + "electronica": 2.0, + "synthpop": 2.0, + "indie rock": 19.0, + "electronic": 68.0, + "dance": 2.0, + "britpop": 2.0, + "indie pop": 10.0, + "seen live": 47.0, + "alternative": 53.0, + "alternative rock": 4.0, + "00s": 2.0 + } + }, + { + "description": "OneRepublic", + "features": { + "indie": 63.0, + "favorites": 2.0, + "male vocalists": 8.0, + "emo": 1.0, + "american": 12.0, + "rock": 100.0, + "pop": 21.0, + "piano": 2.0, + "indie rock": 5.0, + "indie pop": 2.0, + "seen live": 9.0, + "alternative": 94.0, + "acoustic": 1.0, + "alternative rock": 80.0, + "00s": 3.0, + "Love": 2.0 + } + }, + { + "description": "Cage the Elephant", + "features": { + "indie": 59.0, + "male vocalists": 2.0, + "american": 11.0, + "rock": 68.0, + "punk rock": 44.0, + "indie rock": 100.0, + "seen live": 41.0, + "alternative": 73.0, + "alternative rock": 26.0, + "00s": 4.0, + "punk": 7.0 + } + }, + { + "description": "Arcade Fire", + "features": { + "indie": 100.0, + "male vocalists": 2.0, + "experimental": 6.0, + "rock": 48.0, + "pop": 2.0, + "beautiful": 1.0, + "post-rock": 2.0, + "indie rock": 99.0, + "new wave": 1.0, + "indie pop": 4.0, + "seen live": 59.0, + "alternative": 76.0, + "post-punk": 3.0, + "alternative rock": 16.0, + "00s": 5.0, + "female vocalists": 2.0, + "folk": 6.0 + } + }, + { + "description": "Bruno Mars", + "features": { + "indie": 3.0, + "male vocalists": 47.0, + "singer-songwriter": 7.0, + "soul": 10.0, + "american": 8.0, + "blues": 2.0, + "pop": 100.0, + "rock": 2.0, + "hip hop": 2.0, + "dance": 2.0, + "seen live": 6.0, + "Hip-Hop": 3.0, + "rnb": 63.0, + "alternative": 2.0, + "acoustic": 1.0, + "folk": 1.0, + "funk": 4.0, + "reggae": 4.0 + } + }, + { + "description": "Carly Rae Jepsen", + "features": { + "singer-songwriter": 5.0, + "soul": 2.0, + "chillout": 2.0, + "pop": 100.0, + "synthpop": 9.0, + "electronic": 4.0, + "dance": 11.0, + "seen live": 6.0, + "acoustic": 21.0, + "female vocalist": 4.0, + "00s": 1.0, + "female vocalists": 46.0, + "folk": 26.0 + } + }, + { + "description": "Weezer", + "features": { + "indie": 50.0, + "favorites": 3.0, + "male vocalists": 2.0, + "emo": 15.0, + "american": 8.0, + "classic rock": 2.0, + "rock": 100.0, + "pop": 6.0, + "punk rock": 5.0, + "indie rock": 41.0, + "britpop": 1.0, + "indie pop": 3.0, + "seen live": 37.0, + "hardcore": 1.0, + "Grunge": 2.0, + "alternative": 86.0, + "metal": 2.0, + "alternative rock": 73.0, + "00s": 2.0, + "punk": 11.0, + "Love": 1.0, + "hard rock": 2.0, + "90s": 9.0 + } + }, + { + "description": "P!nk", + "features": { + "indie": 2.0, + "favorites": 2.0, + "singer-songwriter": 5.0, + "soul": 2.0, + "american": 11.0, + "pop": 100.0, + "rock": 59.0, + "electronic": 2.0, + "dance": 7.0, + "seen live": 14.0, + "Hip-Hop": 2.0, + "rnb": 5.0, + "alternative": 4.0, + "female vocalist": 4.0, + "alternative rock": 2.0, + "00s": 4.0, + "female vocalists": 74.0, + "punk": 3.0 + } + }, + { + "description": "System of a Down", + "features": { + "indie": 2.0, + "favorites": 1.0, + "male vocalists": 1.0, + "emo": 2.0, + "american": 5.0, + "experimental": 3.0, + "rock": 65.0, + "punk rock": 2.0, + "metalcore": 1.0, + "heavy metal": 6.0, + "Progressive metal": 3.0, + "thrash metal": 2.0, + "seen live": 18.0, + "hardcore": 3.0, + "metal": 100.0, + "alternative": 54.0, + "Progressive rock": 2.0, + "Nu Metal": 62.0, + "alternative rock": 13.0, + "industrial": 1.0, + "00s": 2.0, + "punk": 3.0, + "hard rock": 20.0, + "90s": 2.0 + } + }, + { + "description": "Adele", + "features": { + "indie": 40.0, + "singer-songwriter": 50.0, + "soul": 100.0, + "jazz": 8.0, + "chillout": 2.0, + "Mellow": 2.0, + "british": 66.0, + "blues": 3.0, + "pop": 19.0, + "rock": 2.0, + "beautiful": 1.0, + "piano": 2.0, + "britpop": 3.0, + "indie pop": 3.0, + "seen live": 2.0, + "rnb": 2.0, + "acoustic": 4.0, + "alternative": 4.0, + "female vocalist": 4.0, + "00s": 2.0, + "female vocalists": 81.0, + "Love": 2.0, + "folk": 2.0 + } + }, + { + "description": "xxxtentacion", + "features": { + "american": 11.0, + "experimental": 7.0, + "punk rock": 4.0, + "rap": 80.0, + "folk": 4.0, + "rock": 7.0, + "pop": 4.0, + "heavy metal": 4.0, + "seen live": 4.0, + "rnb": 7.0, + "emo": 49.0, + "soul": 4.0, + "hip hop": 32.0, + "new wave": 4.0, + "hardcore": 4.0, + "Hip-Hop": 100.0, + "alternative": 11.0, + "alternative rock": 7.0 + } + }, + { + "description": "The 1975", + "features": { + "male vocalists": 5.0, + "british": 69.0, + "experimental": 2.0, + "indie rock": 98.0, + "Love": 1.0, + "indie": 100.0, + "emo": 1.0, + "ambient": 1.0, + "rock": 21.0, + "pop": 9.0, + "post-rock": 1.0, + "synthpop": 5.0, + "new wave": 4.0, + "electronic": 3.0, + "britpop": 1.0, + "indie pop": 17.0, + "seen live": 73.0, + "alternative": 69.0, + "alternative rock": 20.0, + "00s": 1.0, + "funk": 1.0 + } + }, + { + "description": "Depeche Mode", + "features": { + "indie": 3.0, + "favorites": 1.0, + "male vocalists": 2.0, + "british": 13.0, + "ambient": 1.0, + "experimental": 1.0, + "classic rock": 2.0, + "rock": 16.0, + "electronica": 11.0, + "pop": 9.0, + "electro": 3.0, + "synthpop": 56.0, + "electronic": 100.0, + "new wave": 87.0, + "dance": 3.0, + "britpop": 2.0, + "seen live": 22.0, + "techno": 1.0, + "alternative": 20.0, + "Gothic": 2.0, + "post-punk": 4.0, + "alternative rock": 5.0, + "industrial": 3.0, + "00s": 2.0, + "80s": 59.0, + "90s": 4.0 + } + }, + { + "description": "The White Stripes", + "features": { + "indie": 59.0, + "favorites": 2.0, + "male vocalists": 1.0, + "singer-songwriter": 1.0, + "american": 8.0, + "experimental": 1.0, + "blues": 13.0, + "classic rock": 3.0, + "rock": 100.0, + "pop": 2.0, + "punk rock": 2.0, + "indie rock": 47.0, + "seen live": 25.0, + "Grunge": 1.0, + "alternative": 74.0, + "metal": 1.0, + "guitar": 2.0, + "Progressive rock": 1.0, + "alternative rock": 65.0, + "00s": 3.0, + "punk": 5.0, + "hard rock": 3.0, + "folk": 2.0, + "90s": 2.0 + } + }, + { + "description": "The Clash", + "features": { + "indie": 5.0, + "british": 43.0, + "classic rock": 29.0, + "rock": 43.0, + "pop": 1.0, + "punk rock": 71.0, + "indie rock": 2.0, + "new wave": 4.0, + "alternative": 9.0, + "post-punk": 3.0, + "alternative rock": 2.0, + "punk": 100.0, + "hard rock": 1.0, + "70s": 8.0, + "80s": 13.0, + "reggae": 6.0 + } + } +] \ No newline at end of file diff --git a/algorithms-miscellaneous-3/src/main/resources/kmeans/lastfm.json b/algorithms-miscellaneous-3/src/main/resources/kmeans/lastfm.json new file mode 100644 index 0000000000..4d684b2fc0 --- /dev/null +++ b/algorithms-miscellaneous-3/src/main/resources/kmeans/lastfm.json @@ -0,0 +1,490 @@ +{ + "children": [ + { + "children": [ + { + "name": "Radiohead" + }, + { + "name": "Red Hot Chili Peppers" + }, + { + "name": "Coldplay" + }, + { + "name": "Nirvana" + }, + { + "name": "Panic! at the Disco" + }, + { + "name": "The Cure" + }, + { + "name": "Linkin Park" + }, + { + "name": "Radiohead" + }, + { + "name": "Red Hot Chili Peppers" + }, + { + "name": "Coldplay" + }, + { + "name": "Nirvana" + }, + { + "name": "Panic! at the Disco" + }, + { + "name": "The Cure" + }, + { + "name": "Linkin Park" + }, + { + "name": "Muse" + }, + { + "name": "Maroon 5" + }, + { + "name": "Foo Fighters" + }, + { + "name": "Paramore" + }, + { + "name": "Oasis" + }, + { + "name": "Fall Out Boy" + }, + { + "name": "OneRepublic" + }, + { + "name": "Weezer" + }, + { + "name": "System of a Down" + }, + { + "name": "The White Stripes" + } + ], + "name": "rock, alternative" + }, + { + "children": [ + { + "name": "Lil Nas X" + }, + { + "name": "Post Malone" + }, + { + "name": "Drake" + }, + { + "name": "Kanye West" + }, + { + "name": "Kendrick Lamar" + }, + { + "name": "Tyler, the Creator" + }, + { + "name": "Eminem" + }, + { + "name": "Childish Gambino" + }, + { + "name": "Frank Ocean" + }, + { + "name": "Lil Nas X" + }, + { + "name": "Post Malone" + }, + { + "name": "Drake" + }, + { + "name": "Kanye West" + }, + { + "name": "Kendrick Lamar" + }, + { + "name": "Tyler, the Creator" + }, + { + "name": "Eminem" + }, + { + "name": "Childish Gambino" + }, + { + "name": "Frank Ocean" + }, + { + "name": "Lizzo" + }, + { + "name": "Travi$ Scott" + }, + { + "name": "A$AP Rocky" + }, + { + "name": "Nicki Minaj" + }, + { + "name": "xxxtentacion" + } + ], + "name": "Hip-Hop, rap" + }, + { + "children": [ + { + "name": "Arctic Monkeys" + }, + { + "name": "Imagine Dragons" + }, + { + "name": "The Killers" + }, + { + "name": "Gorillaz" + }, + { + "name": "The Black Keys" + }, + { + "name": "Arctic Monkeys" + }, + { + "name": "Imagine Dragons" + }, + { + "name": "The Killers" + }, + { + "name": "Gorillaz" + }, + { + "name": "The Black Keys" + }, + { + "name": "Twenty One Pilots" + }, + { + "name": "Ellie Goulding" + }, + { + "name": "Florence + the Machine" + }, + { + "name": "Vampire Weekend" + }, + { + "name": "The Smiths" + }, + { + "name": "The Strokes" + }, + { + "name": "MGMT" + }, + { + "name": "Foster the People" + }, + { + "name": "Two Door Cinema Club" + }, + { + "name": "Cage the Elephant" + }, + { + "name": "Arcade Fire" + }, + { + "name": "The 1975" + } + ], + "name": "indie, alternative" + }, + { + "children": [ + { + "name": "Ed Sheeran" + }, + { + "name": "Tame Impala" + }, + { + "name": "Ed Sheeran" + }, + { + "name": "Tame Impala" + }, + { + "name": "Green Day" + }, + { + "name": "Metallica" + }, + { + "name": "blink-182" + }, + { + "name": "Bon Iver" + }, + { + "name": "The Clash" + } + ], + "name": "rock, punk rock" + }, + { + "children": [ + { + "name": "Calvin Harris" + }, + { + "name": "The Weeknd" + }, + { + "name": "The Chainsmokers" + }, + { + "name": "Daft Punk" + }, + { + "name": "Marshmello" + }, + { + "name": "David Guetta" + }, + { + "name": "Calvin Harris" + }, + { + "name": "The Weeknd" + }, + { + "name": "The Chainsmokers" + }, + { + "name": "Daft Punk" + }, + { + "name": "Marshmello" + }, + { + "name": "David Guetta" + }, + { + "name": "Avicii" + }, + { + "name": "Kygo" + }, + { + "name": "Martin Garrix" + }, + { + "name": "Major Lazer" + }, + { + "name": "Depeche Mode" + } + ], + "name": "electronic, dance" + }, + { + "children": [ + { + "name": "Queen" + }, + { + "name": "The Beatles" + }, + { + "name": "David Bowie" + }, + { + "name": "Fleetwood Mac" + }, + { + "name": "Pink Floyd" + }, + { + "name": "The Rolling Stones" + }, + { + "name": "Led Zeppelin" + }, + { + "name": "Queen" + }, + { + "name": "The Beatles" + }, + { + "name": "David Bowie" + }, + { + "name": "Fleetwood Mac" + }, + { + "name": "Pink Floyd" + }, + { + "name": "The Rolling Stones" + }, + { + "name": "Led Zeppelin" + }, + { + "name": "Elton John" + } + ], + "name": "classic rock, rock" + }, + { + "children": [ + { + "name": "Billie Eilish" + }, + { + "name": "Ariana Grande" + }, + { + "name": "Taylor Swift" + }, + { + "name": "Beyoncé" + }, + { + "name": "Shawn Mendes" + }, + { + "name": "Rihanna" + }, + { + "name": "Lana Del Rey" + }, + { + "name": "Katy Perry" + }, + { + "name": "Lady Gaga" + }, + { + "name": "Miley Cyrus" + }, + { + "name": "Mark Ronson" + }, + { + "name": "Madonna" + }, + { + "name": "Lorde" + }, + { + "name": "Khalid" + }, + { + "name": "Billie Eilish" + }, + { + "name": "Ariana Grande" + }, + { + "name": "Taylor Swift" + }, + { + "name": "Beyoncé" + }, + { + "name": "Shawn Mendes" + }, + { + "name": "Rihanna" + }, + { + "name": "Lana Del Rey" + }, + { + "name": "Katy Perry" + }, + { + "name": "Lady Gaga" + }, + { + "name": "Miley Cyrus" + }, + { + "name": "Mark Ronson" + }, + { + "name": "Madonna" + }, + { + "name": "Lorde" + }, + { + "name": "Khalid" + }, + { + "name": "Sia" + }, + { + "name": "Sam Smith" + }, + { + "name": "Halsey" + }, + { + "name": "Michael Jackson" + }, + { + "name": "Charli XCX" + }, + { + "name": "Britney Spears" + }, + { + "name": "Dua Lipa" + }, + { + "name": "Jonas Brothers" + }, + { + "name": "Bruno Mars" + }, + { + "name": "Carly Rae Jepsen" + }, + { + "name": "P!nk" + }, + { + "name": "Adele" + } + ], + "name": "pop, female vocalists" + } + ], + "name": "Musicians" +} diff --git a/algorithms-miscellaneous-3/src/main/resources/kmeans/radial.html b/algorithms-miscellaneous-3/src/main/resources/kmeans/radial.html new file mode 100644 index 0000000000..e7e7403871 --- /dev/null +++ b/algorithms-miscellaneous-3/src/main/resources/kmeans/radial.html @@ -0,0 +1,68 @@ + + + + + + \ No newline at end of file diff --git a/algorithms-miscellaneous-3/src/test/java/com/baeldung/algorithms/interpolationsearch/InterpolationSearchUnitTest.java b/algorithms-miscellaneous-3/src/test/java/com/baeldung/algorithms/interpolationsearch/InterpolationSearchUnitTest.java new file mode 100644 index 0000000000..8ad962055e --- /dev/null +++ b/algorithms-miscellaneous-3/src/test/java/com/baeldung/algorithms/interpolationsearch/InterpolationSearchUnitTest.java @@ -0,0 +1,29 @@ +package com.baeldung.algorithms.interpolationsearch; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.Before; +import org.junit.Test; + +public class InterpolationSearchUnitTest { + + private int[] myData; + + @Before + public void setUp() { + myData = new int[]{13,21,34,55,69,73,84,101}; + } + + @Test + public void givenSortedArray_whenLookingFor84_thenReturn6() { + int pos = InterpolationSearch.interpolationSearch(myData, 84); + assertEquals(6, pos); + } + + @Test + public void givenSortedArray_whenLookingFor19_thenReturnMinusOne() { + int pos = InterpolationSearch.interpolationSearch(myData, 19); + assertEquals(-1, pos); + } + +} diff --git a/algorithms-miscellaneous-3/src/test/java/com/baeldung/algorithms/printtriangles/PrintTriangleExamplesUnitTest.java b/algorithms-miscellaneous-3/src/test/java/com/baeldung/algorithms/printtriangles/PrintTriangleExamplesUnitTest.java new file mode 100644 index 0000000000..6fa6584b8e --- /dev/null +++ b/algorithms-miscellaneous-3/src/test/java/com/baeldung/algorithms/printtriangles/PrintTriangleExamplesUnitTest.java @@ -0,0 +1,93 @@ +package com.baeldung.algorithms.printtriangles; + +import junitparams.JUnitParamsRunner; +import junitparams.Parameters; +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.assertEquals; + +@RunWith(JUnitParamsRunner.class) +public class PrintTriangleExamplesUnitTest { + + private static Object[][] rightAngledTriangles() { + String expected0 = ""; + + String expected2 = "*" + System.lineSeparator() + + "**" + System.lineSeparator(); + + String expected5 = "*" + System.lineSeparator() + + "**" + System.lineSeparator() + + "***" + System.lineSeparator() + + "****" + System.lineSeparator() + + "*****" + System.lineSeparator(); + + String expected7 = "*" + System.lineSeparator() + + "**" + System.lineSeparator() + + "***" + System.lineSeparator() + + "****" + System.lineSeparator() + + "*****" + System.lineSeparator() + + "******" + System.lineSeparator() + + "*******" + System.lineSeparator(); + + return new Object[][] { + { 0, expected0 }, + { 2, expected2 }, + { 5, expected5 }, + { 7, expected7 } + }; + } + + @Test + @Parameters(method = "rightAngledTriangles") + public void whenPrintARightAngledTriangleIsCalled_ThenTheCorrectStringIsReturned(int nrOfRows, String expected) { + String actual = PrintTriangleExamples.printARightAngledTriangle(nrOfRows); + + assertEquals(expected, actual); + } + + private static Object[][] isoscelesTriangles() { + String expected0 = ""; + + String expected2 = " *" + System.lineSeparator() + + "***" + System.lineSeparator(); + + String expected5 = " *" + System.lineSeparator() + + " ***" + System.lineSeparator() + + " *****" + System.lineSeparator() + + " *******" + System.lineSeparator() + + "*********" + System.lineSeparator(); + + String expected7 = " *" + System.lineSeparator() + + " ***" + System.lineSeparator() + + " *****" + System.lineSeparator() + + " *******" + System.lineSeparator() + + " *********" + System.lineSeparator() + + " ***********" + System.lineSeparator() + + "*************" + System.lineSeparator(); + + return new Object[][] { + { 0, expected0 }, + { 2, expected2 }, + { 5, expected5 }, + { 7, expected7 } + }; + } + + @Test + @Parameters(method = "isoscelesTriangles") + public void whenPrintAnIsoscelesTriangleIsCalled_ThenTheCorrectStringIsReturned(int nrOfRows, String expected) { + String actual = PrintTriangleExamples.printAnIsoscelesTriangle(nrOfRows); + + assertEquals(expected, actual); + } + + @Test + @Parameters(method = "isoscelesTriangles") + public void whenPrintAnIsoscelesTriangleUsingSubstringIsCalled_ThenTheCorrectStringIsReturned(int nrOfRows, String expected) { + String actual = PrintTriangleExamples.printAnIsoscelesTriangleUsingSubstring(nrOfRows); + + assertEquals(expected, actual); + } + +} diff --git a/algorithms-miscellaneous-3/src/test/java/com/baeldung/algorithms/stringsortingbynumber/NaturalOrderComparatorsUnitTest.java b/algorithms-miscellaneous-3/src/test/java/com/baeldung/algorithms/stringsortingbynumber/NaturalOrderComparatorsUnitTest.java new file mode 100644 index 0000000000..549151bc93 --- /dev/null +++ b/algorithms-miscellaneous-3/src/test/java/com/baeldung/algorithms/stringsortingbynumber/NaturalOrderComparatorsUnitTest.java @@ -0,0 +1,79 @@ +package com.baeldung.algorithms.stringsortingbynumber; + +import com.baeldung.algorithms.stringsortingbynumber.NaturalOrderComparators; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import static org.junit.Assert.*; + +public class NaturalOrderComparatorsUnitTest { + + @Test + public void givenSimpleStringsContainingIntsAndDoubles_whenSortedByRegex_checkSortingCorrect() { + + List testStrings = Arrays.asList("a1", "b3", "c4", "d2.2", "d2.4", "d2.3d"); + + testStrings.sort(NaturalOrderComparators.createNaturalOrderRegexComparator()); + + List expected = Arrays.asList("a1", "d2.2", "d2.3d", "d2.4", "b3", "c4"); + + assertEquals(expected, testStrings); + + + } + + @Test + public void givenSimpleStringsContainingIntsAndDoublesWithAnInvalidNumber_whenSortedByRegex_checkSortingCorrect() { + + List testStrings = Arrays.asList("a1", "b3", "c4", "d2.2", "d2.4", "d2.3.3d"); + + testStrings.sort(NaturalOrderComparators.createNaturalOrderRegexComparator()); + + List expected = Arrays.asList("d2.3.3d", "a1", "d2.2", "d2.4", "b3", "c4"); + + assertEquals(expected, testStrings); + + + } + + @Test + public void givenAllForseenProblems_whenSortedByRegex_checkSortingCorrect() { + + List testStrings = Arrays.asList("a1", "b3", "c4", "d2.2", "d2.f4", "d2.3.3d"); + + testStrings.sort(NaturalOrderComparators.createNaturalOrderRegexComparator()); + + List expected = Arrays.asList("d2.3.3d", "a1", "d2.2", "d2.f4", "b3", "c4"); + + assertEquals(expected, testStrings); + + + } + + @Test + public void givenComplexStringsContainingSeparatedNumbers_whenSortedByRegex_checkNumbersCondensedAndSorted() { + + List testStrings = Arrays.asList("a1b2c5", "b3ght3.2", "something65.thensomething5"); //125, 33.2, 65.5 + + List expected = Arrays.asList("b3ght3.2", "something65.thensomething5", "a1b2c5" ); + + testStrings.sort(NaturalOrderComparators.createNaturalOrderRegexComparator()); + + assertEquals(expected, testStrings); + + } + + @Test + public void givenStringsNotContainingNumbers_whenSortedByRegex_checkOrderNotChanged() { + + List testStrings = Arrays.asList("a", "c", "d", "e"); + List expected = new ArrayList<>(testStrings); + + testStrings.sort(NaturalOrderComparators.createNaturalOrderRegexComparator()); + + assertEquals(expected, testStrings); + } +} \ No newline at end of file diff --git a/algorithms-sorting/README.md b/algorithms-sorting/README.md index 36460293b0..48c75f88cd 100644 --- a/algorithms-sorting/README.md +++ b/algorithms-sorting/README.md @@ -5,3 +5,4 @@ - [Quicksort Algorithm Implementation in Java](https://www.baeldung.com/java-quicksort) - [Insertion Sort in Java](https://www.baeldung.com/java-insertion-sort) - [Heap Sort in Java](https://www.baeldung.com/java-heap-sort) +- [Shell Sort in Java](https://www.baeldung.com/java-shell-sort) diff --git a/algorithms-sorting/src/main/java/com/baeldung/algorithms/inoutsort/InOutSort.java b/algorithms-sorting/src/main/java/com/baeldung/algorithms/inoutsort/InOutSort.java new file mode 100644 index 0000000000..5ba225cead --- /dev/null +++ b/algorithms-sorting/src/main/java/com/baeldung/algorithms/inoutsort/InOutSort.java @@ -0,0 +1,25 @@ +package com.baeldung.algorithms.inoutsort; + +public class InOutSort { + + public static int[] reverseInPlace(int A[]) { + int n = A.length; + for (int i = 0; i < n / 2; i++) { + int temp = A[i]; + A[i] = A[n - 1 - i]; + A[n - 1 - i] = temp; + } + + return A; + } + + public static int[] reverseOutOfPlace(int A[]) { + int n = A.length; + int[] B = new int[n]; + for (int i = 0; i < n; i++) { + B[n - i - 1] = A[i]; + } + + return B; + } +} diff --git a/algorithms-sorting/src/main/java/com/baeldung/algorithms/selectionsort/SelectionSort.java b/algorithms-sorting/src/main/java/com/baeldung/algorithms/selectionsort/SelectionSort.java new file mode 100644 index 0000000000..17e95edf06 --- /dev/null +++ b/algorithms-sorting/src/main/java/com/baeldung/algorithms/selectionsort/SelectionSort.java @@ -0,0 +1,38 @@ +package com.baeldung.algorithms.selectionsort; + +public class SelectionSort { + + public static void sortAscending(final int[] arr) { + for (int i = 0; i < arr.length - 1; i++) { + int minElementIndex = i; + for (int j = i + 1; j < arr.length; j++) { + if (arr[minElementIndex] > arr[j]) { + minElementIndex = j; + } + } + + if (minElementIndex != i) { + int temp = arr[i]; + arr[i] = arr[minElementIndex]; + arr[minElementIndex] = temp; + } + } + } + + public static void sortDescending(final int[] arr) { + for (int i = 0; i < arr.length - 1; i++) { + int maxElementIndex = i; + for (int j = i + 1; j < arr.length; j++) { + if (arr[maxElementIndex] < arr[j]) { + maxElementIndex = j; + } + } + + if (maxElementIndex != i) { + int temp = arr[i]; + arr[i] = arr[maxElementIndex]; + arr[maxElementIndex] = temp; + } + } + } +} \ No newline at end of file diff --git a/algorithms-sorting/src/test/java/com/baeldung/algorithms/inoutsort/InOutSortUnitTest.java b/algorithms-sorting/src/test/java/com/baeldung/algorithms/inoutsort/InOutSortUnitTest.java new file mode 100644 index 0000000000..321b905f68 --- /dev/null +++ b/algorithms-sorting/src/test/java/com/baeldung/algorithms/inoutsort/InOutSortUnitTest.java @@ -0,0 +1,23 @@ +package com.baeldung.algorithms.inoutsort; + +import static org.junit.Assert.*; +import static org.junit.Assert.assertArrayEquals; + +import org.junit.Test; + +public class InOutSortUnitTest { + + @Test + public void givenArray_whenInPlaceSort_thenReversed() { + int[] input = {1, 2, 3, 4, 5, 6, 7}; + int[] expected = {7, 6, 5, 4, 3, 2, 1}; + assertArrayEquals("the two arrays are not equal", expected, InOutSort.reverseInPlace(input)); + } + + @Test + public void givenArray_whenOutOfPlaceSort_thenReversed() { + int[] input = {1, 2, 3, 4, 5, 6, 7}; + int[] expected = {7, 6, 5, 4, 3, 2, 1}; + assertArrayEquals("the two arrays are not equal", expected, InOutSort.reverseOutOfPlace(input)); + } +} diff --git a/algorithms-sorting/src/test/java/com/baeldung/algorithms/selectionsort/SelectionSortUnitTest.java b/algorithms-sorting/src/test/java/com/baeldung/algorithms/selectionsort/SelectionSortUnitTest.java new file mode 100644 index 0000000000..85efd1d3da --- /dev/null +++ b/algorithms-sorting/src/test/java/com/baeldung/algorithms/selectionsort/SelectionSortUnitTest.java @@ -0,0 +1,25 @@ +package com.baeldung.algorithms.selectionsort; + +import static org.junit.Assert.*; +import static org.junit.Assert.assertArrayEquals; + +import org.junit.Test; + +public class SelectionSortUnitTest { + + @Test + public void givenUnsortedArray_whenSelectionSort_SortAscending_thenSortedAsc() { + int[] input = { 5, 4, 1, 6, 2 }; + SelectionSort.sortAscending(input); + int[] expected = {1, 2, 4, 5, 6}; + assertArrayEquals("the two arrays are not equal", expected, input); + } + + @Test + public void givenUnsortedArray_whenSelectionSort_SortDescending_thenSortedDesc() { + int[] input = { 5, 4, 1, 6, 2 }; + SelectionSort.sortDescending(input); + int[] expected = {6, 5, 4, 2, 1}; + assertArrayEquals("the two arrays are not equal", expected, input); + } +} diff --git a/core-groovy-2/README.md b/core-groovy-2/README.md index 33df8b107b..1211dae76d 100644 --- a/core-groovy-2/README.md +++ b/core-groovy-2/README.md @@ -8,3 +8,4 @@ - [Pattern Matching in Strings in Groovy](https://www.baeldung.com/groovy-pattern-matching) - [Working with XML in Groovy](https://www.baeldung.com/groovy-xml) - [Integrating Groovy into Java Applications](https://www.baeldung.com/groovy-java-applications) +- [Concatenate Strings with Groovy](https://www.baeldung.com/groovy-concatenate-strings) diff --git a/core-groovy-2/src/main/groovy/com/baeldung/metaprogramming/Employee.groovy b/core-groovy-2/src/main/groovy/com/baeldung/metaprogramming/Employee.groovy new file mode 100644 index 0000000000..f49d0f906b --- /dev/null +++ b/core-groovy-2/src/main/groovy/com/baeldung/metaprogramming/Employee.groovy @@ -0,0 +1,45 @@ +package com.baeldung.metaprogramming + +import groovy.transform.AutoClone +import groovy.transform.Canonical +import groovy.transform.EqualsAndHashCode +import groovy.transform.ToString +import groovy.transform.TupleConstructor +import groovy.util.logging.* + +@Canonical +@TupleConstructor +@EqualsAndHashCode +@ToString(includePackage=false, excludes=['id']) +@Log +@AutoClone +class Employee { + + long id + String firstName + String lastName + int age + + //method to catch missing property's getter + def propertyMissing(String propertyName) { + log.info "$propertyName is not available" + "property '$propertyName' is not available" + } + + //method to catch missing property's setter + def propertyMissing(String propertyName, propertyValue) { + println "property '$propertyName' is not available" + log.info "$propertyName is not available" + "property '$propertyName' is not available" + } + + def methodMissing(String methodName, def methodArgs) { + log.info "$methodName is not defined" + "method '$methodName' is not defined" + } + + def logEmp() { + log.info "Employee: $lastName, $firstName is of $age years age" + } + +} \ No newline at end of file diff --git a/core-groovy-2/src/main/groovy/com/baeldung/metaprogramming/extension/BasicExtensions.groovy b/core-groovy-2/src/main/groovy/com/baeldung/metaprogramming/extension/BasicExtensions.groovy new file mode 100644 index 0000000000..65591cae8d --- /dev/null +++ b/core-groovy-2/src/main/groovy/com/baeldung/metaprogramming/extension/BasicExtensions.groovy @@ -0,0 +1,30 @@ +package com.baeldung.metaprogramming.extension + +import com.baeldung.metaprogramming.Employee + +class BasicExtensions { + + static int getYearOfBirth(Employee self) { + return (new Date().getYear() + 1900) - self.age; + } + + static String capitalize(String self) { + return self.substring(0, 1).toUpperCase() + self.substring(1) + } + + static void printCounter(Integer self) { + while (self>0) { + println self + self-- + } + } + + static Long square(Long self) { + return self*self + } + + static BigDecimal cube(BigDecimal self) { + return self*self*self + } + +} \ No newline at end of file diff --git a/core-groovy-2/src/main/groovy/com/baeldung/metaprogramming/extension/StaticEmployeeExtension.groovy b/core-groovy-2/src/main/groovy/com/baeldung/metaprogramming/extension/StaticEmployeeExtension.groovy new file mode 100644 index 0000000000..ab2aac38ea --- /dev/null +++ b/core-groovy-2/src/main/groovy/com/baeldung/metaprogramming/extension/StaticEmployeeExtension.groovy @@ -0,0 +1,10 @@ +package com.baeldung.metaprogramming.extension + +import com.baeldung.metaprogramming.Employee + +class StaticEmployeeExtension { + + static Employee getDefaultObj(Employee self) { + return new Employee(firstName: "firstName", lastName: "lastName", age: 20) + } +} \ No newline at end of file diff --git a/core-groovy-2/src/main/resources/META-INF/services/org.codehaus.groovy.runtime.ExtensionModule b/core-groovy-2/src/main/resources/META-INF/services/org.codehaus.groovy.runtime.ExtensionModule new file mode 100644 index 0000000000..967108b846 --- /dev/null +++ b/core-groovy-2/src/main/resources/META-INF/services/org.codehaus.groovy.runtime.ExtensionModule @@ -0,0 +1,4 @@ +moduleName=core-groovy-2 +moduleVersion=1.0-SNAPSHOT +extensionClasses=com.baeldung.metaprogramming.extension.BasicExtensions +staticExtensionClasses=com.baeldung.metaprogramming.extension.StaticEmployeeExtension diff --git a/core-groovy-2/src/test/groovy/com/baeldung/metaprogramming/MetaprogrammingUnitTest.groovy b/core-groovy-2/src/test/groovy/com/baeldung/metaprogramming/MetaprogrammingUnitTest.groovy new file mode 100644 index 0000000000..8066b10f9b --- /dev/null +++ b/core-groovy-2/src/test/groovy/com/baeldung/metaprogramming/MetaprogrammingUnitTest.groovy @@ -0,0 +1,118 @@ +package com.baeldung.metaprogramming + +import groovy.time.TimeCategory + +class MetaprogrammingUnitTest extends GroovyTestCase { + + Employee emp = new Employee(firstName: "Norman", lastName: "Lewis") + + void testPropertyMissing() { + assert emp.address == "property 'address' is not available" + } + + void testMethodMissing() { + Employee emp = new Employee() + try { + emp.getFullName() + } catch(MissingMethodException e) { + println "method is not defined" + } + assert emp.getFullName() == "method 'getFullName' is not defined" + } + + void testMetaClassProperty() { + Employee.metaClass.address = "" + emp = new Employee(firstName: "Norman", lastName: "Lewis", address: "US") + assert emp.address == "US" + } + + void testMetaClassMethod() { + emp.metaClass.getFullName = { + "$lastName, $firstName" + } + assert emp.getFullName() == "Lewis, Norman" + } + + void testMetaClassConstructor() { + try { + Employee emp = new Employee("Norman") + } catch(GroovyRuntimeException e) { + assert e.message == "Could not find matching constructor for: com.baeldung.metaprogramming.Employee(String)" + } + + Employee.metaClass.constructor = { String firstName -> + new Employee(firstName: firstName) + } + + Employee norman = new Employee("Norman") + assert norman.firstName == "Norman" + assert norman.lastName == null + } + + void testJavaMetaClass() { + String.metaClass.capitalize = { String str -> + str.substring(0, 1).toUpperCase() + str.substring(1); + } + assert "norman".capitalize() == "Norman" + } + + void testEmployeeExtension() { + Employee emp = new Employee(age: 28) + assert emp.getYearOfBirth() == 1991 + } + + void testJavaClassesExtensions() { + 5.printCounter() + + assert 40l.square() == 1600l + + assert (2.98).cube() == 26.463592 + } + + void testStaticEmployeeExtension() { + assert Employee.getDefaultObj().firstName == "firstName" + assert Employee.getDefaultObj().lastName == "lastName" + assert Employee.getDefaultObj().age == 20 + } + + void testToStringAnnotation() { + Employee employee = new Employee() + employee.id = 1 + employee.firstName = "norman" + employee.lastName = "lewis" + employee.age = 28 + + assert employee.toString() == "Employee(norman, lewis, 28)" + } + + void testTupleConstructorAnnotation() { + Employee norman = new Employee(1, "norman", "lewis", 28) + assert norman.toString() == "Employee(norman, lewis, 28)" + + Employee snape = new Employee(2, "snape") + assert snape.toString() == "Employee(snape, null, 0)" + + } + + void testEqualsAndHashCodeAnnotation() { + Employee norman = new Employee(1, "norman", "lewis", 28) + Employee normanCopy = new Employee(1, "norman", "lewis", 28) + assert norman.equals(normanCopy) + assert norman.hashCode() == normanCopy.hashCode() + } + + void testAutoCloneAnnotation() { + try { + Employee norman = new Employee(1, "norman", "lewis", 28) + def normanCopy = norman.clone() + assert norman == normanCopy + } catch(CloneNotSupportedException e) { + e.printStackTrace() + } + } + + void testLoggingAnnotation() { + Employee employee = new Employee(1, "Norman", "Lewis", 28) + employee.logEmp() + } +} \ No newline at end of file diff --git a/core-java-arrays/README.MD b/core-java-arrays/README.MD deleted file mode 100644 index 9ee6998784..0000000000 --- a/core-java-arrays/README.MD +++ /dev/null @@ -1,3 +0,0 @@ -## Relevant Articles - -- [Extending an Array’s Length](https://www.baeldung.com/java-array-add-element-at-the-end) diff --git a/core-java-modules/core-java-12/README.md b/core-java-modules/core-java-12/README.md index 4514fd1a2b..6c603e4dea 100644 --- a/core-java-modules/core-java-12/README.md +++ b/core-java-modules/core-java-12/README.md @@ -1,3 +1,4 @@ -## Relevant articles: +## Relevant Articles: + - [String API Updates in Java 12](https://www.baeldung.com/java12-string-api) diff --git a/core-java-modules/core-java-8-2/README.md b/core-java-modules/core-java-8-2/README.md index 245fa93ba7..d11510b2aa 100644 --- a/core-java-modules/core-java-8-2/README.md +++ b/core-java-modules/core-java-8-2/README.md @@ -7,3 +7,4 @@ - [How to Delay Code Execution in Java](https://www.baeldung.com/java-delay-code-execution) - [Run JAR Application With Command Line Arguments](https://www.baeldung.com/java-run-jar-with-arguments) - [Java 8 Stream skip() vs limit()](https://www.baeldung.com/java-stream-skip-vs-limit) +- [Guide to Java BiFunction Interface](https://www.baeldung.com/java-bifunction-interface) diff --git a/core-java-modules/core-java-8/README.md b/core-java-modules/core-java-8/README.md index b2ae48ea11..6e79eddd16 100644 --- a/core-java-modules/core-java-8/README.md +++ b/core-java-modules/core-java-8/README.md @@ -4,14 +4,10 @@ ### Relevant Articles: - [Guide to Java 8’s Collectors](http://www.baeldung.com/java-8-collectors) -- [Functional Interfaces in Java 8](http://www.baeldung.com/java-8-functional-interfaces) -- [Java 8 – Powerful Comparison with Lambdas](http://www.baeldung.com/java-8-sort-lambda) - [New Features in Java 8](http://www.baeldung.com/java-8-new-features) -- [Lambda Expressions and Functional Interfaces: Tips and Best Practices](http://www.baeldung.com/java-8-lambda-expressions-tips) - [The Double Colon Operator in Java 8](http://www.baeldung.com/java-8-double-colon-operator) - [Guide to Java 8 groupingBy Collector](http://www.baeldung.com/java-groupingby-collector) - [Strategy Design Pattern in Java 8](http://www.baeldung.com/java-strategy-pattern) -- [Exceptions in Java 8 Lambda Expressions](http://www.baeldung.com/java-lambda-exceptions) - [Guide to Java 8 Comparator.comparing()](http://www.baeldung.com/java-8-comparator-comparing) - [Guide To Java 8 Optional](http://www.baeldung.com/java-optional) - [Guide to the Java 8 forEach](http://www.baeldung.com/foreach-java) @@ -38,6 +34,5 @@ - [Java @SafeVarargs Annotation](https://www.baeldung.com/java-safevarargs) - [Java @Deprecated Annotation](https://www.baeldung.com/java-deprecated) - [Java 8 Predicate Chain](https://www.baeldung.com/java-predicate-chain) -- [Method References in Java](https://www.baeldung.com/java-method-references) - [Creating a Custom Annotation in Java](https://www.baeldung.com/java-custom-annotation) - [The Difference Between Collection.stream().forEach() and Collection.forEach()](https://www.baeldung.com/java-collection-stream-foreach) diff --git a/java-numbers-2/.gitignore b/core-java-modules/core-java-arrays-2/.gitignore similarity index 95% rename from java-numbers-2/.gitignore rename to core-java-modules/core-java-arrays-2/.gitignore index 3de4cc647e..374c8bf907 100644 --- a/java-numbers-2/.gitignore +++ b/core-java-modules/core-java-arrays-2/.gitignore @@ -16,7 +16,6 @@ *.ear # Files generated by integration tests -*.txt backup-pom.xml /bin/ /temp diff --git a/core-java-modules/core-java-arrays-2/README.MD b/core-java-modules/core-java-arrays-2/README.MD new file mode 100644 index 0000000000..f272f4d299 --- /dev/null +++ b/core-java-modules/core-java-arrays-2/README.MD @@ -0,0 +1,5 @@ +## 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) diff --git a/core-java-modules/core-java-arrays-2/pom.xml b/core-java-modules/core-java-arrays-2/pom.xml new file mode 100644 index 0000000000..bfe8a349e1 --- /dev/null +++ b/core-java-modules/core-java-arrays-2/pom.xml @@ -0,0 +1,50 @@ + + 4.0.0 + com.baeldung + core-java-arrays-2 + 0.1.0-SNAPSHOT + core-java-arrays-2 + jar + + + com.baeldung + parent-java + 0.0.1-SNAPSHOT + ../../parent-java + + + + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + + + + org.assertj + assertj-core + ${assertj-core.version} + test + + + + + core-java-arrays-2 + + + src/main/resources + true + + + + + + + + 3.9 + + 3.10.0 + + + diff --git a/core-java-arrays/src/main/java/com/baeldung/array/conversions/StreamArrayConversion.java b/core-java-modules/core-java-arrays-2/src/main/java/com/baeldung/array/conversions/StreamArrayConversion.java similarity index 100% rename from core-java-arrays/src/main/java/com/baeldung/array/conversions/StreamArrayConversion.java rename to core-java-modules/core-java-arrays-2/src/main/java/com/baeldung/array/conversions/StreamArrayConversion.java diff --git a/core-java-arrays/src/main/java/com/baeldung/array/looping/LoopDiagonally.java b/core-java-modules/core-java-arrays-2/src/main/java/com/baeldung/array/looping/LoopDiagonally.java similarity index 100% rename from core-java-arrays/src/main/java/com/baeldung/array/looping/LoopDiagonally.java rename to core-java-modules/core-java-arrays-2/src/main/java/com/baeldung/array/looping/LoopDiagonally.java diff --git a/core-java-arrays/src/test/java/com/baeldung/array/conversions/StreamArrayConversionUnitTest.java b/core-java-modules/core-java-arrays-2/src/test/java/com/baeldung/array/conversions/StreamArrayConversionUnitTest.java similarity index 100% rename from core-java-arrays/src/test/java/com/baeldung/array/conversions/StreamArrayConversionUnitTest.java rename to core-java-modules/core-java-arrays-2/src/test/java/com/baeldung/array/conversions/StreamArrayConversionUnitTest.java diff --git a/core-java-arrays/src/test/java/com/baeldung/array/looping/LoopDiagonallyTest.java b/core-java-modules/core-java-arrays-2/src/test/java/com/baeldung/array/looping/LoopDiagonallyUnitTest.java similarity index 92% rename from core-java-arrays/src/test/java/com/baeldung/array/looping/LoopDiagonallyTest.java rename to core-java-modules/core-java-arrays-2/src/test/java/com/baeldung/array/looping/LoopDiagonallyUnitTest.java index df6079270b..5f670f4a59 100644 --- a/core-java-arrays/src/test/java/com/baeldung/array/looping/LoopDiagonallyTest.java +++ b/core-java-modules/core-java-arrays-2/src/test/java/com/baeldung/array/looping/LoopDiagonallyUnitTest.java @@ -4,7 +4,7 @@ import org.junit.Test; import static org.junit.Assert.assertEquals; -public class LoopDiagonallyTest { +public class LoopDiagonallyUnitTest { @Test public void twoArrayIsLoopedDiagonallyAsExpected() { diff --git a/core-java-modules/core-java-arrays/README.md b/core-java-modules/core-java-arrays/README.md index b5f71cc253..45feff3edc 100644 --- a/core-java-modules/core-java-arrays/README.md +++ b/core-java-modules/core-java-arrays/README.md @@ -7,7 +7,7 @@ - [Check if a Java Array Contains a Value](http://www.baeldung.com/java-array-contains-value) - [Initializing Arrays in Java](http://www.baeldung.com/java-initialize-array) - [Guide to the java.util.Arrays Class](http://www.baeldung.com/java-util-arrays) -- [Jagged Arrays In Java](http://www.baeldung.com/java-jagged-arrays) +- [Multi-Dimensional Arrays In Java](http://www.baeldung.com/java-jagged-arrays) - [Find Sum and Average in a Java Array](http://www.baeldung.com/java-array-sum-average) - [Arrays in Java: A Reference Guide](https://www.baeldung.com/java-arrays-guide) - [How to Invert an Array in Java](http://www.baeldung.com/java-invert-array) @@ -16,3 +16,4 @@ - [Sorting Arrays in Java](https://www.baeldung.com/java-sorting-arrays) - [Convert a Float to a Byte Array in Java](https://www.baeldung.com/java-convert-float-to-byte-array) - [Converting Between Stream and Array in Java](https://www.baeldung.com/java-stream-to-array) +- [Removing an Element from an Array in Java](https://www.baeldung.com/java-array-remove-element) diff --git a/core-java-modules/core-java-arrays/src/main/java/com/baeldung/array/SortedArrayChecker.java b/core-java-modules/core-java-arrays/src/main/java/com/baeldung/array/SortedArrayChecker.java index ec612fd53b..78a9a8f4d1 100644 --- a/core-java-modules/core-java-arrays/src/main/java/com/baeldung/array/SortedArrayChecker.java +++ b/core-java-modules/core-java-arrays/src/main/java/com/baeldung/array/SortedArrayChecker.java @@ -2,7 +2,10 @@ package com.baeldung.array; import com.baeldung.arraycopy.model.Employee; +import java.util.Comparator; + public class SortedArrayChecker { + boolean isSorted(int[] array, int length) { if (array == null || length < 2) return true; @@ -22,7 +25,7 @@ public class SortedArrayChecker { return true; } - boolean isSorted(String[] array, int length) { + boolean isSorted(Comparable[] array, int length) { if (array == null || length < 2) return true; @@ -32,40 +35,31 @@ public class SortedArrayChecker { return isSorted(array, length - 1); } -boolean isSorted(String[] array) { - for (int i = 0; i < array.length - 1; ++i) { - if (array[i].compareTo(array[i + 1]) > 0) - return false; - } - - return true; -} - - boolean isSortedByName(Employee[] array) { + boolean isSorted(Comparable[] array) { for (int i = 0; i < array.length - 1; ++i) { - if (array[i].getName().compareTo(array[i + 1].getName()) > 0) + if (array[i].compareTo(array[i + 1]) > 0) return false; } return true; } -boolean isSortedByAge(Employee[] array) { - for (int i = 0; i < array.length - 1; ++i) { - if (array[i].getAge() > (array[i + 1].getAge())) - return false; + boolean isSorted(Object[] array, Comparator comparator) { + for (int i = 0; i < array.length - 1; ++i) { + if (comparator.compare(array[i], (array[i + 1])) > 0) + return false; + } + + return true; } - return true; -} - - boolean isSortedByAge(Employee[] array, int length) { + boolean isSorted(Object[] array, Comparator comparator, int length) { if (array == null || length < 2) return true; - if (array[length - 2].getAge() > array[length - 1].getAge()) + if (comparator.compare(array[length - 2], array[length - 1]) > 0) return false; - return isSortedByAge(array, length - 1); + return isSorted(array, comparator, length - 1); } } diff --git a/core-java-modules/core-java-arrays/src/test/java/com/baeldung/array/SortedArrayCheckerUnitTest.java b/core-java-modules/core-java-arrays/src/test/java/com/baeldung/array/SortedArrayCheckerUnitTest.java index 29866a3c22..7971e0eab7 100644 --- a/core-java-modules/core-java-arrays/src/test/java/com/baeldung/array/SortedArrayCheckerUnitTest.java +++ b/core-java-modules/core-java-arrays/src/test/java/com/baeldung/array/SortedArrayCheckerUnitTest.java @@ -4,32 +4,33 @@ import com.baeldung.arraycopy.model.Employee; import org.junit.Before; import org.junit.Test; +import java.util.Comparator; + import static org.assertj.core.api.Assertions.assertThat; -class SortedArrayCheckerUnitTest { - +public class SortedArrayCheckerUnitTest { private static final int[] INTEGER_SORTED = {1, 3, 5, 7, 9}; private static final int[] INTEGER_NOT_SORTED = {1, 3, 11, 7}; private static final String[] STRING_SORTED = {"abc", "cde", "fgh"}; private static final String[] STRING_NOT_SORTED = {"abc", "fgh", "cde", "ijk"}; - private final Employee[] EMPLOYEES_SORTED_BY_NAME = { + private static final Employee[] EMPLOYEES_SORTED_BY_NAME = { new Employee(1, "Carlos", 26), new Employee(2, "Daniel", 31), new Employee(3, "Marta", 27)}; - private final Employee[] EMPLOYEES_NOT_SORTED_BY_NAME = { + private static final Employee[] EMPLOYEES_NOT_SORTED_BY_NAME = { new Employee(1, "Daniel", 31), new Employee(2, "Carlos", 26), new Employee(3, "Marta", 27)}; - private final Employee[] EMPLOYEES_SORTED_BY_AGE = { + private static final Employee[] EMPLOYEES_SORTED_BY_AGE = { new Employee(1, "Carlos", 26), new Employee(2, "Marta", 27), new Employee(3, "Daniel", 31)}; - private final Employee[] EMPLOYEES_NOT_SORTED_BY_AGE = { + private static final Employee[] EMPLOYEES_NOT_SORTED_BY_AGE = { new Employee(1, "Marta", 27), new Employee(2, "Carlos", 26), new Employee(3, "Daniel", 31)}; @@ -61,13 +62,18 @@ class SortedArrayCheckerUnitTest { @Test public void givenEmployeeArray_thenReturnIfItIsSortedOrNot() { - assertThat(sortedArrayChecker.isSortedByName(EMPLOYEES_SORTED_BY_NAME)).isEqualTo(true); - assertThat(sortedArrayChecker.isSortedByName(EMPLOYEES_NOT_SORTED_BY_NAME)).isEqualTo(false); + assertThat(sortedArrayChecker.isSorted(EMPLOYEES_SORTED_BY_NAME, Comparator.comparing(Employee::getName))).isEqualTo(true); + assertThat(sortedArrayChecker.isSorted(EMPLOYEES_NOT_SORTED_BY_NAME, Comparator.comparing(Employee::getName))).isEqualTo(false); - assertThat(sortedArrayChecker.isSortedByAge(EMPLOYEES_SORTED_BY_AGE)).isEqualTo(true); - assertThat(sortedArrayChecker.isSortedByAge(EMPLOYEES_NOT_SORTED_BY_AGE)).isEqualTo(false); + assertThat(sortedArrayChecker.isSorted(EMPLOYEES_SORTED_BY_AGE, Comparator.comparingInt(Employee::getAge))).isEqualTo(true); + assertThat(sortedArrayChecker.isSorted(EMPLOYEES_NOT_SORTED_BY_AGE, Comparator.comparingInt(Employee::getAge))).isEqualTo(false); - assertThat(sortedArrayChecker.isSortedByAge(EMPLOYEES_SORTED_BY_AGE, EMPLOYEES_SORTED_BY_AGE.length)).isEqualTo(true); - assertThat(sortedArrayChecker.isSortedByAge(EMPLOYEES_NOT_SORTED_BY_AGE, EMPLOYEES_NOT_SORTED_BY_AGE.length)).isEqualTo(false); + assertThat(sortedArrayChecker + .isSorted(EMPLOYEES_SORTED_BY_AGE, Comparator.comparingInt(Employee::getAge), EMPLOYEES_SORTED_BY_AGE.length)) + .isEqualTo(true); + assertThat(sortedArrayChecker + .isSorted(EMPLOYEES_NOT_SORTED_BY_AGE, Comparator.comparingInt(Employee::getAge), EMPLOYEES_NOT_SORTED_BY_AGE.length)) + .isEqualTo(false); } + } \ No newline at end of file diff --git a/core-java-modules/core-java-concurrency-basic/src/main/java/com/baeldung/concurrent/mutex/SequenceGenerator.java b/core-java-modules/core-java-concurrency-basic/src/main/java/com/baeldung/concurrent/mutex/SequenceGenerator.java new file mode 100644 index 0000000000..97d44e5156 --- /dev/null +++ b/core-java-modules/core-java-concurrency-basic/src/main/java/com/baeldung/concurrent/mutex/SequenceGenerator.java @@ -0,0 +1,11 @@ +package com.baeldung.concurrent.mutex; + +public class SequenceGenerator { + private int currentValue = 0; + + public int getNextSequence() throws InterruptedException { + currentValue = currentValue + 1; + Thread.sleep(500); + return currentValue; + } +} diff --git a/core-java-modules/core-java-concurrency-basic/src/main/java/com/baeldung/concurrent/mutex/SequenceGeneratorUsingMonitor.java b/core-java-modules/core-java-concurrency-basic/src/main/java/com/baeldung/concurrent/mutex/SequenceGeneratorUsingMonitor.java new file mode 100644 index 0000000000..30c8da4865 --- /dev/null +++ b/core-java-modules/core-java-concurrency-basic/src/main/java/com/baeldung/concurrent/mutex/SequenceGeneratorUsingMonitor.java @@ -0,0 +1,18 @@ +package com.baeldung.concurrent.mutex; + +import com.google.common.util.concurrent.Monitor; + +public class SequenceGeneratorUsingMonitor extends SequenceGenerator { + + private Monitor monitor = new Monitor(); + + @Override + public int getNextSequence() throws InterruptedException { + monitor.enter(); + try { + return super.getNextSequence(); + } finally { + monitor.leave(); + } + } +} diff --git a/core-java-modules/core-java-concurrency-basic/src/main/java/com/baeldung/concurrent/mutex/SequenceGeneratorUsingReentrantLock.java b/core-java-modules/core-java-concurrency-basic/src/main/java/com/baeldung/concurrent/mutex/SequenceGeneratorUsingReentrantLock.java new file mode 100644 index 0000000000..85ce780bda --- /dev/null +++ b/core-java-modules/core-java-concurrency-basic/src/main/java/com/baeldung/concurrent/mutex/SequenceGeneratorUsingReentrantLock.java @@ -0,0 +1,18 @@ +package com.baeldung.concurrent.mutex; + +import java.util.concurrent.locks.ReentrantLock; + +public class SequenceGeneratorUsingReentrantLock extends SequenceGenerator { + + private ReentrantLock mutex = new ReentrantLock(); + + @Override + public int getNextSequence() throws InterruptedException { + try { + mutex.lock(); + return super.getNextSequence(); + } finally { + mutex.unlock(); + } + } +} diff --git a/core-java-modules/core-java-concurrency-basic/src/main/java/com/baeldung/concurrent/mutex/SequenceGeneratorUsingSemaphore.java b/core-java-modules/core-java-concurrency-basic/src/main/java/com/baeldung/concurrent/mutex/SequenceGeneratorUsingSemaphore.java new file mode 100644 index 0000000000..fdece049e6 --- /dev/null +++ b/core-java-modules/core-java-concurrency-basic/src/main/java/com/baeldung/concurrent/mutex/SequenceGeneratorUsingSemaphore.java @@ -0,0 +1,18 @@ +package com.baeldung.concurrent.mutex; + +import java.util.concurrent.Semaphore; + +public class SequenceGeneratorUsingSemaphore extends SequenceGenerator { + + private Semaphore mutex = new Semaphore(1); + + @Override + public int getNextSequence() throws InterruptedException { + try { + mutex.acquire(); + return super.getNextSequence(); + } finally { + mutex.release(); + } + } +} diff --git a/core-java-modules/core-java-concurrency-basic/src/main/java/com/baeldung/concurrent/mutex/SequenceGeneratorUsingSynchronizedBlock.java b/core-java-modules/core-java-concurrency-basic/src/main/java/com/baeldung/concurrent/mutex/SequenceGeneratorUsingSynchronizedBlock.java new file mode 100644 index 0000000000..d485eae21c --- /dev/null +++ b/core-java-modules/core-java-concurrency-basic/src/main/java/com/baeldung/concurrent/mutex/SequenceGeneratorUsingSynchronizedBlock.java @@ -0,0 +1,12 @@ +package com.baeldung.concurrent.mutex; + +public class SequenceGeneratorUsingSynchronizedBlock extends SequenceGenerator { + + @Override + public int getNextSequence() throws InterruptedException { + synchronized (this) { + return super.getNextSequence(); + } + } + +} diff --git a/core-java-modules/core-java-concurrency-basic/src/main/java/com/baeldung/concurrent/mutex/SequenceGeneratorUsingSynchronizedMethod.java b/core-java-modules/core-java-concurrency-basic/src/main/java/com/baeldung/concurrent/mutex/SequenceGeneratorUsingSynchronizedMethod.java new file mode 100644 index 0000000000..441b33dc43 --- /dev/null +++ b/core-java-modules/core-java-concurrency-basic/src/main/java/com/baeldung/concurrent/mutex/SequenceGeneratorUsingSynchronizedMethod.java @@ -0,0 +1,10 @@ +package com.baeldung.concurrent.mutex; + +public class SequenceGeneratorUsingSynchronizedMethod extends SequenceGenerator { + + @Override + public synchronized int getNextSequence() throws InterruptedException { + return super.getNextSequence(); + } + +} diff --git a/core-java-modules/core-java-concurrency-basic/src/test/java/com/baeldung/concurrent/mutex/MutexUnitTest.java b/core-java-modules/core-java-concurrency-basic/src/test/java/com/baeldung/concurrent/mutex/MutexUnitTest.java new file mode 100644 index 0000000000..620179800a --- /dev/null +++ b/core-java-modules/core-java-concurrency-basic/src/test/java/com/baeldung/concurrent/mutex/MutexUnitTest.java @@ -0,0 +1,81 @@ +package com.baeldung.concurrent.mutex; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; + +import org.junit.Assert; +import org.junit.Test; + +import com.baeldung.concurrent.mutex.SequenceGenerator; +import com.baeldung.concurrent.mutex.SequenceGeneratorUsingMonitor; +import com.baeldung.concurrent.mutex.SequenceGeneratorUsingReentrantLock; +import com.baeldung.concurrent.mutex.SequenceGeneratorUsingSemaphore; +import com.baeldung.concurrent.mutex.SequenceGeneratorUsingSynchronizedBlock; +import com.baeldung.concurrent.mutex.SequenceGeneratorUsingSynchronizedMethod; + +public class MutexUnitTest { + + private final int RANGE = 30; + + @Test + public void givenUnsafeSequenceGenerator_whenRaceCondition_thenUnexpectedBehavior() throws Exception { + Set uniqueSequences = getASetOFUniqueSequences(new SequenceGenerator()); + Assert.assertNotEquals(RANGE, uniqueSequences.size()); + } + + @Test + public void givenSequenceGeneratorUsingSynchronizedMethod_whenRaceCondition_thenSuccess() throws Exception { + Set uniqueSequences = getASetOFUniqueSequences(new SequenceGeneratorUsingSynchronizedMethod()); + Assert.assertEquals(RANGE, uniqueSequences.size()); + } + + @Test + public void givenSequenceGeneratorUsingSynchronizedBlock_whenRaceCondition_thenSuccess() throws Exception { + Set uniqueSequences = getASetOFUniqueSequences(new SequenceGeneratorUsingSynchronizedBlock()); + Assert.assertEquals(RANGE, uniqueSequences.size()); + } + + @Test + public void givenSequenceGeneratorUsingReentrantLock_whenRaceCondition_thenSuccess() throws Exception { + Set uniqueSequences = getASetOFUniqueSequences(new SequenceGeneratorUsingReentrantLock()); + Assert.assertEquals(RANGE, uniqueSequences.size()); + } + + @Test + public void givenSequenceGeneratorUsingSemaphore_whenRaceCondition_thenSuccess() throws Exception { + Set uniqueSequences = getASetOFUniqueSequences(new SequenceGeneratorUsingSemaphore()); + Assert.assertEquals(RANGE, uniqueSequences.size()); + } + + @Test + public void givenSequenceGeneratorUsingMonitor_whenRaceCondition_thenSuccess() throws Exception { + Set uniqueSequences = getASetOFUniqueSequences(new SequenceGeneratorUsingMonitor()); + Assert.assertEquals(RANGE, uniqueSequences.size()); + } + + private Set getASetOFUniqueSequences(SequenceGenerator generator) throws Exception { + ExecutorService executor = Executors.newFixedThreadPool(3); + Set uniqueSequences = new HashSet<>(); + List> futures = new ArrayList<>(); + + for (int i = 0; i < RANGE; i++) { + futures.add(executor.submit(generator::getNextSequence)); + } + + for (Future future : futures) { + uniqueSequences.add(future.get()); + } + + executor.awaitTermination(15, TimeUnit.SECONDS); + executor.shutdown(); + + return uniqueSequences; + } + +} diff --git a/core-java-modules/core-java-exceptions/README.md b/core-java-modules/core-java-exceptions/README.md index 5338789a2f..79e5bad23a 100644 --- a/core-java-modules/core-java-exceptions/README.md +++ b/core-java-modules/core-java-exceptions/README.md @@ -1,3 +1,3 @@ -## Relevant articles: +## Relevant Articles: - [Will an Error Be Caught by Catch Block in Java?](https://www.baeldung.com/java-error-catch) diff --git a/core-java-modules/core-java-jndi/pom.xml b/core-java-modules/core-java-jndi/pom.xml new file mode 100644 index 0000000000..eb363f8598 --- /dev/null +++ b/core-java-modules/core-java-jndi/pom.xml @@ -0,0 +1,65 @@ + + + 4.0.0 + + com.baeldung.jndi + core-java-jndi + 1.0-SNAPSHOT + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + ../../ + + + + + org.junit.jupiter + junit-jupiter + 5.5.1 + test + + + org.springframework + spring-core + 5.0.9.RELEASE + + + org.springframework + spring-context + 5.0.9.RELEASE + + + org.springframework + spring-jdbc + 5.0.9.RELEASE + + + org.springframework + spring-test + 5.0.9.RELEASE + test + + + com.h2database + h2 + 1.4.199 + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + + + + + diff --git a/core-java-modules/core-java-jndi/src/test/java/com/baeldung/jndi/JndiUnitTest.java b/core-java-modules/core-java-jndi/src/test/java/com/baeldung/jndi/JndiUnitTest.java new file mode 100644 index 0000000000..9eea420e7a --- /dev/null +++ b/core-java-modules/core-java-jndi/src/test/java/com/baeldung/jndi/JndiUnitTest.java @@ -0,0 +1,60 @@ +package com.baeldung.jndi; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.springframework.jdbc.datasource.DriverManagerDataSource; +import org.springframework.jndi.JndiTemplate; +import org.springframework.mock.jndi.SimpleNamingContextBuilder; + +import javax.naming.*; +import javax.sql.DataSource; + +import java.util.Enumeration; + +import static org.junit.jupiter.api.Assertions.*; + +class JndiUnitTest { + + private static InitialContext ctx; + private static DriverManagerDataSource ds; + + @BeforeAll + static void setUp() throws Exception { + SimpleNamingContextBuilder builder = new SimpleNamingContextBuilder(); + ds = new DriverManagerDataSource("jdbc:h2:mem:mydb"); + builder.activate(); + + JndiTemplate jndiTemplate = new JndiTemplate(); + ctx = (InitialContext) jndiTemplate.getContext(); + } + + @Test + void givenACompositeName_whenAddingAnElement_thenNameIncludesIt() throws Exception { + Name objectName = new CompositeName("java:comp/env/jdbc"); + + Enumeration elements = objectName.getAll(); + while(elements.hasMoreElements()) { + System.out.println(elements.nextElement()); + } + + objectName.add("example"); + + assertEquals("env", objectName.get(1)); + assertEquals("example", objectName.get(objectName.size() - 1)); + } + + @Test + void givenADataSource_whenAddingDriver_thenBind() throws Exception { + ds.setDriverClassName("org.h2.Driver"); + ctx.bind("java:comp/env/jdbc/datasource", ds); + } + + @Test + void givenContext_whenLookupByName_thenValidDataSource() throws Exception { + DataSource ds = (DataSource) ctx.lookup("java:comp/env/jdbc/datasource"); + + assertNotNull(ds); + assertNotNull(ds.getConnection()); + } + +} diff --git a/core-java-modules/core-java-jndi/src/test/java/com/baeldung/jndi/exceptions/JndiExceptionsUnitTest.java b/core-java-modules/core-java-jndi/src/test/java/com/baeldung/jndi/exceptions/JndiExceptionsUnitTest.java new file mode 100644 index 0000000000..49d4facffb --- /dev/null +++ b/core-java-modules/core-java-jndi/src/test/java/com/baeldung/jndi/exceptions/JndiExceptionsUnitTest.java @@ -0,0 +1,42 @@ +package com.baeldung.jndi.exceptions; + +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.springframework.jndi.JndiTemplate; +import org.springframework.mock.jndi.SimpleNamingContextBuilder; + +import javax.naming.InitialContext; +import javax.naming.NameNotFoundException; +import javax.naming.NoInitialContextException; + +import static org.junit.jupiter.api.Assertions.assertThrows; + +@TestMethodOrder(MethodOrderer.OrderAnnotation.class) +public class JndiExceptionsUnitTest { + + @Test + @Order(1) + void givenNoContext_whenLookupObject_thenThrowNoInitialContext() { + assertThrows(NoInitialContextException.class, () -> { + JndiTemplate jndiTemplate = new JndiTemplate(); + InitialContext ctx = (InitialContext) jndiTemplate.getContext(); + ctx.lookup("java:comp/env/jdbc/datasource"); + }).printStackTrace(); + } + + @Test + @Order(2) + void givenEmptyContext_whenLookupNotBounds_thenThrowNameNotFound() { + assertThrows(NameNotFoundException.class, () -> { + SimpleNamingContextBuilder builder = new SimpleNamingContextBuilder(); + builder.activate(); + + JndiTemplate jndiTemplate = new JndiTemplate(); + InitialContext ctx = (InitialContext) jndiTemplate.getContext(); + ctx.lookup("badJndiName"); + }).printStackTrace(); + } + +} diff --git a/core-java-modules/core-java-jpms/README.md b/core-java-modules/core-java-jpms/README.md new file mode 100644 index 0000000000..5c424711bc --- /dev/null +++ b/core-java-modules/core-java-jpms/README.md @@ -0,0 +1,3 @@ +### Relevant Articles + +- [Design Strategies for Decoupling Java Modules](https://www.baeldung.com/java-modules-decoupling-design-strategies) diff --git a/core-java-modules/core-java-lambdas/README.md b/core-java-modules/core-java-lambdas/README.md index 10b876735e..98fff64d68 100644 --- a/core-java-modules/core-java-lambdas/README.md +++ b/core-java-modules/core-java-lambdas/README.md @@ -1,3 +1,8 @@ ## Relevant articles: - [Why Do Local Variables Used in Lambdas Have to Be Final or Effectively Final?](https://www.baeldung.com/java-lambda-effectively-final-local-variables) +- [Java 8 – Powerful Comparison with Lambdas](http://www.baeldung.com/java-8-sort-lambda) +- [Functional Interfaces in Java 8](http://www.baeldung.com/java-8-functional-interfaces) +- [Lambda Expressions and Functional Interfaces: Tips and Best Practices](http://www.baeldung.com/java-8-lambda-expressions-tips) +- [Exceptions in Java 8 Lambda Expressions](http://www.baeldung.com/java-lambda-exceptions) +- [Method References in Java](https://www.baeldung.com/java-method-references) diff --git a/core-java-modules/core-java-lambdas/pom.xml b/core-java-modules/core-java-lambdas/pom.xml index d6158c2946..9e6e81ed40 100644 --- a/core-java-modules/core-java-lambdas/pom.xml +++ b/core-java-modules/core-java-lambdas/pom.xml @@ -15,5 +15,11 @@ ../../parent-java - + + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + + \ No newline at end of file diff --git a/core-java-modules/core-java-8/src/test/java/com/baeldung/java8/entity/Human.java b/core-java-modules/core-java-lambdas/src/main/java/com/baeldung/java8/entity/Human.java similarity index 100% rename from core-java-modules/core-java-8/src/test/java/com/baeldung/java8/entity/Human.java rename to core-java-modules/core-java-lambdas/src/main/java/com/baeldung/java8/entity/Human.java diff --git a/core-java-modules/core-java-8/src/main/java/com/baeldung/java8/lambda/exceptions/LambdaExceptionWrappers.java b/core-java-modules/core-java-lambdas/src/main/java/com/baeldung/java8/lambda/exceptions/LambdaExceptionWrappers.java similarity index 100% rename from core-java-modules/core-java-8/src/main/java/com/baeldung/java8/lambda/exceptions/LambdaExceptionWrappers.java rename to core-java-modules/core-java-lambdas/src/main/java/com/baeldung/java8/lambda/exceptions/LambdaExceptionWrappers.java diff --git a/core-java-modules/core-java-8/src/main/java/com/baeldung/java8/lambda/exceptions/ThrowingConsumer.java b/core-java-modules/core-java-lambdas/src/main/java/com/baeldung/java8/lambda/exceptions/ThrowingConsumer.java similarity index 100% rename from core-java-modules/core-java-8/src/main/java/com/baeldung/java8/lambda/exceptions/ThrowingConsumer.java rename to core-java-modules/core-java-lambdas/src/main/java/com/baeldung/java8/lambda/exceptions/ThrowingConsumer.java diff --git a/core-java-modules/core-java-8/src/main/java/com/baeldung/java8/lambda/tips/Bar.java b/core-java-modules/core-java-lambdas/src/main/java/com/baeldung/java8/lambda/tips/Bar.java similarity index 100% rename from core-java-modules/core-java-8/src/main/java/com/baeldung/java8/lambda/tips/Bar.java rename to core-java-modules/core-java-lambdas/src/main/java/com/baeldung/java8/lambda/tips/Bar.java diff --git a/core-java-modules/core-java-8/src/main/java/com/baeldung/java8/lambda/tips/Baz.java b/core-java-modules/core-java-lambdas/src/main/java/com/baeldung/java8/lambda/tips/Baz.java similarity index 100% rename from core-java-modules/core-java-8/src/main/java/com/baeldung/java8/lambda/tips/Baz.java rename to core-java-modules/core-java-lambdas/src/main/java/com/baeldung/java8/lambda/tips/Baz.java diff --git a/core-java-modules/core-java-8/src/main/java/com/baeldung/java8/lambda/tips/Foo.java b/core-java-modules/core-java-lambdas/src/main/java/com/baeldung/java8/lambda/tips/Foo.java similarity index 100% rename from core-java-modules/core-java-8/src/main/java/com/baeldung/java8/lambda/tips/Foo.java rename to core-java-modules/core-java-lambdas/src/main/java/com/baeldung/java8/lambda/tips/Foo.java diff --git a/core-java-modules/core-java-8/src/main/java/com/baeldung/java8/lambda/tips/FooExtended.java b/core-java-modules/core-java-lambdas/src/main/java/com/baeldung/java8/lambda/tips/FooExtended.java similarity index 100% rename from core-java-modules/core-java-8/src/main/java/com/baeldung/java8/lambda/tips/FooExtended.java rename to core-java-modules/core-java-lambdas/src/main/java/com/baeldung/java8/lambda/tips/FooExtended.java diff --git a/core-java-modules/core-java-8/src/main/java/com/baeldung/java8/lambda/tips/Processor.java b/core-java-modules/core-java-lambdas/src/main/java/com/baeldung/java8/lambda/tips/Processor.java similarity index 100% rename from core-java-modules/core-java-8/src/main/java/com/baeldung/java8/lambda/tips/Processor.java rename to core-java-modules/core-java-lambdas/src/main/java/com/baeldung/java8/lambda/tips/Processor.java diff --git a/core-java-modules/core-java-8/src/main/java/com/baeldung/java8/lambda/tips/ProcessorImpl.java b/core-java-modules/core-java-lambdas/src/main/java/com/baeldung/java8/lambda/tips/ProcessorImpl.java similarity index 100% rename from core-java-modules/core-java-8/src/main/java/com/baeldung/java8/lambda/tips/ProcessorImpl.java rename to core-java-modules/core-java-lambdas/src/main/java/com/baeldung/java8/lambda/tips/ProcessorImpl.java diff --git a/core-java-modules/core-java-8/src/main/java/com/baeldung/java8/lambda/tips/UseFoo.java b/core-java-modules/core-java-lambdas/src/main/java/com/baeldung/java8/lambda/tips/UseFoo.java similarity index 100% rename from core-java-modules/core-java-8/src/main/java/com/baeldung/java8/lambda/tips/UseFoo.java rename to core-java-modules/core-java-lambdas/src/main/java/com/baeldung/java8/lambda/tips/UseFoo.java diff --git a/core-java-modules/core-java-8/src/test/java/com/baeldung/functionalinterface/FunctionalInterfaceUnitTest.java b/core-java-modules/core-java-lambdas/src/test/java/com/baeldung/functionalinterface/FunctionalInterfaceUnitTest.java similarity index 100% rename from core-java-modules/core-java-8/src/test/java/com/baeldung/functionalinterface/FunctionalInterfaceUnitTest.java rename to core-java-modules/core-java-lambdas/src/test/java/com/baeldung/functionalinterface/FunctionalInterfaceUnitTest.java diff --git a/core-java-modules/core-java-8/src/test/java/com/baeldung/functionalinterface/ShortToByteFunction.java b/core-java-modules/core-java-lambdas/src/test/java/com/baeldung/functionalinterface/ShortToByteFunction.java similarity index 100% rename from core-java-modules/core-java-8/src/test/java/com/baeldung/functionalinterface/ShortToByteFunction.java rename to core-java-modules/core-java-lambdas/src/test/java/com/baeldung/functionalinterface/ShortToByteFunction.java diff --git a/core-java-modules/core-java-8/src/test/java/com/baeldung/java8/Java8SortUnitTest.java b/core-java-modules/core-java-lambdas/src/test/java/com/baeldung/java8/Java8SortUnitTest.java similarity index 100% rename from core-java-modules/core-java-8/src/test/java/com/baeldung/java8/Java8SortUnitTest.java rename to core-java-modules/core-java-lambdas/src/test/java/com/baeldung/java8/Java8SortUnitTest.java diff --git a/core-java-modules/core-java-8/src/test/java/com/baeldung/java8/lambda/exceptions/LambdaExceptionWrappersUnitTest.java b/core-java-modules/core-java-lambdas/src/test/java/com/baeldung/java8/lambda/exceptions/LambdaExceptionWrappersUnitTest.java similarity index 100% rename from core-java-modules/core-java-8/src/test/java/com/baeldung/java8/lambda/exceptions/LambdaExceptionWrappersUnitTest.java rename to core-java-modules/core-java-lambdas/src/test/java/com/baeldung/java8/lambda/exceptions/LambdaExceptionWrappersUnitTest.java diff --git a/core-java-modules/core-java-8/src/test/java/com/baeldung/java8/lambda/methodreference/Bicycle.java b/core-java-modules/core-java-lambdas/src/test/java/com/baeldung/java8/lambda/methodreference/Bicycle.java similarity index 100% rename from core-java-modules/core-java-8/src/test/java/com/baeldung/java8/lambda/methodreference/Bicycle.java rename to core-java-modules/core-java-lambdas/src/test/java/com/baeldung/java8/lambda/methodreference/Bicycle.java diff --git a/core-java-modules/core-java-8/src/test/java/com/baeldung/java8/lambda/methodreference/BicycleComparator.java b/core-java-modules/core-java-lambdas/src/test/java/com/baeldung/java8/lambda/methodreference/BicycleComparator.java similarity index 100% rename from core-java-modules/core-java-8/src/test/java/com/baeldung/java8/lambda/methodreference/BicycleComparator.java rename to core-java-modules/core-java-lambdas/src/test/java/com/baeldung/java8/lambda/methodreference/BicycleComparator.java diff --git a/core-java-modules/core-java-8/src/test/java/com/baeldung/java8/lambda/methodreference/MethodReferenceUnitTest.java b/core-java-modules/core-java-lambdas/src/test/java/com/baeldung/java8/lambda/methodreference/MethodReferenceUnitTest.java similarity index 100% rename from core-java-modules/core-java-8/src/test/java/com/baeldung/java8/lambda/methodreference/MethodReferenceUnitTest.java rename to core-java-modules/core-java-lambdas/src/test/java/com/baeldung/java8/lambda/methodreference/MethodReferenceUnitTest.java diff --git a/core-java-modules/core-java-8/src/test/java/com/baeldung/java8/lambda/tips/Java8FunctionalInteracesLambdasUnitTest.java b/core-java-modules/core-java-lambdas/src/test/java/com/baeldung/java8/lambda/tips/Java8FunctionalInteracesLambdasUnitTest.java similarity index 100% rename from core-java-modules/core-java-8/src/test/java/com/baeldung/java8/lambda/tips/Java8FunctionalInteracesLambdasUnitTest.java rename to core-java-modules/core-java-lambdas/src/test/java/com/baeldung/java8/lambda/tips/Java8FunctionalInteracesLambdasUnitTest.java diff --git a/core-java-modules/core-java-lang-oop-2/src/main/java/com/baeldung/relationships/aggregation/Car.java b/core-java-modules/core-java-lang-oop-2/src/main/java/com/baeldung/relationships/aggregation/Car.java new file mode 100644 index 0000000000..6be9a18781 --- /dev/null +++ b/core-java-modules/core-java-lang-oop-2/src/main/java/com/baeldung/relationships/aggregation/Car.java @@ -0,0 +1,9 @@ +package com.baeldung.relationships.aggregation; + +import java.util.List; + +public class Car { + + private List wheels; + +} diff --git a/core-java-modules/core-java-lang-oop-2/src/main/java/com/baeldung/relationships/aggregation/CarWithStaticInnerWheel.java b/core-java-modules/core-java-lang-oop-2/src/main/java/com/baeldung/relationships/aggregation/CarWithStaticInnerWheel.java new file mode 100644 index 0000000000..96c07f13a4 --- /dev/null +++ b/core-java-modules/core-java-lang-oop-2/src/main/java/com/baeldung/relationships/aggregation/CarWithStaticInnerWheel.java @@ -0,0 +1,13 @@ +package com.baeldung.relationships.aggregation; + +import java.util.List; + +public class CarWithStaticInnerWheel { + + private List wheels; + + public static class Wheel { + + } + +} diff --git a/core-java-modules/core-java-lang-oop-2/src/main/java/com/baeldung/relationships/aggregation/Wheel.java b/core-java-modules/core-java-lang-oop-2/src/main/java/com/baeldung/relationships/aggregation/Wheel.java new file mode 100644 index 0000000000..1f38ea85ad --- /dev/null +++ b/core-java-modules/core-java-lang-oop-2/src/main/java/com/baeldung/relationships/aggregation/Wheel.java @@ -0,0 +1,7 @@ +package com.baeldung.relationships.aggregation; + +public class Wheel { + + private Car car; + +} diff --git a/core-java-modules/core-java-lang-oop-2/src/main/java/com/baeldung/relationships/association/Child.java b/core-java-modules/core-java-lang-oop-2/src/main/java/com/baeldung/relationships/association/Child.java new file mode 100644 index 0000000000..4c748e8084 --- /dev/null +++ b/core-java-modules/core-java-lang-oop-2/src/main/java/com/baeldung/relationships/association/Child.java @@ -0,0 +1,7 @@ +package com.baeldung.relationships.association; + +public class Child { + + private Mother mother; + +} diff --git a/core-java-modules/core-java-lang-oop-2/src/main/java/com/baeldung/relationships/association/Mother.java b/core-java-modules/core-java-lang-oop-2/src/main/java/com/baeldung/relationships/association/Mother.java new file mode 100644 index 0000000000..0e8edef125 --- /dev/null +++ b/core-java-modules/core-java-lang-oop-2/src/main/java/com/baeldung/relationships/association/Mother.java @@ -0,0 +1,9 @@ +package com.baeldung.relationships.association; + +import java.util.List; + +public class Mother { + + private List children; + +} diff --git a/core-java-modules/core-java-lang-oop-2/src/main/java/com/baeldung/relationships/composition/Building.java b/core-java-modules/core-java-lang-oop-2/src/main/java/com/baeldung/relationships/composition/Building.java new file mode 100644 index 0000000000..1ab44f73fa --- /dev/null +++ b/core-java-modules/core-java-lang-oop-2/src/main/java/com/baeldung/relationships/composition/Building.java @@ -0,0 +1,18 @@ +package com.baeldung.relationships.composition; + +import java.util.List; + +public class Building { + + private String address; + private List rooms; + + public class Room { + + public String getBuildingAddress() { + return Building.this.address; + } + + } + +} diff --git a/core-java-modules/core-java-lang-oop-2/src/main/java/com/baeldung/relationships/composition/BuildingWithDefinitionRoomInMethod.java b/core-java-modules/core-java-lang-oop-2/src/main/java/com/baeldung/relationships/composition/BuildingWithDefinitionRoomInMethod.java new file mode 100644 index 0000000000..4e3411cf30 --- /dev/null +++ b/core-java-modules/core-java-lang-oop-2/src/main/java/com/baeldung/relationships/composition/BuildingWithDefinitionRoomInMethod.java @@ -0,0 +1,28 @@ +package com.baeldung.relationships.composition; + +public class BuildingWithDefinitionRoomInMethod { + + public Room createAnonymousRoom() { + return new Room() { + @Override + public void doInRoom() {} + }; + } + + public Room createInlineRoom() { + class InlineRoom implements Room { + @Override + public void doInRoom() {} + } + return new InlineRoom(); + } + + public Room createLambdaRoom() { + return () -> {}; + } + + public interface Room { + void doInRoom(); + } + +} diff --git a/core-java-modules/core-java-lang-oop-2/src/main/java/com/baeldung/relationships/university/Department.java b/core-java-modules/core-java-lang-oop-2/src/main/java/com/baeldung/relationships/university/Department.java new file mode 100644 index 0000000000..63cfd1b89e --- /dev/null +++ b/core-java-modules/core-java-lang-oop-2/src/main/java/com/baeldung/relationships/university/Department.java @@ -0,0 +1,9 @@ +package com.baeldung.relationships.university; + +import java.util.List; + +public class Department { + + private List professors; + +} diff --git a/core-java-modules/core-java-lang-oop-2/src/main/java/com/baeldung/relationships/university/Professor.java b/core-java-modules/core-java-lang-oop-2/src/main/java/com/baeldung/relationships/university/Professor.java new file mode 100644 index 0000000000..8e1258c3e6 --- /dev/null +++ b/core-java-modules/core-java-lang-oop-2/src/main/java/com/baeldung/relationships/university/Professor.java @@ -0,0 +1,10 @@ +package com.baeldung.relationships.university; + +import java.util.List; + +public class Professor { + + private List department; + private List friends; + +} diff --git a/core-java-modules/core-java-lang-oop-2/src/main/java/com/baeldung/relationships/university/University.java b/core-java-modules/core-java-lang-oop-2/src/main/java/com/baeldung/relationships/university/University.java new file mode 100644 index 0000000000..e5e518e0f1 --- /dev/null +++ b/core-java-modules/core-java-lang-oop-2/src/main/java/com/baeldung/relationships/university/University.java @@ -0,0 +1,9 @@ +package com.baeldung.relationships.university; + +import java.util.List; + +public class University { + + private List department; + +} diff --git a/core-java-modules/core-java-lang-operators/pom.xml b/core-java-modules/core-java-lang-operators/pom.xml new file mode 100644 index 0000000000..58cab9d507 --- /dev/null +++ b/core-java-modules/core-java-lang-operators/pom.xml @@ -0,0 +1,43 @@ + + 4.0.0 + com.baeldung + core-java-lang-operators + 0.1.0-SNAPSHOT + core-java-lang-operators + jar + + + com.baeldung + parent-java + 0.0.1-SNAPSHOT + ../../parent-java + + + + + + org.assertj + assertj-core + ${assertj-core.version} + test + + + + + core-java-lang-operators + + + src/main/resources + true + + + + + + + 3.10.0 + + + diff --git a/core-java-modules/core-java-lang-syntax/src/main/java/com/baeldung/keyword/Circle.java b/core-java-modules/core-java-lang-operators/src/main/java/com/baeldung/keyword/Circle.java similarity index 100% rename from core-java-modules/core-java-lang-syntax/src/main/java/com/baeldung/keyword/Circle.java rename to core-java-modules/core-java-lang-operators/src/main/java/com/baeldung/keyword/Circle.java diff --git a/core-java-modules/core-java-lang-syntax/src/main/java/com/baeldung/keyword/Ring.java b/core-java-modules/core-java-lang-operators/src/main/java/com/baeldung/keyword/Ring.java similarity index 100% rename from core-java-modules/core-java-lang-syntax/src/main/java/com/baeldung/keyword/Ring.java rename to core-java-modules/core-java-lang-operators/src/main/java/com/baeldung/keyword/Ring.java diff --git a/core-java-modules/core-java-lang-syntax/src/main/java/com/baeldung/keyword/Round.java b/core-java-modules/core-java-lang-operators/src/main/java/com/baeldung/keyword/Round.java similarity index 100% rename from core-java-modules/core-java-lang-syntax/src/main/java/com/baeldung/keyword/Round.java rename to core-java-modules/core-java-lang-operators/src/main/java/com/baeldung/keyword/Round.java diff --git a/core-java-modules/core-java-lang-syntax/src/main/java/com/baeldung/keyword/Shape.java b/core-java-modules/core-java-lang-operators/src/main/java/com/baeldung/keyword/Shape.java similarity index 100% rename from core-java-modules/core-java-lang-syntax/src/main/java/com/baeldung/keyword/Shape.java rename to core-java-modules/core-java-lang-operators/src/main/java/com/baeldung/keyword/Shape.java diff --git a/core-java-modules/core-java-lang-syntax/src/main/java/com/baeldung/keyword/Triangle.java b/core-java-modules/core-java-lang-operators/src/main/java/com/baeldung/keyword/Triangle.java similarity index 100% rename from core-java-modules/core-java-lang-syntax/src/main/java/com/baeldung/keyword/Triangle.java rename to core-java-modules/core-java-lang-operators/src/main/java/com/baeldung/keyword/Triangle.java diff --git a/core-java-modules/core-java-lang-syntax/src/test/java/com/baeldung/java/diamond/Car.java b/core-java-modules/core-java-lang-operators/src/test/java/com/baeldung/java/diamond/Car.java similarity index 100% rename from core-java-modules/core-java-lang-syntax/src/test/java/com/baeldung/java/diamond/Car.java rename to core-java-modules/core-java-lang-operators/src/test/java/com/baeldung/java/diamond/Car.java diff --git a/core-java-modules/core-java-lang-syntax/src/test/java/com/baeldung/java/diamond/DiamondOperatorUnitTest.java b/core-java-modules/core-java-lang-operators/src/test/java/com/baeldung/java/diamond/DiamondOperatorUnitTest.java similarity index 100% rename from core-java-modules/core-java-lang-syntax/src/test/java/com/baeldung/java/diamond/DiamondOperatorUnitTest.java rename to core-java-modules/core-java-lang-operators/src/test/java/com/baeldung/java/diamond/DiamondOperatorUnitTest.java diff --git a/core-java-modules/core-java-lang-syntax/src/test/java/com/baeldung/java/diamond/Diesel.java b/core-java-modules/core-java-lang-operators/src/test/java/com/baeldung/java/diamond/Diesel.java similarity index 100% rename from core-java-modules/core-java-lang-syntax/src/test/java/com/baeldung/java/diamond/Diesel.java rename to core-java-modules/core-java-lang-operators/src/test/java/com/baeldung/java/diamond/Diesel.java diff --git a/core-java-modules/core-java-lang-syntax/src/test/java/com/baeldung/java/diamond/Engine.java b/core-java-modules/core-java-lang-operators/src/test/java/com/baeldung/java/diamond/Engine.java similarity index 100% rename from core-java-modules/core-java-lang-syntax/src/test/java/com/baeldung/java/diamond/Engine.java rename to core-java-modules/core-java-lang-operators/src/test/java/com/baeldung/java/diamond/Engine.java diff --git a/core-java-modules/core-java-lang-syntax/src/test/java/com/baeldung/java/diamond/Vehicle.java b/core-java-modules/core-java-lang-operators/src/test/java/com/baeldung/java/diamond/Vehicle.java similarity index 100% rename from core-java-modules/core-java-lang-syntax/src/test/java/com/baeldung/java/diamond/Vehicle.java rename to core-java-modules/core-java-lang-operators/src/test/java/com/baeldung/java/diamond/Vehicle.java diff --git a/core-java-modules/core-java-lang-syntax/src/test/java/com/baeldung/java/doublebrace/DoubleBraceUnitTest.java b/core-java-modules/core-java-lang-operators/src/test/java/com/baeldung/java/doublebrace/DoubleBraceUnitTest.java similarity index 100% rename from core-java-modules/core-java-lang-syntax/src/test/java/com/baeldung/java/doublebrace/DoubleBraceUnitTest.java rename to core-java-modules/core-java-lang-operators/src/test/java/com/baeldung/java/doublebrace/DoubleBraceUnitTest.java diff --git a/core-java-modules/core-java-lang-syntax/src/test/java/com/baeldung/keyword/test/InstanceOfUnitTest.java b/core-java-modules/core-java-lang-operators/src/test/java/com/baeldung/keyword/test/InstanceOfUnitTest.java similarity index 100% rename from core-java-modules/core-java-lang-syntax/src/test/java/com/baeldung/keyword/test/InstanceOfUnitTest.java rename to core-java-modules/core-java-lang-operators/src/test/java/com/baeldung/keyword/test/InstanceOfUnitTest.java diff --git a/core-java-modules/core-java-lang-syntax/src/test/java/com/baeldung/modulo/ModuloUnitTest.java b/core-java-modules/core-java-lang-operators/src/test/java/com/baeldung/modulo/ModuloUnitTest.java similarity index 100% rename from core-java-modules/core-java-lang-syntax/src/test/java/com/baeldung/modulo/ModuloUnitTest.java rename to core-java-modules/core-java-lang-operators/src/test/java/com/baeldung/modulo/ModuloUnitTest.java diff --git a/core-java-modules/core-java-lang-syntax/src/test/java/com/baeldung/ternaryoperator/TernaryOperatorUnitTest.java b/core-java-modules/core-java-lang-operators/src/test/java/com/baeldung/ternaryoperator/TernaryOperatorUnitTest.java similarity index 100% rename from core-java-modules/core-java-lang-syntax/src/test/java/com/baeldung/ternaryoperator/TernaryOperatorUnitTest.java rename to core-java-modules/core-java-lang-operators/src/test/java/com/baeldung/ternaryoperator/TernaryOperatorUnitTest.java diff --git a/core-java-modules/core-java-lang-operators/src/test/java/com/baeldung/unaryoperators/IncrementDecrementUnaryOperatorUnitTest.java b/core-java-modules/core-java-lang-operators/src/test/java/com/baeldung/unaryoperators/IncrementDecrementUnaryOperatorUnitTest.java new file mode 100644 index 0000000000..cb0f896ec0 --- /dev/null +++ b/core-java-modules/core-java-lang-operators/src/test/java/com/baeldung/unaryoperators/IncrementDecrementUnaryOperatorUnitTest.java @@ -0,0 +1,64 @@ +package com.baeldung.unaryoperators; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.Test; + +public class IncrementDecrementUnaryOperatorUnitTest { + + @Test + public void givenAnOperand_whenUsingPreIncrementUnaryOperator_thenOperandIsIncrementedByOne() { + int operand = 1; + ++operand; + assertThat(operand).isEqualTo(2); + } + + @Test + public void givenANumber_whenUsingPreIncrementUnaryOperatorInEvaluation_thenNumberIsIncrementedByOne() { + int operand = 1; + int number = ++operand; + assertThat(number).isEqualTo(2); + } + + @Test + public void givenAnOperand_whenUsingPreDecrementUnaryOperator_thenOperandIsDecrementedByOne() { + int operand = 1; + --operand; + assertThat(operand).isEqualTo(0); + } + + @Test + public void givenANumber_whenUsingPreDecrementUnaryOperatorInEvaluation_thenNumberIsDecrementedByOne() { + int operand = 1; + int number = --operand; + assertThat(number).isEqualTo(0); + } + + @Test + public void givenAnOperand_whenUsingPostIncrementUnaryOperator_thenOperandIsIncrementedByOne() { + int operand = 1; + operand++; + assertThat(operand).isEqualTo(2); + } + + @Test + public void givenANumber_whenUsingPostIncrementUnaryOperatorInEvaluation_thenNumberIsSameAsOldValue() { + int operand = 1; + int number = operand++; + assertThat(number).isEqualTo(1); + } + + @Test + public void givenAnOperand_whenUsingPostDecrementUnaryOperator_thenOperandIsDecrementedByOne() { + int operand = 1; + operand--; + assertThat(operand).isEqualTo(0); + } + + @Test + public void givenANumber_whenUsingPostDecrementUnaryOperatorInEvaluation_thenNumberIsSameAsOldValue() { + int operand = 1; + int number = operand--; + assertThat(number).isEqualTo(1); + } +} diff --git a/core-java-modules/core-java-lang-syntax/README.md b/core-java-modules/core-java-lang-syntax/README.md index 81c3d6c354..3293e9b23d 100644 --- a/core-java-modules/core-java-lang-syntax/README.md +++ b/core-java-modules/core-java-lang-syntax/README.md @@ -18,3 +18,4 @@ - [The Modulo Operator in Java](https://www.baeldung.com/modulo-java) - [Ternary Operator In Java](https://www.baeldung.com/java-ternary-operator) - [Java instanceof Operator](https://www.baeldung.com/java-instanceof) +- [Breaking Out of Nested Loops](https://www.baeldung.com/java-breaking-out-nested-loop) diff --git a/core-java-modules/core-java-networking-2/README.md b/core-java-modules/core-java-networking-2/README.md new file mode 100644 index 0000000000..6b6151248e --- /dev/null +++ b/core-java-modules/core-java-networking-2/README.md @@ -0,0 +1,3 @@ +### Relevant Articles + +- [Checking if a URL Exists in Java](https://www.baeldung.com/java-check-url-exists) diff --git a/core-java-modules/core-java-networking-2/pom.xml b/core-java-modules/core-java-networking-2/pom.xml new file mode 100644 index 0000000000..8a26f6ab9f --- /dev/null +++ b/core-java-modules/core-java-networking-2/pom.xml @@ -0,0 +1,20 @@ + + 4.0.0 + core-java-networking-2 + core-java-networking-2 + jar + + + com.baeldung.core-java-modules + core-java-modules + 1.0.0-SNAPSHOT + + + + + + + core-java-networking-2 + + diff --git a/core-java-modules/core-java-networking-2/src/main/java/com/baeldung/url/UrlChecker.java b/core-java-modules/core-java-networking-2/src/main/java/com/baeldung/url/UrlChecker.java new file mode 100644 index 0000000000..b99e74f8bf --- /dev/null +++ b/core-java-modules/core-java-networking-2/src/main/java/com/baeldung/url/UrlChecker.java @@ -0,0 +1,25 @@ +package com.baeldung.url; + +import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.URL; + +public class UrlChecker { + + public int getResponseCodeForURL(String address) throws IOException { + return getResponseCodeForURLUsing(address, "GET"); + } + + public int getResponseCodeForURLUsingHead(String address) throws IOException { + return getResponseCodeForURLUsing(address, "HEAD"); + } + + private int getResponseCodeForURLUsing(String address, String method) throws IOException { + HttpURLConnection.setFollowRedirects(false); // Set follow redirects to false + final URL url = new URL(address); + HttpURLConnection huc = (HttpURLConnection) url.openConnection(); + huc.setRequestMethod(method); + return huc.getResponseCode(); + } + +} diff --git a/core-java-modules/core-java-networking-2/src/test/java/com/baeldung/url/UrlCheckerUnitTest.java b/core-java-modules/core-java-networking-2/src/test/java/com/baeldung/url/UrlCheckerUnitTest.java new file mode 100644 index 0000000000..5e295e65a0 --- /dev/null +++ b/core-java-modules/core-java-networking-2/src/test/java/com/baeldung/url/UrlCheckerUnitTest.java @@ -0,0 +1,39 @@ +package com.baeldung.url; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.io.IOException; + +import org.junit.Test; + +public class UrlCheckerUnitTest { + + @Test + public void givenValidUrl_WhenUsingHEAD_ThenReturn200() throws IOException { + UrlChecker tester = new UrlChecker(); + int responseCode = tester.getResponseCodeForURLUsingHead("http://www.example.com"); + assertEquals(200, responseCode); + } + + @Test + public void givenInvalidIUrl_WhenUsingHEAD_ThenReturn404() throws IOException { + UrlChecker tester = new UrlChecker(); + int responseCode = tester.getResponseCodeForURLUsingHead("http://www.example.com/unkownurl"); + assertEquals(404, responseCode); + } + + @Test + public void givenValidUrl_WhenUsingGET_ThenReturn200() throws IOException { + UrlChecker tester = new UrlChecker(); + int responseCode = tester.getResponseCodeForURL("http://www.example.com"); + assertEquals(200, responseCode); + } + + @Test + public void givenInvalidIUrl_WhenUsingGET_ThenReturn404() throws IOException { + UrlChecker tester = new UrlChecker(); + int responseCode = tester.getResponseCodeForURL("http://www.example.com/unkownurl"); + assertEquals(404, responseCode); + } + +} diff --git a/core-java-modules/core-java-nio/README.md b/core-java-modules/core-java-nio/README.md index 9034c3b3b1..1ac3b6c089 100644 --- a/core-java-modules/core-java-nio/README.md +++ b/core-java-modules/core-java-nio/README.md @@ -1,3 +1,3 @@ -## Relevant articles: +## Relevant Articles: -- [Determine File Creating Date in Java](https://www.baeldung.com/java-file-creation-date) +- [Determine File Creation Date in Java](https://www.baeldung.com/java-file-creation-date) diff --git a/core-java-modules/core-java-nio/src/main/java/com/baeldung/file/Main.java b/core-java-modules/core-java-nio/src/main/java/com/baeldung/file/Main.java new file mode 100644 index 0000000000..d8800dd881 --- /dev/null +++ b/core-java-modules/core-java-nio/src/main/java/com/baeldung/file/Main.java @@ -0,0 +1,26 @@ +package com.baeldung.file; + +import static com.baeldung.file.NumberOfLineFinder.getTotalNumberOfLinesUsingApacheCommonsIO; +import static com.baeldung.file.NumberOfLineFinder.getTotalNumberOfLinesUsingBufferedReader; +import static com.baeldung.file.NumberOfLineFinder.getTotalNumberOfLinesUsingGoogleGuava; +import static com.baeldung.file.NumberOfLineFinder.getTotalNumberOfLinesUsingLineNumberReader; +import static com.baeldung.file.NumberOfLineFinder.getTotalNumberOfLinesUsingNIOFileChannel; +import static com.baeldung.file.NumberOfLineFinder.getTotalNumberOfLinesUsingNIOFiles; +import static com.baeldung.file.NumberOfLineFinder.getTotalNumberOfLinesUsingNIOFilesReadAllLines; +import static com.baeldung.file.NumberOfLineFinder.getTotalNumberOfLinesUsingScanner; + +public class Main { + + private static final String INPUT_FILE_NAME = "src/main/resources/input.txt"; + + public static void main(String... args) throws Exception { + System.out.printf("Total Number of Lines Using BufferedReader: %s%n", getTotalNumberOfLinesUsingBufferedReader(INPUT_FILE_NAME)); + System.out.printf("Total Number of Lines Using LineNumberReader: %s%n", getTotalNumberOfLinesUsingLineNumberReader(INPUT_FILE_NAME)); + System.out.printf("Total Number of Lines Using Scanner: %s%n", getTotalNumberOfLinesUsingScanner(INPUT_FILE_NAME)); + System.out.printf("Total Number of Lines Using NIO Files: %s%n", getTotalNumberOfLinesUsingNIOFiles(INPUT_FILE_NAME)); + System.out.printf("Total Number of Lines Using NIO Files#readAllLines: %s%n", getTotalNumberOfLinesUsingNIOFilesReadAllLines(INPUT_FILE_NAME)); + System.out.printf("Total Number of Lines Using NIO FileChannel: %s%n", getTotalNumberOfLinesUsingNIOFileChannel(INPUT_FILE_NAME)); + System.out.printf("Total Number of Lines Using Apache Commons IO: %s%n", getTotalNumberOfLinesUsingApacheCommonsIO(INPUT_FILE_NAME)); + System.out.printf("Total Number of Lines Using NIO Google Guava: %s%n", getTotalNumberOfLinesUsingGoogleGuava(INPUT_FILE_NAME)); + } +} diff --git a/core-java-modules/core-java-nio/src/main/java/com/baeldung/file/NumberOfLineFinder.java b/core-java-modules/core-java-nio/src/main/java/com/baeldung/file/NumberOfLineFinder.java new file mode 100644 index 0000000000..3abf82f3fa --- /dev/null +++ b/core-java-modules/core-java-nio/src/main/java/com/baeldung/file/NumberOfLineFinder.java @@ -0,0 +1,123 @@ +package com.baeldung.file; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.LineNumberReader; +import java.nio.ByteBuffer; +import java.nio.channels.FileChannel; +import java.nio.channels.FileChannel.MapMode; +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.nio.file.StandardOpenOption; +import java.util.List; +import java.util.Scanner; +import java.util.stream.Stream; + +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.LineIterator; + +public class NumberOfLineFinder { + + public static int getTotalNumberOfLinesUsingBufferedReader(String fileName) { + int lines = 0; + try (BufferedReader reader = new BufferedReader(new FileReader(fileName))) { + while (reader.readLine() != null) { + lines++; + } + } catch (IOException ioe) { + ioe.printStackTrace(); + } + return lines; + } + + public static int getTotalNumberOfLinesUsingLineNumberReader(String fileName) { + int lines = 0; + try (LineNumberReader reader = new LineNumberReader(new FileReader(fileName))) { + reader.skip(Integer.MAX_VALUE); + lines = reader.getLineNumber() + 1; + } catch (IOException ioe) { + ioe.printStackTrace(); + } + return lines; + } + + public static int getTotalNumberOfLinesUsingScanner(String fileName) { + int lines = 0; + try (Scanner scanner = new Scanner(new FileReader(fileName))) { + while (scanner.hasNextLine()) { + scanner.nextLine(); + lines++; + } + } catch (IOException ioe) { + ioe.printStackTrace(); + } + return lines; + } + + public static int getTotalNumberOfLinesUsingNIOFiles(String fileName) { + int lines = 0; + try (Stream fileStream = Files.lines(Paths.get(fileName))) { + lines = (int) fileStream.count(); + } catch (IOException ioe) { + ioe.printStackTrace(); + } + return lines; + } + + public static int getTotalNumberOfLinesUsingNIOFilesReadAllLines(String fileName) { + int lines = 0; + try { + List fileStream = Files.readAllLines(Paths.get(fileName)); + lines = fileStream.size(); + } catch (IOException ioe) { + ioe.printStackTrace(); + } + return lines; + } + + public static int getTotalNumberOfLinesUsingNIOFileChannel(String fileName) { + int lines = 1; + try (FileChannel channel = FileChannel.open(Paths.get(fileName), StandardOpenOption.READ)) { + ByteBuffer byteBuffer = channel.map(MapMode.READ_ONLY, 0, channel.size()); + while (byteBuffer.hasRemaining()) { + byte currentChar = byteBuffer.get(); + if (currentChar == '\n') { + lines++; + } + } + } catch (IOException ioe) { + ioe.printStackTrace(); + } + return lines; + } + + public static int getTotalNumberOfLinesUsingApacheCommonsIO(String fileName) { + int lines = 0; + try { + LineIterator lineIterator = FileUtils.lineIterator(new File(fileName)); + while (lineIterator.hasNext()) { + lineIterator.nextLine(); + lines++; + } + } catch (IOException ioe) { + ioe.printStackTrace(); + } + return lines; + } + + public static int getTotalNumberOfLinesUsingGoogleGuava(String fileName) { + int lines = 0; + try { + List lineItems = com.google.common.io.Files.readLines(Paths.get(fileName) + .toFile(), Charset.defaultCharset()); + lines = lineItems.size(); + } catch (IOException ioe) { + ioe.printStackTrace(); + } + return lines; + } + +} diff --git a/core-java-modules/core-java-nio/src/main/resources/input.txt b/core-java-modules/core-java-nio/src/main/resources/input.txt new file mode 100644 index 0000000000..650da894e8 --- /dev/null +++ b/core-java-modules/core-java-nio/src/main/resources/input.txt @@ -0,0 +1,45 @@ +Lorem ipsum dolor sit amet, consectetur adipiscing elit. In lacus enim, scelerisque id sapien ut, semper euismod quam. Nunc ullamcorper semper blandit. Praesent quis quam mollis, iaculis lectus a, fringilla leo. Interdum et malesuada fames ac ante ipsum primis in faucibus. Duis vitae auctor mauris. Pellentesque eu pellentesque lorem, vel ultricies libero. Pellentesque vestibulum sagittis eros. In vestibulum lacus elit. Interdum et malesuada fames ac ante ipsum primis in faucibus. + +Vivamus pharetra lacus fringilla nisl molestie eleifend. Donec et dolor non quam mattis mattis. Proin malesuada maximus elit id semper. Donec facilisis dolor ut feugiat auctor. Proin accumsan semper consectetur. Vivamus facilisis odio vel bibendum imperdiet. Sed rutrum nisi nec nisi interdum fringilla. Aliquam laoreet velit ullamcorper egestas ultrices. Aliquam ultricies sem sed orci interdum, eu porta purus malesuada. Sed accumsan, nunc ut maximus rhoncus, arcu ante pretium ex, non ultrices magna nisi et velit. Pellentesque tempor mi quis lacus consectetur, quis imperdiet enim efficitur. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. + +Nunc sed maximus erat. Aenean imperdiet finibus massa ac aliquam. Interdum et malesuada fames ac ante ipsum primis in faucibus. Duis dignissim cursus purus, eu tempus urna. Nunc sed mauris scelerisque, luctus eros ut, viverra nisi. Maecenas congue sed ligula in eleifend. Praesent nec dignissim enim, dictum efficitur massa. Nullam eros dui, rutrum quis aliquam accumsan, sollicitudin cursus eros. Phasellus euismod, lorem vitae vehicula ullamcorper, leo lorem vestibulum magna, vitae malesuada libero ipsum id lorem. Aenean finibus turpis facilisis tortor bibendum, vitae dignissim dolor dictum. Ut quis ornare nisi, non rutrum sapien. + +Etiam placerat, est eget placerat imperdiet, neque urna tristique est, a dictum nisl dolor vitae leo. Vivamus porttitor mi vitae volutpat ultrices. Quisque at ante porta mauris ultricies iaculis. Phasellus iaculis sollicitudin urna nec facilisis. Suspendisse dapibus vulputate scelerisque. Fusce felis diam, eleifend in tristique in, malesuada a purus. Suspendisse euismod ipsum sed urna imperdiet, quis venenatis lacus dapibus. Maecenas vitae est vel sem fringilla ornare at ut mi. Quisque porta, nulla at rutrum fringilla, mi ligula egestas libero, ac convallis elit diam et sapien. Vestibulum purus tortor, ornare ut enim sed, mattis lobortis erat. Maecenas ac ante tincidunt, euismod mauris a, fermentum diam. Nullam arcu est, consequat sed enim in, bibendum aliquet velit. Donec bibendum magna ac augue sagittis vehicula. Curabitur nec mauris eu augue bibendum volutpat. Fusce fringilla varius fringilla. + +Aliquam faucibus massa non orci accumsan, porta consectetur diam vulputate. Nullam nec erat mollis, imperdiet libero nec, tincidunt neque. Aenean varius purus nec est auctor, sed vulputate libero varius. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent vel neque elit. Donec vulputate fermentum nulla, ut aliquam neque tempor in. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec vel venenatis est. Suspendisse luctus elit quis dui dapibus, id sodales dolor cursus. Curabitur ut vehicula dui. Fusce aliquet est et ante feugiat, et tempus ex congue. Nunc eget dapibus leo. Nunc eu accumsan diam. Suspendisse risus eros, rutrum et volutpat in, consequat in nulla. Suspendisse id felis a orci accumsan iaculis. + +Duis tincidunt diam eget tortor aliquet sodales. Etiam sodales purus ac urna mollis, et cursus enim porttitor. Nulla viverra ligula nunc, ornare condimentum felis posuere sed. Fusce aliquet pretium sagittis. Sed ac mi elementum massa dictum ornare. Integer quis dapibus lectus. Curabitur in rhoncus justo, et vulputate justo. Integer eget efficitur felis. + +Sed finibus vel tortor ac egestas. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas vestibulum nulla mi, blandit efficitur sapien fermentum eu. Integer sed turpis eros. Phasellus sed aliquam ligula. Etiam dictum quam in dapibus mattis. Donec et tristique quam. Pellentesque gravida luctus dolor, eu ornare sapien. Donec justo ante, lacinia non sem et, ultricies dignissim nibh. Vivamus eu nisl et magna pulvinar efficitur. Sed at vehicula lectus, sit amet luctus sem. Morbi vehicula sapien nisi, nec sagittis orci vestibulum et. + +Praesent non finibus diam. Quisque sit amet nisl vitae augue lobortis commodo. Morbi ullamcorper, tortor id ornare maximus, erat ipsum ullamcorper ipsum, in imperdiet diam sem vel erat. Sed pellentesque quis ex sed volutpat. Vestibulum volutpat diam ac dignissim sollicitudin. Praesent at luctus ex, at volutpat dui. Nunc nulla dui, lobortis et pharetra quis, efficitur in turpis. Donec sodales auctor purus id mollis. Sed auctor eu erat eget bibendum. Mauris tincidunt ornare neque id consequat. Suspendisse non massa ante. Quisque velit enim, rhoncus at erat eget, scelerisque placerat elit. Donec finibus luctus dolor. In sed eleifend lorem. Sed tempor ullamcorper lorem nec tristique. Fusce nec volutpat neque, id elementum est. + +Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Vestibulum mattis elementum tellus, vitae maximus nulla eleifend ut. Vestibulum eu nibh vulputate, posuere felis eget, aliquet ex. Nullam leo ex, lacinia a ante ac, accumsan efficitur ligula. Vestibulum ornare gravida tempus. Proin rhoncus felis sit amet dolor commodo facilisis. Integer aliquet, diam sed pharetra feugiat, sem massa mollis orci, eget pretium libero nunc at quam. Ut rhoncus quam vitae massa hendrerit, ornare condimentum odio varius. Donec odio sapien, tristique eget libero ac, interdum facilisis odio. Phasellus nec mauris vel dolor semper mattis et quis ligula. Donec nec porttitor nunc. Integer maximus quam vitae sem gravida, ut commodo ex porttitor. + +Sed cursus nisi turpis, vel laoreet massa blandit ut. Cras posuere velit nulla, nec pellentesque ipsum dignissim eget. Donec pharetra, ex et commodo viverra, leo dolor dapibus tellus, vel dignissim est sem ac lectus. Quisque a arcu dapibus, aliquet magna sed, rhoncus neque. Integer suscipit, nulla ac varius lacinia, orci metus scelerisque neque, a laoreet nibh risus vitae dolor. Pellentesque felis metus, pulvinar vel cursus id, ultrices non purus. Donec mi lectus, faucibus sit amet nunc at, sagittis pretium lectus. Fusce nec purus arcu. Mauris neque neque, blandit eget mi at, auctor tempus orci. Mauris sapien lorem, luctus nec tellus non, porttitor aliquam dui. + +Mauris non ex risus. Aliquam imperdiet in eros eget placerat. Sed congue sed sapien porta sollicitudin. Phasellus tempor hendrerit metus vitae tincidunt. Suspendisse congue nisi sed augue dapibus, at pretium ante mollis. Cras non posuere nulla. Proin malesuada finibus magna vel iaculis. Cras in dapibus lorem. Pellentesque volutpat dolor sit amet magna tincidunt mollis. Nunc et lectus sodales, accumsan est vitae, ornare augue. Maecenas malesuada arcu leo, eget blandit lectus porttitor et. Nam aliquam sapien sit amet purus consequat lobortis. Aenean varius, augue porta dignissim efficitur, felis velit dapibus leo, tincidunt ultricies magna felis id ligula. Duis hendrerit, lectus eu elementum euismod, elit lectus consequat mi, sit amet egestas justo massa ut urna. Proin eleifend interdum ultrices. + +Donec lacinia orci pharetra ornare tincidunt. Nulla facilisi. Maecenas malesuada dui ac elit sagittis tincidunt id dictum dolor. Quisque lobortis purus ac metus volutpat viverra. Proin finibus sapien ut odio semper consectetur. Sed gravida luctus egestas. Mauris pretium volutpat elit, at commodo arcu sagittis nec. Ut condimentum fringilla urna ac dignissim. Cras aliquam metus pulvinar, pulvinar nibh at, placerat arcu. Nulla ornare tortor sed lectus mollis, vitae fringilla tellus egestas. Vivamus efficitur tincidunt sapien, sed finibus mi congue eu. Nullam magna velit, lacinia vitae ligula eget, molestie consectetur felis. Suspendisse varius turpis orci, ac laoreet arcu accumsan sed. Fusce quis fermentum lacus, nec varius libero. Pellentesque ac odio ut justo lobortis elementum sit amet vehicula lorem. Nulla interdum nulla eget mi tristique, vitae egestas nunc egestas. + +Curabitur commodo libero eu elit tincidunt, quis placerat risus vehicula. Vestibulum vehicula id nunc iaculis fermentum. Aenean semper, tellus ac semper rutrum, justo lorem feugiat leo, quis vulputate neque dui non ligula. Etiam egestas, enim eget tempor porta, nunc est tristique ante, vel suscipit massa lorem vel diam. Donec faucibus ante id turpis rhoncus congue. Nullam laoreet, diam efficitur scelerisque consequat, ligula leo ultrices est, non fermentum elit mauris ut dolor. Morbi non porttitor lorem. Sed volutpat sapien et lorem porttitor, ultricies ultricies tellus congue. Mauris sodales, tortor nec sagittis finibus, dui odio aliquet nibh, in luctus sapien massa eu risus. Nulla in est sed ante molestie vehicula vel nec lectus. Fusce maximus a quam eget aliquam. Vivamus pulvinar quis nisi a maximus. Proin cursus lacus sapien, et hendrerit elit pretium a. Donec tellus lectus, consectetur id dolor a, luctus rutrum libero. Suspendisse auctor scelerisque dui, nec pellentesque felis viverra nec. Cras elit ex, varius sed pulvinar sed, suscipit ultrices lacus. + +Vivamus eu luctus lectus. Maecenas congue magna orci, quis semper nulla blandit vel. Phasellus dignissim risus placerat lacinia sagittis. Praesent at gravida nisi, at pulvinar diam. Nulla egestas lectus sed felis facilisis egestas. Curabitur posuere gravida urna eu vestibulum. Pellentesque at dolor gravida, placerat quam sit amet, fermentum ligula. Morbi fringilla, mi eget mollis dictum, neque dolor ullamcorper leo, a rutrum libero ipsum eget orci. Curabitur consectetur iaculis vestibulum. Suspendisse ultricies ligula et neque lacinia luctus. Sed dignissim neque id eros sollicitudin pellentesque. + +Donec et magna quis lectus pharetra finibus a fringilla sapien. Phasellus accumsan, erat eu sodales cursus, tortor elit dapibus risus, ut ornare neque arcu in tellus. Nam ac vehicula diam, at aliquam nisl. Cras in sem eget nisi ultrices rutrum sit amet eu velit. Sed molestie tellus eget ante scelerisque, sit amet pulvinar neque fringilla. Nunc volutpat facilisis egestas. Cras sodales dui ac massa egestas, in mattis leo rhoncus. Pellentesque vitae urna vehicula ipsum sodales suscipit. Sed commodo tempus fringilla. + +Etiam egestas elit vitae mi maximus fringilla quis eget libero. Fusce finibus ultrices tellus at molestie. Pellentesque posuere blandit elementum. Etiam eu erat eu urna hendrerit euismod. Nulla quis lectus rhoncus, ultricies urna eget, pretium neque. Cras sit amet ipsum sit amet purus rutrum ultricies nec vitae tortor. Sed tempor dapibus augue in pulvinar. Ut pretium sapien in malesuada accumsan. Donec eget ultrices erat, ut efficitur ligula. Sed posuere mauris est, nec convallis ipsum tempus non. + +Duis a ullamcorper ante. Quisque eu ultricies metus, at aliquet odio. Nullam tempus molestie augue ut varius. Fusce purus eros, dictum nec finibus sed, sodales et diam. Suspendisse sed mi purus. Donec eleifend ipsum diam, nec fringilla enim laoreet non. Phasellus condimentum, magna sit amet porttitor suscipit, arcu risus lobortis dolor, ac fringilla nibh nisl vel purus. Phasellus facilisis posuere orci sit amet tempus. Nam nec enim maximus, rhoncus felis a, rutrum diam. + +Suspendisse potenti. Donec vel tempor neque. In aliquet nulla in eleifend bibendum. Sed sapien sem, finibus in sodales vitae, euismod in sem. Phasellus nec elit a erat pulvinar semper. Aliquam luctus nisl in libero molestie aliquam. Nunc ac ornare felis. Ut non mauris ut ipsum rhoncus pretium. Curabitur tristique lacus a sagittis aliquam. Morbi vel volutpat tellus. Maecenas volutpat, lacus sed tempus imperdiet, eros tellus volutpat nisi, a egestas augue nulla quis arcu. In sollicitudin imperdiet efficitur. Suspendisse viverra aliquet nisi, congue ultrices arcu hendrerit in. + +Maecenas vitae vestibulum nunc. Nullam semper faucibus tincidunt. Etiam sed hendrerit risus. Proin gravida, urna nec tincidunt tempus, nulla sapien porttitor nibh, porttitor lobortis nunc quam et tortor. Praesent ut varius lacus, ut hendrerit enim. Ut nec turpis ac felis imperdiet bibendum. Phasellus porttitor enim odio, et vehicula mi convallis vel. Quisque porta scelerisque sagittis. Praesent dignissim sagittis vulputate. Aenean non justo ac est volutpat bibendum. Aliquam mattis, sapien dapibus pellentesque semper, velit urna malesuada diam, nec varius nibh eros at erat. Proin leo ante, ultricies id velit ut, faucibus porta nibh. Sed nec fermentum urna, sed mollis leo. Aliquam erat volutpat. + +Donec condimentum, urna sed hendrerit vestibulum, ante nibh lacinia dui, in tincidunt odio sem eget orci. In hac habitasse platea dictumst. Mauris id ex id ante tempus finibus eu sagittis erat. Quisque interdum urna risus, vel varius nibh euismod non. Nulla eget pellentesque quam. Aliquam vestibulum ac tortor non lobortis. Sed vitae erat sed libero dignissim dictum nec in turpis. Vivamus id ornare elit, ut facilisis lectus. Morbi dictum purus eget ipsum dignissim porttitor. Sed at vehicula purus, nec rhoncus quam. Nunc a nisl quis arcu blandit fermentum vel quis odio. Vivamus rhoncus, sapien sed lacinia hendrerit, velit urna fermentum dolor, id feugiat magna ligula sed urna. Proin euismod efficitur libero, eget porttitor lacus tempus quis. Duis tincidunt quis est a laoreet. Nam sit amet tristique nisl, sit amet mattis mi. + +Aenean id dictum nulla, sed laoreet magna. Morbi consectetur in turpis at aliquam. Maecenas rutrum feugiat metus, at ullamcorper augue fermentum ut. Vivamus in magna pretium nibh dictum rhoncus luctus at orci. In hac habitasse platea dictumst. Fusce convallis, nulla nec hendrerit suscipit, ipsum diam lobortis sem, vitae elementum lectus erat sit amet magna. Quisque sollicitudin fringilla purus, ac molestie justo congue vitae. Nulla sapien leo, ullamcorper ac tellus in, cursus rhoncus enim. Suspendisse rutrum magna non ex elementum elementum id vitae enim. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Suspendisse ornare libero eu molestie pulvinar. Phasellus faucibus, magna eget rutrum porta, lorem turpis blandit lectus, eu viverra massa risus et ex. + +Ut consectetur eros lacus, ac ullamcorper lacus mattis a. Cras congue justo ut erat interdum, et scelerisque nisi malesuada. Quisque sed sapien sollicitudin purus tincidunt finibus vestibulum vel dolor. Cras iaculis bibendum erat, a dictum urna viverra et. Integer non neque vulputate, tincidunt purus nec, rutrum arcu. Aliquam nec magna non sem semper laoreet quis at quam. Mauris dui lectus, convallis eu efficitur at, facilisis nec lorem. Cras felis sem, egestas ac rutrum vel, mollis et ex. Aenean semper egestas libero, nec commodo mi blandit efficitur. Duis nec quam in massa dignissim sagittis vel vitae leo. Nam molestie hendrerit auctor. + +Sed suscipit egestas tellus sed cursus. Donec vel massa sit amet dui condimentum accumsan. Phasellus libero eros, lobortis a nisi id, porttitor maximus lectus. Praesent consectetur diam urna, id viverra turpis elementum in. Vivamus vitae pretium justo, nec tempor felis. Vivamus volutpat ultricies magna. Suspendisse vulputate lectus ac orci volutpat ullamcorper. Nulla eu leo pretium, commodo arcu accumsan, tempor nisl. Fusce sit amet tellus a ipsum vehicula laoreet sed vitae mauris. Duis porttitor massa mattis nibh placerat consequat. Fusce rutrum commodo tortor eget pellentesque. Suspendisse tempor enim libero, consequat dictum nibh dictum varius. Pellentesque feugiat sit amet urna sed facilisis. Curabitur a sagittis augue. \ No newline at end of file diff --git a/core-java-modules/core-java-nio/src/test/java/com/baeldung/file/NumberOfLineFinderUnitTest.java b/core-java-modules/core-java-nio/src/test/java/com/baeldung/file/NumberOfLineFinderUnitTest.java new file mode 100644 index 0000000000..40ed6d6bba --- /dev/null +++ b/core-java-modules/core-java-nio/src/test/java/com/baeldung/file/NumberOfLineFinderUnitTest.java @@ -0,0 +1,67 @@ +package com.baeldung.file; + +import static com.baeldung.file.NumberOfLineFinder.getTotalNumberOfLinesUsingApacheCommonsIO; +import static com.baeldung.file.NumberOfLineFinder.getTotalNumberOfLinesUsingBufferedReader; +import static com.baeldung.file.NumberOfLineFinder.getTotalNumberOfLinesUsingGoogleGuava; +import static com.baeldung.file.NumberOfLineFinder.getTotalNumberOfLinesUsingLineNumberReader; +import static com.baeldung.file.NumberOfLineFinder.getTotalNumberOfLinesUsingNIOFileChannel; +import static com.baeldung.file.NumberOfLineFinder.getTotalNumberOfLinesUsingNIOFiles; +import static com.baeldung.file.NumberOfLineFinder.getTotalNumberOfLinesUsingNIOFilesReadAllLines; +import static com.baeldung.file.NumberOfLineFinder.getTotalNumberOfLinesUsingScanner; +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +public class NumberOfLineFinderUnitTest { + private static final String INPUT_FILE_NAME = "src/main/resources/input.txt"; + private static final int ACTUAL_LINE_COUNT = 45; + + @Test + public void whenUsingBufferedReader_thenReturnTotalNumberOfLines() { + int lines = getTotalNumberOfLinesUsingBufferedReader(INPUT_FILE_NAME); + assertEquals(ACTUAL_LINE_COUNT, lines); + } + + @Test + public void whenUsingLineNumberReader_thenReturnTotalNumberOfLines() { + int lines = getTotalNumberOfLinesUsingLineNumberReader(INPUT_FILE_NAME); + assertEquals(ACTUAL_LINE_COUNT, lines); + } + + @Test + public void whenUsingScanner_thenReturnTotalNumberOfLines() { + int lines = getTotalNumberOfLinesUsingScanner(INPUT_FILE_NAME); + assertEquals(ACTUAL_LINE_COUNT, lines); + } + + @Test + public void whenUsingNIOFiles_thenReturnTotalNumberOfLines() { + int lines = getTotalNumberOfLinesUsingNIOFiles(INPUT_FILE_NAME); + assertEquals(ACTUAL_LINE_COUNT, lines); + } + + @Test + public void whenUsingNIOFilesReadAllLines_thenReturnTotalNumberOfLines() { + int lines = getTotalNumberOfLinesUsingNIOFilesReadAllLines(INPUT_FILE_NAME); + assertEquals(ACTUAL_LINE_COUNT, lines); + } + + @Test + public void whenUsingNIOFileChannel_thenReturnTotalNumberOfLines() { + int lines = getTotalNumberOfLinesUsingNIOFileChannel(INPUT_FILE_NAME); + assertEquals(ACTUAL_LINE_COUNT, lines); + } + + @Test + public void whenUsingApacheCommonsIO_thenReturnTotalNumberOfLines() { + int lines = getTotalNumberOfLinesUsingApacheCommonsIO(INPUT_FILE_NAME); + assertEquals(ACTUAL_LINE_COUNT, lines); + } + + @Test + public void whenUsingGoogleGuava_thenReturnTotalNumberOfLines() { + int lines = getTotalNumberOfLinesUsingGoogleGuava(INPUT_FILE_NAME); + assertEquals(ACTUAL_LINE_COUNT, lines); + } + +} diff --git a/core-java-modules/core-java-os/README.md b/core-java-modules/core-java-os/README.md index 5f5d373d9b..697af5e4d6 100644 --- a/core-java-modules/core-java-os/README.md +++ b/core-java-modules/core-java-os/README.md @@ -7,4 +7,4 @@ This module uses Java 9, so make sure to have the JDK 9 installed to run it. - [Java 9 Process API Improvements](http://www.baeldung.com/java-9-process-api) - [Guide to java.lang.Process API](https://www.baeldung.com/java-process-api) - [Guide to java.lang.ProcessBuilder API](https://www.baeldung.com/java-lang-processbuilder-api) - +- [Get the Current Working Directory in Java](https://www.baeldung.com/java-current-directory) diff --git a/core-java-modules/core-java-security/README.md b/core-java-modules/core-java-security/README.md index 9526b15be5..a833ca30bb 100644 --- a/core-java-modules/core-java-security/README.md +++ b/core-java-modules/core-java-security/README.md @@ -10,3 +10,4 @@ - [SSL Handshake Failures](https://www.baeldung.com/java-ssl-handshake-failures) - [SHA-256 and SHA3-256 Hashing in Java](https://www.baeldung.com/sha-256-hashing-java) - [Enabling TLS v1.2 in Java 7](https://www.baeldung.com/java-7-tls-v12) +- [The Java SecureRandom Class](https://www.baeldung.com/java-secure-random) diff --git a/core-java-modules/core-java-security/src/main/java/com/baeldung/sasl/ClientCallbackHandler.java b/core-java-modules/core-java-security/src/main/java/com/baeldung/sasl/ClientCallbackHandler.java new file mode 100644 index 0000000000..d73f2a2708 --- /dev/null +++ b/core-java-modules/core-java-security/src/main/java/com/baeldung/sasl/ClientCallbackHandler.java @@ -0,0 +1,29 @@ +package com.baeldung.sasl; + +import java.io.IOException; + +import javax.security.auth.callback.Callback; +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.callback.NameCallback; +import javax.security.auth.callback.PasswordCallback; +import javax.security.auth.callback.UnsupportedCallbackException; +import javax.security.sasl.RealmCallback; + +public class ClientCallbackHandler implements CallbackHandler { + + @Override + public void handle(Callback[] cbs) throws IOException, UnsupportedCallbackException { + for (Callback cb : cbs) { + if (cb instanceof NameCallback) { + NameCallback nc = (NameCallback) cb; + nc.setName("username"); + } else if (cb instanceof PasswordCallback) { + PasswordCallback pc = (PasswordCallback) cb; + pc.setPassword("password".toCharArray()); + } else if (cb instanceof RealmCallback) { + RealmCallback rc = (RealmCallback) cb; + rc.setText("myServer"); + } + } + } +} diff --git a/core-java-modules/core-java-security/src/main/java/com/baeldung/sasl/ServerCallbackHandler.java b/core-java-modules/core-java-security/src/main/java/com/baeldung/sasl/ServerCallbackHandler.java new file mode 100644 index 0000000000..3e071d68cc --- /dev/null +++ b/core-java-modules/core-java-security/src/main/java/com/baeldung/sasl/ServerCallbackHandler.java @@ -0,0 +1,34 @@ +package com.baeldung.sasl; + +import java.io.IOException; + +import javax.security.auth.callback.Callback; +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.callback.NameCallback; +import javax.security.auth.callback.PasswordCallback; +import javax.security.auth.callback.UnsupportedCallbackException; +import javax.security.sasl.AuthorizeCallback; +import javax.security.sasl.RealmCallback; + +public class ServerCallbackHandler implements CallbackHandler { + + @Override + public void handle(Callback[] cbs) throws IOException, UnsupportedCallbackException { + for (Callback cb : cbs) { + if (cb instanceof AuthorizeCallback) { + AuthorizeCallback ac = (AuthorizeCallback) cb; + ac.setAuthorized(true); + } else if (cb instanceof NameCallback) { + NameCallback nc = (NameCallback) cb; + nc.setName("username"); + + } else if (cb instanceof PasswordCallback) { + PasswordCallback pc = (PasswordCallback) cb; + pc.setPassword("password".toCharArray()); + } else if (cb instanceof RealmCallback) { + RealmCallback rc = (RealmCallback) cb; + rc.setText("myServer"); + } + } + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-security/src/test/java/com/baeldung/jgss/JgssIntegrationTest.java b/core-java-modules/core-java-security/src/test/java/com/baeldung/jgss/JgssIntegrationTest.java new file mode 100644 index 0000000000..ce784bcae6 --- /dev/null +++ b/core-java-modules/core-java-security/src/test/java/com/baeldung/jgss/JgssIntegrationTest.java @@ -0,0 +1,84 @@ +package com.baeldung.jgss; + +import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import javax.security.sasl.SaslException; + +import org.ietf.jgss.GSSContext; +import org.ietf.jgss.GSSCredential; +import org.ietf.jgss.GSSException; +import org.ietf.jgss.GSSManager; +import org.ietf.jgss.GSSName; +import org.ietf.jgss.MessageProp; +import org.ietf.jgss.Oid; +import org.junit.After; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; + +@Ignore +public class JgssIntegrationTest { + + private static final String SERVER_PRINCIPAL = "HTTP/localhost@EXAMPLE.COM"; + private static final String MECHANISM = "1.2.840.113554.1.2.2"; + + GSSContext serverContext; + GSSContext clientContext; + + @Before + public void setUp() throws SaslException, GSSException { + GSSManager manager = GSSManager.getInstance(); + serverContext = manager.createContext((GSSCredential) null); + String serverPrinciple = SERVER_PRINCIPAL; + GSSName serverName = manager.createName(serverPrinciple, null); + Oid krb5Oid = new Oid(MECHANISM); + clientContext = manager.createContext(serverName, krb5Oid, (GSSCredential) null, GSSContext.DEFAULT_LIFETIME); + clientContext.requestMutualAuth(true); + clientContext.requestConf(true); + clientContext.requestInteg(true); + } + + @Test + public void givenCredential_whenStarted_thenAutenticationWorks() throws SaslException, GSSException { + byte[] serverToken; + byte[] clientToken; + + // On the client-side + clientToken = clientContext.initSecContext(new byte[0], 0, 0); + // sendToServer(clientToken); // This is supposed to be send over the network + + // On the server-side + serverToken = serverContext.acceptSecContext(clientToken, 0, clientToken.length); + // sendToClient(serverToken); // This is supposed to be send over the network + + // Back on the client-side + clientContext.initSecContext(serverToken, 0, serverToken.length); + + assertTrue(serverContext.isEstablished()); + assertTrue(clientContext.isEstablished()); + } + + @Test + public void givenContext_whenStarted_thenSecurityWorks() throws SaslException, GSSException { + // On the client-side + byte[] messageBytes = "Baeldung".getBytes(); + MessageProp clientProp = new MessageProp(0, true); + byte[] clientToken = clientContext.wrap(messageBytes, 0, messageBytes.length, clientProp); + // sendToServer(clientToken); // This is supposed to be send over the network + + // On the server-side + MessageProp serverProp = new MessageProp(0, false); + byte[] bytes = serverContext.unwrap(clientToken, 0, clientToken.length, serverProp); + String string = new String(bytes); + + assertEquals("Baeldung", string); + } + + @After + public void tearDown() throws SaslException, GSSException { + serverContext.dispose(); + clientContext.dispose(); + } + +} diff --git a/core-java-modules/core-java-security/src/test/java/com/baeldung/sasl/SaslUnitTest.java b/core-java-modules/core-java-security/src/test/java/com/baeldung/sasl/SaslUnitTest.java new file mode 100644 index 0000000000..6601654781 --- /dev/null +++ b/core-java-modules/core-java-security/src/test/java/com/baeldung/sasl/SaslUnitTest.java @@ -0,0 +1,76 @@ +package com.baeldung.sasl; + +import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.nio.charset.StandardCharsets; +import java.util.HashMap; +import java.util.Map; + +import javax.security.sasl.Sasl; +import javax.security.sasl.SaslClient; +import javax.security.sasl.SaslException; +import javax.security.sasl.SaslServer; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +public class SaslUnitTest { + + private static final String MECHANISM = "DIGEST-MD5"; + private static final String SERVER_NAME = "myServer"; + private static final String PROTOCOL = "myProtocol"; + private static final String AUTHORIZATION_ID = null; + private static final String QOP_LEVEL = "auth-conf"; + + private SaslServer saslServer; + private SaslClient saslClient; + + @Before + public void setUp() throws SaslException { + + ServerCallbackHandler serverHandler = new ServerCallbackHandler(); + ClientCallbackHandler clientHandler = new ClientCallbackHandler(); + + Map props = new HashMap<>(); + props.put(Sasl.QOP, QOP_LEVEL); + + saslServer = Sasl.createSaslServer(MECHANISM, PROTOCOL, SERVER_NAME, props, serverHandler); + saslClient = Sasl.createSaslClient(new String[] { MECHANISM }, AUTHORIZATION_ID, PROTOCOL, SERVER_NAME, props, clientHandler); + + } + + @Test + public void givenHandlers_whenStarted_thenAutenticationWorks() throws SaslException { + + byte[] challenge; + byte[] response; + + challenge = saslServer.evaluateResponse(new byte[0]); + response = saslClient.evaluateChallenge(challenge); + + challenge = saslServer.evaluateResponse(response); + response = saslClient.evaluateChallenge(challenge); + + assertTrue(saslServer.isComplete()); + assertTrue(saslClient.isComplete()); + + String qop = (String) saslClient.getNegotiatedProperty(Sasl.QOP); + assertEquals("auth-conf", qop); + + byte[] outgoing = "Baeldung".getBytes(); + byte[] secureOutgoing = saslClient.wrap(outgoing, 0, outgoing.length); + + byte[] secureIncoming = secureOutgoing; + byte[] incoming = saslServer.unwrap(secureIncoming, 0, secureIncoming.length); + assertEquals("Baeldung", new String(incoming, StandardCharsets.UTF_8)); + } + + @After + public void tearDown() throws SaslException { + saslClient.dispose(); + saslServer.dispose(); + } + +} diff --git a/core-java-modules/multimodulemavenproject/README.md b/core-java-modules/multimodulemavenproject/README.md new file mode 100644 index 0000000000..fc4ca60b6b --- /dev/null +++ b/core-java-modules/multimodulemavenproject/README.md @@ -0,0 +1,3 @@ +## Relevant Articles + +- [Multi-Module Maven Application with Java Modules](https://www.baeldung.com/maven-multi-module-project-java-jpms) diff --git a/core-java-modules/pom.xml b/core-java-modules/pom.xml index 11a1003460..ecf1f4147e 100644 --- a/core-java-modules/pom.xml +++ b/core-java-modules/pom.xml @@ -17,6 +17,8 @@ pre-jpms core-java-exceptions core-java-optional + core-java-lang-operators + core-java-networking-2 diff --git a/data-structures/README.md b/data-structures/README.md index 2d92068390..5ea9657173 100644 --- a/data-structures/README.md +++ b/data-structures/README.md @@ -1,4 +1,5 @@ ## Relevant articles: -[The Trie Data Structure in Java](https://www.baeldung.com/trie-java) -[Implementing a Binary Tree in Java](https://www.baeldung.com/java-binary-tree) +- [The Trie Data Structure in Java](https://www.baeldung.com/trie-java) +- [Implementing a Binary Tree in Java](https://www.baeldung.com/java-binary-tree) +- [Depth First Search in Java](https://www.baeldung.com/java-depth-first-search) diff --git a/data-structures/src/main/java/com/baeldung/graph/Graph.java b/data-structures/src/main/java/com/baeldung/graph/Graph.java new file mode 100644 index 0000000000..40df2c713a --- /dev/null +++ b/data-structures/src/main/java/com/baeldung/graph/Graph.java @@ -0,0 +1,74 @@ +package com.baeldung.graph; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Stack; + +public class Graph { + + private Map> adjVertices; + + public Graph() { + this.adjVertices = new HashMap>(); + } + + public void addVertex(int vertex) { + adjVertices.putIfAbsent(vertex, new ArrayList<>()); + } + + public void addEdge(int src, int dest) { + adjVertices.get(src).add(dest); + } + + public void dfsWithoutRecursion(int start) { + Stack stack = new Stack(); + boolean[] isVisited = new boolean[adjVertices.size()]; + stack.push(start); + while (!stack.isEmpty()) { + int current = stack.pop(); + isVisited[current] = true; + visit(current); + for (int dest : adjVertices.get(current)) { + if (!isVisited[dest]) + stack.push(dest); + } + } + } + + public void dfs(int start) { + boolean[] isVisited = new boolean[adjVertices.size()]; + dfsRecursive(start, isVisited); + } + + private void dfsRecursive(int current, boolean[] isVisited) { + isVisited[current] = true; + visit(current); + for (int dest : adjVertices.get(current)) { + if (!isVisited[dest]) + dfsRecursive(dest, isVisited); + } + } + + public List topologicalSort(int start) { + LinkedList result = new LinkedList(); + boolean[] isVisited = new boolean[adjVertices.size()]; + topologicalSortRecursive(start, isVisited, result); + return result; + } + + private void topologicalSortRecursive(int current, boolean[] isVisited, LinkedList result) { + isVisited[current] = true; + for (int dest : adjVertices.get(current)) { + if (!isVisited[dest]) + topologicalSortRecursive(dest, isVisited, result); + } + result.addFirst(current); + } + + private void visit(int value) { + System.out.print(" " + value); + } +} diff --git a/data-structures/src/main/java/com/baeldung/tree/BinaryTree.java b/data-structures/src/main/java/com/baeldung/tree/BinaryTree.java index f435e41afa..bb62714006 100644 --- a/data-structures/src/main/java/com/baeldung/tree/BinaryTree.java +++ b/data-structures/src/main/java/com/baeldung/tree/BinaryTree.java @@ -2,6 +2,7 @@ package com.baeldung.tree; import java.util.LinkedList; import java.util.Queue; +import java.util.Stack; public class BinaryTree { @@ -102,14 +103,14 @@ public class BinaryTree { public void traverseInOrder(Node node) { if (node != null) { traverseInOrder(node.left); - System.out.print(" " + node.value); + visit(node.value); traverseInOrder(node.right); } } public void traversePreOrder(Node node) { if (node != null) { - System.out.print(" " + node.value); + visit(node.value); traversePreOrder(node.left); traversePreOrder(node.right); } @@ -119,7 +120,7 @@ public class BinaryTree { if (node != null) { traversePostOrder(node.left); traversePostOrder(node.right); - System.out.print(" " + node.value); + visit(node.value); } } @@ -147,6 +148,71 @@ public class BinaryTree { } } + + public void traverseInOrderWithoutRecursion() { + Stack stack = new Stack(); + Node current = root; + stack.push(root); + while(! stack.isEmpty()) { + while(current.left != null) { + current = current.left; + stack.push(current); + } + current = stack.pop(); + visit(current.value); + if(current.right != null) { + current = current.right; + stack.push(current); + } + } + } + + public void traversePreOrderWithoutRecursion() { + Stack stack = new Stack(); + Node current = root; + stack.push(root); + while(! stack.isEmpty()) { + current = stack.pop(); + visit(current.value); + + if(current.right != null) + stack.push(current.right); + + if(current.left != null) + stack.push(current.left); + } + } + + public void traversePostOrderWithoutRecursion() { + Stack stack = new Stack(); + Node prev = root; + Node current = root; + stack.push(root); + + while (!stack.isEmpty()) { + current = stack.peek(); + boolean hasChild = (current.left != null || current.right != null); + boolean isPrevLastChild = (prev == current.right || (prev == current.left && current.right == null)); + + if (!hasChild || isPrevLastChild) { + current = stack.pop(); + visit(current.value); + prev = current; + } else { + if (current.right != null) { + stack.push(current.right); + } + if (current.left != null) { + stack.push(current.left); + } + } + } + } + + private void visit(int value) { + System.out.print(" " + value); + } + class Node { int value; Node left; diff --git a/data-structures/src/test/java/com/baeldung/graph/GraphUnitTest.java b/data-structures/src/test/java/com/baeldung/graph/GraphUnitTest.java new file mode 100644 index 0000000000..09b92115d2 --- /dev/null +++ b/data-structures/src/test/java/com/baeldung/graph/GraphUnitTest.java @@ -0,0 +1,40 @@ +package com.baeldung.graph; + +import java.util.List; + +import org.junit.Test; + +public class GraphUnitTest { + + @Test + public void givenDirectedGraph_whenDFS_thenPrintAllValues() { + Graph graph = createDirectedGraph(); + graph.dfs(0); + System.out.println(); + graph.dfsWithoutRecursion(0); + } + + @Test + public void givenDirectedGraph_whenGetTopologicalSort_thenPrintValuesSorted() { + Graph graph = createDirectedGraph(); + List list = graph.topologicalSort(0); + System.out.println(list); + } + + private Graph createDirectedGraph() { + Graph graph = new Graph(); + graph.addVertex(0); + graph.addVertex(1); + graph.addVertex(2); + graph.addVertex(3); + graph.addVertex(4); + graph.addVertex(5); + graph.addEdge(0, 1); + graph.addEdge(0, 2); + graph.addEdge(1, 3); + graph.addEdge(2, 3); + graph.addEdge(3, 4); + graph.addEdge(4, 5); + return graph; + } +} diff --git a/data-structures/src/test/java/com/baeldung/tree/BinaryTreeUnitTest.java b/data-structures/src/test/java/com/baeldung/tree/BinaryTreeUnitTest.java index f81247b74d..f99cb52ed7 100644 --- a/data-structures/src/test/java/com/baeldung/tree/BinaryTreeUnitTest.java +++ b/data-structures/src/test/java/com/baeldung/tree/BinaryTreeUnitTest.java @@ -87,6 +87,8 @@ public class BinaryTreeUnitTest { BinaryTree bt = createBinaryTree(); bt.traverseInOrder(bt.root); + System.out.println(); + bt.traverseInOrderWithoutRecursion(); } @Test @@ -95,6 +97,8 @@ public class BinaryTreeUnitTest { BinaryTree bt = createBinaryTree(); bt.traversePreOrder(bt.root); + System.out.println(); + bt.traversePreOrderWithoutRecursion(); } @Test @@ -103,6 +107,8 @@ public class BinaryTreeUnitTest { BinaryTree bt = createBinaryTree(); bt.traversePostOrder(bt.root); + System.out.println(); + bt.traversePostOrderWithoutRecursion(); } @Test diff --git a/httpclient-simple/pom.xml b/httpclient-simple/pom.xml index 7dd54c8fc4..b2b0f98dd1 100644 --- a/httpclient-simple/pom.xml +++ b/httpclient-simple/pom.xml @@ -21,12 +21,12 @@ org.springframework.security spring-security-web - ${spring.version} + ${spring-security.version} org.springframework.security spring-security-config - ${spring.version} + ${spring-security.version} diff --git a/intelliJ/intelliJ-formatter.xml b/intelliJ/intelliJ-formatter.xml index 6dd1ae67f3..9b1d12a3be 100644 --- a/intelliJ/intelliJ-formatter.xml +++ b/intelliJ/intelliJ-formatter.xml @@ -1,19 +1,15 @@ - + \ No newline at end of file diff --git a/jackson-2/README.md b/jackson-2/README.md index d8c233a00e..bb2a58483f 100644 --- a/jackson-2/README.md +++ b/jackson-2/README.md @@ -2,7 +2,7 @@ ## Jackson Cookbooks and Examples -###The Course +### The Course The "REST With Spring" Classes: http://bit.ly/restwithspring ### Relevant Articles: @@ -10,3 +10,4 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [How to Process YAML with Jackson](https://www.baeldung.com/jackson-yaml) - [Working with Tree Model Nodes in Jackson](https://www.baeldung.com/jackson-json-node-tree-model) - [Converting JSON to CSV in Java](https://www.baeldung.com/java-converting-json-to-csv) +- [Compare Two JSON Objects with Jackson](https://www.baeldung.com/jackson-compare-two-json-objects) 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"))); + + } + +} diff --git a/java-dates-2/README.md b/java-dates-2/README.md index 35286115d4..b2f8319e58 100644 --- a/java-dates-2/README.md +++ b/java-dates-2/README.md @@ -1,3 +1,4 @@ ## Relevant Articles: - [Converting Between LocalDate and XMLGregorianCalendar](https://www.baeldung.com/java-localdate-to-xmlgregoriancalendar) - [Convert Time to Milliseconds in Java](https://www.baeldung.com/java-time-milliseconds) +- [Check If a String Is a Valid Date in Java](https://www.baeldung.com/java-string-valid-date) diff --git a/java-dates/README.md b/java-dates/README.md index 8171e5def9..7da309924d 100644 --- a/java-dates/README.md +++ b/java-dates/README.md @@ -29,3 +29,4 @@ - [A Guide to SimpleDateFormat](https://www.baeldung.com/java-simple-date-format) - [ZoneOffset in Java](https://www.baeldung.com/java-zone-offset) - [Differences Between ZonedDateTime and OffsetDateTime](https://www.baeldung.com/java-zoneddatetime-offsetdatetime) +- [Introduction to Joda-Time](http://www.baeldung.com/joda-time) diff --git a/java-math/pom.xml b/java-math/pom.xml index f71577b707..b5c31c4487 100644 --- a/java-math/pom.xml +++ b/java-math/pom.xml @@ -17,6 +17,26 @@ commons-math3 ${commons-math3.version} + + org.ejml + ejml-all + ${ejml.version} + + + org.nd4j + nd4j-native + ${nd4j.version} + + + org.la4j + la4j + ${la4j.version} + + + colt + colt + ${colt.version} + com.google.guava guava @@ -44,6 +64,17 @@ combinatoricslib3 ${combinatoricslib3.version} + + + org.openjdk.jmh + jmh-core + ${jmh.version} + + + org.openjdk.jmh + jmh-generator-annprocess + ${jmh.version} + @@ -64,6 +95,11 @@ 1.11 27.0.1-jre 3.3.0 + 0.38 + 1.0.0-beta4 + 1.2.0 + 0.6.0 + 1.19 \ No newline at end of file diff --git a/java-math/src/main/java/com/baeldung/algorithms/gcd/GCDImplementation.java b/java-math/src/main/java/com/baeldung/algorithms/gcd/GCDImplementation.java new file mode 100644 index 0000000000..d4844abd9c --- /dev/null +++ b/java-math/src/main/java/com/baeldung/algorithms/gcd/GCDImplementation.java @@ -0,0 +1,55 @@ +package com.baeldung.algorithms.gcd; + +public class GCDImplementation { + + public static int gcdByBruteForce(int n1, int n2) { + int gcd = 1; + for (int i = 1; i <= n1 && i <= n2; i++) { + if (n1 % i == 0 && n2 % i == 0) { + gcd = i; + } + } + return gcd; + } + + public static int gcdByEuclidsAlgorithm(int n1, int n2) { + if (n2 == 0) { + return n1; + } + return gcdByEuclidsAlgorithm(n2, n1 % n2); + } + + public static int gcdBySteinsAlgorithm(int n1, int n2) { + if (n1 == 0) { + return n2; + } + + if (n2 == 0) { + return n1; + } + + int n; + for (n = 0; ((n1 | n2) & 1) == 0; n++) { + n1 >>= 1; + n2 >>= 1; + } + + while ((n1 & 1) == 0) { + n1 >>= 1; + } + + do { + while ((n2 & 1) == 0) { + n2 >>= 1; + } + + if (n1 > n2) { + int temp = n1; + n1 = n2; + n2 = temp; + } + n2 = (n2 - n1); + } while (n2 != 0); + return n1 << n; + } +} diff --git a/java-math/src/test/java/com/baeldung/algorithms/gcd/GCDImplementationUnitTest.java b/java-math/src/test/java/com/baeldung/algorithms/gcd/GCDImplementationUnitTest.java new file mode 100644 index 0000000000..d2c91a2eb8 --- /dev/null +++ b/java-math/src/test/java/com/baeldung/algorithms/gcd/GCDImplementationUnitTest.java @@ -0,0 +1,32 @@ +package com.baeldung.algorithms.gcd; + +import org.junit.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +public class GCDImplementationUnitTest { + + @Test + public void whenCalculatingGCDByBruteForceMethod_thenCorrect() { + int n1 = 60; + int n2 = 90; + int gcd = GCDImplementation.gcdByBruteForce(n1, n2); + assertThat(gcd).isEqualTo(30); + } + + @Test + public void whenCalculatingGCDByEuclidsAlgorithm_thenCorrect() { + int n1 = 60; + int n2 = 90; + int gcd = GCDImplementation.gcdByEuclidsAlgorithm(n1, n2); + assertThat(gcd).isEqualTo(30); + } + + @Test + public void whenCalculatingGCDBySteinsAlgorithm_thenCorrect() { + int n1 = 60; + int n2 = 90; + int gcd = GCDImplementation.gcdBySteinsAlgorithm(n1, n2); + assertThat(gcd).isEqualTo(30); + } +} diff --git a/java-math/src/test/java/com/baeldung/algorithms/logarithm/LogarithmUnitTest.java b/java-math/src/test/java/com/baeldung/algorithms/logarithm/LogarithmUnitTest.java new file mode 100644 index 0000000000..a9a04c8d6f --- /dev/null +++ b/java-math/src/test/java/com/baeldung/algorithms/logarithm/LogarithmUnitTest.java @@ -0,0 +1,31 @@ +package com.baeldung.algorithms.logarithm; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.Test; + +public class CombinationUnitTest { + + @Test + public void givenLog10_shouldReturnValidResults() { + assertEquals(Math.log10(100), 2); + assertEquals(Math.log10(1000), 3); + } + + @Test + public void givenLog10_shouldReturnValidResults() { + assertEquals(Math.log(Math.E), 1); + assertEquals(Math.log(10), 2.30258); + } + + @Test + public void givenCustomLog_shouldReturnValidResults() { + assertEquals(customLog(2, 256), 8); + assertEquals(customLog(10, 100), 2); + } + + private static double customLog(double base, double logNumber) { + return Math.log(logNumber) / Math.log(base); + } + +} diff --git a/libraries-2/src/test/java/com/baeldung/matrices/MatrixMultiplicationBenchmarking.java b/java-math/src/test/java/com/baeldung/matrices/MatrixMultiplicationBenchmarking.java similarity index 100% rename from libraries-2/src/test/java/com/baeldung/matrices/MatrixMultiplicationBenchmarking.java rename to java-math/src/test/java/com/baeldung/matrices/MatrixMultiplicationBenchmarking.java diff --git a/libraries-2/src/test/java/com/baeldung/matrices/apache/RealMatrixUnitTest.java b/java-math/src/test/java/com/baeldung/matrices/apache/RealMatrixUnitTest.java similarity index 100% rename from libraries-2/src/test/java/com/baeldung/matrices/apache/RealMatrixUnitTest.java rename to java-math/src/test/java/com/baeldung/matrices/apache/RealMatrixUnitTest.java diff --git a/libraries-2/src/test/java/com/baeldung/matrices/colt/DoubleMatrix2DUnitTest.java b/java-math/src/test/java/com/baeldung/matrices/colt/DoubleMatrix2DUnitTest.java similarity index 100% rename from libraries-2/src/test/java/com/baeldung/matrices/colt/DoubleMatrix2DUnitTest.java rename to java-math/src/test/java/com/baeldung/matrices/colt/DoubleMatrix2DUnitTest.java diff --git a/libraries-2/src/test/java/com/baeldung/matrices/ejml/SimpleMatrixUnitTest.java b/java-math/src/test/java/com/baeldung/matrices/ejml/SimpleMatrixUnitTest.java similarity index 100% rename from libraries-2/src/test/java/com/baeldung/matrices/ejml/SimpleMatrixUnitTest.java rename to java-math/src/test/java/com/baeldung/matrices/ejml/SimpleMatrixUnitTest.java diff --git a/libraries-2/src/test/java/com/baeldung/matrices/homemade/HomemadeMatrixUnitTest.java b/java-math/src/test/java/com/baeldung/matrices/homemade/HomemadeMatrixUnitTest.java similarity index 100% rename from libraries-2/src/test/java/com/baeldung/matrices/homemade/HomemadeMatrixUnitTest.java rename to java-math/src/test/java/com/baeldung/matrices/homemade/HomemadeMatrixUnitTest.java diff --git a/libraries-2/src/test/java/com/baeldung/matrices/la4j/Basic2DMatrixUnitTest.java b/java-math/src/test/java/com/baeldung/matrices/la4j/Basic2DMatrixUnitTest.java similarity index 100% rename from libraries-2/src/test/java/com/baeldung/matrices/la4j/Basic2DMatrixUnitTest.java rename to java-math/src/test/java/com/baeldung/matrices/la4j/Basic2DMatrixUnitTest.java diff --git a/libraries-2/src/test/java/com/baeldung/matrices/nd4j/INDArrayUnitTest.java b/java-math/src/test/java/com/baeldung/matrices/nd4j/INDArrayUnitTest.java similarity index 100% rename from libraries-2/src/test/java/com/baeldung/matrices/nd4j/INDArrayUnitTest.java rename to java-math/src/test/java/com/baeldung/matrices/nd4j/INDArrayUnitTest.java diff --git a/java-numbers-2/README.md b/java-numbers-2/README.md new file mode 100644 index 0000000000..52ffc822b9 --- /dev/null +++ b/java-numbers-2/README.md @@ -0,0 +1,2 @@ +## Relevant Articles +- [Lossy Conversion in Java](https://www.baeldung.com/java-lossy-conversion) diff --git a/java-numbers-2/src/main/java/com/baeldung/binarynumbers/BinaryNumbers.java b/java-numbers-2/src/main/java/com/baeldung/binarynumbers/BinaryNumbers.java new file mode 100644 index 0000000000..62cead726f --- /dev/null +++ b/java-numbers-2/src/main/java/com/baeldung/binarynumbers/BinaryNumbers.java @@ -0,0 +1,140 @@ +package com.baeldung.binarynumbers; + +public class BinaryNumbers { + + /** + * This method takes a decimal number and convert it into a binary number. + * example:- input:10, output:1010 + * + * @param decimalNumber + * @return binary number + */ + public Integer convertDecimalToBinary(Integer decimalNumber) { + + if (decimalNumber == 0) { + return decimalNumber; + } + + StringBuilder binaryNumber = new StringBuilder(); + Integer quotient = decimalNumber; + + while (quotient > 0) { + + int remainder = quotient % 2; + binaryNumber.append(remainder); + quotient /= 2; + } + + binaryNumber = binaryNumber.reverse(); + return Integer.valueOf(binaryNumber.toString()); + } + + /** + * This method takes a binary number and convert it into a decimal number. + * example:- input:101, output:5 + * + * @param binary number + * @return decimal Number + */ + public Integer convertBinaryToDecimal(Integer binaryNumber) { + + Integer decimalNumber = 0; + Integer base = 1; + + while (binaryNumber > 0) { + + int lastDigit = binaryNumber % 10; + binaryNumber = binaryNumber / 10; + + decimalNumber += lastDigit * base; + base = base * 2; + } + return decimalNumber; + } + + /** + * This method accepts two binary numbers and returns sum of input numbers. + * Example:- firstNum: 101, secondNum: 100, output: 1001 + * + * @param firstNum + * @param secondNum + * @return addition of input numbers + */ + public Integer addBinaryNumber(Integer firstNum, Integer secondNum) { + + StringBuilder output = new StringBuilder(); + + int carry = 0; + int temp; + + while (firstNum != 0 || secondNum != 0) { + + temp = (firstNum % 10 + secondNum % 10 + carry) % 2; + output.append(temp); + + carry = (firstNum % 10 + secondNum % 10 + carry) / 2; + + firstNum = firstNum / 10; + secondNum = secondNum / 10; + } + + if (carry != 0) { + output.append(carry); + } + + return Integer.valueOf(output.reverse() + .toString()); + } + + /** + * This method takes two binary number as input and subtract second number from the first number. + * example:- firstNum: 1000, secondNum: 11, output: 101 + * @param firstNum + * @param secondNum + * @return Result of subtraction of secondNum from first + */ + public Integer substractBinaryNumber(Integer firstNum, Integer secondNum) { + + int onesComplement = Integer.valueOf(getOnesComplement(secondNum)); + StringBuilder output = new StringBuilder(); + int carry = 0; + int temp; + + while (firstNum != 0 || onesComplement != 0) { + + temp = (firstNum % 10 + onesComplement % 10 + carry) % 2; + output.append(temp); + + carry = (firstNum % 10 + onesComplement % 10 + carry) / 2; + + firstNum = firstNum / 10; + onesComplement = onesComplement / 10; + } + + String additionOfFirstNumAndOnesComplement = output.reverse() + .toString(); + + if (carry == 1) { + return addBinaryNumber(Integer.valueOf(additionOfFirstNumAndOnesComplement), carry); + } else { + return getOnesComplement(Integer.valueOf(additionOfFirstNumAndOnesComplement)); + } + } + + public Integer getOnesComplement(Integer num) { + + StringBuilder onesComplement = new StringBuilder(); + while (num > 0) { + int lastDigit = num % 10; + if (lastDigit == 0) { + onesComplement.append(1); + } else { + onesComplement.append(0); + } + num = num / 10; + } + return Integer.valueOf(onesComplement.reverse() + .toString()); + } + +} \ No newline at end of file diff --git a/java-numbers-2/src/test/java/com/baeldung/binarynumbers/BinaryNumbersUnitTest.java b/java-numbers-2/src/test/java/com/baeldung/binarynumbers/BinaryNumbersUnitTest.java new file mode 100644 index 0000000000..ca6022261d --- /dev/null +++ b/java-numbers-2/src/test/java/com/baeldung/binarynumbers/BinaryNumbersUnitTest.java @@ -0,0 +1,73 @@ +package com.baeldung.binarynumbers; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +public class BinaryNumbersUnitTest { + + private BinaryNumbers binaryNumbers = new BinaryNumbers(); + + @Test + public void given_decimalNumber_then_returnBinaryNumber() { + assertEquals(Integer.valueOf(1000), binaryNumbers.convertDecimalToBinary(8)); + assertEquals(Integer.valueOf(10100), binaryNumbers.convertDecimalToBinary(20)); + } + + @Test + public void given_decimalNumber_then_convertToBinaryNumber() { + assertEquals("1000", Integer.toBinaryString(8)); + assertEquals("10100", Integer.toBinaryString(20)); + } + + @Test + public void given_binaryNumber_then_ConvertToDecimalNumber() { + assertEquals(8, Integer.parseInt("1000", 2)); + assertEquals(20, Integer.parseInt("10100", 2)); + } + + @Test + public void given_binaryNumber_then_returnDecimalNumber() { + assertEquals(Integer.valueOf(8), binaryNumbers.convertBinaryToDecimal(1000)); + assertEquals(Integer.valueOf(20), binaryNumbers.convertBinaryToDecimal(10100)); + } + + @Test + public void given_twoBinaryNumber_then_returnAddition() { + // adding 4 and 10 + assertEquals(Integer.valueOf(1110), binaryNumbers.addBinaryNumber(100, 1010)); + + // adding 26 and 14 + assertEquals(Integer.valueOf(101000), binaryNumbers.addBinaryNumber(11010, 1110)); + } + + @Test + public void given_twoBinaryNumber_then_returnSubtraction() { + // subtracting 16 from 25 + assertEquals(Integer.valueOf(1001), binaryNumbers.substractBinaryNumber(11001, 10000)); + + // subtracting 29 from 16, the output here is negative + assertEquals(Integer.valueOf(1101), binaryNumbers.substractBinaryNumber(10000, 11101)); + } + + @Test + public void given_binaryLiteral_thenReturnDecimalValue() { + + byte five = 0b101; + assertEquals((byte) 5, five); + + short three = 0b11; + assertEquals((short) 3, three); + + int nine = 0B1001; + assertEquals(9, nine); + + long twentyNine = 0B11101; + assertEquals(29, twentyNine); + + int minusThirtySeven = -0B100101; + assertEquals(-37, minusThirtySeven); + + } + +} diff --git a/java-strings-2/README.MD b/java-strings-2/README.MD deleted file mode 100644 index c6d4f0222a..0000000000 --- a/java-strings-2/README.MD +++ /dev/null @@ -1,7 +0,0 @@ -## Relevant Articles - -- [Java Localization – Formatting Messages](https://www.baeldung.com/java-localization-messages-formatting) -- [Check If a String Contains a Substring](https://www.baeldung.com/java-string-contains-substring) -- [Removing Stopwords from a String in Java](https://www.baeldung.com/java-string-remove-stopwords) -- [Blank and Empty Strings in Java](https://www.baeldung.com/java-blank-empty-strings) -- [String Initialization in Java](https://www.baeldung.com/java-string-initialization) diff --git a/java-strings-2/README.md b/java-strings-2/README.md new file mode 100644 index 0000000000..ad0a46fd96 --- /dev/null +++ b/java-strings-2/README.md @@ -0,0 +1,26 @@ +## Relevant Articles: + +- [Java Localization – Formatting Messages](https://www.baeldung.com/java-localization-messages-formatting) +- [Check If a String Contains a Substring](https://www.baeldung.com/java-string-contains-substring) +- [Removing Stopwords from a String in Java](https://www.baeldung.com/java-string-remove-stopwords) +- [Java – Generate Random String](http://www.baeldung.com/java-random-string) +- [Image to Base64 String Conversion](http://www.baeldung.com/java-base64-image-string) +- [Java Base64 Encoding and Decoding](https://www.baeldung.com/java-base64-encode-and-decode) +- [Generate a Secure Random Password in Java](https://www.baeldung.com/java-generate-secure-password) +- [Removing Repeated Characters from a String](https://www.baeldung.com/java-remove-repeated-char) +- [Join Array of Primitives with Separator in Java](https://www.baeldung.com/java-join-primitive-array) +- [Pad a String with Zeros or Spaces in Java](https://www.baeldung.com/java-pad-string) +- [Remove Emojis from a Java String](https://www.baeldung.com/java-string-remove-emojis) +- [Convert a Comma Separated String to a List in Java](https://www.baeldung.com/java-string-with-separator-to-list) +- [Guide to java.util.Formatter](http://www.baeldung.com/java-string-formatter) +- [Remove Leading and Trailing Characters from a String](https://www.baeldung.com/java-remove-trailing-characters) +- [Concatenating Strings In Java](https://www.baeldung.com/java-strings-concatenation) +- [Java String Interview Questions and Answers](https://www.baeldung.com/java-string-interview-questions) +- [Check if a String is a Pangram in Java](https://www.baeldung.com/java-string-pangram) +- [Check If a String Contains Multiple Keywords](https://www.baeldung.com/string-contains-multiple-words) +- [Checking for Empty or Blank Strings in Java](https://www.baeldung.com/java-blank-empty-strings) +- [String Initialization in Java](https://www.baeldung.com/java-string-initialization) +- [Java Multi-line String](https://www.baeldung.com/java-multiline-string) +- [Checking If a String Is a Repeated Substring](https://www.baeldung.com/java-repeated-substring) +- [How to Reverse a String in Java](https://www.baeldung.com/java-reverse-string) +- [String toLowerCase and toUpperCase Methods in Java](https://www.baeldung.com/java-string-convert-case) diff --git a/java-strings-2/pom.xml b/java-strings-2/pom.xml index 7342953d15..be47b1ec89 100755 --- a/java-strings-2/pom.xml +++ b/java-strings-2/pom.xml @@ -40,6 +40,16 @@ commons-lang3 ${commons-lang3.version} + + commons-io + commons-io + ${commons-io.version} + + + commons-codec + commons-codec + ${commons-codec.version} + junit junit @@ -52,32 +62,54 @@ ${org.hamcrest.version} test + + org.assertj + assertj-core + ${assertj.version} + test + + + + + org.passay + passay + ${passay.version} + org.apache.commons commons-text ${commons-text.version} + + com.vdurmont + emoji-java + ${emoji-java.version} + + + org.ahocorasick + ahocorasick + ${ahocorasick.version} + javax.validation validation-api - 2.0.0.Final + ${validation-api.version} org.hibernate.validator hibernate-validator - 6.0.2.Final + ${hibernate-validator.version} javax.el javax.el-api - 3.0.0 + ${javax.el-api.version} org.glassfish.web javax.el - 2.2.6 + ${javax.el.version} - @@ -105,9 +137,19 @@ 3.8.1 + 1.10 + 1.3.1 + + 3.6.1 + 4.0.0 + 0.4.0 61.1 28.0-jre 1.4 + 2.0.0.Final + 6.0.2.Final + 3.0.0 + 2.2.6 \ No newline at end of file diff --git a/java-strings/src/main/java/com/baeldung/string/MatchWords.java b/java-strings-2/src/main/java/com/baeldung/string/MatchWords.java similarity index 100% rename from java-strings/src/main/java/com/baeldung/string/MatchWords.java rename to java-strings-2/src/main/java/com/baeldung/string/MatchWords.java diff --git a/java-strings/src/main/java/com/baeldung/string/Pangram.java b/java-strings-2/src/main/java/com/baeldung/string/Pangram.java similarity index 100% rename from java-strings/src/main/java/com/baeldung/string/Pangram.java rename to java-strings-2/src/main/java/com/baeldung/string/Pangram.java diff --git a/java-strings/src/main/java/com/baeldung/string/padding/StringPaddingUtil.java b/java-strings-2/src/main/java/com/baeldung/string/padding/StringPaddingUtil.java similarity index 100% rename from java-strings/src/main/java/com/baeldung/string/padding/StringPaddingUtil.java rename to java-strings-2/src/main/java/com/baeldung/string/padding/StringPaddingUtil.java diff --git a/java-strings/src/main/java/com/baeldung/string/password/RandomPasswordGenerator.java b/java-strings-2/src/main/java/com/baeldung/string/password/RandomPasswordGenerator.java similarity index 100% rename from java-strings/src/main/java/com/baeldung/string/password/RandomPasswordGenerator.java rename to java-strings-2/src/main/java/com/baeldung/string/password/RandomPasswordGenerator.java diff --git a/java-strings/src/main/java/com/baeldung/string/removeleadingtrailingchar/RemoveLeadingAndTrailingZeroes.java b/java-strings-2/src/main/java/com/baeldung/string/removeleadingtrailingchar/RemoveLeadingAndTrailingZeroes.java similarity index 100% rename from java-strings/src/main/java/com/baeldung/string/removeleadingtrailingchar/RemoveLeadingAndTrailingZeroes.java rename to java-strings-2/src/main/java/com/baeldung/string/removeleadingtrailingchar/RemoveLeadingAndTrailingZeroes.java diff --git a/java-strings/src/main/java/com/baeldung/stringduplicates/RemoveDuplicateFromString.java b/java-strings-2/src/main/java/com/baeldung/stringduplicates/RemoveDuplicateFromString.java similarity index 100% rename from java-strings/src/main/java/com/baeldung/stringduplicates/RemoveDuplicateFromString.java rename to java-strings-2/src/main/java/com/baeldung/stringduplicates/RemoveDuplicateFromString.java diff --git a/java-strings/src/test/java/com/baeldung/ConvertStringToListUnitTest.java b/java-strings-2/src/test/java/com/baeldung/ConvertStringToListUnitTest.java similarity index 100% rename from java-strings/src/test/java/com/baeldung/ConvertStringToListUnitTest.java rename to java-strings-2/src/test/java/com/baeldung/ConvertStringToListUnitTest.java diff --git a/java-strings/src/test/java/com/baeldung/StringConcatenationUnitTest.java b/java-strings-2/src/test/java/com/baeldung/StringConcatenationUnitTest.java similarity index 100% rename from java-strings/src/test/java/com/baeldung/StringConcatenationUnitTest.java rename to java-strings-2/src/test/java/com/baeldung/StringConcatenationUnitTest.java diff --git a/java-strings/src/test/java/com/baeldung/fileToBase64StringConversion/FileToBase64StringConversionUnitTest.java b/java-strings-2/src/test/java/com/baeldung/fileToBase64StringConversion/FileToBase64StringConversionUnitTest.java similarity index 100% rename from java-strings/src/test/java/com/baeldung/fileToBase64StringConversion/FileToBase64StringConversionUnitTest.java rename to java-strings-2/src/test/java/com/baeldung/fileToBase64StringConversion/FileToBase64StringConversionUnitTest.java diff --git a/java-strings/src/test/java/com/baeldung/java8/base64/ApacheCommonsEncodeDecodeUnitTest.java b/java-strings-2/src/test/java/com/baeldung/java8/base64/ApacheCommonsEncodeDecodeUnitTest.java similarity index 100% rename from java-strings/src/test/java/com/baeldung/java8/base64/ApacheCommonsEncodeDecodeUnitTest.java rename to java-strings-2/src/test/java/com/baeldung/java8/base64/ApacheCommonsEncodeDecodeUnitTest.java diff --git a/java-strings/src/test/java/com/baeldung/java8/base64/Java8EncodeDecodeUnitTest.java b/java-strings-2/src/test/java/com/baeldung/java8/base64/Java8EncodeDecodeUnitTest.java similarity index 100% rename from java-strings/src/test/java/com/baeldung/java8/base64/Java8EncodeDecodeUnitTest.java rename to java-strings-2/src/test/java/com/baeldung/java8/base64/Java8EncodeDecodeUnitTest.java diff --git a/java-strings/src/test/java/com/baeldung/java8/base64/StringToByteArrayUnitTest.java b/java-strings-2/src/test/java/com/baeldung/java8/base64/StringToByteArrayUnitTest.java similarity index 100% rename from java-strings/src/test/java/com/baeldung/java8/base64/StringToByteArrayUnitTest.java rename to java-strings-2/src/test/java/com/baeldung/java8/base64/StringToByteArrayUnitTest.java diff --git a/java-strings/src/test/java/com/baeldung/string/MatchWordsUnitTest.java b/java-strings-2/src/test/java/com/baeldung/string/MatchWordsUnitTest.java similarity index 100% rename from java-strings/src/test/java/com/baeldung/string/MatchWordsUnitTest.java rename to java-strings-2/src/test/java/com/baeldung/string/MatchWordsUnitTest.java diff --git a/java-strings/src/test/java/com/baeldung/string/PangramUnitTest.java b/java-strings-2/src/test/java/com/baeldung/string/PangramUnitTest.java similarity index 100% rename from java-strings/src/test/java/com/baeldung/string/PangramUnitTest.java rename to java-strings-2/src/test/java/com/baeldung/string/PangramUnitTest.java diff --git a/java-strings/src/test/java/com/baeldung/string/RemovingEmojiFromStringUnitTest.java b/java-strings-2/src/test/java/com/baeldung/string/RemovingEmojiFromStringUnitTest.java similarity index 100% rename from java-strings/src/test/java/com/baeldung/string/RemovingEmojiFromStringUnitTest.java rename to java-strings-2/src/test/java/com/baeldung/string/RemovingEmojiFromStringUnitTest.java diff --git a/java-strings/src/test/java/com/baeldung/string/StringFromPrimitiveArrayUnitTest.java b/java-strings-2/src/test/java/com/baeldung/string/StringFromPrimitiveArrayUnitTest.java similarity index 100% rename from java-strings/src/test/java/com/baeldung/string/StringFromPrimitiveArrayUnitTest.java rename to java-strings-2/src/test/java/com/baeldung/string/StringFromPrimitiveArrayUnitTest.java diff --git a/java-strings-2/src/test/java/com/baeldung/string/changecase/ToLowerCaseUnitTest.java b/java-strings-2/src/test/java/com/baeldung/string/changecase/ToLowerCaseUnitTest.java new file mode 100644 index 0000000000..c395b61068 --- /dev/null +++ b/java-strings-2/src/test/java/com/baeldung/string/changecase/ToLowerCaseUnitTest.java @@ -0,0 +1,29 @@ +package com.baeldung.string.changecase; + +import static org.junit.Assert.assertEquals; + +import java.util.Locale; + +import org.junit.Test; + +public class ToLowerCaseUnitTest { + + private static final Locale TURKISH = new Locale("tr"); + private String name = "John Doe"; + private String foreignUppercase = "\u0049"; + + @Test + public void givenMixedCaseString_WhenToLowerCase_ThenResultIsLowerCase() { + assertEquals("john doe", name.toLowerCase()); + } + + @Test + public void givenForeignString_WhenToLowerCaseWithoutLocale_ThenResultIsLowerCase() { + assertEquals("\u0069", foreignUppercase.toLowerCase()); + } + + @Test + public void givenForeignString_WhenToLowerCaseWithLocale_ThenResultIsLowerCase() { + assertEquals("\u0131", foreignUppercase.toLowerCase(TURKISH)); + } +} diff --git a/java-strings-2/src/test/java/com/baeldung/string/changecase/ToUpperCaseUnitTest.java b/java-strings-2/src/test/java/com/baeldung/string/changecase/ToUpperCaseUnitTest.java new file mode 100644 index 0000000000..1807f854b2 --- /dev/null +++ b/java-strings-2/src/test/java/com/baeldung/string/changecase/ToUpperCaseUnitTest.java @@ -0,0 +1,29 @@ +package com.baeldung.string.changecase; + +import static org.junit.Assert.assertEquals; + +import java.util.Locale; + +import org.junit.Test; + +public class ToUpperCaseUnitTest { + + private static final Locale TURKISH = new Locale("tr"); + private String name = "John Doe"; + private String foreignLowercase = "\u0069"; + + @Test + public void givenMixedCaseString_WhenToUpperCase_ThenResultIsUpperCase() { + assertEquals("JOHN DOE", name.toUpperCase()); + } + + @Test + public void givenForeignString_WhenToUpperCaseWithoutLocale_ThenResultIsUpperCase() { + assertEquals("\u0049", foreignLowercase.toUpperCase()); + } + + @Test + public void givenForeignString_WhenToUpperCaseWithLocale_ThenResultIsUpperCase() { + assertEquals("\u0130", foreignLowercase.toUpperCase(TURKISH)); + } +} diff --git a/java-strings/src/test/java/com/baeldung/string/formatter/DateToStringFormatterUnitTest.java b/java-strings-2/src/test/java/com/baeldung/string/formatter/DateToStringFormatterUnitTest.java similarity index 100% rename from java-strings/src/test/java/com/baeldung/string/formatter/DateToStringFormatterUnitTest.java rename to java-strings-2/src/test/java/com/baeldung/string/formatter/DateToStringFormatterUnitTest.java diff --git a/java-strings/src/test/java/com/baeldung/string/formatter/StringFormatterExampleUnitTest.java b/java-strings-2/src/test/java/com/baeldung/string/formatter/StringFormatterExampleUnitTest.java similarity index 100% rename from java-strings/src/test/java/com/baeldung/string/formatter/StringFormatterExampleUnitTest.java rename to java-strings-2/src/test/java/com/baeldung/string/formatter/StringFormatterExampleUnitTest.java diff --git a/java-strings/src/test/java/com/baeldung/string/interview/LocaleUnitTest.java b/java-strings-2/src/test/java/com/baeldung/string/interview/LocaleUnitTest.java similarity index 100% rename from java-strings/src/test/java/com/baeldung/string/interview/LocaleUnitTest.java rename to java-strings-2/src/test/java/com/baeldung/string/interview/LocaleUnitTest.java diff --git a/java-strings/src/test/java/com/baeldung/string/interview/StringAnagramUnitTest.java b/java-strings-2/src/test/java/com/baeldung/string/interview/StringAnagramUnitTest.java similarity index 100% rename from java-strings/src/test/java/com/baeldung/string/interview/StringAnagramUnitTest.java rename to java-strings-2/src/test/java/com/baeldung/string/interview/StringAnagramUnitTest.java diff --git a/java-strings/src/test/java/com/baeldung/string/interview/StringChangeCaseUnitTest.java b/java-strings-2/src/test/java/com/baeldung/string/interview/StringChangeCaseUnitTest.java similarity index 100% rename from java-strings/src/test/java/com/baeldung/string/interview/StringChangeCaseUnitTest.java rename to java-strings-2/src/test/java/com/baeldung/string/interview/StringChangeCaseUnitTest.java diff --git a/java-strings/src/test/java/com/baeldung/string/interview/StringCountOccurrencesUnitTest.java b/java-strings-2/src/test/java/com/baeldung/string/interview/StringCountOccurrencesUnitTest.java similarity index 100% rename from java-strings/src/test/java/com/baeldung/string/interview/StringCountOccurrencesUnitTest.java rename to java-strings-2/src/test/java/com/baeldung/string/interview/StringCountOccurrencesUnitTest.java diff --git a/java-strings/src/test/java/com/baeldung/string/interview/StringFormatUnitTest.java b/java-strings-2/src/test/java/com/baeldung/string/interview/StringFormatUnitTest.java similarity index 100% rename from java-strings/src/test/java/com/baeldung/string/interview/StringFormatUnitTest.java rename to java-strings-2/src/test/java/com/baeldung/string/interview/StringFormatUnitTest.java diff --git a/java-strings/src/test/java/com/baeldung/string/interview/StringInternUnitTest.java b/java-strings-2/src/test/java/com/baeldung/string/interview/StringInternUnitTest.java similarity index 100% rename from java-strings/src/test/java/com/baeldung/string/interview/StringInternUnitTest.java rename to java-strings-2/src/test/java/com/baeldung/string/interview/StringInternUnitTest.java diff --git a/java-strings/src/test/java/com/baeldung/string/interview/StringJoinerUnitTest.java b/java-strings-2/src/test/java/com/baeldung/string/interview/StringJoinerUnitTest.java similarity index 100% rename from java-strings/src/test/java/com/baeldung/string/interview/StringJoinerUnitTest.java rename to java-strings-2/src/test/java/com/baeldung/string/interview/StringJoinerUnitTest.java diff --git a/java-strings/src/test/java/com/baeldung/string/interview/StringPalindromeUnitTest.java b/java-strings-2/src/test/java/com/baeldung/string/interview/StringPalindromeUnitTest.java similarity index 100% rename from java-strings/src/test/java/com/baeldung/string/interview/StringPalindromeUnitTest.java rename to java-strings-2/src/test/java/com/baeldung/string/interview/StringPalindromeUnitTest.java diff --git a/java-strings/src/test/java/com/baeldung/string/interview/StringReverseUnitTest.java b/java-strings-2/src/test/java/com/baeldung/string/interview/StringReverseUnitTest.java similarity index 100% rename from java-strings/src/test/java/com/baeldung/string/interview/StringReverseUnitTest.java rename to java-strings-2/src/test/java/com/baeldung/string/interview/StringReverseUnitTest.java diff --git a/java-strings/src/test/java/com/baeldung/string/interview/StringSplitUnitTest.java b/java-strings-2/src/test/java/com/baeldung/string/interview/StringSplitUnitTest.java similarity index 100% rename from java-strings/src/test/java/com/baeldung/string/interview/StringSplitUnitTest.java rename to java-strings-2/src/test/java/com/baeldung/string/interview/StringSplitUnitTest.java diff --git a/java-strings/src/test/java/com/baeldung/string/interview/StringToByteArrayUnitTest.java b/java-strings-2/src/test/java/com/baeldung/string/interview/StringToByteArrayUnitTest.java similarity index 100% rename from java-strings/src/test/java/com/baeldung/string/interview/StringToByteArrayUnitTest.java rename to java-strings-2/src/test/java/com/baeldung/string/interview/StringToByteArrayUnitTest.java diff --git a/java-strings/src/test/java/com/baeldung/string/interview/StringToCharArrayUnitTest.java b/java-strings-2/src/test/java/com/baeldung/string/interview/StringToCharArrayUnitTest.java similarity index 100% rename from java-strings/src/test/java/com/baeldung/string/interview/StringToCharArrayUnitTest.java rename to java-strings-2/src/test/java/com/baeldung/string/interview/StringToCharArrayUnitTest.java diff --git a/java-strings/src/test/java/com/baeldung/string/interview/StringToIntegerUnitTest.java b/java-strings-2/src/test/java/com/baeldung/string/interview/StringToIntegerUnitTest.java similarity index 100% rename from java-strings/src/test/java/com/baeldung/string/interview/StringToIntegerUnitTest.java rename to java-strings-2/src/test/java/com/baeldung/string/interview/StringToIntegerUnitTest.java diff --git a/java-strings/src/test/java/com/baeldung/string/padding/StringPaddingUtilUnitTest.java b/java-strings-2/src/test/java/com/baeldung/string/padding/StringPaddingUtilUnitTest.java similarity index 100% rename from java-strings/src/test/java/com/baeldung/string/padding/StringPaddingUtilUnitTest.java rename to java-strings-2/src/test/java/com/baeldung/string/padding/StringPaddingUtilUnitTest.java diff --git a/java-strings/src/test/java/com/baeldung/string/password/StringPasswordUnitTest.java b/java-strings-2/src/test/java/com/baeldung/string/password/StringPasswordUnitTest.java similarity index 100% rename from java-strings/src/test/java/com/baeldung/string/password/StringPasswordUnitTest.java rename to java-strings-2/src/test/java/com/baeldung/string/password/StringPasswordUnitTest.java diff --git a/java-strings/src/test/java/com/baeldung/string/removeleadingtrailingchar/RemoveLeadingAndTrailingZeroesUnitTest.java b/java-strings-2/src/test/java/com/baeldung/string/removeleadingtrailingchar/RemoveLeadingAndTrailingZeroesUnitTest.java similarity index 100% rename from java-strings/src/test/java/com/baeldung/string/removeleadingtrailingchar/RemoveLeadingAndTrailingZeroesUnitTest.java rename to java-strings-2/src/test/java/com/baeldung/string/removeleadingtrailingchar/RemoveLeadingAndTrailingZeroesUnitTest.java diff --git a/java-strings/src/test/java/com/baeldung/stringduplicates/RemoveDuplicateFromStringUnitTest.java b/java-strings-2/src/test/java/com/baeldung/stringduplicates/RemoveDuplicateFromStringUnitTest.java similarity index 100% rename from java-strings/src/test/java/com/baeldung/stringduplicates/RemoveDuplicateFromStringUnitTest.java rename to java-strings-2/src/test/java/com/baeldung/stringduplicates/RemoveDuplicateFromStringUnitTest.java diff --git a/java-strings/src/test/resources/test_image.jpg b/java-strings-2/src/test/resources/test_image.jpg similarity index 100% rename from java-strings/src/test/resources/test_image.jpg rename to java-strings-2/src/test/resources/test_image.jpg diff --git a/java-strings-3/README.md b/java-strings-3/README.md new file mode 100644 index 0000000000..6c2339028f --- /dev/null +++ b/java-strings-3/README.md @@ -0,0 +1,3 @@ +## Relevant Articles: + +- [Converting Java String to Double](https://www.baeldung.com/java-string-to-double) diff --git a/java-strings-3/pom.xml b/java-strings-3/pom.xml new file mode 100644 index 0000000000..1e5f757943 --- /dev/null +++ b/java-strings-3/pom.xml @@ -0,0 +1,155 @@ + + 4.0.0 + java-strings-3 + 0.1.0-SNAPSHOT + jar + java-strings-3 + + + com.baeldung + parent-java + 0.0.1-SNAPSHOT + ../parent-java + + + + + org.openjdk.jmh + jmh-core + ${jmh-core.version} + + + org.openjdk.jmh + jmh-generator-annprocess + ${jmh-core.version} + + + com.ibm.icu + icu4j + ${icu4j.version} + + + com.google.guava + guava + ${guava.version} + + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + + + commons-io + commons-io + ${commons-io.version} + + + commons-codec + commons-codec + ${commons-codec.version} + + + junit + junit + ${junit.version} + test + + + org.hamcrest + hamcrest-library + ${org.hamcrest.version} + test + + + org.assertj + assertj-core + ${assertj.version} + test + + + + + org.passay + passay + ${passay.version} + + + org.apache.commons + commons-text + ${commons-text.version} + + + com.vdurmont + emoji-java + ${emoji-java.version} + + + org.ahocorasick + ahocorasick + ${ahocorasick.version} + + + javax.validation + validation-api + ${validation-api.version} + + + org.hibernate.validator + hibernate-validator + ${hibernate-validator.version} + + + javax.el + javax.el-api + ${javax.el-api.version} + + + org.glassfish.web + javax.el + ${javax.el.version} + + + + + java-strings-3 + + + src/main/resources + true + + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + ${java.version} + ${java.version} + -parameters + + + + + + + 3.8.1 + 1.10 + 1.3.1 + + 3.6.1 + 4.0.0 + 0.4.0 + 61.1 + 28.0-jre + 1.4 + 2.0.0.Final + 6.0.2.Final + 3.0.0 + 2.2.6 + + + \ No newline at end of file diff --git a/java-strings-3/src/main/java/com/baeldung/string/README.md b/java-strings-3/src/main/java/com/baeldung/string/README.md new file mode 100644 index 0000000000..e02980e93f --- /dev/null +++ b/java-strings-3/src/main/java/com/baeldung/string/README.md @@ -0,0 +1,3 @@ +This file exists to ensure this empty directory is committed in Git. + +Please remove this file when this directory is populated. \ No newline at end of file diff --git a/spring-security-mvc-session/.gitignore b/java-strings-3/src/main/resources/.gitignore similarity index 100% rename from spring-security-mvc-session/.gitignore rename to java-strings-3/src/main/resources/.gitignore diff --git a/java-strings-3/src/test/java/com/baeldung/string/equalsIgnoreCase/StringEqualsIgnoreCaseUnitTest.java b/java-strings-3/src/test/java/com/baeldung/string/equalsIgnoreCase/StringEqualsIgnoreCaseUnitTest.java new file mode 100644 index 0000000000..5aab63db94 --- /dev/null +++ b/java-strings-3/src/test/java/com/baeldung/string/equalsIgnoreCase/StringEqualsIgnoreCaseUnitTest.java @@ -0,0 +1,26 @@ +package com.baeldung.string.equalsIgnoreCase; + +import org.apache.commons.lang3.StringUtils; +import org.junit.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +public class StringEqualsIgnoreCaseUnitTest { + private String string1 = "equals ignore case"; + private String string2 = "EQUALS IGNORE CASE"; + + @Test + public void givenEqualStringsWithDifferentCase_whenUsingEqualsIgnoreCase_ThenTheyAreEqual() { + assertThat(string1.equalsIgnoreCase(string2)).isTrue(); + } + + @Test + public void givenEqualStringsWithDifferentCase_whenUsingApacheCommonsEqualsIgnoreCase_ThenTheyAreEqual() { + assertThat(StringUtils.equalsIgnoreCase(string1, string2)).isTrue(); + } + + @Test + public void givenAStringAndNullValue_whenUsingApacheCommonsEqualsIgnoreCase_ThenTheyAreNotEqual() { + assertThat(StringUtils.equalsIgnoreCase(string1, null)).isFalse(); + } +} diff --git a/java-strings-3/src/test/java/com/baeldung/string/todouble/StringToDoubleConversionUnitTest.java b/java-strings-3/src/test/java/com/baeldung/string/todouble/StringToDoubleConversionUnitTest.java new file mode 100644 index 0000000000..2c87af53f8 --- /dev/null +++ b/java-strings-3/src/test/java/com/baeldung/string/todouble/StringToDoubleConversionUnitTest.java @@ -0,0 +1,56 @@ +package com.baeldung.string.todouble; + +import static org.junit.Assert.assertEquals; + +import java.text.DecimalFormat; +import java.text.ParseException; + +import org.junit.Test; + +public class StringToDoubleConversionUnitTest { + + @Test + public void givenValidString_WhenParseDouble_ThenResultIsPrimitiveDouble() { + assertEquals(1.23, Double.parseDouble("1.23"), 0.000001); + } + + @Test(expected = NullPointerException.class) + public void givenNullString_WhenParseDouble_ThenNullPointerExceptionIsThrown() { + Double.parseDouble(null); + } + + @Test(expected = NumberFormatException.class) + public void givenInalidString_WhenParseDouble_ThenNumberFormatExceptionIsThrown() { + Double.parseDouble("&"); + } + + @Test + public void givenValidString_WhenValueOf_ThenResultIsPrimitiveDouble() { + assertEquals(1.23, Double.valueOf("1.23"), 0.000001); + } + + @Test(expected = NullPointerException.class) + public void givenNullString_WhenValueOf_ThenNullPointerExceptionIsThrown() { + Double.valueOf(null); + } + + @Test(expected = NumberFormatException.class) + public void givenInalidString_WhenValueOf_ThenNumberFormatExceptionIsThrown() { + Double.valueOf("&"); + } + + @Test + public void givenValidString_WhenDecimalFormat_ThenResultIsValidDouble() throws ParseException { + assertEquals(1.23, new DecimalFormat("#").parse("1.23").doubleValue(), 0.000001); + } + + @Test(expected = NullPointerException.class) + public void givenNullString_WhenDecimalFormat_ThenNullPointerExceptionIsThrown() throws ParseException { + new DecimalFormat("#").parse(null); + } + + @Test(expected = ParseException.class) + public void givenInvalidString_WhenDecimalFormat_ThenParseExceptionIsThrown() throws ParseException { + new DecimalFormat("#").parse("&"); + } +} diff --git a/spring-security-mvc-session/src/test/resources/.gitignore b/java-strings-3/src/test/resources/.gitignore similarity index 100% rename from spring-security-mvc-session/src/test/resources/.gitignore rename to java-strings-3/src/test/resources/.gitignore diff --git a/java-strings-ops/README.md b/java-strings-ops/README.md new file mode 100644 index 0000000000..d909f171a7 --- /dev/null +++ b/java-strings-ops/README.md @@ -0,0 +1,22 @@ +========= + +## Java Strings Cookbooks and Examples + +### Relevant Articles: +- [Convert char to String in Java](http://www.baeldung.com/java-convert-char-to-string) +- [Convert String to int or Integer in Java](http://www.baeldung.com/java-convert-string-to-int-or-integer) +- [Java String Conversions](https://www.baeldung.com/java-string-conversions) +- [Check if a String is a Palindrome](http://www.baeldung.com/java-palindrome) +- [Comparing Strings in Java](http://www.baeldung.com/java-compare-strings) +- [Check If a String Is Numeric in Java](http://www.baeldung.com/java-check-string-number) +- [Get Substring from String in Java](https://www.baeldung.com/java-substring) +- [How to Remove the Last Character of a String?](http://www.baeldung.com/java-remove-last-character-of-string) +- [Add a Character to a String at a Given Position](https://www.baeldung.com/java-add-character-to-string) +- [Count Occurrences of a Char in a String](http://www.baeldung.com/java-count-chars) +- [Guide to Java String Pool](http://www.baeldung.com/java-string-pool) +- [Split a String in Java](http://www.baeldung.com/java-split-string) +- [Common String Operations in Java](https://www.baeldung.com/java-string-operations) +- [Convert String to Byte Array and Reverse in Java](https://www.baeldung.com/java-string-to-byte-array) +- [Java toString() Method](https://www.baeldung.com/java-tostring) +- [CharSequence vs. String in Java](http://www.baeldung.com/java-char-sequence-string) +- [StringBuilder and StringBuffer in Java](http://www.baeldung.com/java-string-builder-string-buffer) \ No newline at end of file diff --git a/java-strings-ops/pom.xml b/java-strings-ops/pom.xml new file mode 100644 index 0000000000..b6a7ea2728 --- /dev/null +++ b/java-strings-ops/pom.xml @@ -0,0 +1,99 @@ + + 4.0.0 + com.baeldung + java-strings-ops + 0.1.0-SNAPSHOT + jar + java-strings-ops + + + com.baeldung + parent-java + 0.0.1-SNAPSHOT + ../parent-java + + + + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + + + log4j + log4j + ${log4j.version} + + + + org.assertj + assertj-core + ${assertj.version} + test + + + org.openjdk.jmh + jmh-core + ${jmh-core.version} + + + org.openjdk.jmh + jmh-generator-annprocess + ${jmh-generator.version} + + + com.google.guava + guava + ${guava.version} + + + + org.junit.jupiter + junit-jupiter-api + ${junit-jupiter-api.version} + test + + + + org.hamcrest + hamcrest-library + ${org.hamcrest.version} + test + + + + + + java-strings-ops + + + src/main/resources + true + + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + ${java.version} + ${java.version} + -parameters + + + + + + + + 3.8.1 + + 3.6.1 + 27.0.1-jre + 5.3.1 + + + diff --git a/java-strings/src/main/java/com/baeldung/datetime/UseLocalDateTime.java b/java-strings-ops/src/main/java/com/baeldung/datetime/UseLocalDateTime.java similarity index 100% rename from java-strings/src/main/java/com/baeldung/datetime/UseLocalDateTime.java rename to java-strings-ops/src/main/java/com/baeldung/datetime/UseLocalDateTime.java diff --git a/java-strings/src/main/java/com/baeldung/string/AppendCharAtPositionX.java b/java-strings-ops/src/main/java/com/baeldung/string/AppendCharAtPositionX.java similarity index 100% rename from java-strings/src/main/java/com/baeldung/string/AppendCharAtPositionX.java rename to java-strings-ops/src/main/java/com/baeldung/string/AppendCharAtPositionX.java diff --git a/java-strings/src/main/java/com/baeldung/string/Palindrome.java b/java-strings-ops/src/main/java/com/baeldung/string/Palindrome.java similarity index 100% rename from java-strings/src/main/java/com/baeldung/string/Palindrome.java rename to java-strings-ops/src/main/java/com/baeldung/string/Palindrome.java diff --git a/java-strings/src/main/java/com/baeldung/string/StringHelper.java b/java-strings-ops/src/main/java/com/baeldung/string/StringHelper.java similarity index 100% rename from java-strings/src/main/java/com/baeldung/string/StringHelper.java rename to java-strings-ops/src/main/java/com/baeldung/string/StringHelper.java diff --git a/java-strings/src/main/java/com/baeldung/string/tostring/Customer.java b/java-strings-ops/src/main/java/com/baeldung/string/tostring/Customer.java similarity index 100% rename from java-strings/src/main/java/com/baeldung/string/tostring/Customer.java rename to java-strings-ops/src/main/java/com/baeldung/string/tostring/Customer.java diff --git a/java-strings/src/main/java/com/baeldung/string/tostring/CustomerArrayToString.java b/java-strings-ops/src/main/java/com/baeldung/string/tostring/CustomerArrayToString.java similarity index 100% rename from java-strings/src/main/java/com/baeldung/string/tostring/CustomerArrayToString.java rename to java-strings-ops/src/main/java/com/baeldung/string/tostring/CustomerArrayToString.java diff --git a/java-strings/src/main/java/com/baeldung/string/tostring/CustomerComplexObjectToString.java b/java-strings-ops/src/main/java/com/baeldung/string/tostring/CustomerComplexObjectToString.java similarity index 100% rename from java-strings/src/main/java/com/baeldung/string/tostring/CustomerComplexObjectToString.java rename to java-strings-ops/src/main/java/com/baeldung/string/tostring/CustomerComplexObjectToString.java diff --git a/java-strings/src/main/java/com/baeldung/string/tostring/CustomerPrimitiveToString.java b/java-strings-ops/src/main/java/com/baeldung/string/tostring/CustomerPrimitiveToString.java similarity index 100% rename from java-strings/src/main/java/com/baeldung/string/tostring/CustomerPrimitiveToString.java rename to java-strings-ops/src/main/java/com/baeldung/string/tostring/CustomerPrimitiveToString.java diff --git a/java-strings/src/main/java/com/baeldung/string/tostring/CustomerReflectionToString.java b/java-strings-ops/src/main/java/com/baeldung/string/tostring/CustomerReflectionToString.java similarity index 100% rename from java-strings/src/main/java/com/baeldung/string/tostring/CustomerReflectionToString.java rename to java-strings-ops/src/main/java/com/baeldung/string/tostring/CustomerReflectionToString.java diff --git a/java-strings/src/main/java/com/baeldung/string/tostring/CustomerWrapperCollectionToString.java b/java-strings-ops/src/main/java/com/baeldung/string/tostring/CustomerWrapperCollectionToString.java similarity index 100% rename from java-strings/src/main/java/com/baeldung/string/tostring/CustomerWrapperCollectionToString.java rename to java-strings-ops/src/main/java/com/baeldung/string/tostring/CustomerWrapperCollectionToString.java diff --git a/java-strings/src/main/java/com/baeldung/string/tostring/Order.java b/java-strings-ops/src/main/java/com/baeldung/string/tostring/Order.java similarity index 100% rename from java-strings/src/main/java/com/baeldung/string/tostring/Order.java rename to java-strings-ops/src/main/java/com/baeldung/string/tostring/Order.java diff --git a/JGit/src/main/resources/logback.xml b/java-strings-ops/src/main/resources/logback.xml similarity index 100% rename from JGit/src/main/resources/logback.xml rename to java-strings-ops/src/main/resources/logback.xml diff --git a/java-strings/src/test/java/com/baeldung/CharToStringUnitTest.java b/java-strings-ops/src/test/java/com/baeldung/CharToStringUnitTest.java similarity index 100% rename from java-strings/src/test/java/com/baeldung/CharToStringUnitTest.java rename to java-strings-ops/src/test/java/com/baeldung/CharToStringUnitTest.java diff --git a/java-strings/src/test/java/com/baeldung/java/conversion/README.md b/java-strings-ops/src/test/java/com/baeldung/java/conversion/README.md similarity index 100% rename from java-strings/src/test/java/com/baeldung/java/conversion/README.md rename to java-strings-ops/src/test/java/com/baeldung/java/conversion/README.md diff --git a/java-strings/src/test/java/com/baeldung/java/conversion/StringConversionUnitTest.java b/java-strings-ops/src/test/java/com/baeldung/java/conversion/StringConversionUnitTest.java similarity index 100% rename from java-strings/src/test/java/com/baeldung/java/conversion/StringConversionUnitTest.java rename to java-strings-ops/src/test/java/com/baeldung/java/conversion/StringConversionUnitTest.java diff --git a/java-strings/src/test/java/com/baeldung/java/countingChars/CountCharsExampleUnitTest.java b/java-strings-ops/src/test/java/com/baeldung/java/countingChars/CountCharsExampleUnitTest.java similarity index 100% rename from java-strings/src/test/java/com/baeldung/java/countingChars/CountCharsExampleUnitTest.java rename to java-strings-ops/src/test/java/com/baeldung/java/countingChars/CountCharsExampleUnitTest.java diff --git a/java-strings/src/test/java/com/baeldung/string/AppendCharAtPositionXUnitTest.java b/java-strings-ops/src/test/java/com/baeldung/string/AppendCharAtPositionXUnitTest.java similarity index 100% rename from java-strings/src/test/java/com/baeldung/string/AppendCharAtPositionXUnitTest.java rename to java-strings-ops/src/test/java/com/baeldung/string/AppendCharAtPositionXUnitTest.java diff --git a/java-strings/src/test/java/com/baeldung/string/CharSequenceVsStringUnitTest.java b/java-strings-ops/src/test/java/com/baeldung/string/CharSequenceVsStringUnitTest.java similarity index 100% rename from java-strings/src/test/java/com/baeldung/string/CharSequenceVsStringUnitTest.java rename to java-strings-ops/src/test/java/com/baeldung/string/CharSequenceVsStringUnitTest.java diff --git a/java-strings/src/test/java/com/baeldung/string/PalindromeUnitTest.java b/java-strings-ops/src/test/java/com/baeldung/string/PalindromeUnitTest.java similarity index 100% rename from java-strings/src/test/java/com/baeldung/string/PalindromeUnitTest.java rename to java-strings-ops/src/test/java/com/baeldung/string/PalindromeUnitTest.java diff --git a/java-strings/src/test/java/com/baeldung/string/SplitUnitTest.java b/java-strings-ops/src/test/java/com/baeldung/string/SplitUnitTest.java similarity index 100% rename from java-strings/src/test/java/com/baeldung/string/SplitUnitTest.java rename to java-strings-ops/src/test/java/com/baeldung/string/SplitUnitTest.java diff --git a/java-strings/src/main/java/com/baeldung/string/StringBufferStringBuilder.java b/java-strings-ops/src/test/java/com/baeldung/string/StringBufferStringBuilder.java similarity index 100% rename from java-strings/src/main/java/com/baeldung/string/StringBufferStringBuilder.java rename to java-strings-ops/src/test/java/com/baeldung/string/StringBufferStringBuilder.java diff --git a/java-strings/src/test/java/com/baeldung/string/StringComparisonUnitTest.java b/java-strings-ops/src/test/java/com/baeldung/string/StringComparisonUnitTest.java similarity index 100% rename from java-strings/src/test/java/com/baeldung/string/StringComparisonUnitTest.java rename to java-strings-ops/src/test/java/com/baeldung/string/StringComparisonUnitTest.java diff --git a/java-strings/src/test/java/com/baeldung/string/StringHelperUnitTest.java b/java-strings-ops/src/test/java/com/baeldung/string/StringHelperUnitTest.java similarity index 100% rename from java-strings/src/test/java/com/baeldung/string/StringHelperUnitTest.java rename to java-strings-ops/src/test/java/com/baeldung/string/StringHelperUnitTest.java diff --git a/java-strings/src/test/java/com/baeldung/string/SubstringUnitTest.java b/java-strings-ops/src/test/java/com/baeldung/string/SubstringUnitTest.java similarity index 100% rename from java-strings/src/test/java/com/baeldung/string/SubstringUnitTest.java rename to java-strings-ops/src/test/java/com/baeldung/string/SubstringUnitTest.java diff --git a/java-strings/src/test/java/com/baeldung/string/conversion/ByteArrayToStringUnitTest.java b/java-strings-ops/src/test/java/com/baeldung/string/conversion/ByteArrayToStringUnitTest.java similarity index 100% rename from java-strings/src/test/java/com/baeldung/string/conversion/ByteArrayToStringUnitTest.java rename to java-strings-ops/src/test/java/com/baeldung/string/conversion/ByteArrayToStringUnitTest.java diff --git a/java-strings/src/test/java/com/baeldung/string/conversion/StringToByteArrayUnitTest.java b/java-strings-ops/src/test/java/com/baeldung/string/conversion/StringToByteArrayUnitTest.java similarity index 100% rename from java-strings/src/test/java/com/baeldung/string/conversion/StringToByteArrayUnitTest.java rename to java-strings-ops/src/test/java/com/baeldung/string/conversion/StringToByteArrayUnitTest.java diff --git a/java-strings/src/test/java/com/baeldung/string/tostring/CustomerArrayToStringUnitTest.java b/java-strings-ops/src/test/java/com/baeldung/string/tostring/CustomerArrayToStringUnitTest.java similarity index 100% rename from java-strings/src/test/java/com/baeldung/string/tostring/CustomerArrayToStringUnitTest.java rename to java-strings-ops/src/test/java/com/baeldung/string/tostring/CustomerArrayToStringUnitTest.java diff --git a/java-strings/src/test/java/com/baeldung/string/tostring/CustomerComplexObjectToStringUnitTest.java b/java-strings-ops/src/test/java/com/baeldung/string/tostring/CustomerComplexObjectToStringUnitTest.java similarity index 100% rename from java-strings/src/test/java/com/baeldung/string/tostring/CustomerComplexObjectToStringUnitTest.java rename to java-strings-ops/src/test/java/com/baeldung/string/tostring/CustomerComplexObjectToStringUnitTest.java diff --git a/java-strings/src/test/java/com/baeldung/string/tostring/CustomerPrimitiveToStringUnitTest.java b/java-strings-ops/src/test/java/com/baeldung/string/tostring/CustomerPrimitiveToStringUnitTest.java similarity index 100% rename from java-strings/src/test/java/com/baeldung/string/tostring/CustomerPrimitiveToStringUnitTest.java rename to java-strings-ops/src/test/java/com/baeldung/string/tostring/CustomerPrimitiveToStringUnitTest.java diff --git a/java-strings/src/test/java/com/baeldung/string/tostring/CustomerWrapperCollectionToStringUnitTest.java b/java-strings-ops/src/test/java/com/baeldung/string/tostring/CustomerWrapperCollectionToStringUnitTest.java similarity index 100% rename from java-strings/src/test/java/com/baeldung/string/tostring/CustomerWrapperCollectionToStringUnitTest.java rename to java-strings-ops/src/test/java/com/baeldung/string/tostring/CustomerWrapperCollectionToStringUnitTest.java diff --git a/java-strings/src/test/java/com/baeldung/stringisnumeric/CoreJavaIsNumericUnitTest.java b/java-strings-ops/src/test/java/com/baeldung/stringisnumeric/CoreJavaIsNumericUnitTest.java similarity index 100% rename from java-strings/src/test/java/com/baeldung/stringisnumeric/CoreJavaIsNumericUnitTest.java rename to java-strings-ops/src/test/java/com/baeldung/stringisnumeric/CoreJavaIsNumericUnitTest.java diff --git a/java-strings/src/test/java/com/baeldung/stringpool/StringPoolUnitTest.java b/java-strings-ops/src/test/java/com/baeldung/stringpool/StringPoolUnitTest.java similarity index 100% rename from java-strings/src/test/java/com/baeldung/stringpool/StringPoolUnitTest.java rename to java-strings-ops/src/test/java/com/baeldung/stringpool/StringPoolUnitTest.java diff --git a/java-strings-ops/src/test/resources/.gitignore b/java-strings-ops/src/test/resources/.gitignore new file mode 100644 index 0000000000..83c05e60c8 --- /dev/null +++ b/java-strings-ops/src/test/resources/.gitignore @@ -0,0 +1,13 @@ +*.class + +#folders# +/target +/neoDb* +/data +/src/main/webapp/WEB-INF/classes +*/META-INF/* + +# Packaged files # +*.jar +*.war +*.ear \ No newline at end of file diff --git a/java-strings/README.md b/java-strings/README.md index b342f53918..ef536b4099 100644 --- a/java-strings/README.md +++ b/java-strings/README.md @@ -6,51 +6,18 @@ - [String Operations with Java Streams](http://www.baeldung.com/java-stream-operations-on-strings) - [Converting String to Stream of chars](http://www.baeldung.com/java-string-to-stream) - [Java 8 StringJoiner](http://www.baeldung.com/java-string-joiner) -- [Image to Base64 String Conversion](http://www.baeldung.com/java-base64-image-string) -- [Java – Generate Random String](http://www.baeldung.com/java-random-string) -- [Convert char to String in Java](http://www.baeldung.com/java-convert-char-to-string) -- [Convert String to int or Integer in Java](http://www.baeldung.com/java-convert-string-to-int-or-integer) -- [Java String Conversions](https://www.baeldung.com/java-string-conversions) - [Converting Strings to Enums in Java](http://www.baeldung.com/java-string-to-enum) - [Quick Guide to the Java StringTokenizer](http://www.baeldung.com/java-stringtokenizer) -- [Count Occurrences of a Char in a String](http://www.baeldung.com/java-count-chars) -- [Split a String in Java](http://www.baeldung.com/java-split-string) -- [How to Remove the Last Character of a String?](http://www.baeldung.com/java-remove-last-character-of-string) -- [CharSequence vs. String in Java](http://www.baeldung.com/java-char-sequence-string) -- [StringBuilder and StringBuffer in Java](http://www.baeldung.com/java-string-builder-string-buffer) -- [Guide to Java String Pool](http://www.baeldung.com/java-string-pool) -- [Check if a String is a Palindrome](http://www.baeldung.com/java-palindrome) -- [Comparing Strings in Java](http://www.baeldung.com/java-compare-strings) -- [Check If a String Is Numeric in Java](http://www.baeldung.com/java-check-string-number) - [Use char[] Array Over a String for Manipulating Passwords in Java?](http://www.baeldung.com/java-storing-passwords) - [Convert a String to Title Case](http://www.baeldung.com/java-string-title-case) - [Compact Strings in Java 9](http://www.baeldung.com/java-9-compact-string) - [Java Check a String for Lowercase/Uppercase Letter, Special Character and Digit](https://www.baeldung.com/java-lowercase-uppercase-special-character-digit-regex) - [Convert java.util.Date to String](https://www.baeldung.com/java-util-date-to-string) -- [Get Substring from String in Java](https://www.baeldung.com/java-substring) - [Converting a Stack Trace to a String in Java](https://www.baeldung.com/java-stacktrace-to-string) - [Sorting a String Alphabetically in Java](https://www.baeldung.com/java-sort-string-alphabetically) -- [Remove Emojis from a Java String](https://www.baeldung.com/java-string-remove-emojis) - [String Not Empty Test Assertions in Java](https://www.baeldung.com/java-assert-string-not-empty) - [String Performance Hints](https://www.baeldung.com/java-string-performance) - [Using indexOf to Find All Occurrences of a Word in a String](https://www.baeldung.com/java-indexOf-find-string-occurrences) -- [Convert String to Byte Array and Reverse in Java](https://www.baeldung.com/java-string-to-byte-array) -- [Java Base64 Encoding and Decoding](https://www.baeldung.com/java-base64-encode-and-decode) -- [Generate a Secure Random Password in Java](https://www.baeldung.com/java-generate-secure-password) -- [Removing Repeated Characters from a String](https://www.baeldung.com/java-remove-repeated-char) -- [Join Array of Primitives with Separator in Java](https://www.baeldung.com/java-join-primitive-array) -- [Convert String to Byte Array and Reverse in Java](https://www.baeldung.com/java-string-to-byte-array) -- [Pad a String with Zeros or Spaces in Java](https://www.baeldung.com/java-pad-string) - [Adding a Newline Character to a String in Java](https://www.baeldung.com/java-string-newline) - [Remove or Replace part of a String in Java](https://www.baeldung.com/java-remove-replace-string-part) -- [Replace a Character at a Specific Index in a String in Java](https://www.baeldung.com/java-replace-character-at-index) -- [Convert a Comma Separated String to a List in Java](https://www.baeldung.com/java-string-with-separator-to-list) -- [Guide to java.util.Formatter](http://www.baeldung.com/java-string-formatter) -- [Add a Character to a String at a Given Position](https://www.baeldung.com/java-add-character-to-string) -- [Remove Leading and Trailing Characters from a String](https://www.baeldung.com/java-remove-trailing-characters) -- [Concatenating Strings In Java](https://www.baeldung.com/java-strings-concatenation) -- [Java toString() Method](https://www.baeldung.com/java-tostring) -- [Java String Interview Questions and Answers](https://www.baeldung.com/java-string-interview-questions) -- [Check if a String is a Pangram in Java](https://www.baeldung.com/java-string-pangram) -- [Check If a String Contains Multiple Keywords](https://www.baeldung.com/string-contains-multiple-words) -- [Common String Operations in Java](https://www.baeldung.com/java-string-operations) +- [Replace a Character at a Specific Index in a String in Java](https://www.baeldung.com/java-replace-character-at-index) \ No newline at end of file diff --git a/java-strings/pom.xml b/java-strings/pom.xml index 7f66b95355..42a57bfb42 100755 --- a/java-strings/pom.xml +++ b/java-strings/pom.xml @@ -62,12 +62,6 @@ guava ${guava.version} - - - com.vdurmont - emoji-java - ${emoji-java.version} - org.junit.jupiter @@ -83,24 +77,6 @@ test - - - org.passay - passay - ${passay.version} - - - org.apache.commons - commons-text - ${commons-text.version} - - - - org.ahocorasick - ahocorasick - ${ahocorasick.version} - - @@ -134,11 +110,8 @@ 3.6.1 61.1 27.0.1-jre - 4.0.0 5.3.1 - 1.3.1 1.4 - 0.4.0 diff --git a/javax-servlets/src/main/java/com/baeldung/servlets/MyHttpServlet.java b/javax-servlets/src/main/java/com/baeldung/servlets/MyHttpServlet.java new file mode 100644 index 0000000000..b4d80db0ab --- /dev/null +++ b/javax-servlets/src/main/java/com/baeldung/servlets/MyHttpServlet.java @@ -0,0 +1,57 @@ +package com.baeldung.servlets; + +import java.io.IOException; +import java.io.PrintWriter; + +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +@WebServlet(name = "MyHttpServlet", urlPatterns = "/servlet-mapping") +public class MyHttpServlet extends HttpServlet { + + public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { + PrintWriter writer = response.getWriter(); + writer.println(request.getParameter("function")); + if ("getContextPath".equals(request.getParameter("function"))) { + writer.println(request.getContextPath()); + } else if ("getLocalAddr".equals(request.getParameter("function"))) { + writer.println(request.getLocalAddr()); + } else if ("getLocalName".equals(request.getParameter("function"))) { + writer.println(request.getLocalName()); + } else if ("getLocalAPort".equals(request.getParameter("function"))) { + writer.println(request.getLocalPort()); + } else if ("getMethod".equals(request.getParameter("function"))) { + writer.println(request.getMethod()); + } else if ("getParameterNames".equals(request.getParameter("function"))) { + writer.println(request.getParameterNames()); + } else if ("getPathInfo".equals(request.getParameter("function"))) { + writer.println(request.getPathInfo()); + } else if ("getProtocol".equals(request.getParameter("function"))) { + writer.println(request.getProtocol()); + } else if ("getQueryString".equals(request.getParameter("function"))) { + writer.println(request.getQueryString()); + } else if ("getRequestedSessionId".equals(request.getParameter("function"))) { + writer.println(request.getRequestedSessionId()); + } else if ("getRequestURI".equals(request.getParameter("function"))) { + writer.println(request.getRequestURI()); + } else if ("getRequestURL".equals(request.getParameter("function"))) { + writer.println(request.getRequestURL()); + } else if ("getScheme".equals(request.getParameter("function"))) { + writer.println(request.getScheme()); + } else if ("getServerName".equals(request.getParameter("function"))) { + writer.println(request.getServerName()); + } else if ("getServerPort".equals(request.getParameter("function"))) { + writer.println(request.getServerPort()); + } else if ("getServletPath".equals(request.getParameter("function"))) { + writer.println(request.getServletPath()); + } else { + writer.println("INVALID FUNCTION"); + } + writer.flush(); + } + +} + + diff --git a/javaxval/src/main/java/org/baeldung/javabeanconstraints/bigdecimal/Invoice.java b/javaxval/src/main/java/org/baeldung/javabeanconstraints/bigdecimal/Invoice.java new file mode 100644 index 0000000000..6df1b79a60 --- /dev/null +++ b/javaxval/src/main/java/org/baeldung/javabeanconstraints/bigdecimal/Invoice.java @@ -0,0 +1,19 @@ +package org.baeldung.javabeanconstraints.bigdecimal; + +import java.math.BigDecimal; + +import javax.validation.constraints.DecimalMin; +import javax.validation.constraints.Digits; + +public class Invoice { + + @DecimalMin(value = "0.0", inclusive = false) + @Digits(integer=3, fraction=2) + private BigDecimal price; + private String description; + + public Invoice(BigDecimal price, String description) { + this.price = price; + this.description = description; + } +} diff --git a/javaxval/src/test/java/org/baeldung/javabeanconstraints/bigdecimal/InvoiceUnitTest.java b/javaxval/src/test/java/org/baeldung/javabeanconstraints/bigdecimal/InvoiceUnitTest.java new file mode 100644 index 0000000000..525dd7d1ad --- /dev/null +++ b/javaxval/src/test/java/org/baeldung/javabeanconstraints/bigdecimal/InvoiceUnitTest.java @@ -0,0 +1,62 @@ +package org.baeldung.javabeanconstraints.bigdecimal; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.math.BigDecimal; +import java.util.Set; + +import javax.validation.ConstraintViolation; +import javax.validation.Validation; +import javax.validation.Validator; + +import org.junit.BeforeClass; +import org.junit.Test; + +public class InvoiceUnitTest { + + private static Validator validator; + + @BeforeClass + public static void setupValidatorInstance() { + validator = Validation.buildDefaultValidatorFactory().getValidator(); + } + + @Test + public void whenPriceIntegerDigitLessThanThreeWithDecimalValue_thenShouldGiveConstraintViolations() { + Invoice invoice = new Invoice(new BigDecimal(10.21), "Book purchased"); + Set> violations = validator.validate(invoice); + assertThat(violations.size()).isEqualTo(1); + violations.forEach(action-> assertThat(action.getMessage()).isEqualTo("numeric value out of bounds (<3 digits>.<2 digits> expected)")); + } + + @Test + public void whenPriceIntegerDigitLessThanThreeWithIntegerValue_thenShouldNotGiveConstraintViolations() { + Invoice invoice = new Invoice(new BigDecimal(10), "Book purchased"); + Set> violations = validator.validate(invoice); + assertThat(violations.size()).isEqualTo(0); + } + + @Test + public void whenPriceIntegerDigitGreaterThanThree_thenShouldGiveConstraintViolations() { + Invoice invoice = new Invoice(new BigDecimal(1021.21), "Book purchased"); + Set> violations = validator.validate(invoice); + assertThat(violations.size()).isEqualTo(1); + violations.forEach(action-> assertThat(action.getMessage()).isEqualTo("numeric value out of bounds (<3 digits>.<2 digits> expected)")); + } + + @Test + public void whenPriceIsZero_thenShouldGiveConstraintViolations() { + Invoice invoice = new Invoice(new BigDecimal(000.00), "Book purchased"); + Set> violations = validator.validate(invoice); + assertThat(violations.size()).isEqualTo(1); + violations.forEach(action-> assertThat(action.getMessage()).isEqualTo("must be greater than 0.0")); + } + + @Test + public void whenPriceIsGreaterThanZero_thenShouldNotGiveConstraintViolations() { + Invoice invoice = new Invoice(new BigDecimal(100.50), "Book purchased"); + Set> violations = validator.validate(invoice); + assertThat(violations.size()).isEqualTo(0); + } + +} diff --git a/jee-kotlin/README.md b/jee-kotlin/README.md index 7d843af9ea..43dcd992ca 100644 --- a/jee-kotlin/README.md +++ b/jee-kotlin/README.md @@ -1 +1,2 @@ ### Relevant Articles: +- [Java EE Application with Kotlin](https://www.baeldung.com/java-ee-kotlin-app) diff --git a/jenkins/README.md b/jenkins/README.md index da60e556df..6b28b61277 100644 --- a/jenkins/README.md +++ b/jenkins/README.md @@ -1,3 +1,2 @@ -## Relevant articles: -- [Writing a Jenkins Plugin](http://www.baeldung.com/jenkins-custom-plugin) +This is an aggregator modules for Jenkins-related modules. diff --git a/jenkins/hello-world/README.md b/jenkins/hello-world/README.md new file mode 100644 index 0000000000..da60e556df --- /dev/null +++ b/jenkins/hello-world/README.md @@ -0,0 +1,3 @@ +## Relevant articles: + +- [Writing a Jenkins Plugin](http://www.baeldung.com/jenkins-custom-plugin) diff --git a/JGit/README.md b/jgit/README.md similarity index 100% rename from JGit/README.md rename to jgit/README.md diff --git a/JGit/pom.xml b/jgit/pom.xml similarity index 100% rename from JGit/pom.xml rename to jgit/pom.xml diff --git a/JGit/src/main/java/com/baeldung/jgit/CreateNewRepository.java b/jgit/src/main/java/com/baeldung/jgit/CreateNewRepository.java similarity index 100% rename from JGit/src/main/java/com/baeldung/jgit/CreateNewRepository.java rename to jgit/src/main/java/com/baeldung/jgit/CreateNewRepository.java diff --git a/JGit/src/main/java/com/baeldung/jgit/OpenRepository.java b/jgit/src/main/java/com/baeldung/jgit/OpenRepository.java similarity index 100% rename from JGit/src/main/java/com/baeldung/jgit/OpenRepository.java rename to jgit/src/main/java/com/baeldung/jgit/OpenRepository.java diff --git a/JGit/src/main/java/com/baeldung/jgit/helper/Helper.java b/jgit/src/main/java/com/baeldung/jgit/helper/Helper.java similarity index 100% rename from JGit/src/main/java/com/baeldung/jgit/helper/Helper.java rename to jgit/src/main/java/com/baeldung/jgit/helper/Helper.java diff --git a/JGit/src/main/java/com/baeldung/jgit/porcelain/AddFile.java b/jgit/src/main/java/com/baeldung/jgit/porcelain/AddFile.java similarity index 100% rename from JGit/src/main/java/com/baeldung/jgit/porcelain/AddFile.java rename to jgit/src/main/java/com/baeldung/jgit/porcelain/AddFile.java diff --git a/JGit/src/main/java/com/baeldung/jgit/porcelain/CommitAll.java b/jgit/src/main/java/com/baeldung/jgit/porcelain/CommitAll.java similarity index 100% rename from JGit/src/main/java/com/baeldung/jgit/porcelain/CommitAll.java rename to jgit/src/main/java/com/baeldung/jgit/porcelain/CommitAll.java diff --git a/JGit/src/main/java/com/baeldung/jgit/porcelain/CreateAndDeleteTag.java b/jgit/src/main/java/com/baeldung/jgit/porcelain/CreateAndDeleteTag.java similarity index 100% rename from JGit/src/main/java/com/baeldung/jgit/porcelain/CreateAndDeleteTag.java rename to jgit/src/main/java/com/baeldung/jgit/porcelain/CreateAndDeleteTag.java diff --git a/JGit/src/main/java/com/baeldung/jgit/porcelain/Log.java b/jgit/src/main/java/com/baeldung/jgit/porcelain/Log.java similarity index 100% rename from JGit/src/main/java/com/baeldung/jgit/porcelain/Log.java rename to jgit/src/main/java/com/baeldung/jgit/porcelain/Log.java diff --git a/Twitter4J/src/main/resources/logback.xml b/jgit/src/main/resources/logback.xml similarity index 100% rename from Twitter4J/src/main/resources/logback.xml rename to jgit/src/main/resources/logback.xml diff --git a/JGit/src/test/java/com/baeldung/jgit/JGitBugIntegrationTest.java b/jgit/src/test/java/com/baeldung/jgit/JGitBugIntegrationTest.java similarity index 100% rename from JGit/src/test/java/com/baeldung/jgit/JGitBugIntegrationTest.java rename to jgit/src/test/java/com/baeldung/jgit/JGitBugIntegrationTest.java diff --git a/JGit/src/test/java/com/baeldung/jgit/porcelain/PorcelainUnitTest.java b/jgit/src/test/java/com/baeldung/jgit/porcelain/PorcelainUnitTest.java similarity index 100% rename from JGit/src/test/java/com/baeldung/jgit/porcelain/PorcelainUnitTest.java rename to jgit/src/test/java/com/baeldung/jgit/porcelain/PorcelainUnitTest.java diff --git a/jhipster-5/README.md b/jhipster-5/README.md index 0537f5b1a5..2731281b3e 100644 --- a/jhipster-5/README.md +++ b/jhipster-5/README.md @@ -1,3 +1,2 @@ -## Relevant articles: -- [Creating New APIs and Views in JHipster](https://www.baeldung.com/jhipster-new-apis-and-views) +This is an aggregator module for JHipster 5 modules. diff --git a/jhipster-5/bookstore-monolith/README.md b/jhipster-5/bookstore-monolith/README.md index 1387b82163..0537f5b1a5 100644 --- a/jhipster-5/bookstore-monolith/README.md +++ b/jhipster-5/bookstore-monolith/README.md @@ -1,179 +1,3 @@ -# Bookstore +## Relevant articles: -This application was generated using JHipster 5.8.2, you can find documentation and help at [https://www.jhipster.tech/documentation-archive/v5.8.2](https://www.jhipster.tech/documentation-archive/v5.8.2). - -## Development - -Before you can build this project, you must install and configure the following dependencies on your machine: - -1. [Node.js][]: We use Node to run a development web server and build the project. - Depending on your system, you can install Node either from source or as a pre-packaged bundle. - -After installing Node, you should be able to run the following command to install development tools. -You will only need to run this command when dependencies change in [package.json](package.json). - - npm install - -We use npm scripts and [Webpack][] as our build system. - -Run the following commands in two separate terminals to create a blissful development experience where your browser -auto-refreshes when files change on your hard drive. - - ./mvnw - npm start - -Npm is also used to manage CSS and JavaScript dependencies used in this application. You can upgrade dependencies by -specifying a newer version in [package.json](package.json). You can also run `npm update` and `npm install` to manage dependencies. -Add the `help` flag on any command to see how you can use it. For example, `npm help update`. - -The `npm run` command will list all of the scripts available to run for this project. - -### Service workers - -Service workers are commented by default, to enable them please uncomment the following code. - -- The service worker registering script in index.html - -```html - -``` - -Note: workbox creates the respective service worker and dynamically generate the `service-worker.js` - -### Managing dependencies - -For example, to add [Leaflet][] library as a runtime dependency of your application, you would run following command: - - npm install --save --save-exact leaflet - -To benefit from TypeScript type definitions from [DefinitelyTyped][] repository in development, you would run following command: - - npm install --save-dev --save-exact @types/leaflet - -Then you would import the JS and CSS files specified in library's installation instructions so that [Webpack][] knows about them: -Edit [src/main/webapp/app/vendor.ts](src/main/webapp/app/vendor.ts) file: - -``` -import 'leaflet/dist/leaflet.js'; -``` - -Edit [src/main/webapp/content/css/vendor.css](src/main/webapp/content/css/vendor.css) file: - -``` -@import '~leaflet/dist/leaflet.css'; -``` - -Note: there are still few other things remaining to do for Leaflet that we won't detail here. - -For further instructions on how to develop with JHipster, have a look at [Using JHipster in development][]. - -### Using angular-cli - -You can also use [Angular CLI][] to generate some custom client code. - -For example, the following command: - - ng generate component my-component - -will generate few files: - - create src/main/webapp/app/my-component/my-component.component.html - create src/main/webapp/app/my-component/my-component.component.ts - update src/main/webapp/app/app.module.ts - -## Building for production - -To optimize the Bookstore application for production, run: - - ./mvnw -Pprod clean package - -This will concatenate and minify the client CSS and JavaScript files. It will also modify `index.html` so it references these new files. -To ensure everything worked, run: - - java -jar target/*.war - -Then navigate to [http://localhost:8080](http://localhost:8080) in your browser. - -Refer to [Using JHipster in production][] for more details. - -## Testing - -To launch your application's tests, run: - - ./mvnw clean test - -### Client tests - -Unit tests are run by [Jest][] and written with [Jasmine][]. They're located in [src/test/javascript/](src/test/javascript/) and can be run with: - - npm test - -For more information, refer to the [Running tests page][]. - -### Code quality - -Sonar is used to analyse code quality. You can start a local Sonar server (accessible on http://localhost:9001) with: - -``` -docker-compose -f src/main/docker/sonar.yml up -d -``` - -Then, run a Sonar analysis: - -``` -./mvnw -Pprod clean test sonar:sonar -``` - -For more information, refer to the [Code quality page][]. - -## Using Docker to simplify development (optional) - -You can use Docker to improve your JHipster development experience. A number of docker-compose configuration are available in the [src/main/docker](src/main/docker) folder to launch required third party services. - -For example, to start a mysql database in a docker container, run: - - docker-compose -f src/main/docker/mysql.yml up -d - -To stop it and remove the container, run: - - docker-compose -f src/main/docker/mysql.yml down - -You can also fully dockerize your application and all the services that it depends on. -To achieve this, first build a docker image of your app by running: - - ./mvnw package -Pprod verify jib:dockerBuild - -Then run: - - docker-compose -f src/main/docker/app.yml up -d - -For more information refer to [Using Docker and Docker-Compose][], this page also contains information on the docker-compose sub-generator (`jhipster docker-compose`), which is able to generate docker configurations for one or several JHipster applications. - -## Continuous Integration (optional) - -To configure CI for your project, run the ci-cd sub-generator (`jhipster ci-cd`), this will let you generate configuration files for a number of Continuous Integration systems. Consult the [Setting up Continuous Integration][] page for more information. - -[jhipster homepage and latest documentation]: https://www.jhipster.tech -[jhipster 5.8.2 archive]: https://www.jhipster.tech/documentation-archive/v5.8.2 -[using jhipster in development]: https://www.jhipster.tech/documentation-archive/v5.8.2/development/ -[using docker and docker-compose]: https://www.jhipster.tech/documentation-archive/v5.8.2/docker-compose -[using jhipster in production]: https://www.jhipster.tech/documentation-archive/v5.8.2/production/ -[running tests page]: https://www.jhipster.tech/documentation-archive/v5.8.2/running-tests/ -[code quality page]: https://www.jhipster.tech/documentation-archive/v5.8.2/code-quality/ -[setting up continuous integration]: https://www.jhipster.tech/documentation-archive/v5.8.2/setting-up-ci/ -[node.js]: https://nodejs.org/ -[yarn]: https://yarnpkg.org/ -[webpack]: https://webpack.github.io/ -[angular cli]: https://cli.angular.io/ -[browsersync]: http://www.browsersync.io/ -[jest]: https://facebook.github.io/jest/ -[jasmine]: http://jasmine.github.io/2.0/introduction.html -[protractor]: https://angular.github.io/protractor/ -[leaflet]: http://leafletjs.com/ -[definitelytyped]: http://definitelytyped.org/ +- [Creating New APIs and Views in JHipster](https://www.baeldung.com/jhipster-new-apis-and-views) diff --git a/jhipster/jhipster-microservice/README.md b/jhipster/jhipster-microservice/README.md new file mode 100644 index 0000000000..7abe3204c4 --- /dev/null +++ b/jhipster/jhipster-microservice/README.md @@ -0,0 +1,3 @@ +## Relevant Articles + +- [JHipster with a Microservice Architecture](https://www.baeldung.com/jhipster-microservices) diff --git a/jhipster/jhipster-monolithic/README.md b/jhipster/jhipster-monolithic/README.md index a2c267b74d..65cc51ad88 100644 --- a/jhipster/jhipster-monolithic/README.md +++ b/jhipster/jhipster-monolithic/README.md @@ -1,4 +1,6 @@ -### Relevant articles +## Relevant Articles + +- [Intro to JHipster](https://www.baeldung.com/jhipster) # baeldung diff --git a/jhipster/jhipster-uaa/README.md b/jhipster/jhipster-uaa/README.md new file mode 100644 index 0000000000..3971e3c8c6 --- /dev/null +++ b/jhipster/jhipster-uaa/README.md @@ -0,0 +1,3 @@ +## Relevant Articles + +- [Building a Basic UAA-Secured JHipster Microservice](https://www.baeldung.com/jhipster-uaa-secured-micro-service) diff --git a/kotlin-quasar/README.md b/kotlin-quasar/README.md index b3b84e0446..b3693284f9 100644 --- a/kotlin-quasar/README.md +++ b/kotlin-quasar/README.md @@ -1,3 +1,4 @@ ### Relevant Articles - [Introduction to Quasar in Kotlin](https://www.baeldung.com/kotlin-quasar) +- [Advanced Quasar Usage for Kotlin](https://www.baeldung.com/kotlin-quasar-advanced) diff --git a/libraries-2/README.md b/libraries-2/README.md index 1b042ac3c5..400aa475d1 100644 --- a/libraries-2/README.md +++ b/libraries-2/README.md @@ -1,5 +1,4 @@ - -### Relevant Articles: +## Relevant Articles: - [A Guide to jBPM with Java](https://www.baeldung.com/jbpm-java) - [Guide to Classgraph Library](https://www.baeldung.com/classgraph) @@ -8,3 +7,7 @@ - [Templating with Handlebars](https://www.baeldung.com/handlebars) - [A Guide to Crawler4j](https://www.baeldung.com/crawler4j) - [Decode an OkHttp JSON Response](https://www.baeldung.com/okhttp-json-response) +- [Key Value Store with Chronicle Map](https://www.baeldung.com/java-chronicle-map) +- [Matrix Multiplication in Java](https://www.baeldung.com/java-matrix-multiplication) +- [Guide to MapDB](https://www.baeldung.com/mapdb) +- [A Guide to Apache Mesos](https://www.baeldung.com/apache-mesos) diff --git a/libraries-2/pom.xml b/libraries-2/pom.xml index ff73888b69..83adf1e199 100644 --- a/libraries-2/pom.xml +++ b/libraries-2/pom.xml @@ -59,26 +59,6 @@ picocli ${picocli.version} - - org.ejml - ejml-all - ${ejml.version} - - - org.nd4j - nd4j-native - ${nd4j.version} - - - org.la4j - la4j - ${la4j.version} - - - colt - colt - ${colt.version} - org.springframework.boot spring-boot-starter @@ -127,17 +107,6 @@ handlebars ${handlebars.version} - - - org.openjdk.jmh - jmh-core - ${jmh.version} - - - org.openjdk.jmh - jmh-generator-annprocess - ${jmh.version} - org.apache.mesos mesos @@ -154,11 +123,6 @@ 3.17.2 4.4.0 2.1.4.RELEASE - 0.38 - 1.0.0-beta4 - 1.2.0 - 0.6.0 - 1.19 0.28.3 1.1.0 3.14.2 diff --git a/libraries-data-2/README.md b/libraries-data-2/README.md new file mode 100644 index 0000000000..8101138c0e --- /dev/null +++ b/libraries-data-2/README.md @@ -0,0 +1,11 @@ +### Relevant articles +- [Introduction to Apache Flink with Java](http://www.baeldung.com/apache-flink) +- [Guide to the HyperLogLog Algorithm](http://www.baeldung.com/java-hyperloglog) +- [Introduction to Conflict-Free Replicated Data Types](http://www.baeldung.com/java-conflict-free-replicated-data-types) +- [Introduction to javax.measure](http://www.baeldung.com/javax-measure) +- [Introduction To Docx4J](http://www.baeldung.com/docx4j) +- [Interact with Google Sheets from Java](http://www.baeldung.com/google-sheets-java-client) +- [Introduction To OpenCSV](http://www.baeldung.com/opencsv) +- [Introduction to Smooks](http://www.baeldung.com/smooks) +- [A Guide to Infinispan in Java](http://www.baeldung.com/infinispan) + diff --git a/libraries-data-2/log4j.properties b/libraries-data-2/log4j.properties new file mode 100644 index 0000000000..2173c5d96f --- /dev/null +++ b/libraries-data-2/log4j.properties @@ -0,0 +1 @@ +log4j.rootLogger=INFO, stdout diff --git a/libraries-data-2/pom.xml b/libraries-data-2/pom.xml new file mode 100644 index 0000000000..87c620f438 --- /dev/null +++ b/libraries-data-2/pom.xml @@ -0,0 +1,145 @@ + + + + 4.0.0 + libraries-data-2 + libraries-data-2 + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + + + + + org.apache.flink + flink-connector-kafka-0.11_2.11 + ${flink.version} + + + org.apache.flink + flink-streaming-java_2.11 + ${flink.version} + + + org.apache.flink + flink-core + ${flink.version} + + + commons-logging + commons-logging + + + + + org.apache.flink + flink-java + ${flink.version} + + + commons-logging + commons-logging + + + + + org.apache.flink + flink-test-utils_2.11 + ${flink.version} + test + + + net.agkn + hll + ${hll.version} + + + com.netopyr.wurmloch + wurmloch-crdt + ${crdt.version} + + + tec.units + unit-ri + ${unit-ri.version} + + + javax.xml.bind + jaxb-api + ${jaxb-api.version} + + + org.docx4j + docx4j + ${docx4j.version} + + + + com.google.api-client + google-api-client + ${google-api.version} + + + com.google.oauth-client + google-oauth-client-jetty + ${google-api.version} + + + com.google.apis + google-api-services-sheets + ${google-sheets.version} + + + + com.opencsv + opencsv + ${opencsv.version} + + + org.milyn + milyn-smooks-all + ${smooks.version} + + + org.infinispan + infinispan-core + ${infinispan.version} + + + com.fasterxml.jackson.datatype + jackson-datatype-jsr310 + ${jackson.version} + + + com.fasterxml.jackson.core + jackson-databind + ${jackson.version} + + + org.springframework + spring-web + ${spring.version} + + + + + + 1.5.0 + 1.6.0 + 0.1.0 + 1.0.3 + 3.3.5 + 2.1 + 1.23.0 + 4.1 + 1.7.0 + 9.1.5.Final + v4-rev493-1.21.0 + 2.9.8 + 4.3.8.RELEASE + + \ No newline at end of file diff --git a/libraries/src/main/java/com/baeldung/docx/Docx4jExample.java b/libraries-data-2/src/main/java/com/baeldung/docx/Docx4jExample.java similarity index 97% rename from libraries/src/main/java/com/baeldung/docx/Docx4jExample.java rename to libraries-data-2/src/main/java/com/baeldung/docx/Docx4jExample.java index 97fbf4adc7..6fe29d26e3 100644 --- a/libraries/src/main/java/com/baeldung/docx/Docx4jExample.java +++ b/libraries-data-2/src/main/java/com/baeldung/docx/Docx4jExample.java @@ -1,105 +1,105 @@ -package com.baeldung.docx; - -import org.docx4j.dml.wordprocessingDrawing.Inline; -import org.docx4j.jaxb.Context; -import org.docx4j.model.table.TblFactory; -import org.docx4j.openpackaging.exceptions.Docx4JException; -import org.docx4j.openpackaging.packages.WordprocessingMLPackage; -import org.docx4j.openpackaging.parts.WordprocessingML.BinaryPartAbstractImage; -import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart; -import org.docx4j.wml.BooleanDefaultTrue; -import org.docx4j.wml.Color; -import org.docx4j.wml.Drawing; -import org.docx4j.wml.ObjectFactory; -import org.docx4j.wml.P; -import org.docx4j.wml.R; -import org.docx4j.wml.RPr; -import org.docx4j.wml.Tbl; -import org.docx4j.wml.Tc; -import org.docx4j.wml.Text; -import org.docx4j.wml.Tr; - -import javax.xml.bind.JAXBElement; -import javax.xml.bind.JAXBException; -import java.io.File; -import java.nio.file.Files; -import java.util.List; - -class Docx4jExample { - - void createDocumentPackage(String outputPath, String imagePath) throws Exception { - WordprocessingMLPackage wordPackage = WordprocessingMLPackage.createPackage(); - MainDocumentPart mainDocumentPart = wordPackage.getMainDocumentPart(); - mainDocumentPart.addStyledParagraphOfText("Title", "Hello World!"); - mainDocumentPart.addParagraphOfText("Welcome To Baeldung!"); - - ObjectFactory factory = Context.getWmlObjectFactory(); - P p = factory.createP(); - R r = factory.createR(); - Text t = factory.createText(); - t.setValue("Welcome To Baeldung"); - r.getContent().add(t); - p.getContent().add(r); - RPr rpr = factory.createRPr(); - BooleanDefaultTrue b = new BooleanDefaultTrue(); - rpr.setB(b); - rpr.setI(b); - rpr.setCaps(b); - Color red = factory.createColor(); - red.setVal("green"); - rpr.setColor(red); - r.setRPr(rpr); - mainDocumentPart.getContent().add(p); - - File image = new File(imagePath); - byte[] fileContent = Files.readAllBytes(image.toPath()); - BinaryPartAbstractImage imagePart = BinaryPartAbstractImage.createImagePart(wordPackage, fileContent); - Inline inline = imagePart.createImageInline("Baeldung Image", "Alt Text", 1, 2, false); - P Imageparagraph = addImageToParagraph(inline); - mainDocumentPart.getContent().add(Imageparagraph); - - int writableWidthTwips = wordPackage.getDocumentModel().getSections().get(0).getPageDimensions().getWritableWidthTwips(); - int columnNumber = 3; - Tbl tbl = TblFactory.createTable(3, 3, writableWidthTwips / columnNumber); - List rows = tbl.getContent(); - for (Object row : rows) { - Tr tr = (Tr) row; - List cells = tr.getContent(); - for (Object cell : cells) { - Tc td = (Tc) cell; - td.getContent().add(p); - } - } - - mainDocumentPart.getContent().add(tbl); - File exportFile = new File(outputPath); - wordPackage.save(exportFile); - } - - boolean isTextExist(String testText) throws Docx4JException, JAXBException { - File doc = new File("helloWorld.docx"); - WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.load(doc); - MainDocumentPart mainDocumentPart = wordMLPackage.getMainDocumentPart(); - String textNodesXPath = "//w:t"; - List paragraphs = mainDocumentPart.getJAXBNodesViaXPath(textNodesXPath, true); - for (Object obj : paragraphs) { - Text text = (Text) ((JAXBElement) obj).getValue(); - String textValue = text.getValue(); - if (textValue != null && textValue.contains(testText)) { - return true; - } - } - return false; - } - - private static P addImageToParagraph(Inline inline) { - ObjectFactory factory = new ObjectFactory(); - P p = factory.createP(); - R r = factory.createR(); - p.getContent().add(r); - Drawing drawing = factory.createDrawing(); - r.getContent().add(drawing); - drawing.getAnchorOrInline().add(inline); - return p; - } -} +package com.baeldung.docx; + +import org.docx4j.dml.wordprocessingDrawing.Inline; +import org.docx4j.jaxb.Context; +import org.docx4j.model.table.TblFactory; +import org.docx4j.openpackaging.exceptions.Docx4JException; +import org.docx4j.openpackaging.packages.WordprocessingMLPackage; +import org.docx4j.openpackaging.parts.WordprocessingML.BinaryPartAbstractImage; +import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart; +import org.docx4j.wml.BooleanDefaultTrue; +import org.docx4j.wml.Color; +import org.docx4j.wml.Drawing; +import org.docx4j.wml.ObjectFactory; +import org.docx4j.wml.P; +import org.docx4j.wml.R; +import org.docx4j.wml.RPr; +import org.docx4j.wml.Tbl; +import org.docx4j.wml.Tc; +import org.docx4j.wml.Text; +import org.docx4j.wml.Tr; + +import javax.xml.bind.JAXBElement; +import javax.xml.bind.JAXBException; +import java.io.File; +import java.nio.file.Files; +import java.util.List; + +class Docx4jExample { + + void createDocumentPackage(String outputPath, String imagePath) throws Exception { + WordprocessingMLPackage wordPackage = WordprocessingMLPackage.createPackage(); + MainDocumentPart mainDocumentPart = wordPackage.getMainDocumentPart(); + mainDocumentPart.addStyledParagraphOfText("Title", "Hello World!"); + mainDocumentPart.addParagraphOfText("Welcome To Baeldung!"); + + ObjectFactory factory = Context.getWmlObjectFactory(); + P p = factory.createP(); + R r = factory.createR(); + Text t = factory.createText(); + t.setValue("Welcome To Baeldung"); + r.getContent().add(t); + p.getContent().add(r); + RPr rpr = factory.createRPr(); + BooleanDefaultTrue b = new BooleanDefaultTrue(); + rpr.setB(b); + rpr.setI(b); + rpr.setCaps(b); + Color red = factory.createColor(); + red.setVal("green"); + rpr.setColor(red); + r.setRPr(rpr); + mainDocumentPart.getContent().add(p); + + File image = new File(imagePath); + byte[] fileContent = Files.readAllBytes(image.toPath()); + BinaryPartAbstractImage imagePart = BinaryPartAbstractImage.createImagePart(wordPackage, fileContent); + Inline inline = imagePart.createImageInline("Baeldung Image", "Alt Text", 1, 2, false); + P Imageparagraph = addImageToParagraph(inline); + mainDocumentPart.getContent().add(Imageparagraph); + + int writableWidthTwips = wordPackage.getDocumentModel().getSections().get(0).getPageDimensions().getWritableWidthTwips(); + int columnNumber = 3; + Tbl tbl = TblFactory.createTable(3, 3, writableWidthTwips / columnNumber); + List rows = tbl.getContent(); + for (Object row : rows) { + Tr tr = (Tr) row; + List cells = tr.getContent(); + for (Object cell : cells) { + Tc td = (Tc) cell; + td.getContent().add(p); + } + } + + mainDocumentPart.getContent().add(tbl); + File exportFile = new File(outputPath); + wordPackage.save(exportFile); + } + + boolean isTextExist(String testText) throws Docx4JException, JAXBException { + File doc = new File("helloWorld.docx"); + WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.load(doc); + MainDocumentPart mainDocumentPart = wordMLPackage.getMainDocumentPart(); + String textNodesXPath = "//w:t"; + List paragraphs = mainDocumentPart.getJAXBNodesViaXPath(textNodesXPath, true); + for (Object obj : paragraphs) { + Text text = (Text) ((JAXBElement) obj).getValue(); + String textValue = text.getValue(); + if (textValue != null && textValue.contains(testText)) { + return true; + } + } + return false; + } + + private static P addImageToParagraph(Inline inline) { + ObjectFactory factory = new ObjectFactory(); + P p = factory.createP(); + R r = factory.createR(); + p.getContent().add(r); + Drawing drawing = factory.createDrawing(); + r.getContent().add(drawing); + drawing.getAnchorOrInline().add(inline); + return p; + } +} diff --git a/libraries-data/src/main/java/com/baeldung/flink/FlinkDataPipeline.java b/libraries-data-2/src/main/java/com/baeldung/flink/FlinkDataPipeline.java similarity index 100% rename from libraries-data/src/main/java/com/baeldung/flink/FlinkDataPipeline.java rename to libraries-data-2/src/main/java/com/baeldung/flink/FlinkDataPipeline.java diff --git a/libraries-data/src/main/java/com/baeldung/flink/LineSplitter.java b/libraries-data-2/src/main/java/com/baeldung/flink/LineSplitter.java similarity index 100% rename from libraries-data/src/main/java/com/baeldung/flink/LineSplitter.java rename to libraries-data-2/src/main/java/com/baeldung/flink/LineSplitter.java diff --git a/libraries-data/src/main/java/com/baeldung/flink/WordCount.java b/libraries-data-2/src/main/java/com/baeldung/flink/WordCount.java similarity index 100% rename from libraries-data/src/main/java/com/baeldung/flink/WordCount.java rename to libraries-data-2/src/main/java/com/baeldung/flink/WordCount.java diff --git a/libraries-data/src/main/java/com/baeldung/flink/connector/Consumers.java b/libraries-data-2/src/main/java/com/baeldung/flink/connector/Consumers.java similarity index 100% rename from libraries-data/src/main/java/com/baeldung/flink/connector/Consumers.java rename to libraries-data-2/src/main/java/com/baeldung/flink/connector/Consumers.java diff --git a/libraries-data/src/main/java/com/baeldung/flink/connector/Producers.java b/libraries-data-2/src/main/java/com/baeldung/flink/connector/Producers.java similarity index 100% rename from libraries-data/src/main/java/com/baeldung/flink/connector/Producers.java rename to libraries-data-2/src/main/java/com/baeldung/flink/connector/Producers.java diff --git a/libraries-data/src/main/java/com/baeldung/flink/model/Backup.java b/libraries-data-2/src/main/java/com/baeldung/flink/model/Backup.java similarity index 100% rename from libraries-data/src/main/java/com/baeldung/flink/model/Backup.java rename to libraries-data-2/src/main/java/com/baeldung/flink/model/Backup.java diff --git a/libraries-data/src/main/java/com/baeldung/flink/model/InputMessage.java b/libraries-data-2/src/main/java/com/baeldung/flink/model/InputMessage.java similarity index 100% rename from libraries-data/src/main/java/com/baeldung/flink/model/InputMessage.java rename to libraries-data-2/src/main/java/com/baeldung/flink/model/InputMessage.java diff --git a/libraries-data/src/main/java/com/baeldung/flink/operator/BackupAggregator.java b/libraries-data-2/src/main/java/com/baeldung/flink/operator/BackupAggregator.java similarity index 100% rename from libraries-data/src/main/java/com/baeldung/flink/operator/BackupAggregator.java rename to libraries-data-2/src/main/java/com/baeldung/flink/operator/BackupAggregator.java diff --git a/libraries-data/src/main/java/com/baeldung/flink/operator/InputMessageTimestampAssigner.java b/libraries-data-2/src/main/java/com/baeldung/flink/operator/InputMessageTimestampAssigner.java similarity index 100% rename from libraries-data/src/main/java/com/baeldung/flink/operator/InputMessageTimestampAssigner.java rename to libraries-data-2/src/main/java/com/baeldung/flink/operator/InputMessageTimestampAssigner.java diff --git a/libraries-data/src/main/java/com/baeldung/flink/operator/WordsCapitalizer.java b/libraries-data-2/src/main/java/com/baeldung/flink/operator/WordsCapitalizer.java similarity index 100% rename from libraries-data/src/main/java/com/baeldung/flink/operator/WordsCapitalizer.java rename to libraries-data-2/src/main/java/com/baeldung/flink/operator/WordsCapitalizer.java diff --git a/libraries-data/src/main/java/com/baeldung/flink/schema/BackupSerializationSchema.java b/libraries-data-2/src/main/java/com/baeldung/flink/schema/BackupSerializationSchema.java similarity index 100% rename from libraries-data/src/main/java/com/baeldung/flink/schema/BackupSerializationSchema.java rename to libraries-data-2/src/main/java/com/baeldung/flink/schema/BackupSerializationSchema.java diff --git a/libraries-data/src/main/java/com/baeldung/flink/schema/InputMessageDeserializationSchema.java b/libraries-data-2/src/main/java/com/baeldung/flink/schema/InputMessageDeserializationSchema.java similarity index 100% rename from libraries-data/src/main/java/com/baeldung/flink/schema/InputMessageDeserializationSchema.java rename to libraries-data-2/src/main/java/com/baeldung/flink/schema/InputMessageDeserializationSchema.java diff --git a/libraries/src/main/java/com/baeldung/google/sheets/GoogleAuthorizeUtil.java b/libraries-data-2/src/main/java/com/baeldung/google/sheets/GoogleAuthorizeUtil.java similarity index 100% rename from libraries/src/main/java/com/baeldung/google/sheets/GoogleAuthorizeUtil.java rename to libraries-data-2/src/main/java/com/baeldung/google/sheets/GoogleAuthorizeUtil.java diff --git a/libraries/src/main/java/com/baeldung/google/sheets/SheetsServiceUtil.java b/libraries-data-2/src/main/java/com/baeldung/google/sheets/SheetsServiceUtil.java similarity index 100% rename from libraries/src/main/java/com/baeldung/google/sheets/SheetsServiceUtil.java rename to libraries-data-2/src/main/java/com/baeldung/google/sheets/SheetsServiceUtil.java diff --git a/libraries/src/main/java/com/baeldung/infinispan/CacheConfiguration.java b/libraries-data-2/src/main/java/com/baeldung/infinispan/CacheConfiguration.java similarity index 100% rename from libraries/src/main/java/com/baeldung/infinispan/CacheConfiguration.java rename to libraries-data-2/src/main/java/com/baeldung/infinispan/CacheConfiguration.java diff --git a/libraries/src/main/java/com/baeldung/infinispan/listener/CacheListener.java b/libraries-data-2/src/main/java/com/baeldung/infinispan/listener/CacheListener.java similarity index 100% rename from libraries/src/main/java/com/baeldung/infinispan/listener/CacheListener.java rename to libraries-data-2/src/main/java/com/baeldung/infinispan/listener/CacheListener.java diff --git a/libraries/src/main/java/com/baeldung/infinispan/repository/HelloWorldRepository.java b/libraries-data-2/src/main/java/com/baeldung/infinispan/repository/HelloWorldRepository.java similarity index 100% rename from libraries/src/main/java/com/baeldung/infinispan/repository/HelloWorldRepository.java rename to libraries-data-2/src/main/java/com/baeldung/infinispan/repository/HelloWorldRepository.java diff --git a/libraries/src/main/java/com/baeldung/infinispan/service/HelloWorldService.java b/libraries-data-2/src/main/java/com/baeldung/infinispan/service/HelloWorldService.java similarity index 100% rename from libraries/src/main/java/com/baeldung/infinispan/service/HelloWorldService.java rename to libraries-data-2/src/main/java/com/baeldung/infinispan/service/HelloWorldService.java diff --git a/libraries/src/main/java/com/baeldung/infinispan/service/TransactionalService.java b/libraries-data-2/src/main/java/com/baeldung/infinispan/service/TransactionalService.java similarity index 100% rename from libraries/src/main/java/com/baeldung/infinispan/service/TransactionalService.java rename to libraries-data-2/src/main/java/com/baeldung/infinispan/service/TransactionalService.java diff --git a/libraries/src/main/java/com/baeldung/measurement/WaterTank.java b/libraries-data-2/src/main/java/com/baeldung/measurement/WaterTank.java similarity index 100% rename from libraries/src/main/java/com/baeldung/measurement/WaterTank.java rename to libraries-data-2/src/main/java/com/baeldung/measurement/WaterTank.java diff --git a/libraries/src/main/java/com/baeldung/opencsv/Application.java b/libraries-data-2/src/main/java/com/baeldung/opencsv/Application.java similarity index 100% rename from libraries/src/main/java/com/baeldung/opencsv/Application.java rename to libraries-data-2/src/main/java/com/baeldung/opencsv/Application.java diff --git a/libraries/src/main/java/com/baeldung/opencsv/Constants.java b/libraries-data-2/src/main/java/com/baeldung/opencsv/Constants.java similarity index 100% rename from libraries/src/main/java/com/baeldung/opencsv/Constants.java rename to libraries-data-2/src/main/java/com/baeldung/opencsv/Constants.java diff --git a/libraries/src/main/java/com/baeldung/opencsv/beans/CsvBean.java b/libraries-data-2/src/main/java/com/baeldung/opencsv/beans/CsvBean.java similarity index 100% rename from libraries/src/main/java/com/baeldung/opencsv/beans/CsvBean.java rename to libraries-data-2/src/main/java/com/baeldung/opencsv/beans/CsvBean.java diff --git a/libraries/src/main/java/com/baeldung/opencsv/beans/NamedColumnBean.java b/libraries-data-2/src/main/java/com/baeldung/opencsv/beans/NamedColumnBean.java similarity index 100% rename from libraries/src/main/java/com/baeldung/opencsv/beans/NamedColumnBean.java rename to libraries-data-2/src/main/java/com/baeldung/opencsv/beans/NamedColumnBean.java diff --git a/libraries/src/main/java/com/baeldung/opencsv/beans/SimplePositionBean.java b/libraries-data-2/src/main/java/com/baeldung/opencsv/beans/SimplePositionBean.java similarity index 100% rename from libraries/src/main/java/com/baeldung/opencsv/beans/SimplePositionBean.java rename to libraries-data-2/src/main/java/com/baeldung/opencsv/beans/SimplePositionBean.java diff --git a/libraries/src/main/java/com/baeldung/opencsv/beans/WriteExampleBean.java b/libraries-data-2/src/main/java/com/baeldung/opencsv/beans/WriteExampleBean.java similarity index 100% rename from libraries/src/main/java/com/baeldung/opencsv/beans/WriteExampleBean.java rename to libraries-data-2/src/main/java/com/baeldung/opencsv/beans/WriteExampleBean.java diff --git a/libraries/src/main/java/com/baeldung/opencsv/examples/sync/BeanExamples.java b/libraries-data-2/src/main/java/com/baeldung/opencsv/examples/sync/BeanExamples.java similarity index 100% rename from libraries/src/main/java/com/baeldung/opencsv/examples/sync/BeanExamples.java rename to libraries-data-2/src/main/java/com/baeldung/opencsv/examples/sync/BeanExamples.java diff --git a/libraries/src/main/java/com/baeldung/opencsv/examples/sync/CsvReaderExamples.java b/libraries-data-2/src/main/java/com/baeldung/opencsv/examples/sync/CsvReaderExamples.java similarity index 100% rename from libraries/src/main/java/com/baeldung/opencsv/examples/sync/CsvReaderExamples.java rename to libraries-data-2/src/main/java/com/baeldung/opencsv/examples/sync/CsvReaderExamples.java diff --git a/libraries/src/main/java/com/baeldung/opencsv/examples/sync/CsvWriterExamples.java b/libraries-data-2/src/main/java/com/baeldung/opencsv/examples/sync/CsvWriterExamples.java similarity index 100% rename from libraries/src/main/java/com/baeldung/opencsv/examples/sync/CsvWriterExamples.java rename to libraries-data-2/src/main/java/com/baeldung/opencsv/examples/sync/CsvWriterExamples.java diff --git a/libraries/src/main/java/com/baeldung/opencsv/helpers/Helpers.java b/libraries-data-2/src/main/java/com/baeldung/opencsv/helpers/Helpers.java similarity index 100% rename from libraries/src/main/java/com/baeldung/opencsv/helpers/Helpers.java rename to libraries-data-2/src/main/java/com/baeldung/opencsv/helpers/Helpers.java diff --git a/libraries/src/main/java/com/baeldung/opencsv/pojos/CsvTransfer.java b/libraries-data-2/src/main/java/com/baeldung/opencsv/pojos/CsvTransfer.java similarity index 100% rename from libraries/src/main/java/com/baeldung/opencsv/pojos/CsvTransfer.java rename to libraries-data-2/src/main/java/com/baeldung/opencsv/pojos/CsvTransfer.java diff --git a/libraries/src/main/java/com/baeldung/smooks/converter/OrderConverter.java b/libraries-data-2/src/main/java/com/baeldung/smooks/converter/OrderConverter.java similarity index 100% rename from libraries/src/main/java/com/baeldung/smooks/converter/OrderConverter.java rename to libraries-data-2/src/main/java/com/baeldung/smooks/converter/OrderConverter.java diff --git a/libraries/src/main/java/com/baeldung/smooks/converter/OrderValidator.java b/libraries-data-2/src/main/java/com/baeldung/smooks/converter/OrderValidator.java similarity index 100% rename from libraries/src/main/java/com/baeldung/smooks/converter/OrderValidator.java rename to libraries-data-2/src/main/java/com/baeldung/smooks/converter/OrderValidator.java diff --git a/libraries/src/main/java/com/baeldung/smooks/model/Item.java b/libraries-data-2/src/main/java/com/baeldung/smooks/model/Item.java similarity index 100% rename from libraries/src/main/java/com/baeldung/smooks/model/Item.java rename to libraries-data-2/src/main/java/com/baeldung/smooks/model/Item.java diff --git a/libraries/src/main/java/com/baeldung/smooks/model/Order.java b/libraries-data-2/src/main/java/com/baeldung/smooks/model/Order.java similarity index 100% rename from libraries/src/main/java/com/baeldung/smooks/model/Order.java rename to libraries-data-2/src/main/java/com/baeldung/smooks/model/Order.java diff --git a/libraries/src/main/java/com/baeldung/smooks/model/Status.java b/libraries-data-2/src/main/java/com/baeldung/smooks/model/Status.java similarity index 100% rename from libraries/src/main/java/com/baeldung/smooks/model/Status.java rename to libraries-data-2/src/main/java/com/baeldung/smooks/model/Status.java diff --git a/libraries/src/main/java/com/baeldung/smooks/model/Supplier.java b/libraries-data-2/src/main/java/com/baeldung/smooks/model/Supplier.java similarity index 100% rename from libraries/src/main/java/com/baeldung/smooks/model/Supplier.java rename to libraries-data-2/src/main/java/com/baeldung/smooks/model/Supplier.java diff --git a/libraries/src/main/resources/google-sheets-client-secret.json b/libraries-data-2/src/main/resources/google-sheets-client-secret.json similarity index 100% rename from libraries/src/main/resources/google-sheets-client-secret.json rename to libraries-data-2/src/main/resources/google-sheets-client-secret.json diff --git a/libraries-data-2/src/main/resources/image.jpg b/libraries-data-2/src/main/resources/image.jpg new file mode 100644 index 0000000000..e2554a0d9c Binary files /dev/null and b/libraries-data-2/src/main/resources/image.jpg differ diff --git a/libraries/src/main/resources/smooks/email.ftl b/libraries-data-2/src/main/resources/smooks/email.ftl similarity index 100% rename from libraries/src/main/resources/smooks/email.ftl rename to libraries-data-2/src/main/resources/smooks/email.ftl diff --git a/libraries/src/main/resources/smooks/item-rules.csv b/libraries-data-2/src/main/resources/smooks/item-rules.csv similarity index 100% rename from libraries/src/main/resources/smooks/item-rules.csv rename to libraries-data-2/src/main/resources/smooks/item-rules.csv diff --git a/libraries/src/main/resources/smooks/order.ftl b/libraries-data-2/src/main/resources/smooks/order.ftl similarity index 100% rename from libraries/src/main/resources/smooks/order.ftl rename to libraries-data-2/src/main/resources/smooks/order.ftl diff --git a/libraries/src/main/resources/smooks/order.json b/libraries-data-2/src/main/resources/smooks/order.json similarity index 100% rename from libraries/src/main/resources/smooks/order.json rename to libraries-data-2/src/main/resources/smooks/order.json diff --git a/libraries/src/main/resources/smooks/order.xml b/libraries-data-2/src/main/resources/smooks/order.xml similarity index 100% rename from libraries/src/main/resources/smooks/order.xml rename to libraries-data-2/src/main/resources/smooks/order.xml diff --git a/libraries/src/main/resources/smooks/smooks-mapping.xml b/libraries-data-2/src/main/resources/smooks/smooks-mapping.xml similarity index 100% rename from libraries/src/main/resources/smooks/smooks-mapping.xml rename to libraries-data-2/src/main/resources/smooks/smooks-mapping.xml diff --git a/libraries/src/main/resources/smooks/smooks-transform-edi.xml b/libraries-data-2/src/main/resources/smooks/smooks-transform-edi.xml similarity index 100% rename from libraries/src/main/resources/smooks/smooks-transform-edi.xml rename to libraries-data-2/src/main/resources/smooks/smooks-transform-edi.xml diff --git a/libraries/src/main/resources/smooks/smooks-transform-email.xml b/libraries-data-2/src/main/resources/smooks/smooks-transform-email.xml similarity index 100% rename from libraries/src/main/resources/smooks/smooks-transform-email.xml rename to libraries-data-2/src/main/resources/smooks/smooks-transform-email.xml diff --git a/libraries/src/main/resources/smooks/smooks-validation.xml b/libraries-data-2/src/main/resources/smooks/smooks-validation.xml similarity index 100% rename from libraries/src/main/resources/smooks/smooks-validation.xml rename to libraries-data-2/src/main/resources/smooks/smooks-validation.xml diff --git a/libraries/src/main/resources/smooks/supplier.properties b/libraries-data-2/src/main/resources/smooks/supplier.properties similarity index 100% rename from libraries/src/main/resources/smooks/supplier.properties rename to libraries-data-2/src/main/resources/smooks/supplier.properties diff --git a/libraries/src/test/java/com/baeldung/crdt/CRDTUnitTest.java b/libraries-data-2/src/test/com/baeldung/crdt/CRDTUnitTest.java similarity index 100% rename from libraries/src/test/java/com/baeldung/crdt/CRDTUnitTest.java rename to libraries-data-2/src/test/com/baeldung/crdt/CRDTUnitTest.java diff --git a/libraries/src/test/java/com/baeldung/docx/Docx4jReadAndWriteIntegrationTest.java b/libraries-data-2/src/test/com/baeldung/docx/Docx4jReadAndWriteIntegrationTest.java similarity index 97% rename from libraries/src/test/java/com/baeldung/docx/Docx4jReadAndWriteIntegrationTest.java rename to libraries-data-2/src/test/com/baeldung/docx/Docx4jReadAndWriteIntegrationTest.java index b6e157beea..9a2691d3f0 100644 --- a/libraries/src/test/java/com/baeldung/docx/Docx4jReadAndWriteIntegrationTest.java +++ b/libraries-data-2/src/test/com/baeldung/docx/Docx4jReadAndWriteIntegrationTest.java @@ -1,19 +1,19 @@ -package com.baeldung.docx; - -import org.junit.Test; - -import static org.junit.Assert.assertTrue; - -public class Docx4jReadAndWriteIntegrationTest { - - private static final String imagePath = "src/main/resources/image.jpg"; - private static final String outputPath = "helloWorld.docx"; - - @Test - public void givenWordPackage_whenTextExist_thenReturnTrue() throws Exception { - Docx4jExample docx4j = new Docx4jExample(); - docx4j.createDocumentPackage(outputPath, imagePath); - assertTrue(docx4j.isTextExist("Hello World!")); - assertTrue(!docx4j.isTextExist("InexistantText")); - } -} +package com.baeldung.docx; + +import org.junit.Test; + +import static org.junit.Assert.assertTrue; + +public class Docx4jReadAndWriteIntegrationTest { + + private static final String imagePath = "src/main/resources/image.jpg"; + private static final String outputPath = "helloWorld.docx"; + + @Test + public void givenWordPackage_whenTextExist_thenReturnTrue() throws Exception { + Docx4jExample docx4j = new Docx4jExample(); + docx4j.createDocumentPackage(outputPath, imagePath); + assertTrue(docx4j.isTextExist("Hello World!")); + assertTrue(!docx4j.isTextExist("InexistantText")); + } +} diff --git a/libraries-data/src/test/java/com/baeldung/flink/BackupCreatorIntegrationTest.java b/libraries-data-2/src/test/com/baeldung/flink/BackupCreatorIntegrationTest.java similarity index 100% rename from libraries-data/src/test/java/com/baeldung/flink/BackupCreatorIntegrationTest.java rename to libraries-data-2/src/test/com/baeldung/flink/BackupCreatorIntegrationTest.java diff --git a/libraries-data/src/test/java/com/baeldung/flink/WordCapitalizerIntegrationTest.java b/libraries-data-2/src/test/com/baeldung/flink/WordCapitalizerIntegrationTest.java similarity index 100% rename from libraries-data/src/test/java/com/baeldung/flink/WordCapitalizerIntegrationTest.java rename to libraries-data-2/src/test/com/baeldung/flink/WordCapitalizerIntegrationTest.java diff --git a/libraries-data/src/test/java/com/baeldung/flink/WordCountIntegrationTest.java b/libraries-data-2/src/test/com/baeldung/flink/WordCountIntegrationTest.java similarity index 100% rename from libraries-data/src/test/java/com/baeldung/flink/WordCountIntegrationTest.java rename to libraries-data-2/src/test/com/baeldung/flink/WordCountIntegrationTest.java diff --git a/libraries/src/test/java/com/baeldung/google/sheets/GoogleSheetsLiveTest.java b/libraries-data-2/src/test/com/baeldung/google/sheets/GoogleSheetsLiveTest.java similarity index 100% rename from libraries/src/test/java/com/baeldung/google/sheets/GoogleSheetsLiveTest.java rename to libraries-data-2/src/test/com/baeldung/google/sheets/GoogleSheetsLiveTest.java diff --git a/libraries/src/test/java/com/baeldung/hll/HLLLongRunningManualTest.java b/libraries-data-2/src/test/com/baeldung/hll/HLLLongRunningManualTest.java similarity index 100% rename from libraries/src/test/java/com/baeldung/hll/HLLLongRunningManualTest.java rename to libraries-data-2/src/test/com/baeldung/hll/HLLLongRunningManualTest.java diff --git a/libraries/src/test/java/com/baeldung/infinispan/AbstractIntegrationTest.java b/libraries-data-2/src/test/com/baeldung/infinispan/AbstractIntegrationTest.java similarity index 100% rename from libraries/src/test/java/com/baeldung/infinispan/AbstractIntegrationTest.java rename to libraries-data-2/src/test/com/baeldung/infinispan/AbstractIntegrationTest.java diff --git a/libraries/src/test/java/com/baeldung/infinispan/service/HelloWorldServiceTemporaryLiveTest.java b/libraries-data-2/src/test/com/baeldung/infinispan/service/HelloWorldServiceTemporaryLiveTest.java similarity index 100% rename from libraries/src/test/java/com/baeldung/infinispan/service/HelloWorldServiceTemporaryLiveTest.java rename to libraries-data-2/src/test/com/baeldung/infinispan/service/HelloWorldServiceTemporaryLiveTest.java diff --git a/libraries/src/test/java/com/baeldung/infinispan/service/TransactionalServiceIntegrationTest.java b/libraries-data-2/src/test/com/baeldung/infinispan/service/TransactionalServiceIntegrationTest.java similarity index 100% rename from libraries/src/test/java/com/baeldung/infinispan/service/TransactionalServiceIntegrationTest.java rename to libraries-data-2/src/test/com/baeldung/infinispan/service/TransactionalServiceIntegrationTest.java diff --git a/libraries/src/test/java/com/baeldung/measurement/WaterTankUnitTest.java b/libraries-data-2/src/test/com/baeldung/measurement/WaterTankUnitTest.java similarity index 100% rename from libraries/src/test/java/com/baeldung/measurement/WaterTankUnitTest.java rename to libraries-data-2/src/test/com/baeldung/measurement/WaterTankUnitTest.java diff --git a/libraries/src/test/java/com/baeldung/opencsv/OpenCsvIntegrationTest.java b/libraries-data-2/src/test/com/baeldung/opencsv/OpenCsvIntegrationTest.java similarity index 100% rename from libraries/src/test/java/com/baeldung/opencsv/OpenCsvIntegrationTest.java rename to libraries-data-2/src/test/com/baeldung/opencsv/OpenCsvIntegrationTest.java diff --git a/libraries/src/test/java/com/baeldung/smooks/converter/SmooksIntegrationTest.java b/libraries-data-2/src/test/com/baeldung/smooks/converter/SmooksIntegrationTest.java similarity index 100% rename from libraries/src/test/java/com/baeldung/smooks/converter/SmooksIntegrationTest.java rename to libraries-data-2/src/test/com/baeldung/smooks/converter/SmooksIntegrationTest.java diff --git a/libraries-data-3/README.md b/libraries-data-3/README.md new file mode 100644 index 0000000000..7f939e7909 --- /dev/null +++ b/libraries-data-3/README.md @@ -0,0 +1,5 @@ +### Relevant articles +- [Parsing YAML with SnakeYAML](http://www.baeldung.com/java-snake-yaml) +- [Guide to JMapper](https://www.baeldung.com/jmapper) +- [An Introduction to SuanShu](https://www.baeldung.com/suanshu) +- [Intro to Derive4J](https://www.baeldung.com/derive4j) diff --git a/libraries-data-3/log4j.properties b/libraries-data-3/log4j.properties new file mode 100644 index 0000000000..2173c5d96f --- /dev/null +++ b/libraries-data-3/log4j.properties @@ -0,0 +1 @@ +log4j.rootLogger=INFO, stdout diff --git a/libraries-data-3/pom.xml b/libraries-data-3/pom.xml new file mode 100644 index 0000000000..f55701f51c --- /dev/null +++ b/libraries-data-3/pom.xml @@ -0,0 +1,55 @@ + + + + 4.0.0 + libraries-data-3 + libraries-data-3 + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + + + + + org.yaml + snakeyaml + ${snakeyaml.version} + + + com.googlecode.jmapper-framework + jmapper-core + ${jmapper.version} + + + com.numericalmethod + suanshu + ${suanshu.version} + + + org.derive4j + derive4j + ${derive4j.version} + + + + + + + nm-repo + Numerical Method's Maven Repository + http://repo.numericalmethod.com/maven/ + default + + + + + 1.21 + 1.6.0.1 + 4.0.0 + 1.1.0 + + \ No newline at end of file diff --git a/libraries/src/main/java/com/baeldung/derive4j/adt/Either.java b/libraries-data-3/src/main/java/com/baeldung/derive4j/adt/Either.java similarity index 100% rename from libraries/src/main/java/com/baeldung/derive4j/adt/Either.java rename to libraries-data-3/src/main/java/com/baeldung/derive4j/adt/Either.java diff --git a/libraries/src/main/java/com/baeldung/derive4j/lazy/LazyRequest.java b/libraries-data-3/src/main/java/com/baeldung/derive4j/lazy/LazyRequest.java similarity index 100% rename from libraries/src/main/java/com/baeldung/derive4j/lazy/LazyRequest.java rename to libraries-data-3/src/main/java/com/baeldung/derive4j/lazy/LazyRequest.java diff --git a/libraries/src/main/java/com/baeldung/derive4j/pattern/HTTPRequest.java b/libraries-data-3/src/main/java/com/baeldung/derive4j/pattern/HTTPRequest.java similarity index 100% rename from libraries/src/main/java/com/baeldung/derive4j/pattern/HTTPRequest.java rename to libraries-data-3/src/main/java/com/baeldung/derive4j/pattern/HTTPRequest.java diff --git a/libraries/src/main/java/com/baeldung/derive4j/pattern/HTTPResponse.java b/libraries-data-3/src/main/java/com/baeldung/derive4j/pattern/HTTPResponse.java similarity index 100% rename from libraries/src/main/java/com/baeldung/derive4j/pattern/HTTPResponse.java rename to libraries-data-3/src/main/java/com/baeldung/derive4j/pattern/HTTPResponse.java diff --git a/libraries/src/main/java/com/baeldung/derive4j/pattern/HTTPServer.java b/libraries-data-3/src/main/java/com/baeldung/derive4j/pattern/HTTPServer.java similarity index 100% rename from libraries/src/main/java/com/baeldung/derive4j/pattern/HTTPServer.java rename to libraries-data-3/src/main/java/com/baeldung/derive4j/pattern/HTTPServer.java diff --git a/libraries-data/src/main/java/com/baeldung/jmapper/User.java b/libraries-data-3/src/main/java/com/baeldung/jmapper/User.java similarity index 100% rename from libraries-data/src/main/java/com/baeldung/jmapper/User.java rename to libraries-data-3/src/main/java/com/baeldung/jmapper/User.java diff --git a/libraries-data/src/main/java/com/baeldung/jmapper/UserDto.java b/libraries-data-3/src/main/java/com/baeldung/jmapper/UserDto.java similarity index 100% rename from libraries-data/src/main/java/com/baeldung/jmapper/UserDto.java rename to libraries-data-3/src/main/java/com/baeldung/jmapper/UserDto.java diff --git a/libraries-data/src/main/java/com/baeldung/jmapper/UserDto1.java b/libraries-data-3/src/main/java/com/baeldung/jmapper/UserDto1.java similarity index 100% rename from libraries-data/src/main/java/com/baeldung/jmapper/UserDto1.java rename to libraries-data-3/src/main/java/com/baeldung/jmapper/UserDto1.java diff --git a/libraries-data/src/main/java/com/baeldung/jmapper/relational/User.java b/libraries-data-3/src/main/java/com/baeldung/jmapper/relational/User.java similarity index 100% rename from libraries-data/src/main/java/com/baeldung/jmapper/relational/User.java rename to libraries-data-3/src/main/java/com/baeldung/jmapper/relational/User.java diff --git a/libraries-data/src/main/java/com/baeldung/jmapper/relational/UserDto1.java b/libraries-data-3/src/main/java/com/baeldung/jmapper/relational/UserDto1.java similarity index 100% rename from libraries-data/src/main/java/com/baeldung/jmapper/relational/UserDto1.java rename to libraries-data-3/src/main/java/com/baeldung/jmapper/relational/UserDto1.java diff --git a/libraries-data/src/main/java/com/baeldung/jmapper/relational/UserDto2.java b/libraries-data-3/src/main/java/com/baeldung/jmapper/relational/UserDto2.java similarity index 100% rename from libraries-data/src/main/java/com/baeldung/jmapper/relational/UserDto2.java rename to libraries-data-3/src/main/java/com/baeldung/jmapper/relational/UserDto2.java diff --git a/libraries/src/main/java/com/baeldung/snakeyaml/Address.java b/libraries-data-3/src/main/java/com/baeldung/snakeyaml/Address.java similarity index 100% rename from libraries/src/main/java/com/baeldung/snakeyaml/Address.java rename to libraries-data-3/src/main/java/com/baeldung/snakeyaml/Address.java diff --git a/libraries/src/main/java/com/baeldung/snakeyaml/Contact.java b/libraries-data-3/src/main/java/com/baeldung/snakeyaml/Contact.java similarity index 100% rename from libraries/src/main/java/com/baeldung/snakeyaml/Contact.java rename to libraries-data-3/src/main/java/com/baeldung/snakeyaml/Contact.java diff --git a/libraries/src/main/java/com/baeldung/snakeyaml/Customer.java b/libraries-data-3/src/main/java/com/baeldung/snakeyaml/Customer.java similarity index 100% rename from libraries/src/main/java/com/baeldung/snakeyaml/Customer.java rename to libraries-data-3/src/main/java/com/baeldung/snakeyaml/Customer.java diff --git a/libraries/src/main/java/com/baeldung/suanshu/SuanShuMath.java b/libraries-data-3/src/main/java/com/baeldung/suanshu/SuanShuMath.java similarity index 100% rename from libraries/src/main/java/com/baeldung/suanshu/SuanShuMath.java rename to libraries-data-3/src/main/java/com/baeldung/suanshu/SuanShuMath.java diff --git a/libraries-data-3/src/main/resources/user_jmapper.xml b/libraries-data-3/src/main/resources/user_jmapper.xml new file mode 100644 index 0000000000..f007de9f0a --- /dev/null +++ b/libraries-data-3/src/main/resources/user_jmapper.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/libraries-data-3/src/main/resources/user_jmapper1.xml b/libraries-data-3/src/main/resources/user_jmapper1.xml new file mode 100644 index 0000000000..abcfd77e1c --- /dev/null +++ b/libraries-data-3/src/main/resources/user_jmapper1.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/libraries-data-3/src/main/resources/user_jmapper2.xml b/libraries-data-3/src/main/resources/user_jmapper2.xml new file mode 100644 index 0000000000..1e708e14bf --- /dev/null +++ b/libraries-data-3/src/main/resources/user_jmapper2.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/libraries/src/test/java/com/baeldung/derive4j/adt/EitherUnitTest.java b/libraries-data-3/src/test/java/com/baeldung/derive4j/adt/EitherUnitTest.java similarity index 100% rename from libraries/src/test/java/com/baeldung/derive4j/adt/EitherUnitTest.java rename to libraries-data-3/src/test/java/com/baeldung/derive4j/adt/EitherUnitTest.java diff --git a/libraries/src/test/java/com/baeldung/derive4j/lazy/LazyRequestUnitTest.java b/libraries-data-3/src/test/java/com/baeldung/derive4j/lazy/LazyRequestUnitTest.java similarity index 100% rename from libraries/src/test/java/com/baeldung/derive4j/lazy/LazyRequestUnitTest.java rename to libraries-data-3/src/test/java/com/baeldung/derive4j/lazy/LazyRequestUnitTest.java diff --git a/libraries/src/test/java/com/baeldung/derive4j/pattern/HTTPRequestUnitTest.java b/libraries-data-3/src/test/java/com/baeldung/derive4j/pattern/HTTPRequestUnitTest.java similarity index 100% rename from libraries/src/test/java/com/baeldung/derive4j/pattern/HTTPRequestUnitTest.java rename to libraries-data-3/src/test/java/com/baeldung/derive4j/pattern/HTTPRequestUnitTest.java diff --git a/libraries-data/src/test/java/com/baeldung/jmapper/JMapperIntegrationTest.java b/libraries-data-3/src/test/java/com/baeldung/jmapper/JMapperIntegrationTest.java similarity index 100% rename from libraries-data/src/test/java/com/baeldung/jmapper/JMapperIntegrationTest.java rename to libraries-data-3/src/test/java/com/baeldung/jmapper/JMapperIntegrationTest.java diff --git a/libraries-data/src/test/java/com/baeldung/jmapper/JMapperRelationalIntegrationTest.java b/libraries-data-3/src/test/java/com/baeldung/jmapper/JMapperRelationalIntegrationTest.java similarity index 100% rename from libraries-data/src/test/java/com/baeldung/jmapper/JMapperRelationalIntegrationTest.java rename to libraries-data-3/src/test/java/com/baeldung/jmapper/JMapperRelationalIntegrationTest.java diff --git a/libraries/src/test/java/com/baeldung/snakeyaml/JavaToYAMLSerializationUnitTest.java b/libraries-data-3/src/test/java/com/baeldung/snakeyaml/JavaToYAMLSerializationUnitTest.java similarity index 100% rename from libraries/src/test/java/com/baeldung/snakeyaml/JavaToYAMLSerializationUnitTest.java rename to libraries-data-3/src/test/java/com/baeldung/snakeyaml/JavaToYAMLSerializationUnitTest.java diff --git a/libraries/src/test/java/com/baeldung/snakeyaml/YAMLToJavaDeserialisationUnitTest.java b/libraries-data-3/src/test/java/com/baeldung/snakeyaml/YAMLToJavaDeserialisationUnitTest.java similarity index 100% rename from libraries/src/test/java/com/baeldung/snakeyaml/YAMLToJavaDeserialisationUnitTest.java rename to libraries-data-3/src/test/java/com/baeldung/snakeyaml/YAMLToJavaDeserialisationUnitTest.java diff --git a/libraries-data-3/src/test/resources/yaml/customer.yaml b/libraries-data-3/src/test/resources/yaml/customer.yaml new file mode 100644 index 0000000000..aa76141c7d --- /dev/null +++ b/libraries-data-3/src/test/resources/yaml/customer.yaml @@ -0,0 +1,3 @@ +firstName: "John" +lastName: "Doe" +age: 20 \ No newline at end of file diff --git a/libraries-data-3/src/test/resources/yaml/customer_with_contact_details.yaml b/libraries-data-3/src/test/resources/yaml/customer_with_contact_details.yaml new file mode 100644 index 0000000000..34563cbd21 --- /dev/null +++ b/libraries-data-3/src/test/resources/yaml/customer_with_contact_details.yaml @@ -0,0 +1,7 @@ +firstName: "John" +lastName: "Doe" +age: 31 +contactDetails: + - { type: "mobile", number: 123456789} + - { type: "landline", number: 456786868} + \ No newline at end of file diff --git a/libraries-data-3/src/test/resources/yaml/customer_with_contact_details_and_address.yaml b/libraries-data-3/src/test/resources/yaml/customer_with_contact_details_and_address.yaml new file mode 100644 index 0000000000..664afe8594 --- /dev/null +++ b/libraries-data-3/src/test/resources/yaml/customer_with_contact_details_and_address.yaml @@ -0,0 +1,13 @@ +firstName: "John" +lastName: "Doe" +age: 31 +contactDetails: + - type: "mobile" + number: 123456789 + - type: "landline" + number: 456786868 +homeAddress: + line: "Xyz, DEF Street" + city: "City Y" + state: "State Y" + zip: 345657 diff --git a/libraries-data-3/src/test/resources/yaml/customer_with_contact_details_and_tags.yaml b/libraries-data-3/src/test/resources/yaml/customer_with_contact_details_and_tags.yaml new file mode 100644 index 0000000000..145da256d9 --- /dev/null +++ b/libraries-data-3/src/test/resources/yaml/customer_with_contact_details_and_tags.yaml @@ -0,0 +1,6 @@ +firstName: "John" +lastName: "Doe" +age: 31 +contactDetails: + - !contact { type: "mobile", number: 123456789} + - !contact { type: "landline", number: 456786868} diff --git a/libraries-data-3/src/test/resources/yaml/customer_with_type.yaml b/libraries-data-3/src/test/resources/yaml/customer_with_type.yaml new file mode 100644 index 0000000000..6e13c26cea --- /dev/null +++ b/libraries-data-3/src/test/resources/yaml/customer_with_type.yaml @@ -0,0 +1,4 @@ +!!com.baeldung.snakeyaml.Customer +firstName: "John" +lastName: "Doe" +age: 20 \ No newline at end of file diff --git a/libraries-data-3/src/test/resources/yaml/customers.yaml b/libraries-data-3/src/test/resources/yaml/customers.yaml new file mode 100644 index 0000000000..23b9039c2e --- /dev/null +++ b/libraries-data-3/src/test/resources/yaml/customers.yaml @@ -0,0 +1,8 @@ +--- +firstName: "John" +lastName: "Doe" +age: 20 +--- +firstName: "Jack" +lastName: "Jones" +age: 25 \ No newline at end of file diff --git a/libraries-data/README.md b/libraries-data/README.md index 077961f887..92c546c258 100644 --- a/libraries-data/README.md +++ b/libraries-data/README.md @@ -9,9 +9,7 @@ - [Introduction to JCache](http://www.baeldung.com/jcache) - [A Guide to Apache Ignite](http://www.baeldung.com/apache-ignite) - [Apache Ignite with Spring Data](http://www.baeldung.com/apache-ignite-spring-data) -- [Guide to JMapper](https://www.baeldung.com/jmapper) - [A Guide to Apache Crunch](https://www.baeldung.com/apache-crunch) -- [Building a Data Pipeline with Flink and Kafka](https://www.baeldung.com/kafka-flink-data-pipeline) - [Intro to Apache Storm](https://www.baeldung.com/apache-storm) - [Guide to Ebean ORM](https://www.baeldung.com/ebean-orm) - [Introduction to Kafka Connectors](https://www.baeldung.com/kafka-connectors-guide) diff --git a/libraries-data/pom.xml b/libraries-data/pom.xml index 88dcceafaa..e255236480 100644 --- a/libraries-data/pom.xml +++ b/libraries-data/pom.xml @@ -141,12 +141,7 @@ hazelcast ${hazelcast.version} - - - com.googlecode.jmapper-framework - jmapper-core - ${jmapper.version} - + org.apache.crunch @@ -460,7 +455,6 @@ 5.0.2 5.0.0-release 5.0.4 - 1.6.0.1 0.15.0 2.2.0 11.22.4 diff --git a/libraries-http/README.md b/libraries-http/README.md index dd8c6a5f67..d5eaed0736 100644 --- a/libraries-http/README.md +++ b/libraries-http/README.md @@ -5,3 +5,7 @@ - [A Guide to Google-Http-Client](http://www.baeldung.com/google-http-client) - [Asynchronous HTTP with async-http-client in Java](http://www.baeldung.com/async-http-client) - [WebSockets with AsyncHttpClient](http://www.baeldung.com/async-http-client-websockets) +- [Integrating Retrofit with RxJava](http://www.baeldung.com/retrofit-rxjava) +- [Introduction to Retrofit](http://www.baeldung.com/retrofit) +- [A Guide to Unirest](http://www.baeldung.com/unirest) +- [Creating REST Microservices with Javalin](http://www.baeldung.com/javalin-rest-microservices) \ No newline at end of file diff --git a/libraries-http/pom.xml b/libraries-http/pom.xml index 6006a93aef..44280d848c 100644 --- a/libraries-http/pom.xml +++ b/libraries-http/pom.xml @@ -44,6 +44,23 @@ ${googleclient.version} + + + com.squareup.retrofit2 + retrofit + ${retrofit.version} + + + com.squareup.retrofit2 + converter-gson + ${retrofit.version} + + + com.squareup.retrofit2 + adapter-rxjava + ${retrofit.version} + + org.asynchttpclient @@ -69,13 +86,52 @@ ${com.squareup.okhttp3.version} test + + + com.mashape.unirest + unirest-java + ${unirest.version} + + + + io.javalin + javalin + ${javalin.version} + + + com.squareup.okhttp3 + logging-interceptor + ${logging-interceptor.version} + + + com.fasterxml.jackson.core + jackson-databind + ${jackson.version} + + + org.apache.httpcomponents + httpclient + ${httpclient.version} + + + commons-logging + commons-logging + + + + 4.5.3 + 2.9.8 3.6.2 3.14.2 1.23.0 2.2.0 + 2.3.0 + 1.4.9 + 1.6.0 + 3.9.0 diff --git a/libraries/src/main/java/com/baeldung/javalin/JavalinApp.java b/libraries-http/src/main/java/com/baeldung/javalin/JavalinApp.java similarity index 100% rename from libraries/src/main/java/com/baeldung/javalin/JavalinApp.java rename to libraries-http/src/main/java/com/baeldung/javalin/JavalinApp.java diff --git a/libraries/src/main/java/com/baeldung/javalin/User/User.java b/libraries-http/src/main/java/com/baeldung/javalin/User/User.java similarity index 100% rename from libraries/src/main/java/com/baeldung/javalin/User/User.java rename to libraries-http/src/main/java/com/baeldung/javalin/User/User.java diff --git a/libraries/src/main/java/com/baeldung/javalin/User/UserController.java b/libraries-http/src/main/java/com/baeldung/javalin/User/UserController.java similarity index 100% rename from libraries/src/main/java/com/baeldung/javalin/User/UserController.java rename to libraries-http/src/main/java/com/baeldung/javalin/User/UserController.java diff --git a/libraries/src/main/java/com/baeldung/javalin/User/UserDao.java b/libraries-http/src/main/java/com/baeldung/javalin/User/UserDao.java similarity index 100% rename from libraries/src/main/java/com/baeldung/javalin/User/UserDao.java rename to libraries-http/src/main/java/com/baeldung/javalin/User/UserDao.java diff --git a/libraries/src/main/java/com/baeldung/retrofit/basic/GitHubBasicApi.java b/libraries-http/src/main/java/com/baeldung/retrofit/basic/GitHubBasicApi.java similarity index 100% rename from libraries/src/main/java/com/baeldung/retrofit/basic/GitHubBasicApi.java rename to libraries-http/src/main/java/com/baeldung/retrofit/basic/GitHubBasicApi.java diff --git a/libraries/src/main/java/com/baeldung/retrofit/basic/GitHubBasicApp.java b/libraries-http/src/main/java/com/baeldung/retrofit/basic/GitHubBasicApp.java similarity index 100% rename from libraries/src/main/java/com/baeldung/retrofit/basic/GitHubBasicApp.java rename to libraries-http/src/main/java/com/baeldung/retrofit/basic/GitHubBasicApp.java diff --git a/libraries/src/main/java/com/baeldung/retrofit/basic/GitHubBasicService.java b/libraries-http/src/main/java/com/baeldung/retrofit/basic/GitHubBasicService.java similarity index 100% rename from libraries/src/main/java/com/baeldung/retrofit/basic/GitHubBasicService.java rename to libraries-http/src/main/java/com/baeldung/retrofit/basic/GitHubBasicService.java diff --git a/libraries/src/main/java/com/baeldung/retrofit/models/Contributor.java b/libraries-http/src/main/java/com/baeldung/retrofit/models/Contributor.java similarity index 100% rename from libraries/src/main/java/com/baeldung/retrofit/models/Contributor.java rename to libraries-http/src/main/java/com/baeldung/retrofit/models/Contributor.java diff --git a/libraries/src/main/java/com/baeldung/retrofit/models/Repository.java b/libraries-http/src/main/java/com/baeldung/retrofit/models/Repository.java similarity index 100% rename from libraries/src/main/java/com/baeldung/retrofit/models/Repository.java rename to libraries-http/src/main/java/com/baeldung/retrofit/models/Repository.java diff --git a/libraries/src/main/java/com/baeldung/retrofit/rx/GitHubRxApi.java b/libraries-http/src/main/java/com/baeldung/retrofit/rx/GitHubRxApi.java similarity index 100% rename from libraries/src/main/java/com/baeldung/retrofit/rx/GitHubRxApi.java rename to libraries-http/src/main/java/com/baeldung/retrofit/rx/GitHubRxApi.java diff --git a/libraries/src/main/java/com/baeldung/retrofit/rx/GitHubRxApp.java b/libraries-http/src/main/java/com/baeldung/retrofit/rx/GitHubRxApp.java similarity index 100% rename from libraries/src/main/java/com/baeldung/retrofit/rx/GitHubRxApp.java rename to libraries-http/src/main/java/com/baeldung/retrofit/rx/GitHubRxApp.java diff --git a/libraries/src/main/java/com/baeldung/retrofit/rx/GitHubRxService.java b/libraries-http/src/main/java/com/baeldung/retrofit/rx/GitHubRxService.java similarity index 100% rename from libraries/src/main/java/com/baeldung/retrofit/rx/GitHubRxService.java rename to libraries-http/src/main/java/com/baeldung/retrofit/rx/GitHubRxService.java diff --git a/libraries/src/main/java/com/baeldung/retrofitguide/GitHubServiceGenerator.java b/libraries-http/src/main/java/com/baeldung/retrofitguide/GitHubServiceGenerator.java similarity index 100% rename from libraries/src/main/java/com/baeldung/retrofitguide/GitHubServiceGenerator.java rename to libraries-http/src/main/java/com/baeldung/retrofitguide/GitHubServiceGenerator.java diff --git a/libraries/src/main/java/com/baeldung/retrofitguide/Main.java b/libraries-http/src/main/java/com/baeldung/retrofitguide/Main.java similarity index 100% rename from libraries/src/main/java/com/baeldung/retrofitguide/Main.java rename to libraries-http/src/main/java/com/baeldung/retrofitguide/Main.java diff --git a/libraries/src/main/java/com/baeldung/retrofitguide/User.java b/libraries-http/src/main/java/com/baeldung/retrofitguide/User.java similarity index 100% rename from libraries/src/main/java/com/baeldung/retrofitguide/User.java rename to libraries-http/src/main/java/com/baeldung/retrofitguide/User.java diff --git a/libraries/src/main/java/com/baeldung/retrofitguide/UserService.java b/libraries-http/src/main/java/com/baeldung/retrofitguide/UserService.java similarity index 100% rename from libraries/src/main/java/com/baeldung/retrofitguide/UserService.java rename to libraries-http/src/main/java/com/baeldung/retrofitguide/UserService.java diff --git a/libraries/src/test/java/com/baeldung/retrofit/basic/GitHubBasicApiLiveTest.java b/libraries-http/src/test/java/com/baeldung/retrofit/basic/GitHubBasicApiLiveTest.java similarity index 100% rename from libraries/src/test/java/com/baeldung/retrofit/basic/GitHubBasicApiLiveTest.java rename to libraries-http/src/test/java/com/baeldung/retrofit/basic/GitHubBasicApiLiveTest.java diff --git a/libraries/src/test/java/com/baeldung/retrofit/rx/GitHubRxLiveTest.java b/libraries-http/src/test/java/com/baeldung/retrofit/rx/GitHubRxLiveTest.java similarity index 100% rename from libraries/src/test/java/com/baeldung/retrofit/rx/GitHubRxLiveTest.java rename to libraries-http/src/test/java/com/baeldung/retrofit/rx/GitHubRxLiveTest.java diff --git a/libraries/src/test/java/com/baeldung/unirest/Article.java b/libraries-http/src/test/java/com/baeldung/unirest/Article.java similarity index 100% rename from libraries/src/test/java/com/baeldung/unirest/Article.java rename to libraries-http/src/test/java/com/baeldung/unirest/Article.java diff --git a/libraries/src/test/java/com/baeldung/unirest/HttpClientLiveTest.java b/libraries-http/src/test/java/com/baeldung/unirest/HttpClientLiveTest.java similarity index 100% rename from libraries/src/test/java/com/baeldung/unirest/HttpClientLiveTest.java rename to libraries-http/src/test/java/com/baeldung/unirest/HttpClientLiveTest.java diff --git a/libraries-security/pom.xml b/libraries-security/pom.xml index 17d57fe203..eb16575be8 100644 --- a/libraries-security/pom.xml +++ b/libraries-security/pom.xml @@ -25,6 +25,11 @@ spring-security-oauth2 ${spring-security-oauth2.version} + + org.springframework + spring-web + ${spring.version} + com.github.scribejava @@ -37,7 +42,16 @@ tink ${tink.version} - + + org.bouncycastle + bcprov-jdk15on + ${bouncycastle.version} + + + org.bouncycastle + bcpkix-jdk15on + ${bouncycastle.version} + junit junit @@ -54,6 +68,11 @@ cryptacular ${cryptacular.version} + + org.jasypt + jasypt + ${jasypt.version} + @@ -63,5 +82,8 @@ 1.3.1 1.2.2 1.2.2 + 1.9.2 + 1.58 + 4.3.8.RELEASE diff --git a/libraries/src/main/java/com/baeldung/bouncycastle/BouncyCastleCrypto.java b/libraries-security/src/main/java/com/baeldung/bouncycastle/BouncyCastleCrypto.java similarity index 98% rename from libraries/src/main/java/com/baeldung/bouncycastle/BouncyCastleCrypto.java rename to libraries-security/src/main/java/com/baeldung/bouncycastle/BouncyCastleCrypto.java index d7040407db..e351552c78 100644 --- a/libraries/src/main/java/com/baeldung/bouncycastle/BouncyCastleCrypto.java +++ b/libraries-security/src/main/java/com/baeldung/bouncycastle/BouncyCastleCrypto.java @@ -1,105 +1,105 @@ -package com.baeldung.bouncycastle; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.security.PrivateKey; -import java.security.cert.CertificateEncodingException; -import java.security.cert.CertificateException; -import java.security.cert.X509Certificate; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Iterator; -import java.util.List; - -import org.bouncycastle.asn1.ASN1InputStream; -import org.bouncycastle.asn1.cms.ContentInfo; -import org.bouncycastle.cert.X509CertificateHolder; -import org.bouncycastle.cert.jcajce.JcaCertStore; -import org.bouncycastle.cms.CMSAlgorithm; -import org.bouncycastle.cms.CMSEnvelopedData; -import org.bouncycastle.cms.CMSEnvelopedDataGenerator; -import org.bouncycastle.cms.CMSException; -import org.bouncycastle.cms.CMSProcessableByteArray; -import org.bouncycastle.cms.CMSSignedData; -import org.bouncycastle.cms.CMSSignedDataGenerator; -import org.bouncycastle.cms.CMSTypedData; -import org.bouncycastle.cms.KeyTransRecipientInformation; -import org.bouncycastle.cms.RecipientInformation; -import org.bouncycastle.cms.SignerInformation; -import org.bouncycastle.cms.SignerInformationStore; -import org.bouncycastle.cms.jcajce.JcaSignerInfoGeneratorBuilder; -import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoVerifierBuilder; -import org.bouncycastle.cms.jcajce.JceCMSContentEncryptorBuilder; -import org.bouncycastle.cms.jcajce.JceKeyTransEnvelopedRecipient; -import org.bouncycastle.cms.jcajce.JceKeyTransRecipient; -import org.bouncycastle.cms.jcajce.JceKeyTransRecipientInfoGenerator; -import org.bouncycastle.operator.ContentSigner; -import org.bouncycastle.operator.OperatorCreationException; -import org.bouncycastle.operator.OutputEncryptor; -import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; -import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder; -import org.bouncycastle.util.Store; - -public class BouncyCastleCrypto { - - public static byte[] signData(byte[] data, final X509Certificate signingCertificate, final PrivateKey signingKey) throws CertificateEncodingException, OperatorCreationException, CMSException, IOException { - byte[] signedMessage = null; - List certList = new ArrayList(); - CMSTypedData cmsData = new CMSProcessableByteArray(data); - certList.add(signingCertificate); - Store certs = new JcaCertStore(certList); - CMSSignedDataGenerator cmsGenerator = new CMSSignedDataGenerator(); - ContentSigner contentSigner = new JcaContentSignerBuilder("SHA256withRSA").build(signingKey); - cmsGenerator.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider("BC").build()).build(contentSigner, signingCertificate)); - cmsGenerator.addCertificates(certs); - CMSSignedData cms = cmsGenerator.generate(cmsData, true); - signedMessage = cms.getEncoded(); - return signedMessage; - } - - public static boolean verifSignData(final byte[] signedData) throws CMSException, IOException, OperatorCreationException, CertificateException { - ByteArrayInputStream bIn = new ByteArrayInputStream(signedData); - ASN1InputStream aIn = new ASN1InputStream(bIn); - CMSSignedData s = new CMSSignedData(ContentInfo.getInstance(aIn.readObject())); - aIn.close(); - bIn.close(); - Store certs = s.getCertificates(); - SignerInformationStore signers = s.getSignerInfos(); - Collection c = signers.getSigners(); - SignerInformation signer = c.iterator().next(); - Collection certCollection = certs.getMatches(signer.getSID()); - Iterator certIt = certCollection.iterator(); - X509CertificateHolder certHolder = certIt.next(); - boolean verifResult = signer.verify(new JcaSimpleSignerInfoVerifierBuilder().build(certHolder)); - if (!verifResult) { - return false; - } - return true; - } - - public static byte[] encryptData(final byte[] data, X509Certificate encryptionCertificate) throws CertificateEncodingException, CMSException, IOException { - byte[] encryptedData = null; - if (null != data && null != encryptionCertificate) { - CMSEnvelopedDataGenerator cmsEnvelopedDataGenerator = new CMSEnvelopedDataGenerator(); - JceKeyTransRecipientInfoGenerator jceKey = new JceKeyTransRecipientInfoGenerator(encryptionCertificate); - cmsEnvelopedDataGenerator.addRecipientInfoGenerator(jceKey); - CMSTypedData msg = new CMSProcessableByteArray(data); - OutputEncryptor encryptor = new JceCMSContentEncryptorBuilder(CMSAlgorithm.AES128_CBC).setProvider("BC").build(); - CMSEnvelopedData cmsEnvelopedData = cmsEnvelopedDataGenerator.generate(msg, encryptor); - encryptedData = cmsEnvelopedData.getEncoded(); - } - return encryptedData; - } - - public static byte[] decryptData(final byte[] encryptedData, final PrivateKey decryptionKey) throws CMSException { - byte[] decryptedData = null; - if (null != encryptedData && null != decryptionKey) { - CMSEnvelopedData envelopedData = new CMSEnvelopedData(encryptedData); - Collection recip = envelopedData.getRecipientInfos().getRecipients(); - KeyTransRecipientInformation recipientInfo = (KeyTransRecipientInformation) recip.iterator().next(); - JceKeyTransRecipient recipient = new JceKeyTransEnvelopedRecipient(decryptionKey); - decryptedData = recipientInfo.getContent(recipient); - } - return decryptedData; - } -} +package com.baeldung.bouncycastle; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.security.PrivateKey; +import java.security.cert.CertificateEncodingException; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +import org.bouncycastle.asn1.ASN1InputStream; +import org.bouncycastle.asn1.cms.ContentInfo; +import org.bouncycastle.cert.X509CertificateHolder; +import org.bouncycastle.cert.jcajce.JcaCertStore; +import org.bouncycastle.cms.CMSAlgorithm; +import org.bouncycastle.cms.CMSEnvelopedData; +import org.bouncycastle.cms.CMSEnvelopedDataGenerator; +import org.bouncycastle.cms.CMSException; +import org.bouncycastle.cms.CMSProcessableByteArray; +import org.bouncycastle.cms.CMSSignedData; +import org.bouncycastle.cms.CMSSignedDataGenerator; +import org.bouncycastle.cms.CMSTypedData; +import org.bouncycastle.cms.KeyTransRecipientInformation; +import org.bouncycastle.cms.RecipientInformation; +import org.bouncycastle.cms.SignerInformation; +import org.bouncycastle.cms.SignerInformationStore; +import org.bouncycastle.cms.jcajce.JcaSignerInfoGeneratorBuilder; +import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoVerifierBuilder; +import org.bouncycastle.cms.jcajce.JceCMSContentEncryptorBuilder; +import org.bouncycastle.cms.jcajce.JceKeyTransEnvelopedRecipient; +import org.bouncycastle.cms.jcajce.JceKeyTransRecipient; +import org.bouncycastle.cms.jcajce.JceKeyTransRecipientInfoGenerator; +import org.bouncycastle.operator.ContentSigner; +import org.bouncycastle.operator.OperatorCreationException; +import org.bouncycastle.operator.OutputEncryptor; +import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; +import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder; +import org.bouncycastle.util.Store; + +public class BouncyCastleCrypto { + + public static byte[] signData(byte[] data, final X509Certificate signingCertificate, final PrivateKey signingKey) throws CertificateEncodingException, OperatorCreationException, CMSException, IOException { + byte[] signedMessage = null; + List certList = new ArrayList(); + CMSTypedData cmsData = new CMSProcessableByteArray(data); + certList.add(signingCertificate); + Store certs = new JcaCertStore(certList); + CMSSignedDataGenerator cmsGenerator = new CMSSignedDataGenerator(); + ContentSigner contentSigner = new JcaContentSignerBuilder("SHA256withRSA").build(signingKey); + cmsGenerator.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider("BC").build()).build(contentSigner, signingCertificate)); + cmsGenerator.addCertificates(certs); + CMSSignedData cms = cmsGenerator.generate(cmsData, true); + signedMessage = cms.getEncoded(); + return signedMessage; + } + + public static boolean verifSignData(final byte[] signedData) throws CMSException, IOException, OperatorCreationException, CertificateException { + ByteArrayInputStream bIn = new ByteArrayInputStream(signedData); + ASN1InputStream aIn = new ASN1InputStream(bIn); + CMSSignedData s = new CMSSignedData(ContentInfo.getInstance(aIn.readObject())); + aIn.close(); + bIn.close(); + Store certs = s.getCertificates(); + SignerInformationStore signers = s.getSignerInfos(); + Collection c = signers.getSigners(); + SignerInformation signer = c.iterator().next(); + Collection certCollection = certs.getMatches(signer.getSID()); + Iterator certIt = certCollection.iterator(); + X509CertificateHolder certHolder = certIt.next(); + boolean verifResult = signer.verify(new JcaSimpleSignerInfoVerifierBuilder().build(certHolder)); + if (!verifResult) { + return false; + } + return true; + } + + public static byte[] encryptData(final byte[] data, X509Certificate encryptionCertificate) throws CertificateEncodingException, CMSException, IOException { + byte[] encryptedData = null; + if (null != data && null != encryptionCertificate) { + CMSEnvelopedDataGenerator cmsEnvelopedDataGenerator = new CMSEnvelopedDataGenerator(); + JceKeyTransRecipientInfoGenerator jceKey = new JceKeyTransRecipientInfoGenerator(encryptionCertificate); + cmsEnvelopedDataGenerator.addRecipientInfoGenerator(jceKey); + CMSTypedData msg = new CMSProcessableByteArray(data); + OutputEncryptor encryptor = new JceCMSContentEncryptorBuilder(CMSAlgorithm.AES128_CBC).setProvider("BC").build(); + CMSEnvelopedData cmsEnvelopedData = cmsEnvelopedDataGenerator.generate(msg, encryptor); + encryptedData = cmsEnvelopedData.getEncoded(); + } + return encryptedData; + } + + public static byte[] decryptData(final byte[] encryptedData, final PrivateKey decryptionKey) throws CMSException { + byte[] decryptedData = null; + if (null != encryptedData && null != decryptionKey) { + CMSEnvelopedData envelopedData = new CMSEnvelopedData(encryptedData); + Collection recip = envelopedData.getRecipientInfos().getRecipients(); + KeyTransRecipientInformation recipientInfo = (KeyTransRecipientInformation) recip.iterator().next(); + JceKeyTransRecipient recipient = new JceKeyTransEnvelopedRecipient(decryptionKey); + decryptedData = recipientInfo.getContent(recipient); + } + return decryptedData; + } +} diff --git a/libraries-security/src/main/resources/Baeldung.cer b/libraries-security/src/main/resources/Baeldung.cer new file mode 100644 index 0000000000..72d0918424 --- /dev/null +++ b/libraries-security/src/main/resources/Baeldung.cer @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDPjCCAiagAwIBAgIJAPvd1gx14C3CMA0GCSqGSIb3DQEBBQUAMEcxCzAJBgNV +BAYTAk1BMRAwDgYDVQQIEwdNb3JvY2NvMRMwEQYDVQQHEwpDYXNhYmxhbmNhMREw +DwYDVQQDEwhCYWVsZHVuZzAeFw0xNzEwMTIxMDQzMTRaFw0yNzEwMTMxMDQzMTRa +MEcxCzAJBgNVBAYTAk1BMRAwDgYDVQQIEwdNb3JvY2NvMRMwEQYDVQQHEwpDYXNh +YmxhbmNhMREwDwYDVQQDEwhCYWVsZHVuZzCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBAMyi5GmOeN4QaH/CP5gSOyHX8znb5TDHWV8wc+ZT7kNU8zt5tGMh +jozK6hax155/6tOsBDR0rSYBhL+Dm/+uCVS7qOlRHhf6cNGtzGF1gnNJB2WjI8oM +AYm24xpLj1WphKUwKrn3nTMPnQup5OoNAMYl99flANrRYVjjxrLQvDZDUio6Iujr +CZ2TtXGM0g/gP++28KT7g1KlUui3xtB0u33wx7UN8Fix3JmjOaPHGwxGpwP3VGSj +fs8cuhqVwRQaZpCOoHU/P8wpXKw80sSdhz+SRueMPtVYqK0CiLL5/O0h0Y3le4IV +whgg3KG1iTGOWn60UMFn1EYmQ18k5Nsma6UCAwEAAaMtMCswCQYDVR0TBAIwADAR +BglghkgBhvhCAQEEBAMCBPAwCwYDVR0PBAQDAgUgMA0GCSqGSIb3DQEBBQUAA4IB +AQC8DDBmJ3p4xytxBiE0s4p1715WT6Dm/QJHp0XC0hkSoyZKDh+XVmrzm+J3SiW1 +vpswb5hLgPo040YX9jnDmgOD+TpleTuKHxZRYj92UYWmdjkWLVtFMcvOh+gxBiAP +pHIqZsqo8lfcyAuh8Jx834IXbknfCUtERDLG/rU9P/3XJhrM2GC5qPQznrW4EYhU +CGPyIJXmvATMVvXMWCtfogAL+n42vjYXQXZoAWomHhLHoNbSJUErnNdWDOh4WoJt +XJCxA6U5LSBplqb3wB2hUTqw+0admKltvmy+KA1PD7OxoGiY7V544zeGqJam1qxU +ia7y5BL6uOa/4ShSV8pcJDYz +-----END CERTIFICATE----- diff --git a/libraries/src/test/java/com/baeldung/bouncycastle/BouncyCastleLiveTest.java b/libraries-security/src/test/java/com/baeldung/bouncycastle/BouncyCastleLiveTest.java similarity index 97% rename from libraries/src/test/java/com/baeldung/bouncycastle/BouncyCastleLiveTest.java rename to libraries-security/src/test/java/com/baeldung/bouncycastle/BouncyCastleLiveTest.java index 009119d97a..37e8e5f6ba 100644 --- a/libraries/src/test/java/com/baeldung/bouncycastle/BouncyCastleLiveTest.java +++ b/libraries-security/src/test/java/com/baeldung/bouncycastle/BouncyCastleLiveTest.java @@ -1,50 +1,50 @@ -package com.baeldung.bouncycastle; - -import static org.junit.Assert.assertTrue; - -import java.io.FileInputStream; -import java.io.IOException; -import java.security.KeyStore; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.security.NoSuchProviderException; -import java.security.PrivateKey; -import java.security.Security; -import java.security.UnrecoverableKeyException; -import java.security.cert.CertificateException; -import java.security.cert.CertificateFactory; -import java.security.cert.X509Certificate; - -import org.bouncycastle.cms.CMSException; -import org.bouncycastle.jce.provider.BouncyCastleProvider; -import org.bouncycastle.operator.OperatorCreationException; -import org.junit.Test; - -public class BouncyCastleLiveTest { - - String certificatePath = "src/main/resources/Baeldung.cer"; - String privateKeyPath = "src/main/resources/Baeldung.p12"; - char[] p12Password = "password".toCharArray(); - char[] keyPassword = "password".toCharArray(); - - @Test - public void givenCryptographicResource_whenOperationSuccess_returnTrue() throws CertificateException, NoSuchProviderException, NoSuchAlgorithmException, IOException, KeyStoreException, UnrecoverableKeyException, CMSException, OperatorCreationException { - Security.addProvider(new BouncyCastleProvider()); - - CertificateFactory certFactory = CertificateFactory.getInstance("X.509", "BC"); - X509Certificate certificate = (X509Certificate) certFactory.generateCertificate(new FileInputStream(certificatePath)); - KeyStore keystore = KeyStore.getInstance("PKCS12"); - keystore.load(new FileInputStream(privateKeyPath), p12Password); - PrivateKey privateKey = (PrivateKey) keystore.getKey("baeldung", keyPassword); - String secretMessage = "My password is 123456Seven"; - System.out.println("Original Message : " + secretMessage); - byte[] stringToEncrypt = secretMessage.getBytes(); - byte[] encryptedData = BouncyCastleCrypto.encryptData(stringToEncrypt, certificate); - byte[] rawData = BouncyCastleCrypto.decryptData(encryptedData, privateKey); - String decryptedMessage = new String(rawData); - assertTrue(decryptedMessage.equals(secretMessage)); - byte[] signedData = BouncyCastleCrypto.signData(rawData, certificate, privateKey); - Boolean check = BouncyCastleCrypto.verifSignData(signedData); - assertTrue(check); - } -} +package com.baeldung.bouncycastle; + +import static org.junit.Assert.assertTrue; + +import java.io.FileInputStream; +import java.io.IOException; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.PrivateKey; +import java.security.Security; +import java.security.UnrecoverableKeyException; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; + +import org.bouncycastle.cms.CMSException; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.operator.OperatorCreationException; +import org.junit.Test; + +public class BouncyCastleLiveTest { + + String certificatePath = "src/main/resources/Baeldung.cer"; + String privateKeyPath = "src/main/resources/Baeldung.p12"; + char[] p12Password = "password".toCharArray(); + char[] keyPassword = "password".toCharArray(); + + @Test + public void givenCryptographicResource_whenOperationSuccess_returnTrue() throws CertificateException, NoSuchProviderException, NoSuchAlgorithmException, IOException, KeyStoreException, UnrecoverableKeyException, CMSException, OperatorCreationException { + Security.addProvider(new BouncyCastleProvider()); + + CertificateFactory certFactory = CertificateFactory.getInstance("X.509", "BC"); + X509Certificate certificate = (X509Certificate) certFactory.generateCertificate(new FileInputStream(certificatePath)); + KeyStore keystore = KeyStore.getInstance("PKCS12"); + keystore.load(new FileInputStream(privateKeyPath), p12Password); + PrivateKey privateKey = (PrivateKey) keystore.getKey("baeldung", keyPassword); + String secretMessage = "My password is 123456Seven"; + System.out.println("Original Message : " + secretMessage); + byte[] stringToEncrypt = secretMessage.getBytes(); + byte[] encryptedData = BouncyCastleCrypto.encryptData(stringToEncrypt, certificate); + byte[] rawData = BouncyCastleCrypto.decryptData(encryptedData, privateKey); + String decryptedMessage = new String(rawData); + assertTrue(decryptedMessage.equals(secretMessage)); + byte[] signedData = BouncyCastleCrypto.signData(rawData, certificate, privateKey); + Boolean check = BouncyCastleCrypto.verifSignData(signedData); + assertTrue(check); + } +} diff --git a/libraries/src/test/java/com/baeldung/jasypt/JasyptUnitTest.java b/libraries-security/src/test/java/com/baeldung/jasypt/JasyptUnitTest.java similarity index 100% rename from libraries/src/test/java/com/baeldung/jasypt/JasyptUnitTest.java rename to libraries-security/src/test/java/com/baeldung/jasypt/JasyptUnitTest.java diff --git a/libraries-security/src/test/java/com/baeldung/tink/TinkUnitTest.java b/libraries-security/src/test/java/com/baeldung/tink/TinkLiveTest.java similarity index 96% rename from libraries-security/src/test/java/com/baeldung/tink/TinkUnitTest.java rename to libraries-security/src/test/java/com/baeldung/tink/TinkLiveTest.java index b98c698016..c4bd487457 100644 --- a/libraries-security/src/test/java/com/baeldung/tink/TinkUnitTest.java +++ b/libraries-security/src/test/java/com/baeldung/tink/TinkLiveTest.java @@ -18,7 +18,9 @@ import org.junit.Test; import java.security.GeneralSecurityException; -public class TinkUnitTest { +public class TinkLiveTest { + + //need to download policy files and put them into ${java.home}/jre/lib/security/ private static final String PLAINTEXT = "BAELDUNG"; private static final String DATA = "TINK"; diff --git a/libraries-server/README.md b/libraries-server/README.md index dc6bcd0716..b5392f5883 100644 --- a/libraries-server/README.md +++ b/libraries-server/README.md @@ -1,4 +1,4 @@ -### Relevant articles +## Relevant Articles: - [Embedded Jetty Server in Java](http://www.baeldung.com/jetty-embedded) - [Introduction to Netty](http://www.baeldung.com/netty) @@ -8,3 +8,4 @@ - [Testing Netty with EmbeddedChannel](http://www.baeldung.com/testing-netty-embedded-channel) - [MQTT Client in Java](https://www.baeldung.com/java-mqtt-client) - [Guide to XMPP Smack Client](https://www.baeldung.com/xmpp-smack-chat-client) +- [A Guide to NanoHTTPD](https://www.baeldung.com/nanohttpd) diff --git a/libraries-testing/README.md b/libraries-testing/README.md new file mode 100644 index 0000000000..6b25a3b875 --- /dev/null +++ b/libraries-testing/README.md @@ -0,0 +1,8 @@ +### Relevant articles + +- [Introduction to Serenity BDD](http://www.baeldung.com/serenity-bdd) +- [Introduction to JSONassert](http://www.baeldung.com/jsonassert) +- [Serenity BDD and Screenplay](http://www.baeldung.com/serenity-screenplay) +- [Serenity BDD with Spring and JBehave](http://www.baeldung.com/serenity-spring-jbehave) +- [Introduction to Awaitlity](http://www.baeldung.com/awaitlity-testing) +- [Introduction to Hoverfly in Java](http://www.baeldung.com/hoverfly) \ No newline at end of file diff --git a/libraries-testing/log4j.properties b/libraries-testing/log4j.properties new file mode 100644 index 0000000000..ed367509d1 --- /dev/null +++ b/libraries-testing/log4j.properties @@ -0,0 +1,5 @@ +log4j.rootLogger=INFO, stdout +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.Target=System.out +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n \ No newline at end of file diff --git a/libraries-testing/pom.xml b/libraries-testing/pom.xml new file mode 100644 index 0000000000..8f7a27bbfa --- /dev/null +++ b/libraries-testing/pom.xml @@ -0,0 +1,170 @@ + + + + 4.0.0 + libraries-testing + libraries-testing + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + + + + + net.serenity-bdd + serenity-core + ${serenity.version} + test + + + org.asciidoctor + asciidoctorj + + + + + net.serenity-bdd + serenity-junit + ${serenity.version} + test + + + net.serenity-bdd + serenity-jbehave + ${serenity.jbehave.version} + test + + + net.serenity-bdd + serenity-rest-assured + ${serenity.version} + test + + + net.serenity-bdd + serenity-jira-requirements-provider + ${serenity.jira.version} + test + + + net.serenity-bdd + serenity-spring + ${serenity.version} + test + + + org.springframework + spring-test + + + + + net.serenity-bdd + serenity-screenplay + ${serenity.version} + test + + + net.serenity-bdd + serenity-screenplay-webdriver + ${serenity.version} + test + + + org.skyscreamer + jsonassert + ${jsonassert.version} + + + org.awaitility + awaitility + ${awaitility.version} + test + + + org.awaitility + awaitility-proxy + ${awaitility.version} + test + + + io.specto + hoverfly-java + ${hoverfly-java.version} + + + org.springframework + spring-web + ${spring.version} + + + io.rest-assured + spring-mock-mvc + ${spring-mock-mvc.version} + test + + + org.assertj + assertj-core + ${assertj.version} + + + + net.serenity-bdd + serenity-core + ${serenity.version} + test + + + org.asciidoctor + asciidoctorj + + + + + org.asciidoctor + asciidoctor-maven-plugin + 1.5.7.1 + + + + + + + + + net.serenity-bdd.maven.plugins + serenity-maven-plugin + ${serenity.plugin.version} + + + serenity-reports + post-integration-test + + aggregate + + + + + + + + + + 1.9.26 + 1.41.0 + 1.9.0 + 1.9.27 + 1.5.0 + 3.0.0 + 0.8.1 + 4.3.8.RELEASE + 3.0.3 + 3.6.2 + + + diff --git a/libraries-testing/serenity.properties b/libraries-testing/serenity.properties new file mode 100644 index 0000000000..c77df9c0f7 --- /dev/null +++ b/libraries-testing/serenity.properties @@ -0,0 +1,4 @@ +jira.url= +jira.project= +jira.username= +jira.password= \ No newline at end of file diff --git a/libraries/src/main/java/com/baeldung/awaitility/AsyncService.java b/libraries-testing/src/main/java/com/baeldung/awaitility/AsyncService.java similarity index 100% rename from libraries/src/main/java/com/baeldung/awaitility/AsyncService.java rename to libraries-testing/src/main/java/com/baeldung/awaitility/AsyncService.java diff --git a/libraries/src/main/java/com/baeldung/serenity/github/GitHubUser.java b/libraries-testing/src/main/java/com/baeldung/serenity/github/GitHubUser.java similarity index 100% rename from libraries/src/main/java/com/baeldung/serenity/github/GitHubUser.java rename to libraries-testing/src/main/java/com/baeldung/serenity/github/GitHubUser.java diff --git a/libraries/src/main/java/com/baeldung/serenity/membership/Commodity.java b/libraries-testing/src/main/java/com/baeldung/serenity/membership/Commodity.java similarity index 100% rename from libraries/src/main/java/com/baeldung/serenity/membership/Commodity.java rename to libraries-testing/src/main/java/com/baeldung/serenity/membership/Commodity.java diff --git a/libraries/src/main/java/com/baeldung/serenity/membership/Member.java b/libraries-testing/src/main/java/com/baeldung/serenity/membership/Member.java similarity index 100% rename from libraries/src/main/java/com/baeldung/serenity/membership/Member.java rename to libraries-testing/src/main/java/com/baeldung/serenity/membership/Member.java diff --git a/libraries/src/main/java/com/baeldung/serenity/membership/MemberGrade.java b/libraries-testing/src/main/java/com/baeldung/serenity/membership/MemberGrade.java similarity index 100% rename from libraries/src/main/java/com/baeldung/serenity/membership/MemberGrade.java rename to libraries-testing/src/main/java/com/baeldung/serenity/membership/MemberGrade.java diff --git a/libraries/src/main/java/com/baeldung/serenity/spring/AdderController.java b/libraries-testing/src/main/java/com/baeldung/serenity/spring/AdderController.java similarity index 100% rename from libraries/src/main/java/com/baeldung/serenity/spring/AdderController.java rename to libraries-testing/src/main/java/com/baeldung/serenity/spring/AdderController.java diff --git a/libraries/src/main/java/com/baeldung/serenity/spring/AdderService.java b/libraries-testing/src/main/java/com/baeldung/serenity/spring/AdderService.java similarity index 100% rename from libraries/src/main/java/com/baeldung/serenity/spring/AdderService.java rename to libraries-testing/src/main/java/com/baeldung/serenity/spring/AdderService.java diff --git a/libraries/src/main/java/com/baeldung/serenity/spring/PlainAdderController.java b/libraries-testing/src/main/java/com/baeldung/serenity/spring/PlainAdderController.java similarity index 100% rename from libraries/src/main/java/com/baeldung/serenity/spring/PlainAdderController.java rename to libraries-testing/src/main/java/com/baeldung/serenity/spring/PlainAdderController.java diff --git a/libraries/src/test/java/com/baeldung/awaitility/AsyncServiceLongRunningManualTest.java b/libraries-testing/src/test/java/com/baeldung/awaitility/AsyncServiceLongRunningManualTest.java similarity index 100% rename from libraries/src/test/java/com/baeldung/awaitility/AsyncServiceLongRunningManualTest.java rename to libraries-testing/src/test/java/com/baeldung/awaitility/AsyncServiceLongRunningManualTest.java diff --git a/libraries/src/test/java/com/baeldung/hoverfly/HoverflyApiLiveTest.java b/libraries-testing/src/test/java/com/baeldung/hoverfly/HoverflyApiLiveTest.java similarity index 100% rename from libraries/src/test/java/com/baeldung/hoverfly/HoverflyApiLiveTest.java rename to libraries-testing/src/test/java/com/baeldung/hoverfly/HoverflyApiLiveTest.java diff --git a/libraries/src/test/java/com/baeldung/jsonassert/JsonAssertUnitTest.java b/libraries-testing/src/test/java/com/baeldung/jsonassert/JsonAssertUnitTest.java similarity index 100% rename from libraries/src/test/java/com/baeldung/jsonassert/JsonAssertUnitTest.java rename to libraries-testing/src/test/java/com/baeldung/jsonassert/JsonAssertUnitTest.java diff --git a/libraries/src/test/java/com/baeldung/serenity/GithubUserProfilePayloadIntegrationTest.java b/libraries-testing/src/test/java/com/baeldung/serenity/GithubUserProfilePayloadIntegrationTest.java similarity index 100% rename from libraries/src/test/java/com/baeldung/serenity/GithubUserProfilePayloadIntegrationTest.java rename to libraries-testing/src/test/java/com/baeldung/serenity/GithubUserProfilePayloadIntegrationTest.java diff --git a/libraries/src/test/java/com/baeldung/serenity/GoogleSearchLiveTest.java b/libraries-testing/src/test/java/com/baeldung/serenity/GoogleSearchLiveTest.java similarity index 100% rename from libraries/src/test/java/com/baeldung/serenity/GoogleSearchLiveTest.java rename to libraries-testing/src/test/java/com/baeldung/serenity/GoogleSearchLiveTest.java diff --git a/libraries/src/test/java/com/baeldung/serenity/GoogleSearchPageObjectLiveTest.java b/libraries-testing/src/test/java/com/baeldung/serenity/GoogleSearchPageObjectLiveTest.java similarity index 100% rename from libraries/src/test/java/com/baeldung/serenity/GoogleSearchPageObjectLiveTest.java rename to libraries-testing/src/test/java/com/baeldung/serenity/GoogleSearchPageObjectLiveTest.java diff --git a/libraries/src/test/java/com/baeldung/serenity/GoogleSearchScreenplayLiveTest.java b/libraries-testing/src/test/java/com/baeldung/serenity/GoogleSearchScreenplayLiveTest.java similarity index 100% rename from libraries/src/test/java/com/baeldung/serenity/GoogleSearchScreenplayLiveTest.java rename to libraries-testing/src/test/java/com/baeldung/serenity/GoogleSearchScreenplayLiveTest.java diff --git a/libraries/src/test/java/com/baeldung/serenity/MemberStatusIntegrationTest.java b/libraries-testing/src/test/java/com/baeldung/serenity/MemberStatusIntegrationTest.java similarity index 100% rename from libraries/src/test/java/com/baeldung/serenity/MemberStatusIntegrationTest.java rename to libraries-testing/src/test/java/com/baeldung/serenity/MemberStatusIntegrationTest.java diff --git a/libraries/src/test/java/com/baeldung/serenity/github/GithubRestAssuredUserAPISteps.java b/libraries-testing/src/test/java/com/baeldung/serenity/github/GithubRestAssuredUserAPISteps.java similarity index 100% rename from libraries/src/test/java/com/baeldung/serenity/github/GithubRestAssuredUserAPISteps.java rename to libraries-testing/src/test/java/com/baeldung/serenity/github/GithubRestAssuredUserAPISteps.java diff --git a/libraries/src/test/java/com/baeldung/serenity/github/GithubRestUserAPISteps.java b/libraries-testing/src/test/java/com/baeldung/serenity/github/GithubRestUserAPISteps.java similarity index 100% rename from libraries/src/test/java/com/baeldung/serenity/github/GithubRestUserAPISteps.java rename to libraries-testing/src/test/java/com/baeldung/serenity/github/GithubRestUserAPISteps.java diff --git a/libraries/src/test/java/com/baeldung/serenity/github/GithubUserProfilePayloadStepDefinitions.java b/libraries-testing/src/test/java/com/baeldung/serenity/github/GithubUserProfilePayloadStepDefinitions.java similarity index 100% rename from libraries/src/test/java/com/baeldung/serenity/github/GithubUserProfilePayloadStepDefinitions.java rename to libraries-testing/src/test/java/com/baeldung/serenity/github/GithubUserProfilePayloadStepDefinitions.java diff --git a/libraries/src/test/java/com/baeldung/serenity/membership/MemberStatusSteps.java b/libraries-testing/src/test/java/com/baeldung/serenity/membership/MemberStatusSteps.java similarity index 100% rename from libraries/src/test/java/com/baeldung/serenity/membership/MemberStatusSteps.java rename to libraries-testing/src/test/java/com/baeldung/serenity/membership/MemberStatusSteps.java diff --git a/libraries/src/test/java/com/baeldung/serenity/pageobjects/GoogleSearchPageObject.java b/libraries-testing/src/test/java/com/baeldung/serenity/pageobjects/GoogleSearchPageObject.java similarity index 100% rename from libraries/src/test/java/com/baeldung/serenity/pageobjects/GoogleSearchPageObject.java rename to libraries-testing/src/test/java/com/baeldung/serenity/pageobjects/GoogleSearchPageObject.java diff --git a/libraries/src/test/java/com/baeldung/serenity/screenplay/GoogleSearchPage.java b/libraries-testing/src/test/java/com/baeldung/serenity/screenplay/GoogleSearchPage.java similarity index 100% rename from libraries/src/test/java/com/baeldung/serenity/screenplay/GoogleSearchPage.java rename to libraries-testing/src/test/java/com/baeldung/serenity/screenplay/GoogleSearchPage.java diff --git a/libraries/src/test/java/com/baeldung/serenity/screenplay/GoogleSearchResults.java b/libraries-testing/src/test/java/com/baeldung/serenity/screenplay/GoogleSearchResults.java similarity index 100% rename from libraries/src/test/java/com/baeldung/serenity/screenplay/GoogleSearchResults.java rename to libraries-testing/src/test/java/com/baeldung/serenity/screenplay/GoogleSearchResults.java diff --git a/libraries/src/test/java/com/baeldung/serenity/screenplay/SearchForKeyword.java b/libraries-testing/src/test/java/com/baeldung/serenity/screenplay/SearchForKeyword.java similarity index 100% rename from libraries/src/test/java/com/baeldung/serenity/screenplay/SearchForKeyword.java rename to libraries-testing/src/test/java/com/baeldung/serenity/screenplay/SearchForKeyword.java diff --git a/libraries/src/test/java/com/baeldung/serenity/screenplay/StartWith.java b/libraries-testing/src/test/java/com/baeldung/serenity/screenplay/StartWith.java similarity index 100% rename from libraries/src/test/java/com/baeldung/serenity/screenplay/StartWith.java rename to libraries-testing/src/test/java/com/baeldung/serenity/screenplay/StartWith.java diff --git a/libraries/src/test/java/com/baeldung/serenity/spring/AdderClassDirtiesContextIntegrationTest.java b/libraries-testing/src/test/java/com/baeldung/serenity/spring/AdderClassDirtiesContextIntegrationTest.java similarity index 100% rename from libraries/src/test/java/com/baeldung/serenity/spring/AdderClassDirtiesContextIntegrationTest.java rename to libraries-testing/src/test/java/com/baeldung/serenity/spring/AdderClassDirtiesContextIntegrationTest.java diff --git a/libraries/src/test/java/com/baeldung/serenity/spring/AdderIntegrationTest.java b/libraries-testing/src/test/java/com/baeldung/serenity/spring/AdderIntegrationTest.java similarity index 100% rename from libraries/src/test/java/com/baeldung/serenity/spring/AdderIntegrationTest.java rename to libraries-testing/src/test/java/com/baeldung/serenity/spring/AdderIntegrationTest.java diff --git a/libraries/src/test/java/com/baeldung/serenity/spring/AdderMethodDirtiesContextDependencyWorkaroundIntegrationTest.java b/libraries-testing/src/test/java/com/baeldung/serenity/spring/AdderMethodDirtiesContextDependencyWorkaroundIntegrationTest.java similarity index 100% rename from libraries/src/test/java/com/baeldung/serenity/spring/AdderMethodDirtiesContextDependencyWorkaroundIntegrationTest.java rename to libraries-testing/src/test/java/com/baeldung/serenity/spring/AdderMethodDirtiesContextDependencyWorkaroundIntegrationTest.java diff --git a/libraries/src/test/java/com/baeldung/serenity/spring/AdderMethodDirtiesContextInitWorkaroundIntegrationTest.java b/libraries-testing/src/test/java/com/baeldung/serenity/spring/AdderMethodDirtiesContextInitWorkaroundIntegrationTest.java similarity index 100% rename from libraries/src/test/java/com/baeldung/serenity/spring/AdderMethodDirtiesContextInitWorkaroundIntegrationTest.java rename to libraries-testing/src/test/java/com/baeldung/serenity/spring/AdderMethodDirtiesContextInitWorkaroundIntegrationTest.java diff --git a/libraries/src/test/java/com/baeldung/serenity/spring/AdderMethodDirtiesContextIntegrationTest.java b/libraries-testing/src/test/java/com/baeldung/serenity/spring/AdderMethodDirtiesContextIntegrationTest.java similarity index 100% rename from libraries/src/test/java/com/baeldung/serenity/spring/AdderMethodDirtiesContextIntegrationTest.java rename to libraries-testing/src/test/java/com/baeldung/serenity/spring/AdderMethodDirtiesContextIntegrationTest.java diff --git a/libraries/src/test/java/com/baeldung/serenity/spring/AdderMethodRuleIntegrationTest.java b/libraries-testing/src/test/java/com/baeldung/serenity/spring/AdderMethodRuleIntegrationTest.java similarity index 100% rename from libraries/src/test/java/com/baeldung/serenity/spring/AdderMethodRuleIntegrationTest.java rename to libraries-testing/src/test/java/com/baeldung/serenity/spring/AdderMethodRuleIntegrationTest.java diff --git a/libraries/src/test/java/com/baeldung/serenity/spring/AdderMockMvcIntegrationTest.java b/libraries-testing/src/test/java/com/baeldung/serenity/spring/AdderMockMvcIntegrationTest.java similarity index 100% rename from libraries/src/test/java/com/baeldung/serenity/spring/AdderMockMvcIntegrationTest.java rename to libraries-testing/src/test/java/com/baeldung/serenity/spring/AdderMockMvcIntegrationTest.java diff --git a/libraries/src/test/java/com/baeldung/serenity/spring/AdderServiceIntegrationTest.java b/libraries-testing/src/test/java/com/baeldung/serenity/spring/AdderServiceIntegrationTest.java similarity index 100% rename from libraries/src/test/java/com/baeldung/serenity/spring/AdderServiceIntegrationTest.java rename to libraries-testing/src/test/java/com/baeldung/serenity/spring/AdderServiceIntegrationTest.java diff --git a/libraries/src/test/java/com/baeldung/serenity/spring/AdderSpringSerenityRunnerIntegrationTest.java b/libraries-testing/src/test/java/com/baeldung/serenity/spring/AdderSpringSerenityRunnerIntegrationTest.java similarity index 100% rename from libraries/src/test/java/com/baeldung/serenity/spring/AdderSpringSerenityRunnerIntegrationTest.java rename to libraries-testing/src/test/java/com/baeldung/serenity/spring/AdderSpringSerenityRunnerIntegrationTest.java diff --git a/libraries/src/test/java/com/baeldung/serenity/spring/RandomNumberUtil.java b/libraries-testing/src/test/java/com/baeldung/serenity/spring/RandomNumberUtil.java similarity index 100% rename from libraries/src/test/java/com/baeldung/serenity/spring/RandomNumberUtil.java rename to libraries-testing/src/test/java/com/baeldung/serenity/spring/RandomNumberUtil.java diff --git a/libraries/src/test/java/com/baeldung/serenity/spring/steps/AdderConstructorDependencySteps.java b/libraries-testing/src/test/java/com/baeldung/serenity/spring/steps/AdderConstructorDependencySteps.java similarity index 100% rename from libraries/src/test/java/com/baeldung/serenity/spring/steps/AdderConstructorDependencySteps.java rename to libraries-testing/src/test/java/com/baeldung/serenity/spring/steps/AdderConstructorDependencySteps.java diff --git a/libraries/src/test/java/com/baeldung/serenity/spring/steps/AdderRestSteps.java b/libraries-testing/src/test/java/com/baeldung/serenity/spring/steps/AdderRestSteps.java similarity index 100% rename from libraries/src/test/java/com/baeldung/serenity/spring/steps/AdderRestSteps.java rename to libraries-testing/src/test/java/com/baeldung/serenity/spring/steps/AdderRestSteps.java diff --git a/libraries/src/test/java/com/baeldung/serenity/spring/steps/AdderServiceSteps.java b/libraries-testing/src/test/java/com/baeldung/serenity/spring/steps/AdderServiceSteps.java similarity index 100% rename from libraries/src/test/java/com/baeldung/serenity/spring/steps/AdderServiceSteps.java rename to libraries-testing/src/test/java/com/baeldung/serenity/spring/steps/AdderServiceSteps.java diff --git a/libraries/src/test/java/com/baeldung/serenity/spring/steps/AdderSteps.java b/libraries-testing/src/test/java/com/baeldung/serenity/spring/steps/AdderSteps.java similarity index 100% rename from libraries/src/test/java/com/baeldung/serenity/spring/steps/AdderSteps.java rename to libraries-testing/src/test/java/com/baeldung/serenity/spring/steps/AdderSteps.java diff --git a/libraries/src/test/java/com/baeldung/serenity/spring/stories/AdderStory.java b/libraries-testing/src/test/java/com/baeldung/serenity/spring/stories/AdderStory.java similarity index 100% rename from libraries/src/test/java/com/baeldung/serenity/spring/stories/AdderStory.java rename to libraries-testing/src/test/java/com/baeldung/serenity/spring/stories/AdderStory.java diff --git a/libraries/src/test/resources/adder-beans.xml b/libraries-testing/src/test/resources/adder-beans.xml similarity index 100% rename from libraries/src/test/resources/adder-beans.xml rename to libraries-testing/src/test/resources/adder-beans.xml diff --git a/libraries/README.md b/libraries/README.md index c7b40e3c94..4ac63e044f 100644 --- a/libraries/README.md +++ b/libraries/README.md @@ -1,48 +1,30 @@ ### Relevant articles -- [Intro to Jasypt](http://www.baeldung.com/jasypt) - [Introduction to Javatuples](http://www.baeldung.com/java-tuples) - [Introduction to Javassist](http://www.baeldung.com/javassist) - [Introduction to Apache Flink with Java](http://www.baeldung.com/apache-flink) - [Introduction to JSONassert](http://www.baeldung.com/jsonassert) - [Intro to JaVers](http://www.baeldung.com/javers) -- [Introduction to Serenity BDD](http://www.baeldung.com/serenity-bdd) - [Merging Streams in Java](http://www.baeldung.com/java-merge-streams) -- [Serenity BDD and Screenplay](http://www.baeldung.com/serenity-screenplay) - [Introduction to Quartz](http://www.baeldung.com/quartz) - [How to Warm Up the JVM](http://www.baeldung.com/java-jvm-warmup) - [Software Transactional Memory in Java Using Multiverse](http://www.baeldung.com/java-multiverse-stm) - [Serenity BDD with Spring and JBehave](http://www.baeldung.com/serenity-spring-jbehave) - [Locality-Sensitive Hashing in Java Using Java-LSH](http://www.baeldung.com/locality-sensitive-hashing) -- [Introduction to Awaitlity](http://www.baeldung.com/awaitlity-testing) -- [Guide to the HyperLogLog Algorithm](http://www.baeldung.com/java-hyperloglog) - [Introduction to Neuroph](http://www.baeldung.com/neuroph) - [Quick Guide to RSS with Rome](http://www.baeldung.com/rome-rss) - [Introduction to PCollections](http://www.baeldung.com/java-pcollections) -- [Introduction to Hoverfly in Java](http://www.baeldung.com/hoverfly) - [Introduction to Eclipse Collections](http://www.baeldung.com/eclipse-collections) - [DistinctBy in the Java Stream API](http://www.baeldung.com/java-streams-distinct-by) - [Introduction to NoException](http://www.baeldung.com/no-exception) -- [Introduction to Conflict-Free Replicated Data Types](http://www.baeldung.com/java-conflict-free-replicated-data-types) -- [Introduction to javax.measure](http://www.baeldung.com/javax-measure) - [Spring Yarg Integration](http://www.baeldung.com/spring-yarg) - [Delete a Directory Recursively in Java](http://www.baeldung.com/java-delete-directory) - [Guide to JDeferred](http://www.baeldung.com/jdeferred) -- [Integrating Retrofit with RxJava](http://www.baeldung.com/retrofit-rxjava) - [Introduction to MBassador](http://www.baeldung.com/mbassador) -- [Introduction to Retrofit](http://www.baeldung.com/retrofit) - [Using Pairs in Java](http://www.baeldung.com/java-pairs) - [Introduction to Caffeine](http://www.baeldung.com/java-caching-caffeine) -- [Introduction To Docx4J](http://www.baeldung.com/docx4j) - [Introduction to StreamEx](http://www.baeldung.com/streamex) -- [Introduction to BouncyCastle with Java](http://www.baeldung.com/java-bouncy-castle) -- [Interact with Google Sheets from Java](http://www.baeldung.com/google-sheets-java-client) - [A Docker Guide for Java](http://www.baeldung.com/docker-java-api) -- [Introduction To OpenCSV](http://www.baeldung.com/opencsv) -- [Introduction to Akka Actors in Java](http://www.baeldung.com/akka-actors-java) -- [Introduction to Smooks](http://www.baeldung.com/smooks) -- [A Guide to Infinispan in Java](http://www.baeldung.com/infinispan) -- [A Guide to Unirest](http://www.baeldung.com/unirest) - [Introduction to Akka Actors in Java](http://www.baeldung.com/akka-actors-java) - [A Guide to Byte Buddy](http://www.baeldung.com/byte-buddy) - [Introduction to jOOL](http://www.baeldung.com/jool) @@ -50,18 +32,12 @@ - [Introduction to Atlassian Fugue](http://www.baeldung.com/java-fugue) - [Publish and Receive Messages with Nats Java Client](http://www.baeldung.com/nats-java-client) - [Java Concurrency Utility with JCTools](http://www.baeldung.com/java-concurrency-jc-tools) -- [Creating REST Microservices with Javalin](http://www.baeldung.com/javalin-rest-microservices) - [Introduction to JavaPoet](http://www.baeldung.com/java-poet) -- [Introduction to Joda-Time](http://www.baeldung.com/joda-time) - [Convert String to Date in Java](http://www.baeldung.com/java-string-to-date) - [Guide to Resilience4j](http://www.baeldung.com/resilience4j) -- [Parsing YAML with SnakeYAML](http://www.baeldung.com/java-snake-yaml) -- [Guide to JMapper](http://www.baeldung.com/jmapper) - [Exactly Once Processing in Kafka](https://www.baeldung.com/kafka-exactly-once) -- [An Introduction to SuanShu](https://www.baeldung.com/suanshu) - [Implementing a FTP-Client in Java](http://www.baeldung.com/java-ftp-client) - [Introduction to Functional Java](https://www.baeldung.com/java-functional-library) -- [Intro to Derive4J](https://www.baeldung.com/derive4j) - [A Guide to the Reflections Library](https://www.baeldung.com/reflections-library) The libraries module contains examples related to small libraries that are relatively easy to use and does not require any separate module of its own. diff --git a/libraries/pom.xml b/libraries/pom.xml index e8ffde5f99..a8ded19a1e 100644 --- a/libraries/pom.xml +++ b/libraries/pom.xml @@ -36,12 +36,6 @@ cglib ${cglib.version} - - - com.opencsv - opencsv - ${opencsv.version} - org.apache.commons commons-lang3 @@ -52,16 +46,7 @@ commons-net ${commons-net.version} - - tec.units - unit-ri - ${unit-ri.version} - - - org.jasypt - jasypt - ${jasypt.version} - + org.javatuples javatuples @@ -117,17 +102,17 @@ - net.serenity-bdd - serenity-core - ${serenity.version} - test - - - org.asciidoctor - asciidoctorj - - - + net.serenity-bdd + serenity-core + ${serenity.version} + test + + + org.asciidoctor + asciidoctorj + + + net.serenity-bdd serenity-junit @@ -347,11 +332,6 @@ ${org.hamcrest.java-hamcrest.version} test - - net.agkn - hll - ${hll.version} - net.bytebuddy byte-buddy @@ -383,22 +363,7 @@ ${vavr.version} - - - com.squareup.retrofit2 - retrofit - ${retrofit.version} - - - com.squareup.retrofit2 - converter-gson - ${retrofit.version} - - - com.squareup.retrofit2 - adapter-rxjava - ${retrofit.version} - + com.squareup.okhttp3 logging-interceptor @@ -464,36 +429,11 @@ jgrapht-core ${jgrapht.version} - - com.netopyr.wurmloch - wurmloch-crdt - ${crdt.version} - - - org.docx4j - docx4j - ${docx4j.version} - - - javax.xml.bind - jaxb-api - ${jaxb-api.version} - com.github.ben-manes.caffeine caffeine ${caffeine.version} - - org.bouncycastle - bcprov-jdk15on - ${bouncycastle.version} - - - org.bouncycastle - bcpkix-jdk15on - ${bouncycastle.version} - com.google.http-client google-http-client @@ -509,11 +449,6 @@ google-http-client-gson ${googleclient.version} - - org.infinispan - infinispan-core - ${infinispan.version} - @@ -553,11 +488,6 @@ google-oauth-client-jetty ${google-api.version} - - com.google.apis - google-api-services-sheets - ${google-sheets.version} - org.apache.kafka kafka-streams @@ -582,23 +512,8 @@ test - - org.milyn - milyn-smooks-all - ${smooks.version} - - - com.mashape.unirest - unirest-java - ${unirest.version} - - - - io.javalin - javalin - ${javalin.version} - + io.atlassian.fugue @@ -655,24 +570,6 @@ test - - org.yaml - snakeyaml - ${snakeyaml.version} - - - - com.numericalmethod - suanshu - ${suanshu.version} - - - - org.derive4j - derive4j - ${derive4j.version} - true - org.mockftpserver MockFtpServer @@ -812,13 +709,10 @@ - 4.0.0 - 1.21 + 1.23.0 - 0.1.0 0.7.0 3.2.7 - 1.9.2 1.2 3.21.0-GA 3.6.2 @@ -839,7 +733,6 @@ 3.5.0 3.0.0 2.0.0.0 - 1.6.0 1.7.1 2.1.2 1.0 @@ -848,22 +741,18 @@ 0.9.0 15.2 1.5.1 - 2.3.0 + 2.10 1.5.1 1.15 - 1.0.3 1.0.0 3.10.2 2.5.5 1.23.0 v4-rev493-1.21.0 2.0.0 - 1.7.0 3.0.14 - 9.1.5.Final - 4.1 - 1.4.9 + 2.1.2 1.10.L001 0.9.4.0006L @@ -893,15 +782,10 @@ 1.2.6 4.8.1 1.0.1 - 3.3.5 - 2.1 - 1.58 1.19.4 - 1.6.0 4.5.1 3.3.0 3.0.2 - 1.1.0 2.7.1 3.6 0.9.11 diff --git a/mapstruct/src/main/java/com/baeldung/dto/CarDTO.java b/mapstruct/src/main/java/com/baeldung/dto/CarDTO.java index 51aa8ccac2..98aefcb971 100644 --- a/mapstruct/src/main/java/com/baeldung/dto/CarDTO.java +++ b/mapstruct/src/main/java/com/baeldung/dto/CarDTO.java @@ -8,4 +8,5 @@ import lombok.Setter; public class CarDTO { private int id; private String name; + private FuelType fuelType; } diff --git a/mapstruct/src/main/java/com/baeldung/dto/FuelType.java b/mapstruct/src/main/java/com/baeldung/dto/FuelType.java new file mode 100644 index 0000000000..88692884ad --- /dev/null +++ b/mapstruct/src/main/java/com/baeldung/dto/FuelType.java @@ -0,0 +1,5 @@ +package com.baeldung.dto; + +public enum FuelType { + ELECTRIC, BIO_DIESEL +} diff --git a/mapstruct/src/main/java/com/baeldung/entity/BioDieselCar.java b/mapstruct/src/main/java/com/baeldung/entity/BioDieselCar.java new file mode 100644 index 0000000000..3f868c10a7 --- /dev/null +++ b/mapstruct/src/main/java/com/baeldung/entity/BioDieselCar.java @@ -0,0 +1,4 @@ +package com.baeldung.entity; + +public class BioDieselCar extends Car { +} diff --git a/mapstruct/src/main/java/com/baeldung/entity/ElectricCar.java b/mapstruct/src/main/java/com/baeldung/entity/ElectricCar.java new file mode 100644 index 0000000000..9b780a244e --- /dev/null +++ b/mapstruct/src/main/java/com/baeldung/entity/ElectricCar.java @@ -0,0 +1,4 @@ +package com.baeldung.entity; + +public class ElectricCar extends Car { +} diff --git a/mapstruct/src/main/java/com/baeldung/mapper/CarsMapper.java b/mapstruct/src/main/java/com/baeldung/mapper/CarsMapper.java new file mode 100644 index 0000000000..430aef1440 --- /dev/null +++ b/mapstruct/src/main/java/com/baeldung/mapper/CarsMapper.java @@ -0,0 +1,32 @@ +package com.baeldung.mapper; + +import org.mapstruct.AfterMapping; +import org.mapstruct.BeforeMapping; +import org.mapstruct.Mapper; +import org.mapstruct.MappingTarget; + +import com.baeldung.dto.CarDTO; +import com.baeldung.dto.FuelType; +import com.baeldung.entity.BioDieselCar; +import com.baeldung.entity.Car; +import com.baeldung.entity.ElectricCar; + +@Mapper +public abstract class CarsMapper { + + @BeforeMapping + protected void enrichDTOWithFuelType(Car car, @MappingTarget CarDTO carDto) { + if (car instanceof ElectricCar) + carDto.setFuelType(FuelType.ELECTRIC); + if (car instanceof BioDieselCar) + carDto.setFuelType(FuelType.BIO_DIESEL); + } + + @AfterMapping + protected void convertNameToUpperCase(@MappingTarget CarDTO carDto) { + carDto.setName(carDto.getName().toUpperCase()); + } + + public abstract CarDTO toCarDto(Car car); + +} diff --git a/mapstruct/src/test/java/com/baeldung/mapper/CarsMapperUnitTest.java b/mapstruct/src/test/java/com/baeldung/mapper/CarsMapperUnitTest.java new file mode 100644 index 0000000000..e729e1a2d0 --- /dev/null +++ b/mapstruct/src/test/java/com/baeldung/mapper/CarsMapperUnitTest.java @@ -0,0 +1,42 @@ +package com.baeldung.mapper; + +import static org.junit.Assert.assertEquals; + +import org.junit.jupiter.api.Test; +import org.mapstruct.factory.Mappers; + +import com.baeldung.dto.CarDTO; +import com.baeldung.dto.FuelType; +import com.baeldung.entity.BioDieselCar; +import com.baeldung.entity.Car; +import com.baeldung.entity.ElectricCar; + +class CarsMapperUnitTest { + + private CarsMapper sut = Mappers.getMapper(CarsMapper.class); + + @Test + void testGivenSubTypeElectric_mapsModifiedFieldsToSuperTypeDto_whenBeforeAndAfterMappingMethodscarCalled() { + Car car = new ElectricCar(); + car.setId(12); + car.setName("Tesla_Model_C"); + + CarDTO carDto = sut.toCarDto(car); + + assertEquals("TESLA_MODEL_C", carDto.getName()); + assertEquals(FuelType.ELECTRIC, carDto.getFuelType()); + } + + @Test + void testGivenSubTypeBioDiesel_mapsModifiedFieldsToSuperTypeDto_whenBeforeAndAfterMappingMethodscarCalled() { + Car car = new BioDieselCar(); + car.setId(11); + car.setName("Tesla_Model_X"); + + CarDTO carDto = sut.toCarDto(car); + + assertEquals("TESLA_MODEL_X", carDto.getName()); + assertEquals(FuelType.BIO_DIESEL, carDto.getFuelType()); + } + +} diff --git a/oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/api/AuthorizationEndpoint.java b/oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/api/AuthorizationEndpoint.java index 10e78a2dfd..ba5e1ec359 100644 --- a/oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/api/AuthorizationEndpoint.java +++ b/oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/api/AuthorizationEndpoint.java @@ -121,8 +121,8 @@ public class AuthorizationEndpoint { String redirectUri = originalParams.getFirst("resolved_redirect_uri"); StringBuilder sb = new StringBuilder(redirectUri); - String approbationStatus = params.getFirst("approbation_status"); - if ("NO".equals(approbationStatus)) { + String approvalStatus = params.getFirst("approval_status"); + if ("NO".equals(approvalStatus)) { URI location = UriBuilder.fromUri(sb.toString()) .queryParam("error", "User doesn't approved the request.") .queryParam("error_description", "User doesn't approved the request.") diff --git a/oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/api/TokenEndpoint.java b/oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/api/TokenEndpoint.java index f39bb2ea2d..0ea12da16e 100644 --- a/oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/api/TokenEndpoint.java +++ b/oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/api/TokenEndpoint.java @@ -15,15 +15,14 @@ import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.Response; +import java.util.Arrays; import java.util.Base64; -import java.util.Collections; import java.util.List; -import java.util.Objects; @Path("token") public class TokenEndpoint { - List supportedGrantTypes = Collections.singletonList("authorization_code"); + List supportedGrantTypes = Arrays.asList("authorization_code", "refresh_token"); @Inject private AppDataRepository appDataRepository; @@ -39,36 +38,36 @@ public class TokenEndpoint { //Check grant_type params String grantType = params.getFirst("grant_type"); - Objects.requireNonNull(grantType, "grant_type params is required"); - if (!supportedGrantTypes.contains(grantType)) { - JsonObject error = Json.createObjectBuilder() - .add("error", "unsupported_grant_type") - .add("error_description", "grant type should be one of :" + supportedGrantTypes) - .build(); - return Response.status(Response.Status.BAD_REQUEST) - .entity(error).build(); + if (grantType == null || grantType.isEmpty()) + return responseError("Invalid_request", "grant_type is required", Response.Status.BAD_REQUEST); + if (!supportedGrantTypes.contains(grantType)) { + return responseError("unsupported_grant_type", "grant_type should be one of :" + supportedGrantTypes, Response.Status.BAD_REQUEST); } //Client Authentication String[] clientCredentials = extract(authHeader); + if (clientCredentials.length != 2) { + return responseError("Invalid_request", "Bad Credentials client_id/client_secret", Response.Status.BAD_REQUEST); + } String clientId = clientCredentials[0]; - String clientSecret = clientCredentials[1]; Client client = appDataRepository.getClient(clientId); - if (client == null || clientSecret == null || !clientSecret.equals(client.getClientSecret())) { - JsonObject error = Json.createObjectBuilder() - .add("error", "invalid_client") - .build(); - return Response.status(Response.Status.UNAUTHORIZED) - .entity(error).build(); + if (client == null) { + return responseError("Invalid_request", "Invalid client_id", Response.Status.BAD_REQUEST); + } + String clientSecret = clientCredentials[1]; + if (!clientSecret.equals(client.getClientSecret())) { + return responseError("Invalid_request", "Invalid client_secret", Response.Status.UNAUTHORIZED); } AuthorizationGrantTypeHandler authorizationGrantTypeHandler = authorizationGrantTypeHandlers.select(NamedLiteral.of(grantType)).get(); JsonObject tokenResponse = null; try { tokenResponse = authorizationGrantTypeHandler.createAccessToken(clientId, params); + } catch (WebApplicationException e) { + return e.getResponse(); } catch (Exception e) { - e.printStackTrace(); + return responseError("Invalid_request", "Can't get token", Response.Status.INTERNAL_SERVER_ERROR); } return Response.ok(tokenResponse) @@ -81,6 +80,15 @@ public class TokenEndpoint { if (authHeader != null && authHeader.startsWith("Basic ")) { return new String(Base64.getDecoder().decode(authHeader.substring(6))).split(":"); } - return null; + return new String[]{}; + } + + private Response responseError(String error, String errorDescription, Response.Status status) { + JsonObject errorResponse = Json.createObjectBuilder() + .add("error", error) + .add("error_description", errorDescription) + .build(); + return Response.status(status) + .entity(errorResponse).build(); } } diff --git a/oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/handler/AbstractGrantTypeHandler.java b/oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/handler/AbstractGrantTypeHandler.java new file mode 100644 index 0000000000..324bacb33f --- /dev/null +++ b/oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/handler/AbstractGrantTypeHandler.java @@ -0,0 +1,87 @@ +package com.baeldung.oauth2.authorization.server.handler; + +import com.baeldung.oauth2.authorization.server.PEMKeyUtils; +import com.nimbusds.jose.*; +import com.nimbusds.jose.crypto.RSASSASigner; +import com.nimbusds.jose.crypto.RSASSAVerifier; +import com.nimbusds.jose.jwk.JWK; +import com.nimbusds.jose.jwk.RSAKey; +import com.nimbusds.jwt.JWTClaimsSet; +import com.nimbusds.jwt.SignedJWT; +import org.eclipse.microprofile.config.Config; + +import javax.inject.Inject; +import java.time.Instant; +import java.time.temporal.ChronoUnit; +import java.util.Arrays; +import java.util.Date; +import java.util.UUID; + +public abstract class AbstractGrantTypeHandler implements AuthorizationGrantTypeHandler { + + //Always RSA 256, but could be parametrized + protected JWSHeader jwsHeader = new JWSHeader.Builder(JWSAlgorithm.RS256).type(JOSEObjectType.JWT).build(); + + @Inject + protected Config config; + + //30 min + protected Long expiresInMin = 30L; + + protected JWSVerifier getJWSVerifier() throws Exception { + String verificationkey = config.getValue("verificationkey", String.class); + String pemEncodedRSAPublicKey = PEMKeyUtils.readKeyAsString(verificationkey); + RSAKey rsaPublicKey = (RSAKey) JWK.parseFromPEMEncodedObjects(pemEncodedRSAPublicKey); + return new RSASSAVerifier(rsaPublicKey); + } + + protected JWSSigner getJwsSigner() throws Exception { + String signingkey = config.getValue("signingkey", String.class); + String pemEncodedRSAPrivateKey = PEMKeyUtils.readKeyAsString(signingkey); + RSAKey rsaKey = (RSAKey) JWK.parseFromPEMEncodedObjects(pemEncodedRSAPrivateKey); + return new RSASSASigner(rsaKey.toRSAPrivateKey()); + } + + protected String getAccessToken(String clientId, String subject, String approvedScope) throws Exception { + //4. Signing + JWSSigner jwsSigner = getJwsSigner(); + + Instant now = Instant.now(); + //Long expiresInMin = 30L; + Date expirationTime = Date.from(now.plus(expiresInMin, ChronoUnit.MINUTES)); + + //3. JWT Payload or claims + JWTClaimsSet jwtClaims = new JWTClaimsSet.Builder() + .issuer("http://localhost:9080") + .subject(subject) + .claim("upn", subject) + .claim("client_id", clientId) + .audience("http://localhost:9280") + .claim("scope", approvedScope) + .claim("groups", Arrays.asList(approvedScope.split(" "))) + .expirationTime(expirationTime) // expires in 30 minutes + .notBeforeTime(Date.from(now)) + .issueTime(Date.from(now)) + .jwtID(UUID.randomUUID().toString()) + .build(); + SignedJWT signedJWT = new SignedJWT(jwsHeader, jwtClaims); + signedJWT.sign(jwsSigner); + return signedJWT.serialize(); + } + + protected String getRefreshToken(String clientId, String subject, String approvedScope) throws Exception { + JWSSigner jwsSigner = getJwsSigner(); + Instant now = Instant.now(); + //6.Build refresh token + JWTClaimsSet refreshTokenClaims = new JWTClaimsSet.Builder() + .subject(subject) + .claim("client_id", clientId) + .claim("scope", approvedScope) + //refresh token for 1 day. + .expirationTime(Date.from(now.plus(1, ChronoUnit.DAYS))) + .build(); + SignedJWT signedRefreshToken = new SignedJWT(jwsHeader, refreshTokenClaims); + signedRefreshToken.sign(jwsSigner); + return signedRefreshToken.serialize(); + } +} diff --git a/oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/handler/AuthorizationCodeGrantTypeHandler.java b/oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/handler/AuthorizationCodeGrantTypeHandler.java index 889c7fcea2..78128aead6 100644 --- a/oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/handler/AuthorizationCodeGrantTypeHandler.java +++ b/oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/handler/AuthorizationCodeGrantTypeHandler.java @@ -1,18 +1,7 @@ package com.baeldung.oauth2.authorization.server.handler; -import com.baeldung.oauth2.authorization.server.PEMKeyUtils; import com.baeldung.oauth2.authorization.server.model.AuthorizationCode; -import com.nimbusds.jose.JOSEObjectType; -import com.nimbusds.jose.JWSAlgorithm; -import com.nimbusds.jose.JWSHeader; -import com.nimbusds.jose.crypto.RSASSASigner; -import com.nimbusds.jose.jwk.JWK; -import com.nimbusds.jose.jwk.RSAKey; -import com.nimbusds.jwt.JWTClaimsSet; -import com.nimbusds.jwt.SignedJWT; -import org.eclipse.microprofile.config.Config; -import javax.inject.Inject; import javax.inject.Named; import javax.json.Json; import javax.json.JsonObject; @@ -20,22 +9,14 @@ import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.MultivaluedMap; -import java.time.Instant; import java.time.LocalDateTime; -import java.time.temporal.ChronoUnit; -import java.util.Arrays; -import java.util.Date; -import java.util.UUID; @Named("authorization_code") -public class AuthorizationCodeGrantTypeHandler implements AuthorizationGrantTypeHandler { +public class AuthorizationCodeGrantTypeHandler extends AbstractGrantTypeHandler { @PersistenceContext private EntityManager entityManager; - @Inject - private Config config; - @Override public JsonObject createAccessToken(String clientId, MultivaluedMap params) throws Exception { //1. code is required @@ -58,42 +39,16 @@ public class AuthorizationCodeGrantTypeHandler implements AuthorizationGrantType throw new WebApplicationException("invalid_grant"); } - //JWT Header - JWSHeader jwsHeader = new JWSHeader.Builder(JWSAlgorithm.RS256).type(JOSEObjectType.JWT).build(); - - Instant now = Instant.now(); - Long expiresInMin = 30L; - Date expiresIn = Date.from(now.plus(expiresInMin, ChronoUnit.MINUTES)); - //3. JWT Payload or claims - JWTClaimsSet jwtClaims = new JWTClaimsSet.Builder() - .issuer("http://localhost:9080") - .subject(authorizationCode.getUserId()) - .claim("upn", authorizationCode.getUserId()) - .audience("http://localhost:9280") - .claim("scope", authorizationCode.getApprovedScopes()) - .claim("groups", Arrays.asList(authorizationCode.getApprovedScopes().split(" "))) - .expirationTime(expiresIn) // expires in 30 minutes - .notBeforeTime(Date.from(now)) - .issueTime(Date.from(now)) - .jwtID(UUID.randomUUID().toString()) - .build(); - SignedJWT signedJWT = new SignedJWT(jwsHeader, jwtClaims); - - //4. Signing - String signingkey = config.getValue("signingkey", String.class); - String pemEncodedRSAPrivateKey = PEMKeyUtils.readKeyAsString(signingkey); - RSAKey rsaKey = (RSAKey) JWK.parseFromPEMEncodedObjects(pemEncodedRSAPrivateKey); - signedJWT.sign(new RSASSASigner(rsaKey.toRSAPrivateKey())); - - //5. Finally the JWT access token - String accessToken = signedJWT.serialize(); + String accessToken = getAccessToken(clientId, authorizationCode.getUserId(), authorizationCode.getApprovedScopes()); + String refreshToken = getRefreshToken(clientId, authorizationCode.getUserId(), authorizationCode.getApprovedScopes()); return Json.createObjectBuilder() .add("token_type", "Bearer") .add("access_token", accessToken) .add("expires_in", expiresInMin * 60) .add("scope", authorizationCode.getApprovedScopes()) + .add("refresh_token", refreshToken) .build(); } } diff --git a/oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/handler/RefreshTokenGrantTypeHandler.java b/oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/handler/RefreshTokenGrantTypeHandler.java new file mode 100644 index 0000000000..63e3552353 --- /dev/null +++ b/oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/handler/RefreshTokenGrantTypeHandler.java @@ -0,0 +1,72 @@ +package com.baeldung.oauth2.authorization.server.handler; + +import com.nimbusds.jose.JWSVerifier; +import com.nimbusds.jwt.SignedJWT; + +import javax.inject.Named; +import javax.json.Json; +import javax.json.JsonObject; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.core.Response; +import java.util.Arrays; +import java.util.Date; +import java.util.HashSet; +import java.util.Set; + +@Named("refresh_token") +public class RefreshTokenGrantTypeHandler extends AbstractGrantTypeHandler { + + @Override + public JsonObject createAccessToken(String clientId, MultivaluedMap params) throws Exception { + String refreshToken = params.getFirst("refresh_token"); + if (refreshToken == null || "".equals(refreshToken)) { + throw new WebApplicationException("invalid_grant"); + } + + //Decode refresh token + SignedJWT signedRefreshToken = SignedJWT.parse(refreshToken); + JWSVerifier verifier = getJWSVerifier(); + + if (!signedRefreshToken.verify(verifier)) { + throw new WebApplicationException("Invalid refresh token."); + } + if (!(new Date().before(signedRefreshToken.getJWTClaimsSet().getExpirationTime()))) { + throw new WebApplicationException("Refresh token expired."); + } + String refreshTokenClientId = signedRefreshToken.getJWTClaimsSet().getStringClaim("client_id"); + if (!clientId.equals(refreshTokenClientId)) { + throw new WebApplicationException("Invalid client_id."); + } + + //At this point, the refresh token is valid and not yet expired + //So create a new access token from it. + String subject = signedRefreshToken.getJWTClaimsSet().getSubject(); + String approvedScopes = signedRefreshToken.getJWTClaimsSet().getStringClaim("scope"); + + String requestedScopes = params.getFirst("scope"); + if (requestedScopes != null && !requestedScopes.isEmpty()) { + Set rScopes = new HashSet(Arrays.asList(requestedScopes.split(" "))); + Set aScopes = new HashSet(Arrays.asList(approvedScopes.split(" "))); + if (!aScopes.containsAll(rScopes)) { + JsonObject error = Json.createObjectBuilder() + .add("error", "Invalid_request") + .add("error_description", "Requested scopes should be a subset of the original scopes.") + .build(); + Response response = Response.status(Response.Status.BAD_REQUEST).entity(error).build(); + throw new WebApplicationException(response); + } + } else { + requestedScopes = approvedScopes; + } + + String accessToken = getAccessToken(clientId, subject, requestedScopes); + return Json.createObjectBuilder() + .add("token_type", "Bearer") + .add("access_token", accessToken) + .add("expires_in", expiresInMin * 60) + .add("scope", requestedScopes) + .add("refresh_token", refreshToken) + .build(); + } +} diff --git a/oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/web/AuthorizationEndpoint.java b/oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/web/AuthorizationEndpoint.java deleted file mode 100644 index 84b9a89c54..0000000000 --- a/oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/web/AuthorizationEndpoint.java +++ /dev/null @@ -1,209 +0,0 @@ -//package com.baeldung.security.oauth2.server.web; -// -//import AuthorizationCode; -//import Client; -//import User; -//import com.baeldung.security.oauth2.server.service.AuthCodeService; -// -//import javax.ejb.EJB; -//import javax.enterprise.context.RequestScoped; -//import javax.inject.Inject; -//import javax.persistence.EntityManager; -//import javax.persistence.PersistenceContext; -//import javax.security.enterprise.SecurityContext; -//import javax.security.enterprise.authentication.mechanism.http.FormAuthenticationMechanismDefinition; -//import javax.security.enterprise.authentication.mechanism.http.LoginToContinue; -//import javax.servlet.ServletException; -//import javax.servlet.annotation.HttpConstraint; -//import javax.servlet.annotation.ServletSecurity; -//import javax.servlet.annotation.WebServlet; -//import javax.servlet.http.HttpServlet; -//import javax.servlet.http.HttpServletRequest; -//import javax.servlet.http.HttpServletResponse; -//import java.io.IOException; -//import java.security.Principal; -//import java.util.*; -// -///** -// * 1. GET http://localhost:8080/app/ (302) -// * 2. GET http://localhost:8080/uaa/authorize?client_id=app&redirect_uri=http://localhost:8080/app/&response_type=code&state=A123 (302) -// * 3. GET http://localhost:8080/uaa/login (200) with initial request as hidden input -// * 4. POST http://localhost:8080/uaa/login (username, password, initial client request) (302) -// * 5. GET http://localhost:8080/uaa/authorize?client_id=app&redirect_uri=http://localhost:8080/app/&response_type=code&state=A123 (200) -// * 7. POST http://localhost:8080/uaa/authorize?client_id=app&redirect_uri=http://localhost:8080/app/&response_type=code&state=A123 (302) -// * 8. GET http://localhost:8080/app/?code=rkWijq06mL&state=A123 (200) -// */ -///* -// -//Query Params: -// client_id: app -// redirect_uri: http://localhost:8080/app/ -// response_type: code -// state: A123 -// -// ==> GET user login WITH client request as hidden input: -// -// -// ==> After user login ==> Initial client request -// ==> gen code -// == redirect to redirect uri + params code & state : 302, location : http://localhost:8080/app/?code=w6A0YQFzzg&state=A123 -//*/ -// -////authorize?client_id=app&redirect_uri=http://localhost:8080/app/&response_type=code&state=A123 -////http://localhost:9080/authorize?response_type=code&client_id=client_id_1&redirect_uri=http://localhost:9080/app&state=A123 -// -////@RequestScoped -//@FormAuthenticationMechanismDefinition( -// loginToContinue = @LoginToContinue( -// loginPage = "/login-servlet", -// errorPage = "/login-error-servlet" -// ) -//) -//@WebServlet({"/authorize"}) -//@ServletSecurity(@HttpConstraint(rolesAllowed = "user")) -////@Stateless -//@RequestScoped -//public class AuthorizationEndpoint extends HttpServlet { -// -// private static final List authorizedResponseTypes = Arrays.asList("code", "token"); -// -// @Inject -// private SecurityContext securityContext; -// -// @PersistenceContext(name = "jpa-oauth2-pu") -// private EntityManager entityManager; -// -// @EJB -// private AuthCodeService authCodeService; -// -// //HTTP GET IS A MUST, POST IS OPTIONAL -// @Override -// protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { -// -// String error = ""; -// -// //1. User Authentication -// Principal principal = securityContext.getCallerPrincipal(); -// -// //2. Check for a valid client_id -// String clientId = request.getParameter("client_id"); -// if (clientId == null) { -// request.setAttribute("error", "The client " + clientId + " doesn't exist."); -// } -// request.setAttribute("clientId", clientId); -// Client client = entityManager.find(Client.class, clientId); -// if (client == null) { -// request.setAttribute("error", "The client " + clientId + " doesn't exist."); -// } -// -// //3. check for a valid response_type -// String responseType = request.getParameter("response_type"); -// if (!authorizedResponseTypes.contains(responseType)) { -// error = "invalid_grant :" + responseType + ", response_type params should be one of :" + authorizedResponseTypes; -// request.setAttribute("error", error); -// request.getRequestDispatcher("/error.jsp") -// .forward(request, response); -// } -// -// //4. Optional redirect_uri, if provided should match -// String redirectUri = request.getParameter("redirect_uri"); -// checkRedirectUri(client, redirectUri); -// -// //save params -// String currentUri = request.getRequestURI(); -// request.setAttribute("post_redirect_uri", currentUri); -// -// String state = request.getParameter("state"); -// Map requestMap = new HashMap<>(); -// requestMap.put("response_type", responseType); -// requestMap.put("client_id", clientId); -// requestMap.put("redirect_uri", redirectUri); -// requestMap.put("state", state); -// request.setAttribute("requestMap", requestMap); -// -// //5.scope: Optional -// String requestedScope = request.getParameter("scope"); -// if (requestedScope.isEmpty()) { -// requestedScope = client.getScope(); -// } -// //requestedScope should be a subset of the client scope: clientScopes.containsAll(requestedScopes) -// //checkRequestedScope(requestedScope, client.getScope()); -// -// //sub set of user scope -// //allowed scope by the user -// -// User user = entityManager.find(User.class, principal.getName()); -// request.setAttribute("scopes", requestedScope); -// -// -// forward("/authorize.jsp", request, response); -// } -// -// @Override -// protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { -// String clientId = request.getParameter("client_id"); -// -// String responseType = request.getParameter("response_type"); -// if (!authorizedResponseTypes.contains(responseType)) { -// String error = "invalid_grant :" + responseType + ", response_type params should be one of :" + authorizedResponseTypes; -// request.setAttribute("error", error); -// forward("/error.jsp", request, response); -// } -// -// Client client = entityManager.find(Client.class, clientId); -// Objects.requireNonNull(client); -// -// String userId = securityContext.getCallerPrincipal().getName(); -// AuthorizationCode authorizationCode = new AuthorizationCode(); -// authorizationCode.setClientId(clientId); -// authorizationCode.setUserId(userId); -// String redirectUri = request.getParameter("redirect_uri"); -// authorizationCode.setRedirectUri(redirectUri); -// -// redirectUri = checkRedirectUri(client, redirectUri); -// -// String[] scope = request.getParameterValues("scope"); -// if (scope == null) { -// request.setAttribute("error", "User doesn't approved any scope"); -// forward("/error.jsp", request, response); -// } -// -// String approvedScopes = String.join(" ", scope); -// authorizationCode.setApprovedScopes(approvedScopes); -// -// //entityManager.persist(authorizationCode); -// authCodeService.save(authorizationCode); -// String code = authorizationCode.getCode(); -// -// StringBuilder sb = new StringBuilder(redirectUri); -// sb.append("?code=").append(code); -// -// //If the client send a state, Send it back -// String state = request.getParameter("state"); -// if (state != null) { -// sb.append("&state=").append(state); -// } -// response.sendRedirect(sb.toString()); -// } -// -// private String checkRedirectUri(Client client, String redirectUri) { -// //redirect uri -// if (redirectUri == null) { -// //erreur: param redirect_uri && client redirect_uri don't match. -// redirectUri = client.getRedirectUri(); -// if (redirectUri == null) { -// throw new IllegalStateException("redirectUri shloud be not null, unless a registred client have a redirect_uri."); -// } -// } else if (!redirectUri.equals(client.getRedirectUri())) { -// throw new IllegalStateException("request redirectUri and client registred redirect_uri should match."); -// } -// return redirectUri; -// } -// -// private void forward(String path, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { -// request.getRequestDispatcher(path) -// .forward(request, response); -// } -//} diff --git a/oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/web/TokenEndpoint.java b/oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/web/TokenEndpoint.java deleted file mode 100644 index 73085a68d1..0000000000 --- a/oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/web/TokenEndpoint.java +++ /dev/null @@ -1,70 +0,0 @@ -//package com.baeldung.security.oauth2.server.web; -// -//import AuthorizationGrantTypeHandler; -//import TokenResponse; -//import com.baeldung.security.oauth2.server.security.Authenticated; -//import com.nimbusds.jose.JOSEException; -// -//import javax.enterprise.inject.Instance; -//import javax.enterprise.inject.literal.NamedLiteral; -//import javax.inject.Inject; -//import javax.security.enterprise.SecurityContext; -//import javax.ws.rs.Consumes; -//import javax.ws.rs.POST; -//import javax.ws.rs.Path; -//import javax.ws.rs.Produces; -//import javax.ws.rs.core.MediaType; -//import javax.ws.rs.core.MultivaluedMap; -//import javax.ws.rs.core.Response; -//import java.security.Principal; -//import java.util.Arrays; -//import java.util.List; -//import java.util.Objects; -// -///** -// * { -// * "access_token" : "acb6803a48114d9fb4761e403c17f812", -// * "token_type" : "bearer", -// * "id_token" : "eyJhbGciOiJIUzI1NiIsImprdSI6Imh0dHBzOi8vbG9jYWxob3N0OjgwODAvdWFhL3Rva2VuX2tleXMiLCJraWQiOiJsZWdhY3ktdG9rZW4ta2V5IiwidHlwIjoiSldUIn0.eyJzdWIiOiIwNzYzZTM2MS02ODUwLTQ3N2ItYjk1Ny1iMmExZjU3MjczMTQiLCJhdWQiOlsibG9naW4iXSwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL3VhYS9vYXV0aC90b2tlbiIsImV4cCI6MTU1NzgzMDM4NSwiaWF0IjoxNTU3Nzg3MTg1LCJhenAiOiJsb2dpbiIsInNjb3BlIjpbIm9wZW5pZCJdLCJlbWFpbCI6IndyaHBONUB0ZXN0Lm9yZyIsInppZCI6InVhYSIsIm9yaWdpbiI6InVhYSIsImp0aSI6ImFjYjY4MDNhNDgxMTRkOWZiNDc2MWU0MDNjMTdmODEyIiwiZW1haWxfdmVyaWZpZWQiOnRydWUsImNsaWVudF9pZCI6ImxvZ2luIiwiY2lkIjoibG9naW4iLCJncmFudF90eXBlIjoiYXV0aG9yaXphdGlvbl9jb2RlIiwidXNlcl9uYW1lIjoid3JocE41QHRlc3Qub3JnIiwicmV2X3NpZyI6ImI3MjE5ZGYxIiwidXNlcl9pZCI6IjA3NjNlMzYxLTY4NTAtNDc3Yi1iOTU3LWIyYTFmNTcyNzMxNCIsImF1dGhfdGltZSI6MTU1Nzc4NzE4NX0.Fo8wZ_Zq9mwFks3LfXQ1PfJ4ugppjWvioZM6jSqAAQQ", -// * "refresh_token" : "f59dcb5dcbca45f981f16ce519d61486-r", -// * "expires_in" : 43199, -// * "scope" : "openid oauth.approvals", -// * "jti" : "acb6803a48114d9fb4761e403c17f812" -// * } -// */ -//@Path("token") -//public class TokenEndpoint { -// -// List supportedGrantTypes = Arrays.asList("authorization_code", "password", "refresh_token", "client_credentials"); -// -// @Inject -// private SecurityContext securityContext; -// -// @Inject -// Instance authorizationGrantTypeHandlers; -// -// @POST -// @Produces(MediaType.APPLICATION_JSON) -// @Consumes(MediaType.APPLICATION_FORM_URLENCODED) -// @Authenticated -// public Response token(MultivaluedMap params) throws JOSEException { -// //Authenticate client with [basic] http authentication mechanism -// Principal principal = securityContext.getCallerPrincipal(); -// Objects.requireNonNull(principal, "Client not authenticated!"); -// -// //Check grant_type params -// String grantType = params.getFirst("grant_type"); -// Objects.requireNonNull(grantType, "grant_type params is required"); -// //authorization_code, password, refresh, client_credentials -// if (!supportedGrantTypes.contains(grantType)) { -// throw new RuntimeException("grant_type parameter should be one of the following :" + supportedGrantTypes); -// } -// AuthorizationGrantTypeHandler authorizationGrantTypeHandler = authorizationGrantTypeHandlers.select(NamedLiteral.of(grantType)).get(); -// TokenResponse tokenResponse = authorizationGrantTypeHandler.createAccessToken(principal.getName(), params); -// Response response = Response.ok(tokenResponse) -// .header("Cache-Control", "no-store") -// .header("Pragma", "no-cache") -// .build(); -// return response; -// } -//} diff --git a/oauth2-framework-impl/oauth2-authorization-server/src/main/webapp/authorize.jsp b/oauth2-framework-impl/oauth2-authorization-server/src/main/webapp/authorize.jsp index 1004b5b8b7..41b0582c03 100644 --- a/oauth2-framework-impl/oauth2-authorization-server/src/main/webapp/authorize.jsp +++ b/oauth2-framework-impl/oauth2-authorization-server/src/main/webapp/authorize.jsp @@ -41,8 +41,8 @@ - - + + diff --git a/oauth2-framework-impl/oauth2-client/src/main/java/com/baeldung/oauth2/client/AbstractServlet.java b/oauth2-framework-impl/oauth2-client/src/main/java/com/baeldung/oauth2/client/AbstractServlet.java new file mode 100644 index 0000000000..7059c4f7e1 --- /dev/null +++ b/oauth2-framework-impl/oauth2-client/src/main/java/com/baeldung/oauth2/client/AbstractServlet.java @@ -0,0 +1,23 @@ +package com.baeldung.oauth2.client; + +import javax.servlet.RequestDispatcher; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.Base64; + +public abstract class AbstractServlet extends HttpServlet { + + protected void dispatch(String location, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + RequestDispatcher requestDispatcher = request.getRequestDispatcher(location); + requestDispatcher.forward(request, response); + } + + protected String getAuthorizationHeaderValue(String clientId, String clientSecret) { + String token = clientId + ":" + clientSecret; + String encodedString = Base64.getEncoder().encodeToString(token.getBytes()); + return "Basic " + encodedString; + } +} diff --git a/oauth2-framework-impl/oauth2-client/src/main/java/com/baeldung/oauth2/client/CallbackServlet.java b/oauth2-framework-impl/oauth2-client/src/main/java/com/baeldung/oauth2/client/CallbackServlet.java index 87aa8bc668..e72877076c 100644 --- a/oauth2-framework-impl/oauth2-client/src/main/java/com/baeldung/oauth2/client/CallbackServlet.java +++ b/oauth2-framework-impl/oauth2-client/src/main/java/com/baeldung/oauth2/client/CallbackServlet.java @@ -4,10 +4,8 @@ import org.eclipse.microprofile.config.Config; import javax.inject.Inject; import javax.json.JsonObject; -import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; -import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.ws.rs.client.Client; @@ -18,10 +16,9 @@ import javax.ws.rs.core.Form; import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.MediaType; import java.io.IOException; -import java.util.Base64; @WebServlet(urlPatterns = "/callback") -public class CallbackServlet extends HttpServlet { +public class CallbackServlet extends AbstractServlet { @Inject private Config config; @@ -29,6 +26,9 @@ public class CallbackServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + String clientId = config.getValue("client.clientId", String.class); + String clientSecret = config.getValue("client.clientSecret", String.class); + //Error: String error = request.getParameter("error"); if (error != null) { @@ -53,24 +53,15 @@ public class CallbackServlet extends HttpServlet { form.param("code", code); form.param("redirect_uri", config.getValue("client.redirectUri", String.class)); - JsonObject tokenResponse = target.request(MediaType.APPLICATION_JSON_TYPE) - .header(HttpHeaders.AUTHORIZATION, getAuthorizationHeaderValue()) - .post(Entity.entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE), JsonObject.class); - - request.getSession().setAttribute("tokenResponse", tokenResponse); + try { + JsonObject tokenResponse = target.request(MediaType.APPLICATION_JSON_TYPE) + .header(HttpHeaders.AUTHORIZATION, getAuthorizationHeaderValue(clientId, clientSecret)) + .post(Entity.entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE), JsonObject.class); + request.getSession().setAttribute("tokenResponse", tokenResponse); + } catch (Exception ex) { + System.out.println(ex.getMessage()); + request.setAttribute("error", ex.getMessage()); + } dispatch("/", request, response); } - - private void dispatch(String location, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { - RequestDispatcher requestDispatcher = request.getRequestDispatcher(location); - requestDispatcher.forward(request, response); - } - - private String getAuthorizationHeaderValue() { - String clientId = config.getValue("client.clientId", String.class); - String clientSecret = config.getValue("client.clientSecret", String.class); - String token = clientId + ":" + clientSecret; - String encodedString = Base64.getEncoder().encodeToString(token.getBytes()); - return "Basic " + encodedString; - } } diff --git a/oauth2-framework-impl/oauth2-client/src/main/java/com/baeldung/oauth2/client/RefreshTokenServlet.java b/oauth2-framework-impl/oauth2-client/src/main/java/com/baeldung/oauth2/client/RefreshTokenServlet.java new file mode 100644 index 0000000000..a519a53070 --- /dev/null +++ b/oauth2-framework-impl/oauth2-client/src/main/java/com/baeldung/oauth2/client/RefreshTokenServlet.java @@ -0,0 +1,57 @@ +package com.baeldung.oauth2.client; + +import org.eclipse.microprofile.config.Config; + +import javax.inject.Inject; +import javax.json.JsonObject; +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.Form; +import javax.ws.rs.core.HttpHeaders; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import java.io.IOException; + +@WebServlet(urlPatterns = "/refreshtoken") +public class RefreshTokenServlet extends AbstractServlet { + + @Inject + private Config config; + + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + + String clientId = config.getValue("client.clientId", String.class); + String clientSecret = config.getValue("client.clientSecret", String.class); + + JsonObject actualTokenResponse = (JsonObject) request.getSession().getAttribute("tokenResponse"); + Client client = ClientBuilder.newClient(); + WebTarget target = client.target(config.getValue("provider.tokenUri", String.class)); + + Form form = new Form(); + form.param("grant_type", "refresh_token"); + form.param("refresh_token", actualTokenResponse.getString("refresh_token")); + + String scope = request.getParameter("scope"); + if (scope != null && !scope.isEmpty()) { + form.param("scope", scope); + } + + Response jaxrsResponse = target.request(MediaType.APPLICATION_JSON_TYPE) + .header(HttpHeaders.AUTHORIZATION, getAuthorizationHeaderValue(clientId, clientSecret)) + .post(Entity.entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE), Response.class); + JsonObject tokenResponse = jaxrsResponse.readEntity(JsonObject.class); + if (jaxrsResponse.getStatus() == 200) { + request.getSession().setAttribute("tokenResponse", tokenResponse); + } else { + request.setAttribute("error", tokenResponse.getString("error_description", "error!")); + } + dispatch("/", request, response); + } +} diff --git a/oauth2-framework-impl/oauth2-client/src/main/webapp/index.jsp b/oauth2-framework-impl/oauth2-client/src/main/webapp/index.jsp index 23fec70f33..ccb74df228 100644 --- a/oauth2-framework-impl/oauth2-client/src/main/webapp/index.jsp +++ b/oauth2-framework-impl/oauth2-client/src/main/webapp/index.jsp @@ -10,6 +10,7 @@ body { margin: 0px; } + input[type=text], input[type=password] { width: 75%; padding: 4px 0px; @@ -17,6 +18,7 @@ border: 1px solid #502bcc; box-sizing: border-box; } + .container-error { padding: 16px; border: 1px solid #cc102a; @@ -25,6 +27,7 @@ margin-left: 25px; margin-bottom: 25px; } + .container { padding: 16px; border: 1px solid #130ecc; @@ -81,8 +84,20 @@
  • access_token: ${tokenResponse.getString("access_token")}
  • scope: ${tokenResponse.getString("scope")}
  • Expires in (s): ${tokenResponse.getInt("expires_in")}
  • +
  • refresh_token: ${tokenResponse.getString("refresh_token")}
  • + + +

    OAuth2 Resource Server Call


    @@ -90,7 +105,6 @@
  • Read Protected Resource
  • Write Protected Resource
  • -
    diff --git a/parent-boot-1/pom.xml b/parent-boot-1/pom.xml index 1054038623..8f1af24466 100644 --- a/parent-boot-1/pom.xml +++ b/parent-boot-1/pom.xml @@ -55,7 +55,7 @@ 3.1.0 - 1.5.19.RELEASE + 1.5.22.RELEASE diff --git a/parent-boot-2/pom.xml b/parent-boot-2/pom.xml index f0e921bf37..edc115d186 100644 --- a/parent-boot-2/pom.xml +++ b/parent-boot-2/pom.xml @@ -78,6 +78,6 @@ 3.3.0 1.0.22.RELEASE - 2.1.6.RELEASE + 2.1.7.RELEASE
    diff --git a/parent-boot-performance/README.md b/parent-boot-performance/README.md deleted file mode 100644 index fce9e101da..0000000000 --- a/parent-boot-performance/README.md +++ /dev/null @@ -1 +0,0 @@ -This is a parent module for projects that want to take advantage of the latest Spring Boot improvements/features. \ No newline at end of file diff --git a/parent-boot-performance/pom.xml b/parent-boot-performance/pom.xml deleted file mode 100644 index b7d12e2ba4..0000000000 --- a/parent-boot-performance/pom.xml +++ /dev/null @@ -1,92 +0,0 @@ - - 4.0.0 - parent-boot-performance - 0.0.1-SNAPSHOT - parent-boot-performance - pom - Parent for all modules that want to take advantage of the latest Spring Boot improvements/features. Current version: 2.2 - - - com.baeldung - parent-modules - 1.0.0-SNAPSHOT - - - - - - org.springframework.boot - spring-boot-dependencies - ${spring-boot.version} - pom - import - - - - - - - io.rest-assured - rest-assured - - - org.springframework.boot - spring-boot-starter-test - test - - - - - - - - org.springframework.boot - spring-boot-maven-plugin - ${spring-boot.version} - - ${start-class} - - - - - - - - - - spring-milestones - Spring Milestones - https://repo.spring.io/milestone - - - - - - thin-jar - - - - org.springframework.boot - spring-boot-maven-plugin - - - - org.springframework.boot.experimental - spring-boot-thin-layout - ${thin.version} - - - - - - - - - - 3.1.0 - - 1.0.21.RELEASE - 2.2.0.M3 - - diff --git a/parent-java/README.md b/parent-java/README.md index ff12555376..729105e3fd 100644 --- a/parent-java/README.md +++ b/parent-java/README.md @@ -1 +1 @@ -## Relevant articles: +## Relevant Articles: diff --git a/parent-java/pom.xml b/parent-java/pom.xml index cb3e205871..09e2596d0a 100644 --- a/parent-java/pom.xml +++ b/parent-java/pom.xml @@ -21,10 +21,16 @@ guava ${guava.version}
    + + commons-io + commons-io + ${commons.io.version} + 23.0 + 2.6 diff --git a/parent-spring-4/README.md b/parent-spring-4/README.md index ff12555376..729105e3fd 100644 --- a/parent-spring-4/README.md +++ b/parent-spring-4/README.md @@ -1 +1 @@ -## Relevant articles: +## Relevant Articles: diff --git a/parent-spring-4/pom.xml b/parent-spring-4/pom.xml index ab66cf19bf..390934ca7b 100644 --- a/parent-spring-4/pom.xml +++ b/parent-spring-4/pom.xml @@ -51,7 +51,7 @@ - 4.3.22.RELEASE + 4.3.25.RELEASE 1.6.1 diff --git a/parent-spring-5/README.md b/parent-spring-5/README.md index ff12555376..729105e3fd 100644 --- a/parent-spring-5/README.md +++ b/parent-spring-5/README.md @@ -1 +1 @@ -## Relevant articles: +## Relevant Articles: diff --git a/parent-spring-5/pom.xml b/parent-spring-5/pom.xml index f85924b801..e43e129c7f 100644 --- a/parent-spring-5/pom.xml +++ b/parent-spring-5/pom.xml @@ -1,4 +1,5 @@ - 4.0.0 com.baeldung @@ -29,8 +30,8 @@ - 5.1.4.RELEASE - 5.1.4.RELEASE + 5.1.9.RELEASE + 5.1.6.RELEASE \ No newline at end of file diff --git a/patterns/backoff-jitter/README.md b/patterns/backoff-jitter/README.md new file mode 100644 index 0000000000..a3940cc418 --- /dev/null +++ b/patterns/backoff-jitter/README.md @@ -0,0 +1,2 @@ +### Relevant Articles: +- [Better Retries with Exponential Backoff and Jitter](https://www.baeldung.com/resilience4j-backoff-jitter) diff --git a/patterns/backoff-jitter/pom.xml b/patterns/backoff-jitter/pom.xml new file mode 100644 index 0000000000..6b0d016609 --- /dev/null +++ b/patterns/backoff-jitter/pom.xml @@ -0,0 +1,54 @@ + + + 4.0.0 + com.baeldung + backoff-jitter + 1.0.0-SNAPSHOT + pom + + + + junit + junit + ${junit.version} + test + + + org.mockito + mockito-core + ${mockito-core.version} + test + + + io.github.resilience4j + resilience4j-retry + ${resilience4j.version} + test + + + org.slf4j + slf4j-api + ${slf4j.version} + test + + + org.slf4j + slf4j-simple + ${slf4j.version} + test + + + + + UTF-8 + 1.8 + 1.8 + 4.12 + 2.27.0 + 1.7.26 + 0.16.0 + + + \ No newline at end of file diff --git a/patterns/backoff-jitter/src/test/java/com/baeldung/backoff/jitter/BackoffWithJitterTest.java b/patterns/backoff-jitter/src/test/java/com/baeldung/backoff/jitter/BackoffWithJitterTest.java new file mode 100644 index 0000000000..f6b3ebbe45 --- /dev/null +++ b/patterns/backoff-jitter/src/test/java/com/baeldung/backoff/jitter/BackoffWithJitterTest.java @@ -0,0 +1,103 @@ +package com.baeldung.backoff.jitter; + +import io.github.resilience4j.retry.IntervalFunction; +import io.github.resilience4j.retry.Retry; +import io.github.resilience4j.retry.RetryConfig; +import org.junit.Before; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutorService; +import java.util.function.Function; + +import static com.baeldung.backoff.jitter.BackoffWithJitterTest.RetryProperties.*; +import static io.github.resilience4j.retry.IntervalFunction.ofExponentialBackoff; +import static io.github.resilience4j.retry.IntervalFunction.ofExponentialRandomBackoff; +import static java.util.Collections.nCopies; +import static java.util.concurrent.Executors.newFixedThreadPool; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.*; + +public class BackoffWithJitterTest { + + static Logger log = LoggerFactory.getLogger(BackoffWithJitterTest.class); + + interface PingPongService { + + String call(String ping) throws PingPongServiceException; + } + + class PingPongServiceException extends RuntimeException { + + public PingPongServiceException(String reason) { + super(reason); + } + } + + private PingPongService service; + private static final int NUM_CONCURRENT_CLIENTS = 8; + + @Before + public void setUp() { + service = mock(PingPongService.class); + } + + @Test + public void whenRetryExponentialBackoff_thenRetriedConfiguredNoOfTimes() { + IntervalFunction intervalFn = ofExponentialBackoff(INITIAL_INTERVAL, MULTIPLIER); + Function pingPongFn = getRetryablePingPongFn(intervalFn); + + when(service.call(anyString())).thenThrow(PingPongServiceException.class); + try { + pingPongFn.apply("Hello"); + } catch (PingPongServiceException e) { + verify(service, times(MAX_RETRIES)).call(anyString()); + } + } + + @Test + public void whenRetryExponentialBackoffWithoutJitter_thenThunderingHerdProblemOccurs() throws InterruptedException { + IntervalFunction intervalFn = ofExponentialBackoff(INITIAL_INTERVAL, MULTIPLIER); + test(intervalFn); + } + + @Test + public void whenRetryExponentialBackoffWithJitter_thenRetriesAreSpread() throws InterruptedException { + IntervalFunction intervalFn = ofExponentialRandomBackoff(INITIAL_INTERVAL, MULTIPLIER, RANDOMIZATION_FACTOR); + test(intervalFn); + } + + private void test(IntervalFunction intervalFn) throws InterruptedException { + Function pingPongFn = getRetryablePingPongFn(intervalFn); + ExecutorService executors = newFixedThreadPool(NUM_CONCURRENT_CLIENTS); + List> tasks = nCopies(NUM_CONCURRENT_CLIENTS, () -> pingPongFn.apply("Hello")); + + when(service.call(anyString())).thenThrow(PingPongServiceException.class); + + executors.invokeAll(tasks); + } + + private Function getRetryablePingPongFn(IntervalFunction intervalFn) { + RetryConfig retryConfig = RetryConfig.custom() + .maxAttempts(MAX_RETRIES) + .intervalFunction(intervalFn) + .retryExceptions(PingPongServiceException.class) + .build(); + Retry retry = Retry.of("pingpong", retryConfig); + return Retry.decorateFunction(retry, ping -> { + log.info("Invoked at {}", LocalDateTime.now()); + return service.call(ping); + }); + } + + static class RetryProperties { + static final Long INITIAL_INTERVAL = 1000L; + static final Double MULTIPLIER = 2.0D; + static final Double RANDOMIZATION_FACTOR = 0.6D; + static final Integer MAX_RETRIES = 4; + } +} diff --git a/patterns/design-patterns-2/pom.xml b/patterns/design-patterns-2/pom.xml index 574edecb36..f99bb4dc9c 100644 --- a/patterns/design-patterns-2/pom.xml +++ b/patterns/design-patterns-2/pom.xml @@ -36,6 +36,17 @@ assertj-core ${assertj.version} test + + + org.inferred + freebuilder + ${freebuilder.version} + true + + + com.google.code.findbugs + jsr305 + ${javax.annotations.version} @@ -45,5 +56,7 @@ 1.8 16.0.2 3.12.2 + 2.4.1 + 3.0.2 diff --git a/patterns/design-patterns-2/src/main/java/com/baeldung/freebuilder/Address.java b/patterns/design-patterns-2/src/main/java/com/baeldung/freebuilder/Address.java new file mode 100644 index 0000000000..6d727f6d9f --- /dev/null +++ b/patterns/design-patterns-2/src/main/java/com/baeldung/freebuilder/Address.java @@ -0,0 +1,25 @@ +package com.baeldung.freebuilder; + +import org.inferred.freebuilder.FreeBuilder; + +import java.util.Optional; + +@FreeBuilder +public interface Address { + + Optional getAddressLine1(); + + Optional getAddressLine2(); + + Optional getAddressLine3(); + + String getCity(); + + Optional getState(); + + Optional getPinCode(); + + class Builder extends Address_Builder { + + } +} \ No newline at end of file diff --git a/patterns/design-patterns-2/src/main/java/com/baeldung/freebuilder/Employee.java b/patterns/design-patterns-2/src/main/java/com/baeldung/freebuilder/Employee.java new file mode 100644 index 0000000000..06558dde0b --- /dev/null +++ b/patterns/design-patterns-2/src/main/java/com/baeldung/freebuilder/Employee.java @@ -0,0 +1,65 @@ +package com.baeldung.freebuilder; + +import org.inferred.freebuilder.FreeBuilder; + +import javax.annotation.Nullable; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +@FreeBuilder +public interface Employee { + + String getName(); + + int getAge(); + + String getDepartment(); + + String getRole(); + + String getSupervisorName(); + + String getDesignation(); + + String getEmail(); + + long getPhoneNumber(); + + Optional getPermanent(); + + Optional getDateOfJoining(); + + @Nullable + String getCurrentProject(); + + Address getAddress(); + + List getAccessTokens(); + + Map getAssetsSerialIdMapping(); + + Optional getSalaryInUSD(); + + + class Builder extends Employee_Builder { + + public Builder() { + // setting default value for department + setDepartment("Builder Pattern"); + } + + @Override + public Builder setEmail(String email) { + if (checkValidEmail(email)) + return super.setEmail(email); + else + throw new IllegalArgumentException("Invalid email"); + + } + + private boolean checkValidEmail(String email) { + return email.contains("@"); + } + } +} diff --git a/patterns/design-patterns-2/src/main/java/com/baeldung/freebuilder/builder/Employee.java b/patterns/design-patterns-2/src/main/java/com/baeldung/freebuilder/builder/Employee.java new file mode 100644 index 0000000000..141d734c43 --- /dev/null +++ b/patterns/design-patterns-2/src/main/java/com/baeldung/freebuilder/builder/Employee.java @@ -0,0 +1,53 @@ +package com.baeldung.freebuilder.builder; + +public class Employee { + + private final String name; + private final int age; + private final String department; + + private Employee(String name, int age, String department) { + this.name = name; + this.age = age; + this.department = department; + } + + public String getName() { + return name; + } + + public int getAge() { + return age; + } + + public String getDepartment() { + return department; + } + + public static class Builder { + + private String name; + private int age; + private String department; + + public Builder setName(String name) { + this.name = name; + return this; + } + + public Builder setAge(int age) { + this.age = age; + return this; + } + + public Builder setDepartment(String department) { + this.department = department; + return this; + } + + public Employee build() { + return new Employee(name, age, department); + } + } + +} diff --git a/patterns/design-patterns-2/src/test/java/com/baeldung/freebuilder/EmployeeBuilderUnitTest.java b/patterns/design-patterns-2/src/test/java/com/baeldung/freebuilder/EmployeeBuilderUnitTest.java new file mode 100644 index 0000000000..d28edfcf3d --- /dev/null +++ b/patterns/design-patterns-2/src/test/java/com/baeldung/freebuilder/EmployeeBuilderUnitTest.java @@ -0,0 +1,226 @@ +package com.baeldung.freebuilder; + +import org.junit.jupiter.api.Test; + +import java.util.Optional; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class EmployeeBuilderUnitTest { + + private static final int PIN_CODE = 223344; + public static final String CITY_NAME = "New York"; + public static final int INPUT_SALARY_EUROS = 10000; + public static final double EUROS_TO_USD_RATIO = 0.6; + + @Test + public void whenBuildEmployeeWithAddress_thenReturnEmployeeWithValidAddress() { + + // when + Address.Builder addressBuilder = new Address.Builder(); + Address address = addressBuilder.setCity(CITY_NAME).build(); + + Employee.Builder builder = new Employee.Builder(); + + Employee employee = builder.setName("baeldung") + .setAge(10) + .setDesignation("author") + .setEmail("abc@xyz.com") + .setSupervisorName("Admin") + .setPhoneNumber(4445566) + .setPermanent(true) + .setRole("developer") + .setAddress(address) + .build(); + + // then + assertTrue(employee.getAddress().getCity().equalsIgnoreCase(CITY_NAME)); + + } + + @Test + public void whenMapSalary_thenReturnEmployeeWithSalaryInUSD() { + + // when + Address.Builder addressBuilder = new Address.Builder(); + Address address = addressBuilder.setCity(CITY_NAME).setPinCode(PIN_CODE).build(); + + long salaryInEuros = INPUT_SALARY_EUROS; + Employee.Builder builder = new Employee.Builder(); + + Employee employee = builder + .setName("baeldung") + .setAge(10) + .setDesignation("author") + .setEmail("abc@xyz.com") + .setSupervisorName("Admin") + .setPhoneNumber(4445566) + .setPermanent(true) + .setRole("developer") + .setAddress(address) + .mapSalaryInUSD(sal -> salaryInEuros * EUROS_TO_USD_RATIO) + .build(); + + // then + assertTrue(employee.getAddress().getPinCode().get() == PIN_CODE); + + } + + @Test + public void whenOptionalFields_thenReturnEmployeeWithEmptyValues() { + + // when + Address.Builder addressBuilder = new Address.Builder(); + Address address = addressBuilder.setCity(CITY_NAME).build(); + + Employee.Builder builder = new Employee.Builder(); + + Employee employee = builder.setName("baeldung") + .setAge(10) + .setDesignation("author") + .setEmail("abc@xyz.com") + .setSupervisorName("Admin") + .setPhoneNumber(4445566) + .setPermanent(true) + .setRole("developer") + .setAddress(address) + .build(); + + // then + assertTrue(employee.getPermanent().isPresent()); + assertTrue(employee.getPermanent().get()); + assertFalse(employee.getDateOfJoining().isPresent()); + + } + + @Test + public void whenNullableFields_thenReturnEmployeeWithNullValueForField() { + + // when + Address.Builder addressBuilder = new Address.Builder(); + Address address = addressBuilder.setCity(CITY_NAME).build(); + + Employee.Builder builder = new Employee.Builder(); + + Employee employee = builder.setName("baeldung") + .setAge(10) + .setDesignation("author") + .setEmail("abc@xyz.com") + .setSupervisorName("Admin") + .setPhoneNumber(4445566) + .setNullablePermanent(null) + .setDateOfJoining(Optional.empty()) + .setRole("developer") + .setAddress(address) + .build(); + + // then + assertNull(employee.getCurrentProject()); + + } + + @Test + public void whenCollectionFields_thenReturnEmployeeWithValues() { + + // when + Address.Builder addressBuilder = new Address.Builder(); + Address address = addressBuilder.setCity(CITY_NAME).build(); + + Employee.Builder builder = new Employee.Builder(); + + Employee employee = builder.setName("baeldung") + .setAge(10) + .setDesignation("author") + .setEmail("abc@xyz.com") + .setSupervisorName("Admin") + .setPhoneNumber(4445566) + .setNullablePermanent(null) + .setDateOfJoining(Optional.empty()) + .setRole("developer") + .addAccessTokens(1221819L) + .addAccessTokens(1223441L, 134567L) + .setAddress(address) + .build(); + + // then + assertTrue(employee.getAccessTokens().size() == 3); + + } + + @Test + public void whenMapFields_thenReturnEmployeeWithValues() { + + // when + Address.Builder addressBuilder = new Address.Builder(); + Address address = addressBuilder.setCity(CITY_NAME).build(); + + Employee.Builder builder = new Employee.Builder(); + + Employee employee = builder.setName("baeldung") + .setAge(10) + .setDesignation("author") + .setEmail("abc@xyz.com") + .setSupervisorName("Admin") + .setPhoneNumber(4445566) + .setNullablePermanent(null) + .setDateOfJoining(Optional.empty()) + .setRole("developer") + .addAccessTokens(1221819L) + .addAccessTokens(1223441L, 134567L) + .putAssetsSerialIdMapping("Laptop", 12345L) + .setAddress(address) + .build(); + + // then + assertTrue(employee.getAssetsSerialIdMapping().size() == 1); + + } + + @Test + public void whenNestedBuilderTypes_thenReturnEmployeeWithValues() { + + // when + Address.Builder addressBuilder = new Address.Builder(); + Address address = addressBuilder.setCity(CITY_NAME).build(); + + Employee.Builder builder = new Employee.Builder(); + + Employee employee = builder.setName("baeldung") + .setAge(10) + .setDesignation("author") + .setEmail("abc@xyz.com") + .setSupervisorName("Admin") + .setPhoneNumber(4445566) + .setNullablePermanent(null) + .setDateOfJoining(Optional.empty()) + .setRole("developer") + .addAccessTokens(1221819L) + .addAccessTokens(1223441L, 134567L) + .putAssetsSerialIdMapping("Laptop", 12345L) + .setAddress(address) + .mutateAddress(a -> a.setPinCode(112200)) + .build(); + + // then + assertTrue(employee.getAssetsSerialIdMapping().size() == 1); + + } + + @Test() + public void whenPartialEmployeeWithValidEmail_thenReturnEmployeeWithEmail() { + + // when + Employee.Builder builder = new Employee.Builder(); + + Employee employee = builder.setName("baeldung") + .setAge(10) + .setEmail("abc@xyz.com") + .buildPartial(); + + assertNotNull(employee.getEmail()); + } + +} diff --git a/patterns/design-patterns-2/src/test/java/com/baeldung/freebuilder/builder/EmployeeBuilderUnitTest.java b/patterns/design-patterns-2/src/test/java/com/baeldung/freebuilder/builder/EmployeeBuilderUnitTest.java new file mode 100644 index 0000000000..1394f851b6 --- /dev/null +++ b/patterns/design-patterns-2/src/test/java/com/baeldung/freebuilder/builder/EmployeeBuilderUnitTest.java @@ -0,0 +1,27 @@ +package com.baeldung.freebuilder.builder; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + + +class EmployeeBuilderUnitTest { + + public static final String NAME = "baeldung"; + + @Test + public void whenBuildEmployee_thenReturnValidEmployee() { + + // when + Employee.Builder emplBuilder = new Employee.Builder(); + + Employee employee = emplBuilder + .setName(NAME) + .setAge(12) + .setDepartment("Builder Pattern") + .build(); + + //then + Assertions.assertTrue(employee.getName().equalsIgnoreCase(NAME)); + } + +} \ No newline at end of file diff --git a/patterns/pom.xml b/patterns/pom.xml index 2be9d2519e..7f7368ca07 100644 --- a/patterns/pom.xml +++ b/patterns/pom.xml @@ -19,7 +19,8 @@ design-patterns design-patterns-2 solid - dip + dip + backoff-jitter diff --git a/persistence-modules/java-cassandra/pom.xml b/persistence-modules/java-cassandra/pom.xml index 708d2b3c76..e7c93bc4e5 100644 --- a/persistence-modules/java-cassandra/pom.xml +++ b/persistence-modules/java-cassandra/pom.xml @@ -4,7 +4,7 @@ com.baeldung java-cassandra 1.0.0-SNAPSHOT - java-cassandra + java-cassandra com.baeldung @@ -29,6 +29,19 @@ ${cassandra-unit.version} + + + com.datastax.oss + java-driver-core + ${datastax-cassandra.version} + + + + io.netty + netty-handler + ${io-netty.version} + + @@ -39,6 +52,8 @@ 3.1.2 3.1.1.0 + 4.1.0 + 4.1.34.Final 18.0 diff --git a/persistence-modules/java-cassandra/src/main/java/com/baeldung/datastax/cassandra/Application.java b/persistence-modules/java-cassandra/src/main/java/com/baeldung/datastax/cassandra/Application.java new file mode 100644 index 0000000000..23140e0455 --- /dev/null +++ b/persistence-modules/java-cassandra/src/main/java/com/baeldung/datastax/cassandra/Application.java @@ -0,0 +1,46 @@ +package com.baeldung.datastax.cassandra; + +import com.baeldung.datastax.cassandra.domain.Video; +import com.baeldung.datastax.cassandra.repository.KeyspaceRepository; +import com.baeldung.datastax.cassandra.repository.VideoRepository; +import com.datastax.oss.driver.api.core.CqlSession; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.time.Instant; +import java.time.temporal.ChronoUnit; +import java.util.List; + +public class Application { + + private static final Logger LOG = LoggerFactory.getLogger(Application.class); + + public static void main(String[] args) { + new Application().run(); + } + + public void run() { + CassandraConnector connector = new CassandraConnector(); + connector.connect("127.0.0.1", 9042, "datacenter1"); + CqlSession session = connector.getSession(); + + KeyspaceRepository keyspaceRepository = new KeyspaceRepository(session); + + keyspaceRepository.createKeyspace("testKeyspace", "SimpleStrategy", 1); + keyspaceRepository.useKeyspace("testKeyspace"); + + VideoRepository videoRepository = new VideoRepository(session); + + videoRepository.createTable(); + + videoRepository.insertVideo(new Video("Video Title 1", Instant.now())); + videoRepository.insertVideo(new Video("Video Title 2", + Instant.now().minus(1, ChronoUnit.DAYS))); + + List - data-flow-server - - time-source - time-processor - log-sink + spring-cloud-data-flow-stream-processing + spring-cloud-data-flow-etl batch-job - etl apache-spark-job diff --git a/spring-cloud-data-flow/etl/README.MD b/spring-cloud-data-flow/spring-cloud-data-flow-etl/README.MD similarity index 100% rename from spring-cloud-data-flow/etl/README.MD rename to spring-cloud-data-flow/spring-cloud-data-flow-etl/README.MD diff --git a/spring-cloud-data-flow/etl/customer-mongodb-sink/pom.xml b/spring-cloud-data-flow/spring-cloud-data-flow-etl/customer-mongodb-sink/pom.xml similarity index 100% rename from spring-cloud-data-flow/etl/customer-mongodb-sink/pom.xml rename to spring-cloud-data-flow/spring-cloud-data-flow-etl/customer-mongodb-sink/pom.xml diff --git a/spring-cloud-data-flow/etl/customer-mongodb-sink/src/main/java/com/customer/customermongodbsink/Customer.java b/spring-cloud-data-flow/spring-cloud-data-flow-etl/customer-mongodb-sink/src/main/java/com/customer/customermongodbsink/Customer.java similarity index 100% rename from spring-cloud-data-flow/etl/customer-mongodb-sink/src/main/java/com/customer/customermongodbsink/Customer.java rename to spring-cloud-data-flow/spring-cloud-data-flow-etl/customer-mongodb-sink/src/main/java/com/customer/customermongodbsink/Customer.java diff --git a/spring-cloud-data-flow/etl/customer-mongodb-sink/src/main/java/com/customer/customermongodbsink/CustomerListener.java b/spring-cloud-data-flow/spring-cloud-data-flow-etl/customer-mongodb-sink/src/main/java/com/customer/customermongodbsink/CustomerListener.java similarity index 100% rename from spring-cloud-data-flow/etl/customer-mongodb-sink/src/main/java/com/customer/customermongodbsink/CustomerListener.java rename to spring-cloud-data-flow/spring-cloud-data-flow-etl/customer-mongodb-sink/src/main/java/com/customer/customermongodbsink/CustomerListener.java diff --git a/spring-cloud-data-flow/etl/customer-mongodb-sink/src/main/java/com/customer/customermongodbsink/CustomerMongodbSinkApplication.java b/spring-cloud-data-flow/spring-cloud-data-flow-etl/customer-mongodb-sink/src/main/java/com/customer/customermongodbsink/CustomerMongodbSinkApplication.java similarity index 100% rename from spring-cloud-data-flow/etl/customer-mongodb-sink/src/main/java/com/customer/customermongodbsink/CustomerMongodbSinkApplication.java rename to spring-cloud-data-flow/spring-cloud-data-flow-etl/customer-mongodb-sink/src/main/java/com/customer/customermongodbsink/CustomerMongodbSinkApplication.java diff --git a/spring-cloud-data-flow/etl/customer-mongodb-sink/src/main/java/com/customer/customermongodbsink/CustomerRepository.java b/spring-cloud-data-flow/spring-cloud-data-flow-etl/customer-mongodb-sink/src/main/java/com/customer/customermongodbsink/CustomerRepository.java similarity index 100% rename from spring-cloud-data-flow/etl/customer-mongodb-sink/src/main/java/com/customer/customermongodbsink/CustomerRepository.java rename to spring-cloud-data-flow/spring-cloud-data-flow-etl/customer-mongodb-sink/src/main/java/com/customer/customermongodbsink/CustomerRepository.java diff --git a/spring-cloud-data-flow/etl/customer-mongodb-sink/src/main/resources/application.properties b/spring-cloud-data-flow/spring-cloud-data-flow-etl/customer-mongodb-sink/src/main/resources/application.properties similarity index 100% rename from spring-cloud-data-flow/etl/customer-mongodb-sink/src/main/resources/application.properties rename to spring-cloud-data-flow/spring-cloud-data-flow-etl/customer-mongodb-sink/src/main/resources/application.properties diff --git a/spring-cloud-data-flow/etl/customer-transform/pom.xml b/spring-cloud-data-flow/spring-cloud-data-flow-etl/customer-transform/pom.xml similarity index 100% rename from spring-cloud-data-flow/etl/customer-transform/pom.xml rename to spring-cloud-data-flow/spring-cloud-data-flow-etl/customer-transform/pom.xml diff --git a/spring-cloud-data-flow/etl/customer-transform/src/main/java/com/customer/customertransform/Customer.java b/spring-cloud-data-flow/spring-cloud-data-flow-etl/customer-transform/src/main/java/com/customer/customertransform/Customer.java similarity index 100% rename from spring-cloud-data-flow/etl/customer-transform/src/main/java/com/customer/customertransform/Customer.java rename to spring-cloud-data-flow/spring-cloud-data-flow-etl/customer-transform/src/main/java/com/customer/customertransform/Customer.java diff --git a/spring-cloud-data-flow/etl/customer-transform/src/main/java/com/customer/customertransform/CustomerProcessorConfiguration.java b/spring-cloud-data-flow/spring-cloud-data-flow-etl/customer-transform/src/main/java/com/customer/customertransform/CustomerProcessorConfiguration.java similarity index 100% rename from spring-cloud-data-flow/etl/customer-transform/src/main/java/com/customer/customertransform/CustomerProcessorConfiguration.java rename to spring-cloud-data-flow/spring-cloud-data-flow-etl/customer-transform/src/main/java/com/customer/customertransform/CustomerProcessorConfiguration.java diff --git a/spring-cloud-data-flow/etl/customer-transform/src/main/java/com/customer/customertransform/CustomerTransformApplication.java b/spring-cloud-data-flow/spring-cloud-data-flow-etl/customer-transform/src/main/java/com/customer/customertransform/CustomerTransformApplication.java similarity index 100% rename from spring-cloud-data-flow/etl/customer-transform/src/main/java/com/customer/customertransform/CustomerTransformApplication.java rename to spring-cloud-data-flow/spring-cloud-data-flow-etl/customer-transform/src/main/java/com/customer/customertransform/CustomerTransformApplication.java diff --git a/spring-cloud-data-flow/etl/customer-transform/src/main/resources/application.properties b/spring-cloud-data-flow/spring-cloud-data-flow-etl/customer-transform/src/main/resources/application.properties similarity index 100% rename from spring-cloud-data-flow/etl/customer-transform/src/main/resources/application.properties rename to spring-cloud-data-flow/spring-cloud-data-flow-etl/customer-transform/src/main/resources/application.properties diff --git a/spring-cloud-data-flow/etl/pom.xml b/spring-cloud-data-flow/spring-cloud-data-flow-etl/pom.xml similarity index 91% rename from spring-cloud-data-flow/etl/pom.xml rename to spring-cloud-data-flow/spring-cloud-data-flow-etl/pom.xml index 55b2f34289..ab34271273 100644 --- a/spring-cloud-data-flow/etl/pom.xml +++ b/spring-cloud-data-flow/spring-cloud-data-flow-etl/pom.xml @@ -1,7 +1,7 @@ 4.0.0 - etl + spring-cloud-data-flow-etl 0.0.1-SNAPSHOT etl pom diff --git a/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/README.MD b/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/README.MD new file mode 100644 index 0000000000..522c43252f --- /dev/null +++ b/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/README.MD @@ -0,0 +1,4 @@ +### Relevant Articles: + +- [Getting Started with Stream Processing with Spring Cloud Data Flow](http://www.baeldung.com/spring-cloud-data-flow-stream-processing) + diff --git a/spring-cloud-data-flow/data-flow-server/pom.xml b/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/data-flow-server/pom.xml similarity index 100% rename from spring-cloud-data-flow/data-flow-server/pom.xml rename to spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/data-flow-server/pom.xml diff --git a/spring-cloud-data-flow/data-flow-server/src/main/java/org/baeldung/spring/cloud/DataFlowServerApplication.java b/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/data-flow-server/src/main/java/org/baeldung/spring/cloud/DataFlowServerApplication.java similarity index 100% rename from spring-cloud-data-flow/data-flow-server/src/main/java/org/baeldung/spring/cloud/DataFlowServerApplication.java rename to spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/data-flow-server/src/main/java/org/baeldung/spring/cloud/DataFlowServerApplication.java diff --git a/spring-amqp/src/main/resources/logback.xml b/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/data-flow-server/src/main/resources/logback.xml similarity index 100% rename from spring-amqp/src/main/resources/logback.xml rename to spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/data-flow-server/src/main/resources/logback.xml diff --git a/spring-cloud-data-flow/data-flow-server/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/data-flow-server/src/test/java/org/baeldung/SpringContextIntegrationTest.java similarity index 100% rename from spring-cloud-data-flow/data-flow-server/src/test/java/org/baeldung/SpringContextIntegrationTest.java rename to spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/data-flow-server/src/test/java/org/baeldung/SpringContextIntegrationTest.java diff --git a/spring-cloud-data-flow/data-flow-server/src/test/java/org/baeldung/SpringContextTest.java b/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/data-flow-server/src/test/java/org/baeldung/SpringContextLiveTest.java similarity index 92% rename from spring-cloud-data-flow/data-flow-server/src/test/java/org/baeldung/SpringContextTest.java rename to spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/data-flow-server/src/test/java/org/baeldung/SpringContextLiveTest.java index 83cb8067cf..980c096f5e 100644 --- a/spring-cloud-data-flow/data-flow-server/src/test/java/org/baeldung/SpringContextTest.java +++ b/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/data-flow-server/src/test/java/org/baeldung/SpringContextLiveTest.java @@ -8,7 +8,7 @@ import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest(classes = DataFlowServerApplication.class) -public class SpringContextTest { +public class SpringContextLiveTest { @Test public void whenSpringContextIsBootstrapped_thenNoExceptions() { diff --git a/spring-cloud-data-flow/data-flow-server/src/test/java/org/baeldung/spring/cloud/DataFlowServerApplicationIntegrationTest.java b/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/data-flow-server/src/test/java/org/baeldung/spring/cloud/DataFlowServerApplicationIntegrationTest.java similarity index 100% rename from spring-cloud-data-flow/data-flow-server/src/test/java/org/baeldung/spring/cloud/DataFlowServerApplicationIntegrationTest.java rename to spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/data-flow-server/src/test/java/org/baeldung/spring/cloud/DataFlowServerApplicationIntegrationTest.java diff --git a/spring-cloud-data-flow/data-flow-shell/pom.xml b/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/data-flow-shell/pom.xml similarity index 100% rename from spring-cloud-data-flow/data-flow-shell/pom.xml rename to spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/data-flow-shell/pom.xml diff --git a/spring-cloud-data-flow/data-flow-shell/spring-shell.log b/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/data-flow-shell/spring-shell.log similarity index 100% rename from spring-cloud-data-flow/data-flow-shell/spring-shell.log rename to spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/data-flow-shell/spring-shell.log diff --git a/spring-cloud-data-flow/data-flow-shell/src/main/java/org/baeldung/spring/cloud/DataFlowShellApplication.java b/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/data-flow-shell/src/main/java/org/baeldung/spring/cloud/DataFlowShellApplication.java similarity index 100% rename from spring-cloud-data-flow/data-flow-shell/src/main/java/org/baeldung/spring/cloud/DataFlowShellApplication.java rename to spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/data-flow-shell/src/main/java/org/baeldung/spring/cloud/DataFlowShellApplication.java diff --git a/spring-cloud-data-flow/data-flow-server/src/main/resources/logback.xml b/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/data-flow-shell/src/main/resources/logback.xml similarity index 100% rename from spring-cloud-data-flow/data-flow-server/src/main/resources/logback.xml rename to spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/data-flow-shell/src/main/resources/logback.xml diff --git a/spring-cloud-data-flow/data-flow-shell/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/data-flow-shell/src/test/java/org/baeldung/SpringContextIntegrationTest.java similarity index 100% rename from spring-cloud-data-flow/data-flow-shell/src/test/java/org/baeldung/SpringContextIntegrationTest.java rename to spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/data-flow-shell/src/test/java/org/baeldung/SpringContextIntegrationTest.java diff --git a/spring-cloud-data-flow/data-flow-shell/src/test/java/org/baeldung/SpringContextTest.java b/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/data-flow-shell/src/test/java/org/baeldung/SpringContextLiveTest.java similarity index 91% rename from spring-cloud-data-flow/data-flow-shell/src/test/java/org/baeldung/SpringContextTest.java rename to spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/data-flow-shell/src/test/java/org/baeldung/SpringContextLiveTest.java index c456f69979..5be4f9c077 100644 --- a/spring-cloud-data-flow/data-flow-shell/src/test/java/org/baeldung/SpringContextTest.java +++ b/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/data-flow-shell/src/test/java/org/baeldung/SpringContextLiveTest.java @@ -8,7 +8,7 @@ import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest(classes = DataFlowShellApplication.class) -public class SpringContextTest { +public class SpringContextLiveTest { @Test public void contextLoads() { diff --git a/spring-cloud-data-flow/log-sink/pom.xml b/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/log-sink/pom.xml similarity index 100% rename from spring-cloud-data-flow/log-sink/pom.xml rename to spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/log-sink/pom.xml diff --git a/spring-cloud-data-flow/log-sink/src/main/java/org/baeldung/spring/cloud/LogSinkApplication.java b/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/log-sink/src/main/java/org/baeldung/spring/cloud/LogSinkApplication.java similarity index 100% rename from spring-cloud-data-flow/log-sink/src/main/java/org/baeldung/spring/cloud/LogSinkApplication.java rename to spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/log-sink/src/main/java/org/baeldung/spring/cloud/LogSinkApplication.java diff --git a/spring-cloud-data-flow/data-flow-shell/src/main/resources/logback.xml b/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/log-sink/src/main/resources/logback.xml similarity index 100% rename from spring-cloud-data-flow/data-flow-shell/src/main/resources/logback.xml rename to spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/log-sink/src/main/resources/logback.xml diff --git a/spring-cloud-data-flow/log-sink/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/log-sink/src/test/java/org/baeldung/SpringContextIntegrationTest.java similarity index 100% rename from spring-cloud-data-flow/log-sink/src/test/java/org/baeldung/SpringContextIntegrationTest.java rename to spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/log-sink/src/test/java/org/baeldung/SpringContextIntegrationTest.java diff --git a/spring-cloud-data-flow/log-sink/src/test/java/org/baeldung/SpringContextTest.java b/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/log-sink/src/test/java/org/baeldung/SpringContextTest.java similarity index 100% rename from spring-cloud-data-flow/log-sink/src/test/java/org/baeldung/SpringContextTest.java rename to spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/log-sink/src/test/java/org/baeldung/SpringContextTest.java diff --git a/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/pom.xml b/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/pom.xml new file mode 100644 index 0000000000..e5c6830393 --- /dev/null +++ b/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/pom.xml @@ -0,0 +1,23 @@ + + 4.0.0 + spring-cloud-data-flow-stream + 0.0.1-SNAPSHOT + spring-cloud-data-flow-stream + pom + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + + + + data-flow-server + data-flow-shell + time-source + time-processor + log-sink + + + diff --git a/spring-cloud-data-flow/time-processor/pom.xml b/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/time-processor/pom.xml similarity index 100% rename from spring-cloud-data-flow/time-processor/pom.xml rename to spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/time-processor/pom.xml diff --git a/spring-cloud-data-flow/time-processor/src/main/java/org/baeldung/spring/cloud/TimeProcessorApplication.java b/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/time-processor/src/main/java/org/baeldung/spring/cloud/TimeProcessorApplication.java similarity index 100% rename from spring-cloud-data-flow/time-processor/src/main/java/org/baeldung/spring/cloud/TimeProcessorApplication.java rename to spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/time-processor/src/main/java/org/baeldung/spring/cloud/TimeProcessorApplication.java diff --git a/spring-cloud-data-flow/log-sink/src/main/resources/logback.xml b/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/time-processor/src/main/resources/logback.xml similarity index 100% rename from spring-cloud-data-flow/log-sink/src/main/resources/logback.xml rename to spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/time-processor/src/main/resources/logback.xml diff --git a/spring-cloud-data-flow/time-processor/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/time-processor/src/test/java/org/baeldung/SpringContextIntegrationTest.java similarity index 100% rename from spring-cloud-data-flow/time-processor/src/test/java/org/baeldung/SpringContextIntegrationTest.java rename to spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/time-processor/src/test/java/org/baeldung/SpringContextIntegrationTest.java diff --git a/spring-cloud-data-flow/time-processor/src/test/java/org/baeldung/SpringContextTest.java b/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/time-processor/src/test/java/org/baeldung/SpringContextTest.java similarity index 100% rename from spring-cloud-data-flow/time-processor/src/test/java/org/baeldung/SpringContextTest.java rename to spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/time-processor/src/test/java/org/baeldung/SpringContextTest.java diff --git a/spring-cloud-data-flow/time-source/pom.xml b/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/time-source/pom.xml similarity index 100% rename from spring-cloud-data-flow/time-source/pom.xml rename to spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/time-source/pom.xml diff --git a/spring-cloud-data-flow/time-source/src/main/java/org/baeldung/spring/cloud/TimeSourceApplication.java b/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/time-source/src/main/java/org/baeldung/spring/cloud/TimeSourceApplication.java similarity index 100% rename from spring-cloud-data-flow/time-source/src/main/java/org/baeldung/spring/cloud/TimeSourceApplication.java rename to spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/time-source/src/main/java/org/baeldung/spring/cloud/TimeSourceApplication.java diff --git a/spring-cloud-data-flow/time-processor/src/main/resources/logback.xml b/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/time-source/src/main/resources/logback.xml similarity index 100% rename from spring-cloud-data-flow/time-processor/src/main/resources/logback.xml rename to spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/time-source/src/main/resources/logback.xml diff --git a/spring-cloud-data-flow/time-source/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/time-source/src/test/java/org/baeldung/SpringContextIntegrationTest.java similarity index 100% rename from spring-cloud-data-flow/time-source/src/test/java/org/baeldung/SpringContextIntegrationTest.java rename to spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/time-source/src/test/java/org/baeldung/SpringContextIntegrationTest.java diff --git a/spring-cloud-data-flow/time-source/src/test/java/org/baeldung/SpringContextTest.java b/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/time-source/src/test/java/org/baeldung/SpringContextTest.java similarity index 100% rename from spring-cloud-data-flow/time-source/src/test/java/org/baeldung/SpringContextTest.java rename to spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/time-source/src/test/java/org/baeldung/SpringContextTest.java diff --git a/spring-cloud/spring-cloud-bootstrap/gateway/src/test/java/com/baeldung/spring/cloud/bootstrap/gateway/SpringContextTest.java b/spring-cloud/spring-cloud-bootstrap/gateway/src/test/java/com/baeldung/spring/cloud/bootstrap/gateway/SpringContextLiveTest.java similarity index 90% rename from spring-cloud/spring-cloud-bootstrap/gateway/src/test/java/com/baeldung/spring/cloud/bootstrap/gateway/SpringContextTest.java rename to spring-cloud/spring-cloud-bootstrap/gateway/src/test/java/com/baeldung/spring/cloud/bootstrap/gateway/SpringContextLiveTest.java index a2d1cd1087..a3cbb3310d 100644 --- a/spring-cloud/spring-cloud-bootstrap/gateway/src/test/java/com/baeldung/spring/cloud/bootstrap/gateway/SpringContextTest.java +++ b/spring-cloud/spring-cloud-bootstrap/gateway/src/test/java/com/baeldung/spring/cloud/bootstrap/gateway/SpringContextLiveTest.java @@ -7,7 +7,7 @@ import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest -public class SpringContextTest { +public class SpringContextLiveTest { @Test public void whenSpringContextIsBootstrapped_thenNoExceptions() { diff --git a/spring-cloud/spring-cloud-stream/spring-cloud-stream-kafka/README.md b/spring-cloud/spring-cloud-stream/spring-cloud-stream-kafka/README.md new file mode 100644 index 0000000000..81e0ffe5c8 --- /dev/null +++ b/spring-cloud/spring-cloud-stream/spring-cloud-stream-kafka/README.md @@ -0,0 +1,3 @@ +## Relevant Articles: + +- [Guide to Spring Cloud Stream with Kafka, Apache Avro and Confluent Schema Registry](https://www.baeldung.com/spring-cloud-stream-kafka-avro-confluent) diff --git a/spring-cloud/spring-cloud-vault/pom.xml b/spring-cloud/spring-cloud-vault/pom.xml index 9a1be3f5c0..faf27b6ac8 100644 --- a/spring-cloud/spring-cloud-vault/pom.xml +++ b/spring-cloud/spring-cloud-vault/pom.xml @@ -42,6 +42,18 @@ org.springframework.boot spring-boot-starter-jdbc + + org.springframework.boot + spring-boot-devtools + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-data-jpa + diff --git a/spring-cloud/spring-cloud-vault/src/main/java/org/baeldung/spring/cloud/vaultsample/AccountRepo.java b/spring-cloud/spring-cloud-vault/src/main/java/org/baeldung/spring/cloud/vaultsample/AccountRepo.java new file mode 100644 index 0000000000..318cc84957 --- /dev/null +++ b/spring-cloud/spring-cloud-vault/src/main/java/org/baeldung/spring/cloud/vaultsample/AccountRepo.java @@ -0,0 +1,10 @@ +package org.baeldung.spring.cloud.vaultsample; + +import org.baeldung.spring.cloud.vaultsample.domain.Account; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface AccountRepo extends JpaRepository{ + +} diff --git a/spring-cloud/spring-cloud-vault/src/main/java/org/baeldung/spring/cloud/vaultsample/AccountResource.java b/spring-cloud/spring-cloud-vault/src/main/java/org/baeldung/spring/cloud/vaultsample/AccountResource.java new file mode 100644 index 0000000000..8fcaa9e2aa --- /dev/null +++ b/spring-cloud/spring-cloud-vault/src/main/java/org/baeldung/spring/cloud/vaultsample/AccountResource.java @@ -0,0 +1,27 @@ +package org.baeldung.spring.cloud.vaultsample; + +import org.baeldung.spring.cloud.vaultsample.domain.Account; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class AccountResource { + @Autowired + private AccountRepo repo; + + @GetMapping("/account/{id}") + public ResponseEntity getAccount(@PathVariable("id") Long id) { + + Account acc = repo.findById(id).orElse(null); + if ( acc != null ) { + return new ResponseEntity(acc, HttpStatus.OK); + } + else { + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } + } +} diff --git a/spring-cloud/spring-cloud-vault/src/main/java/org/baeldung/spring/cloud/vaultsample/SecretResource.java b/spring-cloud/spring-cloud-vault/src/main/java/org/baeldung/spring/cloud/vaultsample/SecretResource.java new file mode 100644 index 0000000000..c4579da045 --- /dev/null +++ b/spring-cloud/spring-cloud-vault/src/main/java/org/baeldung/spring/cloud/vaultsample/SecretResource.java @@ -0,0 +1,37 @@ +/** + * + */ +package org.baeldung.spring.cloud.vaultsample; + + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.env.Environment; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RestController; + +/** + * @author Philippe + * + */ +@RestController +public class SecretResource { + + @Autowired + Environment env; + + @GetMapping("/secret/{key}") + public ResponseEntity readSecret(@PathVariable("key") String key) { + + String value = env.getProperty(key); + + if ( value != null ) { + return new ResponseEntity(value, HttpStatus.OK); + } + else { + return new ResponseEntity("not found", HttpStatus.NOT_FOUND); + } + } +} diff --git a/spring-cloud/spring-cloud-vault/src/main/java/org/baeldung/spring/cloud/vaultsample/domain/Account.java b/spring-cloud/spring-cloud-vault/src/main/java/org/baeldung/spring/cloud/vaultsample/domain/Account.java new file mode 100644 index 0000000000..df4778831b --- /dev/null +++ b/spring-cloud/spring-cloud-vault/src/main/java/org/baeldung/spring/cloud/vaultsample/domain/Account.java @@ -0,0 +1,133 @@ +/** + * + */ +package org.baeldung.spring.cloud.vaultsample.domain; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; +import javax.validation.constraints.NotNull; + +/** + * @author Philippe + * + */ +@Entity +@Table(name = "account") +public class Account { + + @Id + private Long id; + + @NotNull + private String name; + + private Long branchId; + private Long customerId; + + /** + * @return the id + */ + public Long getId() { + return id; + } + + /** + * @param id the id to set + */ + public void setId(Long id) { + this.id = id; + } + + /** + * @return the name + */ + public String getName() { + return name; + } + + /** + * @param name the name to set + */ + public void setName(String name) { + this.name = name; + } + + /** + * @return the branchId + */ + public Long getBranchId() { + return branchId; + } + + /** + * @param branchId the branchId to set + */ + public void setBranchId(Long branchId) { + this.branchId = branchId; + } + + /** + * @return the customerId + */ + public Long getCustomerId() { + return customerId; + } + + /** + * @param customerId the customerId to set + */ + public void setCustomerId(Long customerId) { + this.customerId = customerId; + } + + /* (non-Javadoc) + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((branchId == null) ? 0 : branchId.hashCode()); + result = prime * result + ((customerId == null) ? 0 : customerId.hashCode()); + result = prime * result + ((id == null) ? 0 : id.hashCode()); + result = prime * result + ((name == null) ? 0 : name.hashCode()); + return result; + } + + /* (non-Javadoc) + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Account other = (Account) obj; + if (branchId == null) { + if (other.branchId != null) + return false; + } else if (!branchId.equals(other.branchId)) + return false; + if (customerId == null) { + if (other.customerId != null) + return false; + } else if (!customerId.equals(other.customerId)) + return false; + if (id == null) { + if (other.id != null) + return false; + } else if (!id.equals(other.id)) + return false; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + return true; + } + +} diff --git a/spring-cloud/spring-cloud-vault/src/main/resources/application.yml b/spring-cloud/spring-cloud-vault/src/main/resources/application.yml index 3d347ec855..1c75ac21e6 100644 --- a/spring-cloud/spring-cloud-vault/src/main/resources/application.yml +++ b/spring-cloud/spring-cloud-vault/src/main/resources/application.yml @@ -1,6 +1,11 @@ -spring: - application: - name: fakebank - - datasource: - url: jdbc:mysql://localhost:3306/fakebank +spring: + application: + name: fakebank + + datasource: + url: jdbc:mysql://localhost:3306/fakebank?serverTimezone=GMT-3 + hikari: connection-test-query: select 1 + idle-timeout: 5000 + max-lifetime: 120000 + maximum-pool-size: 5 + minimum-idle: 5 diff --git a/spring-cloud/spring-cloud-vault/src/main/resources/bootstrap.yml b/spring-cloud/spring-cloud-vault/src/main/resources/bootstrap.yml index 1e837c4920..7d38b06c0f 100644 --- a/spring-cloud/spring-cloud-vault/src/main/resources/bootstrap.yml +++ b/spring-cloud/spring-cloud-vault/src/main/resources/bootstrap.yml @@ -4,8 +4,6 @@ spring: uri: https://localhost:8200 connection-timeout: 5000 read-timeout: 15000 - config: - order: -10 ssl: trust-store: classpath:/vault.jks @@ -15,17 +13,19 @@ spring: enabled: true application-name: fakebank - kv: - enabled: false - backend: kv - application-name: fakebank - +# kv: +# enabled: false +# backend: kv +# application-name: fakebank +# database: enabled: true role: fakebank-accounts-rw -# backend: database -# username-property: spring.datasource.username -# password-property: spring.datasource.password + backend: database + username-property: spring.datasource.username + password-property: spring.datasource.password +# +# diff --git a/spring-cloud/spring-cloud-vault/src/test/java/org/baeldung/spring/cloud/vaultsample/SpringContextTest.java b/spring-cloud/spring-cloud-vault/src/test/java/org/baeldung/spring/cloud/vaultsample/SpringContextLiveTest.java similarity index 91% rename from spring-cloud/spring-cloud-vault/src/test/java/org/baeldung/spring/cloud/vaultsample/SpringContextTest.java rename to spring-cloud/spring-cloud-vault/src/test/java/org/baeldung/spring/cloud/vaultsample/SpringContextLiveTest.java index 73fcbe55f0..3be4d96964 100644 --- a/spring-cloud/spring-cloud-vault/src/test/java/org/baeldung/spring/cloud/vaultsample/SpringContextTest.java +++ b/spring-cloud/spring-cloud-vault/src/test/java/org/baeldung/spring/cloud/vaultsample/SpringContextLiveTest.java @@ -7,7 +7,7 @@ import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest(classes = VaultSampleApplication.class) -public class SpringContextTest { +public class SpringContextLiveTest { @Test public void whenSpringContextIsBootstrapped_thenNoExceptions() { diff --git a/spring-cloud/spring-cloud-vault/src/test/vault-config/vault-test.hcl b/spring-cloud/spring-cloud-vault/src/test/vault-config/vault-test.hcl index c880f2d744..d16665a744 100644 --- a/spring-cloud/spring-cloud-vault/src/test/vault-config/vault-test.hcl +++ b/spring-cloud/spring-cloud-vault/src/test/vault-config/vault-test.hcl @@ -17,4 +17,7 @@ listener "tcp" { tls_key_file = "./src/test/vault-config/localhost.key" } +// Audit to stdout + + diff --git a/spring-cloud/spring-cloud-vault/vault-cheatsheet.txt b/spring-cloud/spring-cloud-vault/vault-cheatsheet.txt index b965a95321..2d5f2363ac 100644 --- a/spring-cloud/spring-cloud-vault/vault-cheatsheet.txt +++ b/spring-cloud/spring-cloud-vault/vault-cheatsheet.txt @@ -5,16 +5,13 @@ 2. Open another shell and execute the command below: > vault operator init -Vault will output the unseal keys and root token: STORE THEM SAFELY !!! +Unseal Key 1: Iwvpd4IVofhcmQ2HEIPs5HMUbz4tz6JhqmLZ6+1MhAPx +Unseal Key 2: ANQDXUFGGtLtt6grX25YsdmeKELhM/ioKWzwFukJIe2f +Unseal Key 3: 8MHyzFnOvlwVQzdWYJ3BIN4xPDOn8a4VemZ/Qe5HgurU +Unseal Key 4: ywT9YR9OfxIpA4l1RniNNCvSZWAuNZsAEFRyD7aqFOrp +Unseal Key 5: q1c7M+lnlT72jGLoCH+jjri6KGSBhc5lCzlT0I1R9URU -Example output: -Unseal Key 1: OfCseaSZzjTZmrxhfx+5clKobwLGCNiJdAlfixSG9E3o -Unseal Key 2: iplVLPTHW0n0WL5XuI6QWwyNtWbKTek1SoKcG0gR7vdT -Unseal Key 3: K0TleK3OYUvWFF+uIDsQuf5a+/gkv1PtZ3O47ornzRoF -Unseal Key 4: +5zhysLAO4hIdZs0kiZpkrRovw11uQacfloiBwnZBJA/ -Unseal Key 5: GDwSq18lXV3Cw4MoHsKIH137kuI0mdl36UiD9WxOdulc - -Initial Root Token: d341fdaf-1cf9-936a-3c38-cf5eec94b5c0 +Initial Root Token: dee7107a-8819-0719-62a3-cea3ea854589 ... @@ -73,8 +70,8 @@ flush privileges; > vault write database/roles/fakebank-accounts-rw ^ db_name=mysql-fakebank ^ creation_statements="CREATE USER '{{name}}'@'%' IDENTIFIED BY '{{password}}';GRANT SELECT,INSERT,UPDATE ON fakebank.* TO '{{name}}'@'%';" ^ - default_ttl="1m" ^ - max_ttl="2m" + default_ttl="5m" ^ + max_ttl="30m" === Get credentials > vault read database/creds/fakebank-accounts-rw diff --git a/spring-cloud/spring-cloud-vault/vault-unseal.bat b/spring-cloud/spring-cloud-vault/vault-unseal.bat index 8133f90892..1e3f229fcf 100644 --- a/spring-cloud/spring-cloud-vault/vault-unseal.bat +++ b/spring-cloud/spring-cloud-vault/vault-unseal.bat @@ -1,7 +1,7 @@ call %~dp0%/vault-env.bat -vault operator unseal OfCseaSZzjTZmrxhfx+5clKobwLGCNiJdAlfixSG9E3o -vault operator unseal iplVLPTHW0n0WL5XuI6QWwyNtWbKTek1SoKcG0gR7vdT -vault operator unseal iplVLPTHW0n0WL5XuI6QWwyNtWbKTek1SoKcG0gR7vdT -vault operator unseal K0TleK3OYUvWFF+uIDsQuf5a+/gkv1PtZ3O47ornzRoF +vault operator unseal Iwvpd4IVofhcmQ2HEIPs5HMUbz4tz6JhqmLZ6+1MhAPx +vault operator unseal ANQDXUFGGtLtt6grX25YsdmeKELhM/ioKWzwFukJIe2f +vault operator unseal 8MHyzFnOvlwVQzdWYJ3BIN4xPDOn8a4VemZ/Qe5HgurU + diff --git a/spring-core-2/README.md b/spring-core-2/README.md new file mode 100644 index 0000000000..4c9e3b9ddf --- /dev/null +++ b/spring-core-2/README.md @@ -0,0 +1,3 @@ +## Relevant Articles: + +- [Understanding getBean() in Spring](https://www.baeldung.com/spring-getbean) diff --git a/spring-core-2/pom.xml b/spring-core-2/pom.xml index 20cd900e00..6b5547aba9 100644 --- a/spring-core-2/pom.xml +++ b/spring-core-2/pom.xml @@ -47,13 +47,13 @@ org.apache.maven.plugins maven-surefire-plugin - 2.22.1 + ${maven.surefire.version} - 5.1.4.RELEASE + 2.22.1 \ No newline at end of file diff --git a/spring-core/README.md b/spring-core/README.md index 18d14b7ecf..111b034bef 100644 --- a/spring-core/README.md +++ b/spring-core/README.md @@ -4,14 +4,10 @@ - [How to use the Spring FactoryBean?](http://www.baeldung.com/spring-factorybean) - [Constructor Dependency Injection in Spring](http://www.baeldung.com/constructor-injection-in-spring) - [Constructor Injection in Spring with Lombok](http://www.baeldung.com/spring-injection-lombok) -- [A Quick Guide to Spring @Value](http://www.baeldung.com/spring-value-annotation) -- [Spring YAML Configuration](http://www.baeldung.com/spring-yaml) - [Introduction to Spring’s StreamUtils](http://www.baeldung.com/spring-stream-utils) -- [Using Spring @Value with Defaults](http://www.baeldung.com/spring-value-defaults) - [XML-Based Injection in Spring](http://www.baeldung.com/spring-xml-injection) - [A Quick Guide to the Spring @Lazy Annotation](http://www.baeldung.com/spring-lazy-annotation) - [Injecting Prototype Beans into a Singleton Instance in Spring](http://www.baeldung.com/spring-inject-prototype-bean-into-singleton) -- [How to Inject a Property Value Into a Class Not Managed by Spring?](http://www.baeldung.com/inject-properties-value-non-spring-class) - [@Lookup Annotation in Spring](http://www.baeldung.com/spring-lookup) - [BeanNameAware and BeanFactoryAware Interfaces in Spring](http://www.baeldung.com/spring-bean-name-factory-aware) - [Spring – Injecting Collections](http://www.baeldung.com/spring-injecting-collections) diff --git a/spring-data-rest-querydsl/src/test/java/org/baeldung/SpringContextTest.java b/spring-data-rest-querydsl/src/test/java/org/baeldung/SpringContextLiveTest.java similarity index 91% rename from spring-data-rest-querydsl/src/test/java/org/baeldung/SpringContextTest.java rename to spring-data-rest-querydsl/src/test/java/org/baeldung/SpringContextLiveTest.java index 5e68a8e64f..5cb0a8167e 100644 --- a/spring-data-rest-querydsl/src/test/java/org/baeldung/SpringContextTest.java +++ b/spring-data-rest-querydsl/src/test/java/org/baeldung/SpringContextLiveTest.java @@ -9,7 +9,7 @@ import com.baeldung.Application; @RunWith(SpringRunner.class) @SpringBootTest(classes = Application.class) -public class SpringContextTest { +public class SpringContextLiveTest { @Test public void whenSpringContextIsBootstrapped_thenNoExceptions() { diff --git a/spring-di/README.md b/spring-di/README.md new file mode 100644 index 0000000000..a61ebe5127 --- /dev/null +++ b/spring-di/README.md @@ -0,0 +1,3 @@ +### Relevant Articles + +- [The Spring @Qualifier Annotation](https://www.baeldung.com/spring-qualifier-annotation) diff --git a/spring-di/pom.xml b/spring-di/pom.xml new file mode 100644 index 0000000000..62456ba31c --- /dev/null +++ b/spring-di/pom.xml @@ -0,0 +1,101 @@ + + + 4.0.0 + spring-di + 1.0-SNAPSHOT + war + + + parent-boot-2 + com.baeldung + 0.0.1-SNAPSHOT + ../parent-boot-2 + + + + + + org.springframework + spring-context + + + + javax.annotation + javax.annotation-api + ${annotation-api.version} + + + + + org.springframework + spring-test + test + + + + + + + + org.springframework + spring-framework-bom + ${org.springframework.version} + pom + import + + + org.springframework + spring-core + ${org.springframework.version} + + + + + + spring-di + + + src/main/resources + true + + + + + org.apache.maven.plugins + maven-war-plugin + 3.2.2 + + false + + + + + + + + dev + + true + + + dev + + + + prod + + prod + + + + + + org.baeldung.org.baeldung.sample.App + + 5.0.6.RELEASE + 1.3.2 + + + \ No newline at end of file diff --git a/spring-di/src/main/java/org/baeldung/sample/App.java b/spring-di/src/main/java/org/baeldung/sample/App.java new file mode 100644 index 0000000000..17fc49fc8c --- /dev/null +++ b/spring-di/src/main/java/org/baeldung/sample/App.java @@ -0,0 +1,11 @@ +package org.baeldung.sample; + +import org.springframework.context.annotation.AnnotationConfigApplicationContext; + +public class App { + public static void main(String[] args) { + AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class); + FooService fooService = ctx.getBean(FooService.class); + fooService.doStuff(); + } +} diff --git a/spring-di/src/main/java/org/baeldung/sample/AppConfig.java b/spring-di/src/main/java/org/baeldung/sample/AppConfig.java new file mode 100644 index 0000000000..8a177d2611 --- /dev/null +++ b/spring-di/src/main/java/org/baeldung/sample/AppConfig.java @@ -0,0 +1,10 @@ +package org.baeldung.sample; + +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +@Configuration +@ComponentScan("org.baeldung.sample") +public class AppConfig { + +} diff --git a/spring-di/src/main/java/org/baeldung/sample/Bar.java b/spring-di/src/main/java/org/baeldung/sample/Bar.java new file mode 100644 index 0000000000..54e8d54418 --- /dev/null +++ b/spring-di/src/main/java/org/baeldung/sample/Bar.java @@ -0,0 +1,5 @@ +package org.baeldung.sample; + +public class Bar { + +} diff --git a/spring-di/src/main/java/org/baeldung/sample/BarFormatter.java b/spring-di/src/main/java/org/baeldung/sample/BarFormatter.java new file mode 100644 index 0000000000..8396653970 --- /dev/null +++ b/spring-di/src/main/java/org/baeldung/sample/BarFormatter.java @@ -0,0 +1,13 @@ +package org.baeldung.sample; + +import org.springframework.stereotype.Component; + +@FormatterType("Bar") +@Component +public class BarFormatter implements Formatter { + + public String format() { + return "bar"; + } + +} diff --git a/spring-di/src/main/java/org/baeldung/sample/Foo.java b/spring-di/src/main/java/org/baeldung/sample/Foo.java new file mode 100644 index 0000000000..562a00121a --- /dev/null +++ b/spring-di/src/main/java/org/baeldung/sample/Foo.java @@ -0,0 +1,5 @@ +package org.baeldung.sample; + +public class Foo { + +} diff --git a/spring-di/src/main/java/org/baeldung/sample/FooDAO.java b/spring-di/src/main/java/org/baeldung/sample/FooDAO.java new file mode 100644 index 0000000000..151c0c38de --- /dev/null +++ b/spring-di/src/main/java/org/baeldung/sample/FooDAO.java @@ -0,0 +1,5 @@ +package org.baeldung.sample; + +public class FooDAO { + +} diff --git a/spring-di/src/main/java/org/baeldung/sample/FooFormatter.java b/spring-di/src/main/java/org/baeldung/sample/FooFormatter.java new file mode 100644 index 0000000000..68cb7f81f2 --- /dev/null +++ b/spring-di/src/main/java/org/baeldung/sample/FooFormatter.java @@ -0,0 +1,13 @@ +package org.baeldung.sample; + +import org.springframework.stereotype.Component; + +@FormatterType("Foo") +@Component +public class FooFormatter implements Formatter { + + public String format() { + return "foo"; + } + +} diff --git a/spring-di/src/main/java/org/baeldung/sample/FooService.java b/spring-di/src/main/java/org/baeldung/sample/FooService.java new file mode 100644 index 0000000000..711711f205 --- /dev/null +++ b/spring-di/src/main/java/org/baeldung/sample/FooService.java @@ -0,0 +1,17 @@ +package org.baeldung.sample; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class FooService { + + @Autowired + @FormatterType("Foo") + private Formatter formatter; + + public String doStuff() { + return formatter.format(); + } + +} diff --git a/spring-di/src/main/java/org/baeldung/sample/Formatter.java b/spring-di/src/main/java/org/baeldung/sample/Formatter.java new file mode 100644 index 0000000000..ab29c2b848 --- /dev/null +++ b/spring-di/src/main/java/org/baeldung/sample/Formatter.java @@ -0,0 +1,7 @@ +package org.baeldung.sample; + +public interface Formatter { + + String format(); + +} diff --git a/spring-di/src/main/java/org/baeldung/sample/FormatterType.java b/spring-di/src/main/java/org/baeldung/sample/FormatterType.java new file mode 100644 index 0000000000..a00a9750bf --- /dev/null +++ b/spring-di/src/main/java/org/baeldung/sample/FormatterType.java @@ -0,0 +1,17 @@ +package org.baeldung.sample; + +import org.springframework.beans.factory.annotation.Qualifier; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Qualifier +@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.TYPE, ElementType.PARAMETER }) +@Retention(RetentionPolicy.RUNTIME) +public @interface FormatterType { + + String value(); + +} diff --git a/spring-di/src/test/java/org/baeldung/sample/FooServiceIntegrationTest.java b/spring-di/src/test/java/org/baeldung/sample/FooServiceIntegrationTest.java new file mode 100644 index 0000000000..6b518395a1 --- /dev/null +++ b/spring-di/src/test/java/org/baeldung/sample/FooServiceIntegrationTest.java @@ -0,0 +1,22 @@ +package org.baeldung.sample; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.support.AnnotationConfigContextLoader; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = AppConfig.class, loader = AnnotationConfigContextLoader.class) +public class FooServiceIntegrationTest { + + @Autowired + FooService fooService; + + @Test + public void whenFooFormatterType_thenReturnFoo() { + Assert.assertEquals("foo", fooService.doStuff()); + } +} diff --git a/spring-ejb/spring-ejb-client/src/test/java/org/baeldung/SpringContextTest.java b/spring-ejb/spring-ejb-client/src/test/java/org/baeldung/SpringContextLiveTest.java similarity index 92% rename from spring-ejb/spring-ejb-client/src/test/java/org/baeldung/SpringContextTest.java rename to spring-ejb/spring-ejb-client/src/test/java/org/baeldung/SpringContextLiveTest.java index 3e9af8a336..bbd3b6c2ba 100644 --- a/spring-ejb/spring-ejb-client/src/test/java/org/baeldung/SpringContextTest.java +++ b/spring-ejb/spring-ejb-client/src/test/java/org/baeldung/SpringContextLiveTest.java @@ -9,7 +9,7 @@ import com.baeldung.springejbclient.SpringEjbClientApplication; @RunWith(SpringRunner.class) @SpringBootTest(classes = SpringEjbClientApplication.class) -public class SpringContextTest { +public class SpringContextLiveTest { @Test public void whenSpringContextIsBootstrapped_thenNoExceptions() { diff --git a/spring-groovy/README.md b/spring-groovy/README.md index ff12555376..36404230a9 100644 --- a/spring-groovy/README.md +++ b/spring-groovy/README.md @@ -1 +1,3 @@ -## Relevant articles: +## Relevant Articles: + +- [Groovy Bean Definitions](https://www.baeldung.com/spring-groovy-beans) diff --git a/spring-jooq/src/test/java/com/baeldung/jooq/introduction/QueryIntegrationTest.java b/spring-jooq/src/test/java/com/baeldung/jooq/introduction/QueryIntegrationTest.java index 28bc4c63c7..ff1e8dc6f8 100644 --- a/spring-jooq/src/test/java/com/baeldung/jooq/introduction/QueryIntegrationTest.java +++ b/spring-jooq/src/test/java/com/baeldung/jooq/introduction/QueryIntegrationTest.java @@ -47,12 +47,14 @@ public class QueryIntegrationTest { .from(AUTHOR) .join(AUTHOR_BOOK).on(AUTHOR.ID.equal(AUTHOR_BOOK.AUTHOR_ID)) .join(BOOK).on(AUTHOR_BOOK.BOOK_ID.equal(BOOK.ID)) - .groupBy(AUTHOR.LAST_NAME).fetch(); + .groupBy(AUTHOR.LAST_NAME) + .orderBy(AUTHOR.LAST_NAME.desc()) + .fetch(); assertEquals(3, result.size()); assertEquals("Sierra", result.getValue(0, AUTHOR.LAST_NAME)); assertEquals(Integer.valueOf(2), result.getValue(0, DSL.count())); - assertEquals("Schildt", result.getValue(2, AUTHOR.LAST_NAME)); + assertEquals("Bates", result.getValue(2, AUTHOR.LAST_NAME)); assertEquals(Integer.valueOf(1), result.getValue(2, DSL.count())); } diff --git a/spring-jooq/src/test/java/com/baeldung/jooq/springboot/SpringBootIntegrationTest.java b/spring-jooq/src/test/java/com/baeldung/jooq/springboot/SpringBootIntegrationTest.java index 5e76fb3c93..3b3e865108 100644 --- a/spring-jooq/src/test/java/com/baeldung/jooq/springboot/SpringBootIntegrationTest.java +++ b/spring-jooq/src/test/java/com/baeldung/jooq/springboot/SpringBootIntegrationTest.java @@ -49,12 +49,13 @@ public class SpringBootIntegrationTest { .from(AUTHOR).join(AUTHOR_BOOK).on(AUTHOR.ID.equal(AUTHOR_BOOK.AUTHOR_ID)) .join(BOOK).on(AUTHOR_BOOK.BOOK_ID.equal(BOOK.ID)) .groupBy(AUTHOR.LAST_NAME) + .orderBy(AUTHOR.LAST_NAME.desc()) .fetch(); assertEquals(3, result.size()); assertEquals("Sierra", result.getValue(0, AUTHOR.LAST_NAME)); assertEquals(Integer.valueOf(2), result.getValue(0, DSL.count())); - assertEquals("Schildt", result.getValue(2, AUTHOR.LAST_NAME)); + assertEquals("Bates", result.getValue(2, AUTHOR.LAST_NAME)); assertEquals(Integer.valueOf(1), result.getValue(2, DSL.count())); } diff --git a/spring-security-client/README.MD b/spring-security-client/README.MD deleted file mode 100644 index 0b0af7ffe1..0000000000 --- a/spring-security-client/README.MD +++ /dev/null @@ -1,11 +0,0 @@ -========= -## Spring Security Authentication/Authorization Example Project - -##The Course -The "REST With Spring" Classes: http://github.learnspringsecurity.com - -### Relevant Articles: -- [Spring Security Manual Authentication](http://www.baeldung.com/spring-security-authentication) - -### Build the Project -mvn clean install diff --git a/spring-security-client/pom.xml b/spring-security-client/pom.xml deleted file mode 100644 index 96ac837a09..0000000000 --- a/spring-security-client/pom.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - 4.0.0 - spring-security-client - spring-security-client - pom - - - com.baeldung - parent-modules - 1.0.0-SNAPSHOT - .. - - - - spring-security-jsp-authentication - spring-security-jsp-authorize - spring-security-jsp-config - spring-security-mvc - spring-security-thymeleaf-authentication - spring-security-thymeleaf-authorize - spring-security-thymeleaf-config - - diff --git a/spring-security-client/spring-security-jsp-authentication/pom.xml b/spring-security-client/spring-security-jsp-authentication/pom.xml deleted file mode 100644 index 9cb2a45331..0000000000 --- a/spring-security-client/spring-security-jsp-authentication/pom.xml +++ /dev/null @@ -1,47 +0,0 @@ - - - 4.0.0 - com.baeldung - spring-security-jsp-authentication - 0.0.1-SNAPSHOT - spring-security-jsp-authentication - war - Spring Security JSP Authentication tag sample - - - parent-boot-1 - com.baeldung - 0.0.1-SNAPSHOT - ../../parent-boot-1 - - - - - org.springframework.boot - spring-boot-starter-security - - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.boot - spring-boot-starter-tomcat - - - org.apache.tomcat.embed - tomcat-embed-jasper - provided - - - javax.servlet - jstl - - - org.springframework.security - spring-security-taglibs - - - - diff --git a/spring-security-client/spring-security-jsp-authentication/src/main/java/org/baeldung/config/Application.java b/spring-security-client/spring-security-jsp-authentication/src/main/java/org/baeldung/config/Application.java deleted file mode 100644 index c2c5939676..0000000000 --- a/spring-security-client/spring-security-jsp-authentication/src/main/java/org/baeldung/config/Application.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.baeldung.config; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; -import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.boot.web.support.SpringBootServletInitializer; - -@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class }) -public class Application extends SpringBootServletInitializer { - - @Override - protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { - return application.sources(Application.class); - } - - public static void main(String[] args) { - SpringApplication.run(Application.class, args); - } - -} diff --git a/spring-security-client/spring-security-jsp-authentication/src/main/java/org/baeldung/config/MvcConfig.java b/spring-security-client/spring-security-jsp-authentication/src/main/java/org/baeldung/config/MvcConfig.java deleted file mode 100644 index fa2a324146..0000000000 --- a/spring-security-client/spring-security-jsp-authentication/src/main/java/org/baeldung/config/MvcConfig.java +++ /dev/null @@ -1,23 +0,0 @@ -package org.baeldung.config; - -import org.springframework.context.annotation.Configuration; -import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; - -@Configuration -public class MvcConfig extends WebMvcConfigurerAdapter { - - public MvcConfig() { - super(); - } - - // - - @Override - public void addViewControllers(final ViewControllerRegistry registry) { - super.addViewControllers(registry); - registry.addViewController("/").setViewName("forward:/index"); - registry.addViewController("/index"); - } - -} \ No newline at end of file diff --git a/spring-security-client/spring-security-jsp-authentication/src/main/java/org/baeldung/config/SecurityConfig.java b/spring-security-client/spring-security-jsp-authentication/src/main/java/org/baeldung/config/SecurityConfig.java deleted file mode 100644 index bd6c56d38a..0000000000 --- a/spring-security-client/spring-security-jsp-authentication/src/main/java/org/baeldung/config/SecurityConfig.java +++ /dev/null @@ -1,40 +0,0 @@ -package org.baeldung.config; - -import org.springframework.context.annotation.Configuration; -import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.builders.WebSecurity; -import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; - -@Configuration -@EnableWebSecurity -public class SecurityConfig extends WebSecurityConfigurerAdapter { - - @Override - protected void configure(final AuthenticationManagerBuilder auth) throws Exception { - // @formatter:off - auth.inMemoryAuthentication() - .withUser("john").password("123").roles("USER") - .and() - .withUser("tom").password("111").roles("ADMIN"); - // @formatter:on - } - - @Override - public void configure(WebSecurity web) throws Exception { - web.ignoring().antMatchers("/resources/**"); - } - - @Override - protected void configure(final HttpSecurity http) throws Exception { - // @formatter:off - http.authorizeRequests() - .antMatchers("/login").permitAll() - .antMatchers("/admin").hasRole("ADMIN") - .anyRequest().authenticated() - .and().formLogin().permitAll() - ; - // @formatter:on - } -} \ No newline at end of file diff --git a/spring-security-client/spring-security-jsp-authentication/src/main/resources/application.properties b/spring-security-client/spring-security-jsp-authentication/src/main/resources/application.properties deleted file mode 100644 index 26a80c79f3..0000000000 --- a/spring-security-client/spring-security-jsp-authentication/src/main/resources/application.properties +++ /dev/null @@ -1,3 +0,0 @@ -server.port: 8081 -spring.mvc.view.prefix: /WEB-INF/jsp/ -spring.mvc.view.suffix: .jsp \ No newline at end of file diff --git a/spring-security-client/spring-security-jsp-authentication/src/main/webapp/WEB-INF/jsp/index.jsp b/spring-security-client/spring-security-jsp-authentication/src/main/webapp/WEB-INF/jsp/index.jsp deleted file mode 100644 index 90c00e980a..0000000000 --- a/spring-security-client/spring-security-jsp-authentication/src/main/webapp/WEB-INF/jsp/index.jsp +++ /dev/null @@ -1,24 +0,0 @@ - <%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %> - - - - -Spring Security JSP Authorize - - - - - -
    - Current user name: -
    - Current user roles: -
    - - \ No newline at end of file diff --git a/spring-security-client/spring-security-jsp-authentication/src/test/java/org/baeldung/SpringContextTest.java b/spring-security-client/spring-security-jsp-authentication/src/test/java/org/baeldung/SpringContextTest.java deleted file mode 100644 index 0afb3899db..0000000000 --- a/spring-security-client/spring-security-jsp-authentication/src/test/java/org/baeldung/SpringContextTest.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.baeldung; - -import org.baeldung.config.Application; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringRunner; - -@RunWith(SpringRunner.class) -@SpringBootTest(classes = Application.class) -public class SpringContextTest { - - @Test - public void whenSpringContextIsBootstrapped_thenNoExceptions() { - } -} diff --git a/spring-security-client/spring-security-jsp-authorize/pom.xml b/spring-security-client/spring-security-jsp-authorize/pom.xml deleted file mode 100644 index ad4c9d105b..0000000000 --- a/spring-security-client/spring-security-jsp-authorize/pom.xml +++ /dev/null @@ -1,47 +0,0 @@ - - - 4.0.0 - com.baeldung - spring-security-jsp-authorize - 0.0.1-SNAPSHOT - spring-security-jsp-authorize - Spring Security JSP Authorize tag sample - war - - - parent-boot-1 - com.baeldung - 0.0.1-SNAPSHOT - ../../parent-boot-1 - - - - - org.springframework.boot - spring-boot-starter-security - - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.boot - spring-boot-starter-tomcat - - - org.apache.tomcat.embed - tomcat-embed-jasper - provided - - - javax.servlet - jstl - - - org.springframework.security - spring-security-taglibs - - - - diff --git a/spring-security-client/spring-security-jsp-authorize/src/main/java/org/baeldung/config/Application.java b/spring-security-client/spring-security-jsp-authorize/src/main/java/org/baeldung/config/Application.java deleted file mode 100644 index c2c5939676..0000000000 --- a/spring-security-client/spring-security-jsp-authorize/src/main/java/org/baeldung/config/Application.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.baeldung.config; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; -import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.boot.web.support.SpringBootServletInitializer; - -@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class }) -public class Application extends SpringBootServletInitializer { - - @Override - protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { - return application.sources(Application.class); - } - - public static void main(String[] args) { - SpringApplication.run(Application.class, args); - } - -} diff --git a/spring-security-client/spring-security-jsp-authorize/src/main/java/org/baeldung/config/MvcConfig.java b/spring-security-client/spring-security-jsp-authorize/src/main/java/org/baeldung/config/MvcConfig.java deleted file mode 100644 index fa2a324146..0000000000 --- a/spring-security-client/spring-security-jsp-authorize/src/main/java/org/baeldung/config/MvcConfig.java +++ /dev/null @@ -1,23 +0,0 @@ -package org.baeldung.config; - -import org.springframework.context.annotation.Configuration; -import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; - -@Configuration -public class MvcConfig extends WebMvcConfigurerAdapter { - - public MvcConfig() { - super(); - } - - // - - @Override - public void addViewControllers(final ViewControllerRegistry registry) { - super.addViewControllers(registry); - registry.addViewController("/").setViewName("forward:/index"); - registry.addViewController("/index"); - } - -} \ No newline at end of file diff --git a/spring-security-client/spring-security-jsp-authorize/src/main/java/org/baeldung/config/SecurityConfig.java b/spring-security-client/spring-security-jsp-authorize/src/main/java/org/baeldung/config/SecurityConfig.java deleted file mode 100644 index bd6c56d38a..0000000000 --- a/spring-security-client/spring-security-jsp-authorize/src/main/java/org/baeldung/config/SecurityConfig.java +++ /dev/null @@ -1,40 +0,0 @@ -package org.baeldung.config; - -import org.springframework.context.annotation.Configuration; -import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.builders.WebSecurity; -import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; - -@Configuration -@EnableWebSecurity -public class SecurityConfig extends WebSecurityConfigurerAdapter { - - @Override - protected void configure(final AuthenticationManagerBuilder auth) throws Exception { - // @formatter:off - auth.inMemoryAuthentication() - .withUser("john").password("123").roles("USER") - .and() - .withUser("tom").password("111").roles("ADMIN"); - // @formatter:on - } - - @Override - public void configure(WebSecurity web) throws Exception { - web.ignoring().antMatchers("/resources/**"); - } - - @Override - protected void configure(final HttpSecurity http) throws Exception { - // @formatter:off - http.authorizeRequests() - .antMatchers("/login").permitAll() - .antMatchers("/admin").hasRole("ADMIN") - .anyRequest().authenticated() - .and().formLogin().permitAll() - ; - // @formatter:on - } -} \ No newline at end of file diff --git a/spring-security-client/spring-security-jsp-authorize/src/main/resources/application.properties b/spring-security-client/spring-security-jsp-authorize/src/main/resources/application.properties deleted file mode 100644 index 26a80c79f3..0000000000 --- a/spring-security-client/spring-security-jsp-authorize/src/main/resources/application.properties +++ /dev/null @@ -1,3 +0,0 @@ -server.port: 8081 -spring.mvc.view.prefix: /WEB-INF/jsp/ -spring.mvc.view.suffix: .jsp \ No newline at end of file diff --git a/spring-security-client/spring-security-jsp-authorize/src/main/webapp/WEB-INF/jsp/index.jsp b/spring-security-client/spring-security-jsp-authorize/src/main/webapp/WEB-INF/jsp/index.jsp deleted file mode 100644 index 08af845bd4..0000000000 --- a/spring-security-client/spring-security-jsp-authorize/src/main/webapp/WEB-INF/jsp/index.jsp +++ /dev/null @@ -1,33 +0,0 @@ - <%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %> - - - - -Spring Security JSP Authorize - - - - - -
    - - Only admins can see this message - - - - Only users can see this message - -
    - - - Only users who can call "/admin" URL can see this message - -
    - - \ No newline at end of file diff --git a/spring-security-client/spring-security-jsp-authorize/src/test/java/org/baeldung/SpringContextTest.java b/spring-security-client/spring-security-jsp-authorize/src/test/java/org/baeldung/SpringContextTest.java deleted file mode 100644 index 0afb3899db..0000000000 --- a/spring-security-client/spring-security-jsp-authorize/src/test/java/org/baeldung/SpringContextTest.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.baeldung; - -import org.baeldung.config.Application; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringRunner; - -@RunWith(SpringRunner.class) -@SpringBootTest(classes = Application.class) -public class SpringContextTest { - - @Test - public void whenSpringContextIsBootstrapped_thenNoExceptions() { - } -} diff --git a/spring-security-client/spring-security-jsp-config/pom.xml b/spring-security-client/spring-security-jsp-config/pom.xml deleted file mode 100644 index 02ea206738..0000000000 --- a/spring-security-client/spring-security-jsp-config/pom.xml +++ /dev/null @@ -1,47 +0,0 @@ - - - 4.0.0 - com.baeldung - spring-security-jsp-config - 0.0.1-SNAPSHOT - spring-security-jsp-config - Spring Security JSP configuration - war - - - parent-boot-1 - com.baeldung - 0.0.1-SNAPSHOT - ../../parent-boot-1 - - - - - org.springframework.boot - spring-boot-starter-security - - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.boot - spring-boot-starter-tomcat - - - org.apache.tomcat.embed - tomcat-embed-jasper - provided - - - javax.servlet - jstl - - - org.springframework.security - spring-security-taglibs - - - - diff --git a/spring-security-client/spring-security-jsp-config/src/main/java/org/baeldung/config/Application.java b/spring-security-client/spring-security-jsp-config/src/main/java/org/baeldung/config/Application.java deleted file mode 100644 index c2c5939676..0000000000 --- a/spring-security-client/spring-security-jsp-config/src/main/java/org/baeldung/config/Application.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.baeldung.config; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; -import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.boot.web.support.SpringBootServletInitializer; - -@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class }) -public class Application extends SpringBootServletInitializer { - - @Override - protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { - return application.sources(Application.class); - } - - public static void main(String[] args) { - SpringApplication.run(Application.class, args); - } - -} diff --git a/spring-security-client/spring-security-jsp-config/src/main/java/org/baeldung/config/MvcConfig.java b/spring-security-client/spring-security-jsp-config/src/main/java/org/baeldung/config/MvcConfig.java deleted file mode 100644 index fa2a324146..0000000000 --- a/spring-security-client/spring-security-jsp-config/src/main/java/org/baeldung/config/MvcConfig.java +++ /dev/null @@ -1,23 +0,0 @@ -package org.baeldung.config; - -import org.springframework.context.annotation.Configuration; -import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; - -@Configuration -public class MvcConfig extends WebMvcConfigurerAdapter { - - public MvcConfig() { - super(); - } - - // - - @Override - public void addViewControllers(final ViewControllerRegistry registry) { - super.addViewControllers(registry); - registry.addViewController("/").setViewName("forward:/index"); - registry.addViewController("/index"); - } - -} \ No newline at end of file diff --git a/spring-security-client/spring-security-jsp-config/src/main/java/org/baeldung/config/SecurityConfig.java b/spring-security-client/spring-security-jsp-config/src/main/java/org/baeldung/config/SecurityConfig.java deleted file mode 100644 index bd6c56d38a..0000000000 --- a/spring-security-client/spring-security-jsp-config/src/main/java/org/baeldung/config/SecurityConfig.java +++ /dev/null @@ -1,40 +0,0 @@ -package org.baeldung.config; - -import org.springframework.context.annotation.Configuration; -import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.builders.WebSecurity; -import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; - -@Configuration -@EnableWebSecurity -public class SecurityConfig extends WebSecurityConfigurerAdapter { - - @Override - protected void configure(final AuthenticationManagerBuilder auth) throws Exception { - // @formatter:off - auth.inMemoryAuthentication() - .withUser("john").password("123").roles("USER") - .and() - .withUser("tom").password("111").roles("ADMIN"); - // @formatter:on - } - - @Override - public void configure(WebSecurity web) throws Exception { - web.ignoring().antMatchers("/resources/**"); - } - - @Override - protected void configure(final HttpSecurity http) throws Exception { - // @formatter:off - http.authorizeRequests() - .antMatchers("/login").permitAll() - .antMatchers("/admin").hasRole("ADMIN") - .anyRequest().authenticated() - .and().formLogin().permitAll() - ; - // @formatter:on - } -} \ No newline at end of file diff --git a/spring-security-client/spring-security-jsp-config/src/main/resources/application.properties b/spring-security-client/spring-security-jsp-config/src/main/resources/application.properties deleted file mode 100644 index 26a80c79f3..0000000000 --- a/spring-security-client/spring-security-jsp-config/src/main/resources/application.properties +++ /dev/null @@ -1,3 +0,0 @@ -server.port: 8081 -spring.mvc.view.prefix: /WEB-INF/jsp/ -spring.mvc.view.suffix: .jsp \ No newline at end of file diff --git a/spring-security-client/spring-security-jsp-config/src/main/resources/logback.xml b/spring-security-client/spring-security-jsp-config/src/main/resources/logback.xml deleted file mode 100644 index 7d900d8ea8..0000000000 --- a/spring-security-client/spring-security-jsp-config/src/main/resources/logback.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n - - - - - - - - \ No newline at end of file diff --git a/spring-security-client/spring-security-jsp-config/src/main/webapp/WEB-INF/jsp/index.jsp b/spring-security-client/spring-security-jsp-config/src/main/webapp/WEB-INF/jsp/index.jsp deleted file mode 100644 index bd5ccb0c78..0000000000 --- a/spring-security-client/spring-security-jsp-config/src/main/webapp/WEB-INF/jsp/index.jsp +++ /dev/null @@ -1,21 +0,0 @@ - - - - -Spring Security JSP - - - - - -
    - Welcome -
    - - \ No newline at end of file diff --git a/spring-security-client/spring-security-jsp-config/src/test/java/org/baeldung/SpringContextTest.java b/spring-security-client/spring-security-jsp-config/src/test/java/org/baeldung/SpringContextTest.java deleted file mode 100644 index 0afb3899db..0000000000 --- a/spring-security-client/spring-security-jsp-config/src/test/java/org/baeldung/SpringContextTest.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.baeldung; - -import org.baeldung.config.Application; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringRunner; - -@RunWith(SpringRunner.class) -@SpringBootTest(classes = Application.class) -public class SpringContextTest { - - @Test - public void whenSpringContextIsBootstrapped_thenNoExceptions() { - } -} diff --git a/spring-security-client/spring-security-mvc/pom.xml b/spring-security-client/spring-security-mvc/pom.xml deleted file mode 100644 index 75298026a8..0000000000 --- a/spring-security-client/spring-security-mvc/pom.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - 4.0.0 - com.baeldung - spring-security-mvc - 0.0.1-SNAPSHOT - spring-security-mvc - Spring Security MVC - war - - - parent-boot-1 - com.baeldung - 0.0.1-SNAPSHOT - ../../parent-boot-1 - - - - - org.springframework.boot - spring-boot-starter-security - - - org.springframework.boot - spring-boot-starter-web - - - - diff --git a/spring-security-client/spring-security-mvc/src/main/java/org/baeldung/config/Application.java b/spring-security-client/spring-security-mvc/src/main/java/org/baeldung/config/Application.java deleted file mode 100644 index 34c43fbe5a..0000000000 --- a/spring-security-client/spring-security-mvc/src/main/java/org/baeldung/config/Application.java +++ /dev/null @@ -1,20 +0,0 @@ -package org.baeldung.config; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.boot.web.support.SpringBootServletInitializer; - -@SpringBootApplication -public class Application extends SpringBootServletInitializer { - - @Override - protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { - return application.sources(Application.class); - } - - public static void main(String[] args) { - SpringApplication.run(Application.class, args); - } - -} diff --git a/spring-security-client/spring-security-mvc/src/main/java/org/baeldung/config/SecurityConfig.java b/spring-security-client/spring-security-mvc/src/main/java/org/baeldung/config/SecurityConfig.java deleted file mode 100644 index bd6c56d38a..0000000000 --- a/spring-security-client/spring-security-mvc/src/main/java/org/baeldung/config/SecurityConfig.java +++ /dev/null @@ -1,40 +0,0 @@ -package org.baeldung.config; - -import org.springframework.context.annotation.Configuration; -import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.builders.WebSecurity; -import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; - -@Configuration -@EnableWebSecurity -public class SecurityConfig extends WebSecurityConfigurerAdapter { - - @Override - protected void configure(final AuthenticationManagerBuilder auth) throws Exception { - // @formatter:off - auth.inMemoryAuthentication() - .withUser("john").password("123").roles("USER") - .and() - .withUser("tom").password("111").roles("ADMIN"); - // @formatter:on - } - - @Override - public void configure(WebSecurity web) throws Exception { - web.ignoring().antMatchers("/resources/**"); - } - - @Override - protected void configure(final HttpSecurity http) throws Exception { - // @formatter:off - http.authorizeRequests() - .antMatchers("/login").permitAll() - .antMatchers("/admin").hasRole("ADMIN") - .anyRequest().authenticated() - .and().formLogin().permitAll() - ; - // @formatter:on - } -} \ No newline at end of file diff --git a/spring-security-client/spring-security-mvc/src/main/resources/application.properties b/spring-security-client/spring-security-mvc/src/main/resources/application.properties deleted file mode 100644 index c2eee0d931..0000000000 --- a/spring-security-client/spring-security-mvc/src/main/resources/application.properties +++ /dev/null @@ -1 +0,0 @@ -server.port: 8081 \ No newline at end of file diff --git a/spring-security-client/spring-security-mvc/src/main/resources/logback.xml b/spring-security-client/spring-security-mvc/src/main/resources/logback.xml deleted file mode 100644 index 7d900d8ea8..0000000000 --- a/spring-security-client/spring-security-mvc/src/main/resources/logback.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n - - - - - - - - \ No newline at end of file diff --git a/spring-security-client/spring-security-mvc/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-security-client/spring-security-mvc/src/test/java/org/baeldung/SpringContextIntegrationTest.java deleted file mode 100644 index 66243ef00d..0000000000 --- a/spring-security-client/spring-security-mvc/src/test/java/org/baeldung/SpringContextIntegrationTest.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.baeldung; - -import org.baeldung.config.Application; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringRunner; - -@RunWith(SpringRunner.class) -@SpringBootTest(classes = Application.class) -public class SpringContextIntegrationTest { - - @Test - public void whenSpringContextIsBootstrapped_thenNoExceptions() { - } -} diff --git a/spring-security-client/spring-security-mvc/src/test/java/org/baeldung/SpringContextTest.java b/spring-security-client/spring-security-mvc/src/test/java/org/baeldung/SpringContextTest.java deleted file mode 100644 index 0afb3899db..0000000000 --- a/spring-security-client/spring-security-mvc/src/test/java/org/baeldung/SpringContextTest.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.baeldung; - -import org.baeldung.config.Application; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringRunner; - -@RunWith(SpringRunner.class) -@SpringBootTest(classes = Application.class) -public class SpringContextTest { - - @Test - public void whenSpringContextIsBootstrapped_thenNoExceptions() { - } -} diff --git a/spring-security-client/spring-security-thymeleaf-authentication/pom.xml b/spring-security-client/spring-security-thymeleaf-authentication/pom.xml deleted file mode 100644 index 01d2c6bdbe..0000000000 --- a/spring-security-client/spring-security-thymeleaf-authentication/pom.xml +++ /dev/null @@ -1,43 +0,0 @@ - - - 4.0.0 - - com.baeldung - spring-security-thymeleaf-authentication - 0.0.1-SNAPSHOT - spring-security-thymeleaf-authentication - Spring Security thymeleaf authentication tag sample - war - - - parent-boot-1 - com.baeldung - 0.0.1-SNAPSHOT - ../../parent-boot-1 - - - - - org.springframework.boot - spring-boot-starter-security - - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.boot - spring-boot-starter-tomcat - - - org.springframework.boot - spring-boot-starter-thymeleaf - - - org.thymeleaf.extras - thymeleaf-extras-springsecurity4 - - - - diff --git a/spring-security-client/spring-security-thymeleaf-authentication/src/main/java/org/baeldung/config/MvcConfig.java b/spring-security-client/spring-security-thymeleaf-authentication/src/main/java/org/baeldung/config/MvcConfig.java deleted file mode 100644 index 259433f6ae..0000000000 --- a/spring-security-client/spring-security-thymeleaf-authentication/src/main/java/org/baeldung/config/MvcConfig.java +++ /dev/null @@ -1,44 +0,0 @@ -package org.baeldung.config; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; -import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer; -import org.springframework.web.servlet.config.annotation.EnableWebMvc; -import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; -import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; -import org.springframework.context.annotation.Profile; - -@Configuration -@EnableWebMvc -@Profile("!manual") -public class MvcConfig extends WebMvcConfigurerAdapter { - - public MvcConfig() { - super(); - } - - // - @Bean - public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() { - return new PropertySourcesPlaceholderConfigurer(); - } - - @Override - public void configureDefaultServletHandling(final DefaultServletHandlerConfigurer configurer) { - configurer.enable(); - } - - @Override - public void addViewControllers(final ViewControllerRegistry registry) { - super.addViewControllers(registry); - registry.addViewController("/").setViewName("forward:/index"); - registry.addViewController("/index"); - } - - @Override - public void addResourceHandlers(final ResourceHandlerRegistry registry) { - registry.addResourceHandler("/resources/**").addResourceLocations("/resources/"); - } -} \ No newline at end of file diff --git a/spring-security-client/spring-security-thymeleaf-authentication/src/main/java/org/baeldung/config/MvcConfigManual.java b/spring-security-client/spring-security-thymeleaf-authentication/src/main/java/org/baeldung/config/MvcConfigManual.java deleted file mode 100644 index d80527c30a..0000000000 --- a/spring-security-client/spring-security-thymeleaf-authentication/src/main/java/org/baeldung/config/MvcConfigManual.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.baeldung.config; - -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Profile; -import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; -import org.springframework.web.servlet.config.annotation.EnableWebMvc; - -@Configuration -@EnableWebMvc -@Profile("manual") -public class MvcConfigManual extends WebMvcConfigurerAdapter { - - @Override - public void addViewControllers(ViewControllerRegistry registry) { - registry.addViewController("/home").setViewName("home"); - registry.addViewController("/").setViewName("home"); - registry.addViewController("/hello").setViewName("hello"); - registry.addViewController("/login").setViewName("login"); - } - -} diff --git a/spring-security-client/spring-security-thymeleaf-authentication/src/main/java/org/baeldung/config/RegistrationController.java b/spring-security-client/spring-security-thymeleaf-authentication/src/main/java/org/baeldung/config/RegistrationController.java deleted file mode 100644 index 2414ff9cac..0000000000 --- a/spring-security-client/spring-security-thymeleaf-authentication/src/main/java/org/baeldung/config/RegistrationController.java +++ /dev/null @@ -1,89 +0,0 @@ -package org.baeldung.config; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Profile; -import org.springframework.security.authentication.AbstractAuthenticationToken; -import org.springframework.security.authentication.AuthenticationManager; -import org.springframework.security.authentication.BadCredentialsException; -import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.security.web.authentication.WebAuthenticationDetails; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.GetMapping; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -/** - * Manually authenticate a user using Spring Security / Spring Web MVC' (upon successful account registration) - * (http://stackoverflow.com/questions/4664893/how-to-manually-set-an-authenticated-user-in-spring-security-springmvc) - * - * @author jim clayson - */ -@Controller -@Profile("manual") -public class RegistrationController { - private static final Logger logger = LoggerFactory.getLogger(RegistrationController.class); - - @Autowired - private AuthenticationManager authenticationManager; - - /** - * For demo purposes this need only be a GET request method - * - * @param request - * @param response - * @return The view. Page confirming either successful registration (and/or - * successful authentication) or failed registration. - */ - @GetMapping("/register") - public String registerAndAuthenticate(HttpServletRequest request, HttpServletResponse response) { - logger.debug("registerAndAuthenticate: attempt to register, application should manually authenticate."); - - // Mocked values. Potentially could come from an HTML registration form, - // in which case this mapping would match on an HTTP POST, rather than a GET - String username = "user"; - String password = "password"; - - if (requestQualifiesForManualAuthentication()) { - try { - authenticate(username, password, request, response); - logger.debug("registerAndAuthenticate: authentication completed."); - } catch (BadCredentialsException bce) { - logger.debug("Authentication failure: bad credentials"); - bce.printStackTrace(); - return "systemError"; // assume a low-level error, since the registration - // form would have been successfully validated - } - } - - return "registrationSuccess"; - } - - private boolean requestQualifiesForManualAuthentication() { - // Some processing to determine that the user requires a Spring Security-recognized, - // application-directed login e.g. successful account registration. - return true; - } - - private void authenticate(String username, String password, HttpServletRequest request, HttpServletResponse response) throws BadCredentialsException { - logger.debug("attempting to authenticated, manually ... "); - - // create and populate the token - AbstractAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(username, password); - authToken.setDetails(new WebAuthenticationDetails(request)); - - // This call returns an authentication object, which holds principle and user credentials - Authentication authentication = this.authenticationManager.authenticate(authToken); - - // The security context holds the authentication object, and is stored - // in thread local scope. - SecurityContextHolder.getContext().setAuthentication(authentication); - - logger.debug("User should now be authenticated."); - } - -} \ No newline at end of file diff --git a/spring-security-client/spring-security-thymeleaf-authentication/src/main/java/org/baeldung/config/SecurityConfig.java b/spring-security-client/spring-security-thymeleaf-authentication/src/main/java/org/baeldung/config/SecurityConfig.java deleted file mode 100644 index 153cc67661..0000000000 --- a/spring-security-client/spring-security-thymeleaf-authentication/src/main/java/org/baeldung/config/SecurityConfig.java +++ /dev/null @@ -1,42 +0,0 @@ -package org.baeldung.config; - -import org.springframework.context.annotation.Configuration; -import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.builders.WebSecurity; -import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; -import org.springframework.context.annotation.Profile; - -@Configuration -@EnableWebSecurity -@Profile("!manual") -public class SecurityConfig extends WebSecurityConfigurerAdapter { - - @Override - protected void configure(final AuthenticationManagerBuilder auth) throws Exception { - // @formatter:off - auth.inMemoryAuthentication() - .withUser("john").password("123").roles("USER") - .and() - .withUser("tom").password("111").roles("ADMIN"); - // @formatter:on - } - - @Override - public void configure(WebSecurity web) throws Exception { - web.ignoring().antMatchers("/resources/**"); - } - - @Override - protected void configure(final HttpSecurity http) throws Exception { - // @formatter:off - http.authorizeRequests() - .antMatchers("/login").permitAll() - .antMatchers("/admin").hasRole("ADMIN") - .anyRequest().authenticated() - .and().formLogin().permitAll() - ; - // @formatter:on - } -} \ No newline at end of file diff --git a/spring-security-client/spring-security-thymeleaf-authentication/src/main/java/org/baeldung/config/WebSecurityConfigManual.java b/spring-security-client/spring-security-thymeleaf-authentication/src/main/java/org/baeldung/config/WebSecurityConfigManual.java deleted file mode 100644 index 180a53deba..0000000000 --- a/spring-security-client/spring-security-thymeleaf-authentication/src/main/java/org/baeldung/config/WebSecurityConfigManual.java +++ /dev/null @@ -1,35 +0,0 @@ -package org.baeldung.config; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Profile; -import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; - -@Configuration -@EnableWebSecurity -@Profile("manual") -public class WebSecurityConfigManual extends WebSecurityConfigurerAdapter { - - @Override - protected void configure(HttpSecurity http) throws Exception { - // @formatter:off - http - .authorizeRequests() - .antMatchers("/", "/home", "/register").permitAll() - .anyRequest().authenticated() - .and() - .formLogin() - .loginPage("/login").permitAll() - .and() - .logout().permitAll(); - // @formatter:on - } - - @Autowired - public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { - auth.inMemoryAuthentication().withUser("user").password("password").roles("USER"); - } -} diff --git a/spring-security-client/spring-security-thymeleaf-authentication/src/main/resources/application.properties b/spring-security-client/spring-security-thymeleaf-authentication/src/main/resources/application.properties deleted file mode 100644 index bafddced85..0000000000 --- a/spring-security-client/spring-security-thymeleaf-authentication/src/main/resources/application.properties +++ /dev/null @@ -1 +0,0 @@ -server.port=8081 \ No newline at end of file diff --git a/spring-security-client/spring-security-thymeleaf-authentication/src/main/resources/logback.xml b/spring-security-client/spring-security-thymeleaf-authentication/src/main/resources/logback.xml deleted file mode 100644 index 7d900d8ea8..0000000000 --- a/spring-security-client/spring-security-thymeleaf-authentication/src/main/resources/logback.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n - - - - - - - - \ No newline at end of file diff --git a/spring-security-client/spring-security-thymeleaf-authentication/src/main/resources/templates/hello.html b/spring-security-client/spring-security-thymeleaf-authentication/src/main/resources/templates/hello.html deleted file mode 100644 index b37731b0ed..0000000000 --- a/spring-security-client/spring-security-thymeleaf-authentication/src/main/resources/templates/hello.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - Hello World! - - -

    Hello [[${#httpServletRequest.remoteUser}]]!

    -
    - -
    -

    Click here to go to the home page.

    - - - \ No newline at end of file diff --git a/spring-security-client/spring-security-thymeleaf-authentication/src/main/resources/templates/home.html b/spring-security-client/spring-security-thymeleaf-authentication/src/main/resources/templates/home.html deleted file mode 100644 index 6dbdf491c6..0000000000 --- a/spring-security-client/spring-security-thymeleaf-authentication/src/main/resources/templates/home.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - Spring Security Example - - -

    Welcome!

    - -

    Click here to see a greeting.

    -

    Click here to send a dummy registration request, where the application logs you in.

    - - \ No newline at end of file diff --git a/spring-security-client/spring-security-thymeleaf-authentication/src/main/resources/templates/index.html b/spring-security-client/spring-security-thymeleaf-authentication/src/main/resources/templates/index.html deleted file mode 100644 index c65b5f092b..0000000000 --- a/spring-security-client/spring-security-thymeleaf-authentication/src/main/resources/templates/index.html +++ /dev/null @@ -1,23 +0,0 @@ - - - - -Spring Security Thymeleaf - - - - - -
    - Current user name: Bob -
    - Current user roles: [ROLE_USER, ROLE_ADMIN] -
    - - \ No newline at end of file diff --git a/spring-security-client/spring-security-thymeleaf-authentication/src/main/resources/templates/login.html b/spring-security-client/spring-security-thymeleaf-authentication/src/main/resources/templates/login.html deleted file mode 100644 index 3f28efac69..0000000000 --- a/spring-security-client/spring-security-thymeleaf-authentication/src/main/resources/templates/login.html +++ /dev/null @@ -1,21 +0,0 @@ - - - - Spring Security Example - - -
    - Invalid username and password. -
    -
    - You have been logged out. -
    -
    -
    -
    -
    -
    -

    Click here to go to the home page.

    - - \ No newline at end of file diff --git a/spring-security-client/spring-security-thymeleaf-authentication/src/main/resources/templates/registrationError.html b/spring-security-client/spring-security-thymeleaf-authentication/src/main/resources/templates/registrationError.html deleted file mode 100644 index 756cc2390d..0000000000 --- a/spring-security-client/spring-security-thymeleaf-authentication/src/main/resources/templates/registrationError.html +++ /dev/null @@ -1 +0,0 @@ -Registration could not be completed at this time. Please try again later or contact support! \ No newline at end of file diff --git a/spring-security-client/spring-security-thymeleaf-authentication/src/main/resources/templates/registrationSuccess.html b/spring-security-client/spring-security-thymeleaf-authentication/src/main/resources/templates/registrationSuccess.html deleted file mode 100644 index b1c4336f2f..0000000000 --- a/spring-security-client/spring-security-thymeleaf-authentication/src/main/resources/templates/registrationSuccess.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - Registration Success! - - -

    Registration succeeded. You have been logged in by the system. Welcome [[${#httpServletRequest.remoteUser}]]!

    -
    - -
    -

    Click here to go to the home page.

    - - - \ No newline at end of file diff --git a/spring-security-client/spring-security-thymeleaf-authentication/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-security-client/spring-security-thymeleaf-authentication/src/test/java/org/baeldung/SpringContextIntegrationTest.java deleted file mode 100644 index 66243ef00d..0000000000 --- a/spring-security-client/spring-security-thymeleaf-authentication/src/test/java/org/baeldung/SpringContextIntegrationTest.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.baeldung; - -import org.baeldung.config.Application; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringRunner; - -@RunWith(SpringRunner.class) -@SpringBootTest(classes = Application.class) -public class SpringContextIntegrationTest { - - @Test - public void whenSpringContextIsBootstrapped_thenNoExceptions() { - } -} diff --git a/spring-security-client/spring-security-thymeleaf-authentication/src/test/java/org/baeldung/SpringContextTest.java b/spring-security-client/spring-security-thymeleaf-authentication/src/test/java/org/baeldung/SpringContextTest.java deleted file mode 100644 index 0afb3899db..0000000000 --- a/spring-security-client/spring-security-thymeleaf-authentication/src/test/java/org/baeldung/SpringContextTest.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.baeldung; - -import org.baeldung.config.Application; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringRunner; - -@RunWith(SpringRunner.class) -@SpringBootTest(classes = Application.class) -public class SpringContextTest { - - @Test - public void whenSpringContextIsBootstrapped_thenNoExceptions() { - } -} diff --git a/spring-security-client/spring-security-thymeleaf-authorize/pom.xml b/spring-security-client/spring-security-thymeleaf-authorize/pom.xml deleted file mode 100644 index 8c600c1f81..0000000000 --- a/spring-security-client/spring-security-thymeleaf-authorize/pom.xml +++ /dev/null @@ -1,43 +0,0 @@ - - - 4.0.0 - - com.baeldung - spring-security-thymeleaf-authorize - 0.0.1-SNAPSHOT - spring-security-thymeleaf-authorize - Spring Security thymeleaf authorize tag sample - war - - - parent-boot-1 - com.baeldung - 0.0.1-SNAPSHOT - ../../parent-boot-1 - - - - - org.springframework.boot - spring-boot-starter-security - - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.boot - spring-boot-starter-tomcat - - - org.springframework.boot - spring-boot-starter-thymeleaf - - - org.thymeleaf.extras - thymeleaf-extras-springsecurity4 - - - - diff --git a/spring-security-client/spring-security-thymeleaf-authorize/src/main/java/org/baeldung/config/Application.java b/spring-security-client/spring-security-thymeleaf-authorize/src/main/java/org/baeldung/config/Application.java deleted file mode 100644 index 329b104143..0000000000 --- a/spring-security-client/spring-security-thymeleaf-authorize/src/main/java/org/baeldung/config/Application.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.baeldung.config; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.web.support.SpringBootServletInitializer; - -@SpringBootApplication -public class Application extends SpringBootServletInitializer { - - public static void main(String[] args) { - SpringApplication.run(Application.class, args); - } - -} diff --git a/spring-security-client/spring-security-thymeleaf-authorize/src/main/java/org/baeldung/config/MvcConfig.java b/spring-security-client/spring-security-thymeleaf-authorize/src/main/java/org/baeldung/config/MvcConfig.java deleted file mode 100644 index 9ade60e54c..0000000000 --- a/spring-security-client/spring-security-thymeleaf-authorize/src/main/java/org/baeldung/config/MvcConfig.java +++ /dev/null @@ -1,42 +0,0 @@ -package org.baeldung.config; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; -import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer; -import org.springframework.web.servlet.config.annotation.EnableWebMvc; -import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; -import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; - -@Configuration -@EnableWebMvc -public class MvcConfig extends WebMvcConfigurerAdapter { - - public MvcConfig() { - super(); - } - - // - @Bean - public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() { - return new PropertySourcesPlaceholderConfigurer(); - } - - @Override - public void configureDefaultServletHandling(final DefaultServletHandlerConfigurer configurer) { - configurer.enable(); - } - - @Override - public void addViewControllers(final ViewControllerRegistry registry) { - super.addViewControllers(registry); - registry.addViewController("/").setViewName("forward:/index"); - registry.addViewController("/index"); - } - - @Override - public void addResourceHandlers(final ResourceHandlerRegistry registry) { - registry.addResourceHandler("/resources/**").addResourceLocations("/resources/"); - } -} \ No newline at end of file diff --git a/spring-security-client/spring-security-thymeleaf-authorize/src/main/java/org/baeldung/config/SecurityConfig.java b/spring-security-client/spring-security-thymeleaf-authorize/src/main/java/org/baeldung/config/SecurityConfig.java deleted file mode 100644 index bd6c56d38a..0000000000 --- a/spring-security-client/spring-security-thymeleaf-authorize/src/main/java/org/baeldung/config/SecurityConfig.java +++ /dev/null @@ -1,40 +0,0 @@ -package org.baeldung.config; - -import org.springframework.context.annotation.Configuration; -import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.builders.WebSecurity; -import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; - -@Configuration -@EnableWebSecurity -public class SecurityConfig extends WebSecurityConfigurerAdapter { - - @Override - protected void configure(final AuthenticationManagerBuilder auth) throws Exception { - // @formatter:off - auth.inMemoryAuthentication() - .withUser("john").password("123").roles("USER") - .and() - .withUser("tom").password("111").roles("ADMIN"); - // @formatter:on - } - - @Override - public void configure(WebSecurity web) throws Exception { - web.ignoring().antMatchers("/resources/**"); - } - - @Override - protected void configure(final HttpSecurity http) throws Exception { - // @formatter:off - http.authorizeRequests() - .antMatchers("/login").permitAll() - .antMatchers("/admin").hasRole("ADMIN") - .anyRequest().authenticated() - .and().formLogin().permitAll() - ; - // @formatter:on - } -} \ No newline at end of file diff --git a/spring-security-client/spring-security-thymeleaf-authorize/src/main/resources/application.properties b/spring-security-client/spring-security-thymeleaf-authorize/src/main/resources/application.properties deleted file mode 100644 index bafddced85..0000000000 --- a/spring-security-client/spring-security-thymeleaf-authorize/src/main/resources/application.properties +++ /dev/null @@ -1 +0,0 @@ -server.port=8081 \ No newline at end of file diff --git a/spring-security-client/spring-security-thymeleaf-authorize/src/main/resources/logback.xml b/spring-security-client/spring-security-thymeleaf-authorize/src/main/resources/logback.xml deleted file mode 100644 index 7d900d8ea8..0000000000 --- a/spring-security-client/spring-security-thymeleaf-authorize/src/main/resources/logback.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n - - - - - - - - \ No newline at end of file diff --git a/spring-security-client/spring-security-thymeleaf-authorize/src/main/resources/templates/index.html b/spring-security-client/spring-security-thymeleaf-authorize/src/main/resources/templates/index.html deleted file mode 100644 index fcbbfb4957..0000000000 --- a/spring-security-client/spring-security-thymeleaf-authorize/src/main/resources/templates/index.html +++ /dev/null @@ -1,32 +0,0 @@ - - - - -Spring Security Thymeleaf - - - - - -
    -
    - Only admins can see this message -
    - -
    - Only users can see this message -
    -
    - -
    - Only users who can call "/admin" URL can see this message -
    -
    - - \ No newline at end of file diff --git a/spring-security-client/spring-security-thymeleaf-authorize/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-security-client/spring-security-thymeleaf-authorize/src/test/java/org/baeldung/SpringContextIntegrationTest.java deleted file mode 100644 index 66243ef00d..0000000000 --- a/spring-security-client/spring-security-thymeleaf-authorize/src/test/java/org/baeldung/SpringContextIntegrationTest.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.baeldung; - -import org.baeldung.config.Application; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringRunner; - -@RunWith(SpringRunner.class) -@SpringBootTest(classes = Application.class) -public class SpringContextIntegrationTest { - - @Test - public void whenSpringContextIsBootstrapped_thenNoExceptions() { - } -} diff --git a/spring-security-client/spring-security-thymeleaf-authorize/src/test/java/org/baeldung/SpringContextTest.java b/spring-security-client/spring-security-thymeleaf-authorize/src/test/java/org/baeldung/SpringContextTest.java deleted file mode 100644 index 0afb3899db..0000000000 --- a/spring-security-client/spring-security-thymeleaf-authorize/src/test/java/org/baeldung/SpringContextTest.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.baeldung; - -import org.baeldung.config.Application; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringRunner; - -@RunWith(SpringRunner.class) -@SpringBootTest(classes = Application.class) -public class SpringContextTest { - - @Test - public void whenSpringContextIsBootstrapped_thenNoExceptions() { - } -} diff --git a/spring-security-client/spring-security-thymeleaf-config/pom.xml b/spring-security-client/spring-security-thymeleaf-config/pom.xml deleted file mode 100644 index aeda999405..0000000000 --- a/spring-security-client/spring-security-thymeleaf-config/pom.xml +++ /dev/null @@ -1,42 +0,0 @@ - - - 4.0.0 - com.baeldung - spring-security-thymeleaf-config - 0.0.1-SNAPSHOT - spring-security-thymeleaf-config - Spring Security thymeleaf configuration sample project - war - - - parent-boot-1 - com.baeldung - 0.0.1-SNAPSHOT - ../../parent-boot-1 - - - - - org.springframework.boot - spring-boot-starter-security - - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.boot - spring-boot-starter-tomcat - - - org.springframework.boot - spring-boot-starter-thymeleaf - - - org.thymeleaf.extras - thymeleaf-extras-springsecurity4 - - - - diff --git a/spring-security-client/spring-security-thymeleaf-config/src/main/java/org/baeldung/config/MvcConfig.java b/spring-security-client/spring-security-thymeleaf-config/src/main/java/org/baeldung/config/MvcConfig.java deleted file mode 100644 index 9ade60e54c..0000000000 --- a/spring-security-client/spring-security-thymeleaf-config/src/main/java/org/baeldung/config/MvcConfig.java +++ /dev/null @@ -1,42 +0,0 @@ -package org.baeldung.config; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; -import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer; -import org.springframework.web.servlet.config.annotation.EnableWebMvc; -import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; -import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; - -@Configuration -@EnableWebMvc -public class MvcConfig extends WebMvcConfigurerAdapter { - - public MvcConfig() { - super(); - } - - // - @Bean - public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() { - return new PropertySourcesPlaceholderConfigurer(); - } - - @Override - public void configureDefaultServletHandling(final DefaultServletHandlerConfigurer configurer) { - configurer.enable(); - } - - @Override - public void addViewControllers(final ViewControllerRegistry registry) { - super.addViewControllers(registry); - registry.addViewController("/").setViewName("forward:/index"); - registry.addViewController("/index"); - } - - @Override - public void addResourceHandlers(final ResourceHandlerRegistry registry) { - registry.addResourceHandler("/resources/**").addResourceLocations("/resources/"); - } -} \ No newline at end of file diff --git a/spring-security-client/spring-security-thymeleaf-config/src/main/java/org/baeldung/config/SecurityConfig.java b/spring-security-client/spring-security-thymeleaf-config/src/main/java/org/baeldung/config/SecurityConfig.java deleted file mode 100644 index bd6c56d38a..0000000000 --- a/spring-security-client/spring-security-thymeleaf-config/src/main/java/org/baeldung/config/SecurityConfig.java +++ /dev/null @@ -1,40 +0,0 @@ -package org.baeldung.config; - -import org.springframework.context.annotation.Configuration; -import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.builders.WebSecurity; -import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; - -@Configuration -@EnableWebSecurity -public class SecurityConfig extends WebSecurityConfigurerAdapter { - - @Override - protected void configure(final AuthenticationManagerBuilder auth) throws Exception { - // @formatter:off - auth.inMemoryAuthentication() - .withUser("john").password("123").roles("USER") - .and() - .withUser("tom").password("111").roles("ADMIN"); - // @formatter:on - } - - @Override - public void configure(WebSecurity web) throws Exception { - web.ignoring().antMatchers("/resources/**"); - } - - @Override - protected void configure(final HttpSecurity http) throws Exception { - // @formatter:off - http.authorizeRequests() - .antMatchers("/login").permitAll() - .antMatchers("/admin").hasRole("ADMIN") - .anyRequest().authenticated() - .and().formLogin().permitAll() - ; - // @formatter:on - } -} \ No newline at end of file diff --git a/spring-security-client/spring-security-thymeleaf-config/src/main/resources/application.properties b/spring-security-client/spring-security-thymeleaf-config/src/main/resources/application.properties deleted file mode 100644 index bafddced85..0000000000 --- a/spring-security-client/spring-security-thymeleaf-config/src/main/resources/application.properties +++ /dev/null @@ -1 +0,0 @@ -server.port=8081 \ No newline at end of file diff --git a/spring-security-client/spring-security-thymeleaf-config/src/main/resources/logback.xml b/spring-security-client/spring-security-thymeleaf-config/src/main/resources/logback.xml deleted file mode 100644 index 7d900d8ea8..0000000000 --- a/spring-security-client/spring-security-thymeleaf-config/src/main/resources/logback.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n - - - - - - - - \ No newline at end of file diff --git a/spring-security-client/spring-security-thymeleaf-config/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-security-client/spring-security-thymeleaf-config/src/test/java/org/baeldung/SpringContextIntegrationTest.java deleted file mode 100644 index 66243ef00d..0000000000 --- a/spring-security-client/spring-security-thymeleaf-config/src/test/java/org/baeldung/SpringContextIntegrationTest.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.baeldung; - -import org.baeldung.config.Application; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringRunner; - -@RunWith(SpringRunner.class) -@SpringBootTest(classes = Application.class) -public class SpringContextIntegrationTest { - - @Test - public void whenSpringContextIsBootstrapped_thenNoExceptions() { - } -} diff --git a/spring-security-client/spring-security-thymeleaf-config/src/test/java/org/baeldung/SpringContextTest.java b/spring-security-client/spring-security-thymeleaf-config/src/test/java/org/baeldung/SpringContextTest.java deleted file mode 100644 index 0afb3899db..0000000000 --- a/spring-security-client/spring-security-thymeleaf-config/src/test/java/org/baeldung/SpringContextTest.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.baeldung; - -import org.baeldung.config.Application; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringRunner; - -@RunWith(SpringRunner.class) -@SpringBootTest(classes = Application.class) -public class SpringContextTest { - - @Test - public void whenSpringContextIsBootstrapped_thenNoExceptions() { - } -} diff --git a/spring-security-core/README.md b/spring-security-core/README.md index b38dc061b4..bc9a8afed7 100644 --- a/spring-security-core/README.md +++ b/spring-security-core/README.md @@ -10,3 +10,4 @@ mvn clean install - [Spring Security – @PreFilter and @PostFilter](http://www.baeldung.com/spring-security-prefilter-postfilter) - [Spring Boot Authentication Auditing Support](http://www.baeldung.com/spring-boot-authentication-audit) - [Introduction to Spring Method Security](http://www.baeldung.com/spring-security-method-security) +- [Overview and Need for DelegatingFilterProxy in Spring](https://www.baeldung.com/spring-delegating-filter-proxy) \ No newline at end of file diff --git a/spring-security-core/pom.xml b/spring-security-core/pom.xml index 41dea087d3..b144357e25 100644 --- a/spring-security-core/pom.xml +++ b/spring-security-core/pom.xml @@ -9,10 +9,10 @@ war - parent-boot-1 + parent-boot-2 com.baeldung 0.0.1-SNAPSHOT - ../parent-boot-1 + ../parent-boot-2 @@ -36,6 +36,10 @@ org.springframework.boot spring-boot-starter-actuator + + org.springframework.boot + spring-boot-starter-web + com.h2database h2 diff --git a/spring-security-core/src/main/java/org/baeldung/app/App.java b/spring-security-core/src/main/java/org/baeldung/app/App.java index 37d8c34c5a..bf719b3b12 100644 --- a/spring-security-core/src/main/java/org/baeldung/app/App.java +++ b/spring-security-core/src/main/java/org/baeldung/app/App.java @@ -1,11 +1,15 @@ package org.baeldung.app; +import javax.servlet.Filter; + import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.domain.EntityScan; -import org.springframework.boot.web.support.SpringBootServletInitializer; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; import org.springframework.context.annotation.ComponentScan; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.web.filter.DelegatingFilterProxy; +import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer; @SpringBootApplication @EnableJpaRepositories("org.baeldung.repository") @@ -15,4 +19,32 @@ public class App extends SpringBootServletInitializer { public static void main(String[] args) { SpringApplication.run(App.class, args); } + + public static class ApplicationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { + + @Override + protected javax.servlet.Filter[] getServletFilters() { + DelegatingFilterProxy delegateFilterProxy = new DelegatingFilterProxy(); + delegateFilterProxy.setTargetBeanName("loggingFilter"); + return new Filter[] { delegateFilterProxy }; + } + + @Override + protected Class[] getRootConfigClasses() { + // TODO Auto-generated method stub + return null; + } + + @Override + protected Class[] getServletConfigClasses() { + // TODO Auto-generated method stub + return null; + } + + @Override + protected String[] getServletMappings() { + // TODO Auto-generated method stub + return null; + } + } } diff --git a/spring-security-core/src/main/java/org/baeldung/config/WebSecurityConfig.java b/spring-security-core/src/main/java/org/baeldung/config/WebSecurityConfig.java index 0b6cd34f3e..df7c7d1611 100644 --- a/spring-security-core/src/main/java/org/baeldung/config/WebSecurityConfig.java +++ b/spring-security-core/src/main/java/org/baeldung/config/WebSecurityConfig.java @@ -1,12 +1,15 @@ package org.baeldung.config; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; @Configuration @EnableWebSecurity @@ -21,8 +24,13 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication() - .withUser("jim").password("jim").roles("USER", "ACTUATOR") - .and().withUser("pam").password("pam").roles("USER") - .and().withUser("michael").password("michael").roles("MANAGER"); + .withUser("jim").password(passwordEncoder().encode("jim")).roles("USER", "ACTUATOR") + .and().withUser("pam").password(passwordEncoder().encode("pam")).roles("USER") + .and().withUser("michael").password(passwordEncoder().encode("michael")).roles("MANAGER"); + } + + @Bean + public PasswordEncoder passwordEncoder() { + return new BCryptPasswordEncoder(); } } diff --git a/spring-5-mvc/src/main/java/com/baeldung/spring/filter/CustomFilter.java b/spring-security-core/src/main/java/org/baeldung/filter/CustomFilter.java similarity index 96% rename from spring-5-mvc/src/main/java/com/baeldung/spring/filter/CustomFilter.java rename to spring-security-core/src/main/java/org/baeldung/filter/CustomFilter.java index 4aa33cd749..35596eae16 100644 --- a/spring-5-mvc/src/main/java/com/baeldung/spring/filter/CustomFilter.java +++ b/spring-security-core/src/main/java/org/baeldung/filter/CustomFilter.java @@ -1,4 +1,4 @@ -package com.baeldung.spring.filter; +package org.baeldung.filter; import java.io.IOException; diff --git a/spring-security-core/src/main/java/org/baeldung/service/TaskService.java b/spring-security-core/src/main/java/org/baeldung/service/TaskService.java index 4a0dae3aac..4efa3b0294 100644 --- a/spring-security-core/src/main/java/org/baeldung/service/TaskService.java +++ b/spring-security-core/src/main/java/org/baeldung/service/TaskService.java @@ -20,7 +20,7 @@ public class TaskService { @PreFilter("hasRole('MANAGER') or filterObject.assignee == authentication.name") public Iterable save(Iterable entities) { - return taskRepository.save(entities); + return taskRepository.saveAll(entities); } } diff --git a/spring-security-core/src/main/resources/application.properties b/spring-security-core/src/main/resources/application.properties new file mode 100644 index 0000000000..709574239b --- /dev/null +++ b/spring-security-core/src/main/resources/application.properties @@ -0,0 +1 @@ +spring.main.allow-bean-definition-overriding=true \ No newline at end of file diff --git a/spring-security-core/src/main/webapp/WEB-INF/web.xml b/spring-security-core/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000000..e4954338a9 --- /dev/null +++ b/spring-security-core/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,17 @@ + + + + + loggingFilter + org.springframework.web.filter.DelegatingFilterProxy + + + + loggingFilter + /* + + + \ No newline at end of file diff --git a/spring-security-cors/README.md b/spring-security-cors/README.md new file mode 100644 index 0000000000..2ab5e33ee3 --- /dev/null +++ b/spring-security-cors/README.md @@ -0,0 +1,3 @@ +## Relevant Articles + +- [Fixing 401s with CORS Preflights and Spring Security](https://www.baeldung.com/spring-security-cors-preflight) diff --git a/spring-security-mvc-boot/pom.xml b/spring-security-mvc-boot/pom.xml index 4c25dc01e8..906bebf442 100644 --- a/spring-security-mvc-boot/pom.xml +++ b/spring-security-mvc-boot/pom.xml @@ -1,12 +1,13 @@ - + 4.0.0 com.baeldung spring-security-mvc-boot 0.0.1-SNAPSHOT spring-security-mvc-boot - war + pom Spring Security MVC Boot @@ -45,10 +46,6 @@ org.springframework.security spring-security-data - - com.h2database - h2 - org.hamcrest hamcrest-core @@ -198,7 +195,7 @@ **/*LiveTest.java **/*IntegrationTest.java - **/*IntTest.java + **/*IntTest.java **/*EntryPointsTest.java @@ -217,22 +214,13 @@ + + spring-security-mvc-boot-default + spring-security-mvc-boot-mysql + spring-security-mvc-boot-postgre + - org.baeldung.custom.Application - - - - - - - - - 1.1.2 1.6.1 2.6.11 diff --git a/spring-security-mvc-boot/spring-security-mvc-boot-default/pom.xml b/spring-security-mvc-boot/spring-security-mvc-boot-default/pom.xml new file mode 100644 index 0000000000..8f7f18f093 --- /dev/null +++ b/spring-security-mvc-boot/spring-security-mvc-boot-default/pom.xml @@ -0,0 +1,42 @@ + + + 4.0.0 + com.baeldung + spring-security-mvc-boot-default + 0.0.1-SNAPSHOT + spring-security-mvc-boot-default + jar + Spring Security MVC Boot + + + spring-security-mvc-boot + com.baeldung + 0.0.1-SNAPSHOT + ../ + + + + + com.h2database + h2 + + + + + org.baeldung.custom.Application + + + + + + + + + + + diff --git a/spring-security-mvc-boot/src/main/java/com/baeldung/AppConfig.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/com/baeldung/AppConfig.java similarity index 100% rename from spring-security-mvc-boot/src/main/java/com/baeldung/AppConfig.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/com/baeldung/AppConfig.java diff --git a/spring-security-mvc-boot/src/main/java/com/baeldung/SpringSecurityConfig.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/com/baeldung/SpringSecurityConfig.java similarity index 100% rename from spring-security-mvc-boot/src/main/java/com/baeldung/SpringSecurityConfig.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/com/baeldung/SpringSecurityConfig.java diff --git a/spring-security-mvc-boot/src/main/java/com/baeldung/data/repositories/TweetRepository.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/com/baeldung/data/repositories/TweetRepository.java similarity index 100% rename from spring-security-mvc-boot/src/main/java/com/baeldung/data/repositories/TweetRepository.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/com/baeldung/data/repositories/TweetRepository.java diff --git a/spring-security-mvc-boot/src/main/java/com/baeldung/data/repositories/UserRepository.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/com/baeldung/data/repositories/UserRepository.java similarity index 100% rename from spring-security-mvc-boot/src/main/java/com/baeldung/data/repositories/UserRepository.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/com/baeldung/data/repositories/UserRepository.java diff --git a/spring-security-mvc-boot/src/main/java/com/baeldung/models/AppUser.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/com/baeldung/models/AppUser.java similarity index 100% rename from spring-security-mvc-boot/src/main/java/com/baeldung/models/AppUser.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/com/baeldung/models/AppUser.java diff --git a/spring-security-mvc-boot/src/main/java/com/baeldung/models/Tweet.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/com/baeldung/models/Tweet.java similarity index 100% rename from spring-security-mvc-boot/src/main/java/com/baeldung/models/Tweet.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/com/baeldung/models/Tweet.java diff --git a/spring-security-mvc-boot/src/main/java/com/baeldung/security/AppUserPrincipal.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/com/baeldung/security/AppUserPrincipal.java similarity index 100% rename from spring-security-mvc-boot/src/main/java/com/baeldung/security/AppUserPrincipal.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/com/baeldung/security/AppUserPrincipal.java diff --git a/spring-security-mvc-boot/src/main/java/com/baeldung/security/AuthenticationSuccessHandlerImpl.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/com/baeldung/security/AuthenticationSuccessHandlerImpl.java similarity index 100% rename from spring-security-mvc-boot/src/main/java/com/baeldung/security/AuthenticationSuccessHandlerImpl.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/com/baeldung/security/AuthenticationSuccessHandlerImpl.java diff --git a/spring-security-mvc-boot/src/main/java/com/baeldung/security/CustomUserDetailsService.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/com/baeldung/security/CustomUserDetailsService.java similarity index 100% rename from spring-security-mvc-boot/src/main/java/com/baeldung/security/CustomUserDetailsService.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/com/baeldung/security/CustomUserDetailsService.java diff --git a/spring-security-mvc-boot/src/main/java/com/baeldung/util/DummyContentUtil.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/com/baeldung/util/DummyContentUtil.java similarity index 100% rename from spring-security-mvc-boot/src/main/java/com/baeldung/util/DummyContentUtil.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/com/baeldung/util/DummyContentUtil.java diff --git a/spring-security-client/spring-security-thymeleaf-authentication/src/main/java/org/baeldung/config/Application.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/custom/Application.java similarity index 74% rename from spring-security-client/spring-security-thymeleaf-authentication/src/main/java/org/baeldung/config/Application.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/custom/Application.java index 329b104143..682d429963 100644 --- a/spring-security-client/spring-security-thymeleaf-authentication/src/main/java/org/baeldung/config/Application.java +++ b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/custom/Application.java @@ -1,14 +1,12 @@ -package org.baeldung.config; +package org.baeldung.custom; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.web.support.SpringBootServletInitializer; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; @SpringBootApplication public class Application extends SpringBootServletInitializer { - public static void main(String[] args) { SpringApplication.run(Application.class, args); } - } diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/custom/config/MethodSecurityConfig.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/custom/config/MethodSecurityConfig.java similarity index 100% rename from spring-security-mvc-boot/src/main/java/org/baeldung/custom/config/MethodSecurityConfig.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/custom/config/MethodSecurityConfig.java diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/custom/config/MvcConfig.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/custom/config/MvcConfig.java similarity index 100% rename from spring-security-mvc-boot/src/main/java/org/baeldung/custom/config/MvcConfig.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/custom/config/MvcConfig.java diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/custom/config/SecurityConfig.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/custom/config/SecurityConfig.java similarity index 100% rename from spring-security-mvc-boot/src/main/java/org/baeldung/custom/config/SecurityConfig.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/custom/config/SecurityConfig.java diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/custom/persistence/SetupData.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/custom/persistence/SetupData.java similarity index 100% rename from spring-security-mvc-boot/src/main/java/org/baeldung/custom/persistence/SetupData.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/custom/persistence/SetupData.java diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/custom/persistence/dao/OrganizationRepository.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/custom/persistence/dao/OrganizationRepository.java similarity index 100% rename from spring-security-mvc-boot/src/main/java/org/baeldung/custom/persistence/dao/OrganizationRepository.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/custom/persistence/dao/OrganizationRepository.java diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/custom/persistence/dao/PrivilegeRepository.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/custom/persistence/dao/PrivilegeRepository.java similarity index 100% rename from spring-security-mvc-boot/src/main/java/org/baeldung/custom/persistence/dao/PrivilegeRepository.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/custom/persistence/dao/PrivilegeRepository.java diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/custom/persistence/dao/UserRepository.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/custom/persistence/dao/UserRepository.java similarity index 100% rename from spring-security-mvc-boot/src/main/java/org/baeldung/custom/persistence/dao/UserRepository.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/custom/persistence/dao/UserRepository.java diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/custom/persistence/model/Foo.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/custom/persistence/model/Foo.java similarity index 100% rename from spring-security-mvc-boot/src/main/java/org/baeldung/custom/persistence/model/Foo.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/custom/persistence/model/Foo.java diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/custom/persistence/model/Organization.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/custom/persistence/model/Organization.java similarity index 100% rename from spring-security-mvc-boot/src/main/java/org/baeldung/custom/persistence/model/Organization.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/custom/persistence/model/Organization.java diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/custom/persistence/model/Privilege.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/custom/persistence/model/Privilege.java similarity index 100% rename from spring-security-mvc-boot/src/main/java/org/baeldung/custom/persistence/model/Privilege.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/custom/persistence/model/Privilege.java diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/custom/persistence/model/User.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/custom/persistence/model/User.java similarity index 100% rename from spring-security-mvc-boot/src/main/java/org/baeldung/custom/persistence/model/User.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/custom/persistence/model/User.java diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/custom/security/CustomMethodSecurityExpressionHandler.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/custom/security/CustomMethodSecurityExpressionHandler.java similarity index 100% rename from spring-security-mvc-boot/src/main/java/org/baeldung/custom/security/CustomMethodSecurityExpressionHandler.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/custom/security/CustomMethodSecurityExpressionHandler.java diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/custom/security/CustomMethodSecurityExpressionRoot.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/custom/security/CustomMethodSecurityExpressionRoot.java similarity index 100% rename from spring-security-mvc-boot/src/main/java/org/baeldung/custom/security/CustomMethodSecurityExpressionRoot.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/custom/security/CustomMethodSecurityExpressionRoot.java diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/custom/security/CustomPermissionEvaluator.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/custom/security/CustomPermissionEvaluator.java similarity index 100% rename from spring-security-mvc-boot/src/main/java/org/baeldung/custom/security/CustomPermissionEvaluator.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/custom/security/CustomPermissionEvaluator.java diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/custom/security/MySecurityExpressionRoot.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/custom/security/MySecurityExpressionRoot.java similarity index 100% rename from spring-security-mvc-boot/src/main/java/org/baeldung/custom/security/MySecurityExpressionRoot.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/custom/security/MySecurityExpressionRoot.java diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/custom/security/MyUserDetailsService.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/custom/security/MyUserDetailsService.java similarity index 100% rename from spring-security-mvc-boot/src/main/java/org/baeldung/custom/security/MyUserDetailsService.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/custom/security/MyUserDetailsService.java diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/custom/security/MyUserPrincipal.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/custom/security/MyUserPrincipal.java similarity index 100% rename from spring-security-mvc-boot/src/main/java/org/baeldung/custom/security/MyUserPrincipal.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/custom/security/MyUserPrincipal.java diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/custom/web/MainController.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/custom/web/MainController.java similarity index 100% rename from spring-security-mvc-boot/src/main/java/org/baeldung/custom/web/MainController.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/custom/web/MainController.java diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/ip/IpApplication.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/ip/IpApplication.java similarity index 100% rename from spring-security-mvc-boot/src/main/java/org/baeldung/ip/IpApplication.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/ip/IpApplication.java diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/ip/config/CustomIpAuthenticationProvider.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/ip/config/CustomIpAuthenticationProvider.java similarity index 100% rename from spring-security-mvc-boot/src/main/java/org/baeldung/ip/config/CustomIpAuthenticationProvider.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/ip/config/CustomIpAuthenticationProvider.java diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/ip/config/SecurityConfig.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/ip/config/SecurityConfig.java similarity index 100% rename from spring-security-mvc-boot/src/main/java/org/baeldung/ip/config/SecurityConfig.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/ip/config/SecurityConfig.java diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/ip/config/SecurityXmlConfig.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/ip/config/SecurityXmlConfig.java similarity index 100% rename from spring-security-mvc-boot/src/main/java/org/baeldung/ip/config/SecurityXmlConfig.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/ip/config/SecurityXmlConfig.java diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/ip/web/MainController.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/ip/web/MainController.java similarity index 100% rename from spring-security-mvc-boot/src/main/java/org/baeldung/ip/web/MainController.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/ip/web/MainController.java diff --git a/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/jdbcauthentication/h2/H2JdbcAuthenticationApplication.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/jdbcauthentication/h2/H2JdbcAuthenticationApplication.java new file mode 100644 index 0000000000..6bd30414ef --- /dev/null +++ b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/jdbcauthentication/h2/H2JdbcAuthenticationApplication.java @@ -0,0 +1,15 @@ +package org.baeldung.jdbcauthentication.h2; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; + +@SpringBootApplication +@EnableWebSecurity +public class H2JdbcAuthenticationApplication { + + public static void main(String[] args) { + SpringApplication.run(H2JdbcAuthenticationApplication.class, args); + } + +} diff --git a/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/jdbcauthentication/h2/config/SecurityConfiguration.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/jdbcauthentication/h2/config/SecurityConfiguration.java new file mode 100644 index 0000000000..8b8696f0b2 --- /dev/null +++ b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/jdbcauthentication/h2/config/SecurityConfiguration.java @@ -0,0 +1,51 @@ +package org.baeldung.jdbcauthentication.h2.config; + +import javax.sql.DataSource; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; + +@Configuration +public class SecurityConfiguration extends WebSecurityConfigurerAdapter { + @Override + protected void configure(HttpSecurity httpSecurity) throws Exception { + httpSecurity.authorizeRequests() + .antMatchers("/h2-console/**") + .permitAll() + .anyRequest() + .authenticated() + .and() + .formLogin() + .permitAll(); + httpSecurity.csrf() + .ignoringAntMatchers("/h2-console/**"); + httpSecurity.headers() + .frameOptions() + .sameOrigin(); + } + + @Autowired + private DataSource dataSource; + + @Autowired + public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { + auth.jdbcAuthentication() + .dataSource(dataSource) + .withDefaultSchema() + .withUser(User.withUsername("user") + .password(passwordEncoder().encode("pass")) + .roles("USER")); + } + + @Bean + public PasswordEncoder passwordEncoder() { + return new BCryptPasswordEncoder(); + } +} \ No newline at end of file diff --git a/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/jdbcauthentication/h2/web/UserController.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/jdbcauthentication/h2/web/UserController.java new file mode 100644 index 0000000000..0955061614 --- /dev/null +++ b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/jdbcauthentication/h2/web/UserController.java @@ -0,0 +1,17 @@ +package org.baeldung.jdbcauthentication.h2.web; + +import java.security.Principal; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/principal") +public class UserController { + + @GetMapping + public Principal retrievePrincipal(Principal principal) { + return principal; + } +} diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/multipleauthproviders/CustomAuthenticationProvider.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/multipleauthproviders/CustomAuthenticationProvider.java similarity index 100% rename from spring-security-mvc-boot/src/main/java/org/baeldung/multipleauthproviders/CustomAuthenticationProvider.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/multipleauthproviders/CustomAuthenticationProvider.java diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/multipleauthproviders/MultipleAuthController.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/multipleauthproviders/MultipleAuthController.java similarity index 100% rename from spring-security-mvc-boot/src/main/java/org/baeldung/multipleauthproviders/MultipleAuthController.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/multipleauthproviders/MultipleAuthController.java diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/multipleauthproviders/MultipleAuthProvidersApplication.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/multipleauthproviders/MultipleAuthProvidersApplication.java similarity index 100% rename from spring-security-mvc-boot/src/main/java/org/baeldung/multipleauthproviders/MultipleAuthProvidersApplication.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/multipleauthproviders/MultipleAuthProvidersApplication.java diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/multipleauthproviders/MultipleAuthProvidersSecurityConfig.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/multipleauthproviders/MultipleAuthProvidersSecurityConfig.java similarity index 100% rename from spring-security-mvc-boot/src/main/java/org/baeldung/multipleauthproviders/MultipleAuthProvidersSecurityConfig.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/multipleauthproviders/MultipleAuthProvidersSecurityConfig.java diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/multipleentrypoints/MultipleEntryPointsApplication.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/multipleentrypoints/MultipleEntryPointsApplication.java similarity index 100% rename from spring-security-mvc-boot/src/main/java/org/baeldung/multipleentrypoints/MultipleEntryPointsApplication.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/multipleentrypoints/MultipleEntryPointsApplication.java diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/multipleentrypoints/MultipleEntryPointsSecurityConfig.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/multipleentrypoints/MultipleEntryPointsSecurityConfig.java similarity index 100% rename from spring-security-mvc-boot/src/main/java/org/baeldung/multipleentrypoints/MultipleEntryPointsSecurityConfig.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/multipleentrypoints/MultipleEntryPointsSecurityConfig.java diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/multipleentrypoints/PagesController.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/multipleentrypoints/PagesController.java similarity index 100% rename from spring-security-mvc-boot/src/main/java/org/baeldung/multipleentrypoints/PagesController.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/multipleentrypoints/PagesController.java diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/multiplelogin/MultipleLoginApplication.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/multiplelogin/MultipleLoginApplication.java similarity index 69% rename from spring-security-mvc-boot/src/main/java/org/baeldung/multiplelogin/MultipleLoginApplication.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/multiplelogin/MultipleLoginApplication.java index e9dc541ad3..d25324eb54 100644 --- a/spring-security-mvc-boot/src/main/java/org/baeldung/multiplelogin/MultipleLoginApplication.java +++ b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/multiplelogin/MultipleLoginApplication.java @@ -1,11 +1,8 @@ package org.baeldung.multiplelogin; import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.Configuration; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.context.annotation.ComponentScan; @SpringBootApplication @ComponentScan("org.baeldung.multiplelogin") diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/multiplelogin/MultipleLoginMvcConfig.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/multiplelogin/MultipleLoginMvcConfig.java similarity index 100% rename from spring-security-mvc-boot/src/main/java/org/baeldung/multiplelogin/MultipleLoginMvcConfig.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/multiplelogin/MultipleLoginMvcConfig.java diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/multiplelogin/MultipleLoginSecurityConfig.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/multiplelogin/MultipleLoginSecurityConfig.java similarity index 100% rename from spring-security-mvc-boot/src/main/java/org/baeldung/multiplelogin/MultipleLoginSecurityConfig.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/multiplelogin/MultipleLoginSecurityConfig.java diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/multiplelogin/UsersController.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/multiplelogin/UsersController.java similarity index 100% rename from spring-security-mvc-boot/src/main/java/org/baeldung/multiplelogin/UsersController.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/multiplelogin/UsersController.java diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/CustomAuthenticationProvider.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/rolesauthorities/CustomAuthenticationProvider.java similarity index 100% rename from spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/CustomAuthenticationProvider.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/rolesauthorities/CustomAuthenticationProvider.java diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/MyLogoutSuccessHandler.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/rolesauthorities/MyLogoutSuccessHandler.java similarity index 100% rename from spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/MyLogoutSuccessHandler.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/rolesauthorities/MyLogoutSuccessHandler.java diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/MyUserDetailsService.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/rolesauthorities/MyUserDetailsService.java similarity index 100% rename from spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/MyUserDetailsService.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/rolesauthorities/MyUserDetailsService.java diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/RolesAuthoritiesApplication.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/rolesauthorities/RolesAuthoritiesApplication.java similarity index 100% rename from spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/RolesAuthoritiesApplication.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/rolesauthorities/RolesAuthoritiesApplication.java diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/config/MvcConfig.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/rolesauthorities/config/MvcConfig.java similarity index 100% rename from spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/config/MvcConfig.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/rolesauthorities/config/MvcConfig.java diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/config/SecurityConfig.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/rolesauthorities/config/SecurityConfig.java similarity index 100% rename from spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/config/SecurityConfig.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/rolesauthorities/config/SecurityConfig.java diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/model/Privilege.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/rolesauthorities/model/Privilege.java similarity index 100% rename from spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/model/Privilege.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/rolesauthorities/model/Privilege.java diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/model/Role.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/rolesauthorities/model/Role.java similarity index 100% rename from spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/model/Role.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/rolesauthorities/model/Role.java diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/model/User.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/rolesauthorities/model/User.java similarity index 100% rename from spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/model/User.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/rolesauthorities/model/User.java diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/persistence/IUserService.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/rolesauthorities/persistence/IUserService.java similarity index 100% rename from spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/persistence/IUserService.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/rolesauthorities/persistence/IUserService.java diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/persistence/PrivilegeRepository.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/rolesauthorities/persistence/PrivilegeRepository.java similarity index 100% rename from spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/persistence/PrivilegeRepository.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/rolesauthorities/persistence/PrivilegeRepository.java diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/persistence/RoleRepository.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/rolesauthorities/persistence/RoleRepository.java similarity index 100% rename from spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/persistence/RoleRepository.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/rolesauthorities/persistence/RoleRepository.java diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/persistence/SetupDataLoader.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/rolesauthorities/persistence/SetupDataLoader.java similarity index 100% rename from spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/persistence/SetupDataLoader.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/rolesauthorities/persistence/SetupDataLoader.java diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/persistence/UserRepository.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/rolesauthorities/persistence/UserRepository.java similarity index 100% rename from spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/persistence/UserRepository.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/rolesauthorities/persistence/UserRepository.java diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/persistence/UserService.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/rolesauthorities/persistence/UserService.java similarity index 100% rename from spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/persistence/UserService.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/rolesauthorities/persistence/UserService.java diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/ssl/HttpsEnabledApplication.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/ssl/HttpsEnabledApplication.java similarity index 100% rename from spring-security-mvc-boot/src/main/java/org/baeldung/ssl/HttpsEnabledApplication.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/ssl/HttpsEnabledApplication.java diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/ssl/SecurityConfig.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/ssl/SecurityConfig.java similarity index 100% rename from spring-security-mvc-boot/src/main/java/org/baeldung/ssl/SecurityConfig.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/ssl/SecurityConfig.java diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/ssl/WelcomeController.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/ssl/WelcomeController.java similarity index 100% rename from spring-security-mvc-boot/src/main/java/org/baeldung/ssl/WelcomeController.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/ssl/WelcomeController.java diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/voter/MinuteBasedVoter.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/voter/MinuteBasedVoter.java similarity index 100% rename from spring-security-mvc-boot/src/main/java/org/baeldung/voter/MinuteBasedVoter.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/voter/MinuteBasedVoter.java diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/voter/VoterApplication.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/voter/VoterApplication.java similarity index 100% rename from spring-security-mvc-boot/src/main/java/org/baeldung/voter/VoterApplication.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/voter/VoterApplication.java diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/voter/VoterMvcConfig.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/voter/VoterMvcConfig.java similarity index 100% rename from spring-security-mvc-boot/src/main/java/org/baeldung/voter/VoterMvcConfig.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/voter/VoterMvcConfig.java diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/voter/WebSecurityConfig.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/voter/WebSecurityConfig.java similarity index 100% rename from spring-security-mvc-boot/src/main/java/org/baeldung/voter/WebSecurityConfig.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/voter/WebSecurityConfig.java diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/voter/XmlSecurityConfig.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/voter/XmlSecurityConfig.java similarity index 100% rename from spring-security-mvc-boot/src/main/java/org/baeldung/voter/XmlSecurityConfig.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/java/org/baeldung/voter/XmlSecurityConfig.java diff --git a/spring-security-mvc-boot/src/main/resources/application-ssl.properties b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/resources/application-ssl.properties similarity index 100% rename from spring-security-mvc-boot/src/main/resources/application-ssl.properties rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/resources/application-ssl.properties diff --git a/spring-security-mvc-boot/src/main/resources/application.properties b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/resources/application.properties similarity index 74% rename from spring-security-mvc-boot/src/main/resources/application.properties rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/resources/application.properties index 25eac743d1..365dedab9e 100644 --- a/spring-security-mvc-boot/src/main/resources/application.properties +++ b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/resources/application.properties @@ -8,5 +8,7 @@ spring.jpa.database=H2 spring.jpa.show-sql=false spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect +logging.level.org.springframework.security.web.FilterChainProxy=DEBUG -#logging.level.org.springframework.security.web.FilterChainProxy=DEBUG \ No newline at end of file +spring.h2.console.enabled=true +spring.h2.console.path=/h2-console \ No newline at end of file diff --git a/spring-security-mvc-boot/src/main/resources/keystore/baeldung.p12 b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/resources/keystore/baeldung.p12 similarity index 100% rename from spring-security-mvc-boot/src/main/resources/keystore/baeldung.p12 rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/resources/keystore/baeldung.p12 diff --git a/spring-cloud-data-flow/time-source/src/main/resources/logback.xml b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/resources/logback.xml similarity index 100% rename from spring-cloud-data-flow/time-source/src/main/resources/logback.xml rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/resources/logback.xml diff --git a/spring-security-mvc-boot/src/main/resources/persistence-h2.properties b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/resources/persistence-h2.properties similarity index 100% rename from spring-security-mvc-boot/src/main/resources/persistence-h2.properties rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/resources/persistence-h2.properties diff --git a/spring-security-mvc-boot/src/main/resources/spring-security-custom-voter.xml b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/resources/spring-security-custom-voter.xml similarity index 100% rename from spring-security-mvc-boot/src/main/resources/spring-security-custom-voter.xml rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/resources/spring-security-custom-voter.xml diff --git a/spring-security-mvc-boot/src/main/resources/spring-security-ip.xml b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/resources/spring-security-ip.xml similarity index 100% rename from spring-security-mvc-boot/src/main/resources/spring-security-ip.xml rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/resources/spring-security-ip.xml diff --git a/spring-security-mvc-boot/src/main/resources/spring-security-multiple-auth-providers.xml b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/resources/spring-security-multiple-auth-providers.xml similarity index 100% rename from spring-security-mvc-boot/src/main/resources/spring-security-multiple-auth-providers.xml rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/resources/spring-security-multiple-auth-providers.xml diff --git a/spring-security-mvc-boot/src/main/resources/spring-security-multiple-entry.xml b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/resources/spring-security-multiple-entry.xml similarity index 100% rename from spring-security-mvc-boot/src/main/resources/spring-security-multiple-entry.xml rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/resources/spring-security-multiple-entry.xml diff --git a/spring-security-mvc-boot/src/main/resources/templates/403.html b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/resources/templates/403.html similarity index 100% rename from spring-security-mvc-boot/src/main/resources/templates/403.html rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/resources/templates/403.html diff --git a/spring-security-mvc-boot/src/main/resources/templates/adminPage.html b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/resources/templates/adminPage.html similarity index 100% rename from spring-security-mvc-boot/src/main/resources/templates/adminPage.html rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/resources/templates/adminPage.html diff --git a/spring-security-client/spring-security-thymeleaf-config/src/main/resources/templates/index.html b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/resources/templates/index.html similarity index 100% rename from spring-security-client/spring-security-thymeleaf-config/src/main/resources/templates/index.html rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/resources/templates/index.html diff --git a/spring-security-mvc-boot/src/main/resources/templates/login.html b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/resources/templates/login.html similarity index 100% rename from spring-security-mvc-boot/src/main/resources/templates/login.html rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/resources/templates/login.html diff --git a/spring-security-mvc-boot/src/main/resources/templates/loginAdmin.html b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/resources/templates/loginAdmin.html similarity index 100% rename from spring-security-mvc-boot/src/main/resources/templates/loginAdmin.html rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/resources/templates/loginAdmin.html diff --git a/spring-security-mvc-boot/src/main/resources/templates/loginUser.html b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/resources/templates/loginUser.html similarity index 100% rename from spring-security-mvc-boot/src/main/resources/templates/loginUser.html rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/resources/templates/loginUser.html diff --git a/spring-security-mvc-boot/src/main/resources/templates/multipleHttpElems/login.html b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/resources/templates/multipleHttpElems/login.html similarity index 100% rename from spring-security-mvc-boot/src/main/resources/templates/multipleHttpElems/login.html rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/resources/templates/multipleHttpElems/login.html diff --git a/spring-security-mvc-boot/src/main/resources/templates/multipleHttpElems/loginWithWarning.html b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/resources/templates/multipleHttpElems/loginWithWarning.html similarity index 100% rename from spring-security-mvc-boot/src/main/resources/templates/multipleHttpElems/loginWithWarning.html rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/resources/templates/multipleHttpElems/loginWithWarning.html diff --git a/spring-security-mvc-boot/src/main/resources/templates/multipleHttpElems/multipleHttpLinks.html b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/resources/templates/multipleHttpElems/multipleHttpLinks.html similarity index 100% rename from spring-security-mvc-boot/src/main/resources/templates/multipleHttpElems/multipleHttpLinks.html rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/resources/templates/multipleHttpElems/multipleHttpLinks.html diff --git a/spring-security-mvc-boot/src/main/resources/templates/multipleHttpElems/myAdminPage.html b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/resources/templates/multipleHttpElems/myAdminPage.html similarity index 100% rename from spring-security-mvc-boot/src/main/resources/templates/multipleHttpElems/myAdminPage.html rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/resources/templates/multipleHttpElems/myAdminPage.html diff --git a/spring-security-mvc-boot/src/main/resources/templates/multipleHttpElems/myGuestPage.html b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/resources/templates/multipleHttpElems/myGuestPage.html similarity index 100% rename from spring-security-mvc-boot/src/main/resources/templates/multipleHttpElems/myGuestPage.html rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/resources/templates/multipleHttpElems/myGuestPage.html diff --git a/spring-security-mvc-boot/src/main/resources/templates/multipleHttpElems/myPrivateUserPage.html b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/resources/templates/multipleHttpElems/myPrivateUserPage.html similarity index 100% rename from spring-security-mvc-boot/src/main/resources/templates/multipleHttpElems/myPrivateUserPage.html rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/resources/templates/multipleHttpElems/myPrivateUserPage.html diff --git a/spring-security-mvc-boot/src/main/resources/templates/multipleHttpElems/myUserPage.html b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/resources/templates/multipleHttpElems/myUserPage.html similarity index 100% rename from spring-security-mvc-boot/src/main/resources/templates/multipleHttpElems/myUserPage.html rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/resources/templates/multipleHttpElems/myUserPage.html diff --git a/spring-security-mvc-boot/src/main/resources/templates/private.html b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/resources/templates/private.html similarity index 100% rename from spring-security-mvc-boot/src/main/resources/templates/private.html rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/resources/templates/private.html diff --git a/spring-security-mvc-boot/src/main/resources/templates/protectedLinks.html b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/resources/templates/protectedLinks.html similarity index 100% rename from spring-security-mvc-boot/src/main/resources/templates/protectedLinks.html rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/resources/templates/protectedLinks.html diff --git a/spring-security-mvc-boot/src/main/resources/templates/rolesauthorities/home.html b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/resources/templates/rolesauthorities/home.html similarity index 100% rename from spring-security-mvc-boot/src/main/resources/templates/rolesauthorities/home.html rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/resources/templates/rolesauthorities/home.html diff --git a/spring-security-mvc-boot/src/main/resources/templates/rolesauthorities/login.html b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/resources/templates/rolesauthorities/login.html similarity index 100% rename from spring-security-mvc-boot/src/main/resources/templates/rolesauthorities/login.html rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/resources/templates/rolesauthorities/login.html diff --git a/spring-security-mvc-boot/src/main/resources/templates/rolesauthorities/protectedbyauthority.html b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/resources/templates/rolesauthorities/protectedbyauthority.html similarity index 100% rename from spring-security-mvc-boot/src/main/resources/templates/rolesauthorities/protectedbyauthority.html rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/resources/templates/rolesauthorities/protectedbyauthority.html diff --git a/spring-security-mvc-boot/src/main/resources/templates/rolesauthorities/protectedbynothing.html b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/resources/templates/rolesauthorities/protectedbynothing.html similarity index 100% rename from spring-security-mvc-boot/src/main/resources/templates/rolesauthorities/protectedbynothing.html rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/resources/templates/rolesauthorities/protectedbynothing.html diff --git a/spring-security-mvc-boot/src/main/resources/templates/rolesauthorities/protectedbyrole.html b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/resources/templates/rolesauthorities/protectedbyrole.html similarity index 100% rename from spring-security-mvc-boot/src/main/resources/templates/rolesauthorities/protectedbyrole.html rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/resources/templates/rolesauthorities/protectedbyrole.html diff --git a/spring-security-mvc-boot/src/main/resources/templates/ssl/welcome.html b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/resources/templates/ssl/welcome.html similarity index 100% rename from spring-security-mvc-boot/src/main/resources/templates/ssl/welcome.html rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/resources/templates/ssl/welcome.html diff --git a/spring-security-mvc-boot/src/main/resources/templates/userPage.html b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/resources/templates/userPage.html similarity index 100% rename from spring-security-mvc-boot/src/main/resources/templates/userPage.html rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/main/resources/templates/userPage.html diff --git a/spring-security-mvc-boot/src/test/java/com/baeldung/relationships/SpringDataWithSecurityIntegrationTest.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/test/java/com/baeldung/relationships/SpringDataWithSecurityIntegrationTest.java similarity index 100% rename from spring-security-mvc-boot/src/test/java/com/baeldung/relationships/SpringDataWithSecurityIntegrationTest.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/test/java/com/baeldung/relationships/SpringDataWithSecurityIntegrationTest.java diff --git a/spring-security-mvc-boot/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/test/java/org/baeldung/SpringContextIntegrationTest.java similarity index 100% rename from spring-security-mvc-boot/src/test/java/org/baeldung/SpringContextIntegrationTest.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/test/java/org/baeldung/SpringContextIntegrationTest.java diff --git a/spring-security-mvc-boot/spring-security-mvc-boot-default/src/test/java/org/baeldung/jdbcauthentication/h2/web/UserControllerLiveTest.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/test/java/org/baeldung/jdbcauthentication/h2/web/UserControllerLiveTest.java new file mode 100644 index 0000000000..638e9d7919 --- /dev/null +++ b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/test/java/org/baeldung/jdbcauthentication/h2/web/UserControllerLiveTest.java @@ -0,0 +1,35 @@ +package org.baeldung.jdbcauthentication.h2.web; + +import static io.restassured.RestAssured.given; +import static org.hamcrest.CoreMatchers.is; + +import org.junit.jupiter.api.Test; +import org.springframework.http.HttpStatus; + +import io.restassured.authentication.FormAuthConfig; +import io.restassured.filter.session.SessionFilter; + +/** + * This Live Test requires the H2JdbcAuthenticationApplication application to be up and running + */ +public class UserControllerLiveTest { + + private static final String PRINCIPAL_SVC_URL = "http://localhost:8082/principal"; + + @Test + public void givenExisting_whenRequestPrincipal_thenRetrieveData() throws Exception { + SessionFilter filter = new SessionFilter(); + given().auth() + .form("user", "pass", new FormAuthConfig("/login", "username", "password").withCsrfFieldName("_csrf")) + .and() + .filter(filter) + .when() + .get(PRINCIPAL_SVC_URL) + .then() + .statusCode(HttpStatus.OK.value()) + .and() + .body("authorities[0].authority", is("ROLE_USER")) + .body("principal.username", is("user")) + .body("name", is("user")); + } +} diff --git a/spring-security-mvc-boot/src/test/java/org/baeldung/web/ApplicationLiveTest.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/test/java/org/baeldung/web/ApplicationLiveTest.java similarity index 100% rename from spring-security-mvc-boot/src/test/java/org/baeldung/web/ApplicationLiveTest.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/test/java/org/baeldung/web/ApplicationLiveTest.java diff --git a/spring-security-mvc-boot/src/test/java/org/baeldung/web/CustomUserDetailsServiceIntegrationTest.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/test/java/org/baeldung/web/CustomUserDetailsServiceIntegrationTest.java similarity index 100% rename from spring-security-mvc-boot/src/test/java/org/baeldung/web/CustomUserDetailsServiceIntegrationTest.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/test/java/org/baeldung/web/CustomUserDetailsServiceIntegrationTest.java diff --git a/spring-security-mvc-boot/src/test/java/org/baeldung/web/HttpsApplicationIntegrationTest.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/test/java/org/baeldung/web/HttpsApplicationIntegrationTest.java similarity index 100% rename from spring-security-mvc-boot/src/test/java/org/baeldung/web/HttpsApplicationIntegrationTest.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/test/java/org/baeldung/web/HttpsApplicationIntegrationTest.java diff --git a/spring-security-mvc-boot/src/test/java/org/baeldung/web/IpLiveTest.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/test/java/org/baeldung/web/IpLiveTest.java similarity index 100% rename from spring-security-mvc-boot/src/test/java/org/baeldung/web/IpLiveTest.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/test/java/org/baeldung/web/IpLiveTest.java diff --git a/spring-security-mvc-boot/src/test/java/org/baeldung/web/MultipleAuthProvidersApplicationIntegrationTest.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/test/java/org/baeldung/web/MultipleAuthProvidersApplicationIntegrationTest.java similarity index 100% rename from spring-security-mvc-boot/src/test/java/org/baeldung/web/MultipleAuthProvidersApplicationIntegrationTest.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/test/java/org/baeldung/web/MultipleAuthProvidersApplicationIntegrationTest.java diff --git a/spring-security-mvc-boot/src/test/java/org/baeldung/web/MultipleEntryPointsIntegrationTest.java b/spring-security-mvc-boot/spring-security-mvc-boot-default/src/test/java/org/baeldung/web/MultipleEntryPointsIntegrationTest.java similarity index 100% rename from spring-security-mvc-boot/src/test/java/org/baeldung/web/MultipleEntryPointsIntegrationTest.java rename to spring-security-mvc-boot/spring-security-mvc-boot-default/src/test/java/org/baeldung/web/MultipleEntryPointsIntegrationTest.java diff --git a/spring-security-mvc-boot/spring-security-mvc-boot-mysql/pom.xml b/spring-security-mvc-boot/spring-security-mvc-boot-mysql/pom.xml new file mode 100644 index 0000000000..765953c557 --- /dev/null +++ b/spring-security-mvc-boot/spring-security-mvc-boot-mysql/pom.xml @@ -0,0 +1,28 @@ + + + 4.0.0 + com.baeldung + spring-security-mvc-boot-mysql + 0.0.1-SNAPSHOT + spring-security-mvc-boot-mysql + jar + Spring Security MVC Boot using MySQL + + + spring-security-mvc-boot + com.baeldung + 0.0.1-SNAPSHOT + .. + + + + + mysql + mysql-connector-java + runtime + + + + diff --git a/spring-security-mvc-boot/spring-security-mvc-boot-mysql/src/main/java/com/baeldung/jdbcauthentication/mysql/MySqlJdbcAuthenticationApplication.java b/spring-security-mvc-boot/spring-security-mvc-boot-mysql/src/main/java/com/baeldung/jdbcauthentication/mysql/MySqlJdbcAuthenticationApplication.java new file mode 100644 index 0000000000..238a48730c --- /dev/null +++ b/spring-security-mvc-boot/spring-security-mvc-boot-mysql/src/main/java/com/baeldung/jdbcauthentication/mysql/MySqlJdbcAuthenticationApplication.java @@ -0,0 +1,13 @@ +package com.baeldung.jdbcauthentication.mysql; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class MySqlJdbcAuthenticationApplication { + + public static void main(String[] args) { + SpringApplication.run(MySqlJdbcAuthenticationApplication.class, args); + } + +} diff --git a/spring-security-mvc-boot/spring-security-mvc-boot-mysql/src/main/java/com/baeldung/jdbcauthentication/mysql/config/SecurityConfiguration.java b/spring-security-mvc-boot/spring-security-mvc-boot-mysql/src/main/java/com/baeldung/jdbcauthentication/mysql/config/SecurityConfiguration.java new file mode 100644 index 0000000000..a0584818cd --- /dev/null +++ b/spring-security-mvc-boot/spring-security-mvc-boot-mysql/src/main/java/com/baeldung/jdbcauthentication/mysql/config/SecurityConfiguration.java @@ -0,0 +1,35 @@ +package com.baeldung.jdbcauthentication.mysql.config; + +import javax.sql.DataSource; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; + +@Configuration +public class SecurityConfiguration { + + @Autowired + private DataSource dataSource; + + @Autowired + public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { + auth.jdbcAuthentication() + .dataSource(dataSource) + .usersByUsernameQuery("select email,password,enabled " + + "from bael_users " + + "where email = ?") + .authoritiesByUsernameQuery("select email,authority " + + "from authorities " + + "where email = ?"); + } + + @Bean + public PasswordEncoder passwordEncoder() { + return new BCryptPasswordEncoder(); + } + +} \ No newline at end of file diff --git a/spring-security-mvc-boot/spring-security-mvc-boot-mysql/src/main/java/com/baeldung/jdbcauthentication/mysql/web/UserController.java b/spring-security-mvc-boot/spring-security-mvc-boot-mysql/src/main/java/com/baeldung/jdbcauthentication/mysql/web/UserController.java new file mode 100644 index 0000000000..ed15f8bfe6 --- /dev/null +++ b/spring-security-mvc-boot/spring-security-mvc-boot-mysql/src/main/java/com/baeldung/jdbcauthentication/mysql/web/UserController.java @@ -0,0 +1,17 @@ +package com.baeldung.jdbcauthentication.mysql.web; + +import java.security.Principal; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/principal") +public class UserController { + + @GetMapping + public Principal retrievePrincipal(Principal principal) { + return principal; + } +} \ No newline at end of file diff --git a/spring-security-mvc-boot/spring-security-mvc-boot-mysql/src/main/resources/application.properties b/spring-security-mvc-boot/spring-security-mvc-boot-mysql/src/main/resources/application.properties new file mode 100644 index 0000000000..2962475108 --- /dev/null +++ b/spring-security-mvc-boot/spring-security-mvc-boot-mysql/src/main/resources/application.properties @@ -0,0 +1,8 @@ +server.port=8082 + +spring.datasource.url=jdbc:mysql://localhost:3306/jdbc_authentication +spring.datasource.username=root +spring.datasource.password=pass + +spring.datasource.initialization-mode=always +spring.jpa.hibernate.ddl-auto=none diff --git a/spring-security-mvc-boot/spring-security-mvc-boot-mysql/src/main/resources/data.sql b/spring-security-mvc-boot/spring-security-mvc-boot-mysql/src/main/resources/data.sql new file mode 100644 index 0000000000..8214fd8204 --- /dev/null +++ b/spring-security-mvc-boot/spring-security-mvc-boot-mysql/src/main/resources/data.sql @@ -0,0 +1,4 @@ +-- User user@email.com/pass +INSERT INTO bael_users (name, email, password, enabled) values ('user', 'user@email.com', '$2a$10$8.UnVuG9HHgffUDAlk8qfOuVGkqRzgVymGe07xd00DMxs.AQubh4a', 1); + +INSERT INTO authorities (email, authority) values ('user@email.com', 'ROLE_USER'); \ No newline at end of file diff --git a/spring-security-mvc-boot/spring-security-mvc-boot-mysql/src/main/resources/schema.sql b/spring-security-mvc-boot/spring-security-mvc-boot-mysql/src/main/resources/schema.sql new file mode 100644 index 0000000000..bb38c74366 --- /dev/null +++ b/spring-security-mvc-boot/spring-security-mvc-boot-mysql/src/main/resources/schema.sql @@ -0,0 +1,18 @@ +DROP TABLE IF EXISTS authorities; +DROP TABLE IF EXISTS bael_users; + +CREATE TABLE bael_users ( + name VARCHAR(50) NOT NULL, + email VARCHAR(50) NOT NULL, + password VARCHAR(100) NOT NULL, + enabled TINYINT NOT NULL DEFAULT 1, + PRIMARY KEY (email) +); + +CREATE TABLE authorities ( + email VARCHAR(50) NOT NULL, + authority VARCHAR(50) NOT NULL, + FOREIGN KEY (email) REFERENCES bael_users(email) +); + +CREATE UNIQUE INDEX ix_auth_email on authorities (email,authority); \ No newline at end of file diff --git a/spring-security-client/spring-security-jsp-config/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-security-mvc-boot/spring-security-mvc-boot-mysql/src/test/java/com/baeldung/jdbcauthentication/mysql/SpringContextIntegrationTest.java similarity index 74% rename from spring-security-client/spring-security-jsp-config/src/test/java/org/baeldung/SpringContextIntegrationTest.java rename to spring-security-mvc-boot/spring-security-mvc-boot-mysql/src/test/java/com/baeldung/jdbcauthentication/mysql/SpringContextIntegrationTest.java index 66243ef00d..2c19e2c0ca 100644 --- a/spring-security-client/spring-security-jsp-config/src/test/java/org/baeldung/SpringContextIntegrationTest.java +++ b/spring-security-mvc-boot/spring-security-mvc-boot-mysql/src/test/java/com/baeldung/jdbcauthentication/mysql/SpringContextIntegrationTest.java @@ -1,13 +1,12 @@ -package org.baeldung; +package com.baeldung.jdbcauthentication.mysql; -import org.baeldung.config.Application; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) -@SpringBootTest(classes = Application.class) +@SpringBootTest(classes = MySqlJdbcAuthenticationApplication.class) public class SpringContextIntegrationTest { @Test diff --git a/spring-security-mvc-boot/spring-security-mvc-boot-mysql/src/test/java/com/baeldung/jdbcauthentication/mysql/web/UserControllerLiveTest.java b/spring-security-mvc-boot/spring-security-mvc-boot-mysql/src/test/java/com/baeldung/jdbcauthentication/mysql/web/UserControllerLiveTest.java new file mode 100644 index 0000000000..79bc84ea69 --- /dev/null +++ b/spring-security-mvc-boot/spring-security-mvc-boot-mysql/src/test/java/com/baeldung/jdbcauthentication/mysql/web/UserControllerLiveTest.java @@ -0,0 +1,35 @@ +package com.baeldung.jdbcauthentication.mysql.web; + +import static io.restassured.RestAssured.given; +import static org.hamcrest.CoreMatchers.is; + +import org.junit.jupiter.api.Test; +import org.springframework.http.HttpStatus; + +/** + * This Live Test requires: + * * a MySql instance running, that allows a 'root' user with password 'pass', and with a database named jdbc_authentication + * (e.g. with the following command `docker run -p 3306:3306 --name bael-mysql -e MYSQL_ROOT_PASSWORD=pass -e MYSQL_DATABASE=jdbc_authentication mysql:latest`) + * * the service up and running + * + */ +public class UserControllerLiveTest { + + private static final String PRINCIPAL_SVC_URL = "http://localhost:8082/principal"; + + @Test + public void givenExisting_whenRequestPrincipal_thenRetrieveData() throws Exception { + given().auth() + .preemptive() + .basic("user@email.com", "pass") + .when() + .get(PRINCIPAL_SVC_URL) + .then() + .statusCode(HttpStatus.OK.value()) + .and() + .body("authorities[0].authority", is("ROLE_USER")) + .body("principal.username", is("user@email.com")) + .body("name", is("user@email.com")); + } + +} diff --git a/spring-security-mvc-boot/spring-security-mvc-boot-postgre/pom.xml b/spring-security-mvc-boot/spring-security-mvc-boot-postgre/pom.xml new file mode 100644 index 0000000000..e68e47b596 --- /dev/null +++ b/spring-security-mvc-boot/spring-security-mvc-boot-postgre/pom.xml @@ -0,0 +1,28 @@ + + + 4.0.0 + com.baeldung + spring-security-mvc-boot-postgre + 0.0.1-SNAPSHOT + spring-security-mvc-boot-postgre + jar + Spring Security MVC Boot using PostgreSQL + + + spring-security-mvc-boot + com.baeldung + 0.0.1-SNAPSHOT + .. + + + + + org.postgresql + postgresql + runtime + + + + diff --git a/spring-security-mvc-boot/spring-security-mvc-boot-postgre/src/main/java/com/baeldung/jdbcauthentication/postgre/PostgreJdbcAuthenticationApplication.java b/spring-security-mvc-boot/spring-security-mvc-boot-postgre/src/main/java/com/baeldung/jdbcauthentication/postgre/PostgreJdbcAuthenticationApplication.java new file mode 100644 index 0000000000..d4b555e8c6 --- /dev/null +++ b/spring-security-mvc-boot/spring-security-mvc-boot-postgre/src/main/java/com/baeldung/jdbcauthentication/postgre/PostgreJdbcAuthenticationApplication.java @@ -0,0 +1,13 @@ +package com.baeldung.jdbcauthentication.postgre; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class PostgreJdbcAuthenticationApplication { + + public static void main(String[] args) { + SpringApplication.run(PostgreJdbcAuthenticationApplication.class, args); + } + +} diff --git a/spring-security-mvc-boot/spring-security-mvc-boot-postgre/src/main/java/com/baeldung/jdbcauthentication/postgre/config/SecurityConfiguration.java b/spring-security-mvc-boot/spring-security-mvc-boot-postgre/src/main/java/com/baeldung/jdbcauthentication/postgre/config/SecurityConfiguration.java new file mode 100644 index 0000000000..85dc9d364c --- /dev/null +++ b/spring-security-mvc-boot/spring-security-mvc-boot-postgre/src/main/java/com/baeldung/jdbcauthentication/postgre/config/SecurityConfiguration.java @@ -0,0 +1,29 @@ +package com.baeldung.jdbcauthentication.postgre.config; + +import javax.sql.DataSource; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; + +@Configuration +public class SecurityConfiguration { + + @Autowired + private DataSource dataSource; + + @Autowired + public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { + auth.jdbcAuthentication() + .dataSource(dataSource); + } + + @Bean + public PasswordEncoder passwordEncoder() { + return new BCryptPasswordEncoder(); + } + +} \ No newline at end of file diff --git a/spring-security-mvc-boot/spring-security-mvc-boot-postgre/src/main/java/com/baeldung/jdbcauthentication/postgre/web/UserController.java b/spring-security-mvc-boot/spring-security-mvc-boot-postgre/src/main/java/com/baeldung/jdbcauthentication/postgre/web/UserController.java new file mode 100644 index 0000000000..da85a46562 --- /dev/null +++ b/spring-security-mvc-boot/spring-security-mvc-boot-postgre/src/main/java/com/baeldung/jdbcauthentication/postgre/web/UserController.java @@ -0,0 +1,17 @@ +package com.baeldung.jdbcauthentication.postgre.web; + +import java.security.Principal; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/principal") +public class UserController { + + @GetMapping + public Principal retrievePrincipal(Principal principal) { + return principal; + } +} \ No newline at end of file diff --git a/spring-security-mvc-boot/spring-security-mvc-boot-postgre/src/main/resources/application.properties b/spring-security-mvc-boot/spring-security-mvc-boot-postgre/src/main/resources/application.properties new file mode 100644 index 0000000000..2940c5121e --- /dev/null +++ b/spring-security-mvc-boot/spring-security-mvc-boot-postgre/src/main/resources/application.properties @@ -0,0 +1,8 @@ +server.port=8082 + +spring.datasource.url=jdbc:postgresql://localhost:5432/jdbc_authentication +spring.datasource.username=postgres +spring.datasource.password=pass + +spring.datasource.initialization-mode=always +spring.jpa.hibernate.ddl-auto=none diff --git a/spring-security-mvc-boot/spring-security-mvc-boot-postgre/src/main/resources/data.sql b/spring-security-mvc-boot/spring-security-mvc-boot-postgre/src/main/resources/data.sql new file mode 100644 index 0000000000..fcc6b54949 --- /dev/null +++ b/spring-security-mvc-boot/spring-security-mvc-boot-postgre/src/main/resources/data.sql @@ -0,0 +1,4 @@ +-- User user/pass +INSERT INTO users (username, password, enabled) values ('user', '$2a$10$8.UnVuG9HHgffUDAlk8qfOuVGkqRzgVymGe07xd00DMxs.AQubh4a', true); + +INSERT INTO authorities (username, authority) values ('user', 'ROLE_USER'); \ No newline at end of file diff --git a/spring-security-mvc-boot/spring-security-mvc-boot-postgre/src/main/resources/schema.sql b/spring-security-mvc-boot/spring-security-mvc-boot-postgre/src/main/resources/schema.sql new file mode 100644 index 0000000000..d78edfb528 --- /dev/null +++ b/spring-security-mvc-boot/spring-security-mvc-boot-postgre/src/main/resources/schema.sql @@ -0,0 +1,16 @@ +DROP TABLE IF EXISTS authorities; +DROP TABLE IF EXISTS users; + +CREATE TABLE users ( + username varchar(50) NOT NULL PRIMARY KEY, + password varchar(100) NOT NULL, + enabled boolean not null DEFAULT true +); + +CREATE TABLE authorities ( + username varchar(50) NOT NULL, + authority varchar(50) NOT NULL, + CONSTRAINT foreign_authorities_users_1 foreign key(username) references users(username) +); + +CREATE UNIQUE INDEX ix_auth_username on authorities (username,authority); \ No newline at end of file diff --git a/spring-security-client/spring-security-jsp-authentication/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-security-mvc-boot/spring-security-mvc-boot-postgre/src/test/java/com/baeldung/jdbcauthentication/postgre/SpringContextIntegrationTest.java similarity index 62% rename from spring-security-client/spring-security-jsp-authentication/src/test/java/org/baeldung/SpringContextIntegrationTest.java rename to spring-security-mvc-boot/spring-security-mvc-boot-postgre/src/test/java/com/baeldung/jdbcauthentication/postgre/SpringContextIntegrationTest.java index 66243ef00d..f133ef73be 100644 --- a/spring-security-client/spring-security-jsp-authentication/src/test/java/org/baeldung/SpringContextIntegrationTest.java +++ b/spring-security-mvc-boot/spring-security-mvc-boot-postgre/src/test/java/com/baeldung/jdbcauthentication/postgre/SpringContextIntegrationTest.java @@ -1,13 +1,14 @@ -package org.baeldung; +package com.baeldung.jdbcauthentication.postgre; -import org.baeldung.config.Application; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; +import com.baeldung.jdbcauthentication.postgre.PostgreJdbcAuthenticationApplication; + @RunWith(SpringRunner.class) -@SpringBootTest(classes = Application.class) +@SpringBootTest(classes = PostgreJdbcAuthenticationApplication.class) public class SpringContextIntegrationTest { @Test diff --git a/spring-security-mvc-boot/spring-security-mvc-boot-postgre/src/test/java/com/baeldung/jdbcauthentication/postgre/web/UserControllerLiveTest.java b/spring-security-mvc-boot/spring-security-mvc-boot-postgre/src/test/java/com/baeldung/jdbcauthentication/postgre/web/UserControllerLiveTest.java new file mode 100644 index 0000000000..b5f4379c0a --- /dev/null +++ b/spring-security-mvc-boot/spring-security-mvc-boot-postgre/src/test/java/com/baeldung/jdbcauthentication/postgre/web/UserControllerLiveTest.java @@ -0,0 +1,35 @@ +package com.baeldung.jdbcauthentication.postgre.web; + +import static io.restassured.RestAssured.given; +import static org.hamcrest.CoreMatchers.is; + +import org.junit.jupiter.api.Test; +import org.springframework.http.HttpStatus; + +/** + * This Live Test requires: + * * a PostgreSQL instance running, that allows a 'root' user with password 'pass', and with a database named jdbc_authentication + * (e.g. with the following command `docker run -p 5432:5432 --name bael-postgre -e POSTGRES_PASSWORD=pass -e POSTGRES_DB=jdbc_authentication postgres:latest`) + * * the service up and running + * + */ +public class UserControllerLiveTest { + + private static final String PRINCIPAL_SVC_URL = "http://localhost:8082/principal"; + + @Test + public void givenExisting_whenRequestPrincipal_thenRetrieveData() throws Exception { + given().auth() + .preemptive() + .basic("user", "pass") + .when() + .get(PRINCIPAL_SVC_URL) + .then() + .statusCode(HttpStatus.OK.value()) + .and() + .body("authorities[0].authority", is("ROLE_USER")) + .body("principal.username", is("user")) + .body("name", is("user")); + } + +} diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/custom/Application.java b/spring-security-mvc-boot/src/main/java/org/baeldung/custom/Application.java deleted file mode 100644 index f932ac3066..0000000000 --- a/spring-security-mvc-boot/src/main/java/org/baeldung/custom/Application.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.baeldung.custom; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.Configuration; -import org.springframework.data.jpa.repository.config.EnableJpaRepositories; - -@SpringBootApplication -public class Application extends SpringBootServletInitializer { - public static void main(String[] args) { - SpringApplication.run(Application.class, args); - } -} diff --git a/spring-security-mvc-boot/src/main/resources/logback.xml b/spring-security-mvc-boot/src/main/resources/logback.xml deleted file mode 100644 index 7d900d8ea8..0000000000 --- a/spring-security-mvc-boot/src/main/resources/logback.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n - - - - - - - - \ No newline at end of file diff --git a/spring-security-mvc-boot/src/main/resources/templates/index.html b/spring-security-mvc-boot/src/main/resources/templates/index.html deleted file mode 100644 index 8e7394ad6a..0000000000 --- a/spring-security-mvc-boot/src/main/resources/templates/index.html +++ /dev/null @@ -1,21 +0,0 @@ - - - - -Spring Security Thymeleaf - - - - - -
    - Welcome -
    - - \ No newline at end of file diff --git a/spring-security-mvc-session/pom.xml b/spring-security-mvc-session/pom.xml deleted file mode 100644 index b55ce70517..0000000000 --- a/spring-security-mvc-session/pom.xml +++ /dev/null @@ -1,125 +0,0 @@ - - 4.0.0 - com.baeldung - spring-security-mvc-session - 0.1-SNAPSHOT - spring-security-mvc-session - war - - - parent-boot-2 - com.baeldung - 0.0.1-SNAPSHOT - ../parent-boot-2 - - - - - - - - org.springframework.boot - spring-boot-starter-security - - - org.springframework.security - spring-security-taglibs - - - - - org.springframework.boot - spring-boot-starter-web - - - org.apache.tomcat.embed - tomcat-embed-jasper - - - org.springframework.boot - spring-boot-starter-tomcat - - - - - - javax.servlet - javax.servlet-api - provided - - - - javax.servlet - jstl - runtime - - - - - - com.codahale.metrics - metrics-core - ${codahale.metrics.version} - - - - - org.springframework.boot - spring-boot-starter-test - test - - - - - - spring-security-mvc-session - - - src/main/resources - true - - - - - - - org.apache.maven.plugins - maven-war-plugin - ${maven-war-plugin.version} - - - - org.codehaus.cargo - cargo-maven2-plugin - ${cargo-maven2-plugin.version} - - true - - jetty8x - embedded - - - - - - - 8082 - - - - - - - - - - - - 3.0.2 - - - 1.6.1 - - - \ No newline at end of file diff --git a/spring-security-mvc-session/src/main/java/org/baeldung/spring/MvcConfig.java b/spring-security-mvc-session/src/main/java/org/baeldung/spring/MvcConfig.java deleted file mode 100644 index b9f50ded73..0000000000 --- a/spring-security-mvc-session/src/main/java/org/baeldung/spring/MvcConfig.java +++ /dev/null @@ -1,44 +0,0 @@ -package org.baeldung.spring; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.web.servlet.ViewResolver; -import org.springframework.web.servlet.config.annotation.EnableWebMvc; -import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; -import org.springframework.web.servlet.view.InternalResourceViewResolver; -import org.springframework.web.servlet.view.JstlView; - -@EnableWebMvc -@Configuration -public class MvcConfig implements WebMvcConfigurer { - - public MvcConfig() { - super(); - } - - // API - - @Override - public void addViewControllers(final ViewControllerRegistry registry) { - - registry.addViewController("/anonymous.html"); - - registry.addViewController("/login.html"); - registry.addViewController("/homepage.html"); - registry.addViewController("/sessionExpired.html"); - registry.addViewController("/invalidExpired.html"); - registry.addViewController("/console.html"); - } - - @Bean - public ViewResolver viewResolver() { - final InternalResourceViewResolver bean = new InternalResourceViewResolver(); - - bean.setViewClass(JstlView.class); - bean.setPrefix("/WEB-INF/view/"); - bean.setSuffix(".jsp"); - - return bean; - } -} \ No newline at end of file diff --git a/spring-security-mvc-session/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-security-mvc-session/src/test/java/org/baeldung/SpringContextIntegrationTest.java deleted file mode 100644 index 9e74e83a53..0000000000 --- a/spring-security-mvc-session/src/test/java/org/baeldung/SpringContextIntegrationTest.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.baeldung; - -import org.baeldung.spring.MvcConfig; -import org.baeldung.spring.SecSecurityConfig; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.test.context.web.WebAppConfiguration; - -@RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(classes = { MvcConfig.class, SecSecurityConfig.class }) -@WebAppConfiguration -public class SpringContextIntegrationTest { - - @Test - public void whenSpringContextIsBootstrapped_thenNoExceptions() { - } -} diff --git a/spring-security-mvc-session/src/test/java/org/baeldung/SpringContextTest.java b/spring-security-mvc-session/src/test/java/org/baeldung/SpringContextTest.java deleted file mode 100644 index 5ee80d856a..0000000000 --- a/spring-security-mvc-session/src/test/java/org/baeldung/SpringContextTest.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.baeldung; - -import org.baeldung.spring.MvcConfig; -import org.baeldung.spring.SecSecurityConfig; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.test.context.web.WebAppConfiguration; - -@RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(classes = { MvcConfig.class, SecSecurityConfig.class }) -@WebAppConfiguration -public class SpringContextTest { - - @Test - public void whenSpringContextIsBootstrapped_thenNoExceptions() { - } -} diff --git a/spring-security-mvc/.gitignore b/spring-security-mvc/.gitignore new file mode 100644 index 0000000000..83c05e60c8 --- /dev/null +++ b/spring-security-mvc/.gitignore @@ -0,0 +1,13 @@ +*.class + +#folders# +/target +/neoDb* +/data +/src/main/webapp/WEB-INF/classes +*/META-INF/* + +# Packaged files # +*.jar +*.war +*.ear \ No newline at end of file diff --git a/spring-security-mvc-session/README.md b/spring-security-mvc/README.md similarity index 100% rename from spring-security-mvc-session/README.md rename to spring-security-mvc/README.md diff --git a/spring-security-mvc/pom.xml b/spring-security-mvc/pom.xml new file mode 100644 index 0000000000..98ad3daa46 --- /dev/null +++ b/spring-security-mvc/pom.xml @@ -0,0 +1,84 @@ + + 4.0.0 + com.baeldung + spring-security-mvc + 0.1-SNAPSHOT + spring-security-mvc + jar + + + com.baeldung + parent-boot-2 + 0.0.1-SNAPSHOT + ../parent-boot-2 + + + + + + + + org.springframework.boot + spring-boot-starter-security + + + org.springframework.security + spring-security-taglibs + + + + + org.springframework.boot + spring-boot-starter-web + + + org.apache.tomcat.embed + tomcat-embed-jasper + provided + + + org.springframework.boot + spring-boot-starter-tomcat + + + + javax.servlet + jstl + runtime + + + + + io.dropwizard.metrics + metrics-core + + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.security + spring-security-test + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + com.baeldung.SpringSessionApplication + JAR + + + + + + diff --git a/spring-security-mvc-session/src/main/java/org/baeldung/SpringSessionApplication.java b/spring-security-mvc/src/main/java/com/baeldung/SpringSessionApplication.java similarity index 93% rename from spring-security-mvc-session/src/main/java/org/baeldung/SpringSessionApplication.java rename to spring-security-mvc/src/main/java/com/baeldung/SpringSessionApplication.java index 9e52f0430a..c2a4b35df0 100644 --- a/spring-security-mvc-session/src/main/java/org/baeldung/SpringSessionApplication.java +++ b/spring-security-mvc/src/main/java/com/baeldung/SpringSessionApplication.java @@ -1,4 +1,4 @@ -package org.baeldung; +package com.baeldung; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; diff --git a/spring-security-mvc-session/src/main/java/org/baeldung/monitoring/MetricRegistrySingleton.java b/spring-security-mvc/src/main/java/com/baeldung/monitoring/MetricRegistrySingleton.java similarity index 95% rename from spring-security-mvc-session/src/main/java/org/baeldung/monitoring/MetricRegistrySingleton.java rename to spring-security-mvc/src/main/java/com/baeldung/monitoring/MetricRegistrySingleton.java index ed253305ed..e2224996c2 100644 --- a/spring-security-mvc-session/src/main/java/org/baeldung/monitoring/MetricRegistrySingleton.java +++ b/spring-security-mvc/src/main/java/com/baeldung/monitoring/MetricRegistrySingleton.java @@ -1,4 +1,4 @@ -package org.baeldung.monitoring; +package com.baeldung.monitoring; import java.util.concurrent.TimeUnit; diff --git a/spring-security-mvc-session/src/main/java/org/baeldung/security/MySimpleUrlAuthenticationSuccessHandler.java b/spring-security-mvc/src/main/java/com/baeldung/security/MySimpleUrlAuthenticationSuccessHandler.java similarity index 99% rename from spring-security-mvc-session/src/main/java/org/baeldung/security/MySimpleUrlAuthenticationSuccessHandler.java rename to spring-security-mvc/src/main/java/com/baeldung/security/MySimpleUrlAuthenticationSuccessHandler.java index 19f49ea59d..9d4fc19098 100644 --- a/spring-security-mvc-session/src/main/java/org/baeldung/security/MySimpleUrlAuthenticationSuccessHandler.java +++ b/spring-security-mvc/src/main/java/com/baeldung/security/MySimpleUrlAuthenticationSuccessHandler.java @@ -1,4 +1,4 @@ -package org.baeldung.security; +package com.baeldung.security; import java.io.IOException; import java.util.Collection; diff --git a/spring-security-mvc-session/src/main/java/org/baeldung/security/SessionFilter.java b/spring-security-mvc/src/main/java/com/baeldung/security/SessionFilter.java similarity index 97% rename from spring-security-mvc-session/src/main/java/org/baeldung/security/SessionFilter.java rename to spring-security-mvc/src/main/java/com/baeldung/security/SessionFilter.java index d37d46e478..f4f876af9c 100644 --- a/spring-security-mvc-session/src/main/java/org/baeldung/security/SessionFilter.java +++ b/spring-security-mvc/src/main/java/com/baeldung/security/SessionFilter.java @@ -1,4 +1,4 @@ -package org.baeldung.security; +package com.baeldung.security; import java.io.IOException; import java.util.Arrays; diff --git a/spring-security-mvc/src/main/java/com/baeldung/spring/MvcConfig.java b/spring-security-mvc/src/main/java/com/baeldung/spring/MvcConfig.java new file mode 100644 index 0000000000..38a4f3f81b --- /dev/null +++ b/spring-security-mvc/src/main/java/com/baeldung/spring/MvcConfig.java @@ -0,0 +1,33 @@ +package com.baeldung.spring; + +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +@Configuration +public class MvcConfig implements WebMvcConfigurer { + + @Override + public void addViewControllers(final ViewControllerRegistry registry) { + registry.addViewController("/anonymous.html"); + + registry.addViewController("/login.html"); + registry.addViewController("/homepage.html"); + registry.addViewController("/sessionExpired.html"); + registry.addViewController("/invalidSession.html"); + registry.addViewController("/console.html"); + } + + + /* + * Spring Boot supports configuring a ViewResolver with properties + */ +// @Bean +// public ViewResolver viewResolver() { +// final InternalResourceViewResolver bean = new InternalResourceViewResolver(); +// +// bean.setViewClass(JstlView.class); +// bean.setPrefix("/WEB-INF/view/"); +// bean.setSuffix(".jsp"); +// } +} diff --git a/spring-security-mvc-session/src/main/java/org/baeldung/spring/SecSecurityConfig.java b/spring-security-mvc/src/main/java/com/baeldung/spring/SecSecurityConfig.java similarity index 91% rename from spring-security-mvc-session/src/main/java/org/baeldung/spring/SecSecurityConfig.java rename to spring-security-mvc/src/main/java/com/baeldung/spring/SecSecurityConfig.java index b7996ebf18..a922ba6f7f 100644 --- a/spring-security-mvc-session/src/main/java/org/baeldung/spring/SecSecurityConfig.java +++ b/spring-security-mvc/src/main/java/com/baeldung/spring/SecSecurityConfig.java @@ -1,11 +1,9 @@ -package org.baeldung.spring; +package com.baeldung.spring; -import org.baeldung.security.MySimpleUrlAuthenticationSuccessHandler; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; @@ -13,9 +11,10 @@ import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.authentication.AuthenticationSuccessHandler; import org.springframework.security.web.session.HttpSessionEventPublisher; +import com.baeldung.security.MySimpleUrlAuthenticationSuccessHandler; + @Configuration // @ImportResource({ "classpath:webSecurityConfig.xml" }) -@EnableWebSecurity public class SecSecurityConfig extends WebSecurityConfigurerAdapter { public SecSecurityConfig() { @@ -39,7 +38,7 @@ public class SecSecurityConfig extends WebSecurityConfigurerAdapter { .csrf().disable() .authorizeRequests() .antMatchers("/anonymous*").anonymous() - .antMatchers("/login*").permitAll() + .antMatchers("/login*","/invalidSession*", "/sessionExpired*").permitAll() .anyRequest().authenticated() .and() .formLogin() @@ -70,7 +69,7 @@ public class SecSecurityConfig extends WebSecurityConfigurerAdapter { public HttpSessionEventPublisher httpSessionEventPublisher() { return new HttpSessionEventPublisher(); } - + @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); diff --git a/spring-security-mvc-session/src/main/java/org/baeldung/web/SessionListenerWithMetrics.java b/spring-security-mvc/src/main/java/com/baeldung/web/SessionListenerWithMetrics.java similarity index 92% rename from spring-security-mvc-session/src/main/java/org/baeldung/web/SessionListenerWithMetrics.java rename to spring-security-mvc/src/main/java/com/baeldung/web/SessionListenerWithMetrics.java index 46bf2708f7..fb1a81744e 100644 --- a/spring-security-mvc-session/src/main/java/org/baeldung/web/SessionListenerWithMetrics.java +++ b/spring-security-mvc/src/main/java/com/baeldung/web/SessionListenerWithMetrics.java @@ -1,12 +1,11 @@ -package org.baeldung.web; +package com.baeldung.web; import java.util.concurrent.atomic.AtomicInteger; import javax.servlet.http.HttpSessionEvent; import javax.servlet.http.HttpSessionListener; -import org.baeldung.monitoring.MetricRegistrySingleton; - +import com.baeldung.monitoring.MetricRegistrySingleton; import com.codahale.metrics.Counter; public class SessionListenerWithMetrics implements HttpSessionListener { diff --git a/spring-security-mvc/src/main/java/com/baeldung/web/SessionRestController.java b/spring-security-mvc/src/main/java/com/baeldung/web/SessionRestController.java new file mode 100644 index 0000000000..1353ee25d0 --- /dev/null +++ b/spring-security-mvc/src/main/java/com/baeldung/web/SessionRestController.java @@ -0,0 +1,17 @@ +package com.baeldung.web; + +import javax.servlet.http.HttpSession; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class SessionRestController { + + @GetMapping("/session-max-interval") + @ResponseBody + public String retrieveMaxSessionIncativeInterval(HttpSession session) { + return "Max Inactive Interval before Session expires: " + session.getMaxInactiveInterval(); + } +} diff --git a/spring-security-mvc/src/main/resources/application.properties b/spring-security-mvc/src/main/resources/application.properties new file mode 100644 index 0000000000..56b2b7b123 --- /dev/null +++ b/spring-security-mvc/src/main/resources/application.properties @@ -0,0 +1,8 @@ +server.servlet.session.timeout=65s + +spring.mvc.view.prefix=/WEB-INF/view/ +spring.mvc.view.suffix=.jsp + +## Secure Session Cookie configurations +#server.servlet.session.cookie.http-only=true +#server.servlet.session.cookie.secure=true \ No newline at end of file diff --git a/spring-security-mvc-session/src/main/resources/logback.xml b/spring-security-mvc/src/main/resources/logback.xml similarity index 100% rename from spring-security-mvc-session/src/main/resources/logback.xml rename to spring-security-mvc/src/main/resources/logback.xml diff --git a/spring-security-mvc-session/src/main/resources/webSecurityConfig.xml b/spring-security-mvc/src/main/resources/webSecurityConfig.xml similarity index 100% rename from spring-security-mvc-session/src/main/resources/webSecurityConfig.xml rename to spring-security-mvc/src/main/resources/webSecurityConfig.xml diff --git a/spring-security-mvc-session/src/main/webapp/WEB-INF/mvc-servlet.xml b/spring-security-mvc/src/main/webapp/WEB-INF/mvc-servlet.xml similarity index 100% rename from spring-security-mvc-session/src/main/webapp/WEB-INF/mvc-servlet.xml rename to spring-security-mvc/src/main/webapp/WEB-INF/mvc-servlet.xml diff --git a/spring-security-mvc-session/src/main/webapp/WEB-INF/view/anonymous.jsp b/spring-security-mvc/src/main/webapp/WEB-INF/view/anonymous.jsp similarity index 100% rename from spring-security-mvc-session/src/main/webapp/WEB-INF/view/anonymous.jsp rename to spring-security-mvc/src/main/webapp/WEB-INF/view/anonymous.jsp diff --git a/spring-security-mvc-session/src/main/webapp/WEB-INF/view/console.jsp b/spring-security-mvc/src/main/webapp/WEB-INF/view/console.jsp similarity index 100% rename from spring-security-mvc-session/src/main/webapp/WEB-INF/view/console.jsp rename to spring-security-mvc/src/main/webapp/WEB-INF/view/console.jsp diff --git a/spring-security-mvc-session/src/main/webapp/WEB-INF/view/homepage.jsp b/spring-security-mvc/src/main/webapp/WEB-INF/view/homepage.jsp similarity index 100% rename from spring-security-mvc-session/src/main/webapp/WEB-INF/view/homepage.jsp rename to spring-security-mvc/src/main/webapp/WEB-INF/view/homepage.jsp diff --git a/spring-security-mvc-session/src/main/webapp/WEB-INF/view/invalidSession.jsp b/spring-security-mvc/src/main/webapp/WEB-INF/view/invalidSession.jsp similarity index 100% rename from spring-security-mvc-session/src/main/webapp/WEB-INF/view/invalidSession.jsp rename to spring-security-mvc/src/main/webapp/WEB-INF/view/invalidSession.jsp diff --git a/spring-security-mvc-session/src/main/webapp/WEB-INF/view/login.jsp b/spring-security-mvc/src/main/webapp/WEB-INF/view/login.jsp similarity index 100% rename from spring-security-mvc-session/src/main/webapp/WEB-INF/view/login.jsp rename to spring-security-mvc/src/main/webapp/WEB-INF/view/login.jsp diff --git a/spring-security-mvc-session/src/main/webapp/WEB-INF/view/sessionExpired.jsp b/spring-security-mvc/src/main/webapp/WEB-INF/view/sessionExpired.jsp similarity index 100% rename from spring-security-mvc-session/src/main/webapp/WEB-INF/view/sessionExpired.jsp rename to spring-security-mvc/src/main/webapp/WEB-INF/view/sessionExpired.jsp diff --git a/spring-security-mvc-session/src/main/webapp/WEB-INF/web.xml b/spring-security-mvc/src/main/webapp/WEB-INF/web.xml similarity index 100% rename from spring-security-mvc-session/src/main/webapp/WEB-INF/web.xml rename to spring-security-mvc/src/main/webapp/WEB-INF/web.xml diff --git a/spring-security-client/spring-security-jsp-authorize/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-security-mvc/src/test/java/com/baeldung/SpringContextIntegrationTest.java similarity index 76% rename from spring-security-client/spring-security-jsp-authorize/src/test/java/org/baeldung/SpringContextIntegrationTest.java rename to spring-security-mvc/src/test/java/com/baeldung/SpringContextIntegrationTest.java index 66243ef00d..8e53a6371a 100644 --- a/spring-security-client/spring-security-jsp-authorize/src/test/java/org/baeldung/SpringContextIntegrationTest.java +++ b/spring-security-mvc/src/test/java/com/baeldung/SpringContextIntegrationTest.java @@ -1,13 +1,12 @@ -package org.baeldung; +package com.baeldung; -import org.baeldung.config.Application; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) -@SpringBootTest(classes = Application.class) +@SpringBootTest public class SpringContextIntegrationTest { @Test diff --git a/spring-security-mvc/src/test/java/com/baeldung/session/SessionConfigurationLiveTest.java b/spring-security-mvc/src/test/java/com/baeldung/session/SessionConfigurationLiveTest.java new file mode 100644 index 0000000000..7d9a03d5f6 --- /dev/null +++ b/spring-security-mvc/src/test/java/com/baeldung/session/SessionConfigurationLiveTest.java @@ -0,0 +1,92 @@ +package com.baeldung.session; + +import static io.restassured.RestAssured.given; +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.Optional; + +import org.junit.Test; +import org.springframework.http.HttpStatus; + +import io.restassured.filter.session.SessionFilter; +import io.restassured.response.Response; +import io.restassured.specification.RequestSpecification; + +/** + * This Live Test requires the service to be up and running. + */ +public class SessionConfigurationLiveTest { + + private static final String USER = "user1"; + private static final String PASSWORD = "user1Pass"; + private static final String SESSION_SVC_URL = "http://localhost:8080/session-max-interval"; + + @Test + public void givenValidUser_whenRequestResourceAfterSessionExpiration_thenRedirectedToInvalidSessionUri() throws Exception { + SessionFilter sessionFilter = new SessionFilter(); + simpleSvcRequestLoggingIn(sessionFilter); + Response resp2 = simpleResponseRequestUsingSessionNotFollowingRedirects(sessionFilter); + assertThat(resp2.getStatusCode()).isEqualTo(HttpStatus.OK.value()); + assertThat(resp2.getBody() + .asString()).isEqualTo("Max Inactive Interval before Session expires: 60"); + + // session will be expired in 60 seconds... + Thread.sleep(62000); + Response resp3 = simpleResponseRequestUsingSessionNotFollowingRedirects(sessionFilter); + + assertThat(resp3.getStatusCode()).isEqualTo(HttpStatus.FOUND.value()); + assertThat(resp3.getHeader("Location")).isEqualTo("http://localhost:8080/invalidSession.html"); + } + + @Test + public void givenValidUser_whenLoginMoreThanMaxValidSession_thenRedirectedToExpiredSessionUri() throws Exception { + SessionFilter sessionFilter = new SessionFilter(); + simpleSvcRequestLoggingIn(sessionFilter); + simpleSvcRequestLoggingIn(); + + // this login will expire the first session + simpleSvcRequestLoggingIn(); + + // now try to access a resource using expired session + Response resp4 = given().filter(sessionFilter) + .and() + .redirects() + .follow(false) + .when() + .get(SESSION_SVC_URL); + + assertThat(resp4.getStatusCode()).isEqualTo(HttpStatus.FOUND.value()); + assertThat(resp4.getHeader("Location")).isEqualTo("http://localhost:8080/sessionExpired.html"); + } + + private static void simpleSvcRequestLoggingIn() { + simpleSvcRequestLoggingIn(null); + } + + private static void simpleSvcRequestLoggingIn(SessionFilter sessionFilter) { + Response response = simpleResponseSvcRequestLoggingIn(Optional.ofNullable(sessionFilter)); + + assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK.value()); + assertThat(response.getBody() + .asString()).isEqualTo("Max Inactive Interval before Session expires: 60"); + } + + private static Response simpleResponseSvcRequestLoggingIn(Optional sessionFilter) { + RequestSpecification spec = given().auth() + .form(USER, PASSWORD); + sessionFilter.ifPresent(filter -> spec.and() + .filter(filter)); + return spec.when() + .get(SESSION_SVC_URL); + } + + private static Response simpleResponseRequestUsingSessionNotFollowingRedirects(SessionFilter sessionFilter) { + return given().filter(sessionFilter) + .and() + .redirects() + .follow(false) + .when() + .get(SESSION_SVC_URL); + } + +} diff --git a/spring-security-mvc/src/test/resources/.gitignore b/spring-security-mvc/src/test/resources/.gitignore new file mode 100644 index 0000000000..83c05e60c8 --- /dev/null +++ b/spring-security-mvc/src/test/resources/.gitignore @@ -0,0 +1,13 @@ +*.class + +#folders# +/target +/neoDb* +/data +/src/main/webapp/WEB-INF/classes +*/META-INF/* + +# Packaged files # +*.jar +*.war +*.ear \ No newline at end of file diff --git a/spring-security-rest-basic-auth/pom.xml b/spring-security-rest-basic-auth/pom.xml index 78bab83db5..143c61ae76 100644 --- a/spring-security-rest-basic-auth/pom.xml +++ b/spring-security-rest-basic-auth/pom.xml @@ -22,12 +22,12 @@ org.springframework.security spring-security-web - ${spring.version} + ${spring-security.version} org.springframework.security spring-security-config - ${spring.version} + ${spring-security.version} diff --git a/spring-session/spring-session-mongodb/src/test/java/org/baeldung/SpringContextTest.java b/spring-session/spring-session-mongodb/src/test/java/org/baeldung/SpringContextLiveTest.java similarity index 92% rename from spring-session/spring-session-mongodb/src/test/java/org/baeldung/SpringContextTest.java rename to spring-session/spring-session-mongodb/src/test/java/org/baeldung/SpringContextLiveTest.java index 307d31a809..b41f2b0338 100644 --- a/spring-session/spring-session-mongodb/src/test/java/org/baeldung/SpringContextTest.java +++ b/spring-session/spring-session-mongodb/src/test/java/org/baeldung/SpringContextLiveTest.java @@ -8,7 +8,7 @@ import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest(classes = SpringSessionMongoDBApplication.class) -public class SpringContextTest { +public class SpringContextLiveTest { @Test public void whenSpringContextIsBootstrapped_thenNoExceptions() { diff --git a/spring-session/spring-session-redis/src/test/java/org/baeldung/SpringContextTest.java b/spring-session/spring-session-redis/src/test/java/org/baeldung/SpringContextLiveTest.java similarity index 92% rename from spring-session/spring-session-redis/src/test/java/org/baeldung/SpringContextTest.java rename to spring-session/spring-session-redis/src/test/java/org/baeldung/SpringContextLiveTest.java index 994f93c24f..b23ce7dbbb 100644 --- a/spring-session/spring-session-redis/src/test/java/org/baeldung/SpringContextTest.java +++ b/spring-session/spring-session-redis/src/test/java/org/baeldung/SpringContextLiveTest.java @@ -9,7 +9,7 @@ import com.baeldung.spring.session.SessionWebApplication; @RunWith(SpringRunner.class) @SpringBootTest(classes = SessionWebApplication.class) -public class SpringContextTest { +public class SpringContextLiveTest { @Test public void whenSpringContextIsBootstrapped_thenNoExceptions() { diff --git a/spring-thymeleaf-2/README.md b/spring-thymeleaf-2/README.md new file mode 100644 index 0000000000..9e12f2d99f --- /dev/null +++ b/spring-thymeleaf-2/README.md @@ -0,0 +1,4 @@ +## Relevant Articles: + +- [Working with Enums in Thymeleaf](https://www.baeldung.com/thymeleaf-enums) +- [Changing the Thymeleaf Template Directory in Spring Boot](https://www.baeldung.com/spring-thymeleaf-template-directory) diff --git a/spring-thymeleaf-2/pom.xml b/spring-thymeleaf-2/pom.xml index 1b95cac43c..d31e5fa7f6 100644 --- a/spring-thymeleaf-2/pom.xml +++ b/spring-thymeleaf-2/pom.xml @@ -21,6 +21,12 @@ org.springframework.boot spring-boot-starter-thymeleaf
    + + + org.springframework.boot + spring-boot-starter-test + test +
    diff --git a/spring-thymeleaf-2/src/main/java/com/baeldung/thymeleaf/ThymeleafConfig.java b/spring-thymeleaf-2/src/main/java/com/baeldung/thymeleaf/ThymeleafConfig.java new file mode 100644 index 0000000000..2fd11628ad --- /dev/null +++ b/spring-thymeleaf-2/src/main/java/com/baeldung/thymeleaf/ThymeleafConfig.java @@ -0,0 +1,23 @@ +package com.baeldung.thymeleaf; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.thymeleaf.templatemode.TemplateMode; +import org.thymeleaf.templateresolver.ClassLoaderTemplateResolver; + +@Configuration +public class ThymeleafConfig { + + @Bean + public ClassLoaderTemplateResolver secondaryTemplateResolver() { + ClassLoaderTemplateResolver secondaryTemplateResolver = new ClassLoaderTemplateResolver(); + secondaryTemplateResolver.setPrefix("templates-2/"); + secondaryTemplateResolver.setSuffix(".html"); + secondaryTemplateResolver.setTemplateMode(TemplateMode.HTML); + secondaryTemplateResolver.setCharacterEncoding("UTF-8"); + secondaryTemplateResolver.setOrder(1); + secondaryTemplateResolver.setCheckExistence(true); + + return secondaryTemplateResolver; + } +} diff --git a/spring-thymeleaf-2/src/main/java/com/baeldung/thymeleaf/lists/ListsController.java b/spring-thymeleaf-2/src/main/java/com/baeldung/thymeleaf/lists/ListsController.java new file mode 100644 index 0000000000..55a7f7c38e --- /dev/null +++ b/spring-thymeleaf-2/src/main/java/com/baeldung/thymeleaf/lists/ListsController.java @@ -0,0 +1,64 @@ +package com.baeldung.thymeleaf.lists; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; + +@Controller +@RequestMapping("/lists") +public class ListsController { + + @GetMapping("/toList") + public String usingToList(Model model) { + List colors = getColors(); + String[] colorsArray = colors.toArray(new String[0]); + model.addAttribute("myArray", colorsArray); + return "lists/toList"; + } + + @GetMapping("/contains") + public String usingContains(Model model) { + model.addAttribute("myList", getColors()); + model.addAttribute("others", getOtherColors()); + return "lists/contains"; + } + + @GetMapping("/size") + public String usingSize(Model model) { + model.addAttribute("myList", getColors()); + return "lists/size"; + } + + @GetMapping("/isEmpty") + public String usingIsEmpty(Model model) { + model.addAttribute("myList", getColors()); + return "lists/isEmpty"; + } + + @GetMapping("/sort") + public String usingSort(Model model) { + model.addAttribute("myList", getColors()); + model.addAttribute("reverse", Comparator.reverseOrder()); + return "lists/sort"; + } + + private List getColors() { + List colors = new ArrayList<>(); + colors.add("green"); + colors.add("yellow"); + colors.add("red"); + colors.add("blue"); + return colors; + } + + private List getOtherColors() { + List colors = new ArrayList<>(); + colors.add("green"); + colors.add("blue"); + return colors; + } +} diff --git a/spring-thymeleaf-2/src/main/java/com/baeldung/thymeleaf/templatedir/HelloController.java b/spring-thymeleaf-2/src/main/java/com/baeldung/thymeleaf/templatedir/HelloController.java new file mode 100644 index 0000000000..b404418106 --- /dev/null +++ b/spring-thymeleaf-2/src/main/java/com/baeldung/thymeleaf/templatedir/HelloController.java @@ -0,0 +1,13 @@ +package com.baeldung.thymeleaf.templatedir; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; + +@Controller +public class HelloController { + + @GetMapping("/hello") + public String sayHello() { + return "hello"; + } +} diff --git a/spring-thymeleaf-2/src/main/resources/application.properties b/spring-thymeleaf-2/src/main/resources/application.properties new file mode 100644 index 0000000000..b09232bb1b --- /dev/null +++ b/spring-thymeleaf-2/src/main/resources/application.properties @@ -0,0 +1 @@ +#spring.thymeleaf.prefix=classpath:/templates-2/ \ No newline at end of file diff --git a/spring-thymeleaf-2/src/main/resources/templates-2/hello.html b/spring-thymeleaf-2/src/main/resources/templates-2/hello.html new file mode 100644 index 0000000000..035904c8ba --- /dev/null +++ b/spring-thymeleaf-2/src/main/resources/templates-2/hello.html @@ -0,0 +1,10 @@ + + + + +Enums in Thymeleaf + + +

    Hello from 'templates/templates-2'

    + + \ No newline at end of file diff --git a/spring-thymeleaf-2/src/main/resources/templates/lists/contains.html b/spring-thymeleaf-2/src/main/resources/templates/lists/contains.html new file mode 100644 index 0000000000..2d874791d7 --- /dev/null +++ b/spring-thymeleaf-2/src/main/resources/templates/lists/contains.html @@ -0,0 +1,12 @@ + + + + + Lists Utility Class in Thymeleaf + + +myList contains red: + +myList contains red and green: + + diff --git a/spring-thymeleaf-2/src/main/resources/templates/lists/isEmpty.html b/spring-thymeleaf-2/src/main/resources/templates/lists/isEmpty.html new file mode 100644 index 0000000000..06c66153c7 --- /dev/null +++ b/spring-thymeleaf-2/src/main/resources/templates/lists/isEmpty.html @@ -0,0 +1,14 @@ + + + + + Lists Utility Class in Thymeleaf + + + +isEmpty Check : + +List is not empty + + + \ No newline at end of file diff --git a/spring-thymeleaf-2/src/main/resources/templates/lists/size.html b/spring-thymeleaf-2/src/main/resources/templates/lists/size.html new file mode 100644 index 0000000000..594ff08467 --- /dev/null +++ b/spring-thymeleaf-2/src/main/resources/templates/lists/size.html @@ -0,0 +1,12 @@ + + + + + Lists Utility Class in Thymeleaf + + + +size: + + + \ No newline at end of file diff --git a/spring-thymeleaf-2/src/main/resources/templates/lists/sort.html b/spring-thymeleaf-2/src/main/resources/templates/lists/sort.html new file mode 100644 index 0000000000..e23c7bccbb --- /dev/null +++ b/spring-thymeleaf-2/src/main/resources/templates/lists/sort.html @@ -0,0 +1,12 @@ + + + + + Lists Utility Class in Thymeleaf + + +sort: + +sort with Comparator: + + \ No newline at end of file diff --git a/spring-thymeleaf-2/src/main/resources/templates/lists/toList.html b/spring-thymeleaf-2/src/main/resources/templates/lists/toList.html new file mode 100644 index 0000000000..680c13160e --- /dev/null +++ b/spring-thymeleaf-2/src/main/resources/templates/lists/toList.html @@ -0,0 +1,14 @@ + + + + + Lists Utility Class in Thymeleaf + + + + + converted list size: + + + + \ No newline at end of file diff --git a/spring-thymeleaf-2/src/test/java/com/baeldung/thymeleaf/lists/ListsControllerIntegrationTest.java b/spring-thymeleaf-2/src/test/java/com/baeldung/thymeleaf/lists/ListsControllerIntegrationTest.java new file mode 100644 index 0000000000..252ec3bef3 --- /dev/null +++ b/spring-thymeleaf-2/src/test/java/com/baeldung/thymeleaf/lists/ListsControllerIntegrationTest.java @@ -0,0 +1,60 @@ +package com.baeldung.thymeleaf.lists; + +import static org.hamcrest.CoreMatchers.containsString; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; + +@RunWith(SpringRunner.class) +@SpringBootTest +@AutoConfigureMockMvc(printOnlyOnFailure = false) +public class ListsControllerIntegrationTest { + + @Autowired + private MockMvc mockMvc; + + @Test + public void whenCalledToList_ThenConvertsToList() throws Exception { + mockMvc.perform(MockMvcRequestBuilders.get("/lists/toList")) + .andExpect(status().isOk()) + .andExpect(content().string(containsString("converted list size: 4"))); + } + + @Test + public void whenCalledContains_ThenChecksMembership() throws Exception { + mockMvc.perform(MockMvcRequestBuilders.get("/lists/contains")) + .andExpect(status().isOk()) + .andExpect(content().string(containsString("myList contains red: true"))) + .andExpect(content().string(containsString("myList contains red and green: true"))); + } + + @Test + public void whenCalledSize_ThenReturnsSize() throws Exception { + mockMvc.perform(MockMvcRequestBuilders.get("/lists/size")) + .andExpect(status().isOk()) + .andExpect(content().string(containsString("size: 4"))); + } + + @Test + public void whenCalledSort_ThenSortsItems() throws Exception { + mockMvc.perform(MockMvcRequestBuilders.get("/lists/sort")) + .andExpect(status().isOk()) + .andExpect(content().string(containsString("sort: [blue, green, red, yellow]"))) + .andExpect(content().string(containsString("sort with Comparator: [yellow, red, green, blue]"))); + } + + @Test + public void whenCalledIsEmpty_ThenChecksAnyMembers() throws Exception { + mockMvc.perform(MockMvcRequestBuilders.get("/lists/isEmpty")) + .andExpect(status().isOk()) + .andExpect(content().string(containsString("isEmpty Check : false"))); + } +} \ No newline at end of file diff --git a/spring-thymeleaf/README.md b/spring-thymeleaf/README.md index b6824003db..082a65f55b 100644 --- a/spring-thymeleaf/README.md +++ b/spring-thymeleaf/README.md @@ -18,6 +18,7 @@ - [Spring with Thymeleaf Pagination for a List](http://www.baeldung.com/spring-thymeleaf-pagination) - [Working with Select and Option in Thymeleaf](http://www.baeldung.com/thymeleaf-select-option) - [Working With Custom HTML Attributes in Thymeleaf](https://www.baeldung.com/thymeleaf-custom-html-attributes) +- [Spring Request Parameters with Thymeleaf](https://www.baeldung.com/spring-thymeleaf-request-parameters) ### Build the Project diff --git a/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/controller/ParticipantController.java b/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/controller/ParticipantController.java new file mode 100644 index 0000000000..eebe37e000 --- /dev/null +++ b/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/controller/ParticipantController.java @@ -0,0 +1,28 @@ +package com.example.demo; + +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; + +import java.util.List; + +import static java.util.Arrays.asList; + +@Controller +public class ParticipantController { + + @RequestMapping("/") + public String index( + @RequestParam(value = "participant", required = false) String participant, + @RequestParam(value = "country", required = false) String country, + @RequestParam(value = "action", required = false) String action, + @RequestParam(value = "id", required = false) Integer id, + Model model + ) { + model.addAttribute("id", id); + List userIds = asList(1,2,3,4); + model.addAttribute("userIds", userIds); + return "participants"; + } +} diff --git a/spring-thymeleaf/src/main/resources/templates/participants.html b/spring-thymeleaf/src/main/resources/templates/participants.html new file mode 100644 index 0000000000..8d4e552093 --- /dev/null +++ b/spring-thymeleaf/src/main/resources/templates/participants.html @@ -0,0 +1,32 @@ + + + + + +

    Enter participant

    +
    + + + + + +
    + + +

    User Details

    +

    Details for user [[${id}]] ...

    +
    + +

    Users

    + +

    + User [[${userId}]] +

    +
    + + diff --git a/spring-userservice/src/test/java/org/baeldung/SpringContextTest.java b/spring-userservice/src/test/java/org/baeldung/SpringContextTest.java deleted file mode 100644 index 2853a955fa..0000000000 --- a/spring-userservice/src/test/java/org/baeldung/SpringContextTest.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.baeldung; - -import org.baeldung.custom.config.MvcConfig; -import org.baeldung.custom.config.PersistenceDerbyJPAConfig; -import org.baeldung.custom.config.SecSecurityConfig; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringRunner; - -@RunWith(SpringRunner.class) -@SpringBootTest(classes = { MvcConfig.class, PersistenceDerbyJPAConfig.class, SecSecurityConfig.class }) -public class SpringContextTest { - - @Test - public void whenSpringContextIsBootstrapped_thenNoExceptions() { - } -} diff --git a/spring-vault/src/test/java/org/baeldung/SpringContextTest.java b/spring-vault/src/test/java/org/baeldung/SpringContextLiveTest.java similarity index 92% rename from spring-vault/src/test/java/org/baeldung/SpringContextTest.java rename to spring-vault/src/test/java/org/baeldung/SpringContextLiveTest.java index 95abe622fa..1b3db59ecb 100644 --- a/spring-vault/src/test/java/org/baeldung/SpringContextTest.java +++ b/spring-vault/src/test/java/org/baeldung/SpringContextLiveTest.java @@ -8,7 +8,7 @@ import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest(classes = SpringVaultApplication.class) -public class SpringContextTest { +public class SpringContextLiveTest { @Test public void whenSpringContextIsBootstrapped_thenNoExceptions() { diff --git a/spring-webflux-amqp/src/test/java/org/baeldung/SpringContextTest.java b/spring-webflux-amqp/src/test/java/org/baeldung/SpringContextLiveTest.java similarity index 92% rename from spring-webflux-amqp/src/test/java/org/baeldung/SpringContextTest.java rename to spring-webflux-amqp/src/test/java/org/baeldung/SpringContextLiveTest.java index 88d29d5ac0..effe8d2cfa 100644 --- a/spring-webflux-amqp/src/test/java/org/baeldung/SpringContextTest.java +++ b/spring-webflux-amqp/src/test/java/org/baeldung/SpringContextLiveTest.java @@ -8,7 +8,7 @@ import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest(classes = SpringWebfluxAmqpApplication.class) -public class SpringContextTest { +public class SpringContextLiveTest { @Test public void whenSpringContextIsBootstrapped_thenNoExceptions() { diff --git a/testing-modules/README.md b/testing-modules/README.md index b269f547ec..d534e5cea6 100644 --- a/testing-modules/README.md +++ b/testing-modules/README.md @@ -1,15 +1,5 @@ ## Testing Modules -### Relevant Articles: +This is a aggregator module containing several modules focused on testing libraries. -- [Quick Guide to BDDMockito](http://www.baeldung.com/bdd-mockito) -- [AssertJ Exception Assertions](http://www.baeldung.com/assertj-exception-assertion) -- [Using Hamcrest Number Matchers](http://www.baeldung.com/hamcrest-number-matchers) -- [Assertions in JUnit 4 and JUnit 5](http://www.baeldung.com/junit-assertions) -- [REST-assured with Groovy](http://www.baeldung.com/rest-assured-groovy) -- [Hamcrest Bean Matchers](http://www.baeldung.com/hamcrest-bean-matchers) -- [Hamcrest Object Matchers](http://www.baeldung.com/hamcrest-object-matchers) -- [Headers, Cookies and Parameters with REST-assured](http://www.baeldung.com/rest-assured-header-cookie-parameter) -- [JSON Schema Validation with REST-assured](http://www.baeldung.com/rest-assured-json-schema) -- [Testing Callbacks with Mockito](http://www.baeldung.com/mockito-callbacks) diff --git a/testing-modules/easy-random/README.md b/testing-modules/easy-random/README.md new file mode 100644 index 0000000000..117d636bcc --- /dev/null +++ b/testing-modules/easy-random/README.md @@ -0,0 +1,3 @@ +## Relevant Articles: + +- [Quick Guide to EasyRandom in Java](https://www.baeldung.com/java-easy-random) diff --git a/testing-modules/junit-5-advanced/README.md b/testing-modules/junit-5-advanced/README.md index 7282a4efad..61a65b2e5a 100644 --- a/testing-modules/junit-5-advanced/README.md +++ b/testing-modules/junit-5-advanced/README.md @@ -1,3 +1,4 @@ -### Relevant Articles +## Relevant Articles: - [JUnit 5 TestWatcher API](https://www.baeldung.com/junit-testwatcher) +- [JUnit Custom Display Name Generator API](https://www.baeldung.com/junit-custom-display-name-generator) diff --git a/testing-modules/junit-5-advanced/pom.xml b/testing-modules/junit-5-advanced/pom.xml index f65f7e2a2f..bc879ebfc3 100644 --- a/testing-modules/junit-5-advanced/pom.xml +++ b/testing-modules/junit-5-advanced/pom.xml @@ -1,32 +1,52 @@ - 4.0.0 - junit-5-advanced - 1.0-SNAPSHOT - junit-5-advanced - Advanced JUnit 5 Topics + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 + junit-5-advanced + 1.0-SNAPSHOT + junit-5-advanced + Advanced JUnit 5 Topics - - com.baeldung - parent-modules - 1.0.0-SNAPSHOT - ../../ - + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + ../../ + - - - org.junit.jupiter - junit-jupiter - ${junit-jupiter.version} - test - - - - - 5.4.2 - 2.21.0 - + + + org.junit.jupiter + junit-jupiter + ${junit-jupiter.version} + test + + + org.junit.jupiter + junit-jupiter-engine + ${junit-jupiter.version} + + + org.junit.vintage + junit-vintage-engine + ${junit.vintage.version} + test + + + + + + + maven-surefire-plugin + ${maven-surefire-plugin.version} + + + + + 5.4.2 + 2.21.0 + 5.4.2 + diff --git a/testing-modules/junit-5-advanced/src/main/java/com/baeldung/junit5/testinstance/Tweet.java b/testing-modules/junit-5-advanced/src/main/java/com/baeldung/junit5/testinstance/Tweet.java new file mode 100644 index 0000000000..dac023697a --- /dev/null +++ b/testing-modules/junit-5-advanced/src/main/java/com/baeldung/junit5/testinstance/Tweet.java @@ -0,0 +1,27 @@ +package com.baeldung.junit5.testinstance; + +import java.io.Serializable; + +public class Tweet implements Serializable { + + private static final long serialVersionUID = 1L; + private String id; + private String content; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + +} diff --git a/testing-modules/junit-5-advanced/src/main/java/com/baeldung/junit5/testinstance/TweetException.java b/testing-modules/junit-5-advanced/src/main/java/com/baeldung/junit5/testinstance/TweetException.java new file mode 100644 index 0000000000..920f996b59 --- /dev/null +++ b/testing-modules/junit-5-advanced/src/main/java/com/baeldung/junit5/testinstance/TweetException.java @@ -0,0 +1,10 @@ +package com.baeldung.junit5.testinstance; + +public class TweetException extends RuntimeException { + + private static final long serialVersionUID = 1L; + + public TweetException(String message) { + super(message); + } +} diff --git a/testing-modules/junit-5-advanced/src/main/java/com/baeldung/junit5/testinstance/TweetSerializer.java b/testing-modules/junit-5-advanced/src/main/java/com/baeldung/junit5/testinstance/TweetSerializer.java new file mode 100644 index 0000000000..734c06b9f5 --- /dev/null +++ b/testing-modules/junit-5-advanced/src/main/java/com/baeldung/junit5/testinstance/TweetSerializer.java @@ -0,0 +1,41 @@ +package com.baeldung.junit5.testinstance; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectOutputStream; + +public class TweetSerializer { + + private static final int MAX_TWEET_SIZE = 1000; + private static final int MIN_TWEET_SIZE = 150; + private final Tweet tweet; + + public TweetSerializer(Tweet tweet) { + this.tweet = tweet; + } + + public byte[] serialize() throws IOException { + byte[] tweetContent = serializeTweet(); + int totalLength = tweetContent.length; + validateSizeOfTweet(totalLength); + return tweetContent; + } + + private void validateSizeOfTweet(int tweetSize) { + if (tweetSize > MAX_TWEET_SIZE) { + throw new TweetException("Tweet is too large"); + } + if (tweetSize < MIN_TWEET_SIZE) { + throw new TweetException("Tweet is too small"); + } + } + + private byte[] serializeTweet() throws IOException { + try (ByteArrayOutputStream arrayOutputStream = new ByteArrayOutputStream(); + ObjectOutputStream objectStream = new ObjectOutputStream(arrayOutputStream)) { + objectStream.writeObject(tweet); + return arrayOutputStream.toByteArray(); + } + } + +} diff --git a/testing-modules/junit-5-advanced/src/test/java/com/baeldung/junit5/testinstance/AdditionUnitTest.java b/testing-modules/junit-5-advanced/src/test/java/com/baeldung/junit5/testinstance/AdditionUnitTest.java new file mode 100644 index 0000000000..430082dc28 --- /dev/null +++ b/testing-modules/junit-5-advanced/src/test/java/com/baeldung/junit5/testinstance/AdditionUnitTest.java @@ -0,0 +1,22 @@ +package com.baeldung.junit5.testinstance; + +import static org.junit.Assert.assertEquals; + +import org.junit.jupiter.api.Test; + +class AdditionUnitTest { + + private int sum = 1; + + @Test + void addingTwoToSumReturnsThree() { + sum += 2; + assertEquals(3, sum); + } + + @Test + void addingThreeToSumReturnsFour() { + sum += 3; + assertEquals(4, sum); + } +} diff --git a/testing-modules/junit-5-advanced/src/test/java/com/baeldung/junit5/testinstance/OrderUnitTest.java b/testing-modules/junit-5-advanced/src/test/java/com/baeldung/junit5/testinstance/OrderUnitTest.java new file mode 100644 index 0000000000..5907dd5654 --- /dev/null +++ b/testing-modules/junit-5-advanced/src/test/java/com/baeldung/junit5/testinstance/OrderUnitTest.java @@ -0,0 +1,38 @@ +package com.baeldung.junit5.testinstance; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.MethodOrderer.OrderAnnotation; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.api.TestInstance.Lifecycle; +import org.junit.jupiter.api.TestMethodOrder; + +@TestMethodOrder(OrderAnnotation.class) +@TestInstance(Lifecycle.PER_CLASS) +class OrderUnitTest { + + private int sum; + + @BeforeAll + void init() { + sum = 1; + } + + @Test + @Order(1) + void firstTest() { + sum += 2; + assertEquals(3, sum); + } + + @Test + @Order(2) + void secondTest() { + sum += 3; + assertEquals(6, sum); + } + +} diff --git a/testing-modules/junit-5-advanced/src/test/java/com/baeldung/junit5/testinstance/TweetSerializerJUnit4UnitTest.java b/testing-modules/junit-5-advanced/src/test/java/com/baeldung/junit5/testinstance/TweetSerializerJUnit4UnitTest.java new file mode 100644 index 0000000000..e8c4dae77d --- /dev/null +++ b/testing-modules/junit-5-advanced/src/test/java/com/baeldung/junit5/testinstance/TweetSerializerJUnit4UnitTest.java @@ -0,0 +1,62 @@ +package com.baeldung.junit5.testinstance; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.notNullValue; +import static org.junit.Assert.assertThat; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; + +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +public class TweetSerializerJUnit4UnitTest { + + private static String largeContent; + private static String content; + private static String smallContent; + + private static Tweet tweet; + + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + @BeforeClass + public static void setUpFixture() throws IOException { + content = "Lorem ipsum dolor sit amet, consectetur adipiscing elit"; + smallContent = "Lorem ipsum dolor"; + largeContent = new String(Files.readAllBytes(Paths.get("src/test/resources/lorem-ipsum.txt"))); + tweet = new Tweet(); + tweet.setId("AX1346"); + } + + @Test + public void serializerThrowsExceptionWhenMessageIsTooLarge() throws IOException { + tweet.setContent(largeContent); + + expectedException.expect(TweetException.class); + expectedException.expectMessage("Tweet is too large"); + + new TweetSerializer(tweet).serialize(); + } + + @Test + public void serializerThrowsExceptionWhenMessageIsTooSmall() throws IOException { + tweet.setContent(smallContent); + + expectedException.expect(TweetException.class); + expectedException.expectMessage("Tweet is too small"); + + new TweetSerializer(tweet).serialize(); + } + + @Test + public void serializeTweet() throws IOException { + tweet.setContent(content); + byte[] content = new TweetSerializer(tweet).serialize(); + assertThat(content, is(notNullValue())); + } +} diff --git a/testing-modules/junit-5-advanced/src/test/java/com/baeldung/junit5/testinstance/TweetSerializerUnitTest.java b/testing-modules/junit-5-advanced/src/test/java/com/baeldung/junit5/testinstance/TweetSerializerUnitTest.java new file mode 100644 index 0000000000..ddbea8b052 --- /dev/null +++ b/testing-modules/junit-5-advanced/src/test/java/com/baeldung/junit5/testinstance/TweetSerializerUnitTest.java @@ -0,0 +1,59 @@ +package com.baeldung.junit5.testinstance; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.notNullValue; +import static org.junit.Assert.assertThat; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.api.TestInstance.Lifecycle; + +@TestInstance(Lifecycle.PER_CLASS) +class TweetSerializerUnitTest { + + private String largeContent; + private String content; + private String smallContent; + + private Tweet tweet; + + @BeforeAll + void setUpFixture() throws IOException { + content = "Lorem ipsum dolor sit amet, consectetur adipiscing elit"; + smallContent = "Lorem ipsum dolor"; + largeContent = new String(Files.readAllBytes(Paths.get("src/test/resources/lorem-ipsum.txt"))); + tweet = new Tweet(); + tweet.setId("AX1346"); + } + + @Test + void serializerThrowsExceptionWhenMessageIsTooLarge() throws IOException { + tweet.setContent(largeContent); + + TweetException tweetException = assertThrows(TweetException.class, () -> new TweetSerializer(tweet).serialize()); + assertThat(tweetException.getMessage(), is(equalTo("Tweet is too large"))); + } + + @Test + void serializerThrowsExceptionWhenMessageIsTooSmall() throws IOException { + tweet.setContent(smallContent); + + TweetException tweetException = assertThrows(TweetException.class, () -> new TweetSerializer(tweet).serialize()); + assertThat(tweetException.getMessage(), is(equalTo("Tweet is too small"))); + } + + @Test + void serializeTweet() throws IOException { + tweet.setContent(content); + byte[] content = new TweetSerializer(tweet).serialize(); + assertThat(content, is(notNullValue())); + } + +} diff --git a/testing-modules/junit-5-advanced/src/test/resources/lorem-ipsum.txt b/testing-modules/junit-5-advanced/src/test/resources/lorem-ipsum.txt new file mode 100644 index 0000000000..2e9db81938 --- /dev/null +++ b/testing-modules/junit-5-advanced/src/test/resources/lorem-ipsum.txt @@ -0,0 +1,4 @@ +Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. +Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. +Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. +Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. \ No newline at end of file diff --git a/testing-modules/junit-5-basics/README.md b/testing-modules/junit-5-basics/README.md index dbe6803401..31eb75a792 100644 --- a/testing-modules/junit-5-basics/README.md +++ b/testing-modules/junit-5-basics/README.md @@ -8,3 +8,4 @@ - [JUnit 5 @Test Annotation](http://www.baeldung.com/junit-5-test-annotation) - [Migrating from JUnit 4 to JUnit 5](http://www.baeldung.com/junit-5-migration) - [Assert an Exception is Thrown in JUnit 4 and 5](http://www.baeldung.com/junit-assert-exception) +- [The Difference Between Failure and Error in JUnit](https://www.baeldung.com/junit-failure-vs-error) diff --git a/testing-modules/junit-5-basics/src/main/java/com/baeldung/failure_vs_error/SimpleCalculator.java b/testing-modules/junit-5-basics/src/main/java/com/baeldung/failure_vs_error/SimpleCalculator.java new file mode 100644 index 0000000000..d018aa939f --- /dev/null +++ b/testing-modules/junit-5-basics/src/main/java/com/baeldung/failure_vs_error/SimpleCalculator.java @@ -0,0 +1,15 @@ +package com.baeldung.failure_vs_error; + +/** + * @author paullatzelsperger + * @since 2019-07-17 + */ +public class SimpleCalculator { + + public static double divideNumbers(double dividend, double divisor) { + if (divisor == 0) { + throw new ArithmeticException("Division by zero!"); + } + return dividend / divisor; + } +} diff --git a/testing-modules/junit-5-basics/src/test/java/com/baeldung/failure_vs_error/SimpleCalculatorUnitTest.java b/testing-modules/junit-5-basics/src/test/java/com/baeldung/failure_vs_error/SimpleCalculatorUnitTest.java new file mode 100644 index 0000000000..6833834959 --- /dev/null +++ b/testing-modules/junit-5-basics/src/test/java/com/baeldung/failure_vs_error/SimpleCalculatorUnitTest.java @@ -0,0 +1,39 @@ +package com.baeldung.failure_vs_error; + +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +/** + * @author paullatzelsperger + * @since 2019-07-17 + */ +class SimpleCalculatorUnitTest { + + @Test + void whenDivideByValidNumber_thenAssertCorrectResult() { + double result = SimpleCalculator.divideNumbers(6, 3); + assertEquals(2, result); + } + + @Test + @Disabled("test is expected to fail, disabled so that CI build still goes through") + void whenDivideNumbers_thenExpectWrongResult() { + double result = SimpleCalculator.divideNumbers(6, 3); + assertEquals(15, result); + } + + @Test + @Disabled("test is expected to raise an error, disabled so that CI build still goes through") + void whenDivideByZero_thenThrowsException() { + SimpleCalculator.divideNumbers(10, 0); + } + + @Test + void whenDivideByZero_thenAssertException(){ + assertThrows(ArithmeticException.class, () -> SimpleCalculator.divideNumbers(10, 0)); + } + +} diff --git a/testing-modules/junit-5/README.md b/testing-modules/junit-5/README.md index d543b9b09b..14e018a5f9 100644 --- a/testing-modules/junit-5/README.md +++ b/testing-modules/junit-5/README.md @@ -11,3 +11,4 @@ - [A Quick JUnit vs TestNG Comparison](http://www.baeldung.com/junit-vs-testng) - [Guide to JUnit 5 Parameterized Tests](https://www.baeldung.com/parameterized-tests-junit-5) - [JUnit 5 Conditional Test Execution with Annotations](https://www.baeldung.com/junit-5-conditional-test-execution) +- [Assertions in JUnit 4 and JUnit 5](http://www.baeldung.com/junit-assertions) diff --git a/testing-modules/load-testing-comparison/README.md b/testing-modules/load-testing-comparison/README.md new file mode 100644 index 0000000000..9823be5369 --- /dev/null +++ b/testing-modules/load-testing-comparison/README.md @@ -0,0 +1,3 @@ +## Relevant Articles + +- [Gatling vs JMeter vs The Grinder: Comparing Load Test Tools](https://www.baeldung.com/gatling-jmeter-grinder-comparison) diff --git a/testing-modules/mockito/README.md b/testing-modules/mockito/README.md index 59954784f9..8fe57016e3 100644 --- a/testing-modules/mockito/README.md +++ b/testing-modules/mockito/README.md @@ -18,3 +18,7 @@ - [Hamcrest Common Core Matchers](http://www.baeldung.com/hamcrest-core-matchers) - [Testing Callbacks with Mockito](http://www.baeldung.com/mockito-callbacks) - [Using Hamcrest Number Matchers](https://www.baeldung.com/hamcrest-number-matchers) +- [Quick Guide to BDDMockito](http://www.baeldung.com/bdd-mockito) +- [Hamcrest Bean Matchers](http://www.baeldung.com/hamcrest-bean-matchers) +- [Hamcrest Object Matchers](http://www.baeldung.com/hamcrest-object-matchers) +- [Testing Callbacks with Mockito](http://www.baeldung.com/mockito-callbacks) diff --git a/testing-modules/parallel-tests-junit/README.md b/testing-modules/parallel-tests-junit/README.md new file mode 100644 index 0000000000..0b7834c5e7 --- /dev/null +++ b/testing-modules/parallel-tests-junit/README.md @@ -0,0 +1,3 @@ +## Relevant Articles + +- [Running JUnit Tests in Parallel with Maven](https://www.baeldung.com/maven-junit-parallel-tests) diff --git a/testing-modules/rest-assured/README.md b/testing-modules/rest-assured/README.md index ec108353a0..0012a63012 100644 --- a/testing-modules/rest-assured/README.md +++ b/testing-modules/rest-assured/README.md @@ -3,3 +3,7 @@ - [REST-assured Support for Spring MockMvc](https://www.baeldung.com/spring-mock-mvc-rest-assured) - [Getting and Verifying Response Data with REST-assured](https://www.baeldung.com/rest-assured-response) - [REST Assured Authentication](https://www.baeldung.com/rest-assured-authentication) +- [REST-assured with Groovy](http://www.baeldung.com/rest-assured-groovy) +- [Headers, Cookies and Parameters with REST-assured](http://www.baeldung.com/rest-assured-header-cookie-parameter) +- [JSON Schema Validation with REST-assured](http://www.baeldung.com/rest-assured-json-schema) + diff --git a/testing-modules/spring-testing/README.md b/testing-modules/spring-testing/README.md index 0970eabeff..1b06c13953 100644 --- a/testing-modules/spring-testing/README.md +++ b/testing-modules/spring-testing/README.md @@ -1,8 +1,8 @@ -### Relevant Articles: +## Relevant Articles: - [Mockito.mock() vs @Mock vs @MockBean](http://www.baeldung.com/java-spring-mockito-mock-mockbean) - [A Quick Guide to @TestPropertySource](https://www.baeldung.com/spring-test-property-source) - [Guide to ReflectionTestUtils for Unit Testing](https://www.baeldung.com/spring-reflection-test-utils) - [How to Test the @Scheduled Annotation](https://www.baeldung.com/spring-testing-scheduled-annotation) - [Using SpringJUnit4ClassRunner with Parameterized](https://www.baeldung.com/springjunit4classrunner-parameterized) -- [Override properties in Spring]() +- [Override Properties in Spring’s Tests](https://www.baeldung.com/spring-tests-override-properties) diff --git a/testing-modules/testing/README.md b/testing-modules/testing/README.md index 4a7829e867..135ef1054a 100644 --- a/testing-modules/testing/README.md +++ b/testing-modules/testing/README.md @@ -21,3 +21,4 @@ - [Using Conditions with AssertJ Assertions](http://www.baeldung.com/assertj-conditions) - [A Guide to JavaFaker](https://www.baeldung.com/java-faker) - [Running JUnit Tests Programmatically, from a Java Application](https://www.baeldung.com/junit-tests-run-programmatically-from-java) +- [AssertJ Exception Assertions](http://www.baeldung.com/assertj-exception-assertion) diff --git a/Twitter4J/README.md b/twitter4j/README.md similarity index 100% rename from Twitter4J/README.md rename to twitter4j/README.md diff --git a/Twitter4J/pom.xml b/twitter4j/pom.xml similarity index 100% rename from Twitter4J/pom.xml rename to twitter4j/pom.xml diff --git a/Twitter4J/src/main/java/com/baeldung/Application.java b/twitter4j/src/main/java/com/baeldung/Application.java similarity index 100% rename from Twitter4J/src/main/java/com/baeldung/Application.java rename to twitter4j/src/main/java/com/baeldung/Application.java diff --git a/spring-security-client/spring-security-jsp-authentication/src/main/resources/logback.xml b/twitter4j/src/main/resources/logback.xml similarity index 100% rename from spring-security-client/spring-security-jsp-authentication/src/main/resources/logback.xml rename to twitter4j/src/main/resources/logback.xml diff --git a/Twitter4J/src/main/resources/twitter4j.properties b/twitter4j/src/main/resources/twitter4j.properties similarity index 100% rename from Twitter4J/src/main/resources/twitter4j.properties rename to twitter4j/src/main/resources/twitter4j.properties diff --git a/Twitter4J/src/test/java/com/baeldung/ApplicationIntegrationTest.java b/twitter4j/src/test/java/com/baeldung/ApplicationIntegrationTest.java similarity index 100% rename from Twitter4J/src/test/java/com/baeldung/ApplicationIntegrationTest.java rename to twitter4j/src/test/java/com/baeldung/ApplicationIntegrationTest.java diff --git a/vaadin/src/main/java/com/baeldung/introduction/Row.java b/vaadin/src/main/java/com/baeldung/introduction/Row.java new file mode 100644 index 0000000000..412a286376 --- /dev/null +++ b/vaadin/src/main/java/com/baeldung/introduction/Row.java @@ -0,0 +1,45 @@ +package com.baeldung.introduction; + +public class Row { + + private String column1; + + private String column2; + + private String column3; + + public Row() { + + } + + public Row(String column1, String column2, String column3) { + super(); + this.column1 = column1; + this.column2 = column2; + this.column3 = column3; + } + + public String getColumn1() { + return column1; + } + + public void setColumn1(String column1) { + this.column1 = column1; + } + + public String getColumn2() { + return column2; + } + + public void setColumn2(String column2) { + this.column2 = column2; + } + + public String getColumn3() { + return column3; + } + + public void setColumn3(String column3) { + this.column3 = column3; + } +} \ No newline at end of file diff --git a/vaadin/src/main/java/com/baeldung/introduction/VaadinUI.java b/vaadin/src/main/java/com/baeldung/introduction/VaadinUI.java index 68be53b1b3..22ce19f5e0 100644 --- a/vaadin/src/main/java/com/baeldung/introduction/VaadinUI.java +++ b/vaadin/src/main/java/com/baeldung/introduction/VaadinUI.java @@ -201,10 +201,14 @@ public class VaadinUI extends UI { TwinColSelect twinColSelect = new TwinColSelect("TwinColSelect"); twinColSelect.setItems(numbers); - Grid grid = new Grid("Grid"); - grid.setColumns("Column1", "Column2", "Column3"); - grid.setItems("Item1", "Item2", "Item3"); - grid.setItems("Item4", "Item5", "Item6"); + Grid grid = new Grid(Row.class); + grid.setColumns("column1", "column2", "column3"); + Row row1 = new Row("Item1", "Item2", "Item3"); + Row row2 = new Row("Item4", "Item5", "Item6"); + List rows = new ArrayList(); + rows.add(row1); + rows.add(row2); + grid.setItems(rows); Panel panel = new Panel("Panel"); panel.setContent(grid); @@ -271,7 +275,7 @@ public class VaadinUI extends UI { setContent(verticalLayout); } - @WebServlet(urlPatterns = "/*", name = "MyUIServlet", asyncSupported = true) + @WebServlet(urlPatterns = "/VAADIN/*", name = "MyUIServlet", asyncSupported = true) @VaadinServletConfiguration(ui = VaadinUI.class, productionMode = false) public static class MyUIServlet extends VaadinServlet { } diff --git a/video-tutorials/README.md b/video-tutorials/README.md index ff12555376..729105e3fd 100644 --- a/video-tutorials/README.md +++ b/video-tutorials/README.md @@ -1 +1 @@ -## Relevant articles: +## Relevant Articles: diff --git a/xml/src/main/java/com/baeldung/xml/attribute/Dom4jTransformer.java b/xml/src/main/java/com/baeldung/xml/attribute/Dom4jTransformer.java index a1922ad224..d4fdeb0d58 100644 --- a/xml/src/main/java/com/baeldung/xml/attribute/Dom4jTransformer.java +++ b/xml/src/main/java/com/baeldung/xml/attribute/Dom4jTransformer.java @@ -3,6 +3,7 @@ package com.baeldung.xml.attribute; import org.dom4j.*; import org.dom4j.io.DocumentSource; import org.dom4j.io.SAXReader; +import org.xml.sax.SAXException; import javax.xml.XMLConstants; import javax.xml.transform.OutputKeys; @@ -17,9 +18,12 @@ import java.util.List; public class Dom4jTransformer { private final Document input; - public Dom4jTransformer(String resourcePath) throws DocumentException { + public Dom4jTransformer(String resourcePath) throws DocumentException, SAXException { // 1- Build the doc from the XML file SAXReader xmlReader = new SAXReader(); + xmlReader.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); + xmlReader.setFeature("http://xml.org/sax/features/external-general-entities", false); + xmlReader.setFeature("http://xml.org/sax/features/external-parameter-entities", false); this.input = xmlReader.read(resourcePath); } diff --git a/xml/src/main/java/com/baeldung/xml/attribute/JaxpTransformer.java b/xml/src/main/java/com/baeldung/xml/attribute/JaxpTransformer.java index a2266a2b44..a55b00950c 100644 --- a/xml/src/main/java/com/baeldung/xml/attribute/JaxpTransformer.java +++ b/xml/src/main/java/com/baeldung/xml/attribute/JaxpTransformer.java @@ -32,7 +32,8 @@ public class JaxpTransformer { // 1- Build the doc from the XML file DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); - input = factory.newDocumentBuilder() + factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); + this.input = factory.newDocumentBuilder() .parse(resourcePath); } @@ -40,24 +41,24 @@ public class JaxpTransformer { // 2- Locate the node(s) with xpath XPath xpath = XPathFactory.newInstance() .newXPath(); - NodeList nodes = (NodeList) xpath.evaluate(String.format("//*[contains(@%s, '%s')]", attribute, oldValue), input, XPathConstants.NODESET); + NodeList nodes = (NodeList) xpath.evaluate(String.format("//*[contains(@%s, '%s')]", attribute, oldValue), this.input, XPathConstants.NODESET); // 3- Make the change on the selected nodes for (int i = 0; i < nodes.getLength(); i++) { Element value = (Element) nodes.item(i); value.setAttribute(attribute, newValue); } - //Stream api syntax - // IntStream - // .range(0, nodes.getLength()) - // .mapToObj(i -> (Element) nodes.item(i)) - // .forEach(value -> value.setAttribute(attribute, newValue)); + // Stream api syntax + // IntStream + // .range(0, nodes.getLength()) + // .mapToObj(i -> (Element) nodes.item(i)) + // .forEach(value -> value.setAttribute(attribute, newValue)); // 4- Save the result to a new XML doc TransformerFactory factory = TransformerFactory.newInstance(); factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); Transformer xformer = factory.newTransformer(); xformer.setOutputProperty(OutputKeys.INDENT, "yes"); Writer output = new StringWriter(); - xformer.transform(new DOMSource(input), new StreamResult(output)); + xformer.transform(new DOMSource(this.input), new StreamResult(output)); return output.toString(); } } diff --git a/xml/src/main/java/com/baeldung/xml/attribute/jmh/AttributeBenchMark.java b/xml/src/main/java/com/baeldung/xml/attribute/jmh/AttributeBenchMark.java index 064e181713..f5f3a2ce6c 100644 --- a/xml/src/main/java/com/baeldung/xml/attribute/jmh/AttributeBenchMark.java +++ b/xml/src/main/java/com/baeldung/xml/attribute/jmh/AttributeBenchMark.java @@ -1,7 +1,19 @@ package com.baeldung.xml.attribute.jmh; +import java.io.IOException; +import java.util.concurrent.TimeUnit; + +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.TransformerException; +import javax.xml.xpath.XPathExpressionException; + import org.dom4j.DocumentException; -import org.openjdk.jmh.annotations.*; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.State; import org.openjdk.jmh.runner.Runner; import org.openjdk.jmh.runner.RunnerException; import org.openjdk.jmh.runner.options.Options; @@ -12,30 +24,23 @@ import com.baeldung.xml.attribute.Dom4jTransformer; import com.baeldung.xml.attribute.JaxpTransformer; import com.baeldung.xml.attribute.JooxTransformer; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.transform.TransformerException; -import javax.xml.xpath.XPathExpressionException; -import java.io.IOException; -import java.util.concurrent.TimeUnit; - @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.MILLISECONDS) @State(Scope.Benchmark) public class AttributeBenchMark { public static void main(String[] args) throws RunnerException { - Options opt = new OptionsBuilder() - .include(AttributeBenchMark.class.getSimpleName()) - .forks(1) - .build(); + Options opt = new OptionsBuilder().include(AttributeBenchMark.class.getSimpleName()) + .forks(1) + .build(); new Runner(opt).run(); } @Benchmark - public String dom4jBenchmark() throws DocumentException, TransformerException { - String path = getClass() - .getResource("/xml/attribute.xml") - .toString(); + public String dom4jBenchmark() throws DocumentException, TransformerException, SAXException { + String path = this.getClass() + .getResource("/xml/attribute.xml") + .toString(); Dom4jTransformer transformer = new Dom4jTransformer(path); String attribute = "customer"; String oldValue = "true"; @@ -46,9 +51,9 @@ public class AttributeBenchMark { @Benchmark public String jooxBenchmark() throws IOException, SAXException { - String path = getClass() - .getResource("/xml/attribute.xml") - .toString(); + String path = this.getClass() + .getResource("/xml/attribute.xml") + .toString(); JooxTransformer transformer = new JooxTransformer(path); String attribute = "customer"; String oldValue = "true"; @@ -59,9 +64,9 @@ public class AttributeBenchMark { @Benchmark public String jaxpBenchmark() throws TransformerException, ParserConfigurationException, SAXException, IOException, XPathExpressionException { - String path = getClass() - .getResource("/xml/attribute.xml") - .toString(); + String path = this.getClass() + .getResource("/xml/attribute.xml") + .toString(); JaxpTransformer transformer = new JaxpTransformer(path); String attribute = "customer"; String oldValue = "true"; diff --git a/xml/src/test/java/com/baeldung/xml/attribute/Dom4jProcessorUnitTest.java b/xml/src/test/java/com/baeldung/xml/attribute/Dom4jProcessorUnitTest.java index 485744f9a5..351b8bc437 100644 --- a/xml/src/test/java/com/baeldung/xml/attribute/Dom4jProcessorUnitTest.java +++ b/xml/src/test/java/com/baeldung/xml/attribute/Dom4jProcessorUnitTest.java @@ -2,14 +2,19 @@ package com.baeldung.xml.attribute; import org.dom4j.DocumentException; import org.junit.jupiter.api.Test; +import org.xml.sax.SAXException; +import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactoryConfigurationError; +import javax.xml.xpath.XPathExpressionException; + import java.io.IOException; import java.net.URISyntaxException; import java.nio.file.Files; import java.nio.file.Paths; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.xmlunit.assertj.XmlAssert.assertThat; /** @@ -18,10 +23,9 @@ import static org.xmlunit.assertj.XmlAssert.assertThat; public class Dom4jProcessorUnitTest { @Test - public void givenXmlWithAttributes_whenModifyAttribute_thenGetXmlUpdated() throws TransformerFactoryConfigurationError, TransformerException, DocumentException { - String path = getClass() - .getResource("/xml/attribute.xml") - .toString(); + public void givenXmlWithAttributes_whenModifyAttribute_thenGetXmlUpdated() throws TransformerFactoryConfigurationError, TransformerException, DocumentException, SAXException { + String path = getClass().getResource("/xml/attribute.xml") + .toString(); Dom4jTransformer transformer = new Dom4jTransformer(path); String attribute = "customer"; String oldValue = "true"; @@ -33,23 +37,32 @@ public class Dom4jProcessorUnitTest { } @Test - public void givenTwoXml_whenModifyAttribute_thenGetSimilarXml() throws IOException, TransformerFactoryConfigurationError, TransformerException, URISyntaxException, DocumentException { - String path = getClass() - .getResource("/xml/attribute.xml") - .toString(); + public void givenTwoXml_whenModifyAttribute_thenGetSimilarXml() throws IOException, TransformerFactoryConfigurationError, TransformerException, URISyntaxException, DocumentException, SAXException { + String path = getClass().getResource("/xml/attribute.xml") + .toString(); Dom4jTransformer transformer = new Dom4jTransformer(path); String attribute = "customer"; String oldValue = "true"; String newValue = "false"; - String expectedXml = new String(Files.readAllBytes((Paths.get(getClass() - .getResource("/xml/attribute_expected.xml") - .toURI())))); + String expectedXml = new String(Files.readAllBytes((Paths.get(getClass().getResource("/xml/attribute_expected.xml") + .toURI())))); String result = transformer.modifyAttribute(attribute, oldValue, newValue); - assertThat(result) - .and(expectedXml) - .areSimilar(); + assertThat(result).and(expectedXml) + .areSimilar(); + } + + @Test + public void givenXmlXee_whenInit_thenThrowException() throws IOException, SAXException, ParserConfigurationException, XPathExpressionException, TransformerFactoryConfigurationError, TransformerException { + String path = getClass().getResource("/xml/xee_attribute.xml") + .toString(); + + assertThatThrownBy(() -> { + + new Dom4jTransformer(path); + + }).isInstanceOf(DocumentException.class); } } diff --git a/xml/src/test/java/com/baeldung/xml/attribute/JaxpProcessorUnitTest.java b/xml/src/test/java/com/baeldung/xml/attribute/JaxpProcessorUnitTest.java index 8394016dbd..8d814783e0 100644 --- a/xml/src/test/java/com/baeldung/xml/attribute/JaxpProcessorUnitTest.java +++ b/xml/src/test/java/com/baeldung/xml/attribute/JaxpProcessorUnitTest.java @@ -1,5 +1,6 @@ package com.baeldung.xml.attribute; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.xmlunit.assertj.XmlAssert.assertThat; import java.io.IOException; @@ -11,6 +12,7 @@ import javax.xml.xpath.XPathExpressionException; import org.junit.jupiter.api.Test; import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; /** * Unit test for {@link JaxpTransformer}. @@ -31,4 +33,16 @@ public class JaxpProcessorUnitTest { assertThat(result).hasXPath("//*[contains(@customer, 'false')]"); } + @Test + public void givenXmlXee_whenInit_thenThrowException() throws IOException, SAXException, ParserConfigurationException, XPathExpressionException, TransformerFactoryConfigurationError, TransformerException { + String path = getClass().getResource("/xml/xee_attribute.xml") + .toString(); + + assertThatThrownBy(() -> { + + new JaxpTransformer(path); + + }).isInstanceOf(SAXParseException.class); + } + } diff --git a/xml/src/test/java/com/baeldung/xml/attribute/JooxProcessorUnitTest.java b/xml/src/test/java/com/baeldung/xml/attribute/JooxProcessorUnitTest.java index 38c7c59789..40d0c671e7 100644 --- a/xml/src/test/java/com/baeldung/xml/attribute/JooxProcessorUnitTest.java +++ b/xml/src/test/java/com/baeldung/xml/attribute/JooxProcessorUnitTest.java @@ -2,13 +2,19 @@ package com.baeldung.xml.attribute; import org.junit.jupiter.api.Test; import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactoryConfigurationError; +import javax.xml.xpath.XPathExpressionException; + import java.io.IOException; import java.net.URISyntaxException; import java.nio.file.Files; import java.nio.file.Paths; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.xmlunit.assertj.XmlAssert.assertThat; /** @@ -18,9 +24,8 @@ public class JooxProcessorUnitTest { @Test public void givenXmlWithAttributes_whenModifyAttribute_thenGetXmlUpdated() throws IOException, SAXException, TransformerFactoryConfigurationError { - String path = getClass() - .getResource("/xml/attribute.xml") - .toString(); + String path = getClass().getResource("/xml/attribute.xml") + .toString(); JooxTransformer transformer = new JooxTransformer(path); String attribute = "customer"; String oldValue = "true"; @@ -33,22 +38,31 @@ public class JooxProcessorUnitTest { @Test public void givenTwoXml_whenModifyAttribute_thenGetSimilarXml() throws IOException, TransformerFactoryConfigurationError, URISyntaxException, SAXException { - String path = getClass() - .getResource("/xml/attribute.xml") - .toString(); + String path = getClass().getResource("/xml/attribute.xml") + .toString(); JooxTransformer transformer = new JooxTransformer(path); String attribute = "customer"; String oldValue = "true"; String newValue = "false"; - String expectedXml = new String(Files.readAllBytes((Paths.get(getClass() - .getResource("/xml/attribute_expected.xml") - .toURI())))); + String expectedXml = new String(Files.readAllBytes((Paths.get(getClass().getResource("/xml/attribute_expected.xml") + .toURI())))); String result = transformer.modifyAttribute(attribute, oldValue, newValue); - assertThat(result) - .and(expectedXml) - .areSimilar(); + assertThat(result).and(expectedXml) + .areSimilar(); + } + + @Test + public void givenXmlXee_whenInit_thenThrowException() throws IOException, SAXException, ParserConfigurationException, XPathExpressionException, TransformerFactoryConfigurationError, TransformerException { + String path = getClass().getResource("/xml/xee_attribute.xml") + .toString(); + + assertThatThrownBy(() -> { + + new JooxTransformer(path); + + }).isInstanceOf(SAXParseException.class); } } diff --git a/xml/src/test/resources/xml/xee_attribute.xml b/xml/src/test/resources/xml/xee_attribute.xml new file mode 100644 index 0000000000..9633ca15b0 --- /dev/null +++ b/xml/src/test/resources/xml/xee_attribute.xml @@ -0,0 +1,9 @@ + + ]> + + &xxe; + + john@email.com + mary@email.com + \ No newline at end of file diff --git a/xstream/README.md b/xstream/README.md index e8302c14ef..bf917e81fb 100644 --- a/xstream/README.md +++ b/xstream/README.md @@ -1,4 +1,6 @@ -### Relevant Articles: +## Relevant Articles: + - [XStream User Guide: JSON](http://www.baeldung.com/xstream-json-processing) - [XStream User Guide: Converting XML to Objects](http://www.baeldung.com/xstream-deserialize-xml-to-object) - [XStream User Guide: Converting Objects to XML](http://www.baeldung.com/xstream-serialize-object-to-xml) +- [Remote Code Execution with XStream](https://www.baeldung.com/java-xstream-remote-code-execution)