diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 5e86714a89..0000000000 --- a/.travis.yml +++ /dev/null @@ -1,24 +0,0 @@ -language: java - -before_install: - - echo "MAVEN_OPTS='-Xmx2048M -Xss128M -XX:+CMSClassUnloadingEnabled -XX:+UseG1GC -XX:-UseGCOverheadLimit'" > ~/.mavenrc - -install: skip -script: travis_wait 60 mvn -q install -Pdefault-first,default-second -Dgib.enabled=true - -sudo: required - -jdk: - - oraclejdk8 - -addons: - apt: - packages: - - oracle-java8-installer - -cache: - directories: - - .autoconf - - $HOME/.m2 - - 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..ce0fde0415 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) @@ -7,3 +7,4 @@ - [Checking If a List Is Sorted in Java](https://www.baeldung.com/java-check-if-list-sorted) - [Checking if a Java Graph has a Cycle](https://www.baeldung.com/java-graph-has-a-cycle) - [A Guide to the Folding Technique in Java](https://www.baeldung.com/folding-hashing-technique) +- [Creating a Triangle with for Loops in Java](https://www.baeldung.com/java-print-triangle) 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..156766f382 --- /dev/null +++ b/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/printtriangles/PrintTriangleExamples.java @@ -0,0 +1,61 @@ +package com.baeldung.algorithms.printtriangles; + +import org.apache.commons.lang3.StringUtils; + +public class PrintTriangleExamples { + + public static String printARightTriangle(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 printAnIsoscelesTriangleUsingStringUtils(int N) { + StringBuilder result = new StringBuilder(); + + for (int r = 1; r <= N; r++) { + result.append(StringUtils.repeat(' ', N - r)); + result.append(StringUtils.repeat('*', 2 * r - 1)); + 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(printARightTriangle(5)); + System.out.println(printAnIsoscelesTriangle(5)); + System.out.println(printAnIsoscelesTriangleUsingStringUtils(5)); + System.out.println(printAnIsoscelesTriangleUsingSubstring(5)); + } + +} \ No newline at end of file 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..97e99290c9 --- /dev/null +++ b/algorithms-miscellaneous-3/src/test/java/com/baeldung/algorithms/printtriangles/PrintTriangleExamplesUnitTest.java @@ -0,0 +1,101 @@ +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[][] rightTriangles() { + 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 = "rightTriangles") + public void whenPrintARightTriangleIsCalled_ThenTheCorrectStringIsReturned(int nrOfRows, String expected) { + String actual = PrintTriangleExamples.printARightTriangle(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 whenPrintAnIsoscelesTriangleUsingStringUtilsIsCalled_ThenTheCorrectStringIsReturned(int nrOfRows, String expected) { + String actual = PrintTriangleExamples.printAnIsoscelesTriangleUsingStringUtils(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-sorting/README.md b/algorithms-sorting/README.md index 36460293b0..968d51aecf 100644 --- a/algorithms-sorting/README.md +++ b/algorithms-sorting/README.md @@ -5,3 +5,5 @@ - [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) +- [Counting Sort in Java](https://www.baeldung.com/java-counting-sort) diff --git a/algorithms-sorting/src/main/java/com/baeldung/algorithms/counting/CountingSort.java b/algorithms-sorting/src/main/java/com/baeldung/algorithms/counting/CountingSort.java new file mode 100644 index 0000000000..823f372849 --- /dev/null +++ b/algorithms-sorting/src/main/java/com/baeldung/algorithms/counting/CountingSort.java @@ -0,0 +1,48 @@ +package com.baeldung.algorithms.counting; + +import java.util.Arrays; +import java.util.stream.IntStream; + +public class CountingSort { + + public static int[] sort(int[] input, int k) { + verifyPreconditions(input, k); + if (input.length == 0) return input; + + int[] c = countElements(input, k); + int[] sorted = new int[input.length]; + for (int i = input.length - 1; i >= 0; i--) { + int current = input[i]; + sorted[c[current] - 1] = current; + c[current] -= 1; + } + + return sorted; + } + + static int[] countElements(int[] input, int k) { + int[] c = new int[k + 1]; + Arrays.fill(c, 0); + for (int i : input) { + c[i] += 1; + } + + for (int i = 1; i < c.length; i++) { + c[i] += c[i - 1]; + } + return c; + } + + private static void verifyPreconditions(int[] input, int k) { + if (input == null) { + throw new IllegalArgumentException("Input is required"); + } + + int min = IntStream.of(input).min().getAsInt(); + int max = IntStream.of(input).max().getAsInt(); + + if (min < 0 || max > k) { + throw new IllegalArgumentException("The input numbers should be between zero and " + k); + } + } +} 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-miscellaneous-3/src/main/java/com/baeldung/algorithms/stringsortingbynumber/NaturalOrderComparators.java b/algorithms-sorting/src/main/java/com/baeldung/algorithms/sort/bynumber/NaturalOrderComparators.java similarity index 93% rename from algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/stringsortingbynumber/NaturalOrderComparators.java rename to algorithms-sorting/src/main/java/com/baeldung/algorithms/sort/bynumber/NaturalOrderComparators.java index 376b196aa1..b177bd60fc 100644 --- a/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/stringsortingbynumber/NaturalOrderComparators.java +++ b/algorithms-sorting/src/main/java/com/baeldung/algorithms/sort/bynumber/NaturalOrderComparators.java @@ -1,4 +1,4 @@ -package com.baeldung.algorithms.stringsortingbynumber; +package com.baeldung.algorithms.sort.bynumber; import java.util.Comparator; diff --git a/algorithms-sorting/src/test/java/com/baeldung/algorithms/counting/CountingSortUnitTest.java b/algorithms-sorting/src/test/java/com/baeldung/algorithms/counting/CountingSortUnitTest.java new file mode 100644 index 0000000000..ec6cf0784e --- /dev/null +++ b/algorithms-sorting/src/test/java/com/baeldung/algorithms/counting/CountingSortUnitTest.java @@ -0,0 +1,32 @@ +package com.baeldung.algorithms.counting; + +import java.util.Arrays; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; + +import org.junit.jupiter.api.Test; + +class CountingSortUnitTest { + + @Test + void countElements_GivenAnArray_ShouldCalculateTheFrequencyArrayAsExpected() { + int k = 5; + int[] input = { 4, 3, 2, 5, 4, 3, 5, 1, 0, 2, 5 }; + + int[] c = CountingSort.countElements(input, k); + int[] expected = { 1, 2, 4, 6, 8, 11 }; + assertArrayEquals(expected, c); + } + + @Test + void sort_GivenAnArray_ShouldSortTheInputAsExpected() { + int k = 5; + int[] input = { 4, 3, 2, 5, 4, 3, 5, 1, 0, 2, 5 }; + + int[] sorted = CountingSort.sort(input, k); + + // Our sorting algorithm and Java's should return the same result + Arrays.sort(input); + assertArrayEquals(input, sorted); + } +} \ 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/algorithms-miscellaneous-3/src/test/java/com/baeldung/algorithms/stringsortingbynumber/NaturalOrderComparatorsUnitTest.java b/algorithms-sorting/src/test/java/com/baeldung/algorithms/sort/bynumber/NaturalOrderComparatorsUnitTest.java similarity index 94% rename from algorithms-miscellaneous-3/src/test/java/com/baeldung/algorithms/stringsortingbynumber/NaturalOrderComparatorsUnitTest.java rename to algorithms-sorting/src/test/java/com/baeldung/algorithms/sort/bynumber/NaturalOrderComparatorsUnitTest.java index 549151bc93..2f05f62147 100644 --- a/algorithms-miscellaneous-3/src/test/java/com/baeldung/algorithms/stringsortingbynumber/NaturalOrderComparatorsUnitTest.java +++ b/algorithms-sorting/src/test/java/com/baeldung/algorithms/sort/bynumber/NaturalOrderComparatorsUnitTest.java @@ -1,6 +1,6 @@ -package com.baeldung.algorithms.stringsortingbynumber; +package com.baeldung.algorithms.sort.bynumber; -import com.baeldung.algorithms.stringsortingbynumber.NaturalOrderComparators; +import com.baeldung.algorithms.sort.bynumber.NaturalOrderComparators; import org.junit.Test; import java.util.ArrayList; diff --git a/apache-olingo/olingo2/pom.xml b/apache-olingo/olingo2/pom.xml index 24e7b4e0b2..727e6ca484 100644 --- a/apache-olingo/olingo2/pom.xml +++ b/apache-olingo/olingo2/pom.xml @@ -4,9 +4,9 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 org.baeldung.examples.olingo2 - olingo2-sample + olingo2 0.0.1-SNAPSHOT - olingo2-sample + olingo2 Sample Olingo 2 Project diff --git a/apache-spark/data/iris.data b/apache-spark/data/iris.data new file mode 100644 index 0000000000..396653cc98 --- /dev/null +++ b/apache-spark/data/iris.data @@ -0,0 +1,150 @@ +5.1,3.5,1.4,0.2,Iris-setosa +4.9,3.0,1.4,0.2,Iris-setosa +4.7,3.2,1.3,0.2,Iris-setosa +4.6,3.1,1.5,0.2,Iris-setosa +5.0,3.6,1.4,0.2,Iris-setosa +5.4,3.9,1.7,0.4,Iris-setosa +4.6,3.4,1.4,0.3,Iris-setosa +5.0,3.4,1.5,0.2,Iris-setosa +4.4,2.9,1.4,0.2,Iris-setosa +4.9,3.1,1.5,0.1,Iris-setosa +5.4,3.7,1.5,0.2,Iris-setosa +4.8,3.4,1.6,0.2,Iris-setosa +4.8,3.0,1.4,0.1,Iris-setosa +4.3,3.0,1.1,0.1,Iris-setosa +5.8,4.0,1.2,0.2,Iris-setosa +5.7,4.4,1.5,0.4,Iris-setosa +5.4,3.9,1.3,0.4,Iris-setosa +5.1,3.5,1.4,0.3,Iris-setosa +5.7,3.8,1.7,0.3,Iris-setosa +5.1,3.8,1.5,0.3,Iris-setosa +5.4,3.4,1.7,0.2,Iris-setosa +5.1,3.7,1.5,0.4,Iris-setosa +4.6,3.6,1.0,0.2,Iris-setosa +5.1,3.3,1.7,0.5,Iris-setosa +4.8,3.4,1.9,0.2,Iris-setosa +5.0,3.0,1.6,0.2,Iris-setosa +5.0,3.4,1.6,0.4,Iris-setosa +5.2,3.5,1.5,0.2,Iris-setosa +5.2,3.4,1.4,0.2,Iris-setosa +4.7,3.2,1.6,0.2,Iris-setosa +4.8,3.1,1.6,0.2,Iris-setosa +5.4,3.4,1.5,0.4,Iris-setosa +5.2,4.1,1.5,0.1,Iris-setosa +5.5,4.2,1.4,0.2,Iris-setosa +4.9,3.1,1.5,0.1,Iris-setosa +5.0,3.2,1.2,0.2,Iris-setosa +5.5,3.5,1.3,0.2,Iris-setosa +4.9,3.1,1.5,0.1,Iris-setosa +4.4,3.0,1.3,0.2,Iris-setosa +5.1,3.4,1.5,0.2,Iris-setosa +5.0,3.5,1.3,0.3,Iris-setosa +4.5,2.3,1.3,0.3,Iris-setosa +4.4,3.2,1.3,0.2,Iris-setosa +5.0,3.5,1.6,0.6,Iris-setosa +5.1,3.8,1.9,0.4,Iris-setosa +4.8,3.0,1.4,0.3,Iris-setosa +5.1,3.8,1.6,0.2,Iris-setosa +4.6,3.2,1.4,0.2,Iris-setosa +5.3,3.7,1.5,0.2,Iris-setosa +5.0,3.3,1.4,0.2,Iris-setosa +7.0,3.2,4.7,1.4,Iris-versicolor +6.4,3.2,4.5,1.5,Iris-versicolor +6.9,3.1,4.9,1.5,Iris-versicolor +5.5,2.3,4.0,1.3,Iris-versicolor +6.5,2.8,4.6,1.5,Iris-versicolor +5.7,2.8,4.5,1.3,Iris-versicolor +6.3,3.3,4.7,1.6,Iris-versicolor +4.9,2.4,3.3,1.0,Iris-versicolor +6.6,2.9,4.6,1.3,Iris-versicolor +5.2,2.7,3.9,1.4,Iris-versicolor +5.0,2.0,3.5,1.0,Iris-versicolor +5.9,3.0,4.2,1.5,Iris-versicolor +6.0,2.2,4.0,1.0,Iris-versicolor +6.1,2.9,4.7,1.4,Iris-versicolor +5.6,2.9,3.6,1.3,Iris-versicolor +6.7,3.1,4.4,1.4,Iris-versicolor +5.6,3.0,4.5,1.5,Iris-versicolor +5.8,2.7,4.1,1.0,Iris-versicolor +6.2,2.2,4.5,1.5,Iris-versicolor +5.6,2.5,3.9,1.1,Iris-versicolor +5.9,3.2,4.8,1.8,Iris-versicolor +6.1,2.8,4.0,1.3,Iris-versicolor +6.3,2.5,4.9,1.5,Iris-versicolor +6.1,2.8,4.7,1.2,Iris-versicolor +6.4,2.9,4.3,1.3,Iris-versicolor +6.6,3.0,4.4,1.4,Iris-versicolor +6.8,2.8,4.8,1.4,Iris-versicolor +6.7,3.0,5.0,1.7,Iris-versicolor +6.0,2.9,4.5,1.5,Iris-versicolor +5.7,2.6,3.5,1.0,Iris-versicolor +5.5,2.4,3.8,1.1,Iris-versicolor +5.5,2.4,3.7,1.0,Iris-versicolor +5.8,2.7,3.9,1.2,Iris-versicolor +6.0,2.7,5.1,1.6,Iris-versicolor +5.4,3.0,4.5,1.5,Iris-versicolor +6.0,3.4,4.5,1.6,Iris-versicolor +6.7,3.1,4.7,1.5,Iris-versicolor +6.3,2.3,4.4,1.3,Iris-versicolor +5.6,3.0,4.1,1.3,Iris-versicolor +5.5,2.5,4.0,1.3,Iris-versicolor +5.5,2.6,4.4,1.2,Iris-versicolor +6.1,3.0,4.6,1.4,Iris-versicolor +5.8,2.6,4.0,1.2,Iris-versicolor +5.0,2.3,3.3,1.0,Iris-versicolor +5.6,2.7,4.2,1.3,Iris-versicolor +5.7,3.0,4.2,1.2,Iris-versicolor +5.7,2.9,4.2,1.3,Iris-versicolor +6.2,2.9,4.3,1.3,Iris-versicolor +5.1,2.5,3.0,1.1,Iris-versicolor +5.7,2.8,4.1,1.3,Iris-versicolor +6.3,3.3,6.0,2.5,Iris-virginica +5.8,2.7,5.1,1.9,Iris-virginica +7.1,3.0,5.9,2.1,Iris-virginica +6.3,2.9,5.6,1.8,Iris-virginica +6.5,3.0,5.8,2.2,Iris-virginica +7.6,3.0,6.6,2.1,Iris-virginica +4.9,2.5,4.5,1.7,Iris-virginica +7.3,2.9,6.3,1.8,Iris-virginica +6.7,2.5,5.8,1.8,Iris-virginica +7.2,3.6,6.1,2.5,Iris-virginica +6.5,3.2,5.1,2.0,Iris-virginica +6.4,2.7,5.3,1.9,Iris-virginica +6.8,3.0,5.5,2.1,Iris-virginica +5.7,2.5,5.0,2.0,Iris-virginica +5.8,2.8,5.1,2.4,Iris-virginica +6.4,3.2,5.3,2.3,Iris-virginica +6.5,3.0,5.5,1.8,Iris-virginica +7.7,3.8,6.7,2.2,Iris-virginica +7.7,2.6,6.9,2.3,Iris-virginica +6.0,2.2,5.0,1.5,Iris-virginica +6.9,3.2,5.7,2.3,Iris-virginica +5.6,2.8,4.9,2.0,Iris-virginica +7.7,2.8,6.7,2.0,Iris-virginica +6.3,2.7,4.9,1.8,Iris-virginica +6.7,3.3,5.7,2.1,Iris-virginica +7.2,3.2,6.0,1.8,Iris-virginica +6.2,2.8,4.8,1.8,Iris-virginica +6.1,3.0,4.9,1.8,Iris-virginica +6.4,2.8,5.6,2.1,Iris-virginica +7.2,3.0,5.8,1.6,Iris-virginica +7.4,2.8,6.1,1.9,Iris-virginica +7.9,3.8,6.4,2.0,Iris-virginica +6.4,2.8,5.6,2.2,Iris-virginica +6.3,2.8,5.1,1.5,Iris-virginica +6.1,2.6,5.6,1.4,Iris-virginica +7.7,3.0,6.1,2.3,Iris-virginica +6.3,3.4,5.6,2.4,Iris-virginica +6.4,3.1,5.5,1.8,Iris-virginica +6.0,3.0,4.8,1.8,Iris-virginica +6.9,3.1,5.4,2.1,Iris-virginica +6.7,3.1,5.6,2.4,Iris-virginica +6.9,3.1,5.1,2.3,Iris-virginica +5.8,2.7,5.1,1.9,Iris-virginica +6.8,3.2,5.9,2.3,Iris-virginica +6.7,3.3,5.7,2.5,Iris-virginica +6.7,3.0,5.2,2.3,Iris-virginica +6.3,2.5,5.0,1.9,Iris-virginica +6.5,3.0,5.2,2.0,Iris-virginica +6.2,3.4,5.4,2.3,Iris-virginica +5.9,3.0,5.1,1.8,Iris-virginica \ No newline at end of file diff --git a/apache-spark/model/logistic-regression/data/._SUCCESS.crc b/apache-spark/model/logistic-regression/data/._SUCCESS.crc new file mode 100644 index 0000000000..3b7b044936 Binary files /dev/null and b/apache-spark/model/logistic-regression/data/._SUCCESS.crc differ diff --git a/apache-spark/model/logistic-regression/data/.part-00000-f3a3ee61-f200-41ff-80d9-8e1edf399601-c000.snappy.parquet.crc b/apache-spark/model/logistic-regression/data/.part-00000-f3a3ee61-f200-41ff-80d9-8e1edf399601-c000.snappy.parquet.crc new file mode 100644 index 0000000000..46311024cf Binary files /dev/null and b/apache-spark/model/logistic-regression/data/.part-00000-f3a3ee61-f200-41ff-80d9-8e1edf399601-c000.snappy.parquet.crc differ diff --git a/spring-cloud-data-flow/etl/customer-mongodb-sink/src/main/resources/application.properties b/apache-spark/model/logistic-regression/data/_SUCCESS similarity index 100% rename from spring-cloud-data-flow/etl/customer-mongodb-sink/src/main/resources/application.properties rename to apache-spark/model/logistic-regression/data/_SUCCESS diff --git a/apache-spark/model/logistic-regression/data/part-00000-f3a3ee61-f200-41ff-80d9-8e1edf399601-c000.snappy.parquet b/apache-spark/model/logistic-regression/data/part-00000-f3a3ee61-f200-41ff-80d9-8e1edf399601-c000.snappy.parquet new file mode 100644 index 0000000000..07f442ef34 Binary files /dev/null and b/apache-spark/model/logistic-regression/data/part-00000-f3a3ee61-f200-41ff-80d9-8e1edf399601-c000.snappy.parquet differ diff --git a/apache-spark/model/logistic-regression/metadata/._SUCCESS.crc b/apache-spark/model/logistic-regression/metadata/._SUCCESS.crc new file mode 100644 index 0000000000..3b7b044936 Binary files /dev/null and b/apache-spark/model/logistic-regression/metadata/._SUCCESS.crc differ diff --git a/apache-spark/model/logistic-regression/metadata/.part-00000.crc b/apache-spark/model/logistic-regression/metadata/.part-00000.crc new file mode 100644 index 0000000000..35d5043fbe Binary files /dev/null and b/apache-spark/model/logistic-regression/metadata/.part-00000.crc differ diff --git a/spring-cloud-data-flow/etl/customer-transform/src/main/resources/application.properties b/apache-spark/model/logistic-regression/metadata/_SUCCESS similarity index 100% rename from spring-cloud-data-flow/etl/customer-transform/src/main/resources/application.properties rename to apache-spark/model/logistic-regression/metadata/_SUCCESS diff --git a/apache-spark/model/logistic-regression/metadata/part-00000 b/apache-spark/model/logistic-regression/metadata/part-00000 new file mode 100644 index 0000000000..e3f27fec10 --- /dev/null +++ b/apache-spark/model/logistic-regression/metadata/part-00000 @@ -0,0 +1 @@ +{"class":"org.apache.spark.mllib.classification.LogisticRegressionModel","version":"1.0","numFeatures":4,"numClasses":3} diff --git a/apache-spark/pom.xml b/apache-spark/pom.xml index b8c1962dd4..3df81e5aee 100644 --- a/apache-spark/pom.xml +++ b/apache-spark/pom.xml @@ -1,31 +1,32 @@ - - 4.0.0 - com.baeldung - apache-spark - 1.0-SNAPSHOT - apache-spark - jar - http://maven.apache.org + + 4.0.0 + com.baeldung + apache-spark + 1.0-SNAPSHOT + apache-spark + jar + http://maven.apache.org - - com.baeldung - parent-modules - 1.0.0-SNAPSHOT - + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + - - - org.apache.spark - spark-core_2.11 - ${org.apache.spark.spark-core.version} - provided - + - org.apache.spark - spark-sql_2.11 - ${org.apache.spark.spark-sql.version} - provided + org.apache.spark + spark-core_2.11 + ${org.apache.spark.spark-core.version} + provided + + + org.apache.spark + spark-sql_2.11 + ${org.apache.spark.spark-sql.version} + provided org.apache.spark @@ -33,6 +34,12 @@ ${org.apache.spark.spark-streaming.version} provided + + org.apache.spark + spark-mllib_2.11 + ${org.apache.spark.spark-mllib.version} + provided + org.apache.spark spark-streaming-kafka-0-10_2.11 @@ -48,46 +55,47 @@ spark-cassandra-connector-java_2.11 ${com.datastax.spark.spark-cassandra-connector-java.version} - + - - - org.apache.maven.plugins - maven-compiler-plugin - ${maven-compiler-plugin.version} - - ${java.version} - ${java.version} - - - - maven-assembly-plugin - - - package - - single - - - - - - jar-with-dependencies - - - - - + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + ${java.version} + ${java.version} + + + + maven-assembly-plugin + + + package + + single + + + + + + jar-with-dependencies + + + + + - - 2.3.0 - 2.3.0 - 2.3.0 - 2.3.0 - 2.3.0 - 1.5.2 + + 2.3.0 + 2.3.0 + 2.3.0 + 2.3.0 + 2.3.0 + 2.3.0 + 1.5.2 3.2 - + diff --git a/apache-spark/src/main/java/com/baeldung/ml/MachineLearningApp.java b/apache-spark/src/main/java/com/baeldung/ml/MachineLearningApp.java new file mode 100644 index 0000000000..6094683031 --- /dev/null +++ b/apache-spark/src/main/java/com/baeldung/ml/MachineLearningApp.java @@ -0,0 +1,111 @@ +package com.baeldung.ml; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.log4j.Level; +import org.apache.log4j.Logger; +import org.apache.spark.SparkConf; +import org.apache.spark.api.java.JavaPairRDD; +import org.apache.spark.api.java.JavaRDD; +import org.apache.spark.api.java.JavaSparkContext; +import org.apache.spark.mllib.classification.LogisticRegressionModel; +import org.apache.spark.mllib.classification.LogisticRegressionWithLBFGS; +import org.apache.spark.mllib.evaluation.MulticlassMetrics; +import org.apache.spark.mllib.linalg.Matrix; +import org.apache.spark.mllib.linalg.Vector; +import org.apache.spark.mllib.linalg.Vectors; +import org.apache.spark.mllib.regression.LabeledPoint; +import org.apache.spark.mllib.stat.MultivariateStatisticalSummary; +import org.apache.spark.mllib.stat.Statistics; + +import scala.Tuple2; + +public class MachineLearningApp { + + public static void main(String[] args) { + + // 1. Setting the Spark Context + SparkConf conf = new SparkConf().setAppName("Main") + .setMaster("local[2]") + .set("spark.executor.memory", "3g") + .set("spark.driver.memory", "3g"); + JavaSparkContext sc = new JavaSparkContext(conf); + Logger.getLogger("org") + .setLevel(Level.OFF); + Logger.getLogger("akka") + .setLevel(Level.OFF); + + // 2. Loading the Data-set + String dataFile = "data\\iris.data"; + JavaRDD data = sc.textFile(dataFile); + + // 3. Exploratory Data Analysis + // 3.1. Creating Vector of Input Data + JavaRDD inputData = data.map(line -> { + String[] parts = line.split(","); + double[] v = new double[parts.length - 1]; + for (int i = 0; i < parts.length - 1; i++) { + v[i] = Double.parseDouble(parts[i]); + } + return Vectors.dense(v); + }); + // 3.2. Performing Statistical Analysis + MultivariateStatisticalSummary summary = Statistics.colStats(inputData.rdd()); + System.out.println("Summary Mean:"); + System.out.println(summary.mean()); + System.out.println("Summary Variance:"); + System.out.println(summary.variance()); + System.out.println("Summary Non-zero:"); + System.out.println(summary.numNonzeros()); + // 3.3. Performing Correlation Analysis + Matrix correlMatrix = Statistics.corr(inputData.rdd(), "pearson"); + System.out.println("Correlation Matrix:"); + System.out.println(correlMatrix.toString()); + + // 4. Data Preparation + // 4.1. Creating Map for Textual Output Labels + Map map = new HashMap(); + map.put("Iris-setosa", 0); + map.put("Iris-versicolor", 1); + map.put("Iris-virginica", 2); + // 4.2. Creating LabeledPoint of Input and Output Data + JavaRDD parsedData = data.map(line -> { + String[] parts = line.split(","); + double[] v = new double[parts.length - 1]; + for (int i = 0; i < parts.length - 1; i++) { + v[i] = Double.parseDouble(parts[i]); + } + return new LabeledPoint(map.get(parts[parts.length - 1]), Vectors.dense(v)); + }); + + // 5. Data Splitting into 80% Training and 20% Test Sets + JavaRDD[] splits = parsedData.randomSplit(new double[] { 0.8, 0.2 }, 11L); + JavaRDD trainingData = splits[0].cache(); + JavaRDD testData = splits[1]; + + // 6. Modeling + // 6.1. Model Training + LogisticRegressionModel model = new LogisticRegressionWithLBFGS().setNumClasses(3) + .run(trainingData.rdd()); + // 6.2. Model Evaluation + JavaPairRDD predictionAndLabels = testData.mapToPair(p -> new Tuple2<>(model.predict(p.features()), p.label())); + MulticlassMetrics metrics = new MulticlassMetrics(predictionAndLabels.rdd()); + double accuracy = metrics.accuracy(); + System.out.println("Model Accuracy on Test Data: " + accuracy); + + // 7. Model Saving and Loading + // 7.1. Model Saving + model.save(sc.sc(), "model\\logistic-regression"); + // 7.2. Model Loading + LogisticRegressionModel sameModel = LogisticRegressionModel.load(sc.sc(), "model\\logistic-regression"); + // 7.3. Prediction on New Data + Vector newData = Vectors.dense(new double[] { 1, 1, 1, 1 }); + double prediction = sameModel.predict(newData); + System.out.println("Model Prediction on New Data = " + prediction); + + // 8. Clean-up + sc.close(); + } + +} diff --git a/bazel/README.md b/bazel/README.md new file mode 100644 index 0000000000..d1f8f1af5b --- /dev/null +++ b/bazel/README.md @@ -0,0 +1,3 @@ +## Relevant Articles: + +- [Building Java Applications with Bazel](https://www.baeldung.com/bazel-build-tool) diff --git a/bazel/WORKSPACE b/bazel/WORKSPACE new file mode 100644 index 0000000000..415aa398f9 --- /dev/null +++ b/bazel/WORKSPACE @@ -0,0 +1,31 @@ + +load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_jar") +load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") + + +RULES_JVM_EXTERNAL_TAG = "2.0.1" +RULES_JVM_EXTERNAL_SHA = "55e8d3951647ae3dffde22b4f7f8dee11b3f70f3f89424713debd7076197eaca" + +http_archive( + name = "rules_jvm_external", + strip_prefix = "rules_jvm_external-%s" % RULES_JVM_EXTERNAL_TAG, + sha256 = RULES_JVM_EXTERNAL_SHA, + url = "https://github.com/bazelbuild/rules_jvm_external/archive/%s.zip" % RULES_JVM_EXTERNAL_TAG, +) + +load("@rules_jvm_external//:defs.bzl", "maven_install") + +maven_install( + artifacts = [ + "org.apache.commons:commons-lang3:3.9" + ], + repositories = [ + "https://repo1.maven.org/maven2", + ] +) + +http_jar ( + name = "apache-commons-lang", + url = "https://repo1.maven.org/maven2/org/apache/commons/commons-lang3/3.9/commons-lang3-3.9.jar" +) + diff --git a/bazel/bazelapp/BUILD b/bazel/bazelapp/BUILD new file mode 100644 index 0000000000..1de95aada5 --- /dev/null +++ b/bazel/bazelapp/BUILD @@ -0,0 +1,7 @@ + +java_binary ( + name = "BazelApp", + srcs = glob(["src/main/java/com/baeldung/*.java"]), + main_class = "com.baeldung.BazelApp", + deps = ["//bazelgreeting:greeter", "@maven//:org_apache_commons_commons_lang3"] +) diff --git a/bazel/bazelapp/pom.xml b/bazel/bazelapp/pom.xml new file mode 100644 index 0000000000..9c9fb59619 --- /dev/null +++ b/bazel/bazelapp/pom.xml @@ -0,0 +1,29 @@ + + + 4.0.0 + bazelapp + bazelapp + + + bazel + com.baeldung + 1.0.0-SNAPSHOT + + + + + com.baeldung + bazelgreeting + 1.0.0-SNAPSHOT + + + org.apache.commons + commons-lang3 + 3.9 + + + + + \ No newline at end of file diff --git a/bazel/bazelapp/src/main/java/com/baeldung/BazelApp.java b/bazel/bazelapp/src/main/java/com/baeldung/BazelApp.java new file mode 100644 index 0000000000..e92d85018b --- /dev/null +++ b/bazel/bazelapp/src/main/java/com/baeldung/BazelApp.java @@ -0,0 +1,15 @@ +package com.baeldung; + +import com.baeldung.Greetings; +import org.apache.commons.lang3.StringUtils; + +public class BazelApp { + + public static void main(String ... args) { + Greetings greetings = new Greetings(); + + System.out.println(greetings.greet("Bazel")); + + System.out.println(StringUtils.lowerCase("Bazel")); + } +} diff --git a/bazel/bazelgreeting/BUILD b/bazel/bazelgreeting/BUILD new file mode 100644 index 0000000000..6cd8bc13f7 --- /dev/null +++ b/bazel/bazelgreeting/BUILD @@ -0,0 +1,6 @@ + +java_library ( + name = "greeter", + srcs = glob(["src/main/java/com/baeldung/*.java"]), + visibility = ["//bazelapp:__pkg__"] +) diff --git a/bazel/bazelgreeting/pom.xml b/bazel/bazelgreeting/pom.xml new file mode 100644 index 0000000000..e688a55bd5 --- /dev/null +++ b/bazel/bazelgreeting/pom.xml @@ -0,0 +1,16 @@ + + + 4.0.0 + bazelgreeting + bazelgreeting + + + bazel + com.baeldung + 1.0.0-SNAPSHOT + + + + \ No newline at end of file diff --git a/bazel/bazelgreeting/src/main/java/com/baeldung/Greetings.java b/bazel/bazelgreeting/src/main/java/com/baeldung/Greetings.java new file mode 100644 index 0000000000..0e8fae7fbe --- /dev/null +++ b/bazel/bazelgreeting/src/main/java/com/baeldung/Greetings.java @@ -0,0 +1,8 @@ +package com.baeldung; + +public class Greetings { + + public String greet(String name) { + return "Hello ".concat(name); + } +} diff --git a/bazel/pom.xml b/bazel/pom.xml new file mode 100644 index 0000000000..cb784ec6e6 --- /dev/null +++ b/bazel/pom.xml @@ -0,0 +1,22 @@ + + + 4.0.0 + bazel + pom + bazel + + + parent-modules + com.baeldung + 1.0.0-SNAPSHOT + + + + bazelgreeting + bazelapp + + + + \ No newline at end of file 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-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/core-java-modules/core-java-arrays-2/README.MD b/core-java-modules/core-java-arrays-2/README.MD index 9ee6998784..f272f4d299 100644 --- a/core-java-modules/core-java-arrays-2/README.MD +++ b/core-java-modules/core-java-arrays-2/README.MD @@ -1,3 +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/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-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..26354de0a9 --- /dev/null +++ b/core-java-modules/core-java-concurrency-basic/src/main/java/com/baeldung/concurrent/mutex/SequenceGenerator.java @@ -0,0 +1,12 @@ +package com.baeldung.concurrent.mutex; + +public class SequenceGenerator { + + private int currentValue = 0; + + public int getNextSequence() { + currentValue = currentValue + 1; + 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..2824237e24 --- /dev/null +++ b/core-java-modules/core-java-concurrency-basic/src/main/java/com/baeldung/concurrent/mutex/SequenceGeneratorUsingMonitor.java @@ -0,0 +1,19 @@ +package com.baeldung.concurrent.mutex; + +import com.google.common.util.concurrent.Monitor; + +public class SequenceGeneratorUsingMonitor extends SequenceGenerator { + + private Monitor mutex = new Monitor(); + + @Override + public int getNextSequence() { + mutex.enter(); + try { + return super.getNextSequence(); + } finally { + mutex.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..d57b0c4a52 --- /dev/null +++ b/core-java-modules/core-java-concurrency-basic/src/main/java/com/baeldung/concurrent/mutex/SequenceGeneratorUsingReentrantLock.java @@ -0,0 +1,19 @@ +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() { + 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..50f2538646 --- /dev/null +++ b/core-java-modules/core-java-concurrency-basic/src/main/java/com/baeldung/concurrent/mutex/SequenceGeneratorUsingSemaphore.java @@ -0,0 +1,21 @@ +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() { + try { + mutex.acquire(); + return super.getNextSequence(); + } catch (InterruptedException e) { + throw new RuntimeException("Exception in critical section.", e); + } 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..9933c302cb --- /dev/null +++ b/core-java-modules/core-java-concurrency-basic/src/main/java/com/baeldung/concurrent/mutex/SequenceGeneratorUsingSynchronizedBlock.java @@ -0,0 +1,14 @@ +package com.baeldung.concurrent.mutex; + +public class SequenceGeneratorUsingSynchronizedBlock extends SequenceGenerator { + + private Object mutex = new Object(); + + @Override + public int getNextSequence() { + synchronized (mutex) { + 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..6de8725d73 --- /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() { + return super.getNextSequence(); + } + +} diff --git a/core-java-modules/core-java-concurrency-basic/src/test/java/com/baeldung/java8/Java8ExecutorServiceIntegrationTest.java b/core-java-modules/core-java-concurrency-basic/src/test/java/com/baeldung/concurrent/executorservice/Java8ExecutorServiceIntegrationTest.java similarity index 99% rename from core-java-modules/core-java-concurrency-basic/src/test/java/com/baeldung/java8/Java8ExecutorServiceIntegrationTest.java rename to core-java-modules/core-java-concurrency-basic/src/test/java/com/baeldung/concurrent/executorservice/Java8ExecutorServiceIntegrationTest.java index a1f5b6f1e2..998152c452 100644 --- a/core-java-modules/core-java-concurrency-basic/src/test/java/com/baeldung/java8/Java8ExecutorServiceIntegrationTest.java +++ b/core-java-modules/core-java-concurrency-basic/src/test/java/com/baeldung/concurrent/executorservice/Java8ExecutorServiceIntegrationTest.java @@ -1,4 +1,4 @@ -package com.baeldung.java8; +package com.baeldung.concurrent.executorservice; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; 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..462f910718 --- /dev/null +++ b/core-java-modules/core-java-concurrency-basic/src/test/java/com/baeldung/concurrent/mutex/MutexUnitTest.java @@ -0,0 +1,80 @@ +package com.baeldung.concurrent.mutex; + +import java.util.ArrayList; +import java.util.LinkedHashSet; +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; + +public class MutexUnitTest { + + // @Test + // This test verifies the race condition use case, it may pass or fail based on execution environment + // Uncomment @Test to run it + public void givenUnsafeSequenceGenerator_whenRaceCondition_thenUnexpectedBehavior() throws Exception { + int count = 1000; + Set uniqueSequences = getUniqueSequences(new SequenceGenerator(), count); + Assert.assertNotEquals(count, uniqueSequences.size()); + } + + @Test + public void givenSequenceGeneratorUsingSynchronizedMethod_whenRaceCondition_thenSuccess() throws Exception { + int count = 1000; + Set uniqueSequences = getUniqueSequences(new SequenceGeneratorUsingSynchronizedMethod(), count); + Assert.assertEquals(count, uniqueSequences.size()); + } + + @Test + public void givenSequenceGeneratorUsingSynchronizedBlock_whenRaceCondition_thenSuccess() throws Exception { + int count = 1000; + Set uniqueSequences = getUniqueSequences(new SequenceGeneratorUsingSynchronizedBlock(), count); + Assert.assertEquals(count, uniqueSequences.size()); + } + + @Test + public void givenSequenceGeneratorUsingReentrantLock_whenRaceCondition_thenSuccess() throws Exception { + int count = 1000; + Set uniqueSequences = getUniqueSequences(new SequenceGeneratorUsingReentrantLock(), count); + Assert.assertEquals(count, uniqueSequences.size()); + } + + @Test + public void givenSequenceGeneratorUsingSemaphore_whenRaceCondition_thenSuccess() throws Exception { + int count = 1000; + Set uniqueSequences = getUniqueSequences(new SequenceGeneratorUsingSemaphore(), count); + Assert.assertEquals(count, uniqueSequences.size()); + } + + @Test + public void givenSequenceGeneratorUsingMonitor_whenRaceCondition_thenSuccess() throws Exception { + int count = 1000; + Set uniqueSequences = getUniqueSequences(new SequenceGeneratorUsingMonitor(), count); + Assert.assertEquals(count, uniqueSequences.size()); + } + + private Set getUniqueSequences(SequenceGenerator generator, int count) throws Exception { + ExecutorService executor = Executors.newFixedThreadPool(3); + Set uniqueSequences = new LinkedHashSet<>(); + List> futures = new ArrayList<>(); + + for (int i = 0; i < count; i++) { + futures.add(executor.submit(generator::getNextSequence)); + } + + for (Future future : futures) { + uniqueSequences.add(future.get()); + } + + executor.awaitTermination(1, 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-exceptions/src/main/java/com/baeldung/exceptions/CheckedUncheckedExceptions.java b/core-java-modules/core-java-exceptions/src/main/java/com/baeldung/exceptions/CheckedUncheckedExceptions.java new file mode 100644 index 0000000000..780189b654 --- /dev/null +++ b/core-java-modules/core-java-exceptions/src/main/java/com/baeldung/exceptions/CheckedUncheckedExceptions.java @@ -0,0 +1,43 @@ +package com.baeldung.exceptions; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; + +public class CheckedUncheckedExceptions { + public static void checkedExceptionWithThrows() throws FileNotFoundException { + File file = new File("not_existing_file.txt"); + FileInputStream stream = new FileInputStream(file); + } + + public static void checkedExceptionWithTryCatch() { + File file = new File("not_existing_file.txt"); + try { + FileInputStream stream = new FileInputStream(file); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + } + + public static int divideByZero() { + int numerator = 1; + int denominator = 0; + return numerator / denominator; + } + + public static void checkFile(String fileName) throws IncorrectFileNameException { + if (fileName == null || fileName.isEmpty()) { + throw new NullOrEmptyException("The filename is null."); + } + if (!isCorrectFileName(fileName)) { + throw new IncorrectFileNameException("Incorrect filename : " + fileName); + } + } + + private static boolean isCorrectFileName(String fileName) { + if (fileName.equals("wrongFileName.txt")) + return false; + else + return true; + } +} diff --git a/core-java-modules/core-java-exceptions/src/main/java/com/baeldung/exceptions/IncorrectFileNameException.java b/core-java-modules/core-java-exceptions/src/main/java/com/baeldung/exceptions/IncorrectFileNameException.java new file mode 100644 index 0000000000..9877fe25ca --- /dev/null +++ b/core-java-modules/core-java-exceptions/src/main/java/com/baeldung/exceptions/IncorrectFileNameException.java @@ -0,0 +1,13 @@ +package com.baeldung.exceptions; + +public class IncorrectFileNameException extends Exception { + private static final long serialVersionUID = 1L; + + public IncorrectFileNameException(String errorMessage) { + super(errorMessage); + } + + public IncorrectFileNameException(String errorMessage, Throwable thr) { + super(errorMessage, thr); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-exceptions/src/main/java/com/baeldung/exceptions/NullOrEmptyException.java b/core-java-modules/core-java-exceptions/src/main/java/com/baeldung/exceptions/NullOrEmptyException.java new file mode 100644 index 0000000000..d4ee9c0d6f --- /dev/null +++ b/core-java-modules/core-java-exceptions/src/main/java/com/baeldung/exceptions/NullOrEmptyException.java @@ -0,0 +1,14 @@ +package com.baeldung.exceptions; + +public class NullOrEmptyException extends RuntimeException { + + private static final long serialVersionUID = 1L; + + public NullOrEmptyException(String errorMessage) { + super(errorMessage); + } + + public NullOrEmptyException(String errorMessage, Throwable thr) { + super(errorMessage, thr); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-exceptions/src/test/java/com/baeldung/exceptions/CheckedUncheckedExceptionsUnitTest.java b/core-java-modules/core-java-exceptions/src/test/java/com/baeldung/exceptions/CheckedUncheckedExceptionsUnitTest.java new file mode 100644 index 0000000000..d82b1349d8 --- /dev/null +++ b/core-java-modules/core-java-exceptions/src/test/java/com/baeldung/exceptions/CheckedUncheckedExceptionsUnitTest.java @@ -0,0 +1,55 @@ +package com.baeldung.exceptions; + +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.io.FileNotFoundException; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +/** + * Tests the {@link CheckedUncheckedExceptions}. + */ +public class CheckedUncheckedExceptionsUnitTest { + + @Test + public void whenFileNotExist_thenThrowException() { + assertThrows(FileNotFoundException.class, () -> { + CheckedUncheckedExceptions.checkedExceptionWithThrows(); + }); + } + + @Test + public void whenTryCatchExcetpion_thenSuccess() { + try { + CheckedUncheckedExceptions.checkedExceptionWithTryCatch(); + } catch (Exception e) { + Assertions.fail(e.getMessage()); + } + } + + @Test + public void whenDivideByZero_thenThrowException() { + assertThrows(ArithmeticException.class, () -> { + CheckedUncheckedExceptions.divideByZero(); + }); + } + + @Test + public void whenInvalidFile_thenThrowException() { + + assertThrows(IncorrectFileNameException.class, () -> { + CheckedUncheckedExceptions.checkFile("wrongFileName.txt"); + }); + } + + @Test + public void whenNullOrEmptyFile_thenThrowException() { + assertThrows(NullOrEmptyException.class, () -> { + CheckedUncheckedExceptions.checkFile(null); + }); + assertThrows(NullOrEmptyException.class, () -> { + CheckedUncheckedExceptions.checkFile(""); + }); + } +} diff --git a/core-java-modules/core-java-io-2/.gitignore b/core-java-modules/core-java-io-2/.gitignore new file mode 100644 index 0000000000..de044ef20f --- /dev/null +++ b/core-java-modules/core-java-io-2/.gitignore @@ -0,0 +1,3 @@ +# Intellij +.idea/ +*.iml diff --git a/core-java-modules/core-java-io-2/pom.xml b/core-java-modules/core-java-io-2/pom.xml new file mode 100644 index 0000000000..64d9434beb --- /dev/null +++ b/core-java-modules/core-java-io-2/pom.xml @@ -0,0 +1,279 @@ + + 4.0.0 + core-java-io-2 + 0.1.0-SNAPSHOT + core-java-io-2 + jar + + + com.baeldung + parent-java + 0.0.1-SNAPSHOT + ../../parent-java + + + + + + net.sourceforge.collections + collections-generic + ${collections-generic.version} + + + org.apache.commons + commons-collections4 + ${commons-collections4.version} + + + commons-io + commons-io + ${commons-io.version} + + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + + + org.apache.commons + commons-math3 + ${commons-math3.version} + + + org.decimal4j + decimal4j + ${decimal4j.version} + + + org.bouncycastle + bcprov-jdk15on + ${bouncycastle.version} + + + org.unix4j + unix4j-command + ${unix4j.version} + + + com.googlecode.grep4j + grep4j + ${grep4j.version} + + + + + com.fasterxml.jackson.core + jackson-databind + ${jackson.version} + + + + log4j + log4j + ${log4j.version} + + + org.slf4j + log4j-over-slf4j + ${org.slf4j.version} + + + org.projectlombok + lombok + ${lombok.version} + provided + + + + org.assertj + assertj-core + ${assertj.version} + test + + + com.jayway.awaitility + awaitility + ${avaitility.version} + test + + + commons-codec + commons-codec + ${commons-codec.version} + + + org.javamoney + moneta + ${moneta.version} + + + org.owasp.esapi + esapi + ${esapi.version} + + + com.sun.messaging.mq + fscontext + ${fscontext.version} + + + com.codepoetics + protonpack + ${protonpack.version} + + + one.util + streamex + ${streamex.version} + + + io.vavr + vavr + ${vavr.version} + + + org.openjdk.jmh + jmh-core + ${jmh-core.version} + + + org.openjdk.jmh + jmh-generator-annprocess + ${jmh-generator-annprocess.version} + + + org.hsqldb + hsqldb + ${hsqldb.version} + runtime + + + + org.asynchttpclient + async-http-client + ${async-http-client.version} + + + com.opencsv + opencsv + ${opencsv.version} + test + + + + org.apache.tika + tika-core + ${tika.version} + + + net.sf.jmimemagic + jmimemagic + ${jmime-magic.version} + + + + + core-java-io-2 + + + src/main/resources + true + + + + + org.codehaus.mojo + exec-maven-plugin + ${exec-maven-plugin.version} + + java + com.baeldung.outofmemoryerror.OutOfMemoryGCLimitExceed + + -Xmx300m + -XX:+UseParallelGC + -classpath + + com.baeldung.outofmemoryerror.OutOfMemoryGCLimitExceed + + + + + org.apache.maven.plugins + maven-javadoc-plugin + ${maven-javadoc-plugin.version} + + ${maven.compiler.source} + ${maven.compiler.target} + + + + + + + + integration + + + + org.codehaus.mojo + exec-maven-plugin + + + + run-benchmarks + + none + + exec + + + test + java + + -classpath + + org.openjdk.jmh.Main + .* + + + + + + + + + + + + + + 1.55 + 1.10 + 3.6.1 + 1.0.3 + 4.1 + 4.01 + 0.4 + 1.8.7 + 4.6-b01 + 1.13 + 0.6.5 + 0.9.0 + 4.1 + + 3.6.1 + 1.7.0 + + + 3.0.0-M1 + 2.4.0 + 2.1.0.1 + 1.19 + 2.4.5 + + 1.18 + 0.1.5 + + + \ No newline at end of file diff --git a/core-java-modules/core-java-io-2/src/main/java/com/baeldung/filereader/FileReaderExample.java b/core-java-modules/core-java-io-2/src/main/java/com/baeldung/filereader/FileReaderExample.java new file mode 100644 index 0000000000..34a8f61615 --- /dev/null +++ b/core-java-modules/core-java-io-2/src/main/java/com/baeldung/filereader/FileReaderExample.java @@ -0,0 +1,57 @@ +package com.baeldung.filereader; + +import java.io.*; + +public class FileReaderExample { + + public static String readAllCharactersOneByOne(Reader reader) throws IOException { + StringBuilder content = new StringBuilder(); + int nextChar; + while ((nextChar = reader.read()) != -1) { + content.append((char) nextChar); + } + return String.valueOf(content); + } + + public static String readMultipleCharacters(Reader reader, int length) throws IOException { + char[] buffer = new char[length]; + int charactersRead = reader.read(buffer, 0, length); + + + if (charactersRead != -1) { + return new String(buffer, 0, charactersRead); + } else { + return ""; + } + } + + public static String readFile(String path) { + FileReader fileReader = null; + try { + fileReader = new FileReader(path); + return readAllCharactersOneByOne(fileReader); + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (fileReader != null) { + try { + fileReader.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return null; + } + + public static String readFileUsingTryWithResources(String path) { + try (FileReader fileReader = new FileReader(path)) { + return readAllCharactersOneByOne(fileReader); + } catch (IOException e) { + e.printStackTrace(); + } + return null; + } + + +} \ No newline at end of file diff --git a/core-java-modules/core-java-io-2/src/test/java/com/baeldung/filereader/FileReaderExampleUnitTest.java b/core-java-modules/core-java-io-2/src/test/java/com/baeldung/filereader/FileReaderExampleUnitTest.java new file mode 100644 index 0000000000..968c041115 --- /dev/null +++ b/core-java-modules/core-java-io-2/src/test/java/com/baeldung/filereader/FileReaderExampleUnitTest.java @@ -0,0 +1,62 @@ +package com.baeldung.filereader; + +import org.junit.Assert; +import org.junit.Test; + +import java.io.File; +import java.io.FileReader; +import java.io.IOException; + +public class FileReaderExampleUnitTest { + + + private static final String FILE_PATH = "src/test/resources/HelloWorld.txt"; + + + @Test + public void givenFileReader_whenReadAllCharacters_thenReturnsContent() throws IOException { + String expectedText = "Hello, World!"; + File file = new File(FILE_PATH); + FileReader fileReader = null; + try { + fileReader = new FileReader(file); + String content = FileReaderExample.readAllCharactersOneByOne(fileReader); + Assert.assertEquals(expectedText, content); + } finally { + if (fileReader != null) { + fileReader.close(); + } + } + } + + @Test + public void givenFileReader_whenReadMultipleCharacters_thenReturnsContent() throws IOException { + String expectedText = "Hello"; + File file = new File(FILE_PATH); + FileReader fileReader = null; + try { + fileReader = new FileReader(file); + String content = FileReaderExample.readMultipleCharacters(fileReader, 5); + Assert.assertEquals(expectedText, content); + } finally { + if (fileReader != null) { + fileReader.close(); + } + } + } + + @Test + public void whenReadFile_thenReturnsContent() { + String expectedText = "Hello, World!"; + String content = FileReaderExample.readFile(FILE_PATH); + Assert.assertEquals(expectedText, content); + } + + @Test + public void whenReadFileUsingTryWithResources_thenReturnsContent() { + String expectedText = "Hello, World!"; + String content = FileReaderExample.readFileUsingTryWithResources(FILE_PATH); + Assert.assertEquals(expectedText, content); + } + +} diff --git a/core-java-modules/core-java-io-2/src/test/resources/HelloWorld.txt b/core-java-modules/core-java-io-2/src/test/resources/HelloWorld.txt new file mode 100644 index 0000000000..b45ef6fec8 --- /dev/null +++ b/core-java-modules/core-java-io-2/src/test/resources/HelloWorld.txt @@ -0,0 +1 @@ +Hello, World! \ No newline at end of file diff --git a/core-java-modules/core-java-io/src/test/java/org/baeldung/java/io/JavaWriteToFileUnitTest.java b/core-java-modules/core-java-io/src/test/java/org/baeldung/writetofile/JavaWriteToFileUnitTest.java similarity index 99% rename from core-java-modules/core-java-io/src/test/java/org/baeldung/java/io/JavaWriteToFileUnitTest.java rename to core-java-modules/core-java-io/src/test/java/org/baeldung/writetofile/JavaWriteToFileUnitTest.java index 9ff95c4e16..bdc6b34b5c 100644 --- a/core-java-modules/core-java-io/src/test/java/org/baeldung/java/io/JavaWriteToFileUnitTest.java +++ b/core-java-modules/core-java-io/src/test/java/org/baeldung/writetofile/JavaWriteToFileUnitTest.java @@ -1,4 +1,4 @@ -package org.baeldung.java.io; +package org.baeldung.writetofile; import static org.junit.Assert.assertEquals; 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..7f621af21d --- /dev/null +++ b/core-java-modules/core-java-jndi/pom.xml @@ -0,0 +1,66 @@ + + + 4.0.0 + + com.baeldung.jndi + core-java-jndi + 1.0-SNAPSHOT + core-java-jndi + + + 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..433db0a9ca 100644 --- a/core-java-modules/core-java-lambdas/pom.xml +++ b/core-java-modules/core-java-lambdas/pom.xml @@ -5,7 +5,7 @@ 4.0.0 core-java-lambdas 0.1.0-SNAPSHOT - core-java + core-java-lambdas jar @@ -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-networking-2/.gitignore b/core-java-modules/core-java-lang-2/.gitignore similarity index 100% rename from core-java-modules/core-java-networking-2/.gitignore rename to core-java-modules/core-java-lang-2/.gitignore diff --git a/core-java-modules/core-java-lang-2/README.md b/core-java-modules/core-java-lang-2/README.md new file mode 100644 index 0000000000..88a48661a0 --- /dev/null +++ b/core-java-modules/core-java-lang-2/README.md @@ -0,0 +1,5 @@ +========= + +## Core Java Lang Cookbooks and Examples + +### Relevant Articles: diff --git a/core-java-modules/core-java-lang-2/pom.xml b/core-java-modules/core-java-lang-2/pom.xml new file mode 100644 index 0000000000..4b02e06be4 --- /dev/null +++ b/core-java-modules/core-java-lang-2/pom.xml @@ -0,0 +1,33 @@ + + 4.0.0 + com.baeldung + core-java-lang-2 + 0.1.0-SNAPSHOT + core-java-lang-2 + jar + + + com.baeldung + parent-java + 0.0.1-SNAPSHOT + ../../parent-java + + + + + + + core-java-lang-2 + + + src/main/resources + true + + + + + + + + diff --git a/core-java-modules/core-java-lang-2/src/main/java/com/baeldung/commandlinearguments/CliExample.java b/core-java-modules/core-java-lang-2/src/main/java/com/baeldung/commandlinearguments/CliExample.java new file mode 100644 index 0000000000..d6a7dec8aa --- /dev/null +++ b/core-java-modules/core-java-lang-2/src/main/java/com/baeldung/commandlinearguments/CliExample.java @@ -0,0 +1,12 @@ +package com.baeldung.commandlinearguments; + +public class CliExample { + + public static void main(String[] args) { + System.out.println("Argument count: " + args.length); + for (int i = 0; i < args.length; i++) { + System.out.println("Argument " + i + ": " + args[i]); + } + } + +} diff --git a/core-java-modules/core-java-lang-2/src/main/java/com/baeldung/commandlinearguments/CliExampleWithVarargs.java b/core-java-modules/core-java-lang-2/src/main/java/com/baeldung/commandlinearguments/CliExampleWithVarargs.java new file mode 100644 index 0000000000..899e03416e --- /dev/null +++ b/core-java-modules/core-java-lang-2/src/main/java/com/baeldung/commandlinearguments/CliExampleWithVarargs.java @@ -0,0 +1,12 @@ +package com.baeldung.commandlinearguments; + +public class CliExampleWithVarargs { + + public static void main(String... args) { + System.out.println("Argument count: " + args.length); + for (int i = 0; i < args.length; i++) { + System.out.println("Argument " + i + ": " + args[i]); + } + } + +} diff --git a/core-java-modules/core-java-lang-oop-2/pom.xml b/core-java-modules/core-java-lang-oop-2/pom.xml index 669a37b0f5..b7bd72372b 100644 --- a/core-java-modules/core-java-lang-oop-2/pom.xml +++ b/core-java-modules/core-java-lang-oop-2/pom.xml @@ -14,6 +14,19 @@ ../../parent-java + + + com.h2database + h2 + ${h2.version} + test + + + + + 1.4.199 + + core-java-lang-oop-2 diff --git a/core-java-modules/core-java-lang-oop-2/src/main/java/com/baeldung/accessmodifiers/publicmodifier/ListOfThree.java b/core-java-modules/core-java-lang-oop-2/src/main/java/com/baeldung/accessmodifiers/publicmodifier/ListOfThree.java new file mode 100644 index 0000000000..2ded0ba5d3 --- /dev/null +++ b/core-java-modules/core-java-lang-oop-2/src/main/java/com/baeldung/accessmodifiers/publicmodifier/ListOfThree.java @@ -0,0 +1,31 @@ +package com.baeldung.accessmodifiers.publicmodifier; + +import java.util.AbstractList; +import java.util.Arrays; + +public class ListOfThree extends AbstractList { + + private static final int LENGTH = 3; + private Object[] elements; + + public ListOfThree(E[] data) { + if(data == null + || data.length != LENGTH) + throw new IllegalArgumentException(); + + this.elements = Arrays.copyOf(data, data.length); //shallow copy + + } + + @Override + @SuppressWarnings("unchecked") + public E get(int index) { + return (E)elements[index]; + } + + @Override + public int size() { + return LENGTH; + } + +} diff --git a/core-java-modules/core-java-lang-oop-2/src/main/java/com/baeldung/accessmodifiers/publicmodifier/SpecialCharacters.java b/core-java-modules/core-java-lang-oop-2/src/main/java/com/baeldung/accessmodifiers/publicmodifier/SpecialCharacters.java new file mode 100644 index 0000000000..5556e9aa57 --- /dev/null +++ b/core-java-modules/core-java-lang-oop-2/src/main/java/com/baeldung/accessmodifiers/publicmodifier/SpecialCharacters.java @@ -0,0 +1,7 @@ +package com.baeldung.accessmodifiers.publicmodifier; + +public class SpecialCharacters { + + public static final String SLASH = "/"; + +} diff --git a/core-java-modules/core-java-lang-oop-2/src/main/java/com/baeldung/accessmodifiers/publicmodifier/Student.java b/core-java-modules/core-java-lang-oop-2/src/main/java/com/baeldung/accessmodifiers/publicmodifier/Student.java new file mode 100644 index 0000000000..83a0dcb30f --- /dev/null +++ b/core-java-modules/core-java-lang-oop-2/src/main/java/com/baeldung/accessmodifiers/publicmodifier/Student.java @@ -0,0 +1,67 @@ +package com.baeldung.accessmodifiers.publicmodifier; + +import java.math.BigDecimal; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; +import java.util.Date; + +public class Student { + + private StudentGrade grade; //new data representation +// private int grade; //old data representation + private String name; + private int age; + + public void setGrade(int grade) { + this.grade = new StudentGrade(grade); + } + + public int getGrade() { + return this.grade.getGrade().intValue(); //int is returned for backward compatibility + } + + public Connection getConnection() throws SQLException { + + final String URL = "jdbc:h2:~/test"; + return DriverManager.getConnection(URL, "sa", ""); + + } + + public void setAge(int age) { + if (age < 0 || age > 150) { + throw new IllegalArgumentException(); + } + + this.age = age; + } + + public int getAge() { + return age; + } + + @Override + public String toString() { + return this.name; + } + + private class StudentGrade { + private BigDecimal grade = BigDecimal.ZERO; + private Date updatedAt; + + public StudentGrade(int grade) { + this.grade = new BigDecimal(grade); + this.updatedAt = new Date(); + } + + public BigDecimal getGrade() { + return grade; + } + + public Date getDate() { + return updatedAt; + } + + } + +} diff --git a/core-java-modules/core-java-lang-oop-2/src/main/java/com/baeldung/core/modifiers/Employee.java b/core-java-modules/core-java-lang-oop-2/src/main/java/com/baeldung/core/modifiers/Employee.java new file mode 100644 index 0000000000..6ec68d6ebb --- /dev/null +++ b/core-java-modules/core-java-lang-oop-2/src/main/java/com/baeldung/core/modifiers/Employee.java @@ -0,0 +1,59 @@ +package com.baeldung.core.modifiers; + +public class Employee { + + private String privateId; + private String name; + private boolean manager; + + public Employee(String id, String name) { + setPrivateId(id); + setName(name); + } + + private Employee(String id, String name, boolean managerAttribute) { + this.privateId = id; + this.name = name; + this.privateId = id + "_ID-MANAGER"; + } + + public void setPrivateId(String customId) { + if (customId.endsWith("_ID")) { + this.privateId = customId; + } else { + this.privateId = customId + "_ID"; + } + } + + public String getPrivateId() { + return privateId; + } + + public boolean isManager() { + return manager; + } + + public void elevateToManager() { + if ("Carl".equals(this.name)) { + setManager(true); + } + } + + private void setManager(boolean manager) { + this.manager = manager; + } + + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public static Employee buildManager(String id, String name) { + return new Employee(id, name, true); + } + +} diff --git a/core-java-modules/core-java-lang-oop-2/src/main/java/com/baeldung/core/modifiers/ExampleClass.java b/core-java-modules/core-java-lang-oop-2/src/main/java/com/baeldung/core/modifiers/ExampleClass.java new file mode 100644 index 0000000000..41f0b7a690 --- /dev/null +++ b/core-java-modules/core-java-lang-oop-2/src/main/java/com/baeldung/core/modifiers/ExampleClass.java @@ -0,0 +1,10 @@ +package com.baeldung.core.modifiers; + +public class ExampleClass { + + public static void main(String[] args) { + Employee employee = new Employee("Bob","ABC123"); + employee.setPrivateId("BCD234"); + System.out.println(employee.getPrivateId()); + } +} diff --git a/core-java-modules/core-java-lang-oop-2/src/main/java/com/baeldung/core/modifiers/PublicOuterClass.java b/core-java-modules/core-java-lang-oop-2/src/main/java/com/baeldung/core/modifiers/PublicOuterClass.java new file mode 100644 index 0000000000..329ebf3bb6 --- /dev/null +++ b/core-java-modules/core-java-lang-oop-2/src/main/java/com/baeldung/core/modifiers/PublicOuterClass.java @@ -0,0 +1,16 @@ +package com.baeldung.core.modifiers; + +public class PublicOuterClass { + + public PrivateInnerClass getInnerClassInstance() { + PrivateInnerClass myPrivateClassInstance = this.new PrivateInnerClass(); + myPrivateClassInstance.id = "ID1"; + myPrivateClassInstance.name = "Bob"; + return myPrivateClassInstance; + } + + private class PrivateInnerClass { + public String name; + public String id; + } +} 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-oop-2/src/test/java/com/baeldung/accessmodifiers/PublicAccessModifierUnitTest.java b/core-java-modules/core-java-lang-oop-2/src/test/java/com/baeldung/accessmodifiers/PublicAccessModifierUnitTest.java new file mode 100644 index 0000000000..a2d891ac93 --- /dev/null +++ b/core-java-modules/core-java-lang-oop-2/src/test/java/com/baeldung/accessmodifiers/PublicAccessModifierUnitTest.java @@ -0,0 +1,93 @@ +package com.baeldung.accessmodifiers; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.api.TestInstance.Lifecycle; +import com.baeldung.accessmodifiers.publicmodifier.ListOfThree; +import com.baeldung.accessmodifiers.publicmodifier.Student; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertEquals; +import java.math.BigDecimal; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@TestInstance(Lifecycle.PER_CLASS) +public class PublicAccessModifierUnitTest { + + @Test + public void whenUsingBigDecimalIntValueMethod_correspondingIntIsReturned() { + assertEquals(0, new BigDecimal(0).intValue()); //instance member + } + + @Test + public void whenUsingIntegerMaxValueField_maxPossibleIntValueIsReturned() { + assertEquals(2147483647, Integer.MAX_VALUE); //static field + } + + @Test + public void whenChangingStudentInternalRepresentation_clientCodeWillNotBreak() { + + Student student = new Student(); + student.setGrade(100); + + assertEquals(100, student.getGrade()); + } + + @Test + public void whenUsingEntrySet_keyValuePairsAreReturned() { + + Map mapObject = new HashMap(); + mapObject.put("name", "Alex"); + + for(Map.Entry entry : mapObject.entrySet()) { + assertEquals("name", entry.getKey()); + assertEquals("Alex", entry.getValue()); + } + + } + + @Test + public void whenUsingStringToLowerCase_stringTurnsToLowerCase() { + assertEquals("alex", "ALEX".toLowerCase()); + } + + @Test + public void whenParsingStringOne_parseIntReturns1() { + assertEquals(1, Integer.parseInt("1")); + } + + @Test + public void whenConnectingToH2_connectionInstanceIsReturned() throws SQLException { + + final String url = "jdbc:h2:~/test"; + Connection conn = DriverManager.getConnection(url, "sa", ""); + assertNotNull(conn); + } + + @Test + public void whenCreatingCustomList_concreteAndInheritedMethodsWork() { + + String[] dataSet1 = new String[] {"zero", "one", "two"}; + + List list1 = new ListOfThree(dataSet1); + + //our implemented methods + assertEquals("one", list1.get(1)); + assertEquals(3, list1.size()); + + //inherited implementations + assertEquals(1, list1.indexOf("one")); + + String[] dataSet2 = new String[] {"two", "zero", "one"}; + List list2 = new ListOfThree(dataSet2); + + assertTrue(list1.containsAll(list2)); + } + +} 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/src/main/java/com/baeldung/http/FullResponseBuilder.java b/core-java-modules/core-java-networking/src/main/java/com/baeldung/httprequest/FullResponseBuilder.java similarity index 98% rename from core-java-modules/core-java-networking/src/main/java/com/baeldung/http/FullResponseBuilder.java rename to core-java-modules/core-java-networking/src/main/java/com/baeldung/httprequest/FullResponseBuilder.java index 394255bd70..cc9d79aa65 100644 --- a/core-java-modules/core-java-networking/src/main/java/com/baeldung/http/FullResponseBuilder.java +++ b/core-java-modules/core-java-networking/src/main/java/com/baeldung/httprequest/FullResponseBuilder.java @@ -1,4 +1,4 @@ -package com.baeldung.http; +package com.baeldung.httprequest; import java.io.BufferedReader; import java.io.IOException; diff --git a/core-java-modules/core-java-networking/src/main/java/com/baeldung/http/ParameterStringBuilder.java b/core-java-modules/core-java-networking/src/main/java/com/baeldung/httprequest/ParameterStringBuilder.java similarity index 95% rename from core-java-modules/core-java-networking/src/main/java/com/baeldung/http/ParameterStringBuilder.java rename to core-java-modules/core-java-networking/src/main/java/com/baeldung/httprequest/ParameterStringBuilder.java index bed4195faa..f91ab332c7 100644 --- a/core-java-modules/core-java-networking/src/main/java/com/baeldung/http/ParameterStringBuilder.java +++ b/core-java-modules/core-java-networking/src/main/java/com/baeldung/httprequest/ParameterStringBuilder.java @@ -1,4 +1,4 @@ -package com.baeldung.http; +package com.baeldung.httprequest; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; diff --git a/core-java-modules/core-java-networking/src/test/java/com/baeldung/http/HttpRequestLiveTest.java b/core-java-modules/core-java-networking/src/test/java/com/baeldung/httprequest/HttpRequestLiveTest.java similarity index 97% rename from core-java-modules/core-java-networking/src/test/java/com/baeldung/http/HttpRequestLiveTest.java rename to core-java-modules/core-java-networking/src/test/java/com/baeldung/httprequest/HttpRequestLiveTest.java index bd6c0a4410..77bf9bc8db 100644 --- a/core-java-modules/core-java-networking/src/test/java/com/baeldung/http/HttpRequestLiveTest.java +++ b/core-java-modules/core-java-networking/src/test/java/com/baeldung/httprequest/HttpRequestLiveTest.java @@ -1,8 +1,11 @@ -package com.baeldung.http; +package com.baeldung.httprequest; import org.apache.commons.lang3.StringUtils; import org.junit.Test; +import com.baeldung.httprequest.FullResponseBuilder; +import com.baeldung.httprequest.ParameterStringBuilder; + import java.io.BufferedReader; import java.io.DataOutputStream; import java.io.IOException; 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-optional/pom.xml b/core-java-modules/core-java-optional/pom.xml index eb981c0907..ca6158ef5a 100644 --- a/core-java-modules/core-java-optional/pom.xml +++ b/core-java-modules/core-java-optional/pom.xml @@ -3,6 +3,7 @@ core-java-optional 0.1.0-SNAPSHOT jar + core-java-optional com.baeldung.core-java-modules 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-os/src/main/java/com/baeldung/system/exit/SystemExitExample.java b/core-java-modules/core-java-os/src/main/java/com/baeldung/system/exit/SystemExitExample.java new file mode 100644 index 0000000000..a9738a0448 --- /dev/null +++ b/core-java-modules/core-java-os/src/main/java/com/baeldung/system/exit/SystemExitExample.java @@ -0,0 +1,20 @@ +package com.baeldung.system.exit; + +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.IOException; + +public class SystemExitExample { + + public void readFile() { + try { + BufferedReader br = new BufferedReader(new FileReader("file.txt")); + System.out.println(br.readLine()); + br.close(); + } catch (IOException e) { + System.exit(2); + } finally { + System.out.println("Exiting the program"); + } + } +} diff --git a/core-java-modules/core-java-os/src/test/java/com/baeldung/system/exit/SystemExitUnitTest.java b/core-java-modules/core-java-os/src/test/java/com/baeldung/system/exit/SystemExitUnitTest.java new file mode 100644 index 0000000000..6d5f9c2f34 --- /dev/null +++ b/core-java-modules/core-java-os/src/test/java/com/baeldung/system/exit/SystemExitUnitTest.java @@ -0,0 +1,63 @@ +package com.baeldung.system.exit; + +import static org.junit.Assert.assertEquals; + +import java.security.Permission; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +public class SystemExitUnitTest { + + protected static class ExitException extends SecurityException { + + private static final long serialVersionUID = 1L; + public final int status; + + public ExitException(int status) { + this.status = status; + } + } + + private static class NoExitSecurityManager extends SecurityManager { + @Override + public void checkPermission(Permission perm) { + } + + @Override + public void checkPermission(Permission perm, Object context) { + } + + @Override + public void checkExit(int status) { + super.checkExit(status); + throw new ExitException(status); + } + } + + private SecurityManager securityManager; + + private SystemExitExample example; + + @Before + public void setUp() throws Exception { + example = new SystemExitExample(); + securityManager = System.getSecurityManager(); + System.setSecurityManager(new NoExitSecurityManager()); + } + + @After + public void tearDown() throws Exception { + System.setSecurityManager(securityManager); + } + + @Test + public void testExit() throws Exception { + try { + example.readFile(); + } catch (ExitException e) { + assertEquals("Exit status", 2, e.status); + } + } +} \ No newline at end of file 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 2dca62005d..ecf1f4147e 100644 --- a/core-java-modules/pom.xml +++ b/core-java-modules/pom.xml @@ -17,6 +17,7 @@ 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/gradle-5/build.gradle b/gradle-5/build.gradle new file mode 100644 index 0000000000..a728845dff --- /dev/null +++ b/gradle-5/build.gradle @@ -0,0 +1,54 @@ +plugins { + id "application" +} +apply plugin :"java" + +description = "Java MainClass execution examples" +group = "com.baeldung" +version = "0.0.1" +sourceCompatibility = "1.8" +targetCompatibility = "1.8" + +ext { + javaMainClass = "com.baeldung.gradle.exec.MainClass" +} + +jar { + manifest { + attributes( + "Main-Class": javaMainClass + ) + } +} + +application { + mainClassName = javaMainClass +} + +task runWithJavaExec(type: JavaExec) { + group = "Execution" + description = "Run the main class with JavaExecTask" + classpath = sourceSets.main.runtimeClasspath + main = javaMainClass +} + +task runWithExec(type: Exec) { + dependsOn build + group = "Execution" + description = "Run the main class with ExecTask" + commandLine "java", "-classpath", sourceSets.main.runtimeClasspath.getAsPath(), javaMainClass +} + +task runWithExecJarExecutable(type: Exec) { + dependsOn jar + group = "Execution" + description = "Run the output executable jar with ExecTask" + commandLine "java", "-jar", jar.archiveFile.get() +} + +task runWithExecJarOnClassPath(type: Exec) { + dependsOn jar + group = "Execution" + description = "Run the mainClass from the output jar in classpath with ExecTask" + commandLine "java", "-classpath", jar.archiveFile.get() , javaMainClass +} \ No newline at end of file diff --git a/gradle-5/gradle/wrapper/gradle-wrapper.jar b/gradle-5/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000..736fb7d3f9 Binary files /dev/null and b/gradle-5/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle-5/gradle/wrapper/gradle-wrapper.properties b/gradle-5/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000000..b33419deee --- /dev/null +++ b/gradle-5/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-5.5.1-bin.zip diff --git a/gradle-5/gradlew b/gradle-5/gradlew new file mode 100755 index 0000000000..27309d9231 --- /dev/null +++ b/gradle-5/gradlew @@ -0,0 +1,164 @@ +#!/usr/bin/env bash + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn ( ) { + echo "$*" +} + +die ( ) { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules +function splitJvmOpts() { + JVM_OPTS=("$@") +} +eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS +JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" + +exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/gradle-5/gradlew.bat b/gradle-5/gradlew.bat new file mode 100644 index 0000000000..832fdb6079 --- /dev/null +++ b/gradle-5/gradlew.bat @@ -0,0 +1,90 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args +if "%@eval[2+2]" == "4" goto 4NT_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* +goto execute + +:4NT_args +@rem Get arguments from the 4NT Shell from JP Software +set CMD_LINE_ARGS=%$ + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/gradle-5/src/main/java/com/baeldung/gradle/exec/MainClass.java b/gradle-5/src/main/java/com/baeldung/gradle/exec/MainClass.java new file mode 100644 index 0000000000..1e0c05389c --- /dev/null +++ b/gradle-5/src/main/java/com/baeldung/gradle/exec/MainClass.java @@ -0,0 +1,8 @@ +package com.baeldung.gradle.exec; + +public class MainClass { + + public static void main(String[] args) { + System.out.println("Goodbye cruel world ..."); + } +} diff --git a/guava-collections/src/test/java/org/baeldung/guava/GuavaMapInitializeUnitTest.java b/guava-collections/src/test/java/org/baeldung/guava/maps/initialize/GuavaMapInitializeUnitTest.java similarity index 95% rename from guava-collections/src/test/java/org/baeldung/guava/GuavaMapInitializeUnitTest.java rename to guava-collections/src/test/java/org/baeldung/guava/maps/initialize/GuavaMapInitializeUnitTest.java index 69a7505316..2414afb720 100644 --- a/guava-collections/src/test/java/org/baeldung/guava/GuavaMapInitializeUnitTest.java +++ b/guava-collections/src/test/java/org/baeldung/guava/maps/initialize/GuavaMapInitializeUnitTest.java @@ -1,4 +1,4 @@ -package org.baeldung.guava; +package org.baeldung.guava.maps.initialize; import static org.hamcrest.core.IsEqual.equalTo; import static org.junit.Assert.*; 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..920eaa91e8 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,5 @@ 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) +- [Calling Default Serializer from Custom Serializer in Jackson](https://www.baeldung.com/jackson-call-default-serializer-from-custom-serializer) 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-numbers-2/.gitignore b/java-blockchain/.gitignore similarity index 100% rename from java-numbers-2/.gitignore rename to java-blockchain/.gitignore diff --git a/java-blockchain/README.md b/java-blockchain/README.md new file mode 100644 index 0000000000..600f4dd610 --- /dev/null +++ b/java-blockchain/README.md @@ -0,0 +1,6 @@ +========= + +## Basic Implementation of Blockchian in Java + +### Relevant Articles: +- []() diff --git a/java-blockchain/pom.xml b/java-blockchain/pom.xml new file mode 100644 index 0000000000..2f9e011aa7 --- /dev/null +++ b/java-blockchain/pom.xml @@ -0,0 +1,40 @@ + + 4.0.0 + com.baeldung.blockchain + java-blockchain + 0.1.0-SNAPSHOT + java-blockchain + jar + + com.baeldung + parent-java + 0.0.1-SNAPSHOT + ../parent-java + + + java-blockchain + + + src/main/resources + true + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + ${maven.compiler.source} + ${maven.compiler.target} + + + + + + 1.8 + 1.8 + + \ No newline at end of file diff --git a/java-blockchain/src/main/java/com/baeldung/blockchain/Block.java b/java-blockchain/src/main/java/com/baeldung/blockchain/Block.java new file mode 100644 index 0000000000..264e3c4b69 --- /dev/null +++ b/java-blockchain/src/main/java/com/baeldung/blockchain/Block.java @@ -0,0 +1,65 @@ +package com.baeldung.blockchain; + +import java.io.UnsupportedEncodingException; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.Date; +import java.util.logging.Level; +import java.util.logging.Logger; + +public class Block { + + private static Logger logger = Logger.getLogger(Block.class.getName()); + + private String hash; + private String previousHash; + private String data; + private long timeStamp; + private int nonce; + + public Block(String data, String previousHash) { + this.data = data; + this.previousHash = previousHash; + this.timeStamp = new Date().getTime(); + this.hash = calculateBlockHash(); + } + + public String mineBlock(int prefix) { + String prefixString = new String(new char[prefix]).replace('\0', '0'); + while (!hash.substring(0, prefix) + .equals(prefixString)) { + nonce++; + hash = calculateBlockHash(); + } + return hash; + } + + public String calculateBlockHash() { + String dataToHash = previousHash + Long.toString(timeStamp) + Integer.toString(nonce) + data; + MessageDigest digest = null; + byte[] bytes = null; + try { + digest = MessageDigest.getInstance("SHA-256"); + bytes = digest.digest(dataToHash.getBytes("UTF-8")); + } catch (NoSuchAlgorithmException | UnsupportedEncodingException ex) { + logger.log(Level.SEVERE, ex.getMessage()); + } + StringBuffer buffer = new StringBuffer(); + for (byte b : bytes) { + buffer.append(String.format("%02x", b)); + } + return buffer.toString(); + } + + public String getHash() { + return this.hash; + } + + public String getPreviousHash() { + return this.previousHash; + } + + public void setData(String data) { + this.data = data; + } +} diff --git a/JGit/src/main/resources/logback.xml b/java-blockchain/src/main/resources/logback.xml similarity index 100% rename from JGit/src/main/resources/logback.xml rename to java-blockchain/src/main/resources/logback.xml diff --git a/java-blockchain/src/test/java/com/baeldung/blockchain/BlockchainUnitTest.java b/java-blockchain/src/test/java/com/baeldung/blockchain/BlockchainUnitTest.java new file mode 100644 index 0000000000..acbf651e78 --- /dev/null +++ b/java-blockchain/src/test/java/com/baeldung/blockchain/BlockchainUnitTest.java @@ -0,0 +1,67 @@ +package com.baeldung.blockchain; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +public class BlockchainUnitTest { + + public static List blockchain = new ArrayList(); + public static int prefix = 4; + public static String prefixString = new String(new char[prefix]).replace('\0', '0'); + + @BeforeClass + public static void setUp() { + Block genesisBlock = new Block("The is the Genesis Block.", "0"); + genesisBlock.mineBlock(prefix); + blockchain.add(genesisBlock); + Block firstBlock = new Block("The is the First Block.", genesisBlock.getHash()); + firstBlock.mineBlock(prefix); + blockchain.add(firstBlock); + } + + @Test + public void givenBlockchain_whenNewBlockAdded_thenSuccess() { + Block newBlock = new Block("The is a New Block.", blockchain.get(blockchain.size() - 1) + .getHash()); + newBlock.mineBlock(prefix); + assertTrue(newBlock.getHash() + .substring(0, prefix) + .equals(prefixString)); + blockchain.add(newBlock); + } + + @Test + public void givenBlockchain_whenValidated_thenSuccess() { + boolean flag = true; + for (int i = 0; i < blockchain.size(); i++) { + String previousHash = i == 0 ? "0" + : blockchain.get(i - 1) + .getHash(); + flag = blockchain.get(i) + .getHash() + .equals(blockchain.get(i) + .calculateBlockHash()) + && previousHash.equals(blockchain.get(i) + .getPreviousHash()) + && blockchain.get(i) + .getHash() + .substring(0, prefix) + .equals(prefixString); + if (!flag) + break; + } + assertTrue(flag); + } + + @AfterClass + public static void tearDown() { + blockchain.clear(); + } + +} diff --git a/spring-boot-properties/.gitignore b/java-blockchain/src/test/resources/.gitignore similarity index 82% rename from spring-boot-properties/.gitignore rename to java-blockchain/src/test/resources/.gitignore index 0532ef1888..83c05e60c8 100644 --- a/spring-boot-properties/.gitignore +++ b/java-blockchain/src/test/resources/.gitignore @@ -10,8 +10,4 @@ # Packaged files # *.jar *.war -*.ear - -*.ipr -*.iml -*.iws +*.ear \ No newline at end of file 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-dates/src/main/java/com/baeldung/java9/datetime/DateToLocalDateConverter.java b/java-dates/src/main/java/com/baeldung/datetolocaldate/DateToLocalDateConverter.java similarity index 96% rename from java-dates/src/main/java/com/baeldung/java9/datetime/DateToLocalDateConverter.java rename to java-dates/src/main/java/com/baeldung/datetolocaldate/DateToLocalDateConverter.java index c794c57e87..80bccb399a 100644 --- a/java-dates/src/main/java/com/baeldung/java9/datetime/DateToLocalDateConverter.java +++ b/java-dates/src/main/java/com/baeldung/datetolocaldate/DateToLocalDateConverter.java @@ -1,7 +1,7 @@ /** * */ -package com.baeldung.java9.datetime; +package com.baeldung.datetolocaldate; import java.time.Instant; import java.time.LocalDate; diff --git a/java-dates/src/main/java/com/baeldung/java9/datetime/DateToLocalDateTimeConverter.java b/java-dates/src/main/java/com/baeldung/datetolocaldate/DateToLocalDateTimeConverter.java similarity index 96% rename from java-dates/src/main/java/com/baeldung/java9/datetime/DateToLocalDateTimeConverter.java rename to java-dates/src/main/java/com/baeldung/datetolocaldate/DateToLocalDateTimeConverter.java index 17ca5b1122..1d1e3b7d92 100644 --- a/java-dates/src/main/java/com/baeldung/java9/datetime/DateToLocalDateTimeConverter.java +++ b/java-dates/src/main/java/com/baeldung/datetolocaldate/DateToLocalDateTimeConverter.java @@ -1,7 +1,7 @@ /** * */ -package com.baeldung.java9.datetime; +package com.baeldung.datetolocaldate; import java.time.Instant; import java.time.LocalDateTime; diff --git a/java-dates/src/main/java/com/baeldung/java9/datetime/LocalDateTimeToDateConverter.java b/java-dates/src/main/java/com/baeldung/datetolocaldate/LocalDateTimeToDateConverter.java similarity index 94% rename from java-dates/src/main/java/com/baeldung/java9/datetime/LocalDateTimeToDateConverter.java rename to java-dates/src/main/java/com/baeldung/datetolocaldate/LocalDateTimeToDateConverter.java index f219dcf038..9a6bb248fa 100644 --- a/java-dates/src/main/java/com/baeldung/java9/datetime/LocalDateTimeToDateConverter.java +++ b/java-dates/src/main/java/com/baeldung/datetolocaldate/LocalDateTimeToDateConverter.java @@ -1,7 +1,7 @@ /** * */ -package com.baeldung.java9.datetime; +package com.baeldung.datetolocaldate; import java.time.LocalDateTime; import java.time.ZoneId; diff --git a/java-dates/src/main/java/com/baeldung/java9/datetime/LocalDateToDateConverter.java b/java-dates/src/main/java/com/baeldung/datetolocaldate/LocalDateToDateConverter.java similarity index 94% rename from java-dates/src/main/java/com/baeldung/java9/datetime/LocalDateToDateConverter.java rename to java-dates/src/main/java/com/baeldung/datetolocaldate/LocalDateToDateConverter.java index f9893da5d0..f679ffb77a 100644 --- a/java-dates/src/main/java/com/baeldung/java9/datetime/LocalDateToDateConverter.java +++ b/java-dates/src/main/java/com/baeldung/datetolocaldate/LocalDateToDateConverter.java @@ -1,7 +1,7 @@ /** * */ -package com.baeldung.java9.datetime; +package com.baeldung.datetolocaldate; import java.time.LocalDate; import java.time.ZoneId; diff --git a/java-dates/src/test/java/com/baeldung/java9/datetime/DateToLocalDateConverterUnitTest.java b/java-dates/src/test/java/com/baeldung/datetolocaldate/DateToLocalDateConverterUnitTest.java similarity index 96% rename from java-dates/src/test/java/com/baeldung/java9/datetime/DateToLocalDateConverterUnitTest.java rename to java-dates/src/test/java/com/baeldung/datetolocaldate/DateToLocalDateConverterUnitTest.java index f7f07500f1..b5a54e28eb 100644 --- a/java-dates/src/test/java/com/baeldung/java9/datetime/DateToLocalDateConverterUnitTest.java +++ b/java-dates/src/test/java/com/baeldung/datetolocaldate/DateToLocalDateConverterUnitTest.java @@ -1,7 +1,7 @@ /** * */ -package com.baeldung.java9.datetime; +package com.baeldung.datetolocaldate; import static org.junit.Assert.assertEquals; @@ -12,7 +12,7 @@ import java.util.Date; import org.junit.Test; -import com.baeldung.java9.datetime.DateToLocalDateConverter; +import com.baeldung.datetolocaldate.DateToLocalDateConverter; /** * JUnits for {@link DateToLocalDateConverter} class. diff --git a/java-dates/src/test/java/com/baeldung/java9/datetime/DateToLocalDateTimeConverterUnitTest.java b/java-dates/src/test/java/com/baeldung/datetolocaldate/DateToLocalDateTimeConverterUnitTest.java similarity index 97% rename from java-dates/src/test/java/com/baeldung/java9/datetime/DateToLocalDateTimeConverterUnitTest.java rename to java-dates/src/test/java/com/baeldung/datetolocaldate/DateToLocalDateTimeConverterUnitTest.java index 9ad29ea673..e6098cec1c 100644 --- a/java-dates/src/test/java/com/baeldung/java9/datetime/DateToLocalDateTimeConverterUnitTest.java +++ b/java-dates/src/test/java/com/baeldung/datetolocaldate/DateToLocalDateTimeConverterUnitTest.java @@ -1,7 +1,7 @@ /** * */ -package com.baeldung.java9.datetime; +package com.baeldung.datetolocaldate; import static org.junit.Assert.assertEquals; @@ -12,7 +12,7 @@ import java.util.Date; import org.junit.Test; -import com.baeldung.java9.datetime.DateToLocalDateTimeConverter; +import com.baeldung.datetolocaldate.DateToLocalDateTimeConverter; /** * JUnits for {@link DateToLocalDateTimeConverter} class. diff --git a/java-dates/src/test/java/com/baeldung/java9/datetime/LocalDateTimeToDateConverterUnitTest.java b/java-dates/src/test/java/com/baeldung/datetolocaldate/LocalDateTimeToDateConverterUnitTest.java similarity index 94% rename from java-dates/src/test/java/com/baeldung/java9/datetime/LocalDateTimeToDateConverterUnitTest.java rename to java-dates/src/test/java/com/baeldung/datetolocaldate/LocalDateTimeToDateConverterUnitTest.java index e5a541c546..c8e596c220 100644 --- a/java-dates/src/test/java/com/baeldung/java9/datetime/LocalDateTimeToDateConverterUnitTest.java +++ b/java-dates/src/test/java/com/baeldung/datetolocaldate/LocalDateTimeToDateConverterUnitTest.java @@ -1,7 +1,7 @@ /** * */ -package com.baeldung.java9.datetime; +package com.baeldung.datetolocaldate; import static org.junit.Assert.assertEquals; @@ -11,6 +11,8 @@ import java.util.Date; import org.junit.Test; +import com.baeldung.datetolocaldate.LocalDateTimeToDateConverter; + /** * * JUnits for {@link LocalDateTimeToDateConverter} class. diff --git a/java-dates/src/test/java/com/baeldung/java9/datetime/LocalDateToDateConverterUnitTest.java b/java-dates/src/test/java/com/baeldung/datetolocaldate/LocalDateToDateConverterUnitTest.java similarity index 93% rename from java-dates/src/test/java/com/baeldung/java9/datetime/LocalDateToDateConverterUnitTest.java rename to java-dates/src/test/java/com/baeldung/datetolocaldate/LocalDateToDateConverterUnitTest.java index 4e4dd20f2f..4ff3682158 100644 --- a/java-dates/src/test/java/com/baeldung/java9/datetime/LocalDateToDateConverterUnitTest.java +++ b/java-dates/src/test/java/com/baeldung/datetolocaldate/LocalDateToDateConverterUnitTest.java @@ -1,7 +1,7 @@ /** * */ -package com.baeldung.java9.datetime; +package com.baeldung.datetolocaldate; import static org.junit.Assert.assertEquals; @@ -11,6 +11,8 @@ import java.util.Date; import org.junit.Test; +import com.baeldung.datetolocaldate.LocalDateToDateConverter; + /** * * JUnits for {@link LocalDateToDateConverter} class. diff --git a/java-jdi/pom.xml b/java-jdi/pom.xml new file mode 100644 index 0000000000..3d70461dce --- /dev/null +++ b/java-jdi/pom.xml @@ -0,0 +1,130 @@ + + 4.0.0 + java-jdi + 0.1.0-SNAPSHOT + java-jdi + jar + + + com.baeldung + parent-java + 0.0.1-SNAPSHOT + ../parent-java + + + + + log4j + log4j + ${log4j.version} + + + org.slf4j + slf4j-api + ${org.slf4j.version} + + + ch.qos.logback + logback-classic + ${logback.version} + + + org.openjdk.jmh + jmh-core + ${jmh-core.version} + + + org.openjdk.jmh + jmh-generator-annprocess + ${jmh-generator.version} + + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + + + org.assertj + assertj-core + ${assertj.version} + test + + + com.sun + tools + ${tools.version} + system + ${java.home}/../lib/tools.jar + + + + + java-jdi + + + src/main/resources + true + + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + ${maven-javadoc-plugin.version} + + 1.8 + 1.8 + + + + + + + + integration + + + + org.apache.maven.plugins + maven-surefire-plugin + + + integration-test + + test + + + + **/*IntegrationTest.java + + + + + + + json + + + + + + + + + + 3.5 + + 3.6.1 + 1.8 + 1.7.21 + 1.1.7 + 1.8 + 2.21.0 + 3.0.0-M1 + 3.0.2 + + diff --git a/java-jdi/src/main/java/com/baeldung/jdi/JDIExampleDebuggee.java b/java-jdi/src/main/java/com/baeldung/jdi/JDIExampleDebuggee.java new file mode 100644 index 0000000000..4fb49024fb --- /dev/null +++ b/java-jdi/src/main/java/com/baeldung/jdi/JDIExampleDebuggee.java @@ -0,0 +1,14 @@ +package com.baeldung.jdi; + +public class JDIExampleDebuggee { + + public static void main(String[] args) { + String jpda = "Java Platform Debugger Architecture"; + System.out.println("Hi Everyone, Welcome to " + jpda); //add a break point here + + String jdi = "Java Debug Interface"; //add a break point here and also stepping in here + String text = "Today, we'll dive into " + jdi; + System.out.println(text); + } + +} diff --git a/java-jdi/src/main/java/com/baeldung/jdi/JDIExampleDebugger.java b/java-jdi/src/main/java/com/baeldung/jdi/JDIExampleDebugger.java new file mode 100644 index 0000000000..41a568e55f --- /dev/null +++ b/java-jdi/src/main/java/com/baeldung/jdi/JDIExampleDebugger.java @@ -0,0 +1,171 @@ +package com.baeldung.jdi; + +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.util.Map; + +import com.sun.jdi.AbsentInformationException; +import com.sun.jdi.Bootstrap; +import com.sun.jdi.ClassType; +import com.sun.jdi.IncompatibleThreadStateException; +import com.sun.jdi.LocalVariable; +import com.sun.jdi.Location; +import com.sun.jdi.StackFrame; +import com.sun.jdi.VMDisconnectedException; +import com.sun.jdi.Value; +import com.sun.jdi.VirtualMachine; +import com.sun.jdi.connect.Connector; +import com.sun.jdi.connect.IllegalConnectorArgumentsException; +import com.sun.jdi.connect.LaunchingConnector; +import com.sun.jdi.connect.VMStartException; +import com.sun.jdi.event.BreakpointEvent; +import com.sun.jdi.event.ClassPrepareEvent; +import com.sun.jdi.event.Event; +import com.sun.jdi.event.EventSet; +import com.sun.jdi.event.LocatableEvent; +import com.sun.jdi.event.StepEvent; +import com.sun.jdi.request.BreakpointRequest; +import com.sun.jdi.request.ClassPrepareRequest; +import com.sun.jdi.request.StepRequest; + +public class JDIExampleDebugger { + + private Class debugClass; + private int[] breakPointLines; + + public Class getDebugClass() { + return debugClass; + } + + public void setDebugClass(Class debugClass) { + this.debugClass = debugClass; + } + + public int[] getBreakPointLines() { + return breakPointLines; + } + + public void setBreakPointLines(int[] breakPointLines) { + this.breakPointLines = breakPointLines; + } + + /** + * Sets the debug class as the main argument in the connector and launches the VM + * @return VirtualMachine + * @throws IOException + * @throws IllegalConnectorArgumentsException + * @throws VMStartException + */ + public VirtualMachine connectAndLaunchVM() throws IOException, IllegalConnectorArgumentsException, VMStartException { + LaunchingConnector launchingConnector = Bootstrap.virtualMachineManager().defaultConnector(); + Map arguments = launchingConnector.defaultArguments(); + arguments.get("main").setValue(debugClass.getName()); + VirtualMachine vm = launchingConnector.launch(arguments); + return vm; + } + + /** + * Creates a request to prepare the debug class, add filter as the debug class and enables it + * @param vm + */ + public void enableClassPrepareRequest(VirtualMachine vm) { + ClassPrepareRequest classPrepareRequest = vm.eventRequestManager().createClassPrepareRequest(); + classPrepareRequest.addClassFilter(debugClass.getName()); + classPrepareRequest.enable(); + } + + /** + * Sets the break points at the line numbers mentioned in breakPointLines array + * @param vm + * @param event + * @throws AbsentInformationException + */ + public void setBreakPoints(VirtualMachine vm, ClassPrepareEvent event) throws AbsentInformationException { + ClassType classType = (ClassType) event.referenceType(); + for(int lineNumber: breakPointLines) { + Location location = classType.locationsOfLine(lineNumber).get(0); + BreakpointRequest bpReq = vm.eventRequestManager().createBreakpointRequest(location); + bpReq.enable(); + } + } + + /** + * Displays the visible variables + * @param event + * @throws IncompatibleThreadStateException + * @throws AbsentInformationException + */ + public void displayVariables(LocatableEvent event) throws IncompatibleThreadStateException, AbsentInformationException { + StackFrame stackFrame = event.thread().frame(0); + if(stackFrame.location().toString().contains(debugClass.getName())) { + Map visibleVariables = stackFrame.getValues(stackFrame.visibleVariables()); + System.out.println("Variables at " +stackFrame.location().toString() + " > "); + for (Map.Entry entry : visibleVariables.entrySet()) { + System.out.println(entry.getKey().name() + " = " + entry.getValue()); + } + } + } + + /** + * Enables step request for a break point + * @param vm + * @param event + */ + public void enableStepRequest(VirtualMachine vm, BreakpointEvent event) { + //enable step request for last break point + if(event.location().toString().contains(debugClass.getName()+":"+breakPointLines[breakPointLines.length-1])) { + StepRequest stepRequest = vm.eventRequestManager().createStepRequest(event.thread(), StepRequest.STEP_LINE, StepRequest.STEP_OVER); + stepRequest.enable(); + } + } + + public static void main(String[] args) throws Exception { + + JDIExampleDebugger debuggerInstance = new JDIExampleDebugger(); + debuggerInstance.setDebugClass(JDIExampleDebuggee.class); + int[] breakPoints = {6, 9}; + debuggerInstance.setBreakPointLines(breakPoints); + VirtualMachine vm = null; + + try { + vm = debuggerInstance.connectAndLaunchVM(); + debuggerInstance.enableClassPrepareRequest(vm); + + EventSet eventSet = null; + while ((eventSet = vm.eventQueue().remove()) != null) { + for (Event event : eventSet) { + if (event instanceof ClassPrepareEvent) { + debuggerInstance.setBreakPoints(vm, (ClassPrepareEvent)event); + } + + if (event instanceof BreakpointEvent) { + event.request().disable(); + debuggerInstance.displayVariables((BreakpointEvent) event); + debuggerInstance.enableStepRequest(vm, (BreakpointEvent)event); + } + + if (event instanceof StepEvent) { + debuggerInstance.displayVariables((StepEvent) event); + } + vm.resume(); + } + } + } catch (VMDisconnectedException e) { + System.out.println("Virtual Machine is disconnected."); + } catch (Exception e) { + e.printStackTrace(); + } + finally { + InputStreamReader reader = new InputStreamReader(vm.process().getInputStream()); + OutputStreamWriter writer = new OutputStreamWriter(System.out); + char[] buf = new char[512]; + + reader.read(buf); + writer.write(buf); + writer.flush(); + } + + } + +} diff --git a/java-math/README.md b/java-math/README.md index d821348204..244417d1a5 100644 --- a/java-math/README.md +++ b/java-math/README.md @@ -7,4 +7,5 @@ - [Find the Intersection of Two Lines in Java](https://www.baeldung.com/java-intersection-of-two-lines) - [Round Up to the Nearest Hundred](https://www.baeldung.com/java-round-up-nearest-hundred) - [Calculate Percentage in Java](https://www.baeldung.com/java-calculate-percentage) -- [Convert Latitude and Longitude to a 2D Point in Java](https://www.baeldung.com/java-convert-latitude-longitude) \ No newline at end of file +- [Convert Latitude and Longitude to a 2D Point in Java](https://www.baeldung.com/java-convert-latitude-longitude) +- [Debugging with Eclipse](https://www.baeldung.com/eclipse-debugging) 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/main/java/com/baeldung/matrices/HomemadeMatrix.java b/java-math/src/main/java/com/baeldung/matrices/HomemadeMatrix.java new file mode 100644 index 0000000000..0676250959 --- /dev/null +++ b/java-math/src/main/java/com/baeldung/matrices/HomemadeMatrix.java @@ -0,0 +1,23 @@ +package com.baeldung.matrices; + +public class HomemadeMatrix { + public static double[][] multiplyMatrices(double[][] firstMatrix, double[][] secondMatrix) { + double[][] result = new double[firstMatrix.length][secondMatrix[0].length]; + + for (int row = 0; row < result.length; row++) { + for (int col = 0; col < result[row].length; col++) { + result[row][col] = multiplyMatricesCell(firstMatrix, secondMatrix, row, col); + } + } + + return result; + } + + private static double multiplyMatricesCell(double[][] firstMatrix, double[][] secondMatrix, int row, int col) { + double cell = 0; + for (int i = 0; i < secondMatrix.length; i++) { + cell += firstMatrix[row][i] * secondMatrix[i][col]; + } + return cell; + } +} \ No newline at end of file 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..facad1edc4 --- /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 LogarithmUnitTest { + + @Test + public void givenLog10_shouldReturnValidResults() { + assertEquals(Math.log10(100), 2); + assertEquals(Math.log10(1000), 3); + } + + @Test + public void givenLogE_shouldReturnValidResults() { + assertEquals(Math.log(Math.E), 1); + assertEquals(Math.log(10), 2.30258, 0.00001); + } + + @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/java-math/src/test/java/com/baeldung/matrices/MatrixMultiplicationBenchmarking.java b/java-math/src/test/java/com/baeldung/matrices/MatrixMultiplicationBenchmarking.java new file mode 100644 index 0000000000..171a1d28a4 --- /dev/null +++ b/java-math/src/test/java/com/baeldung/matrices/MatrixMultiplicationBenchmarking.java @@ -0,0 +1,84 @@ +package com.baeldung.matrices; + +import cern.colt.matrix.DoubleFactory2D; +import cern.colt.matrix.DoubleMatrix2D; +import cern.colt.matrix.linalg.Algebra; +import org.apache.commons.math3.linear.Array2DRowRealMatrix; +import org.apache.commons.math3.linear.RealMatrix; +import org.ejml.simple.SimpleMatrix; +import org.la4j.Matrix; +import org.la4j.matrix.dense.Basic2DMatrix; +import org.nd4j.linalg.api.ndarray.INDArray; +import org.nd4j.linalg.factory.Nd4j; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; + +import java.util.concurrent.TimeUnit; + +public class MatrixMultiplicationBenchmarking { + + public static void main(String[] args) throws Exception { + Options opt = new OptionsBuilder() + .include(MatrixMultiplicationBenchmarking.class.getSimpleName()) + .mode(Mode.AverageTime) + .forks(2) + .warmupIterations(5) + .measurementIterations(10) + .timeUnit(TimeUnit.MICROSECONDS) + .build(); + + new Runner(opt).run(); + } + + @Benchmark + public Object homemadeMatrixMultiplication(MatrixProvider matrixProvider) { + return HomemadeMatrix.multiplyMatrices(matrixProvider.getFirstMatrix(), matrixProvider.getSecondMatrix()); + } + + @Benchmark + public Object ejmlMatrixMultiplication(MatrixProvider matrixProvider) { + SimpleMatrix firstMatrix = new SimpleMatrix(matrixProvider.getFirstMatrix()); + SimpleMatrix secondMatrix = new SimpleMatrix(matrixProvider.getSecondMatrix()); + + return firstMatrix.mult(secondMatrix); + } + + @Benchmark + public Object apacheCommonsMatrixMultiplication(MatrixProvider matrixProvider) { + RealMatrix firstMatrix = new Array2DRowRealMatrix(matrixProvider.getFirstMatrix()); + RealMatrix secondMatrix = new Array2DRowRealMatrix(matrixProvider.getSecondMatrix()); + + return firstMatrix.multiply(secondMatrix); + } + + @Benchmark + public Object la4jMatrixMultiplication(MatrixProvider matrixProvider) { + Matrix firstMatrix = new Basic2DMatrix(matrixProvider.getFirstMatrix()); + Matrix secondMatrix = new Basic2DMatrix(matrixProvider.getSecondMatrix()); + + return firstMatrix.multiply(secondMatrix); + } + + @Benchmark + public Object nd4jMatrixMultiplication(MatrixProvider matrixProvider) { + INDArray firstMatrix = Nd4j.create(matrixProvider.getFirstMatrix()); + INDArray secondMatrix = Nd4j.create(matrixProvider.getSecondMatrix()); + + return firstMatrix.mmul(secondMatrix); + } + + @Benchmark + public Object coltMatrixMultiplication(MatrixProvider matrixProvider) { + DoubleFactory2D doubleFactory2D = DoubleFactory2D.dense; + + DoubleMatrix2D firstMatrix = doubleFactory2D.make(matrixProvider.getFirstMatrix()); + DoubleMatrix2D secondMatrix = doubleFactory2D.make(matrixProvider.getSecondMatrix()); + + Algebra algebra = new Algebra(); + return algebra.mult(firstMatrix, secondMatrix); + } + +} \ No newline at end of file diff --git a/java-math/src/test/java/com/baeldung/matrices/MatrixProvider.java b/java-math/src/test/java/com/baeldung/matrices/MatrixProvider.java new file mode 100644 index 0000000000..33bd074b6e --- /dev/null +++ b/java-math/src/test/java/com/baeldung/matrices/MatrixProvider.java @@ -0,0 +1,33 @@ +package com.baeldung.matrices; + +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.State; + +@State(Scope.Benchmark) +public class MatrixProvider { + private double[][] firstMatrix; + private double[][] secondMatrix; + + public MatrixProvider() { + firstMatrix = + new double[][] { + new double[] {1d, 5d}, + new double[] {2d, 3d}, + new double[] {1d ,7d} + }; + + secondMatrix = + new double[][] { + new double[] {1d, 2d, 3d, 7d}, + new double[] {5d, 2d, 8d, 1d} + }; + } + + public double[][] getFirstMatrix() { + return firstMatrix; + } + + public double[][] getSecondMatrix() { + return secondMatrix; + } +} \ No newline at end of file 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 82% 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 index 05944e7b3a..e7d99fbe3e 100644 --- a/libraries-2/src/test/java/com/baeldung/matrices/apache/RealMatrixUnitTest.java +++ b/java-math/src/test/java/com/baeldung/matrices/apache/RealMatrixUnitTest.java @@ -7,15 +7,10 @@ import org.openjdk.jmh.annotations.*; import static org.assertj.core.api.Assertions.assertThat; -@BenchmarkMode(Mode.AverageTime) -@Fork(value = 2) -@Warmup(iterations = 5) -@Measurement(iterations = 10) -public class RealMatrixUnitTest { +class RealMatrixUnitTest { @Test - @Benchmark - public void givenTwoMatrices_whenMultiply_thenMultiplicatedMatrix() { + void givenTwoMatrices_whenMultiply_thenMultiplicatedMatrix() { RealMatrix firstMatrix = new Array2DRowRealMatrix( new double[][] { new double[] {1d, 5d}, @@ -43,5 +38,4 @@ public class RealMatrixUnitTest { assertThat(actual).isEqualTo(expected); } - } 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 83% 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 index fb4a419eb0..da66cd7d61 100644 --- a/libraries-2/src/test/java/com/baeldung/matrices/colt/DoubleMatrix2DUnitTest.java +++ b/java-math/src/test/java/com/baeldung/matrices/colt/DoubleMatrix2DUnitTest.java @@ -8,15 +8,10 @@ import org.openjdk.jmh.annotations.*; import static org.assertj.core.api.Assertions.assertThat; -@BenchmarkMode(Mode.AverageTime) -@Fork(value = 2) -@Warmup(iterations = 5) -@Measurement(iterations = 10) -public class DoubleMatrix2DUnitTest { +class DoubleMatrix2DUnitTest { @Test - @Benchmark - public void givenTwoMatrices_whenMultiply_thenMultiplicatedMatrix() { + void givenTwoMatrices_whenMultiply_thenMultiplicatedMatrix() { DoubleFactory2D doubleFactory2D = DoubleFactory2D.dense; DoubleMatrix2D firstMatrix = doubleFactory2D.make( @@ -48,4 +43,4 @@ public class DoubleMatrix2DUnitTest { assertThat(actual).isEqualTo(expected); } -} +} \ No newline at end of file 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 81% 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 index b025266a1d..60381ece63 100644 --- a/libraries-2/src/test/java/com/baeldung/matrices/ejml/SimpleMatrixUnitTest.java +++ b/java-math/src/test/java/com/baeldung/matrices/ejml/SimpleMatrixUnitTest.java @@ -6,15 +6,10 @@ import org.openjdk.jmh.annotations.*; import static org.assertj.core.api.Assertions.assertThat; -@BenchmarkMode(Mode.AverageTime) -@Fork(value = 2) -@Warmup(iterations = 5) -@Measurement(iterations = 10) -public class SimpleMatrixUnitTest { +class SimpleMatrixUnitTest { @Test - @Benchmark - public void givenTwoMatrices_whenMultiply_thenMultiplicatedMatrix() { + void givenTwoMatrices_whenMultiply_thenMultiplicatedMatrix() { SimpleMatrix firstMatrix = new SimpleMatrix( new double[][] { new double[] {1d, 5d}, @@ -43,4 +38,4 @@ public class SimpleMatrixUnitTest { assertThat(actual).matches(m -> m.isIdentical(expected, 0d)); } -} +} \ No newline at end of file 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 86% 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 index be9e483d5b..d1a062ee79 100644 --- a/libraries-2/src/test/java/com/baeldung/matrices/homemade/HomemadeMatrixUnitTest.java +++ b/java-math/src/test/java/com/baeldung/matrices/homemade/HomemadeMatrixUnitTest.java @@ -5,15 +5,10 @@ import org.openjdk.jmh.annotations.*; import static org.assertj.core.api.Assertions.assertThat; -@BenchmarkMode(Mode.AverageTime) -@Fork(value = 2) -@Warmup(iterations = 5) -@Measurement(iterations = 10) -public class HomemadeMatrixUnitTest { +class HomemadeMatrixUnitTest { @Test - @Benchmark - public void givenTwoMatrices_whenMultiply_thenMultiplicatedMatrix() { + void givenTwoMatrices_whenMultiply_thenMultiplicatedMatrix() { double[][] firstMatrix = { new double[]{1d, 5d}, new double[]{2d, 3d}, @@ -55,4 +50,5 @@ public class HomemadeMatrixUnitTest { } return cell; } -} + +} \ No newline at end of file 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 80% 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 index afb84ff3db..01731a3dd5 100644 --- a/libraries-2/src/test/java/com/baeldung/matrices/la4j/Basic2DMatrixUnitTest.java +++ b/java-math/src/test/java/com/baeldung/matrices/la4j/Basic2DMatrixUnitTest.java @@ -7,15 +7,10 @@ import org.openjdk.jmh.annotations.*; import static org.assertj.core.api.Assertions.assertThat; -@BenchmarkMode(Mode.AverageTime) -@Fork(value = 2) -@Warmup(iterations = 5) -@Measurement(iterations = 10) -public class Basic2DMatrixUnitTest { +class Basic2DMatrixUnitTest { @Test - @Benchmark - public void givenTwoMatrices_whenMultiply_thenMultiplicatedMatrix() { + void givenTwoMatrices_whenMultiply_thenMultiplicatedMatrix() { Matrix firstMatrix = new Basic2DMatrix( new double[][]{ new double[]{1d, 5d}, @@ -44,4 +39,4 @@ public class Basic2DMatrixUnitTest { assertThat(actual).isEqualTo(expected); } -} +} \ No newline at end of file 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 82% 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 index fb3030bccf..72ef60a571 100644 --- a/libraries-2/src/test/java/com/baeldung/matrices/nd4j/INDArrayUnitTest.java +++ b/java-math/src/test/java/com/baeldung/matrices/nd4j/INDArrayUnitTest.java @@ -7,14 +7,10 @@ import org.openjdk.jmh.annotations.*; import static org.assertj.core.api.Assertions.assertThat; -@BenchmarkMode(Mode.AverageTime) -@Fork(value = 2) -@Warmup(iterations = 5) -@Measurement(iterations = 10) -public class INDArrayUnitTest { +class INDArrayUnitTest { @Test - public void givenTwoMatrices_whenMultiply_thenMultiplicatedMatrix() { + void givenTwoMatrices_whenMultiply_thenMultiplicatedMatrix() { INDArray firstMatrix = Nd4j.create( new double[][]{ new double[]{1d, 5d}, @@ -43,4 +39,4 @@ public class INDArrayUnitTest { assertThat(actual).isEqualTo(expected); } -} +} \ No newline at end of file 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/main/java/com/baeldung/lcm/BigIntegerLCM.java b/java-numbers-2/src/main/java/com/baeldung/lcm/BigIntegerLCM.java new file mode 100644 index 0000000000..affface9c0 --- /dev/null +++ b/java-numbers-2/src/main/java/com/baeldung/lcm/BigIntegerLCM.java @@ -0,0 +1,13 @@ +package com.baeldung.lcm; + +import java.math.BigInteger; + +public class BigIntegerLCM { + + public static BigInteger lcm(BigInteger number1, BigInteger number2) { + BigInteger gcd = number1.gcd(number2); + BigInteger absProduct = number1.multiply(number2).abs(); + return absProduct.divide(gcd); + } + +} diff --git a/java-numbers-2/src/main/java/com/baeldung/lcm/EuclideanAlgorithm.java b/java-numbers-2/src/main/java/com/baeldung/lcm/EuclideanAlgorithm.java new file mode 100644 index 0000000000..4032d119fa --- /dev/null +++ b/java-numbers-2/src/main/java/com/baeldung/lcm/EuclideanAlgorithm.java @@ -0,0 +1,40 @@ +package com.baeldung.lcm; + +import java.util.Arrays; + +public class EuclideanAlgorithm { + + public static int gcd(int number1, int number2) { + if (number1 == 0 || number2 == 0) { + return number1 + number2; + } else { + int absNumber1 = Math.abs(number1); + int absNumber2 = Math.abs(number2); + int biggerValue = Math.max(absNumber1, absNumber2); + int smallerValue = Math.min(absNumber1, absNumber2); + return gcd(biggerValue % smallerValue, smallerValue); + } + } + + public static int lcm(int number1, int number2) { + if (number1 == 0 || number2 == 0) + return 0; + else { + int gcd = gcd(number1, number2); + return Math.abs(number1 * number2) / gcd; + } + } + + public static int lcmForArray(int[] numbers) { + int lcm = numbers[0]; + for (int i = 1; i <= numbers.length - 1; i++) { + lcm = lcm(lcm, numbers[i]); + } + return lcm; + } + + public static int lcmByLambda(int... numbers) { + return Arrays.stream(numbers).reduce(1, (lcmSoFar, currentNumber) -> Math.abs(lcmSoFar * currentNumber) / gcd(lcmSoFar, currentNumber)); + } + +} diff --git a/java-numbers-2/src/main/java/com/baeldung/lcm/PrimeFactorizationAlgorithm.java b/java-numbers-2/src/main/java/com/baeldung/lcm/PrimeFactorizationAlgorithm.java new file mode 100644 index 0000000000..cfdc3bfe96 --- /dev/null +++ b/java-numbers-2/src/main/java/com/baeldung/lcm/PrimeFactorizationAlgorithm.java @@ -0,0 +1,42 @@ +package com.baeldung.lcm; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +public class PrimeFactorizationAlgorithm { + + public static Map getPrimeFactors(int number) { + int absNumber = Math.abs(number); + Map primeFactorsMap = new HashMap(); + for (int factor = 2; factor <= absNumber; factor++) { + while (absNumber % factor == 0) { + Integer power = primeFactorsMap.get(factor); + if (power == null) { + power = 0; + } + primeFactorsMap.put(factor, power + 1); + absNumber /= factor; + } + } + return primeFactorsMap; + } + + public static int lcm(int number1, int number2) { + if (number1 == 0 || number2 == 0) { + return 0; + } + Map primeFactorsForNum1 = getPrimeFactors(number1); + Map primeFactorsForNum2 = getPrimeFactors(number2); + Set primeFactorsUnionSet = new HashSet(primeFactorsForNum1.keySet()); + primeFactorsUnionSet.addAll(primeFactorsForNum2.keySet()); + int lcm = 1; + for (Integer primeFactor : primeFactorsUnionSet) { + lcm *= Math.pow(primeFactor, Math.max(primeFactorsForNum1.getOrDefault(primeFactor, 0), + primeFactorsForNum2.getOrDefault(primeFactor, 0))); + } + return lcm; + } + +} diff --git a/java-numbers-2/src/main/java/com/baeldung/lcm/SimpleAlgorithm.java b/java-numbers-2/src/main/java/com/baeldung/lcm/SimpleAlgorithm.java new file mode 100644 index 0000000000..6ba4966dc7 --- /dev/null +++ b/java-numbers-2/src/main/java/com/baeldung/lcm/SimpleAlgorithm.java @@ -0,0 +1,18 @@ +package com.baeldung.lcm; + +public class SimpleAlgorithm { + public static int lcm(int number1, int number2) { + if (number1 == 0 || number2 == 0) { + return 0; + } + int absNumber1 = Math.abs(number1); + int absNumber2 = Math.abs(number2); + int absHigherNumber = Math.max(absNumber1, absNumber2); + int absLowerNumber = Math.min(absNumber1, absNumber2); + int lcm = absHigherNumber; + while (lcm % absLowerNumber != 0) { + lcm += absHigherNumber; + } + return lcm; + } +} diff --git a/java-numbers-2/src/main/java/com/baeldung/numbersinrange/NumbersInARange.java b/java-numbers-2/src/main/java/com/baeldung/numbersinrange/NumbersInARange.java new file mode 100644 index 0000000000..937583cdb5 --- /dev/null +++ b/java-numbers-2/src/main/java/com/baeldung/numbersinrange/NumbersInARange.java @@ -0,0 +1,36 @@ +package com.baeldung.numbersinrange; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +public class NumbersInARange { + + public List getNumbersInRange(int start, int end) { + List result = new ArrayList<>(); + for (int i = start; i < end; i++) { + result.add(i); + } + return result; + } + + public List getNumbersUsingIntStreamRange(int start, int end) { + return IntStream.range(start, end) + .boxed() + .collect(Collectors.toList()); + } + + public List getNumbersUsingIntStreamRangeClosed(int start, int end) { + return IntStream.rangeClosed(start, end) + .boxed() + .collect(Collectors.toList()); + } + + public List getNumbersUsingIntStreamIterate(int start, int limit) { + return IntStream.iterate(start, i -> i + 1) + .limit(limit) + .boxed() + .collect(Collectors.toList()); + } +} diff --git a/java-numbers-2/src/main/java/com/baeldung/numbersinrange/RandomNumbersInARange.java b/java-numbers-2/src/main/java/com/baeldung/numbersinrange/RandomNumbersInARange.java new file mode 100644 index 0000000000..dc6ddfe781 --- /dev/null +++ b/java-numbers-2/src/main/java/com/baeldung/numbersinrange/RandomNumbersInARange.java @@ -0,0 +1,22 @@ +package com.baeldung.numbersinrange; + +import java.util.Random; + +public class RandomNumbersInARange { + + public int getRandomNumber(int min, int max) { + return (int) ((Math.random() * (max - min)) + min); + } + + public int getRandomNumberUsingNextInt(int min, int max) { + Random random = new Random(); + return random.nextInt(max - min) + min; + } + + public int getRandomNumberUsingInts(int min, int max) { + Random random = new Random(); + return random.ints(min, max) + .findFirst() + .getAsInt(); + } +} 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-numbers-2/src/test/java/com/baeldung/lcm/BigIntegerLCMUnitTest.java b/java-numbers-2/src/test/java/com/baeldung/lcm/BigIntegerLCMUnitTest.java new file mode 100644 index 0000000000..10bee4c087 --- /dev/null +++ b/java-numbers-2/src/test/java/com/baeldung/lcm/BigIntegerLCMUnitTest.java @@ -0,0 +1,18 @@ +package com.baeldung.lcm; + + +import org.junit.Assert; +import org.junit.Test; + +import java.math.BigInteger; + +public class BigIntegerLCMUnitTest { + + @Test + public void testLCM() { + BigInteger number1 = new BigInteger("12"); + BigInteger number2 = new BigInteger("18"); + BigInteger expectedLCM = new BigInteger("36"); + Assert.assertEquals(expectedLCM, BigIntegerLCM.lcm(number1, number2)); + } +} diff --git a/java-numbers-2/src/test/java/com/baeldung/lcm/EuclideanAlgorithmUnitTest.java b/java-numbers-2/src/test/java/com/baeldung/lcm/EuclideanAlgorithmUnitTest.java new file mode 100644 index 0000000000..09a53cfa4e --- /dev/null +++ b/java-numbers-2/src/test/java/com/baeldung/lcm/EuclideanAlgorithmUnitTest.java @@ -0,0 +1,27 @@ +package com.baeldung.lcm; + +import org.junit.Assert; +import org.junit.Test; + +public class EuclideanAlgorithmUnitTest { + + @Test + public void testGCD() { + Assert.assertEquals(6, EuclideanAlgorithm.gcd(12, 18)); + } + + @Test + public void testLCM() { + Assert.assertEquals(36, EuclideanAlgorithm.lcm(12, 18)); + } + + @Test + public void testLCMForArray() { + Assert.assertEquals(15, EuclideanAlgorithm.lcmForArray(new int[]{3, 5, 15})); + } + + @Test + public void testLCMByLambdaForArray() { + Assert.assertEquals(15, EuclideanAlgorithm.lcmByLambda(new int[]{3, 5, 15})); + } +} diff --git a/java-numbers-2/src/test/java/com/baeldung/lcm/PrimeFactorizationAlgorithmUnitTest.java b/java-numbers-2/src/test/java/com/baeldung/lcm/PrimeFactorizationAlgorithmUnitTest.java new file mode 100644 index 0000000000..b33b81f85e --- /dev/null +++ b/java-numbers-2/src/test/java/com/baeldung/lcm/PrimeFactorizationAlgorithmUnitTest.java @@ -0,0 +1,30 @@ +package com.baeldung.lcm; + +import org.junit.Assert; +import org.junit.Test; + +import java.util.HashMap; +import java.util.Map; + +import static com.baeldung.lcm.PrimeFactorizationAlgorithm.*; + + +public class PrimeFactorizationAlgorithmUnitTest { + + @Test + public void testGetPrimeFactors() { + Map expectedPrimeFactorsMapForTwelve = new HashMap<>(); + expectedPrimeFactorsMapForTwelve.put(2, 2); + expectedPrimeFactorsMapForTwelve.put(3, 1); + Map expectedPrimeFactorsMapForEighteen = new HashMap<>(); + expectedPrimeFactorsMapForEighteen.put(2, 1); + expectedPrimeFactorsMapForEighteen.put(3, 2); + Assert.assertEquals(expectedPrimeFactorsMapForTwelve, getPrimeFactors(12)); + Assert.assertEquals(expectedPrimeFactorsMapForEighteen, getPrimeFactors(18)); + } + + @Test + public void testLCM() { + Assert.assertEquals(36, PrimeFactorizationAlgorithm.lcm(12, 18)); + } +} diff --git a/java-numbers-2/src/test/java/com/baeldung/lcm/SimpleAlgorithmUnitTest.java b/java-numbers-2/src/test/java/com/baeldung/lcm/SimpleAlgorithmUnitTest.java new file mode 100644 index 0000000000..bc0a1690f4 --- /dev/null +++ b/java-numbers-2/src/test/java/com/baeldung/lcm/SimpleAlgorithmUnitTest.java @@ -0,0 +1,15 @@ +package com.baeldung.lcm; + +import org.junit.Assert; +import org.junit.Test; + +import static com.baeldung.lcm.SimpleAlgorithm.*; + +public class SimpleAlgorithmUnitTest { + + @Test + public void testLCM() { + Assert.assertEquals(36, lcm(12, 18)); + } + +} diff --git a/java-numbers-2/src/test/java/com/baeldung/numbersinrange/NumbersInARangeUnitTest.java b/java-numbers-2/src/test/java/com/baeldung/numbersinrange/NumbersInARangeUnitTest.java new file mode 100644 index 0000000000..3225257166 --- /dev/null +++ b/java-numbers-2/src/test/java/com/baeldung/numbersinrange/NumbersInARangeUnitTest.java @@ -0,0 +1,43 @@ +package com.baeldung.numbersinrange; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.Arrays; +import java.util.List; + +import org.junit.Test; + +public class NumbersInARangeUnitTest { + + @Test + public void givenTheRange1To10_andUsingForLoop_thenExpectCorrectResult() { + NumbersInARange numbersInARange = new NumbersInARange(); + List numbers = numbersInARange.getNumbersInRange(1, 10); + + assertEquals(Arrays.asList(1,2,3,4,5,6,7,8,9), numbers); + } + + @Test + public void givenTheRange1To10_andUsingIntStreamRange_thenExpectCorrectResult() { + NumbersInARange numbersInARange = new NumbersInARange(); + List numbers = numbersInARange.getNumbersUsingIntStreamRange(1, 10); + + assertEquals(Arrays.asList(1,2,3,4,5,6,7,8,9), numbers); + } + + @Test + public void givenTheRange1To10_andUsingIntStreamRangeClosed_thenExpectCorrectResult() { + NumbersInARange numbersInARange = new NumbersInARange(); + List numbers = numbersInARange.getNumbersUsingIntStreamRangeClosed(1, 10); + + assertEquals(Arrays.asList(1,2,3,4,5,6,7,8,9,10), numbers); + } + + @Test + public void givenTheRange1To10_andUsingIntStreamIterate_thenExpectCorrectResult() { + NumbersInARange numbersInARange = new NumbersInARange(); + List numbers = numbersInARange.getNumbersUsingIntStreamIterate(1, 10); + + assertEquals(Arrays.asList(1,2,3,4,5,6,7,8,9,10), numbers); + } +} diff --git a/java-numbers-2/src/test/java/com/baeldung/numbersinrange/RandomNumbersInARangeUnitTest.java b/java-numbers-2/src/test/java/com/baeldung/numbersinrange/RandomNumbersInARangeUnitTest.java new file mode 100644 index 0000000000..77b2cbbfef --- /dev/null +++ b/java-numbers-2/src/test/java/com/baeldung/numbersinrange/RandomNumbersInARangeUnitTest.java @@ -0,0 +1,35 @@ +package com.baeldung.numbersinrange; + +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +public class RandomNumbersInARangeUnitTest { + + @Test + public void givenTheRange1To10_andUsingMathRandom_thenExpectCorrectResult() { + RandomNumbersInARange randomNumbersInARange = new RandomNumbersInARange(); + int number = randomNumbersInARange.getRandomNumber(1, 10); + + assertTrue(number >= 1); + assertTrue(number < 10); + } + + @Test + public void givenTheRange1To10_andUsingRandomInts_thenExpectCorrectResult() { + RandomNumbersInARange randomNumbersInARange = new RandomNumbersInARange(); + int number = randomNumbersInARange.getRandomNumberUsingInts(1, 10); + + assertTrue(number >= 1); + assertTrue(number < 10); + } + + @Test + public void givenTheRange1To10_andUsingRandomNextInt_thenExpectCorrectResult() { + RandomNumbersInARange randomNumbersInARange = new RandomNumbersInARange(); + int number = randomNumbersInARange.getRandomNumberUsingNextInt(1, 10); + + assertTrue(number >= 1); + assertTrue(number < 10); + } +} diff --git a/java-streams-2/pom.xml b/java-streams-2/pom.xml index f7a0379ac5..4cebd44427 100644 --- a/java-streams-2/pom.xml +++ b/java-streams-2/pom.xml @@ -2,9 +2,9 @@ 4.0.0 com.baeldung.javastreams2 - javastreams2 + java-streams-2 1.0 - javastreams2 + java-streams-2 jar 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-2/src/main/java/com/baeldung/string/streamtokenizer/StreamTokenizerDemo.java b/java-strings-2/src/main/java/com/baeldung/string/streamtokenizer/StreamTokenizerDemo.java new file mode 100644 index 0000000000..3bb0ff5b77 --- /dev/null +++ b/java-strings-2/src/main/java/com/baeldung/string/streamtokenizer/StreamTokenizerDemo.java @@ -0,0 +1,76 @@ +package com.baeldung.string.streamtokenizer; + +import java.io.*; +import java.util.ArrayList; +import java.util.List; + +public class StreamTokenizerDemo { + + private static final String INPUT_FILE = "/stream-tokenizer-example.txt"; + private static final int QUOTE_CHARACTER = '\''; + private static final int DOUBLE_QUOTE_CHARACTER = '"'; + + public static List streamTokenizerWithDefaultConfiguration(Reader reader) throws IOException { + StreamTokenizer streamTokenizer = new StreamTokenizer(reader); + List tokens = new ArrayList<>(); + + int currentToken = streamTokenizer.nextToken(); + while (currentToken != StreamTokenizer.TT_EOF) { + + if (streamTokenizer.ttype == StreamTokenizer.TT_NUMBER) { + tokens.add(streamTokenizer.nval); + } else if (streamTokenizer.ttype == StreamTokenizer.TT_WORD + || streamTokenizer.ttype == QUOTE_CHARACTER + || streamTokenizer.ttype == DOUBLE_QUOTE_CHARACTER) { + tokens.add(streamTokenizer.sval); + } else { + tokens.add((char) currentToken); + } + + currentToken = streamTokenizer.nextToken(); + } + + return tokens; + } + + public static List streamTokenizerWithCustomConfiguration(Reader reader) throws IOException { + StreamTokenizer streamTokenizer = new StreamTokenizer(reader); + List tokens = new ArrayList<>(); + + streamTokenizer.wordChars('!', '-'); + streamTokenizer.ordinaryChar('/'); + streamTokenizer.commentChar('#'); + streamTokenizer.eolIsSignificant(true); + + int currentToken = streamTokenizer.nextToken(); + while (currentToken != StreamTokenizer.TT_EOF) { + + if (streamTokenizer.ttype == StreamTokenizer.TT_NUMBER) { + tokens.add(streamTokenizer.nval); + } else if (streamTokenizer.ttype == StreamTokenizer.TT_WORD + || streamTokenizer.ttype == QUOTE_CHARACTER + || streamTokenizer.ttype == DOUBLE_QUOTE_CHARACTER) { + tokens.add(streamTokenizer.sval); + } else { + tokens.add((char) currentToken); + } + currentToken = streamTokenizer.nextToken(); + } + + return tokens; + } + + public static Reader createReaderFromFile() throws FileNotFoundException { + String inputFile = StreamTokenizerDemo.class.getResource(INPUT_FILE).getFile(); + return new FileReader(inputFile); + } + + public static void main(String[] args) throws IOException { + List tokens1 = streamTokenizerWithDefaultConfiguration(createReaderFromFile()); + List tokens2 = streamTokenizerWithCustomConfiguration(createReaderFromFile()); + + System.out.println(tokens1); + System.out.println(tokens2); + } + +} \ No newline at end of file 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-2/src/main/resources/stream-tokenizer-example.txt b/java-strings-2/src/main/resources/stream-tokenizer-example.txt new file mode 100644 index 0000000000..6efe4fdc81 --- /dev/null +++ b/java-strings-2/src/main/resources/stream-tokenizer-example.txt @@ -0,0 +1,3 @@ +3 quick brown foxes jump over the "lazy" dog! +#test1 +//test2 \ No newline at end of file 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/java8/base64/ApacheCommonsEncodeDecodeUnitTest.java b/java-strings-2/src/test/java/com/baeldung/base64encodinganddecoding/ApacheCommonsEncodeDecodeUnitTest.java similarity index 97% rename from java-strings/src/test/java/com/baeldung/java8/base64/ApacheCommonsEncodeDecodeUnitTest.java rename to java-strings-2/src/test/java/com/baeldung/base64encodinganddecoding/ApacheCommonsEncodeDecodeUnitTest.java index 7889e6ad53..a0fc845d52 100644 --- a/java-strings/src/test/java/com/baeldung/java8/base64/ApacheCommonsEncodeDecodeUnitTest.java +++ b/java-strings-2/src/test/java/com/baeldung/base64encodinganddecoding/ApacheCommonsEncodeDecodeUnitTest.java @@ -1,4 +1,4 @@ -package com.baeldung.java8.base64; +package com.baeldung.base64encodinganddecoding; import org.apache.commons.codec.binary.Base64; import org.junit.Test; diff --git a/java-strings/src/test/java/com/baeldung/java8/base64/Java8EncodeDecodeUnitTest.java b/java-strings-2/src/test/java/com/baeldung/base64encodinganddecoding/Java8EncodeDecodeUnitTest.java similarity index 98% rename from java-strings/src/test/java/com/baeldung/java8/base64/Java8EncodeDecodeUnitTest.java rename to java-strings-2/src/test/java/com/baeldung/base64encodinganddecoding/Java8EncodeDecodeUnitTest.java index 62cfa4c0a1..191a3628e8 100644 --- a/java-strings/src/test/java/com/baeldung/java8/base64/Java8EncodeDecodeUnitTest.java +++ b/java-strings-2/src/test/java/com/baeldung/base64encodinganddecoding/Java8EncodeDecodeUnitTest.java @@ -1,4 +1,4 @@ -package com.baeldung.java8.base64; +package com.baeldung.base64encodinganddecoding; import org.junit.Test; diff --git a/java-strings/src/test/java/com/baeldung/java8/base64/StringToByteArrayUnitTest.java b/java-strings-2/src/test/java/com/baeldung/base64encodinganddecoding/StringToByteArrayUnitTest.java similarity index 97% rename from java-strings/src/test/java/com/baeldung/java8/base64/StringToByteArrayUnitTest.java rename to java-strings-2/src/test/java/com/baeldung/base64encodinganddecoding/StringToByteArrayUnitTest.java index c5f7051c25..e2bb7bb64d 100644 --- a/java-strings/src/test/java/com/baeldung/java8/base64/StringToByteArrayUnitTest.java +++ b/java-strings-2/src/test/java/com/baeldung/base64encodinganddecoding/StringToByteArrayUnitTest.java @@ -1,4 +1,4 @@ -package com.baeldung.java8.base64; +package com.baeldung.base64encodinganddecoding; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; 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/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/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-2/src/test/java/com/baeldung/string/streamtokenizer/StreamTokenizerDemoUnitTest.java b/java-strings-2/src/test/java/com/baeldung/string/streamtokenizer/StreamTokenizerDemoUnitTest.java new file mode 100644 index 0000000000..01091ec629 --- /dev/null +++ b/java-strings-2/src/test/java/com/baeldung/string/streamtokenizer/StreamTokenizerDemoUnitTest.java @@ -0,0 +1,34 @@ +package com.baeldung.string.streamtokenizer; + +import org.junit.Test; + +import java.io.IOException; +import java.io.Reader; +import java.util.Arrays; +import java.util.List; + +import static org.junit.Assert.assertArrayEquals; + +public class StreamTokenizerDemoUnitTest { + + @Test + public void whenStreamTokenizerWithDefaultConfigurationIsCalled_ThenCorrectTokensAreReturned() throws IOException { + Reader reader = StreamTokenizerDemo.createReaderFromFile(); + List expectedTokens = Arrays.asList(3.0, "quick", "brown", "foxes", "jump", "over", "the", "lazy", "dog", '!', '#', "test1"); + + List actualTokens = StreamTokenizerDemo.streamTokenizerWithDefaultConfiguration(reader); + + assertArrayEquals(expectedTokens.toArray(), actualTokens.toArray()); + } + + @Test + public void whenStreamTokenizerWithCustomConfigurationIsCalled_ThenCorrectTokensAreReturned() throws IOException { + Reader reader = StreamTokenizerDemo.createReaderFromFile(); + List expectedTokens = Arrays.asList(3.0, "quick", "brown", "foxes", "jump", "over", "the", "\"lazy\"", "dog!", '\n', '\n', '/', '/', "test2"); + + List actualTokens = StreamTokenizerDemo.streamTokenizerWithCustomConfiguration(reader); + + assertArrayEquals(expectedTokens.toArray(), actualTokens.toArray()); + } + +} 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/wordcount/WordCounter.java b/java-strings-3/src/main/java/com/baeldung/string/wordcount/WordCounter.java new file mode 100644 index 0000000000..30275773a6 --- /dev/null +++ b/java-strings-3/src/main/java/com/baeldung/string/wordcount/WordCounter.java @@ -0,0 +1,49 @@ +package com.baeldung.string.wordcount; + +import java.util.StringTokenizer; + +public class WordCounter { + static final int WORD = 0; + static final int SEPARATOR = 1; + + public static int countWordsUsingRegex(String arg) { + if (arg == null) { + return 0; + } + final String[] words = arg.split("[\\pP\\s&&[^']]+"); + return words.length; + } + + public static int countWordsUsingTokenizer(String arg) { + if (arg == null) { + return 0; + } + final StringTokenizer stringTokenizer = new StringTokenizer(arg); + return stringTokenizer.countTokens(); + } + + public static int countWordsManually(String arg) { + if (arg == null) { + return 0; + } + int flag = SEPARATOR; + int count = 0; + int stringLength = arg.length(); + int characterCounter = 0; + + while (characterCounter < stringLength) { + if (isAllowedInWord(arg.charAt(characterCounter)) && flag == SEPARATOR) { + flag = WORD; + count++; + } else if (!isAllowedInWord(arg.charAt(characterCounter))) { + flag = SEPARATOR; + } + characterCounter++; + } + return count; + } + + private static boolean isAllowedInWord(char charAt) { + return charAt == '\'' || Character.isLetter(charAt); + } +} diff --git a/java-strings-3/src/main/resources/.gitignore b/java-strings-3/src/main/resources/.gitignore new file mode 100644 index 0000000000..83c05e60c8 --- /dev/null +++ b/java-strings-3/src/main/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-3/src/test/java/com/baeldung/string/charArrayToString/CharArrayToStringConversionUnitTest.java b/java-strings-3/src/test/java/com/baeldung/string/charArrayToString/CharArrayToStringConversionUnitTest.java new file mode 100644 index 0000000000..1030185c3e --- /dev/null +++ b/java-strings-3/src/test/java/com/baeldung/string/charArrayToString/CharArrayToStringConversionUnitTest.java @@ -0,0 +1,72 @@ +package com.baeldung.string.charArrayToString; + +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; + +import com.google.common.base.Joiner; +import org.junit.Test; + +import java.util.Arrays; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class CharArrayToStringConversionUnitTest { + + @Test + public void whenStringConstructor_thenOK() { + final char[] charArray = { 'b', 'a', 'e', 'l', 'd', 'u', 'n', 'g' }; + + String string = new String(charArray); + + assertThat(string, is("baeldung")); + } + + @Test + public void whenStringCopyValueOf_thenOK() { + final char[] charArray = { 'b', 'a', 'e', 'l', 'd', 'u', 'n', 'g' }; + + String string = String.copyValueOf(charArray); + + assertThat(string, is("baeldung")); + } + + @Test + public void whenStringValueOf_thenOK() { + final char[] charArray = { 'b', 'a', 'e', 'l', 'd', 'u', 'n', 'g' }; + + String string = String.valueOf(charArray); + + assertThat(string, is("baeldung")); + } + + @Test + public void whenStringBuilder_thenOK() { + final char[][] arrayOfCharArray = { { 'b', 'a' }, { 'e', 'l', 'd', 'u' }, { 'n', 'g' } }; + + StringBuilder sb = new StringBuilder(); + for (char[] subArray : arrayOfCharArray) { + sb.append(subArray); + } + + assertThat(sb.toString(), is("baeldung")); + } + + @Test + public void whenStreamCollectors_thenOK() { + final Character[] charArray = { 'b', 'a', 'e', 'l', 'd', 'u', 'n', 'g' }; + + Stream charStream = Arrays.stream(charArray); + String string = charStream.map(String::valueOf).collect(Collectors.joining()); + + assertThat(string, is("baeldung")); + } + + @Test + public void whenGoogleCommonBaseJoiners_thenOK() { + final Character[] charArray = { 'b', 'a', 'e', 'l', 'd', 'u', 'n', 'g' }; + + String string = Joiner.on("|").join(charArray); + + assertThat(string, is("b|a|e|l|d|u|n|g")); + } +} 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/java-strings-3/src/test/java/com/baeldung/string/wordcount/WordCountUnitTest.java b/java-strings-3/src/test/java/com/baeldung/string/wordcount/WordCountUnitTest.java new file mode 100644 index 0000000000..fdd045978f --- /dev/null +++ b/java-strings-3/src/test/java/com/baeldung/string/wordcount/WordCountUnitTest.java @@ -0,0 +1,35 @@ +package com.baeldung.string.wordcount; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import java.util.StringTokenizer; + +public class WordCountUnitTest { + private String string1 = "This is a test sentence with eight words"; + private String string2 = "This#is%a test sentence with eight words"; + + @Test + public void givenStringWith8Words_whenUsingRegexCount_ThenResultEqual8() { + assertEquals(8, WordCounter.countWordsUsingRegex(string2)); + assertEquals(9, WordCounter.countWordsUsingRegex("no&one#should%ever-write-like,this;but:well")); + assertEquals(7, WordCounter.countWordsUsingRegex("the farmer's wife--she was from Albuquerque")); + } + + @Test + public void givenStringWith8Words_whenUsingManualMethod_ThenWordCountEqual8() { + assertEquals(8, WordCounter.countWordsManually(string1)); + assertEquals(9, WordCounter.countWordsManually("no&one#should%ever-write-like,this but well")); + assertEquals(7, WordCounter.countWordsManually("the farmer's wife--she was from Albuquerque")); + } + + @Test + public void givenAStringWith8Words_whenUsingTokenizer_ThenWordCountEqual8() { + assertEquals(8, WordCounter.countWordsUsingTokenizer(string1)); + assertEquals(3, new StringTokenizer("three blind mice").countTokens()); + assertEquals(4, new StringTokenizer("see\thow\tthey\trun").countTokens()); + assertEquals(7, new StringTokenizer("the farmer's wife--she was from Albuquerque", " -").countTokens()); + assertEquals(10, new StringTokenizer("did,you,ever,see,such,a,sight,in,your,life", ",").countTokens()); + } +} diff --git a/java-strings-3/src/test/resources/.gitignore b/java-strings-3/src/test/resources/.gitignore new file mode 100644 index 0000000000..83c05e60c8 --- /dev/null +++ b/java-strings-3/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-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/Twitter4J/src/main/resources/logback.xml b/java-strings-ops/src/main/resources/logback.xml similarity index 100% rename from Twitter4J/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/java-strings/src/main/java/com/baeldung/string/AddingNewLineToString.java b/java-strings/src/main/java/com/baeldung/string/newline/AddingNewLineToString.java similarity index 98% rename from java-strings/src/main/java/com/baeldung/string/AddingNewLineToString.java rename to java-strings/src/main/java/com/baeldung/string/newline/AddingNewLineToString.java index b522f7337b..48b71eed12 100644 --- a/java-strings/src/main/java/com/baeldung/string/AddingNewLineToString.java +++ b/java-strings/src/main/java/com/baeldung/string/newline/AddingNewLineToString.java @@ -1,4 +1,4 @@ -package com.baeldung.string; +package com.baeldung.string.newline; public class AddingNewLineToString { 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/validationgroup/AdvanceInfo.java b/javaxval/src/main/java/org/baeldung/javabeanconstraints/validationgroup/AdvanceInfo.java new file mode 100644 index 0000000000..4d5df052c2 --- /dev/null +++ b/javaxval/src/main/java/org/baeldung/javabeanconstraints/validationgroup/AdvanceInfo.java @@ -0,0 +1,5 @@ +package org.baeldung.javabeanconstraints.validationgroup; + +public interface AdvanceInfo { + +} diff --git a/javaxval/src/main/java/org/baeldung/javabeanconstraints/validationgroup/BasicInfo.java b/javaxval/src/main/java/org/baeldung/javabeanconstraints/validationgroup/BasicInfo.java new file mode 100644 index 0000000000..4564a7a702 --- /dev/null +++ b/javaxval/src/main/java/org/baeldung/javabeanconstraints/validationgroup/BasicInfo.java @@ -0,0 +1,5 @@ +package org.baeldung.javabeanconstraints.validationgroup; + +public interface BasicInfo { + +} diff --git a/javaxval/src/main/java/org/baeldung/javabeanconstraints/validationgroup/RegistrationForm.java b/javaxval/src/main/java/org/baeldung/javabeanconstraints/validationgroup/RegistrationForm.java new file mode 100644 index 0000000000..154d9821b6 --- /dev/null +++ b/javaxval/src/main/java/org/baeldung/javabeanconstraints/validationgroup/RegistrationForm.java @@ -0,0 +1,99 @@ +package org.baeldung.javabeanconstraints.validationgroup; + +import javax.validation.constraints.Email; +import javax.validation.constraints.NotBlank; + +public class RegistrationForm { + @NotBlank(groups = BasicInfo.class) + private String firstName; + @NotBlank(groups = BasicInfo.class) + private String lastName; + @Email(groups = BasicInfo.class) + private String email; + @NotBlank(groups = BasicInfo.class) + private String phone; + + @NotBlank(groups = AdvanceInfo.class) + private String street; + @NotBlank(groups = AdvanceInfo.class) + private String houseNumber; + @NotBlank(groups = AdvanceInfo.class) + private String zipCode; + @NotBlank(groups = AdvanceInfo.class) + private String city; + @NotBlank(groups = AdvanceInfo.class) + private String contry; + + public String getStreet() { + return street; + } + + public void setStreet(String street) { + this.street = street; + } + + public String getHouseNumber() { + return houseNumber; + } + + public void setHouseNumber(String houseNumber) { + this.houseNumber = houseNumber; + } + + public String getZipCode() { + return zipCode; + } + + public void setZipCode(String zipCode) { + this.zipCode = zipCode; + } + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + + public String getContry() { + return contry; + } + + public void setContry(String contry) { + this.contry = contry; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + +} diff --git a/javaxval/src/main/java/org/baeldung/User.java b/javaxval/src/main/java/org/baeldung/javaxval/beanvalidation/User.java similarity index 97% rename from javaxval/src/main/java/org/baeldung/User.java rename to javaxval/src/main/java/org/baeldung/javaxval/beanvalidation/User.java index e2f2732399..cf80266c9d 100644 --- a/javaxval/src/main/java/org/baeldung/User.java +++ b/javaxval/src/main/java/org/baeldung/javaxval/beanvalidation/User.java @@ -1,4 +1,4 @@ -package org.baeldung; +package org.baeldung.javaxval.beanvalidation; import java.time.LocalDate; import java.util.List; diff --git a/javaxval/src/test/java/org/baeldung/javabeanconstraints/bigdecimal/InvoiceUnitTest.java b/javaxval/src/test/java/org/baeldung/javabeanconstraints/bigdecimal/InvoiceUnitTest.java index 525dd7d1ad..860177f4c9 100644 --- a/javaxval/src/test/java/org/baeldung/javabeanconstraints/bigdecimal/InvoiceUnitTest.java +++ b/javaxval/src/test/java/org/baeldung/javabeanconstraints/bigdecimal/InvoiceUnitTest.java @@ -26,7 +26,8 @@ public class InvoiceUnitTest { 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)")); + violations.forEach(action-> assertThat(action.getMessage()) + .isEqualTo("numeric value out of bounds (<3 digits>.<2 digits> expected)")); } @Test @@ -41,7 +42,8 @@ public class InvoiceUnitTest { 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)")); + violations.forEach(action-> assertThat(action.getMessage()) + .isEqualTo("numeric value out of bounds (<3 digits>.<2 digits> expected)")); } @Test @@ -49,7 +51,8 @@ public class InvoiceUnitTest { 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")); + violations.forEach(action-> assertThat(action.getMessage()) + .isEqualTo("must be greater than 0.0")); } @Test diff --git a/javaxval/src/test/java/org/baeldung/javabeanconstraints/validationgroup/RegistrationFormUnitTest.java b/javaxval/src/test/java/org/baeldung/javabeanconstraints/validationgroup/RegistrationFormUnitTest.java new file mode 100644 index 0000000000..f8944524f3 --- /dev/null +++ b/javaxval/src/test/java/org/baeldung/javabeanconstraints/validationgroup/RegistrationFormUnitTest.java @@ -0,0 +1,80 @@ +package org.baeldung.javabeanconstraints.validationgroup; + +import static org.assertj.core.api.Assertions.assertThat; + +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 RegistrationFormUnitTest { + private static Validator validator; + + @BeforeClass + public static void setupValidatorInstance() { + validator = Validation.buildDefaultValidatorFactory().getValidator(); + } + + @Test + public void whenBasicInfoIsNotComplete_thenShouldGiveConstraintViolationsOnlyForBasicInfo() { + RegistrationForm form = buildRegistrationFormWithBasicInfo(); + form.setFirstName(""); + Set> violations = validator.validate(form, BasicInfo.class); + assertThat(violations.size()).isEqualTo(1); + violations.forEach(action -> { + assertThat(action.getMessage()).isEqualTo("must not be blank"); + assertThat(action.getPropertyPath().toString()).isEqualTo("firstName"); + }); + } + + @Test + public void whenAdvanceInfoIsNotComplete_thenShouldGiveConstraintViolationsOnlyForAdvanceInfo() { + RegistrationForm form = buildRegistrationFormWithAdvanceInfo(); + form.setZipCode(""); + Set> violations = validator.validate(form, AdvanceInfo.class); + assertThat(violations.size()).isEqualTo(1); + violations.forEach(action -> { + assertThat(action.getMessage()).isEqualTo("must not be blank"); + assertThat(action.getPropertyPath().toString()).isEqualTo("zipCode"); + }); + } + + @Test + public void whenBasicAndAdvanceInfoIsComplete_thenShouldNotGiveConstraintViolations() { + RegistrationForm form = buildRegistrationFormWithBasicAndAdvanceInfo(); + Set> violations = validator.validate(form); + assertThat(violations.size()).isEqualTo(0); + } + + private RegistrationForm buildRegistrationFormWithBasicInfo() { + RegistrationForm form = new RegistrationForm(); + form.setFirstName("devender"); + form.setLastName("kumar"); + form.setEmail("anyemail@yopmail.com"); + form.setPhone("12345"); + return form; + } + + private RegistrationForm buildRegistrationFormWithAdvanceInfo() { + RegistrationForm form = new RegistrationForm(); + return populateAdvanceInfo(form); + } + + private RegistrationForm populateAdvanceInfo(RegistrationForm form) { + form.setCity("Berlin"); + form.setContry("DE"); + form.setStreet("alexa str."); + form.setZipCode("19923"); + form.setHouseNumber("2a"); + return form; + } + + private RegistrationForm buildRegistrationFormWithBasicAndAdvanceInfo() { + RegistrationForm form = buildRegistrationFormWithBasicInfo(); + return populateAdvanceInfo(form); + } +} diff --git a/javaxval/src/test/java/org/baeldung/ValidationIntegrationTest.java b/javaxval/src/test/java/org/baeldung/javaxval/beanvalidation/ValidationIntegrationTest.java similarity index 97% rename from javaxval/src/test/java/org/baeldung/ValidationIntegrationTest.java rename to javaxval/src/test/java/org/baeldung/javaxval/beanvalidation/ValidationIntegrationTest.java index 78745a1af2..6639d60ac6 100644 --- a/javaxval/src/test/java/org/baeldung/ValidationIntegrationTest.java +++ b/javaxval/src/test/java/org/baeldung/javaxval/beanvalidation/ValidationIntegrationTest.java @@ -1,20 +1,18 @@ -package org.baeldung; +package org.baeldung.javaxval.beanvalidation; + +import static org.junit.Assert.assertEquals; import java.time.LocalDate; import java.util.Collections; -import java.util.Iterator; import java.util.Set; -import java.util.Optional; - import javax.validation.ConstraintViolation; import javax.validation.Validation; import javax.validation.Validator; import javax.validation.ValidatorFactory; -import static org.junit.Assert.*; -import org.junit.Test; import org.junit.Before; +import org.junit.Test; public class ValidationIntegrationTest { 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/jersey/pom.xml b/jersey/pom.xml index 708b36ce41..0b4d469e3a 100644 --- a/jersey/pom.xml +++ b/jersey/pom.xml @@ -32,7 +32,7 @@ org.glassfish.jersey.containers jersey-container-grizzly2-servlet - ${jersey.version} + ${jersey.version} org.glassfish.jersey.ext @@ -44,6 +44,21 @@ jersey-bean-validation ${jersey.version} + + org.glassfish.jersey.security + oauth1-client + ${jersey.version} + + + org.glassfish.jersey.security + oauth2-client + ${jersey.version} + + + org.glassfish.jersey.media + jersey-media-sse + ${jersey.version} + org.glassfish.jersey.test-framework jersey-test-framework-core diff --git a/jersey/src/main/java/com/baeldung/jersey/client/JerseyClientHeaders.java b/jersey/src/main/java/com/baeldung/jersey/client/JerseyClientHeaders.java new file mode 100644 index 0000000000..ebcbe1d4ab --- /dev/null +++ b/jersey/src/main/java/com/baeldung/jersey/client/JerseyClientHeaders.java @@ -0,0 +1,189 @@ +package com.baeldung.jersey.client; + +import com.baeldung.jersey.client.filter.AddHeaderOnRequestFilter; +import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature; +import org.glassfish.jersey.client.oauth1.AccessToken; +import org.glassfish.jersey.client.oauth1.ConsumerCredentials; +import org.glassfish.jersey.client.oauth1.OAuth1ClientSupport; +import org.glassfish.jersey.client.oauth2.OAuth2ClientSupport; + +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Invocation; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.Feature; +import javax.ws.rs.core.Response; +import javax.ws.rs.sse.InboundSseEvent; +import javax.ws.rs.sse.SseEventSource; + +import static org.glassfish.jersey.client.authentication.HttpAuthenticationFeature.*; + +public class JerseyClientHeaders { + + private static final String BEARER_CONSUMER_SECRET = "my-consumer-secret"; + private static final String BEARER_ACCESS_TOKEN_SECRET = "my-access-token-secret"; + private static final String TARGET = "http://localhost:9998/"; + private static final String MAIN_RESOURCE = "echo-headers"; + private static final String RESOURCE_AUTH_DIGEST = "digest"; + + private static String sseHeaderValue; + + public static Response simpleHeader(String headerKey, String headerValue) { + Client client = ClientBuilder.newClient(); + WebTarget webTarget = client.target(TARGET); + WebTarget resourceWebTarget = webTarget.path(MAIN_RESOURCE); + Invocation.Builder invocationBuilder = resourceWebTarget.request(); + invocationBuilder.header(headerKey, headerValue); + return invocationBuilder.get(); + } + + public static Response simpleHeaderFluently(String headerKey, String headerValue) { + Client client = ClientBuilder.newClient(); + return client.target(TARGET) + .path(MAIN_RESOURCE) + .request() + .header(headerKey, headerValue) + .get(); + } + + public static Response basicAuthenticationAtClientLevel(String username, String password) { + //To simplify we removed de SSL/TLS protection, but it's required to have an encryption + // when using basic authentication schema as it's send only on Base64 encoding + HttpAuthenticationFeature feature = HttpAuthenticationFeature.basic(username, password); + Client client = ClientBuilder.newBuilder().register(feature).build(); + return client.target(TARGET) + .path(MAIN_RESOURCE) + .request() + .get(); + } + + public static Response basicAuthenticationAtRequestLevel(String username, String password) { + //To simplify we removed de SSL/TLS protection, but it's required to have an encryption + // when using basic authentication schema as it's send only on Base64 encoding + HttpAuthenticationFeature feature = HttpAuthenticationFeature.basicBuilder().build(); + Client client = ClientBuilder.newBuilder().register(feature).build(); + return client.target(TARGET) + .path(MAIN_RESOURCE) + .request() + .property(HTTP_AUTHENTICATION_BASIC_USERNAME, username) + .property(HTTP_AUTHENTICATION_BASIC_PASSWORD, password) + .get(); + } + + public static Response digestAuthenticationAtClientLevel(String username, String password) { + HttpAuthenticationFeature feature = HttpAuthenticationFeature.digest(username, password); + Client client = ClientBuilder.newBuilder().register(feature).build(); + return client.target(TARGET) + .path(MAIN_RESOURCE) + .path(RESOURCE_AUTH_DIGEST) + .request() + .get(); + } + + public static Response digestAuthenticationAtRequestLevel(String username, String password) { + HttpAuthenticationFeature feature = HttpAuthenticationFeature.digest(); + + Client client = ClientBuilder.newBuilder().register(feature).build(); + return client.target(TARGET) + .path(MAIN_RESOURCE) + .path(RESOURCE_AUTH_DIGEST) + .request() + .property(HTTP_AUTHENTICATION_DIGEST_USERNAME, username) + .property(HTTP_AUTHENTICATION_DIGEST_PASSWORD, password) + .get(); + } + + public static Response bearerAuthenticationWithOAuth1AtClientLevel(String token, String consumerKey) { + ConsumerCredentials consumerCredential = new ConsumerCredentials(consumerKey, BEARER_CONSUMER_SECRET); + AccessToken accessToken = new AccessToken(token, BEARER_ACCESS_TOKEN_SECRET); + Feature feature = OAuth1ClientSupport + .builder(consumerCredential) + .feature() + .accessToken(accessToken) + .build(); + + Client client = ClientBuilder.newBuilder().register(feature).build(); + return client.target(TARGET) + .path(MAIN_RESOURCE) + .request() + .get(); + } + + public static Response bearerAuthenticationWithOAuth1AtRequestLevel(String token, String consumerKey) { + ConsumerCredentials consumerCredential = new ConsumerCredentials(consumerKey, BEARER_CONSUMER_SECRET); + AccessToken accessToken = new AccessToken(token, BEARER_ACCESS_TOKEN_SECRET); + Feature feature = OAuth1ClientSupport + .builder(consumerCredential) + .feature() + .build(); + + Client client = ClientBuilder.newBuilder().register(feature).build(); + return client.target(TARGET) + .path(MAIN_RESOURCE) + .request() + .property(OAuth1ClientSupport.OAUTH_PROPERTY_ACCESS_TOKEN, accessToken) + .get(); + } + + public static Response bearerAuthenticationWithOAuth2AtClientLevel(String token) { + Feature feature = OAuth2ClientSupport.feature(token); + + Client client = ClientBuilder.newBuilder().register(feature).build(); + return client.target(TARGET) + .path(MAIN_RESOURCE) + .request() + .get(); + } + + public static Response bearerAuthenticationWithOAuth2AtRequestLevel(String token, String otherToken) { + Feature feature = OAuth2ClientSupport.feature(token); + + Client client = ClientBuilder.newBuilder().register(feature).build(); + return client.target(TARGET) + .path(MAIN_RESOURCE) + .request() + .property(OAuth2ClientSupport.OAUTH2_PROPERTY_ACCESS_TOKEN, otherToken) + .get(); + } + + public static Response filter() { + Client client = ClientBuilder.newBuilder().register(AddHeaderOnRequestFilter.class).build(); + return client.target(TARGET) + .path(MAIN_RESOURCE) + .request() + .get(); + } + + public static Response sendRestrictedHeaderThroughDefaultTransportConnector(String headerKey, String headerValue) { + Client client = ClientBuilder.newClient(); + System.setProperty("sun.net.http.allowRestrictedHeaders", "true"); + + return client.target(TARGET) + .path(MAIN_RESOURCE) + .request() + .header(headerKey, headerValue) + .get(); + } + + public static String simpleSSEHeader() throws InterruptedException { + Client client = ClientBuilder.newBuilder() + .register(AddHeaderOnRequestFilter.class) + .build(); + + WebTarget webTarget = client.target(TARGET) + .path(MAIN_RESOURCE) + .path("events"); + + SseEventSource sseEventSource = SseEventSource.target(webTarget).build(); + sseEventSource.register(JerseyClientHeaders::receiveEvent); + sseEventSource.open(); + Thread.sleep(3_000); + sseEventSource.close(); + + return sseHeaderValue; + } + + private static void receiveEvent(InboundSseEvent event) { + sseHeaderValue = event.readData(); + } +} diff --git a/jersey/src/main/java/com/baeldung/jersey/client/filter/AddHeaderOnRequestFilter.java b/jersey/src/main/java/com/baeldung/jersey/client/filter/AddHeaderOnRequestFilter.java new file mode 100644 index 0000000000..a874928c16 --- /dev/null +++ b/jersey/src/main/java/com/baeldung/jersey/client/filter/AddHeaderOnRequestFilter.java @@ -0,0 +1,16 @@ +package com.baeldung.jersey.client.filter; + +import javax.ws.rs.client.ClientRequestContext; +import javax.ws.rs.client.ClientRequestFilter; +import java.io.IOException; + +public class AddHeaderOnRequestFilter implements ClientRequestFilter { + + public static final String FILTER_HEADER_VALUE = "filter-header-value"; + public static final String FILTER_HEADER_KEY = "x-filter-header"; + + @Override + public void filter(ClientRequestContext requestContext) throws IOException { + requestContext.getHeaders().add(FILTER_HEADER_KEY, FILTER_HEADER_VALUE); + } +} diff --git a/jersey/src/main/java/com/baeldung/jersey/server/EchoHeaders.java b/jersey/src/main/java/com/baeldung/jersey/server/EchoHeaders.java new file mode 100644 index 0000000000..a8df3c10a8 --- /dev/null +++ b/jersey/src/main/java/com/baeldung/jersey/server/EchoHeaders.java @@ -0,0 +1,72 @@ +package com.baeldung.jersey.server; + +import com.baeldung.jersey.client.filter.AddHeaderOnRequestFilter; + +import javax.annotation.security.RolesAllowed; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.*; +import javax.ws.rs.sse.OutboundSseEvent; +import javax.ws.rs.sse.Sse; +import javax.ws.rs.sse.SseEventSink; + +@Path("/echo-headers") +public class EchoHeaders { + + static final String REALM_KEY = "realm"; + static final String REALM_VALUE = "Baeldung"; + static final String QOP_KEY = "qop"; + static final String QOP_VALUE = "auth"; + static final String NONCE_KEY = "nonce"; + static final String NONCE_VALUE = "dcd98b7102dd2f0e8b11d0f600bfb0c093"; + static final String OPAQUE_KEY = "opaque"; + static final String OPAQUE_VALUE = "5ccc069c403ebaf9f0171e9517f40e41"; + static final String SSE_HEADER_KEY = "x-sse-header-key"; + + @Context + HttpHeaders headers; + + @GET + public Response getHeadersBack() { + return echoHeaders(); + } + + @RolesAllowed("ADMIN") + @GET + @Path("/digest") + public Response getHeadersBackFromDigestAuthentication() { + // As the Digest authentication require some complex steps to work we'll simulate the process + // https://en.wikipedia.org/wiki/Digest_access_authentication#Example_with_explanation + if (headers.getHeaderString("authorization") == null) { + String authenticationRequired = "Digest " + REALM_KEY + "=\"" + REALM_VALUE + "\", " + QOP_KEY + "=\"" + QOP_VALUE + "\", " + NONCE_KEY + "=\"" + NONCE_VALUE + "\", " + OPAQUE_KEY + "=\"" + OPAQUE_VALUE + "\""; + return Response.status(Response.Status.UNAUTHORIZED) + .header("WWW-Authenticate", authenticationRequired) + .build(); + } else { + return echoHeaders(); + } + } + + @GET + @Path("/events") + @Produces(MediaType.SERVER_SENT_EVENTS) + public void getServerSentEvents(@Context SseEventSink eventSink, @Context Sse sse) { + OutboundSseEvent event = sse.newEventBuilder() + .name("echo-headers") + .data(String.class, headers.getHeaderString(AddHeaderOnRequestFilter.FILTER_HEADER_KEY)) + .build(); + eventSink.send(event); + } + + private Response echoHeaders() { + Response.ResponseBuilder responseBuilder = Response.noContent(); + + headers.getRequestHeaders() + .forEach((k, v) -> { + v.forEach(value -> responseBuilder.header(k, value)); + }); + + return responseBuilder.build(); + } +} diff --git a/jersey/src/test/java/com/baeldung/jersey/server/EchoHeadersUnitTest.java b/jersey/src/test/java/com/baeldung/jersey/server/EchoHeadersUnitTest.java new file mode 100644 index 0000000000..ac2cc2c4eb --- /dev/null +++ b/jersey/src/test/java/com/baeldung/jersey/server/EchoHeadersUnitTest.java @@ -0,0 +1,197 @@ +package com.baeldung.jersey.server; + +import com.baeldung.jersey.client.JerseyClientHeaders; +import com.baeldung.jersey.client.filter.AddHeaderOnRequestFilter; +import org.glassfish.jersey.media.sse.SseFeature; +import org.glassfish.jersey.server.ResourceConfig; +import org.glassfish.jersey.test.JerseyTest; +import org.junit.Test; + +import javax.ws.rs.core.Application; +import javax.ws.rs.core.Response; +import java.util.Base64; +import java.util.HashMap; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +public class EchoHeadersUnitTest extends JerseyTest { + + private static final String SIMPLE_HEADER_KEY = "my-header-key"; + private static final String SIMPLE_HEADER_VALUE = "my-header-value"; + private static final String USERNAME = "baeldung"; + private static final String PASSWORD = "super-secret"; + private static final String AUTHORIZATION_HEADER_KEY = "authorization"; + private static final String BEARER_TOKEN_VALUE = "my-token"; + private static final String BEARER_CONSUMER_KEY_VALUE = "my-consumer-key"; + private static final String BEARER_REQUEST_TOKEN_VALUE = "my-request-token"; + + @Test + public void whenCallingSimpleHeader_thenHeadersReturnedBack() { + Response response = JerseyClientHeaders.simpleHeader(SIMPLE_HEADER_KEY, SIMPLE_HEADER_VALUE); + + assertEquals(response.getHeaderString(SIMPLE_HEADER_KEY), SIMPLE_HEADER_VALUE); + } + + @Test + public void whenCallingSimpleHeaderFluently_thenHeadersReturnedBack() { + Response response = JerseyClientHeaders.simpleHeaderFluently(SIMPLE_HEADER_KEY, SIMPLE_HEADER_VALUE); + + assertEquals(response.getHeaderString(SIMPLE_HEADER_KEY), SIMPLE_HEADER_VALUE); + } + + @Test + public void whenCallingBasicAuthenticationAtClientLevel_thenHeadersReturnedBack() { + Response response = JerseyClientHeaders.basicAuthenticationAtClientLevel(USERNAME, PASSWORD); + + assertBasicAuthenticationHeaders(response); + } + + @Test + public void whenCallingBasicAuthenticationAtRequestLevel_thenHeadersReturnedBack() { + Response response = JerseyClientHeaders.basicAuthenticationAtRequestLevel(USERNAME, PASSWORD); + + assertBasicAuthenticationHeaders(response); + } + + @Test + public void whenCallingDigestAuthenticationAtClientLevel_thenHeadersReturnedBack() { + Response response = JerseyClientHeaders.digestAuthenticationAtClientLevel(USERNAME, PASSWORD); + + Map subHeadersMap = parseAuthenticationSubHeader(response, 7); + + assertDigestAuthenticationHeaders(subHeadersMap); + } + + @Test + public void whenCallingDigestAuthenticationAtRequestLevel_thenHeadersReturnedBack() { + Response response = JerseyClientHeaders.digestAuthenticationAtRequestLevel(USERNAME, PASSWORD); + + Map subHeadersMap = parseAuthenticationSubHeader(response, 7); + + assertDigestAuthenticationHeaders(subHeadersMap); + } + + @Test + public void whenCallingBearerAuthenticationWithOAuth1AtClientLevel_thenHeadersReturnedBack() { + Response response = JerseyClientHeaders.bearerAuthenticationWithOAuth1AtClientLevel(BEARER_TOKEN_VALUE, BEARER_CONSUMER_KEY_VALUE); + + Map subHeadersMap = parseAuthenticationSubHeader(response, 6); + + assertBearerAuthenticationHeaders(subHeadersMap); + } + + @Test + public void whenCallingBearerAuthenticationWithOAuth1AtRequestLevel_thenHeadersReturnedBack() { + Response response = JerseyClientHeaders.bearerAuthenticationWithOAuth1AtRequestLevel(BEARER_TOKEN_VALUE, BEARER_CONSUMER_KEY_VALUE); + + Map subHeadersMap = parseAuthenticationSubHeader(response, 6); + + assertBearerAuthenticationHeaders(subHeadersMap); + } + + @Test + public void whenCallingBearerAuthenticationWithOAuth2AtClientLevel_thenHeadersReturnedBack() { + Response response = JerseyClientHeaders.bearerAuthenticationWithOAuth2AtClientLevel(BEARER_TOKEN_VALUE); + + assertEquals("Bearer " + BEARER_TOKEN_VALUE, response.getHeaderString(AUTHORIZATION_HEADER_KEY)); + } + + @Test + public void whenCallingBearerAuthenticationWithOAuth2AtRequestLevel_thenHeadersReturnedBack() { + Response response = JerseyClientHeaders.bearerAuthenticationWithOAuth2AtRequestLevel(BEARER_TOKEN_VALUE, BEARER_REQUEST_TOKEN_VALUE); + + assertEquals("Bearer " + BEARER_REQUEST_TOKEN_VALUE, response.getHeaderString(AUTHORIZATION_HEADER_KEY)); + } + + @Test + public void whenCallingFilter_thenHeadersReturnedBack() { + Response response = JerseyClientHeaders.filter(); + + assertEquals(AddHeaderOnRequestFilter.FILTER_HEADER_VALUE, response.getHeaderString(AddHeaderOnRequestFilter.FILTER_HEADER_KEY)); + } + + @Test + public void whenCallingSendRestrictedHeaderThroughDefaultTransportConnector_thenHeadersReturnedBack() { + Response response = JerseyClientHeaders.sendRestrictedHeaderThroughDefaultTransportConnector("keep-alive", "keep-alive-value"); + + assertEquals("keep-alive-value", response.getHeaderString("keep-alive")); + } + + @Test + public void whenCallingSimpleSSEHeader_thenHeadersReturnedBack() throws InterruptedException { + String sseHeaderBackValue = JerseyClientHeaders.simpleSSEHeader(); + + assertEquals(AddHeaderOnRequestFilter.FILTER_HEADER_VALUE, sseHeaderBackValue); + } + + private void assertBearerAuthenticationHeaders(Map subHeadersMap) { + + assertEquals(BEARER_TOKEN_VALUE, subHeadersMap.get("oauth_token")); + assertEquals(BEARER_CONSUMER_KEY_VALUE, subHeadersMap.get("oauth_consumer_key")); + assertNotNull(subHeadersMap.get("oauth_nonce")); + assertNotNull(subHeadersMap.get("oauth_signature")); + assertNotNull(subHeadersMap.get("oauth_callback")); + assertNotNull(subHeadersMap.get("oauth_signature_method")); + assertNotNull(subHeadersMap.get("oauth_version")); + assertNotNull(subHeadersMap.get("oauth_timestamp")); + } + + private void assertDigestAuthenticationHeaders(Map subHeadersMap) { + assertEquals(EchoHeaders.NONCE_VALUE, subHeadersMap.get(EchoHeaders.NONCE_KEY)); + assertEquals(EchoHeaders.OPAQUE_VALUE, subHeadersMap.get(EchoHeaders.OPAQUE_KEY)); + assertEquals(EchoHeaders.QOP_VALUE, subHeadersMap.get(EchoHeaders.QOP_KEY)); + assertEquals(EchoHeaders.REALM_VALUE, subHeadersMap.get(EchoHeaders.REALM_KEY)); + + assertEquals(USERNAME, subHeadersMap.get("username")); + assertEquals("/echo-headers/digest", subHeadersMap.get("uri")); + assertNotNull(subHeadersMap.get("cnonce")); + assertEquals("00000001", subHeadersMap.get("nc")); + assertNotNull(subHeadersMap.get("response")); + } + + private Map parseAuthenticationSubHeader(Response response, int startAt) { + String authorizationHeader = response.getHeaderString(AUTHORIZATION_HEADER_KEY); + // The substring(startAt) is used to cut off the authentication schema part from the value returned. + String[] subHeadersKeyValue = authorizationHeader.substring(startAt).split(","); + Map subHeadersMap = new HashMap<>(); + + for (String subHeader : subHeadersKeyValue) { + String[] keyValue = subHeader.split("="); + + if (keyValue[1].startsWith("\"")) { + keyValue[1] = keyValue[1].substring(1, keyValue[1].length() - 1); + } + + subHeadersMap.put(keyValue[0].trim(), keyValue[1].trim()); + } + return subHeadersMap; + } + + private void assertBasicAuthenticationHeaders(Response response) { + String base64Credentials = response.getHeaderString(AUTHORIZATION_HEADER_KEY); + // The substring(6) is used to cut the "Basic " part of the value returned, + // as it's used to indicates the authentication schema and does not belong to the credentials + byte[] credentials = Base64.getDecoder().decode(base64Credentials.substring(6)); + String[] credentialsParsed = new String(credentials).split(":"); + + assertEquals(credentialsParsed[0], USERNAME); + assertEquals(credentialsParsed[1], PASSWORD); + } + + @Override + protected Application configure() { + return new ResourceConfig() + .register(EchoHeaders.class); + } + + @Override + public void setUp() throws Exception { + super.setUp(); + // We need this definition here, because if you are running + // the complete suit test the sendingRestrictedHeaderThroughDefaultTransportConnector_shouldReturnThanBack + // will fail if only defined on the client method, since the JerseyTest is created once. + System.setProperty("sun.net.http.allowRestrictedHeaders", "true"); + } +} \ No newline at end of file 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/spring-amqp-simple/src/main/resources/logback.xml b/jgit/src/main/resources/logback.xml similarity index 100% rename from spring-amqp-simple/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-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/security/CustomAuthenticationManager.java b/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/security/CustomAuthenticationManager.java new file mode 100644 index 0000000000..0a7dd66b24 --- /dev/null +++ b/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/security/CustomAuthenticationManager.java @@ -0,0 +1,126 @@ +package com.baeldung.jhipster5.security; + +import com.baeldung.jhipster5.domain.User; +import com.baeldung.jhipster5.security.dto.LoginRequest; +import com.baeldung.jhipster5.security.dto.LoginResponse; +import com.baeldung.jhipster5.service.UserService; +import com.baeldung.jhipster5.service.dto.UserDTO; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.AuthenticationServiceException; +import org.springframework.security.authentication.BadCredentialsException; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.stereotype.Component; +import org.springframework.web.client.RestTemplate; + +import java.util.Collection; +import java.util.Collections; +import java.util.stream.Collectors; + +@Component +public class CustomAuthenticationManager implements AuthenticationManager { + + private final static Logger LOG = LoggerFactory.getLogger(CustomAuthenticationManager.class); + + private final String REMOTE_LOGIN_URL = "https://example.com/login"; + + private final RestTemplate restTemplate = new RestTemplate(); + + @Autowired + private UserService userService; + + @Override + public Authentication authenticate(Authentication authentication) throws AuthenticationException { + + LoginRequest loginRequest = new LoginRequest(); + loginRequest.setUsername(authentication.getPrincipal().toString()); + loginRequest.setPassword(authentication.getCredentials().toString()); + + try + { + ResponseEntity response = + restTemplate.postForEntity( + REMOTE_LOGIN_URL, + loginRequest, + LoginResponse.class); + + if(response.getStatusCode().is2xxSuccessful()) + { + // + // Need to create a new local user if this is the first time logging in; this + // is required so they can be issued JWTs. We can use this flow to also keep + // our local use entry up to date with data from the remote service if needed + // (for example, if the first and last name might change, this is where we would + // update the local user entry) + // + + User user = userService.getUserWithAuthoritiesByLogin(authentication.getPrincipal().toString()) + .orElseGet(() -> userService.createUser(createUserDTO(response.getBody(), authentication))); + return createAuthentication(authentication, user); + } + else + { + throw new BadCredentialsException("Invalid username or password"); + } + } + catch (Exception e) + { + LOG.warn("Failed to authenticate", e); + throw new AuthenticationServiceException("Failed to login", e); + } + } + + /** + * Creates a new authentication with basic roles + * @param auth Contains auth details that will be copied into the new one. + * @param user User object representing who is logging in + * @return Authentication + */ + private Authentication createAuthentication(Authentication auth, User user) { + + // + // Honor any roles the user already has set; default is just USER role + // but could be modified after account creation + // + + Collection authorities = user + .getAuthorities() + .stream() + .map(a -> new SimpleGrantedAuthority(a.getName())) + .collect(Collectors.toSet()); + + UsernamePasswordAuthenticationToken token + = new UsernamePasswordAuthenticationToken( + user.getId(), + auth.getCredentials().toString(), + authorities); + + return token; + } + + /** + * Creates a new UserDTO with basic info. + * @param loginResponse Response from peloton login API + * @param authentication Contains user login info (namely username and password) + * @return UserDTO + */ + private UserDTO createUserDTO(LoginResponse loginResponse, Authentication authentication) { + + UserDTO dto = new UserDTO(); + + dto.setActivated(true); + dto.setEmail(loginResponse.getEmail()); + dto.setAuthorities(Collections.singleton(AuthoritiesConstants.USER)); + dto.setFirstName(loginResponse.getFirstName()); + dto.setLastName(loginResponse.getLastName()); + + return dto; + } +} diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/security/dto/LoginRequest.java b/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/security/dto/LoginRequest.java new file mode 100644 index 0000000000..f45c23fa39 --- /dev/null +++ b/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/security/dto/LoginRequest.java @@ -0,0 +1,30 @@ +package com.baeldung.jhipster5.security.dto; + +/** + * Simple DTO representing a login request to a remote service. + */ +public class LoginRequest { + + private String username; + + private String password; + + public LoginRequest() { + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } +} diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/security/dto/LoginResponse.java b/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/security/dto/LoginResponse.java new file mode 100644 index 0000000000..ad1fe37a2f --- /dev/null +++ b/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/security/dto/LoginResponse.java @@ -0,0 +1,50 @@ +package com.baeldung.jhipster5.security.dto; + +/** + * Simple DTO representing the response of logging in using a remote service. + */ +public class LoginResponse { + + private String username; + + private String firstName; + + private String lastName; + + private String email; + + public LoginResponse() { + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } +} diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/account/account.route.ts b/jhipster-5/bookstore-monolith/src/main/webapp/app/account/account.route.ts index f849342e69..cba5d40716 100644 --- a/jhipster-5/bookstore-monolith/src/main/webapp/app/account/account.route.ts +++ b/jhipster-5/bookstore-monolith/src/main/webapp/app/account/account.route.ts @@ -1,8 +1,8 @@ import { Routes } from '@angular/router'; -import { activateRoute, passwordRoute, passwordResetFinishRoute, passwordResetInitRoute, registerRoute, settingsRoute } from './'; +import { settingsRoute } from './'; -const ACCOUNT_ROUTES = [activateRoute, passwordRoute, passwordResetFinishRoute, passwordResetInitRoute, registerRoute, settingsRoute]; +const ACCOUNT_ROUTES = [settingsRoute]; export const accountState: Routes = [ { diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/layouts/navbar/navbar.component.html b/jhipster-5/bookstore-monolith/src/main/webapp/app/layouts/navbar/navbar.component.html index e58d234c22..4fab5c76ac 100644 --- a/jhipster-5/bookstore-monolith/src/main/webapp/app/layouts/navbar/navbar.component.html +++ b/jhipster-5/bookstore-monolith/src/main/webapp/app/layouts/navbar/navbar.component.html @@ -114,12 +114,6 @@ Settings -
  • - - - Password - -
  • @@ -132,12 +126,6 @@ Sign in
  • -
  • - - - Register - -
  • diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/shared/login/login.component.html b/jhipster-5/bookstore-monolith/src/main/webapp/app/shared/login/login.component.html index 60d593bd4b..7eb35364b4 100644 --- a/jhipster-5/bookstore-monolith/src/main/webapp/app/shared/login/login.component.html +++ b/jhipster-5/bookstore-monolith/src/main/webapp/app/shared/login/login.component.html @@ -30,14 +30,6 @@ -

    - -
    - You don't have an account yet? - Register a new account -
    diff --git a/jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/security/MockAuthenticationManager.java b/jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/security/MockAuthenticationManager.java new file mode 100644 index 0000000000..bdcdba7644 --- /dev/null +++ b/jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/security/MockAuthenticationManager.java @@ -0,0 +1,54 @@ +package com.baeldung.jhipster5.security; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Primary; +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.AuthenticationException; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Component; + +import java.util.Collection; +import java.util.Collections; + +/** + * AuthenticationManager used solely by unit tests. + */ +@Component +@Primary +public class MockAuthenticationManager implements AuthenticationManager +{ + private final static Collection ROLES = + Collections.singleton(new SimpleGrantedAuthority("ROLE_USER")); + + @Autowired + private UserDetailsService userDetailsService; + + @Autowired + private PasswordEncoder passwordEncoder; + + @Override + public Authentication authenticate(Authentication authentication) throws AuthenticationException + { + + UserDetails userDetails = userDetailsService.loadUserByUsername(authentication.getName()); + + if(userDetails == null || !passwordEncoder.matches(authentication.getCredentials().toString(), userDetails.getPassword())) + { + throw new BadCredentialsException("Invalid username/password"); + } + + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken( + authentication.getPrincipal().toString(), + authentication.getCredentials().toString(), + ROLES); + + return token; + } +} diff --git a/jhipster-5/pom.xml b/jhipster-5/pom.xml index df60b01317..cebbe25d8b 100644 --- a/jhipster-5/pom.xml +++ b/jhipster-5/pom.xml @@ -5,7 +5,7 @@ com.baeldung.jhipster jhipster-5 1.0.0-SNAPSHOT - JHipster + jhipster-5 pom 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/jhipster/pom.xml b/jhipster/pom.xml index c50aac0c7a..dd16205706 100644 --- a/jhipster/pom.xml +++ b/jhipster/pom.xml @@ -5,7 +5,7 @@ com.baeldung.jhipster jhipster 1.0.0-SNAPSHOT - JHipster + jhipster pom 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..708006fa15 100644 --- a/libraries-2/pom.xml +++ b/libraries-2/pom.xml @@ -3,8 +3,8 @@ 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 - libraries2 - libraries2 + libraries-2 + libraries-2 com.baeldung @@ -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-2/src/test/java/com/baeldung/matrices/MatrixMultiplicationBenchmarking.java b/libraries-2/src/test/java/com/baeldung/matrices/MatrixMultiplicationBenchmarking.java deleted file mode 100644 index 1e3b183aa7..0000000000 --- a/libraries-2/src/test/java/com/baeldung/matrices/MatrixMultiplicationBenchmarking.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.baeldung.matrices; - -public class MatrixMultiplicationBenchmarking { - - public static void main(String[] args) throws Exception { - org.openjdk.jmh.Main.main(args); - } - -} 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-primitive/pom.xml b/libraries-primitive/pom.xml index 9bb58470b2..12fc35c1b5 100644 --- a/libraries-primitive/pom.xml +++ b/libraries-primitive/pom.xml @@ -7,6 +7,7 @@ com.baeldung libraries-primitive 1.0-SNAPSHOT + libraries-primitive diff --git a/libraries-security/README.md b/libraries-security/README.md index b9bbf11cdf..96f3fcdac6 100644 --- a/libraries-security/README.md +++ b/libraries-security/README.md @@ -3,3 +3,5 @@ - [Guide to ScribeJava](https://www.baeldung.com/scribejava) - [Guide to Passay](https://www.baeldung.com/java-passay) - [Guide to Google Tink](https://www.baeldung.com/google-tink) +- [Introduction to BouncyCastle with Java](https://www.baeldung.com/java-bouncy-castle) +- [Intro to Jasypt](https://www.baeldung.com/jasypt) 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..ebf087ccd8 100644 --- a/libraries/README.md +++ b/libraries/README.md @@ -1,48 +1,28 @@ ### 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 +30,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/metrics/pom.xml b/metrics/pom.xml index 014931a957..4cd9f3de79 100644 --- a/metrics/pom.xml +++ b/metrics/pom.xml @@ -86,6 +86,24 @@ ${spectator-api.version} + + io.astefanutti.metrics.aspectj + metrics-aspectj + ${metrics-aspectj.version} + + + org.slf4j + slf4j-api + + + + + + io.astefanutti.metrics.aspectj + metrics-aspectj-deps + ${metrics-aspectj.version} + + org.assertj assertj-core @@ -104,6 +122,7 @@ 0.57.1 2.0.7.RELEASE 3.11.1 + 1.1.0 diff --git a/metrics/src/main/java/com/baeldung/metrics/aspectj/MetricsAspectJMain.java b/metrics/src/main/java/com/baeldung/metrics/aspectj/MetricsAspectJMain.java new file mode 100644 index 0000000000..5bcf196035 --- /dev/null +++ b/metrics/src/main/java/com/baeldung/metrics/aspectj/MetricsAspectJMain.java @@ -0,0 +1,34 @@ +package com.baeldung.metrics.aspectj; + +import com.codahale.metrics.ConsoleReporter; +import com.codahale.metrics.MetricRegistry; +import com.codahale.metrics.SharedMetricRegistries; +import java.io.PrintStream; +import java.util.concurrent.TimeUnit; + +public class MetricsAspectJMain { + private static final MetricRegistry REGISTRY = new MetricRegistry(); + + public static void main(String args[]) throws InterruptedException { + startReport(); + + ObjectRunner runner = new ObjectRunner(); + + for (int i = 0; i < 5; i++) { + runner.run(); + } + + Thread.sleep(3000L); + } + + private static void startReport() { + SharedMetricRegistries.add(ObjectRunner.REGISTRY_NAME, REGISTRY); + + ConsoleReporter.forRegistry(REGISTRY) + .convertRatesTo(TimeUnit.SECONDS) + .convertDurationsTo(TimeUnit.MILLISECONDS) + .outputTo(new PrintStream(System.out)) + .build() + .start(3, TimeUnit.SECONDS); + } +} diff --git a/metrics/src/main/java/com/baeldung/metrics/aspectj/ObjectRunner.java b/metrics/src/main/java/com/baeldung/metrics/aspectj/ObjectRunner.java new file mode 100644 index 0000000000..ffded9bdb6 --- /dev/null +++ b/metrics/src/main/java/com/baeldung/metrics/aspectj/ObjectRunner.java @@ -0,0 +1,22 @@ +package com.baeldung.metrics.aspectj; + +import com.codahale.metrics.annotation.Timed; +import io.astefanutti.metrics.aspectj.Metrics; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@Metrics( registry = ObjectRunner.REGISTRY_NAME) +public class ObjectRunner { + + private static final Logger logger = LoggerFactory.getLogger(ObjectRunner.class); + public static final String REGISTRY_NAME = "ObjectRunner"; + + @Timed(name = "timerName") + public void run() { + logger.info("run"); + try { + Thread.sleep(1000L); + } catch (InterruptedException e) { + } + } +} diff --git a/oauth2-framework-impl/README.md b/oauth2-framework-impl/README.md new file mode 100644 index 0000000000..60fefe3415 --- /dev/null +++ b/oauth2-framework-impl/README.md @@ -0,0 +1,3 @@ +### Relevant Articles + +- [Implementing The OAuth 2.0 Authorization Framework Using Java EE](https://www.baeldung.com/java-ee-oauth2-implementation) diff --git a/oauth2-framework-impl/oauth2-authorization-server/pom.xml b/oauth2-framework-impl/oauth2-authorization-server/pom.xml index 8db2150558..6ab7a60f72 100644 --- a/oauth2-framework-impl/oauth2-authorization-server/pom.xml +++ b/oauth2-framework-impl/oauth2-authorization-server/pom.xml @@ -6,6 +6,7 @@ oauth2-authorization-server war + oauth2-authorization-server com.baeldung.oauth2 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-client/pom.xml b/oauth2-framework-impl/oauth2-client/pom.xml index e46a44268e..9b2f05c483 100644 --- a/oauth2-framework-impl/oauth2-client/pom.xml +++ b/oauth2-framework-impl/oauth2-client/pom.xml @@ -5,6 +5,7 @@ 4.0.0 oauth2-client war + oauth2-client com.baeldung.oauth2 diff --git a/oauth2-framework-impl/oauth2-resource-server/pom.xml b/oauth2-framework-impl/oauth2-resource-server/pom.xml index 9b58c33472..e6bc860c67 100644 --- a/oauth2-framework-impl/oauth2-resource-server/pom.xml +++ b/oauth2-framework-impl/oauth2-resource-server/pom.xml @@ -5,6 +5,7 @@ 4.0.0 oauth2-resource-server war + oauth2-resource-server com.baeldung.oauth2 diff --git a/oauth2-framework-impl/pom.xml b/oauth2-framework-impl/pom.xml index 281103660b..47d42eaaea 100644 --- a/oauth2-framework-impl/pom.xml +++ b/oauth2-framework-impl/pom.xml @@ -7,6 +7,7 @@ oauth2-framework-impl 1.0-SNAPSHOT pom + oauth2-framework-impl 1.8 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-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..739aa87873 --- /dev/null +++ b/patterns/backoff-jitter/pom.xml @@ -0,0 +1,55 @@ + + + 4.0.0 + com.baeldung + backoff-jitter + 1.0.0-SNAPSHOT + pom + backoff-jitter + + + + 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 392035ab84..f99bb4dc9c 100644 --- a/patterns/design-patterns-2/pom.xml +++ b/patterns/design-patterns-2/pom.xml @@ -31,6 +31,23 @@ commons-lang3 ${commons-lang3.version} + + org.assertj + assertj-core + ${assertj.version} + test + + + org.inferred + freebuilder + ${freebuilder.version} + true + + + com.google.code.findbugs + jsr305 + ${javax.annotations.version} + @@ -38,5 +55,8 @@ 1.8 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/main/java/com/baeldung/memento/TextEditor.java b/patterns/design-patterns-2/src/main/java/com/baeldung/memento/TextEditor.java new file mode 100644 index 0000000000..37ac962773 --- /dev/null +++ b/patterns/design-patterns-2/src/main/java/com/baeldung/memento/TextEditor.java @@ -0,0 +1,27 @@ +package com.baeldung.memento; + +public class TextEditor { + + private TextWindow textWindow; + private TextWindowState savedTextWindow; + + public TextEditor(TextWindow textWindow) { + this.textWindow = textWindow; + } + + public void write(String text) { + textWindow.addText(text); + } + + public String print() { + return textWindow.getCurrentText(); + } + + public void hitSave() { + savedTextWindow = textWindow.save(); + } + + public void hitUndo() { + textWindow.restore(savedTextWindow); + } +} diff --git a/patterns/design-patterns-2/src/main/java/com/baeldung/memento/TextWindow.java b/patterns/design-patterns-2/src/main/java/com/baeldung/memento/TextWindow.java new file mode 100644 index 0000000000..08778561b0 --- /dev/null +++ b/patterns/design-patterns-2/src/main/java/com/baeldung/memento/TextWindow.java @@ -0,0 +1,26 @@ +package com.baeldung.memento; + +public class TextWindow { + + private StringBuilder currentText; + + public TextWindow() { + this.currentText = new StringBuilder(); + } + + public String getCurrentText() { + return currentText.toString(); + } + + public void addText(String text) { + currentText.append(text); + } + + public TextWindowState save() { + return new TextWindowState(currentText.toString()); + } + + public void restore(TextWindowState save) { + currentText = new StringBuilder(save.getText()); + } +} diff --git a/patterns/design-patterns-2/src/main/java/com/baeldung/memento/TextWindowState.java b/patterns/design-patterns-2/src/main/java/com/baeldung/memento/TextWindowState.java new file mode 100644 index 0000000000..10015a84d1 --- /dev/null +++ b/patterns/design-patterns-2/src/main/java/com/baeldung/memento/TextWindowState.java @@ -0,0 +1,14 @@ +package com.baeldung.memento; + +public class TextWindowState { + + private String text; + + public TextWindowState(String text) { + this.text = text; + } + + public String getText() { + return text; + } +} 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/design-patterns-2/src/test/java/com/baeldung/memento/TextEditorUnitTest.java b/patterns/design-patterns-2/src/test/java/com/baeldung/memento/TextEditorUnitTest.java new file mode 100644 index 0000000000..09f6df70a2 --- /dev/null +++ b/patterns/design-patterns-2/src/test/java/com/baeldung/memento/TextEditorUnitTest.java @@ -0,0 +1,20 @@ +package com.baeldung.memento; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +class TextEditorUnitTest { + + @Test + void givenTextEditor_whenAddTextSaveAddMoreAndUndo_thenSavecStateRestored() { + TextEditor textEditor = new TextEditor(new TextWindow()); + textEditor.write("The Memento Design Pattern\n"); + textEditor.write("How to implement it in Java?\n"); + textEditor.hitSave(); + textEditor.write("Buy milk and eggs before coming home\n"); + textEditor.hitUndo(); + + assertThat(textEditor.print()).isEqualTo("The Memento Design Pattern\nHow to implement it in Java?\n"); + } +} \ 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/performance-tests/README.md b/performance-tests/README.md index 5af735b708..0064157966 100644 --- a/performance-tests/README.md +++ b/performance-tests/README.md @@ -1,3 +1,10 @@ ### Relevant Articles: - [Performance of Java Mapping Frameworks](http://www.baeldung.com/java-performance-mapping-frameworks) + +### Running + + To run the performance benchmarks: + +1: `mvn clean install` +2: `java -jar target/benchmarks.jar` \ No newline at end of file diff --git a/performance-tests/pom.xml b/performance-tests/pom.xml index d7738780bf..956c0ccfa8 100644 --- a/performance-tests/pom.xml +++ b/performance-tests/pom.xml @@ -1,17 +1,20 @@ - - 4.0.0 + + com.baeldung performance-tests - performance-tests - + 1.0 + jar + parent-modules com.baeldung 1.0.0-SNAPSHOT + performance-tests + ma.glasnost.orika @@ -32,7 +35,16 @@ org.mapstruct mapstruct-jdk8 ${mapstruct-jdk8.version} + true + + + org.mapstruct + mapstruct-processor + 1.2.0.Final + provided + + org.modelmapper modelmapper @@ -46,46 +58,141 @@ org.openjdk.jmh jmh-core - ${jmh-core.version} + ${jmh.version} org.openjdk.jmh jmh-generator-annprocess - ${jmh-generator.version} + ${jmh.version} + provided - - - - - - org.apache.maven.plugins - maven-compiler-plugin - ${maven-compiler-plugin.version} - - ${java.version} - ${java.version} - - - org.mapstruct - mapstruct-processor - ${mapstruct-processor.version} - - - - - - - - + + UTF-8 + + + 1.21 1.5.2 5.5.1 1.0.2 1.2.0.Final 1.1.0 1.6.0.1 + 1.8 1.2.0.Final + 1.21 + 1.21 + 3.7.0 + + + 1.8 + + + benchmarks - \ No newline at end of file + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.1 + + ${javac.target} + ${javac.target} + ${javac.target} + + + org.mapstruct + mapstruct-processor + ${mapstruct-processor.version} + + + + + + org.apache.maven.plugins + maven-shade-plugin + 2.2 + + + package + + shade + + + ${uberjar.name} + + + org.openjdk.jmh.Main + + + + + + *:* + + META-INF/*.SF + META-INF/*.DSA + META-INF/*.RSA + + + + + + + + + + + + maven-clean-plugin + 2.5 + + + maven-deploy-plugin + 2.8.1 + + + maven-install-plugin + 2.5.1 + + + maven-jar-plugin + 2.4 + + + maven-javadoc-plugin + 2.9.1 + + + maven-resources-plugin + 2.6 + + + maven-site-plugin + 3.3 + + + maven-source-plugin + 2.2.1 + + + maven-surefire-plugin + 2.17 + + + + + + diff --git a/performance-tests/src/test/java/com/baeldung/performancetests/benchmark/MappingFrameworksPerformance.java b/performance-tests/src/main/java/com/baeldung/performancetests/MappingFrameworksPerformance.java similarity index 100% rename from performance-tests/src/test/java/com/baeldung/performancetests/benchmark/MappingFrameworksPerformance.java rename to performance-tests/src/main/java/com/baeldung/performancetests/MappingFrameworksPerformance.java diff --git a/persistence-modules/hibernate-mapping/pom.xml b/persistence-modules/hibernate-mapping/pom.xml index e90d7463bd..98c946a6e9 100644 --- a/persistence-modules/hibernate-mapping/pom.xml +++ b/persistence-modules/hibernate-mapping/pom.xml @@ -5,6 +5,7 @@ hibernate-mapping 1.0.0-SNAPSHOT 4.0.0 + hibernate-mapping com.baeldung 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 - 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-core/src/test/java/com/baeldung/resource/SpringResourceIntegrationTest.java b/spring-core/src/test/java/com/baeldung/classpathfileaccess/SpringResourceIntegrationTest.java similarity index 99% rename from spring-core/src/test/java/com/baeldung/resource/SpringResourceIntegrationTest.java rename to spring-core/src/test/java/com/baeldung/classpathfileaccess/SpringResourceIntegrationTest.java index c7a2984045..b57a64a8c6 100644 --- a/spring-core/src/test/java/com/baeldung/resource/SpringResourceIntegrationTest.java +++ b/spring-core/src/test/java/com/baeldung/classpathfileaccess/SpringResourceIntegrationTest.java @@ -1,4 +1,4 @@ -package com.baeldung.resource; +package com.baeldung.classpathfileaccess; import static org.junit.Assert.assertEquals; 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-data-rest/README.md b/spring-data-rest/README.md index abbacb69cc..4b89a24bbc 100644 --- a/spring-data-rest/README.md +++ b/spring-data-rest/README.md @@ -17,7 +17,6 @@ To view the running application, visit [http://localhost:8080](http://localhost: - [Guide to Spring Data REST Validators](http://www.baeldung.com/spring-data-rest-validators) - [Working with Relationships in Spring Data REST](http://www.baeldung.com/spring-data-rest-relationships) - [AngularJS CRUD Application with Spring Data REST](http://www.baeldung.com/angularjs-crud-with-spring-data-rest) -- [List of In-Memory Databases](http://www.baeldung.com/java-in-memory-databases) - [Projections and Excerpts in Spring Data REST](http://www.baeldung.com/spring-data-rest-projections-excerpts) - [Spring Data REST Events with @RepositoryEventHandler](http://www.baeldung.com/spring-data-rest-events) - [Customizing HTTP Endpoints in Spring Data REST](https://www.baeldung.com/spring-data-rest-customize-http-endpoints) 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..f3ad380778 --- /dev/null +++ b/spring-di/pom.xml @@ -0,0 +1,102 @@ + + + 4.0.0 + spring-di + 1.0-SNAPSHOT + war + spring-di + + + 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-all/src/main/java/org/baeldung/sample/App.java b/spring-di/src/main/java/org/baeldung/sample/App.java similarity index 100% rename from spring-all/src/main/java/org/baeldung/sample/App.java rename to spring-di/src/main/java/org/baeldung/sample/App.java diff --git a/spring-all/src/main/java/org/baeldung/sample/AppConfig.java b/spring-di/src/main/java/org/baeldung/sample/AppConfig.java similarity index 100% rename from spring-all/src/main/java/org/baeldung/sample/AppConfig.java rename to spring-di/src/main/java/org/baeldung/sample/AppConfig.java 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-all/src/main/java/org/baeldung/sample/BarFormatter.java b/spring-di/src/main/java/org/baeldung/sample/BarFormatter.java similarity index 100% rename from spring-all/src/main/java/org/baeldung/sample/BarFormatter.java rename to spring-di/src/main/java/org/baeldung/sample/BarFormatter.java 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-all/src/main/java/org/baeldung/sample/FooDAO.java b/spring-di/src/main/java/org/baeldung/sample/FooDAO.java similarity index 100% rename from spring-all/src/main/java/org/baeldung/sample/FooDAO.java rename to spring-di/src/main/java/org/baeldung/sample/FooDAO.java diff --git a/spring-all/src/main/java/org/baeldung/sample/FooFormatter.java b/spring-di/src/main/java/org/baeldung/sample/FooFormatter.java similarity index 100% rename from spring-all/src/main/java/org/baeldung/sample/FooFormatter.java rename to spring-di/src/main/java/org/baeldung/sample/FooFormatter.java diff --git a/spring-all/src/main/java/org/baeldung/sample/FooService.java b/spring-di/src/main/java/org/baeldung/sample/FooService.java similarity index 100% rename from spring-all/src/main/java/org/baeldung/sample/FooService.java rename to spring-di/src/main/java/org/baeldung/sample/FooService.java diff --git a/spring-all/src/main/java/org/baeldung/sample/Formatter.java b/spring-di/src/main/java/org/baeldung/sample/Formatter.java similarity index 100% rename from spring-all/src/main/java/org/baeldung/sample/Formatter.java rename to spring-di/src/main/java/org/baeldung/sample/Formatter.java diff --git a/spring-all/src/main/java/org/baeldung/sample/FormatterType.java b/spring-di/src/main/java/org/baeldung/sample/FormatterType.java similarity index 100% rename from spring-all/src/main/java/org/baeldung/sample/FormatterType.java rename to spring-di/src/main/java/org/baeldung/sample/FormatterType.java index d4d82dd022..a00a9750bf 100644 --- a/spring-all/src/main/java/org/baeldung/sample/FormatterType.java +++ b/spring-di/src/main/java/org/baeldung/sample/FormatterType.java @@ -1,12 +1,12 @@ 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; -import org.springframework.beans.factory.annotation.Qualifier; - @Qualifier @Target({ ElementType.FIELD, ElementType.METHOD, ElementType.TYPE, ElementType.PARAMETER }) @Retention(RetentionPolicy.RUNTIME) diff --git a/spring-all/src/test/java/org/baeldung/sample/FooServiceIntegrationTest.java b/spring-di/src/test/java/org/baeldung/sample/FooServiceIntegrationTest.java similarity index 100% rename from spring-all/src/test/java/org/baeldung/sample/FooServiceIntegrationTest.java rename to spring-di/src/test/java/org/baeldung/sample/FooServiceIntegrationTest.java 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-freemarker/src/main/java/com/baeldung/freemarker/controller/SpringController.java b/spring-freemarker/src/main/java/com/baeldung/freemarker/controller/SpringController.java index 18b42f06ea..6f6b5994f3 100644 --- a/spring-freemarker/src/main/java/com/baeldung/freemarker/controller/SpringController.java +++ b/spring-freemarker/src/main/java/com/baeldung/freemarker/controller/SpringController.java @@ -1,9 +1,10 @@ package com.baeldung.freemarker.controller; -import java.util.ArrayList; -import java.util.List; -import java.util.Locale; +import java.util.*; +import com.baeldung.freemarker.method.LastCharMethod; +import freemarker.template.DefaultObjectWrapperBuilder; +import freemarker.template.Version; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.ui.ModelMap; @@ -43,4 +44,12 @@ public class SpringController { return "redirect:/cars"; } -} + @RequestMapping(value = "/commons", method = RequestMethod.GET) + public String showCommonsPage(Model model) { + model.addAttribute("statuses", Arrays.asList("200 OK", "404 Not Found", "500 Internal Server Error")); + model.addAttribute("lastChar", new LastCharMethod()); + model.addAttribute("random", new Random()); + model.addAttribute("statics", new DefaultObjectWrapperBuilder(new Version("2.3.28")).build().getStaticModels()); + return "commons"; + } +} \ No newline at end of file diff --git a/spring-freemarker/src/main/java/com/baeldung/freemarker/method/LastCharMethod.java b/spring-freemarker/src/main/java/com/baeldung/freemarker/method/LastCharMethod.java new file mode 100644 index 0000000000..956a512f56 --- /dev/null +++ b/spring-freemarker/src/main/java/com/baeldung/freemarker/method/LastCharMethod.java @@ -0,0 +1,16 @@ +package com.baeldung.freemarker.method; + +import freemarker.template.TemplateMethodModelEx; +import freemarker.template.TemplateModelException; +import org.springframework.util.StringUtils; + +import java.util.List; + +public class LastCharMethod implements TemplateMethodModelEx { + public Object exec(List arguments) throws TemplateModelException { + if (arguments.size() != 1 || StringUtils.isEmpty(arguments.get(0))) + throw new TemplateModelException("Wrong arguments!"); + String argument = arguments.get(0).toString(); + return argument.charAt(argument.length() - 1); + } +} diff --git a/spring-freemarker/src/main/webapp/WEB-INF/views/ftl/commons.ftl b/spring-freemarker/src/main/webapp/WEB-INF/views/ftl/commons.ftl new file mode 100644 index 0000000000..eea1e6f683 --- /dev/null +++ b/spring-freemarker/src/main/webapp/WEB-INF/views/ftl/commons.ftl @@ -0,0 +1,28 @@ +

    Testing is a property exists: ${student???c}

    +<#if status??> +

    Property value: ${status.reason}

    +<#else> +

    Missing property

    + + +

    Iterating a sequence:

    +<#list statuses> +
      + <#items as status> +
    • ${status}
    • + +
    + <#else> +

    No statuses available

    + + +

    Using static methods

    +<#assign MathUtils=statics['java.lang.Math']> +

    PI value: ${MathUtils.PI}

    +

    2*10 is: ${MathUtils.pow(2, 10)}

    + +

    Using bean method

    +

    Random value: ${random.nextInt()}

    + +

    Use custom method

    +

    Last char example: ${lastChar('mystring')}

    \ No newline at end of file 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-mvc-simple-2/src/main/java/com/baeldung/validation/listvalidation/SpringListValidationApplication.java b/spring-mvc-simple-2/src/main/java/com/baeldung/validation/listvalidation/SpringListValidationApplication.java new file mode 100644 index 0000000000..f16d5f877f --- /dev/null +++ b/spring-mvc-simple-2/src/main/java/com/baeldung/validation/listvalidation/SpringListValidationApplication.java @@ -0,0 +1,17 @@ +package com.baeldung.validation.listvalidation; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +@ComponentScan(basePackages = "com.baeldung.validation.listvalidation") +@Configuration +@SpringBootApplication +public class SpringListValidationApplication { + + public static void main(String[] args) { + SpringApplication.run(SpringListValidationApplication.class, args); + } + +} diff --git a/spring-mvc-simple-2/src/main/java/com/baeldung/validation/listvalidation/constraint/MaxSizeConstraint.java b/spring-mvc-simple-2/src/main/java/com/baeldung/validation/listvalidation/constraint/MaxSizeConstraint.java new file mode 100644 index 0000000000..b5adab5d86 --- /dev/null +++ b/spring-mvc-simple-2/src/main/java/com/baeldung/validation/listvalidation/constraint/MaxSizeConstraint.java @@ -0,0 +1,18 @@ +package com.baeldung.validation.listvalidation.constraint; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +import javax.validation.Constraint; +import javax.validation.Payload; + +@Constraint(validatedBy = MaxSizeConstraintValidator.class) +@Retention(RetentionPolicy.RUNTIME) +public @interface MaxSizeConstraint { + + String message() default "The input list cannot contain more than 4 movies."; + + Class[] groups() default {}; + + Class[] payload() default {}; +} diff --git a/spring-mvc-simple-2/src/main/java/com/baeldung/validation/listvalidation/constraint/MaxSizeConstraintValidator.java b/spring-mvc-simple-2/src/main/java/com/baeldung/validation/listvalidation/constraint/MaxSizeConstraintValidator.java new file mode 100644 index 0000000000..0154fb636a --- /dev/null +++ b/spring-mvc-simple-2/src/main/java/com/baeldung/validation/listvalidation/constraint/MaxSizeConstraintValidator.java @@ -0,0 +1,21 @@ +package com.baeldung.validation.listvalidation.constraint; + +import java.util.List; + +import javax.validation.ConstraintValidator; +import javax.validation.ConstraintValidatorContext; + +import com.baeldung.validation.listvalidation.model.Movie; + +public class MaxSizeConstraintValidator implements ConstraintValidator> { + + @Override + public boolean isValid(List values, ConstraintValidatorContext context) { + boolean isValid = true; + if (values.size() > 4) { + isValid = false; + } + return isValid; + } + +} diff --git a/spring-mvc-simple-2/src/main/java/com/baeldung/validation/listvalidation/controller/MovieController.java b/spring-mvc-simple-2/src/main/java/com/baeldung/validation/listvalidation/controller/MovieController.java new file mode 100644 index 0000000000..45639cf303 --- /dev/null +++ b/spring-mvc-simple-2/src/main/java/com/baeldung/validation/listvalidation/controller/MovieController.java @@ -0,0 +1,31 @@ +package com.baeldung.validation.listvalidation.controller; + +import java.util.List; + +import javax.validation.Valid; +import javax.validation.constraints.NotEmpty; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.baeldung.validation.listvalidation.constraint.MaxSizeConstraint; +import com.baeldung.validation.listvalidation.model.Movie; +import com.baeldung.validation.listvalidation.service.MovieService; + +@Validated +@RestController +@RequestMapping("/movies") +public class MovieController { + + @Autowired + private MovieService movieService; + + @PostMapping + public void addAll(@RequestBody @NotEmpty(message = "Input movie list cannot be empty.") @MaxSizeConstraint List<@Valid Movie> movies) { + movieService.addAll(movies); + } +} diff --git a/spring-mvc-simple-2/src/main/java/com/baeldung/validation/listvalidation/exception/ConstraintViolationExceptionHandler.java b/spring-mvc-simple-2/src/main/java/com/baeldung/validation/listvalidation/exception/ConstraintViolationExceptionHandler.java new file mode 100644 index 0000000000..742be27f61 --- /dev/null +++ b/spring-mvc-simple-2/src/main/java/com/baeldung/validation/listvalidation/exception/ConstraintViolationExceptionHandler.java @@ -0,0 +1,36 @@ +package com.baeldung.validation.listvalidation.exception; + +import java.util.Set; + +import javax.validation.ConstraintViolation; +import javax.validation.ConstraintViolationException; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +@RestControllerAdvice +public class ConstraintViolationExceptionHandler { + + private final Logger logger = LoggerFactory.getLogger(ConstraintViolationExceptionHandler.class); + + @ExceptionHandler(ConstraintViolationException.class) + public ResponseEntity handle(ConstraintViolationException constraintViolationException) { + Set> violations = constraintViolationException.getConstraintViolations(); + String errorMessage = ""; + if (!violations.isEmpty()) { + StringBuilder builder = new StringBuilder(); + violations.forEach(violation -> builder.append("\n" + violation.getMessage())); + errorMessage = builder.toString(); + } else { + errorMessage = "ConstraintViolationException occured."; + } + + logger.error(errorMessage); + return new ResponseEntity<>(errorMessage, HttpStatus.BAD_REQUEST); + } + +} diff --git a/spring-mvc-simple-2/src/main/java/com/baeldung/validation/listvalidation/model/Movie.java b/spring-mvc-simple-2/src/main/java/com/baeldung/validation/listvalidation/model/Movie.java new file mode 100644 index 0000000000..f5a49877bf --- /dev/null +++ b/spring-mvc-simple-2/src/main/java/com/baeldung/validation/listvalidation/model/Movie.java @@ -0,0 +1,40 @@ +package com.baeldung.validation.listvalidation.model; + +import java.util.UUID; + +import javax.validation.constraints.NotEmpty; + +public class Movie { + + private String id; + + @NotEmpty(message = "Movie name cannot be empty.") + private String name; + + public Movie(String name) { + this.id = UUID.randomUUID() + .toString(); + this.name = name; + } + + public Movie(){ + + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + +} diff --git a/spring-mvc-simple-2/src/main/java/com/baeldung/validation/listvalidation/service/MovieService.java b/spring-mvc-simple-2/src/main/java/com/baeldung/validation/listvalidation/service/MovieService.java new file mode 100644 index 0000000000..0339df595d --- /dev/null +++ b/spring-mvc-simple-2/src/main/java/com/baeldung/validation/listvalidation/service/MovieService.java @@ -0,0 +1,55 @@ +package com.baeldung.validation.listvalidation.service; + +import java.util.ArrayList; +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; + +import com.baeldung.validation.listvalidation.model.Movie; + +@Service +public class MovieService { + + private final Logger logger = LoggerFactory.getLogger(MovieService.class); + + private static List moviesData; + + static { + moviesData = new ArrayList<>(); + + Movie m1 = new Movie("MovieABC"); + moviesData.add(m1); + + Movie m2 = new Movie("MovieDEF"); + moviesData.add(m2); + + } + + public Movie get(String name) { + Movie movie = null; + for (Movie m : moviesData) { + if (name.equalsIgnoreCase(m.getName())) { + movie = m; + logger.info("Found movie with name {} : {} ", name, movie); + } + } + + return movie; + } + + public void add(Movie movie) { + if (get(movie.getName()) == null) { + moviesData.add(movie); + logger.info("Added new movie - {}", movie.getName()); + } + } + + public void addAll(List movies) { + for (Movie movie : movies) { + add(movie); + } + } + +} diff --git a/spring-mvc-simple-2/src/test/java/com/baeldung/validation/listvalidation/MovieControllerIntegrationTest.java b/spring-mvc-simple-2/src/test/java/com/baeldung/validation/listvalidation/MovieControllerIntegrationTest.java new file mode 100644 index 0000000000..cddc6c6bd9 --- /dev/null +++ b/spring-mvc-simple-2/src/test/java/com/baeldung/validation/listvalidation/MovieControllerIntegrationTest.java @@ -0,0 +1,83 @@ +package com.baeldung.validation.listvalidation; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +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.http.MediaType; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; +import org.springframework.test.web.servlet.result.MockMvcResultMatchers; + +import com.baeldung.validation.listvalidation.model.Movie; +import com.fasterxml.jackson.databind.ObjectMapper; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = SpringListValidationApplication.class) +@AutoConfigureMockMvc +public class MovieControllerIntegrationTest { + + @Autowired + private MockMvc mvc; + + ObjectMapper objectMapper = new ObjectMapper(); + + @Test + public void givenValidMovieList_whenAddingMovieList_thenIsOK() throws Exception { + List movies = new ArrayList<>(); + Movie movie = new Movie("Movie3"); + movies.add(movie); + mvc.perform(MockMvcRequestBuilders.post("/movies") + .contentType(MediaType.APPLICATION_JSON_UTF8) + .content(objectMapper.writeValueAsString(movies))) + .andExpect(MockMvcResultMatchers.status() + .isOk()); + } + + @Test + public void givenEmptyMovieList_whenAddingMovieList_thenThrowBadRequest() throws Exception { + List movies = new ArrayList<>(); + mvc.perform(MockMvcRequestBuilders.post("/movies") + .contentType(MediaType.APPLICATION_JSON_UTF8) + .content(objectMapper.writeValueAsString(movies))) + .andExpect(MockMvcResultMatchers.status() + .isBadRequest()); + } + + @Test + public void givenEmptyMovieName_whenAddingMovieList_thenThrowBadRequest() throws Exception { + Movie movie = new Movie(""); + mvc.perform(MockMvcRequestBuilders.post("/movies") + .contentType(MediaType.APPLICATION_JSON_UTF8) + .content(objectMapper.writeValueAsString(Arrays.asList(movie)))) + .andExpect(MockMvcResultMatchers.status() + .isBadRequest()); + } + + @Test + public void given5MoviesInputList_whenAddingMovieList_thenThrowBadRequest() throws Exception { + Movie movie1 = new Movie("Movie1"); + Movie movie2 = new Movie("Movie2"); + Movie movie3 = new Movie("Movie3"); + Movie movie4 = new Movie("Movie4"); + Movie movie5 = new Movie("Movie5"); + List movies = new ArrayList<>(); + movies.add(movie1); + movies.add(movie2); + movies.add(movie3); + movies.add(movie4); + movies.add(movie5); + mvc.perform(MockMvcRequestBuilders.post("/movies") + .contentType(MediaType.APPLICATION_JSON_UTF8) + .content(objectMapper.writeValueAsString(movies))) + .andExpect(MockMvcResultMatchers.status() + .isBadRequest()); + } + +} diff --git a/spring-mvc-simple/src/main/java/com/baeldung/spring/controller/RequestParamController.java b/spring-mvc-simple/src/main/java/com/baeldung/spring/requestparam/RequestParamController.java similarity index 96% rename from spring-mvc-simple/src/main/java/com/baeldung/spring/controller/RequestParamController.java rename to spring-mvc-simple/src/main/java/com/baeldung/spring/requestparam/RequestParamController.java index a9846f1ba9..bcb1fe5a82 100644 --- a/spring-mvc-simple/src/main/java/com/baeldung/spring/controller/RequestParamController.java +++ b/spring-mvc-simple/src/main/java/com/baeldung/spring/requestparam/RequestParamController.java @@ -1,4 +1,4 @@ -package com.baeldung.spring.controller; +package com.baeldung.spring.requestparam; import java.util.List; import java.util.Map; @@ -47,7 +47,7 @@ public class RequestParamController { @GetMapping("/api/foos4") @ResponseBody public String getFoos4(@RequestParam List id){ - return "ID are " + id; + return "IDs are " + id; } @GetMapping("/foos/{id}") diff --git a/spring-rest-compress/README.md b/spring-rest-compress/README.md new file mode 100644 index 0000000000..238c28e4b5 --- /dev/null +++ b/spring-rest-compress/README.md @@ -0,0 +1,5 @@ +========================================================================= +## How to compress requests using the Spring RestTemplate Example Project + +### Relevant Articles: +- [How to compress requests using the Spring RestTemplate]() diff --git a/spring-rest-compress/pom.xml b/spring-rest-compress/pom.xml new file mode 100644 index 0000000000..d5afc5708d --- /dev/null +++ b/spring-rest-compress/pom.xml @@ -0,0 +1,66 @@ + + + 4.0.0 + + parent-boot-2 + com.baeldung + 0.0.1-SNAPSHOT + ../parent-boot-2 + + com.baeldung + spring-rest-compress + 0.0.1-SNAPSHOT + spring-rest-compress + + + 1.8 + 2.6 + + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-tomcat + + + + + + org.springframework.boot + spring-boot-starter-jetty + + + + org.apache.httpcomponents + httpclient + + + + commons-io + commons-io + ${commons-io.version} + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/spring-rest-compress/src/main/java/org/baeldung/spring/rest/compress/CompressingClientHttpRequestInterceptor.java b/spring-rest-compress/src/main/java/org/baeldung/spring/rest/compress/CompressingClientHttpRequestInterceptor.java new file mode 100644 index 0000000000..7d5326246d --- /dev/null +++ b/spring-rest-compress/src/main/java/org/baeldung/spring/rest/compress/CompressingClientHttpRequestInterceptor.java @@ -0,0 +1,38 @@ +package org.baeldung.spring.rest.compress; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpRequest; +import org.springframework.http.client.ClientHttpRequestExecution; +import org.springframework.http.client.ClientHttpRequestInterceptor; +import org.springframework.http.client.ClientHttpResponse; + +import java.io.IOException; + +public class CompressingClientHttpRequestInterceptor implements ClientHttpRequestInterceptor { + + private static final Logger LOG = LoggerFactory.getLogger(CompressingClientHttpRequestInterceptor.class); + + private static final String GZIP_ENCODING = "gzip"; + + /** + * Compress a request body using Gzip and add Http headers. + * + * @param req + * @param body + * @param exec + * @return + * @throws IOException + */ + @Override + public ClientHttpResponse intercept(HttpRequest req, byte[] body, ClientHttpRequestExecution exec) + throws IOException { + LOG.info("Compressing request..."); + HttpHeaders httpHeaders = req.getHeaders(); + httpHeaders.add(HttpHeaders.CONTENT_ENCODING, GZIP_ENCODING); + httpHeaders.add(HttpHeaders.ACCEPT_ENCODING, GZIP_ENCODING); + return exec.execute(req, GzipUtils.compress(body)); + } + +} diff --git a/spring-rest-compress/src/main/java/org/baeldung/spring/rest/compress/GzipUtils.java b/spring-rest-compress/src/main/java/org/baeldung/spring/rest/compress/GzipUtils.java new file mode 100644 index 0000000000..f3cb8bd631 --- /dev/null +++ b/spring-rest-compress/src/main/java/org/baeldung/spring/rest/compress/GzipUtils.java @@ -0,0 +1,56 @@ +package org.baeldung.spring.rest.compress; + +import org.apache.commons.codec.Charsets; +import org.apache.commons.io.IOUtils; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.zip.GZIPInputStream; +import java.util.zip.GZIPOutputStream; + +public class GzipUtils { + + /** + * Gzip a string. + * + * @param text + * @return + * @throws Exception + */ + public static byte[] compress(String text) throws Exception { + return GzipUtils.compress(text.getBytes(Charsets.UTF_8)); + } + + /** + * Gzip a byte array. + * + * @param body + * @return + * @throws IOException + */ + public static byte[] compress(byte[] body) throws IOException { + ByteArrayOutputStream output = new ByteArrayOutputStream(); + try { + try (GZIPOutputStream gzipOutputStream = new GZIPOutputStream(output)) { + gzipOutputStream.write(body); + } + } finally { + output.close(); + } + return output.toByteArray(); + } + + /** + * Decompress a Gzipped byte array to a String. + * + * @param body + * @return + * @throws IOException + */ + public static String decompress(byte[] body) throws IOException { + try (GZIPInputStream gzipInputStream = new GZIPInputStream(new ByteArrayInputStream(body))) { + return IOUtils.toString(gzipInputStream, Charsets.UTF_8); + } + } +} diff --git a/spring-rest-compress/src/main/java/org/baeldung/spring/rest/compress/JettyWebServerConfiguration.java b/spring-rest-compress/src/main/java/org/baeldung/spring/rest/compress/JettyWebServerConfiguration.java new file mode 100644 index 0000000000..784814b04d --- /dev/null +++ b/spring-rest-compress/src/main/java/org/baeldung/spring/rest/compress/JettyWebServerConfiguration.java @@ -0,0 +1,38 @@ +package org.baeldung.spring.rest.compress; + +import org.eclipse.jetty.server.handler.HandlerCollection; +import org.eclipse.jetty.server.handler.gzip.GzipHandler; +import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * Configure Jetty web server so it handles compressed requests. + */ +@Configuration +public class JettyWebServerConfiguration { + + private static final int MIN_BYTES = 1; + + /** + * Customise the Jetty web server to automatically decompress requests. + */ + @Bean + public JettyServletWebServerFactory jettyServletWebServerFactory() { + + JettyServletWebServerFactory factory = new JettyServletWebServerFactory(); + factory.addServerCustomizers(server -> { + + GzipHandler gzipHandler = new GzipHandler(); + // Enable request decompression + gzipHandler.setInflateBufferSize(MIN_BYTES); + gzipHandler.setHandler(server.getHandler()); + + HandlerCollection handlerCollection = new HandlerCollection(gzipHandler); + server.setHandler(handlerCollection); + }); + + return factory; + } + +} diff --git a/spring-rest-compress/src/main/java/org/baeldung/spring/rest/compress/Message.java b/spring-rest-compress/src/main/java/org/baeldung/spring/rest/compress/Message.java new file mode 100644 index 0000000000..d3450b227c --- /dev/null +++ b/spring-rest-compress/src/main/java/org/baeldung/spring/rest/compress/Message.java @@ -0,0 +1,29 @@ +package org.baeldung.spring.rest.compress; + +public class Message { + + private String text; + + public Message() { + } + + public Message(String text) { + this.text = text; + } + + public String getText() { + return text; + } + + public void setText(String text) { + this.text = text; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder("Message {"); + sb.append("text='").append(text).append('\''); + sb.append('}'); + return sb.toString(); + } +} diff --git a/spring-rest-compress/src/main/java/org/baeldung/spring/rest/compress/MessageController.java b/spring-rest-compress/src/main/java/org/baeldung/spring/rest/compress/MessageController.java new file mode 100644 index 0000000000..657c3cfec8 --- /dev/null +++ b/spring-rest-compress/src/main/java/org/baeldung/spring/rest/compress/MessageController.java @@ -0,0 +1,38 @@ +package org.baeldung.spring.rest.compress; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Map; + +@RestController +public class MessageController { + + protected static final String PROCESSED = "Processed "; + + protected static final String REQUEST_MAPPING = "process"; + + private static final Logger LOG = LoggerFactory.getLogger(MessageController.class); + + /** + * A simple endpoint that responds with "Processed " + supplied Message content. + * + * @param headers + * @param message + * @return + */ + @PostMapping(value = REQUEST_MAPPING) + public ResponseEntity processMessage(@RequestHeader Map headers, + @RequestBody Message message) { + + // Print headers + headers.forEach((k, v) -> LOG.info(k + "=" + v)); + + return ResponseEntity.ok(PROCESSED + message.getText()); + } +} diff --git a/spring-rest-compress/src/main/java/org/baeldung/spring/rest/compress/RestTemplateConfiguration.java b/spring-rest-compress/src/main/java/org/baeldung/spring/rest/compress/RestTemplateConfiguration.java new file mode 100644 index 0000000000..e1d0f985d9 --- /dev/null +++ b/spring-rest-compress/src/main/java/org/baeldung/spring/rest/compress/RestTemplateConfiguration.java @@ -0,0 +1,21 @@ +package org.baeldung.spring.rest.compress; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.client.RestTemplate; + +@Configuration +public class RestTemplateConfiguration { + + /** + * A RestTemplate that compresses requests. + * + * @return RestTemplate + */ + @Bean + public RestTemplate getRestTemplate() { + RestTemplate restTemplate = new RestTemplate(); + restTemplate.getInterceptors().add(new CompressingClientHttpRequestInterceptor()); + return restTemplate; + } +} diff --git a/spring-rest-compress/src/main/java/org/baeldung/spring/rest/compress/SpringCompressRequestApplication.java b/spring-rest-compress/src/main/java/org/baeldung/spring/rest/compress/SpringCompressRequestApplication.java new file mode 100644 index 0000000000..3082e3c277 --- /dev/null +++ b/spring-rest-compress/src/main/java/org/baeldung/spring/rest/compress/SpringCompressRequestApplication.java @@ -0,0 +1,15 @@ +package org.baeldung.spring.rest.compress; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +@EnableAutoConfiguration +public class SpringCompressRequestApplication { + + public static void main(String[] args) { + SpringApplication.run(SpringCompressRequestApplication.class, args); + } + +} diff --git a/spring-rest-compress/src/test/java/org/baeldung/spring/rest/compress/GzipUtilsUnitTest.java b/spring-rest-compress/src/test/java/org/baeldung/spring/rest/compress/GzipUtilsUnitTest.java new file mode 100644 index 0000000000..d238c9ec7c --- /dev/null +++ b/spring-rest-compress/src/test/java/org/baeldung/spring/rest/compress/GzipUtilsUnitTest.java @@ -0,0 +1,19 @@ +package org.baeldung.spring.rest.compress; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +public class GzipUtilsUnitTest { + + @Test + public void givenCompressedText_whenDecompressed_thenSuccessful() throws Exception { + final String expectedText = "Hello Baeldung!"; + byte[] compressedText = GzipUtils.compress(expectedText); + String decompressedText = GzipUtils.decompress(compressedText); + assertNotNull(compressedText); + assertEquals(expectedText, decompressedText); + } + +} \ No newline at end of file diff --git a/spring-rest-compress/src/test/java/org/baeldung/spring/rest/compress/MessageControllerUnitTest.java b/spring-rest-compress/src/test/java/org/baeldung/spring/rest/compress/MessageControllerUnitTest.java new file mode 100644 index 0000000000..9658204917 --- /dev/null +++ b/spring-rest-compress/src/test/java/org/baeldung/spring/rest/compress/MessageControllerUnitTest.java @@ -0,0 +1,56 @@ +package org.baeldung.spring.rest.compress; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.web.client.RestTemplate; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +public class MessageControllerUnitTest { + + private static final Logger LOG = LoggerFactory.getLogger(MessageControllerUnitTest.class); + + @Autowired + private RestTemplate restTemplate; + + @LocalServerPort + private int randomServerPort; + + /** + * As a further test you can intercept the request body, using a tool like + * Wireshark, to see the request body is actually gzipped. + * + * @throws Exception + */ + @Test + public void givenRestTemplate_whenPostCompressedRequest_thenRespondsSuccessfully() throws Exception { + + final String text = "Hello Baeldung!"; + Message message = new Message(text); + + HttpEntity request = new HttpEntity<>(message); + String uri = String.format("http://localhost:%s/%s", randomServerPort, MessageController.REQUEST_MAPPING); + + ResponseEntity responseEntity = restTemplate.postForEntity(uri, request, String.class); + + String response = responseEntity.getBody(); + LOG.info("Got response [{}]", response); + + assertEquals(HttpStatus.OK, responseEntity.getStatusCode()); + assertNotNull(response); + assertEquals(MessageController.PROCESSED + text, response); + } + +} diff --git a/spring-rest-simple/src/main/java/com/baeldung/config/MvcConfig.java b/spring-rest-simple/src/main/java/com/baeldung/config/MvcConfig.java index d169f7e9d4..48b627a344 100644 --- a/spring-rest-simple/src/main/java/com/baeldung/config/MvcConfig.java +++ b/spring-rest-simple/src/main/java/com/baeldung/config/MvcConfig.java @@ -26,7 +26,7 @@ import java.util.List; */ @Configuration @EnableWebMvc -@ComponentScan({ "com.baeldung.web" }) +@ComponentScan({ "com.baeldung.web", "com.baeldung.requestmapping" }) public class MvcConfig implements WebMvcConfigurer { public MvcConfig() { @@ -66,7 +66,6 @@ public class MvcConfig implements WebMvcConfigurer { public void configureContentNegotiation(ContentNegotiationConfigurer configurer) { configurer.defaultContentType(MediaType.APPLICATION_JSON); } - @Override public void addCorsMappings(CorsRegistry registry) { diff --git a/spring-rest-simple/src/main/java/com/baeldung/web/controller/BarMappingExamplesController.java b/spring-rest-simple/src/main/java/com/baeldung/requestmapping/BarMappingExamplesController.java similarity index 97% rename from spring-rest-simple/src/main/java/com/baeldung/web/controller/BarMappingExamplesController.java rename to spring-rest-simple/src/main/java/com/baeldung/requestmapping/BarMappingExamplesController.java index 3611a4e6cc..e238c545cf 100644 --- a/spring-rest-simple/src/main/java/com/baeldung/web/controller/BarMappingExamplesController.java +++ b/spring-rest-simple/src/main/java/com/baeldung/requestmapping/BarMappingExamplesController.java @@ -1,4 +1,4 @@ -package com.baeldung.web.controller; +package com.baeldung.requestmapping; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PathVariable; diff --git a/spring-rest-simple/src/main/java/com/baeldung/web/controller/BazzNewMappingsExampleController.java b/spring-rest-simple/src/main/java/com/baeldung/requestmapping/BazzNewMappingsExampleController.java similarity index 98% rename from spring-rest-simple/src/main/java/com/baeldung/web/controller/BazzNewMappingsExampleController.java rename to spring-rest-simple/src/main/java/com/baeldung/requestmapping/BazzNewMappingsExampleController.java index 6c7da0296f..0c64006fd4 100644 --- a/spring-rest-simple/src/main/java/com/baeldung/web/controller/BazzNewMappingsExampleController.java +++ b/spring-rest-simple/src/main/java/com/baeldung/requestmapping/BazzNewMappingsExampleController.java @@ -1,4 +1,4 @@ -package com.baeldung.web.controller; +package com.baeldung.requestmapping; import java.util.Arrays; import java.util.List; diff --git a/spring-rest-simple/src/main/java/com/baeldung/web/controller/FooMappingExamplesController.java b/spring-rest-simple/src/main/java/com/baeldung/requestmapping/FooMappingExamplesController.java similarity index 98% rename from spring-rest-simple/src/main/java/com/baeldung/web/controller/FooMappingExamplesController.java rename to spring-rest-simple/src/main/java/com/baeldung/requestmapping/FooMappingExamplesController.java index ec75e4c859..2c11e36141 100644 --- a/spring-rest-simple/src/main/java/com/baeldung/web/controller/FooMappingExamplesController.java +++ b/spring-rest-simple/src/main/java/com/baeldung/requestmapping/FooMappingExamplesController.java @@ -1,4 +1,4 @@ -package com.baeldung.web.controller; +package com.baeldung.requestmapping; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PathVariable; diff --git a/spring-rest-simple/src/test/java/com/baeldung/web/test/BazzNewMappingsExampleIntegrationTest.java b/spring-rest-simple/src/test/java/com/baeldung/requestmapping/BazzNewMappingsExampleIntegrationTest.java similarity index 98% rename from spring-rest-simple/src/test/java/com/baeldung/web/test/BazzNewMappingsExampleIntegrationTest.java rename to spring-rest-simple/src/test/java/com/baeldung/requestmapping/BazzNewMappingsExampleIntegrationTest.java index 4f0395e914..a6039b54c7 100644 --- a/spring-rest-simple/src/test/java/com/baeldung/web/test/BazzNewMappingsExampleIntegrationTest.java +++ b/spring-rest-simple/src/test/java/com/baeldung/requestmapping/BazzNewMappingsExampleIntegrationTest.java @@ -1,5 +1,5 @@ -package com.baeldung.web.test; +package com.baeldung.requestmapping; import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.is; diff --git a/spring-resttemplate/src/test/java/org/baeldung/client/RestTemplateBasicLiveTest.java b/spring-resttemplate/src/test/java/org/baeldung/resttemplate/RestTemplateBasicLiveTest.java similarity index 99% rename from spring-resttemplate/src/test/java/org/baeldung/client/RestTemplateBasicLiveTest.java rename to spring-resttemplate/src/test/java/org/baeldung/resttemplate/RestTemplateBasicLiveTest.java index ff3034a50d..54e416d008 100644 --- a/spring-resttemplate/src/test/java/org/baeldung/client/RestTemplateBasicLiveTest.java +++ b/spring-resttemplate/src/test/java/org/baeldung/resttemplate/RestTemplateBasicLiveTest.java @@ -1,4 +1,4 @@ -package org.baeldung.client; +package org.baeldung.resttemplate; import static org.apache.commons.codec.binary.Base64.encodeBase64; import static org.baeldung.client.Consts.APPLICATION_PORT; diff --git a/spring-roo/pom.xml b/spring-roo/pom.xml index baa0e7f5e6..eb3a680d93 100644 --- a/spring-roo/pom.xml +++ b/spring-roo/pom.xml @@ -604,14 +604,14 @@
    - 2.0.0.RC1 + 2.0.0.RELEASE 8 UTF-8 1.8 1.5.4 - 1.4.1.RELEASE + 2.1.7.RELEASE 1.8 - 1.2.0.RC1 + 1.2.0.RELEASE 1.1.2 3.0.0.RELEASE 2.0.0 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/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/SpringContextIntegrationTest.java b/spring-security-client/spring-security-jsp-authentication/src/test/java/org/baeldung/SpringContextIntegrationTest.java deleted file mode 100644 index 66243ef00d..0000000000 --- a/spring-security-client/spring-security-jsp-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-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/SpringContextIntegrationTest.java b/spring-security-client/spring-security-jsp-authorize/src/test/java/org/baeldung/SpringContextIntegrationTest.java deleted file mode 100644 index 66243ef00d..0000000000 --- a/spring-security-client/spring-security-jsp-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-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/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/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/Application.java b/spring-security-client/spring-security-thymeleaf-authentication/src/main/java/org/baeldung/config/Application.java deleted file mode 100644 index 329b104143..0000000000 --- a/spring-security-client/spring-security-thymeleaf-authentication/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-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/main/resources/templates/index.html b/spring-security-client/spring-security-thymeleaf-config/src/main/resources/templates/index.html deleted file mode 100644 index 8e7394ad6a..0000000000 --- a/spring-security-client/spring-security-thymeleaf-config/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-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/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/com/baeldung/app/App.java similarity index 87% rename from spring-security-core/src/main/java/org/baeldung/app/App.java rename to spring-security-core/src/main/java/com/baeldung/app/App.java index db0c9135c4..d23df9adef 100644 --- a/spring-security-core/src/main/java/org/baeldung/app/App.java +++ b/spring-security-core/src/main/java/com/baeldung/app/App.java @@ -1,20 +1,20 @@ -package org.baeldung.app; +package com.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") -@ComponentScan("org.baeldung") -@EntityScan("org.baeldung.entity") +@EnableJpaRepositories("com.baeldung.repository") +@ComponentScan("com.baeldung") +@EntityScan("com.baeldung.entity") public class App extends SpringBootServletInitializer { public static void main(String[] args) { SpringApplication.run(App.class, args); diff --git a/spring-security-core/src/main/java/org/baeldung/auditing/ExposeAttemptedPathAuthorizationAuditListener.java b/spring-security-core/src/main/java/com/baeldung/auditing/ExposeAttemptedPathAuthorizationAuditListener.java similarity index 98% rename from spring-security-core/src/main/java/org/baeldung/auditing/ExposeAttemptedPathAuthorizationAuditListener.java rename to spring-security-core/src/main/java/com/baeldung/auditing/ExposeAttemptedPathAuthorizationAuditListener.java index bc36ac08b3..615d14584f 100644 --- a/spring-security-core/src/main/java/org/baeldung/auditing/ExposeAttemptedPathAuthorizationAuditListener.java +++ b/spring-security-core/src/main/java/com/baeldung/auditing/ExposeAttemptedPathAuthorizationAuditListener.java @@ -1,4 +1,4 @@ -package org.baeldung.auditing; +package com.baeldung.auditing; import org.springframework.boot.actuate.audit.AuditEvent; import org.springframework.boot.actuate.security.AbstractAuthorizationAuditListener; diff --git a/spring-security-core/src/main/java/org/baeldung/auditing/LoginAttemptsLogger.java b/spring-security-core/src/main/java/com/baeldung/auditing/LoginAttemptsLogger.java similarity index 97% rename from spring-security-core/src/main/java/org/baeldung/auditing/LoginAttemptsLogger.java rename to spring-security-core/src/main/java/com/baeldung/auditing/LoginAttemptsLogger.java index bf0781bced..d06c3e24e1 100644 --- a/spring-security-core/src/main/java/org/baeldung/auditing/LoginAttemptsLogger.java +++ b/spring-security-core/src/main/java/com/baeldung/auditing/LoginAttemptsLogger.java @@ -1,4 +1,4 @@ -package org.baeldung.auditing; +package com.baeldung.auditing; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/spring-security-core/src/main/java/org/baeldung/config/DatabaseLoader.java b/spring-security-core/src/main/java/com/baeldung/config/DatabaseLoader.java similarity index 86% rename from spring-security-core/src/main/java/org/baeldung/config/DatabaseLoader.java rename to spring-security-core/src/main/java/com/baeldung/config/DatabaseLoader.java index e311f62fff..7f22c3ec99 100644 --- a/spring-security-core/src/main/java/org/baeldung/config/DatabaseLoader.java +++ b/spring-security-core/src/main/java/com/baeldung/config/DatabaseLoader.java @@ -1,11 +1,12 @@ -package org.baeldung.config; +package com.baeldung.config; -import org.baeldung.entity.Task; -import org.baeldung.repository.TaskRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.stereotype.Component; +import com.baeldung.entity.Task; +import com.baeldung.repository.TaskRepository; + @Component public class DatabaseLoader implements CommandLineRunner { diff --git a/spring-security-core/src/main/java/org/baeldung/config/WebSecurityConfig.java b/spring-security-core/src/main/java/com/baeldung/config/WebSecurityConfig.java similarity index 65% rename from spring-security-core/src/main/java/org/baeldung/config/WebSecurityConfig.java rename to spring-security-core/src/main/java/com/baeldung/config/WebSecurityConfig.java index 0b6cd34f3e..be11a0fde5 100644 --- a/spring-security-core/src/main/java/org/baeldung/config/WebSecurityConfig.java +++ b/spring-security-core/src/main/java/com/baeldung/config/WebSecurityConfig.java @@ -1,12 +1,15 @@ -package org.baeldung.config; +package com.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-security-core/src/main/java/org/baeldung/controller/TaskController.java b/spring-security-core/src/main/java/com/baeldung/controller/TaskController.java similarity index 90% rename from spring-security-core/src/main/java/org/baeldung/controller/TaskController.java rename to spring-security-core/src/main/java/com/baeldung/controller/TaskController.java index d99109c543..91156354b1 100644 --- a/spring-security-core/src/main/java/org/baeldung/controller/TaskController.java +++ b/spring-security-core/src/main/java/com/baeldung/controller/TaskController.java @@ -1,7 +1,5 @@ -package org.baeldung.controller; +package com.baeldung.controller; -import org.baeldung.entity.Task; -import org.baeldung.service.TaskService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; @@ -9,6 +7,9 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; +import com.baeldung.entity.Task; +import com.baeldung.service.TaskService; + @Controller @RequestMapping("api/tasks") public class TaskController { diff --git a/spring-security-core/src/main/java/org/baeldung/entity/Task.java b/spring-security-core/src/main/java/com/baeldung/entity/Task.java similarity index 96% rename from spring-security-core/src/main/java/org/baeldung/entity/Task.java rename to spring-security-core/src/main/java/com/baeldung/entity/Task.java index 5d3321ef2e..9103c342cc 100644 --- a/spring-security-core/src/main/java/org/baeldung/entity/Task.java +++ b/spring-security-core/src/main/java/com/baeldung/entity/Task.java @@ -1,4 +1,4 @@ -package org.baeldung.entity; +package com.baeldung.entity; import javax.persistence.Entity; import javax.persistence.GeneratedValue; diff --git a/spring-security-core/src/main/java/org/baeldung/filter/CustomFilter.java b/spring-security-core/src/main/java/com/baeldung/filter/CustomFilter.java similarity index 97% rename from spring-security-core/src/main/java/org/baeldung/filter/CustomFilter.java rename to spring-security-core/src/main/java/com/baeldung/filter/CustomFilter.java index 35596eae16..e748b373b7 100644 --- a/spring-security-core/src/main/java/org/baeldung/filter/CustomFilter.java +++ b/spring-security-core/src/main/java/com/baeldung/filter/CustomFilter.java @@ -1,4 +1,4 @@ -package org.baeldung.filter; +package com.baeldung.filter; import java.io.IOException; diff --git a/spring-security-core/src/main/java/org/baeldung/methodsecurity/annotation/IsViewer.java b/spring-security-core/src/main/java/com/baeldung/methodsecurity/annotation/IsViewer.java similarity index 85% rename from spring-security-core/src/main/java/org/baeldung/methodsecurity/annotation/IsViewer.java rename to spring-security-core/src/main/java/com/baeldung/methodsecurity/annotation/IsViewer.java index 711784adbb..bde4456f8e 100644 --- a/spring-security-core/src/main/java/org/baeldung/methodsecurity/annotation/IsViewer.java +++ b/spring-security-core/src/main/java/com/baeldung/methodsecurity/annotation/IsViewer.java @@ -1,4 +1,4 @@ -package org.baeldung.methodsecurity.annotation; +package com.baeldung.methodsecurity.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; diff --git a/spring-security-core/src/main/java/org/baeldung/methodsecurity/config/MethodSecurityConfig.java b/spring-security-core/src/main/java/com/baeldung/methodsecurity/config/MethodSecurityConfig.java similarity index 91% rename from spring-security-core/src/main/java/org/baeldung/methodsecurity/config/MethodSecurityConfig.java rename to spring-security-core/src/main/java/com/baeldung/methodsecurity/config/MethodSecurityConfig.java index 4749c730dc..239f7067a4 100644 --- a/spring-security-core/src/main/java/org/baeldung/methodsecurity/config/MethodSecurityConfig.java +++ b/spring-security-core/src/main/java/com/baeldung/methodsecurity/config/MethodSecurityConfig.java @@ -1,4 +1,4 @@ -package org.baeldung.methodsecurity.config; +package com.baeldung.methodsecurity.config; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; diff --git a/spring-security-core/src/main/java/org/baeldung/methodsecurity/entity/CustomUser.java b/spring-security-core/src/main/java/com/baeldung/methodsecurity/entity/CustomUser.java similarity index 91% rename from spring-security-core/src/main/java/org/baeldung/methodsecurity/entity/CustomUser.java rename to spring-security-core/src/main/java/com/baeldung/methodsecurity/entity/CustomUser.java index fb9174befa..7daaef5984 100644 --- a/spring-security-core/src/main/java/org/baeldung/methodsecurity/entity/CustomUser.java +++ b/spring-security-core/src/main/java/com/baeldung/methodsecurity/entity/CustomUser.java @@ -1,4 +1,4 @@ -package org.baeldung.methodsecurity.entity; +package com.baeldung.methodsecurity.entity; import java.util.Collection; diff --git a/spring-security-core/src/main/java/org/baeldung/methodsecurity/repository/UserRoleRepository.java b/spring-security-core/src/main/java/com/baeldung/methodsecurity/repository/UserRoleRepository.java similarity index 92% rename from spring-security-core/src/main/java/org/baeldung/methodsecurity/repository/UserRoleRepository.java rename to spring-security-core/src/main/java/com/baeldung/methodsecurity/repository/UserRoleRepository.java index fc1a32289d..eef39189a7 100644 --- a/spring-security-core/src/main/java/org/baeldung/methodsecurity/repository/UserRoleRepository.java +++ b/spring-security-core/src/main/java/com/baeldung/methodsecurity/repository/UserRoleRepository.java @@ -1,16 +1,17 @@ -package org.baeldung.methodsecurity.repository; +package com.baeldung.methodsecurity.repository; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import org.baeldung.methodsecurity.entity.CustomUser; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.stereotype.Service; +import com.baeldung.methodsecurity.entity.CustomUser; + @Service public class UserRoleRepository { diff --git a/spring-security-core/src/main/java/org/baeldung/methodsecurity/service/CustomUserDetailsService.java b/spring-security-core/src/main/java/com/baeldung/methodsecurity/service/CustomUserDetailsService.java similarity index 81% rename from spring-security-core/src/main/java/org/baeldung/methodsecurity/service/CustomUserDetailsService.java rename to spring-security-core/src/main/java/com/baeldung/methodsecurity/service/CustomUserDetailsService.java index 91171468bb..685621b55f 100644 --- a/spring-security-core/src/main/java/org/baeldung/methodsecurity/service/CustomUserDetailsService.java +++ b/spring-security-core/src/main/java/com/baeldung/methodsecurity/service/CustomUserDetailsService.java @@ -1,11 +1,12 @@ -package org.baeldung.methodsecurity.service; +package com.baeldung.methodsecurity.service; -import org.baeldung.methodsecurity.repository.UserRoleRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.stereotype.Service; +import com.baeldung.methodsecurity.repository.UserRoleRepository; + @Service("userDetailService") public class CustomUserDetailsService implements UserDetailsService { diff --git a/spring-security-core/src/main/java/org/baeldung/methodsecurity/service/SystemService.java b/spring-security-core/src/main/java/com/baeldung/methodsecurity/service/SystemService.java similarity index 84% rename from spring-security-core/src/main/java/org/baeldung/methodsecurity/service/SystemService.java rename to spring-security-core/src/main/java/com/baeldung/methodsecurity/service/SystemService.java index 5f29d7dee6..623d51d34f 100644 --- a/spring-security-core/src/main/java/org/baeldung/methodsecurity/service/SystemService.java +++ b/spring-security-core/src/main/java/com/baeldung/methodsecurity/service/SystemService.java @@ -1,4 +1,4 @@ -package org.baeldung.methodsecurity.service; +package com.baeldung.methodsecurity.service; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Service; diff --git a/spring-security-core/src/main/java/org/baeldung/methodsecurity/service/UserRoleService.java b/spring-security-core/src/main/java/com/baeldung/methodsecurity/service/UserRoleService.java similarity index 92% rename from spring-security-core/src/main/java/org/baeldung/methodsecurity/service/UserRoleService.java rename to spring-security-core/src/main/java/com/baeldung/methodsecurity/service/UserRoleService.java index 30bbdbc10f..4d090fd90c 100644 --- a/spring-security-core/src/main/java/org/baeldung/methodsecurity/service/UserRoleService.java +++ b/spring-security-core/src/main/java/com/baeldung/methodsecurity/service/UserRoleService.java @@ -1,13 +1,10 @@ -package org.baeldung.methodsecurity.service; +package com.baeldung.methodsecurity.service; import java.util.List; import java.util.stream.Collectors; import javax.annotation.security.RolesAllowed; -import org.baeldung.methodsecurity.annotation.IsViewer; -import org.baeldung.methodsecurity.entity.CustomUser; -import org.baeldung.methodsecurity.repository.UserRoleRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.annotation.Secured; import org.springframework.security.access.prepost.PostAuthorize; @@ -18,6 +15,10 @@ import org.springframework.security.core.context.SecurityContext; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Service; +import com.baeldung.methodsecurity.annotation.IsViewer; +import com.baeldung.methodsecurity.entity.CustomUser; +import com.baeldung.methodsecurity.repository.UserRoleRepository; + @Service public class UserRoleService { diff --git a/spring-security-core/src/main/java/org/baeldung/repository/TaskRepository.java b/spring-security-core/src/main/java/com/baeldung/repository/TaskRepository.java similarity index 66% rename from spring-security-core/src/main/java/org/baeldung/repository/TaskRepository.java rename to spring-security-core/src/main/java/com/baeldung/repository/TaskRepository.java index 651b11684f..afb999719c 100644 --- a/spring-security-core/src/main/java/org/baeldung/repository/TaskRepository.java +++ b/spring-security-core/src/main/java/com/baeldung/repository/TaskRepository.java @@ -1,8 +1,9 @@ -package org.baeldung.repository; +package com.baeldung.repository; -import org.baeldung.entity.Task; import org.springframework.data.repository.CrudRepository; +import com.baeldung.entity.Task; + public interface TaskRepository extends CrudRepository { } diff --git a/spring-security-core/src/main/java/org/baeldung/service/TaskService.java b/spring-security-core/src/main/java/com/baeldung/service/TaskService.java similarity index 80% rename from spring-security-core/src/main/java/org/baeldung/service/TaskService.java rename to spring-security-core/src/main/java/com/baeldung/service/TaskService.java index 4a0dae3aac..1269eb4fd0 100644 --- a/spring-security-core/src/main/java/org/baeldung/service/TaskService.java +++ b/spring-security-core/src/main/java/com/baeldung/service/TaskService.java @@ -1,12 +1,13 @@ -package org.baeldung.service; +package com.baeldung.service; -import org.baeldung.entity.Task; -import org.baeldung.repository.TaskRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.prepost.PostFilter; import org.springframework.security.access.prepost.PreFilter; import org.springframework.stereotype.Service; +import com.baeldung.entity.Task; +import com.baeldung.repository.TaskRepository; + @Service public class TaskService { @@ -20,7 +21,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/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-security-core/src/test/java/com/baeldung/SpringContextIntegrationTest.java similarity index 87% rename from spring-security-core/src/test/java/org/baeldung/SpringContextIntegrationTest.java rename to spring-security-core/src/test/java/com/baeldung/SpringContextIntegrationTest.java index 5698afa417..1cdff1342c 100644 --- a/spring-security-core/src/test/java/org/baeldung/SpringContextIntegrationTest.java +++ b/spring-security-core/src/test/java/com/baeldung/SpringContextIntegrationTest.java @@ -1,11 +1,12 @@ -package org.baeldung; +package com.baeldung; -import org.baeldung.app.App; 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.app.App; + @RunWith(SpringRunner.class) @SpringBootTest(classes = App.class) public class SpringContextIntegrationTest { diff --git a/spring-security-core/src/test/java/org/baeldung/SpringContextTest.java b/spring-security-core/src/test/java/com/baeldung/SpringContextTest.java similarity index 87% rename from spring-security-core/src/test/java/org/baeldung/SpringContextTest.java rename to spring-security-core/src/test/java/com/baeldung/SpringContextTest.java index 1707c706ae..bca6450fb1 100644 --- a/spring-security-core/src/test/java/org/baeldung/SpringContextTest.java +++ b/spring-security-core/src/test/java/com/baeldung/SpringContextTest.java @@ -1,11 +1,12 @@ -package org.baeldung; +package com.baeldung; -import org.baeldung.app.App; 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.app.App; + @RunWith(SpringRunner.class) @SpringBootTest(classes = App.class) public class SpringContextTest { diff --git a/spring-security-core/src/test/java/org/baeldung/methodsecurity/TestClassLevelSecurity.java b/spring-security-core/src/test/java/com/baeldung/methodsecurity/ClassLevelSecurityIntegrationTest.java similarity index 85% rename from spring-security-core/src/test/java/org/baeldung/methodsecurity/TestClassLevelSecurity.java rename to spring-security-core/src/test/java/com/baeldung/methodsecurity/ClassLevelSecurityIntegrationTest.java index 502fd50c46..943bfda72c 100644 --- a/spring-security-core/src/test/java/org/baeldung/methodsecurity/TestClassLevelSecurity.java +++ b/spring-security-core/src/test/java/com/baeldung/methodsecurity/ClassLevelSecurityIntegrationTest.java @@ -1,8 +1,7 @@ -package org.baeldung.methodsecurity; +package com.baeldung.methodsecurity; import static org.junit.Assert.*; -import org.baeldung.methodsecurity.service.SystemService; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; @@ -13,15 +12,17 @@ import org.springframework.security.test.context.support.WithMockUser; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringRunner; +import com.baeldung.methodsecurity.service.SystemService; + @RunWith(SpringRunner.class) @ContextConfiguration -public class TestClassLevelSecurity { +public class ClassLevelSecurityIntegrationTest { @Autowired SystemService systemService; @Configuration - @ComponentScan("org.baeldung.methodsecurity.*") + @ComponentScan("com.baeldung.methodsecurity.*") public static class SpringConfig { } diff --git a/spring-security-core/src/test/java/org/baeldung/methodsecurity/TestMethodSecurity.java b/spring-security-core/src/test/java/com/baeldung/methodsecurity/MethodSecurityIntegrationTest.java similarity index 94% rename from spring-security-core/src/test/java/org/baeldung/methodsecurity/TestMethodSecurity.java rename to spring-security-core/src/test/java/com/baeldung/methodsecurity/MethodSecurityIntegrationTest.java index 009d9af9fc..81b150f43e 100644 --- a/spring-security-core/src/test/java/org/baeldung/methodsecurity/TestMethodSecurity.java +++ b/spring-security-core/src/test/java/com/baeldung/methodsecurity/MethodSecurityIntegrationTest.java @@ -1,4 +1,4 @@ -package org.baeldung.methodsecurity; +package com.baeldung.methodsecurity; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @@ -6,7 +6,6 @@ import static org.junit.Assert.assertTrue; import java.util.ArrayList; import java.util.List; -import org.baeldung.methodsecurity.service.UserRoleService; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; @@ -19,15 +18,17 @@ import org.springframework.security.test.context.support.WithMockUser; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringRunner; +import com.baeldung.methodsecurity.service.UserRoleService; + @RunWith(SpringRunner.class) @ContextConfiguration -public class TestMethodSecurity { +public class MethodSecurityIntegrationTest { @Autowired UserRoleService userRoleService; @Configuration - @ComponentScan("org.baeldung.methodsecurity.*") + @ComponentScan("com.baeldung.methodsecurity.*") public static class SpringConfig { } diff --git a/spring-security-core/src/test/java/org/baeldung/methodsecurity/TestWithMockUserAtClassLevel.java b/spring-security-core/src/test/java/com/baeldung/methodsecurity/MockUserAtClassLevelIntegrationTest.java similarity index 79% rename from spring-security-core/src/test/java/org/baeldung/methodsecurity/TestWithMockUserAtClassLevel.java rename to spring-security-core/src/test/java/com/baeldung/methodsecurity/MockUserAtClassLevelIntegrationTest.java index 4df1af8ca9..fead89f75a 100644 --- a/spring-security-core/src/test/java/org/baeldung/methodsecurity/TestWithMockUserAtClassLevel.java +++ b/spring-security-core/src/test/java/com/baeldung/methodsecurity/MockUserAtClassLevelIntegrationTest.java @@ -1,8 +1,7 @@ -package org.baeldung.methodsecurity; +package com.baeldung.methodsecurity; import static org.junit.Assert.assertEquals; -import org.baeldung.methodsecurity.service.UserRoleService; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; @@ -12,10 +11,12 @@ import org.springframework.security.test.context.support.WithMockUser; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringRunner; +import com.baeldung.methodsecurity.service.UserRoleService; + @RunWith(SpringRunner.class) @ContextConfiguration @WithMockUser(username = "john", roles = { "VIEWER" }) -public class TestWithMockUserAtClassLevel { +public class MockUserAtClassLevelIntegrationTest { @Test public void givenRoleViewer_whenCallGetUsername_thenReturnUsername() { @@ -27,7 +28,7 @@ public class TestWithMockUserAtClassLevel { UserRoleService userService; @Configuration - @ComponentScan("org.baeldung.methodsecurity.*") + @ComponentScan("com.baeldung.methodsecurity.*") public static class SpringConfig { } diff --git a/spring-security-core/src/test/java/org/baeldung/methodsecurity/TestWithUserDetails.java b/spring-security-core/src/test/java/com/baeldung/methodsecurity/UserDetailsIntegrationTest.java similarity index 86% rename from spring-security-core/src/test/java/org/baeldung/methodsecurity/TestWithUserDetails.java rename to spring-security-core/src/test/java/com/baeldung/methodsecurity/UserDetailsIntegrationTest.java index 3ef5996554..d43a26a5ff 100644 --- a/spring-security-core/src/test/java/org/baeldung/methodsecurity/TestWithUserDetails.java +++ b/spring-security-core/src/test/java/com/baeldung/methodsecurity/UserDetailsIntegrationTest.java @@ -1,9 +1,7 @@ -package org.baeldung.methodsecurity; +package com.baeldung.methodsecurity; import static org.junit.Assert.assertEquals; -import org.baeldung.methodsecurity.entity.CustomUser; -import org.baeldung.methodsecurity.service.UserRoleService; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; @@ -14,15 +12,18 @@ import org.springframework.security.test.context.support.WithUserDetails; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringRunner; +import com.baeldung.methodsecurity.entity.CustomUser; +import com.baeldung.methodsecurity.service.UserRoleService; + @RunWith(SpringRunner.class) @ContextConfiguration -public class TestWithUserDetails { +public class UserDetailsIntegrationTest { @Autowired UserRoleService userService; @Configuration - @ComponentScan("org.baeldung.methodsecurity.*") + @ComponentScan("com.baeldung.methodsecurity.*") public static class SpringConfig { } diff --git a/spring-security-core/src/test/java/org/baeldung/methodsecurity/WithMockJohnViewer.java b/spring-security-core/src/test/java/com/baeldung/methodsecurity/WithMockJohnViewer.java similarity index 85% rename from spring-security-core/src/test/java/org/baeldung/methodsecurity/WithMockJohnViewer.java rename to spring-security-core/src/test/java/com/baeldung/methodsecurity/WithMockJohnViewer.java index 5e1e882f3d..f05a6bc20e 100644 --- a/spring-security-core/src/test/java/org/baeldung/methodsecurity/WithMockJohnViewer.java +++ b/spring-security-core/src/test/java/com/baeldung/methodsecurity/WithMockJohnViewer.java @@ -1,4 +1,4 @@ -package org.baeldung.methodsecurity; +package com.baeldung.methodsecurity; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/spring-security-core/src/test/java/org/baeldung/test/LiveTest.java b/spring-security-core/src/test/java/com/baeldung/test/LiveTest.java similarity index 98% rename from spring-security-core/src/test/java/org/baeldung/test/LiveTest.java rename to spring-security-core/src/test/java/com/baeldung/test/LiveTest.java index 7243d3efd5..6bcb2e8f0f 100644 --- a/spring-security-core/src/test/java/org/baeldung/test/LiveTest.java +++ b/spring-security-core/src/test/java/com/baeldung/test/LiveTest.java @@ -1,11 +1,10 @@ -package org.baeldung.test; +package com.baeldung.test; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -import org.baeldung.app.App; import org.junit.Before; import org.junit.FixMethodOrder; import org.junit.Test; @@ -20,6 +19,8 @@ import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.web.context.WebApplicationContext; +import com.baeldung.app.App; + @RunWith(SpringJUnit4ClassRunner.class) @SpringBootTest(classes = App.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @FixMethodOrder(MethodSorters.NAME_ASCENDING) 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..0063a2d82b 100644 --- a/spring-security-mvc-boot/pom.xml +++ b/spring-security-mvc-boot/pom.xml @@ -1,6 +1,7 @@ - + 4.0.0 com.baeldung spring-security-mvc-boot @@ -45,10 +46,20 @@ org.springframework.security spring-security-data + + mysql + mysql-connector-java + runtime + com.h2database h2 + + org.postgresql + postgresql + runtime + org.hamcrest hamcrest-core @@ -198,7 +209,7 @@ **/*LiveTest.java **/*IntegrationTest.java - **/*IntTest.java + **/*IntTest.java **/*EntryPointsTest.java @@ -228,10 +239,10 @@ - - + - + 1.1.2 1.6.1 diff --git a/spring-security-mvc-boot/src/main/java/com/baeldung/AppConfig.java b/spring-security-mvc-boot/src/main/java/com/baeldung/AppConfig.java index 16bbe8b326..8719e39a20 100644 --- a/spring-security-mvc-boot/src/main/java/com/baeldung/AppConfig.java +++ b/spring-security-mvc-boot/src/main/java/com/baeldung/AppConfig.java @@ -18,7 +18,7 @@ import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; @SpringBootApplication -@PropertySource("classpath:persistence-h2.properties") +@PropertySource({"classpath:persistence-h2.properties", "classpath:application-defaults.properties"}) @EnableJpaRepositories(basePackages = { "com.baeldung.data.repositories" }) @EnableWebMvc @Import(SpringSecurityConfig.class) 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 index f932ac3066..2bd0da48d2 100644 --- 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 @@ -1,14 +1,12 @@ 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; +import org.springframework.context.annotation.PropertySource; @SpringBootApplication +@PropertySource("classpath:application-defaults.properties") 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/ip/IpApplication.java b/spring-security-mvc-boot/src/main/java/org/baeldung/ip/IpApplication.java index fd270686a2..b68abbaed1 100644 --- a/spring-security-mvc-boot/src/main/java/org/baeldung/ip/IpApplication.java +++ b/spring-security-mvc-boot/src/main/java/org/baeldung/ip/IpApplication.java @@ -3,8 +3,10 @@ package org.baeldung.ip; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; +import org.springframework.context.annotation.PropertySource; @SpringBootApplication +@PropertySource("classpath:application-defaults.properties") public class IpApplication extends SpringBootServletInitializer { public static void main(String[] args) { SpringApplication.run(IpApplication.class, args); diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/jdbcauthentication/h2/H2JdbcAuthenticationApplication.java b/spring-security-mvc-boot/src/main/java/org/baeldung/jdbcauthentication/h2/H2JdbcAuthenticationApplication.java new file mode 100644 index 0000000000..6936cdc560 --- /dev/null +++ b/spring-security-mvc-boot/src/main/java/org/baeldung/jdbcauthentication/h2/H2JdbcAuthenticationApplication.java @@ -0,0 +1,17 @@ +package org.baeldung.jdbcauthentication.h2; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.PropertySource; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; + +@SpringBootApplication +@EnableWebSecurity +@PropertySource("classpath:application-defaults.properties") +public class H2JdbcAuthenticationApplication { + + public static void main(String[] args) { + SpringApplication.run(H2JdbcAuthenticationApplication.class, args); + } + +} diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/jdbcauthentication/h2/config/SecurityConfiguration.java b/spring-security-mvc-boot/src/main/java/org/baeldung/jdbcauthentication/h2/config/SecurityConfiguration.java new file mode 100644 index 0000000000..8b8696f0b2 --- /dev/null +++ b/spring-security-mvc-boot/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/src/main/java/org/baeldung/jdbcauthentication/h2/web/UserController.java b/spring-security-mvc-boot/src/main/java/org/baeldung/jdbcauthentication/h2/web/UserController.java new file mode 100644 index 0000000000..0955061614 --- /dev/null +++ b/spring-security-mvc-boot/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/jdbcauthentication/mysql/MySqlJdbcAuthenticationApplication.java b/spring-security-mvc-boot/src/main/java/org/baeldung/jdbcauthentication/mysql/MySqlJdbcAuthenticationApplication.java new file mode 100644 index 0000000000..52934e0096 --- /dev/null +++ b/spring-security-mvc-boot/src/main/java/org/baeldung/jdbcauthentication/mysql/MySqlJdbcAuthenticationApplication.java @@ -0,0 +1,15 @@ +package org.baeldung.jdbcauthentication.mysql; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.PropertySource; + +@SpringBootApplication +@PropertySource("classpath:application-mysql.properties") +public class MySqlJdbcAuthenticationApplication { + + public static void main(String[] args) { + SpringApplication.run(MySqlJdbcAuthenticationApplication.class, args); + } + +} diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/jdbcauthentication/mysql/config/SecurityConfiguration.java b/spring-security-mvc-boot/src/main/java/org/baeldung/jdbcauthentication/mysql/config/SecurityConfiguration.java new file mode 100644 index 0000000000..157c0be748 --- /dev/null +++ b/spring-security-mvc-boot/src/main/java/org/baeldung/jdbcauthentication/mysql/config/SecurityConfiguration.java @@ -0,0 +1,35 @@ +package org.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/src/main/java/org/baeldung/jdbcauthentication/mysql/web/UserController.java b/spring-security-mvc-boot/src/main/java/org/baeldung/jdbcauthentication/mysql/web/UserController.java new file mode 100644 index 0000000000..f1060b5f78 --- /dev/null +++ b/spring-security-mvc-boot/src/main/java/org/baeldung/jdbcauthentication/mysql/web/UserController.java @@ -0,0 +1,17 @@ +package org.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/src/main/java/org/baeldung/jdbcauthentication/postgre/PostgreJdbcAuthenticationApplication.java b/spring-security-mvc-boot/src/main/java/org/baeldung/jdbcauthentication/postgre/PostgreJdbcAuthenticationApplication.java new file mode 100644 index 0000000000..2c4d1a5255 --- /dev/null +++ b/spring-security-mvc-boot/src/main/java/org/baeldung/jdbcauthentication/postgre/PostgreJdbcAuthenticationApplication.java @@ -0,0 +1,15 @@ +package org.baeldung.jdbcauthentication.postgre; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.PropertySource; + +@SpringBootApplication +@PropertySource("classpath:application-postgre.properties") +public class PostgreJdbcAuthenticationApplication { + + public static void main(String[] args) { + SpringApplication.run(PostgreJdbcAuthenticationApplication.class, args); + } + +} diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/jdbcauthentication/postgre/config/SecurityConfiguration.java b/spring-security-mvc-boot/src/main/java/org/baeldung/jdbcauthentication/postgre/config/SecurityConfiguration.java new file mode 100644 index 0000000000..ba79635852 --- /dev/null +++ b/spring-security-mvc-boot/src/main/java/org/baeldung/jdbcauthentication/postgre/config/SecurityConfiguration.java @@ -0,0 +1,29 @@ +package org.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/src/main/java/org/baeldung/jdbcauthentication/postgre/web/UserController.java b/spring-security-mvc-boot/src/main/java/org/baeldung/jdbcauthentication/postgre/web/UserController.java new file mode 100644 index 0000000000..c8fd3812b1 --- /dev/null +++ b/spring-security-mvc-boot/src/main/java/org/baeldung/jdbcauthentication/postgre/web/UserController.java @@ -0,0 +1,17 @@ +package org.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/src/main/java/org/baeldung/multipleauthproviders/MultipleAuthProvidersApplication.java b/spring-security-mvc-boot/src/main/java/org/baeldung/multipleauthproviders/MultipleAuthProvidersApplication.java index 077f558bd2..1f641298c3 100644 --- a/spring-security-mvc-boot/src/main/java/org/baeldung/multipleauthproviders/MultipleAuthProvidersApplication.java +++ b/spring-security-mvc-boot/src/main/java/org/baeldung/multipleauthproviders/MultipleAuthProvidersApplication.java @@ -2,8 +2,10 @@ package org.baeldung.multipleauthproviders; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.PropertySource; @SpringBootApplication +@PropertySource("classpath:application-defaults.properties") // @ImportResource({ "classpath*:spring-security-multiple-auth-providers.xml" }) public class MultipleAuthProvidersApplication { public static void main(String[] args) { diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/multipleentrypoints/MultipleEntryPointsApplication.java b/spring-security-mvc-boot/src/main/java/org/baeldung/multipleentrypoints/MultipleEntryPointsApplication.java index 4e5fafcd99..847dab073e 100644 --- a/spring-security-mvc-boot/src/main/java/org/baeldung/multipleentrypoints/MultipleEntryPointsApplication.java +++ b/spring-security-mvc-boot/src/main/java/org/baeldung/multipleentrypoints/MultipleEntryPointsApplication.java @@ -2,8 +2,10 @@ package org.baeldung.multipleentrypoints; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.PropertySource; @SpringBootApplication +@PropertySource("classpath:application-defaults.properties") // @ImportResource({"classpath*:spring-security-multiple-entry.xml"}) public class MultipleEntryPointsApplication { public static void main(String[] args) { diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/multiplelogin/MultipleLoginApplication.java b/spring-security-mvc-boot/src/main/java/org/baeldung/multiplelogin/MultipleLoginApplication.java index e9dc541ad3..90bb5e4260 100644 --- a/spring-security-mvc-boot/src/main/java/org/baeldung/multiplelogin/MultipleLoginApplication.java +++ b/spring-security-mvc-boot/src/main/java/org/baeldung/multiplelogin/MultipleLoginApplication.java @@ -1,13 +1,12 @@ 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; +import org.springframework.context.annotation.PropertySource; @SpringBootApplication +@PropertySource("classpath:application-defaults.properties") @ComponentScan("org.baeldung.multiplelogin") public class MultipleLoginApplication { public static void main(String[] args) { diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/ssl/HttpsEnabledApplication.java b/spring-security-mvc-boot/src/main/java/org/baeldung/ssl/HttpsEnabledApplication.java index 70fe30abdc..17c249067c 100644 --- a/spring-security-mvc-boot/src/main/java/org/baeldung/ssl/HttpsEnabledApplication.java +++ b/spring-security-mvc-boot/src/main/java/org/baeldung/ssl/HttpsEnabledApplication.java @@ -2,8 +2,10 @@ package org.baeldung.ssl; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.PropertySource; @SpringBootApplication +@PropertySource("classpath:application-defaults.properties") public class HttpsEnabledApplication { public static void main(String... args) { diff --git a/spring-security-mvc-boot/src/main/resources/application-defaults.properties b/spring-security-mvc-boot/src/main/resources/application-defaults.properties new file mode 100644 index 0000000000..e2032c4a6b --- /dev/null +++ b/spring-security-mvc-boot/src/main/resources/application-defaults.properties @@ -0,0 +1,13 @@ +spring.datasource.driver-class-name=org.h2.Driver +spring.datasource.url=jdbc:h2:mem:security_permission;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE +spring.datasource.username=sa +spring.datasource.password= +spring.jpa.hibernate.ddl-auto=create-drop +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 + +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/application-mysql.properties b/spring-security-mvc-boot/src/main/resources/application-mysql.properties new file mode 100644 index 0000000000..568d0c5ca3 --- /dev/null +++ b/spring-security-mvc-boot/src/main/resources/application-mysql.properties @@ -0,0 +1,9 @@ +spring.datasource.platform=mysql +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 + +spring.profiles.active=mysql diff --git a/spring-security-mvc-boot/src/main/resources/application-postgre.properties b/spring-security-mvc-boot/src/main/resources/application-postgre.properties new file mode 100644 index 0000000000..69faece45e --- /dev/null +++ b/spring-security-mvc-boot/src/main/resources/application-postgre.properties @@ -0,0 +1,7 @@ +spring.datasource.platform=postgre +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/src/main/resources/application.properties b/spring-security-mvc-boot/src/main/resources/application.properties index 25eac743d1..3cf12afeb9 100644 --- a/spring-security-mvc-boot/src/main/resources/application.properties +++ b/spring-security-mvc-boot/src/main/resources/application.properties @@ -1,12 +1 @@ server.port=8082 -spring.datasource.driver-class-name=org.h2.Driver -spring.datasource.url=jdbc:h2:mem:security_permission;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE -spring.datasource.username=sa -spring.datasource.password= -spring.jpa.hibernate.ddl-auto=create-drop -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 \ No newline at end of file diff --git a/spring-security-mvc-boot/src/main/resources/data-mysql.sql b/spring-security-mvc-boot/src/main/resources/data-mysql.sql new file mode 100644 index 0000000000..8214fd8204 --- /dev/null +++ b/spring-security-mvc-boot/src/main/resources/data-mysql.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/src/main/resources/data-postgre.sql b/spring-security-mvc-boot/src/main/resources/data-postgre.sql new file mode 100644 index 0000000000..fcc6b54949 --- /dev/null +++ b/spring-security-mvc-boot/src/main/resources/data-postgre.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/src/main/resources/schema-mysql.sql b/spring-security-mvc-boot/src/main/resources/schema-mysql.sql new file mode 100644 index 0000000000..bb38c74366 --- /dev/null +++ b/spring-security-mvc-boot/src/main/resources/schema-mysql.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-mvc-boot/src/main/resources/schema-postgre.sql b/spring-security-mvc-boot/src/main/resources/schema-postgre.sql new file mode 100644 index 0000000000..d78edfb528 --- /dev/null +++ b/spring-security-mvc-boot/src/main/resources/schema-postgre.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-config/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-security-mvc-boot/src/test/java/org/baeldung/jdbcauthentication/h2/SpringContextIntegrationTest.java similarity index 75% rename from spring-security-client/spring-security-jsp-config/src/test/java/org/baeldung/SpringContextIntegrationTest.java rename to spring-security-mvc-boot/src/test/java/org/baeldung/jdbcauthentication/h2/SpringContextIntegrationTest.java index 66243ef00d..55a7b9e2be 100644 --- a/spring-security-client/spring-security-jsp-config/src/test/java/org/baeldung/SpringContextIntegrationTest.java +++ b/spring-security-mvc-boot/src/test/java/org/baeldung/jdbcauthentication/h2/SpringContextIntegrationTest.java @@ -1,13 +1,12 @@ -package org.baeldung; +package org.baeldung.jdbcauthentication.h2; -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 = H2JdbcAuthenticationApplication.class) public class SpringContextIntegrationTest { @Test diff --git a/spring-security-mvc-boot/src/test/java/org/baeldung/jdbcauthentication/h2/web/UserControllerLiveTest.java b/spring-security-mvc-boot/src/test/java/org/baeldung/jdbcauthentication/h2/web/UserControllerLiveTest.java new file mode 100644 index 0000000000..638e9d7919 --- /dev/null +++ b/spring-security-mvc-boot/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/jdbcauthentication/mysql/web/UserControllerLiveTest.java b/spring-security-mvc-boot/src/test/java/org/baeldung/jdbcauthentication/mysql/web/UserControllerLiveTest.java new file mode 100644 index 0000000000..261063cbb6 --- /dev/null +++ b/spring-security-mvc-boot/src/test/java/org/baeldung/jdbcauthentication/mysql/web/UserControllerLiveTest.java @@ -0,0 +1,35 @@ +package org.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/src/test/java/org/baeldung/jdbcauthentication/postgre/web/UserControllerLiveTest.java b/spring-security-mvc-boot/src/test/java/org/baeldung/jdbcauthentication/postgre/web/UserControllerLiveTest.java new file mode 100644 index 0000000000..82bf6df8db --- /dev/null +++ b/spring-security-mvc-boot/src/test/java/org/baeldung/jdbcauthentication/postgre/web/UserControllerLiveTest.java @@ -0,0 +1,35 @@ +package org.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-login/src/main/java/com/baeldung/spring/SecSecurityConfig.java b/spring-security-mvc-login/src/main/java/com/baeldung/security/config/SecSecurityConfig.java similarity index 98% rename from spring-security-mvc-login/src/main/java/com/baeldung/spring/SecSecurityConfig.java rename to spring-security-mvc-login/src/main/java/com/baeldung/security/config/SecSecurityConfig.java index 08a83f8633..15fa06aa3e 100644 --- a/spring-security-mvc-login/src/main/java/com/baeldung/spring/SecSecurityConfig.java +++ b/spring-security-mvc-login/src/main/java/com/baeldung/security/config/SecSecurityConfig.java @@ -1,4 +1,4 @@ -package com.baeldung.spring; +package com.baeldung.security.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-security-mvc-login/src/test/java/com/baeldung/security/FormLoginUnitTest.java b/spring-security-mvc-login/src/test/java/com/baeldung/security/FormLoginUnitTest.java index b7d959bf36..01cb8e7b67 100644 --- a/spring-security-mvc-login/src/test/java/com/baeldung/security/FormLoginUnitTest.java +++ b/spring-security-mvc-login/src/test/java/com/baeldung/security/FormLoginUnitTest.java @@ -12,7 +12,7 @@ import org.springframework.test.web.servlet.MvcResult; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.web.context.WebApplicationContext; -import com.baeldung.spring.SecSecurityConfig; +import com.baeldung.security.config.SecSecurityConfig; import javax.servlet.Filter; diff --git a/spring-security-mvc/src/test/java/com/baeldung/session/SessionConfigurationIntegrationTest.java b/spring-security-mvc/src/test/java/com/baeldung/session/SessionConfigurationLiveTest.java similarity index 98% rename from spring-security-mvc/src/test/java/com/baeldung/session/SessionConfigurationIntegrationTest.java rename to spring-security-mvc/src/test/java/com/baeldung/session/SessionConfigurationLiveTest.java index 5a9bf72077..7d9a03d5f6 100644 --- a/spring-security-mvc/src/test/java/com/baeldung/session/SessionConfigurationIntegrationTest.java +++ b/spring-security-mvc/src/test/java/com/baeldung/session/SessionConfigurationLiveTest.java @@ -15,7 +15,7 @@ import io.restassured.specification.RequestSpecification; /** * This Live Test requires the service to be up and running. */ -public class SessionConfigurationIntegrationTest { +public class SessionConfigurationLiveTest { private static final String USER = "user1"; private static final String PASSWORD = "user1Pass"; 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-security-rest/src/main/java/org/baeldung/spring/SecurityJavaConfig.java b/spring-security-rest/src/main/java/org/baeldung/security/SecurityJavaConfig.java similarity index 94% rename from spring-security-rest/src/main/java/org/baeldung/spring/SecurityJavaConfig.java rename to spring-security-rest/src/main/java/org/baeldung/security/SecurityJavaConfig.java index cc023110b6..74623080b5 100644 --- a/spring-security-rest/src/main/java/org/baeldung/spring/SecurityJavaConfig.java +++ b/spring-security-rest/src/main/java/org/baeldung/security/SecurityJavaConfig.java @@ -1,7 +1,7 @@ -package org.baeldung.spring; +package org.baeldung.security; -import org.baeldung.security.MySavedRequestAwareAuthenticationSuccessHandler; -import org.baeldung.security.RestAuthenticationEntryPoint; +import org.baeldung.security.web.MySavedRequestAwareAuthenticationSuccessHandler; +import org.baeldung.security.web.RestAuthenticationEntryPoint; import org.baeldung.web.error.CustomAccessDeniedHandler; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; diff --git a/spring-security-rest/src/main/java/org/baeldung/security/MySavedRequestAwareAuthenticationSuccessHandler.java b/spring-security-rest/src/main/java/org/baeldung/security/web/MySavedRequestAwareAuthenticationSuccessHandler.java similarity index 98% rename from spring-security-rest/src/main/java/org/baeldung/security/MySavedRequestAwareAuthenticationSuccessHandler.java rename to spring-security-rest/src/main/java/org/baeldung/security/web/MySavedRequestAwareAuthenticationSuccessHandler.java index 6018264632..c56568e979 100644 --- a/spring-security-rest/src/main/java/org/baeldung/security/MySavedRequestAwareAuthenticationSuccessHandler.java +++ b/spring-security-rest/src/main/java/org/baeldung/security/web/MySavedRequestAwareAuthenticationSuccessHandler.java @@ -1,4 +1,4 @@ -package org.baeldung.security; +package org.baeldung.security.web; import java.io.IOException; diff --git a/spring-security-rest/src/main/java/org/baeldung/security/RestAuthenticationEntryPoint.java b/spring-security-rest/src/main/java/org/baeldung/security/web/RestAuthenticationEntryPoint.java similarity index 95% rename from spring-security-rest/src/main/java/org/baeldung/security/RestAuthenticationEntryPoint.java rename to spring-security-rest/src/main/java/org/baeldung/security/web/RestAuthenticationEntryPoint.java index e448e6537f..643e2f0575 100644 --- a/spring-security-rest/src/main/java/org/baeldung/security/RestAuthenticationEntryPoint.java +++ b/spring-security-rest/src/main/java/org/baeldung/security/web/RestAuthenticationEntryPoint.java @@ -1,4 +1,4 @@ -package org.baeldung.security; +package org.baeldung.security.web; import java.io.IOException; diff --git a/spring-security-rest/src/main/java/org/baeldung/spring/SwaggerConfig.java b/spring-security-rest/src/main/java/org/baeldung/swagger2/SwaggerConfig.java similarity index 98% rename from spring-security-rest/src/main/java/org/baeldung/spring/SwaggerConfig.java rename to spring-security-rest/src/main/java/org/baeldung/swagger2/SwaggerConfig.java index aa00e8455e..67c760353d 100644 --- a/spring-security-rest/src/main/java/org/baeldung/spring/SwaggerConfig.java +++ b/spring-security-rest/src/main/java/org/baeldung/swagger2/SwaggerConfig.java @@ -1,4 +1,4 @@ -package org.baeldung.spring; +package org.baeldung.swagger2; import static com.google.common.collect.Lists.newArrayList; diff --git a/spring-security-rest/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-security-rest/src/test/java/org/baeldung/SpringContextIntegrationTest.java index e2e9f2af2b..ae0d80bb45 100644 --- a/spring-security-rest/src/test/java/org/baeldung/SpringContextIntegrationTest.java +++ b/spring-security-rest/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -1,7 +1,7 @@ package org.baeldung; +import org.baeldung.security.SecurityJavaConfig; import org.baeldung.spring.ClientWebConfig; -import org.baeldung.spring.SecurityJavaConfig; import org.baeldung.spring.WebConfig; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/spring-security-rest/src/test/java/org/baeldung/SpringContextTest.java b/spring-security-rest/src/test/java/org/baeldung/SpringContextTest.java index d984cf5c35..11586ce670 100644 --- a/spring-security-rest/src/test/java/org/baeldung/SpringContextTest.java +++ b/spring-security-rest/src/test/java/org/baeldung/SpringContextTest.java @@ -1,7 +1,7 @@ package org.baeldung; +import org.baeldung.security.SecurityJavaConfig; import org.baeldung.spring.ClientWebConfig; -import org.baeldung.spring.SecurityJavaConfig; import org.baeldung.spring.WebConfig; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/spring-security-rest/src/test/java/org/baeldung/web/AsyncControllerIntegrationTest.java b/spring-security-rest/src/test/java/org/baeldung/web/AsyncControllerIntegrationTest.java index a09c225a4a..1e5e1b7d85 100644 --- a/spring-security-rest/src/test/java/org/baeldung/web/AsyncControllerIntegrationTest.java +++ b/spring-security-rest/src/test/java/org/baeldung/web/AsyncControllerIntegrationTest.java @@ -1,7 +1,7 @@ package org.baeldung.web; +import org.baeldung.security.SecurityJavaConfig; import org.baeldung.spring.ClientWebConfig; -import org.baeldung.spring.SecurityJavaConfig; import org.baeldung.spring.WebConfig; import org.baeldung.web.controller.AsyncController; import org.junit.Before; 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..ce83032cb5 --- /dev/null +++ b/spring-thymeleaf-2/README.md @@ -0,0 +1,5 @@ +## 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) +- [Spring Request Parameters with Thymeleaf](https://www.baeldung.com/spring-thymeleaf-request-parameters) 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/src/main/java/com/baeldung/thymeleaf/controller/ParticipantController.java b/spring-thymeleaf-2/src/main/java/com/baeldung/thymeleaf/controller/ParticipantController.java similarity index 91% rename from spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/controller/ParticipantController.java rename to spring-thymeleaf-2/src/main/java/com/baeldung/thymeleaf/controller/ParticipantController.java index eebe37e000..9a354e709c 100644 --- a/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/controller/ParticipantController.java +++ b/spring-thymeleaf-2/src/main/java/com/baeldung/thymeleaf/controller/ParticipantController.java @@ -1,4 +1,4 @@ -package com.example.demo; +package com.baeldung.thymeleaf.controller; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; @@ -12,7 +12,7 @@ import static java.util.Arrays.asList; @Controller public class ParticipantController { - @RequestMapping("/") + @RequestMapping("/participants") public String index( @RequestParam(value = "participant", required = false) String participant, @RequestParam(value = "country", required = false) String country, 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/src/main/resources/templates/participants.html b/spring-thymeleaf-2/src/main/resources/templates-2/participants.html similarity index 86% rename from spring-thymeleaf/src/main/resources/templates/participants.html rename to spring-thymeleaf-2/src/main/resources/templates-2/participants.html index 8d4e552093..f7e017e777 100644 --- a/spring-thymeleaf/src/main/resources/templates/participants.html +++ b/spring-thymeleaf-2/src/main/resources/templates-2/participants.html @@ -4,7 +4,7 @@

    Enter participant

    -
    +