findMiddleElementFromHead1PassIteratively(Node head) {
+ if (head == null) {
+ return Optional.empty();
+ }
+
+ Node slowPointer = head;
+ Node fastPointer = head;
+
+ while (fastPointer.hasNext() && fastPointer.next()
+ .hasNext()) {
+ fastPointer = fastPointer.next()
+ .next();
+ slowPointer = slowPointer.next();
+ }
+
+ return Optional.ofNullable(slowPointer.data());
+ }
+
+ private static class MiddleAuxRecursion {
+ Node middle;
+ int length = 0;
+ }
+
+}
diff --git a/algorithms/src/main/java/com/baeldung/algorithms/middleelementlookup/Node.java b/algorithms/src/main/java/com/baeldung/algorithms/middleelementlookup/Node.java
new file mode 100644
index 0000000000..2a594937e3
--- /dev/null
+++ b/algorithms/src/main/java/com/baeldung/algorithms/middleelementlookup/Node.java
@@ -0,0 +1,34 @@
+package com.baeldung.algorithms.middleelementlookup;
+
+public class Node {
+ private Node next;
+ private String data;
+
+ public Node(String data) {
+ this.data = data;
+ }
+
+ public String data() {
+ return data;
+ }
+
+ public void setData(String data) {
+ this.data = data;
+ }
+
+ public boolean hasNext() {
+ return next != null;
+ }
+
+ public Node next() {
+ return next;
+ }
+
+ public void setNext(Node next) {
+ this.next = next;
+ }
+
+ public String toString() {
+ return this.data;
+ }
+}
diff --git a/algorithms/src/main/java/com/baeldung/algorithms/multiswarm/Constants.java b/algorithms/src/main/java/com/baeldung/algorithms/multiswarm/Constants.java
new file mode 100644
index 0000000000..b646c686b2
--- /dev/null
+++ b/algorithms/src/main/java/com/baeldung/algorithms/multiswarm/Constants.java
@@ -0,0 +1,47 @@
+package com.baeldung.algorithms.multiswarm;
+
+/**
+ * Constants used by the Multi-swarm optimization algorithms.
+ *
+ * @author Donato Rimenti
+ *
+ */
+public class Constants {
+
+ /**
+ * The inertia factor encourages a particle to continue moving in its
+ * current direction.
+ */
+ public static final double INERTIA_FACTOR = 0.729;
+
+ /**
+ * The cognitive weight encourages a particle to move toward its historical
+ * best-known position.
+ */
+ public static final double COGNITIVE_WEIGHT = 1.49445;
+
+ /**
+ * The social weight encourages a particle to move toward the best-known
+ * position found by any of the particle’s swarm-mates.
+ */
+ public static final double SOCIAL_WEIGHT = 1.49445;
+
+ /**
+ * The global weight encourages a particle to move toward the best-known
+ * position found by any particle in any swarm.
+ */
+ public static final double GLOBAL_WEIGHT = 0.3645;
+
+ /**
+ * Upper bound for the random generation. We use it to reduce the
+ * computation time since we can rawly estimate it.
+ */
+ public static final int PARTICLE_UPPER_BOUND = 10000000;
+
+ /**
+ * Private constructor for utility class.
+ */
+ private Constants() {
+ }
+
+}
diff --git a/algorithms/src/main/java/com/baeldung/algorithms/multiswarm/FitnessFunction.java b/algorithms/src/main/java/com/baeldung/algorithms/multiswarm/FitnessFunction.java
new file mode 100644
index 0000000000..2d86ec8d94
--- /dev/null
+++ b/algorithms/src/main/java/com/baeldung/algorithms/multiswarm/FitnessFunction.java
@@ -0,0 +1,21 @@
+package com.baeldung.algorithms.multiswarm;
+
+/**
+ * Interface for a fitness function, used to decouple the main algorithm logic
+ * from the specific problem solution.
+ *
+ * @author Donato Rimenti
+ *
+ */
+public interface FitnessFunction {
+
+ /**
+ * Returns the fitness of a particle given its position.
+ *
+ * @param particlePosition
+ * the position of the particle
+ * @return the fitness of the particle
+ */
+ public double getFitness(long[] particlePosition);
+
+}
diff --git a/algorithms/src/main/java/com/baeldung/algorithms/multiswarm/Multiswarm.java b/algorithms/src/main/java/com/baeldung/algorithms/multiswarm/Multiswarm.java
new file mode 100644
index 0000000000..ef60726278
--- /dev/null
+++ b/algorithms/src/main/java/com/baeldung/algorithms/multiswarm/Multiswarm.java
@@ -0,0 +1,227 @@
+package com.baeldung.algorithms.multiswarm;
+
+import java.util.Arrays;
+import java.util.Random;
+
+/**
+ * Represents a collection of {@link Swarm}.
+ *
+ * @author Donato Rimenti
+ *
+ */
+public class Multiswarm {
+
+ /**
+ * The swarms managed by this multiswarm.
+ */
+ private Swarm[] swarms;
+
+ /**
+ * The best position found within all the {@link #swarms}.
+ */
+ private long[] bestPosition;
+
+ /**
+ * The best fitness score found within all the {@link #swarms}.
+ */
+ private double bestFitness = Double.NEGATIVE_INFINITY;
+
+ /**
+ * A random generator.
+ */
+ private Random random = new Random();
+
+ /**
+ * The fitness function used to determine how good is a particle.
+ */
+ private FitnessFunction fitnessFunction;
+
+ /**
+ * Instantiates a new Multiswarm.
+ *
+ * @param numSwarms
+ * the number of {@link #swarms}
+ * @param particlesPerSwarm
+ * the number of particle for each {@link #swarms}
+ * @param fitnessFunction
+ * the {@link #fitnessFunction}
+ */
+ public Multiswarm(int numSwarms, int particlesPerSwarm, FitnessFunction fitnessFunction) {
+ this.fitnessFunction = fitnessFunction;
+ this.swarms = new Swarm[numSwarms];
+ for (int i = 0; i < numSwarms; i++) {
+ swarms[i] = new Swarm(particlesPerSwarm);
+ }
+ }
+
+ /**
+ * Main loop of the algorithm. Iterates all particles of all
+ * {@link #swarms}. For each particle, computes the new fitness and checks
+ * if a new best position has been found among itself, the swarm and all the
+ * swarms and finally updates the particle position and speed.
+ */
+ public void mainLoop() {
+ for (Swarm swarm : swarms) {
+ for (Particle particle : swarm.getParticles()) {
+
+ long[] particleOldPosition = particle.getPosition().clone();
+
+ // Calculate the particle fitness.
+ particle.setFitness(fitnessFunction.getFitness(particleOldPosition));
+
+ // Check if a new best position has been found for the particle
+ // itself, within the swarm and the multiswarm.
+ if (particle.getFitness() > particle.getBestFitness()) {
+ particle.setBestFitness(particle.getFitness());
+ particle.setBestPosition(particleOldPosition);
+
+ if (particle.getFitness() > swarm.getBestFitness()) {
+ swarm.setBestFitness(particle.getFitness());
+ swarm.setBestPosition(particleOldPosition);
+
+ if (swarm.getBestFitness() > bestFitness) {
+ bestFitness = swarm.getBestFitness();
+ bestPosition = swarm.getBestPosition().clone();
+ }
+
+ }
+ }
+
+ // Updates the particle position by adding the speed to the
+ // actual position.
+ long[] position = particle.getPosition();
+ long[] speed = particle.getSpeed();
+
+ position[0] += speed[0];
+ position[1] += speed[1];
+
+ // Updates the particle speed.
+ speed[0] = getNewParticleSpeedForIndex(particle, swarm, 0);
+ speed[1] = getNewParticleSpeedForIndex(particle, swarm, 1);
+ }
+ }
+ }
+
+ /**
+ * Computes a new speed for a given particle of a given swarm on a given
+ * axis. The new speed is computed using the formula:
+ *
+ *
+ * ({@link Constants#INERTIA_FACTOR} * {@link Particle#getSpeed()}) +
+ * (({@link Constants#COGNITIVE_WEIGHT} * random(0,1)) * ({@link Particle#getBestPosition()} - {@link Particle#getPosition()})) +
+ * (({@link Constants#SOCIAL_WEIGHT} * random(0,1)) * ({@link Swarm#getBestPosition()} - {@link Particle#getPosition()})) +
+ * (({@link Constants#GLOBAL_WEIGHT} * random(0,1)) * ({@link #bestPosition} - {@link Particle#getPosition()}))
+ *
+ *
+ * @param particle
+ * the particle whose new speed needs to be computed
+ * @param swarm
+ * the swarm which contains the particle
+ * @param index
+ * the index of the particle axis whose speeds needs to be
+ * computed
+ * @return the new speed of the particle passed on the given axis
+ */
+ private int getNewParticleSpeedForIndex(Particle particle, Swarm swarm, int index) {
+ return (int) ((Constants.INERTIA_FACTOR * particle.getSpeed()[index])
+ + (randomizePercentage(Constants.COGNITIVE_WEIGHT)
+ * (particle.getBestPosition()[index] - particle.getPosition()[index]))
+ + (randomizePercentage(Constants.SOCIAL_WEIGHT)
+ * (swarm.getBestPosition()[index] - particle.getPosition()[index]))
+ + (randomizePercentage(Constants.GLOBAL_WEIGHT)
+ * (bestPosition[index] - particle.getPosition()[index])));
+ }
+
+ /**
+ * Returns a random number between 0 and the value passed as argument.
+ *
+ * @param value
+ * the value to randomize
+ * @return a random value between 0 and the one passed as argument
+ */
+ private double randomizePercentage(double value) {
+ return random.nextDouble() * value;
+ }
+
+ /**
+ * Gets the {@link #bestPosition}.
+ *
+ * @return the {@link #bestPosition}
+ */
+ public long[] getBestPosition() {
+ return bestPosition;
+ }
+
+ /**
+ * Gets the {@link #bestFitness}.
+ *
+ * @return the {@link #bestFitness}
+ */
+ public double getBestFitness() {
+ return bestFitness;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ long temp;
+ temp = Double.doubleToLongBits(bestFitness);
+ result = prime * result + (int) (temp ^ (temp >>> 32));
+ result = prime * result + Arrays.hashCode(bestPosition);
+ result = prime * result + ((fitnessFunction == null) ? 0 : fitnessFunction.hashCode());
+ result = prime * result + ((random == null) ? 0 : random.hashCode());
+ result = prime * result + Arrays.hashCode(swarms);
+ return result;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ Multiswarm other = (Multiswarm) obj;
+ if (Double.doubleToLongBits(bestFitness) != Double.doubleToLongBits(other.bestFitness))
+ return false;
+ if (!Arrays.equals(bestPosition, other.bestPosition))
+ return false;
+ if (fitnessFunction == null) {
+ if (other.fitnessFunction != null)
+ return false;
+ } else if (!fitnessFunction.equals(other.fitnessFunction))
+ return false;
+ if (random == null) {
+ if (other.random != null)
+ return false;
+ } else if (!random.equals(other.random))
+ return false;
+ if (!Arrays.equals(swarms, other.swarms))
+ return false;
+ return true;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return "Multiswarm [swarms=" + Arrays.toString(swarms) + ", bestPosition=" + Arrays.toString(bestPosition)
+ + ", bestFitness=" + bestFitness + ", random=" + random + ", fitnessFunction=" + fitnessFunction + "]";
+ }
+
+}
diff --git a/algorithms/src/main/java/com/baeldung/algorithms/multiswarm/Particle.java b/algorithms/src/main/java/com/baeldung/algorithms/multiswarm/Particle.java
new file mode 100644
index 0000000000..5930a94267
--- /dev/null
+++ b/algorithms/src/main/java/com/baeldung/algorithms/multiswarm/Particle.java
@@ -0,0 +1,204 @@
+package com.baeldung.algorithms.multiswarm;
+
+import java.util.Arrays;
+
+/**
+ * Represents a particle, the basic component of a {@link Swarm}.
+ *
+ * @author Donato Rimenti
+ *
+ */
+public class Particle {
+
+ /**
+ * The current position of this particle.
+ */
+ private long[] position;
+
+ /**
+ * The speed of this particle.
+ */
+ private long[] speed;
+
+ /**
+ * The fitness of this particle for the current position.
+ */
+ private double fitness;
+
+ /**
+ * The best position found by this particle.
+ */
+ private long[] bestPosition;
+
+ /**
+ * The best fitness found by this particle.
+ */
+ private double bestFitness = Double.NEGATIVE_INFINITY;
+
+ /**
+ * Instantiates a new Particle.
+ *
+ * @param initialPosition
+ * the initial {@link #position}
+ * @param initialSpeed
+ * the initial {@link #speed}
+ */
+ public Particle(long[] initialPosition, long[] initialSpeed) {
+ this.position = initialPosition;
+ this.speed = initialSpeed;
+ }
+
+ /**
+ * Gets the {@link #position}.
+ *
+ * @return the {@link #position}
+ */
+ public long[] getPosition() {
+ return position;
+ }
+
+ /**
+ * Gets the {@link #speed}.
+ *
+ * @return the {@link #speed}
+ */
+ public long[] getSpeed() {
+ return speed;
+ }
+
+ /**
+ * Gets the {@link #fitness}.
+ *
+ * @return the {@link #fitness}
+ */
+ public double getFitness() {
+ return fitness;
+ }
+
+ /**
+ * Gets the {@link #bestPosition}.
+ *
+ * @return the {@link #bestPosition}
+ */
+ public long[] getBestPosition() {
+ return bestPosition;
+ }
+
+ /**
+ * Gets the {@link #bestFitness}.
+ *
+ * @return the {@link #bestFitness}
+ */
+ public double getBestFitness() {
+ return bestFitness;
+ }
+
+ /**
+ * Sets the {@link #position}.
+ *
+ * @param position
+ * the new {@link #position}
+ */
+ public void setPosition(long[] position) {
+ this.position = position;
+ }
+
+ /**
+ * Sets the {@link #speed}.
+ *
+ * @param speed
+ * the new {@link #speed}
+ */
+ public void setSpeed(long[] speed) {
+ this.speed = speed;
+ }
+
+ /**
+ * Sets the {@link #fitness}.
+ *
+ * @param fitness
+ * the new {@link #fitness}
+ */
+ public void setFitness(double fitness) {
+ this.fitness = fitness;
+ }
+
+ /**
+ * Sets the {@link #bestPosition}.
+ *
+ * @param bestPosition
+ * the new {@link #bestPosition}
+ */
+ public void setBestPosition(long[] bestPosition) {
+ this.bestPosition = bestPosition;
+ }
+
+ /**
+ * Sets the {@link #bestFitness}.
+ *
+ * @param bestFitness
+ * the new {@link #bestFitness}
+ */
+ public void setBestFitness(double bestFitness) {
+ this.bestFitness = bestFitness;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ long temp;
+ temp = Double.doubleToLongBits(bestFitness);
+ result = prime * result + (int) (temp ^ (temp >>> 32));
+ result = prime * result + Arrays.hashCode(bestPosition);
+ temp = Double.doubleToLongBits(fitness);
+ result = prime * result + (int) (temp ^ (temp >>> 32));
+ result = prime * result + Arrays.hashCode(position);
+ result = prime * result + Arrays.hashCode(speed);
+ return result;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ Particle other = (Particle) obj;
+ if (Double.doubleToLongBits(bestFitness) != Double.doubleToLongBits(other.bestFitness))
+ return false;
+ if (!Arrays.equals(bestPosition, other.bestPosition))
+ return false;
+ if (Double.doubleToLongBits(fitness) != Double.doubleToLongBits(other.fitness))
+ return false;
+ if (!Arrays.equals(position, other.position))
+ return false;
+ if (!Arrays.equals(speed, other.speed))
+ return false;
+ return true;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return "Particle [position=" + Arrays.toString(position) + ", speed=" + Arrays.toString(speed) + ", fitness="
+ + fitness + ", bestPosition=" + Arrays.toString(bestPosition) + ", bestFitness=" + bestFitness + "]";
+ }
+
+}
diff --git a/algorithms/src/main/java/com/baeldung/algorithms/multiswarm/Swarm.java b/algorithms/src/main/java/com/baeldung/algorithms/multiswarm/Swarm.java
new file mode 100644
index 0000000000..e6d37bb7e6
--- /dev/null
+++ b/algorithms/src/main/java/com/baeldung/algorithms/multiswarm/Swarm.java
@@ -0,0 +1,155 @@
+package com.baeldung.algorithms.multiswarm;
+
+import java.util.Arrays;
+import java.util.Random;
+
+/**
+ * Represents a collection of {@link Particle}.
+ *
+ * @author Donato Rimenti
+ *
+ */
+public class Swarm {
+
+ /**
+ * The particles of this swarm.
+ */
+ private Particle[] particles;
+
+ /**
+ * The best position found within the particles of this swarm.
+ */
+ private long[] bestPosition;
+
+ /**
+ * The best fitness score found within the particles of this swarm.
+ */
+ private double bestFitness = Double.NEGATIVE_INFINITY;
+
+ /**
+ * A random generator.
+ */
+ private Random random = new Random();
+
+ /**
+ * Instantiates a new Swarm.
+ *
+ * @param numParticles
+ * the number of particles of the swarm
+ */
+ public Swarm(int numParticles) {
+ particles = new Particle[numParticles];
+ for (int i = 0; i < numParticles; i++) {
+ long[] initialParticlePosition = { random.nextInt(Constants.PARTICLE_UPPER_BOUND),
+ random.nextInt(Constants.PARTICLE_UPPER_BOUND) };
+ long[] initialParticleSpeed = { random.nextInt(Constants.PARTICLE_UPPER_BOUND),
+ random.nextInt(Constants.PARTICLE_UPPER_BOUND) };
+ particles[i] = new Particle(initialParticlePosition, initialParticleSpeed);
+ }
+ }
+
+ /**
+ * Gets the {@link #particles}.
+ *
+ * @return the {@link #particles}
+ */
+ public Particle[] getParticles() {
+ return particles;
+ }
+
+ /**
+ * Gets the {@link #bestPosition}.
+ *
+ * @return the {@link #bestPosition}
+ */
+ public long[] getBestPosition() {
+ return bestPosition;
+ }
+
+ /**
+ * Gets the {@link #bestFitness}.
+ *
+ * @return the {@link #bestFitness}
+ */
+ public double getBestFitness() {
+ return bestFitness;
+ }
+
+ /**
+ * Sets the {@link #bestPosition}.
+ *
+ * @param bestPosition
+ * the new {@link #bestPosition}
+ */
+ public void setBestPosition(long[] bestPosition) {
+ this.bestPosition = bestPosition;
+ }
+
+ /**
+ * Sets the {@link #bestFitness}.
+ *
+ * @param bestFitness
+ * the new {@link #bestFitness}
+ */
+ public void setBestFitness(double bestFitness) {
+ this.bestFitness = bestFitness;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ long temp;
+ temp = Double.doubleToLongBits(bestFitness);
+ result = prime * result + (int) (temp ^ (temp >>> 32));
+ result = prime * result + Arrays.hashCode(bestPosition);
+ result = prime * result + Arrays.hashCode(particles);
+ result = prime * result + ((random == null) ? 0 : random.hashCode());
+ return result;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ Swarm other = (Swarm) obj;
+ if (Double.doubleToLongBits(bestFitness) != Double.doubleToLongBits(other.bestFitness))
+ return false;
+ if (!Arrays.equals(bestPosition, other.bestPosition))
+ return false;
+ if (!Arrays.equals(particles, other.particles))
+ return false;
+ if (random == null) {
+ if (other.random != null)
+ return false;
+ } else if (!random.equals(other.random))
+ return false;
+ return true;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return "Swarm [particles=" + Arrays.toString(particles) + ", bestPosition=" + Arrays.toString(bestPosition)
+ + ", bestFitness=" + bestFitness + ", random=" + random + "]";
+ }
+
+}
diff --git a/algorithms/src/main/java/com/baeldung/algorithms/numberwordconverter/NumberWordConverter.java b/algorithms/src/main/java/com/baeldung/algorithms/numberwordconverter/NumberWordConverter.java
new file mode 100644
index 0000000000..0fe2960f96
--- /dev/null
+++ b/algorithms/src/main/java/com/baeldung/algorithms/numberwordconverter/NumberWordConverter.java
@@ -0,0 +1,75 @@
+package com.baeldung.algorithms.numberwordconverter;
+
+import java.math.BigDecimal;
+
+import pl.allegro.finance.tradukisto.MoneyConverters;
+
+public class NumberWordConverter {
+
+ public static final String INVALID_INPUT_GIVEN = "Invalid input given";
+
+ public static final String[] ones = { "", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen" };
+
+ public static final String[] tens = {
+ "", // 0
+ "", // 1
+ "twenty", // 2
+ "thirty", // 3
+ "forty", // 4
+ "fifty", // 5
+ "sixty", // 6
+ "seventy", // 7
+ "eighty", // 8
+ "ninety" // 9
+ };
+
+ public static String getMoneyIntoWords(String input) {
+ MoneyConverters converter = MoneyConverters.ENGLISH_BANKING_MONEY_VALUE;
+ return converter.asWords(new BigDecimal(input));
+ }
+
+ public static String getMoneyIntoWords(final double money) {
+ long dollar = (long) money;
+ long cents = Math.round((money - dollar) * 100);
+ if (money == 0D) {
+ return "";
+ }
+ if (money < 0) {
+ return INVALID_INPUT_GIVEN;
+ }
+ String dollarPart = "";
+ if (dollar > 0) {
+ dollarPart = convert(dollar) + " dollar" + (dollar == 1 ? "" : "s");
+ }
+ String centsPart = "";
+ if (cents > 0) {
+ if (dollarPart.length() > 0) {
+ centsPart = " and ";
+ }
+ centsPart += convert(cents) + " cent" + (cents == 1 ? "" : "s");
+ }
+ return dollarPart + centsPart;
+ }
+
+ private static String convert(final long n) {
+ if (n < 0) {
+ return INVALID_INPUT_GIVEN;
+ }
+ if (n < 20) {
+ return ones[(int) n];
+ }
+ if (n < 100) {
+ return tens[(int) n / 10] + ((n % 10 != 0) ? " " : "") + ones[(int) n % 10];
+ }
+ if (n < 1000) {
+ return ones[(int) n / 100] + " hundred" + ((n % 100 != 0) ? " " : "") + convert(n % 100);
+ }
+ if (n < 1_000_000) {
+ return convert(n / 1000) + " thousand" + ((n % 1000 != 0) ? " " : "") + convert(n % 1000);
+ }
+ if (n < 1_000_000_000) {
+ return convert(n / 1_000_000) + " million" + ((n % 1_000_000 != 0) ? " " : "") + convert(n % 1_000_000);
+ }
+ return convert(n / 1_000_000_000) + " billion" + ((n % 1_000_000_000 != 0) ? " " : "") + convert(n % 1_000_000_000);
+ }
+}
\ No newline at end of file
diff --git a/algorithms/src/main/java/com/baeldung/algorithms/prime/PrimeGenerator.java b/algorithms/src/main/java/com/baeldung/algorithms/prime/PrimeGenerator.java
deleted file mode 100644
index 48d51a8848..0000000000
--- a/algorithms/src/main/java/com/baeldung/algorithms/prime/PrimeGenerator.java
+++ /dev/null
@@ -1,59 +0,0 @@
-package com.baeldung.algorithms.prime;
-
-import java.util.Arrays;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.stream.Collectors;
-import java.util.stream.IntStream;
-
-public class PrimeGenerator {
- public static List sieveOfEratosthenes(int n) {
- final boolean prime[] = new boolean[n + 1];
- Arrays.fill(prime, true);
-
- for (int p = 2; p * p <= n; p++) {
- if (prime[p]) {
- for (int i = p * 2; i <= n; i += p)
- prime[i] = false;
- }
- }
-
- final List primes = new LinkedList<>();
- for (int i = 2; i <= n; i++) {
- if (prime[i])
- primes.add(i);
- }
- return primes;
- }
-
- public static List primeNumbersBruteForce(int max) {
- final List primeNumbers = new LinkedList();
- for (int i = 2; i <= max; i++) {
- if (isPrimeBruteForce(i)) {
- primeNumbers.add(i);
- }
- }
- return primeNumbers;
- }
-
- private static boolean isPrimeBruteForce(int x) {
- for (int i = 2; i < x; i++) {
- if (x % i == 0) {
- return false;
- }
- }
- return true;
- }
-
- public static List primeNumbersTill(int max) {
- return IntStream.rangeClosed(2, max)
- .filter(x -> isPrime(x))
- .boxed()
- .collect(Collectors.toList());
- }
-
- private static boolean isPrime(int x) {
- return IntStream.rangeClosed(2, (int) (Math.sqrt(x)))
- .allMatch(n -> x % n != 0);
- }
-}
diff --git a/algorithms/src/main/java/com/baeldung/algorithms/quicksort/QuickSort.java b/algorithms/src/main/java/com/baeldung/algorithms/quicksort/QuickSort.java
new file mode 100644
index 0000000000..e113cc3242
--- /dev/null
+++ b/algorithms/src/main/java/com/baeldung/algorithms/quicksort/QuickSort.java
@@ -0,0 +1,39 @@
+package com.baeldung.algorithms.quicksort;
+
+public class QuickSort {
+
+ public static void quickSort(int arr[], int begin, int end)
+ {
+ if (begin < end) {
+ int partitionIndex = partition(arr, begin, end);
+
+ // Recursively sort elements of the 2 sub-arrays
+ quickSort(arr, begin, partitionIndex-1);
+ quickSort(arr, partitionIndex+1, end);
+ }
+ }
+
+ private static int partition(int arr[], int begin, int end)
+ {
+ int pivot = arr[end];
+ int i = (begin-1);
+
+ for (int j=begin; j other.topRight.getY()) {
+ return false;
+ }
+ // one rectangle is to the left of the other
+ if (this.topRight.getX() < other.bottomLeft.getX() || this.bottomLeft.getX() > other.topRight.getX()) {
+ return false;
+ }
+ return true;
+ }
+}
diff --git a/algorithms/src/main/java/com/baeldung/algorithms/romannumerals/RomanArabicConverter.java b/algorithms/src/main/java/com/baeldung/algorithms/romannumerals/RomanArabicConverter.java
new file mode 100644
index 0000000000..ab0922ecf4
--- /dev/null
+++ b/algorithms/src/main/java/com/baeldung/algorithms/romannumerals/RomanArabicConverter.java
@@ -0,0 +1,52 @@
+package com.baeldung.algorithms.romannumerals;
+
+import java.util.List;
+
+class RomanArabicConverter {
+
+ public static int romanToArabic(String input) {
+ String romanNumeral = input.toUpperCase();
+ int result = 0;
+
+ List romanNumerals = RomanNumeral.getReverseSortedValues();
+
+ int i = 0;
+
+ while ((romanNumeral.length() > 0) && (i < romanNumerals.size())) {
+ RomanNumeral symbol = romanNumerals.get(i);
+ if (romanNumeral.startsWith(symbol.name())) {
+ result += symbol.getValue();
+ romanNumeral = romanNumeral.substring(symbol.name().length());
+ } else {
+ i++;
+ }
+ }
+ if (romanNumeral.length() > 0) {
+ throw new IllegalArgumentException(input + " cannot be converted to a Roman Numeral");
+ }
+
+ return result;
+ }
+
+ public static String arabicToRoman(int number) {
+ if ((number <= 0) || (number > 4000)) {
+ throw new IllegalArgumentException(number + " is not in range (0,4000]");
+ }
+
+ List romanNumerals = RomanNumeral.getReverseSortedValues();
+
+ int i = 0;
+ StringBuilder sb = new StringBuilder();
+
+ while (number > 0 && i < romanNumerals.size()) {
+ RomanNumeral currentSymbol = romanNumerals.get(i);
+ if (currentSymbol.getValue() <= number) {
+ sb.append(currentSymbol.name());
+ number -= currentSymbol.getValue();
+ } else {
+ i++;
+ }
+ }
+ return sb.toString();
+ }
+}
diff --git a/algorithms/src/main/java/com/baeldung/algorithms/romannumerals/RomanNumeral.java b/algorithms/src/main/java/com/baeldung/algorithms/romannumerals/RomanNumeral.java
new file mode 100644
index 0000000000..219f0b5090
--- /dev/null
+++ b/algorithms/src/main/java/com/baeldung/algorithms/romannumerals/RomanNumeral.java
@@ -0,0 +1,26 @@
+package com.baeldung.algorithms.romannumerals;
+
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.List;
+import java.util.stream.Collectors;
+
+enum RomanNumeral {
+ I(1), IV(4), V(5), IX(9), X(10), XL(40), L(50), XC(90), C(100), CD(400), D(500), CM(900), M(1000);
+
+ private int value;
+
+ RomanNumeral(int value) {
+ this.value = value;
+ }
+
+ public int getValue() {
+ return value;
+ }
+
+ public static List getReverseSortedValues() {
+ return Arrays.stream(values())
+ .sorted(Comparator.comparing((RomanNumeral e) -> e.value).reversed())
+ .collect(Collectors.toList());
+ }
+}
diff --git a/algorithms/src/main/java/com/baeldung/algorithms/string/EnglishAlphabetLetters.java b/algorithms/src/main/java/com/baeldung/algorithms/string/EnglishAlphabetLetters.java
new file mode 100644
index 0000000000..2dd1fdcb75
--- /dev/null
+++ b/algorithms/src/main/java/com/baeldung/algorithms/string/EnglishAlphabetLetters.java
@@ -0,0 +1,35 @@
+package com.baeldung.algorithms.string;
+
+public class EnglishAlphabetLetters {
+
+ public static boolean checkStringForAllTheLetters(String input) {
+ boolean[] visited = new boolean[26];
+
+ int index = 0;
+
+ for (int id = 0; id < input.length(); id++) {
+ if ('a' <= input.charAt(id) && input.charAt(id) <= 'z') {
+ index = input.charAt(id) - 'a';
+ } else if ('A' <= input.charAt(id) && input.charAt(id) <= 'Z') {
+ index = input.charAt(id) - 'A';
+ }
+ visited[index] = true;
+ }
+
+ for (int id = 0; id < 26; id++) {
+ if (!visited[id]) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public static boolean checkStringForAllLetterUsingStream(String input) {
+ long c = input.toLowerCase().chars().filter(ch -> ch >= 'a' && ch <= 'z').distinct().count();
+ return c == 26;
+ }
+
+ public static void main(String[] args) {
+ checkStringForAllLetterUsingStream("intit");
+ }
+}
\ No newline at end of file
diff --git a/algorithms/src/main/java/com/baeldung/algorithms/sudoku/BacktrackingAlgorithm.java b/algorithms/src/main/java/com/baeldung/algorithms/sudoku/BacktrackingAlgorithm.java
new file mode 100644
index 0000000000..4b37558aab
--- /dev/null
+++ b/algorithms/src/main/java/com/baeldung/algorithms/sudoku/BacktrackingAlgorithm.java
@@ -0,0 +1,104 @@
+package com.baeldung.algorithms.sudoku;
+
+import java.util.stream.IntStream;
+
+public class BacktrackingAlgorithm {
+
+ private static final int BOARD_SIZE = 9;
+ private static final int SUBSECTION_SIZE = 3;
+ private static final int BOARD_START_INDEX = 0;
+
+ private static final int NO_VALUE = 0;
+ private static final int MIN_VALUE = 1;
+ private static final int MAX_VALUE = 9;
+
+ private static int[][] board = {
+ {8, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 3, 6, 0, 0, 0, 0, 0},
+ {0, 7, 0, 0, 9, 0, 2, 0, 0},
+ {0, 5, 0, 0, 0, 7, 0, 0, 0},
+ {0, 0, 0, 0, 4, 5, 7, 0, 0},
+ {0, 0, 0, 1, 0, 0, 0, 3, 0},
+ {0, 0, 1, 0, 0, 0, 0, 6, 8},
+ {0, 0, 8, 5, 0, 0, 0, 1, 0},
+ {0, 9, 0, 0, 0, 0, 4, 0, 0}
+ };
+
+ public static void main(String[] args) {
+ BacktrackingAlgorithm solver = new BacktrackingAlgorithm();
+ solver.solve(board);
+ solver.printBoard();
+ }
+
+ private void printBoard() {
+ for (int row = BOARD_START_INDEX; row < BOARD_SIZE; row++) {
+ for (int column = BOARD_START_INDEX; column < BOARD_SIZE; column++) {
+ System.out.print(board[row][column] + " ");
+ }
+ System.out.println();
+ }
+ }
+
+ private boolean solve(int[][] board) {
+ for (int row = BOARD_START_INDEX; row < BOARD_SIZE; row++) {
+ for (int column = BOARD_START_INDEX; column < BOARD_SIZE; column++) {
+ if (board[row][column] == NO_VALUE) {
+ for (int k = MIN_VALUE; k <= MAX_VALUE; k++) {
+ board[row][column] = k;
+ if (isValid(board, row, column) && solve(board)) {
+ return true;
+ }
+ board[row][column] = NO_VALUE;
+ }
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ private boolean isValid(int[][] board, int row, int column) {
+ return rowConstraint(board, row) &&
+ columnConstraint(board, column) &&
+ subsectionConstraint(board, row, column);
+ }
+
+ private boolean subsectionConstraint(int[][] board, int row, int column) {
+ boolean[] constraint = new boolean[BOARD_SIZE];
+ int subsectionRowStart = (row / SUBSECTION_SIZE) * SUBSECTION_SIZE;
+ int subsectionRowEnd = subsectionRowStart + SUBSECTION_SIZE;
+
+ int subsectionColumnStart = (column / SUBSECTION_SIZE) * SUBSECTION_SIZE;
+ int subsectionColumnEnd = subsectionColumnStart + SUBSECTION_SIZE;
+
+ for (int r = subsectionRowStart; r < subsectionRowEnd; r++) {
+ for (int c = subsectionColumnStart; c < subsectionColumnEnd; c++) {
+ if (!checkConstraint(board, r, constraint, c)) return false;
+ }
+ }
+ return true;
+ }
+
+ private boolean columnConstraint(int[][] board, int column) {
+ boolean[] constraint = new boolean[BOARD_SIZE];
+ return IntStream.range(BOARD_START_INDEX, BOARD_SIZE)
+ .allMatch(row -> checkConstraint(board, row, constraint, column));
+ }
+
+ private boolean rowConstraint(int[][] board, int row) {
+ boolean[] constraint = new boolean[BOARD_SIZE];
+ return IntStream.range(BOARD_START_INDEX, BOARD_SIZE)
+ .allMatch(column -> checkConstraint(board, row, constraint, column));
+ }
+
+ private boolean checkConstraint(int[][] board, int row, boolean[] constraint, int column) {
+ if (board[row][column] != NO_VALUE) {
+ if (!constraint[board[row][column] - 1]) {
+ constraint[board[row][column] - 1] = true;
+ } else {
+ return false;
+ }
+ }
+ return true;
+ }
+}
diff --git a/algorithms/src/main/java/com/baeldung/algorithms/sudoku/ColumnNode.java b/algorithms/src/main/java/com/baeldung/algorithms/sudoku/ColumnNode.java
new file mode 100644
index 0000000000..46995ca42f
--- /dev/null
+++ b/algorithms/src/main/java/com/baeldung/algorithms/sudoku/ColumnNode.java
@@ -0,0 +1,33 @@
+package com.baeldung.algorithms.sudoku;
+
+class ColumnNode extends DancingNode {
+ int size;
+ String name;
+
+ ColumnNode(String n) {
+ super();
+ size = 0;
+ name = n;
+ C = this;
+ }
+
+ void cover() {
+ unlinkLR();
+ for (DancingNode i = this.D; i != this; i = i.D) {
+ for (DancingNode j = i.R; j != i; j = j.R) {
+ j.unlinkUD();
+ j.C.size--;
+ }
+ }
+ }
+
+ void uncover() {
+ for (DancingNode i = this.U; i != this; i = i.U) {
+ for (DancingNode j = i.L; j != i; j = j.L) {
+ j.C.size++;
+ j.relinkUD();
+ }
+ }
+ relinkLR();
+ }
+}
\ No newline at end of file
diff --git a/algorithms/src/main/java/com/baeldung/algorithms/sudoku/DancingLinks.java b/algorithms/src/main/java/com/baeldung/algorithms/sudoku/DancingLinks.java
new file mode 100644
index 0000000000..d3cbb2bd02
--- /dev/null
+++ b/algorithms/src/main/java/com/baeldung/algorithms/sudoku/DancingLinks.java
@@ -0,0 +1,133 @@
+package com.baeldung.algorithms.sudoku;
+
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+
+public class DancingLinks {
+
+ private ColumnNode header;
+ private List answer;
+
+ private void search(int k) {
+ if (header.R == header) {
+ handleSolution(answer);
+ } else {
+ ColumnNode c = selectColumnNodeHeuristic();
+ c.cover();
+
+ for (DancingNode r = c.D; r != c; r = r.D) {
+ answer.add(r);
+
+ for (DancingNode j = r.R; j != r; j = j.R) {
+ j.C.cover();
+ }
+
+ search(k + 1);
+
+ r = answer.remove(answer.size() - 1);
+ c = r.C;
+
+ for (DancingNode j = r.L; j != r; j = j.L) {
+ j.C.uncover();
+ }
+ }
+ c.uncover();
+ }
+ }
+
+ private ColumnNode selectColumnNodeHeuristic() {
+ int min = Integer.MAX_VALUE;
+ ColumnNode ret = null;
+ for (ColumnNode c = (ColumnNode) header.R; c != header; c = (ColumnNode) c.R) {
+ if (c.size < min) {
+ min = c.size;
+ ret = c;
+ }
+ }
+ return ret;
+ }
+
+ private ColumnNode makeDLXBoard(boolean[][] grid) {
+ final int COLS = grid[0].length;
+
+ ColumnNode headerNode = new ColumnNode("header");
+ List columnNodes = new ArrayList<>();
+
+ for (int i = 0; i < COLS; i++) {
+ ColumnNode n = new ColumnNode(Integer.toString(i));
+ columnNodes.add(n);
+ headerNode = (ColumnNode) headerNode.hookRight(n);
+ }
+ headerNode = headerNode.R.C;
+
+ for (boolean[] aGrid : grid) {
+ DancingNode prev = null;
+ for (int j = 0; j < COLS; j++) {
+ if (aGrid[j]) {
+ ColumnNode col = columnNodes.get(j);
+ DancingNode newNode = new DancingNode(col);
+ if (prev == null)
+ prev = newNode;
+ col.U.hookDown(newNode);
+ prev = prev.hookRight(newNode);
+ col.size++;
+ }
+ }
+ }
+
+ headerNode.size = COLS;
+
+ return headerNode;
+ }
+
+ DancingLinks(boolean[][] cover) {
+ header = makeDLXBoard(cover);
+ }
+
+ public void runSolver() {
+ answer = new LinkedList<>();
+ search(0);
+ }
+
+ private void handleSolution(List answer) {
+ int[][] result = parseBoard(answer);
+ printSolution(result);
+ }
+
+ private int size = 9;
+
+ private int[][] parseBoard(List answer) {
+ int[][] result = new int[size][size];
+ for (DancingNode n : answer) {
+ DancingNode rcNode = n;
+ int min = Integer.parseInt(rcNode.C.name);
+ for (DancingNode tmp = n.R; tmp != n; tmp = tmp.R) {
+ int val = Integer.parseInt(tmp.C.name);
+ if (val < min) {
+ min = val;
+ rcNode = tmp;
+ }
+ }
+ int ans1 = Integer.parseInt(rcNode.C.name);
+ int ans2 = Integer.parseInt(rcNode.R.C.name);
+ int r = ans1 / size;
+ int c = ans1 % size;
+ int num = (ans2 % size) + 1;
+ result[r][c] = num;
+ }
+ return result;
+ }
+
+ private static void printSolution(int[][] result) {
+ int size = result.length;
+ for (int[] aResult : result) {
+ StringBuilder ret = new StringBuilder();
+ for (int j = 0; j < size; j++) {
+ ret.append(aResult[j]).append(" ");
+ }
+ System.out.println(ret);
+ }
+ System.out.println();
+ }
+}
diff --git a/algorithms/src/main/java/com/baeldung/algorithms/sudoku/DancingLinksAlgorithm.java b/algorithms/src/main/java/com/baeldung/algorithms/sudoku/DancingLinksAlgorithm.java
new file mode 100644
index 0000000000..df02ff3d11
--- /dev/null
+++ b/algorithms/src/main/java/com/baeldung/algorithms/sudoku/DancingLinksAlgorithm.java
@@ -0,0 +1,121 @@
+package com.baeldung.algorithms.sudoku;
+
+import java.util.Arrays;
+
+public class DancingLinksAlgorithm {
+ private static final int BOARD_SIZE = 9;
+ private static final int SUBSECTION_SIZE = 3;
+ private static final int NO_VALUE = 0;
+ private static final int CONSTRAINTS = 4;
+ private static final int MIN_VALUE = 1;
+ private static final int MAX_VALUE = 9;
+ private static final int COVER_START_INDEX = 1;
+
+ private static int[][] board = {
+ {8, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 3, 6, 0, 0, 0, 0, 0},
+ {0, 7, 0, 0, 9, 0, 2, 0, 0},
+ {0, 5, 0, 0, 0, 7, 0, 0, 0},
+ {0, 0, 0, 0, 4, 5, 7, 0, 0},
+ {0, 0, 0, 1, 0, 0, 0, 3, 0},
+ {0, 0, 1, 0, 0, 0, 0, 6, 8},
+ {0, 0, 8, 5, 0, 0, 0, 1, 0},
+ {0, 9, 0, 0, 0, 0, 4, 0, 0}
+ };
+
+ public static void main(String[] args) {
+ DancingLinksAlgorithm solver = new DancingLinksAlgorithm();
+ solver.solve(board);
+ }
+
+ private void solve(int[][] board) {
+ boolean[][] cover = initializeExactCoverBoard(board);
+ DancingLinks dlx = new DancingLinks(cover);
+ dlx.runSolver();
+ }
+
+ private int getIndex(int row, int column, int num) {
+ return (row - 1) * BOARD_SIZE * BOARD_SIZE + (column - 1) * BOARD_SIZE + (num - 1);
+ }
+
+ private boolean[][] createExactCoverBoard() {
+ boolean[][] coverBoard = new boolean[BOARD_SIZE * BOARD_SIZE * MAX_VALUE][BOARD_SIZE * BOARD_SIZE * CONSTRAINTS];
+
+ int hBase = 0;
+ hBase = checkCellConstraint(coverBoard, hBase);
+ hBase = checkRowConstraint(coverBoard, hBase);
+ hBase = checkColumnConstraint(coverBoard, hBase);
+ checkSubsectionConstraint(coverBoard, hBase);
+
+ return coverBoard;
+ }
+
+ private int checkSubsectionConstraint(boolean[][] coverBoard, int hBase) {
+ for (int row = COVER_START_INDEX; row <= BOARD_SIZE; row += SUBSECTION_SIZE) {
+ for (int column = COVER_START_INDEX; column <= BOARD_SIZE; column += SUBSECTION_SIZE) {
+ for (int n = COVER_START_INDEX; n <= BOARD_SIZE; n++, hBase++) {
+ for (int rowDelta = 0; rowDelta < SUBSECTION_SIZE; rowDelta++) {
+ for (int columnDelta = 0; columnDelta < SUBSECTION_SIZE; columnDelta++) {
+ int index = getIndex(row + rowDelta, column + columnDelta, n);
+ coverBoard[index][hBase] = true;
+ }
+ }
+ }
+ }
+ }
+ return hBase;
+ }
+
+ private int checkColumnConstraint(boolean[][] coverBoard, int hBase) {
+ for (int column = COVER_START_INDEX; column <= BOARD_SIZE; column++) {
+ for (int n = COVER_START_INDEX; n <= BOARD_SIZE; n++, hBase++) {
+ for (int row = COVER_START_INDEX; row <= BOARD_SIZE; row++) {
+ int index = getIndex(row, column, n);
+ coverBoard[index][hBase] = true;
+ }
+ }
+ }
+ return hBase;
+ }
+
+ private int checkRowConstraint(boolean[][] coverBoard, int hBase) {
+ for (int row = COVER_START_INDEX; row <= BOARD_SIZE; row++) {
+ for (int n = COVER_START_INDEX; n <= BOARD_SIZE; n++, hBase++) {
+ for (int column = COVER_START_INDEX; column <= BOARD_SIZE; column++) {
+ int index = getIndex(row, column, n);
+ coverBoard[index][hBase] = true;
+ }
+ }
+ }
+ return hBase;
+ }
+
+ private int checkCellConstraint(boolean[][] coverBoard, int hBase) {
+ for (int row = COVER_START_INDEX; row <= BOARD_SIZE; row++) {
+ for (int column = COVER_START_INDEX; column <= BOARD_SIZE; column++, hBase++) {
+ for (int n = COVER_START_INDEX; n <= BOARD_SIZE; n++) {
+ int index = getIndex(row, column, n);
+ coverBoard[index][hBase] = true;
+ }
+ }
+ }
+ return hBase;
+ }
+
+ private boolean[][] initializeExactCoverBoard(int[][] board) {
+ boolean[][] coverBoard = createExactCoverBoard();
+ for (int row = COVER_START_INDEX; row <= BOARD_SIZE; row++) {
+ for (int column = COVER_START_INDEX; column <= BOARD_SIZE; column++) {
+ int n = board[row - 1][column - 1];
+ if (n != NO_VALUE) {
+ for (int num = MIN_VALUE; num <= MAX_VALUE; num++) {
+ if (num != n) {
+ Arrays.fill(coverBoard[getIndex(row, column, num)], false);
+ }
+ }
+ }
+ }
+ }
+ return coverBoard;
+ }
+}
\ No newline at end of file
diff --git a/algorithms/src/main/java/com/baeldung/algorithms/sudoku/DancingNode.java b/algorithms/src/main/java/com/baeldung/algorithms/sudoku/DancingNode.java
new file mode 100644
index 0000000000..2422ff0dff
--- /dev/null
+++ b/algorithms/src/main/java/com/baeldung/algorithms/sudoku/DancingNode.java
@@ -0,0 +1,50 @@
+package com.baeldung.algorithms.sudoku;
+
+class DancingNode {
+ DancingNode L, R, U, D;
+ ColumnNode C;
+
+ DancingNode hookDown(DancingNode node) {
+ assert (this.C == node.C);
+ node.D = this.D;
+ node.D.U = node;
+ node.U = this;
+ this.D = node;
+ return node;
+ }
+
+ DancingNode hookRight(DancingNode node) {
+ node.R = this.R;
+ node.R.L = node;
+ node.L = this;
+ this.R = node;
+ return node;
+ }
+
+ void unlinkLR() {
+ this.L.R = this.R;
+ this.R.L = this.L;
+ }
+
+ void relinkLR() {
+ this.L.R = this.R.L = this;
+ }
+
+ void unlinkUD() {
+ this.U.D = this.D;
+ this.D.U = this.U;
+ }
+
+ void relinkUD() {
+ this.U.D = this.D.U = this;
+ }
+
+ DancingNode() {
+ L = R = U = D = this;
+ }
+
+ DancingNode(ColumnNode c) {
+ this();
+ C = c;
+ }
+}
\ No newline at end of file
diff --git a/algorithms/src/main/resources/logback.xml b/algorithms/src/main/resources/logback.xml
new file mode 100644
index 0000000000..7d900d8ea8
--- /dev/null
+++ b/algorithms/src/main/resources/logback.xml
@@ -0,0 +1,13 @@
+
+
+
+
+ %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/algorithms/src/main/resources/maze/maze1.txt b/algorithms/src/main/resources/maze/maze1.txt
new file mode 100644
index 0000000000..0a6309d25b
--- /dev/null
+++ b/algorithms/src/main/resources/maze/maze1.txt
@@ -0,0 +1,12 @@
+S ########
+# #
+# ### ## #
+# # # #
+# # # # #
+# ## #####
+# # #
+# # # # #
+##### ####
+# # E
+# # # #
+##########
\ No newline at end of file
diff --git a/algorithms/src/main/resources/maze/maze2.txt b/algorithms/src/main/resources/maze/maze2.txt
new file mode 100644
index 0000000000..22e6d0382a
--- /dev/null
+++ b/algorithms/src/main/resources/maze/maze2.txt
@@ -0,0 +1,22 @@
+S ##########################
+# # # #
+# # #### ############### #
+# # # # # #
+# # #### # # ###############
+# # # # # # #
+# # # #### ### ########### #
+# # # # # #
+# ################## #
+######### # # # # #
+# # #### # ####### # #
+# # ### ### # # # # #
+# # ## # ##### # #
+##### ####### # # # # #
+# # ## ## #### # #
+# ##### ####### # #
+# # ############
+####### ######### # #
+# # ######## #
+# ####### ###### ## # E
+# # # ## #
+############################
\ No newline at end of file
diff --git a/algorithms/src/test/java/algorithms/HillClimbingAlgorithmTest.java b/algorithms/src/test/java/algorithms/HillClimbingAlgorithmTest.java
deleted file mode 100644
index 666adbb180..0000000000
--- a/algorithms/src/test/java/algorithms/HillClimbingAlgorithmTest.java
+++ /dev/null
@@ -1,58 +0,0 @@
-package algorithms;
-
-import com.baeldung.algorithms.hillclimbing.HillClimbing;
-import com.baeldung.algorithms.hillclimbing.State;
-import org.junit.Before;
-import org.junit.Test;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Stack;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-public class HillClimbingAlgorithmTest {
- private Stack initStack;
- private Stack goalStack;
-
- @Before
- public void initStacks() {
- String blockArr[] = { "B", "C", "D", "A" };
- String goalBlockArr[] = { "A", "B", "C", "D" };
- initStack = new Stack<>();
- for (String block : blockArr)
- initStack.push(block);
- goalStack = new Stack<>();
- for (String block : goalBlockArr)
- goalStack.push(block);
- }
-
- @Test
- public void givenInitAndGoalState_whenGetPathWithHillClimbing_thenPathFound() {
- HillClimbing hillClimbing = new HillClimbing();
-
- List path;
- try {
- path = hillClimbing.getRouteWithHillClimbing(initStack, goalStack);
- assertNotNull(path);
- assertEquals(path.get(path.size() - 1)
- .getState()
- .get(0), goalStack);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
- @Test
- public void givenCurrentState_whenFindNextState_thenBetterHeuristics() {
- HillClimbing hillClimbing = new HillClimbing();
- List> initList = new ArrayList<>();
- initList.add(initStack);
- State currentState = new State(initList);
- currentState.setHeuristics(hillClimbing.getHeuristicsValue(initList, goalStack));
- State nextState = hillClimbing.findNextState(currentState, goalStack);
- assertTrue(nextState.getHeuristics() > currentState.getHeuristics());
- }
-}
\ No newline at end of file
diff --git a/algorithms/src/test/java/algorithms/StringSearchAlgorithmsTest.java b/algorithms/src/test/java/algorithms/StringSearchAlgorithmsTest.java
deleted file mode 100755
index e260cd7e5b..0000000000
--- a/algorithms/src/test/java/algorithms/StringSearchAlgorithmsTest.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package algorithms;
-
-
-import org.junit.Assert;
-import org.junit.Test;
-
-import com.baeldung.algorithms.string.search.StringSearchAlgorithms;
-
-public class StringSearchAlgorithmsTest {
-
-
- @Test
- public void testStringSearchAlgorithms(){
- String text = "This is some nice text.";
- String pattern = "some";
-
- int realPosition = text.indexOf(pattern);
- Assert.assertTrue(realPosition == StringSearchAlgorithms.simpleTextSearch(pattern.toCharArray(), text.toCharArray()));
- Assert.assertTrue(realPosition == StringSearchAlgorithms.RabinKarpMethod(pattern.toCharArray(), text.toCharArray()));
- Assert.assertTrue(realPosition == StringSearchAlgorithms.KnuthMorrisPrattSearch(pattern.toCharArray(), text.toCharArray()));
- Assert.assertTrue(realPosition == StringSearchAlgorithms.BoyerMooreHorspoolSimpleSearch(pattern.toCharArray(), text.toCharArray()));
- Assert.assertTrue(realPosition == StringSearchAlgorithms.BoyerMooreHorspoolSearch(pattern.toCharArray(), text.toCharArray()));
- }
-
-}
diff --git a/algorithms/src/test/java/algorithms/binarysearch/BinarySearchTest.java b/algorithms/src/test/java/algorithms/binarysearch/BinarySearchTest.java
deleted file mode 100644
index 959f47a275..0000000000
--- a/algorithms/src/test/java/algorithms/binarysearch/BinarySearchTest.java
+++ /dev/null
@@ -1,43 +0,0 @@
-package algorithms.binarysearch;
-
-import java.util.Arrays;
-import java.util.List;
-
-import org.junit.Assert;
-import org.junit.Test;
-import com.baeldung.algorithms.binarysearch.BinarySearch;
-
-public class BinarySearchTest {
-
- int[] sortedArray = { 0, 1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9 };
- int key = 6;
- int expectedIndexForSearchKey = 7;
- int low = 0;
- int high = sortedArray.length - 1;
- List sortedList = Arrays.asList(0, 1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9);
-
- @Test
- public void givenASortedArrayOfIntegers_whenBinarySearchRunIterativelyForANumber_thenGetIndexOfTheNumber() {
- BinarySearch binSearch = new BinarySearch();
- Assert.assertEquals(expectedIndexForSearchKey, binSearch.runBinarySearchIteratively(sortedArray, key, low, high));
- }
-
- @Test
- public void givenASortedArrayOfIntegers_whenBinarySearchRunRecursivelyForANumber_thenGetIndexOfTheNumber() {
- BinarySearch binSearch = new BinarySearch();
- Assert.assertEquals(expectedIndexForSearchKey, binSearch.runBinarySearchRecursively(sortedArray, key, low, high));
- }
-
- @Test
- public void givenASortedArrayOfIntegers_whenBinarySearchRunUsingArraysClassStaticMethodForANumber_thenGetIndexOfTheNumber() {
- BinarySearch binSearch = new BinarySearch();
- Assert.assertEquals(expectedIndexForSearchKey, binSearch.runBinarySearchUsingJavaArrays(sortedArray, key));
- }
-
- @Test
- public void givenASortedListOfIntegers_whenBinarySearchRunUsingCollectionsClassStaticMethodForANumber_thenGetIndexOfTheNumber() {
- BinarySearch binSearch = new BinarySearch();
- Assert.assertEquals(expectedIndexForSearchKey, binSearch.runBinarySearchUsingJavaCollections(sortedList, key));
- }
-
-}
diff --git a/algorithms/src/test/java/algorithms/mcts/MCTSTest.java b/algorithms/src/test/java/algorithms/mcts/MCTSTest.java
deleted file mode 100644
index 375f66ab6f..0000000000
--- a/algorithms/src/test/java/algorithms/mcts/MCTSTest.java
+++ /dev/null
@@ -1,92 +0,0 @@
-package algorithms.mcts;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import java.util.List;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import com.baeldung.algorithms.mcts.montecarlo.MonteCarloTreeSearch;
-import com.baeldung.algorithms.mcts.montecarlo.State;
-import com.baeldung.algorithms.mcts.montecarlo.UCT;
-import com.baeldung.algorithms.mcts.tictactoe.Board;
-import com.baeldung.algorithms.mcts.tictactoe.Position;
-import com.baeldung.algorithms.mcts.tree.Tree;
-
-public class MCTSTest {
- private Tree gameTree;
- private MonteCarloTreeSearch mcts;
-
- @Before
- public void initGameTree() {
- gameTree = new Tree();
- mcts = new MonteCarloTreeSearch();
- }
-
- @Test
- public void givenStats_whenGetUCTForNode_thenUCTMatchesWithManualData() {
- double uctValue = 15.79;
- assertEquals(UCT.uctValue(600, 300, 20), uctValue, 0.01);
- }
-
- @Test
- public void giveninitBoardState_whenGetAllPossibleStates_thenNonEmptyList() {
- State initState = gameTree.getRoot().getState();
- List possibleStates = initState.getAllPossibleStates();
- assertTrue(possibleStates.size() > 0);
- }
-
- @Test
- public void givenEmptyBoard_whenPerformMove_thenLessAvailablePossitions() {
- Board board = new Board();
- int initAvailablePositions = board.getEmptyPositions().size();
- board.performMove(Board.P1, new Position(1, 1));
- int availablePositions = board.getEmptyPositions().size();
- assertTrue(initAvailablePositions > availablePositions);
- }
-
- @Test
- public void givenEmptyBoard_whenSimulateInterAIPlay_thenGameDraw() {
- Board board = new Board();
-
- int player = Board.P1;
- int totalMoves = Board.DEFAULT_BOARD_SIZE * Board.DEFAULT_BOARD_SIZE;
- for (int i = 0; i < totalMoves; i++) {
- board = mcts.findNextMove(board, player);
- if (board.checkStatus() != -1) {
- break;
- }
- player = 3 - player;
- }
- int winStatus = board.checkStatus();
- assertEquals(winStatus, Board.DRAW);
- }
-
- @Test
- public void givenEmptyBoard_whenLevel1VsLevel3_thenLevel3WinsOrDraw() {
- Board board = new Board();
- MonteCarloTreeSearch mcts1 = new MonteCarloTreeSearch();
- mcts1.setLevel(1);
- MonteCarloTreeSearch mcts3 = new MonteCarloTreeSearch();
- mcts3.setLevel(3);
-
- int player = Board.P1;
- int totalMoves = Board.DEFAULT_BOARD_SIZE * Board.DEFAULT_BOARD_SIZE;
- for (int i = 0; i < totalMoves; i++) {
- if (player == Board.P1)
- board = mcts3.findNextMove(board, player);
- else
- board = mcts1.findNextMove(board, player);
-
- if (board.checkStatus() != -1) {
- break;
- }
- player = 3 - player;
- }
- int winStatus = board.checkStatus();
- assertTrue(winStatus == Board.DRAW || winStatus == Board.P1);
- }
-
-}
diff --git a/algorithms/src/test/java/algorithms/minimax/MinimaxTest.java b/algorithms/src/test/java/algorithms/minimax/MinimaxTest.java
deleted file mode 100644
index b29c16386c..0000000000
--- a/algorithms/src/test/java/algorithms/minimax/MinimaxTest.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package algorithms.minimax;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import static org.junit.Assert.*;
-import com.baeldung.algorithms.minimax.MiniMax;
-import com.baeldung.algorithms.minimax.Tree;
-
-public class MinimaxTest {
- private Tree gameTree;
- private MiniMax miniMax;
-
- @Before
- public void initMiniMaxUtility() {
- miniMax = new MiniMax();
- }
-
- @Test
- public void givenMiniMax_whenConstructTree_thenNotNullTree() {
- assertNull(gameTree);
- miniMax.constructTree(6);
- gameTree = miniMax.getTree();
- assertNotNull(gameTree);
- }
-
- @Test
- public void givenMiniMax_whenCheckWin_thenComputeOptimal() {
- miniMax.constructTree(6);
- boolean result = miniMax.checkWin();
- assertTrue(result);
- miniMax.constructTree(8);
- result = miniMax.checkWin();
- assertFalse(result);
- }
-}
diff --git a/algorithms/src/test/java/algorithms/AntColonyOptimizationLongRunningUnitTest.java b/algorithms/src/test/java/com/baeldung/algorithms/AntColonyOptimizationLongRunningUnitTest.java
similarity index 94%
rename from algorithms/src/test/java/algorithms/AntColonyOptimizationLongRunningUnitTest.java
rename to algorithms/src/test/java/com/baeldung/algorithms/AntColonyOptimizationLongRunningUnitTest.java
index b0218ae23e..2ac7adc3aa 100644
--- a/algorithms/src/test/java/algorithms/AntColonyOptimizationLongRunningUnitTest.java
+++ b/algorithms/src/test/java/com/baeldung/algorithms/AntColonyOptimizationLongRunningUnitTest.java
@@ -1,4 +1,4 @@
-package algorithms;
+package com.baeldung.algorithms;
import org.junit.Assert;
import org.junit.Test;
diff --git a/algorithms/src/test/java/algorithms/BinaryGeneticAlgorithmLongRunningUnitTest.java b/algorithms/src/test/java/com/baeldung/algorithms/BinaryGeneticAlgorithmLongRunningUnitTest.java
similarity index 92%
rename from algorithms/src/test/java/algorithms/BinaryGeneticAlgorithmLongRunningUnitTest.java
rename to algorithms/src/test/java/com/baeldung/algorithms/BinaryGeneticAlgorithmLongRunningUnitTest.java
index fa8ecdee77..e819da4b36 100644
--- a/algorithms/src/test/java/algorithms/BinaryGeneticAlgorithmLongRunningUnitTest.java
+++ b/algorithms/src/test/java/com/baeldung/algorithms/BinaryGeneticAlgorithmLongRunningUnitTest.java
@@ -1,4 +1,4 @@
-package algorithms;
+package com.baeldung.algorithms;
import org.junit.Assert;
import org.junit.Test;
diff --git a/algorithms/src/test/java/algorithms/DijkstraAlgorithmLongRunningUnitTest.java b/algorithms/src/test/java/com/baeldung/algorithms/DijkstraAlgorithmLongRunningUnitTest.java
similarity index 98%
rename from algorithms/src/test/java/algorithms/DijkstraAlgorithmLongRunningUnitTest.java
rename to algorithms/src/test/java/com/baeldung/algorithms/DijkstraAlgorithmLongRunningUnitTest.java
index 68386278fc..bbc4d4f398 100644
--- a/algorithms/src/test/java/algorithms/DijkstraAlgorithmLongRunningUnitTest.java
+++ b/algorithms/src/test/java/com/baeldung/algorithms/DijkstraAlgorithmLongRunningUnitTest.java
@@ -1,4 +1,4 @@
-package algorithms;
+package com.baeldung.algorithms;
import org.junit.Test;
diff --git a/algorithms/src/test/java/com/baeldung/algorithms/HillClimbingAlgorithmUnitTest.java b/algorithms/src/test/java/com/baeldung/algorithms/HillClimbingAlgorithmUnitTest.java
new file mode 100644
index 0000000000..e817d195b3
--- /dev/null
+++ b/algorithms/src/test/java/com/baeldung/algorithms/HillClimbingAlgorithmUnitTest.java
@@ -0,0 +1,58 @@
+package com.baeldung.algorithms;
+
+import com.baeldung.algorithms.hillclimbing.HillClimbing;
+import com.baeldung.algorithms.hillclimbing.State;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Stack;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+public class HillClimbingAlgorithmUnitTest {
+ private Stack initStack;
+ private Stack goalStack;
+
+ @Before
+ public void initStacks() {
+ String blockArr[] = { "B", "C", "D", "A" };
+ String goalBlockArr[] = { "A", "B", "C", "D" };
+ initStack = new Stack<>();
+ for (String block : blockArr)
+ initStack.push(block);
+ goalStack = new Stack<>();
+ for (String block : goalBlockArr)
+ goalStack.push(block);
+ }
+
+ @Test
+ public void givenInitAndGoalState_whenGetPathWithHillClimbing_thenPathFound() {
+ HillClimbing hillClimbing = new HillClimbing();
+
+ List path;
+ try {
+ path = hillClimbing.getRouteWithHillClimbing(initStack, goalStack);
+ assertNotNull(path);
+ assertEquals(path.get(path.size() - 1)
+ .getState()
+ .get(0), goalStack);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Test
+ public void givenCurrentState_whenFindNextState_thenBetterHeuristics() {
+ HillClimbing hillClimbing = new HillClimbing();
+ List> initList = new ArrayList<>();
+ initList.add(initStack);
+ State currentState = new State(initList);
+ currentState.setHeuristics(hillClimbing.getHeuristicsValue(initList, goalStack));
+ State nextState = hillClimbing.findNextState(currentState, goalStack);
+ assertTrue(nextState.getHeuristics() > currentState.getHeuristics());
+ }
+}
\ No newline at end of file
diff --git a/algorithms/src/test/java/com/baeldung/algorithms/MiddleElementLookupUnitTest.java b/algorithms/src/test/java/com/baeldung/algorithms/MiddleElementLookupUnitTest.java
new file mode 100644
index 0000000000..2cda0ccb36
--- /dev/null
+++ b/algorithms/src/test/java/com/baeldung/algorithms/MiddleElementLookupUnitTest.java
@@ -0,0 +1,118 @@
+package com.baeldung.algorithms;
+
+import com.baeldung.algorithms.middleelementlookup.MiddleElementLookup;
+import com.baeldung.algorithms.middleelementlookup.Node;
+import org.junit.Test;
+
+import java.util.LinkedList;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+
+public class MiddleElementLookupUnitTest {
+
+ @Test
+ public void whenFindingMiddleLinkedList_thenMiddleFound() {
+ assertEquals("3", MiddleElementLookup
+ .findMiddleElementLinkedList(createLinkedList(5))
+ .get());
+ assertEquals("2", MiddleElementLookup
+ .findMiddleElementLinkedList(createLinkedList(4))
+ .get());
+ }
+
+ @Test
+ public void whenFindingMiddleFromHead_thenMiddleFound() {
+ assertEquals("3", MiddleElementLookup
+ .findMiddleElementFromHead(createNodesList(5))
+ .get());
+ assertEquals("2", MiddleElementLookup
+ .findMiddleElementFromHead(createNodesList(4))
+ .get());
+ }
+
+ @Test
+ public void whenFindingMiddleFromHead1PassRecursively_thenMiddleFound() {
+ assertEquals("3", MiddleElementLookup
+ .findMiddleElementFromHead1PassRecursively(createNodesList(5))
+ .get());
+ assertEquals("2", MiddleElementLookup
+ .findMiddleElementFromHead1PassRecursively(createNodesList(4))
+ .get());
+ }
+
+ @Test
+ public void whenFindingMiddleFromHead1PassIteratively_thenMiddleFound() {
+ assertEquals("3", MiddleElementLookup
+ .findMiddleElementFromHead1PassIteratively(createNodesList(5))
+ .get());
+ assertEquals("2", MiddleElementLookup
+ .findMiddleElementFromHead1PassIteratively(createNodesList(4))
+ .get());
+ }
+
+ @Test
+ public void whenListEmptyOrNull_thenMiddleNotFound() {
+ // null list
+ assertFalse(MiddleElementLookup
+ .findMiddleElementLinkedList(null)
+ .isPresent());
+ assertFalse(MiddleElementLookup
+ .findMiddleElementFromHead(null)
+ .isPresent());
+ assertFalse(MiddleElementLookup
+ .findMiddleElementFromHead1PassIteratively(null)
+ .isPresent());
+ assertFalse(MiddleElementLookup
+ .findMiddleElementFromHead1PassRecursively(null)
+ .isPresent());
+
+ // empty LinkedList
+ assertFalse(MiddleElementLookup
+ .findMiddleElementLinkedList(new LinkedList<>())
+ .isPresent());
+
+ // LinkedList with nulls
+ LinkedList nullsList = new LinkedList<>();
+ nullsList.add(null);
+ nullsList.add(null);
+ assertFalse(MiddleElementLookup
+ .findMiddleElementLinkedList(nullsList)
+ .isPresent());
+
+ // nodes with null values
+ assertFalse(MiddleElementLookup
+ .findMiddleElementFromHead(new Node(null))
+ .isPresent());
+ assertFalse(MiddleElementLookup
+ .findMiddleElementFromHead1PassIteratively(new Node(null))
+ .isPresent());
+ assertFalse(MiddleElementLookup
+ .findMiddleElementFromHead1PassRecursively(new Node(null))
+ .isPresent());
+ }
+
+ private static LinkedList createLinkedList(int n) {
+ LinkedList list = new LinkedList<>();
+
+ for (int i = 1; i <= n; i++) {
+ list.add(String.valueOf(i));
+ }
+
+ return list;
+ }
+
+ private static Node createNodesList(int n) {
+ Node head = new Node("1");
+ Node current = head;
+
+ for (int i = 2; i <= n; i++) {
+ Node newNode = new Node(String.valueOf(i));
+ current.setNext(newNode);
+ current = newNode;
+ }
+
+ return head;
+ }
+
+}
diff --git a/algorithms/src/test/java/algorithms/RtFiniteStateMachineLongRunningUnitTest.java b/algorithms/src/test/java/com/baeldung/algorithms/RtFiniteStateMachineLongRunningUnitTest.java
similarity index 98%
rename from algorithms/src/test/java/algorithms/RtFiniteStateMachineLongRunningUnitTest.java
rename to algorithms/src/test/java/com/baeldung/algorithms/RtFiniteStateMachineLongRunningUnitTest.java
index 99e962773f..fddccfcd9f 100644
--- a/algorithms/src/test/java/algorithms/RtFiniteStateMachineLongRunningUnitTest.java
+++ b/algorithms/src/test/java/com/baeldung/algorithms/RtFiniteStateMachineLongRunningUnitTest.java
@@ -1,4 +1,4 @@
-package algorithms;
+package com.baeldung.algorithms;
import com.baeldung.algorithms.automata.*;
import org.junit.Test;
diff --git a/algorithms/src/test/java/algorithms/SimulatedAnnealingLongRunningUnitTest.java b/algorithms/src/test/java/com/baeldung/algorithms/SimulatedAnnealingLongRunningUnitTest.java
similarity index 90%
rename from algorithms/src/test/java/algorithms/SimulatedAnnealingLongRunningUnitTest.java
rename to algorithms/src/test/java/com/baeldung/algorithms/SimulatedAnnealingLongRunningUnitTest.java
index 6ee129ece9..2ce7d75e43 100644
--- a/algorithms/src/test/java/algorithms/SimulatedAnnealingLongRunningUnitTest.java
+++ b/algorithms/src/test/java/com/baeldung/algorithms/SimulatedAnnealingLongRunningUnitTest.java
@@ -1,4 +1,4 @@
-package algorithms;
+package com.baeldung.algorithms;
import org.junit.Assert;
import org.junit.Test;
diff --git a/algorithms/src/test/java/com/baeldung/algorithms/StringSearchAlgorithmsUnitTest.java b/algorithms/src/test/java/com/baeldung/algorithms/StringSearchAlgorithmsUnitTest.java
new file mode 100755
index 0000000000..dfe015aad2
--- /dev/null
+++ b/algorithms/src/test/java/com/baeldung/algorithms/StringSearchAlgorithmsUnitTest.java
@@ -0,0 +1,25 @@
+package com.baeldung.algorithms;
+
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.baeldung.algorithms.string.search.StringSearchAlgorithms;
+
+public class StringSearchAlgorithmsUnitTest {
+
+
+ @Test
+ public void testStringSearchAlgorithms(){
+ String text = "This is some nice text.";
+ String pattern = "some";
+
+ int realPosition = text.indexOf(pattern);
+ Assert.assertTrue(realPosition == StringSearchAlgorithms.simpleTextSearch(pattern.toCharArray(), text.toCharArray()));
+ Assert.assertTrue(realPosition == StringSearchAlgorithms.RabinKarpMethod(pattern.toCharArray(), text.toCharArray()));
+ Assert.assertTrue(realPosition == StringSearchAlgorithms.KnuthMorrisPrattSearch(pattern.toCharArray(), text.toCharArray()));
+ Assert.assertTrue(realPosition == StringSearchAlgorithms.BoyerMooreHorspoolSimpleSearch(pattern.toCharArray(), text.toCharArray()));
+ Assert.assertTrue(realPosition == StringSearchAlgorithms.BoyerMooreHorspoolSearch(pattern.toCharArray(), text.toCharArray()));
+ }
+
+}
diff --git a/algorithms/src/test/java/com/baeldung/algorithms/analysis/AnalysisRunnerLiveTest.java b/algorithms/src/test/java/com/baeldung/algorithms/analysis/AnalysisRunnerLiveTest.java
new file mode 100644
index 0000000000..1e9188f726
--- /dev/null
+++ b/algorithms/src/test/java/com/baeldung/algorithms/analysis/AnalysisRunnerLiveTest.java
@@ -0,0 +1,139 @@
+package com.baeldung.algorithms.analysis;
+
+import org.junit.Test;
+
+public class AnalysisRunnerLiveTest {
+
+ int n = 10;
+ int total = 0;
+
+ @Test
+ public void whenConstantComplexity_thenConstantRuntime() {
+
+ System.out.println("**** n = " + n + " ****");
+ System.out.println();
+
+ // Constant Time
+ System.out.println("**** Constant time ****");
+
+ System.out.println("Hey - your input is: " + n);
+ System.out.println("Running time not dependent on input size!");
+ System.out.println();
+ }
+
+ @Test
+ public void whenLogarithmicComplexity_thenLogarithmicRuntime() {
+ // Logarithmic Time
+ System.out.println("**** Logarithmic Time ****");
+ for (int i = 1; i < n; i = i * 2) {
+ // System.out.println("Hey - I'm busy looking at: " + i);
+ total++;
+ }
+ System.out.println("Total amount of times run: " + total);
+ System.out.println();
+ }
+
+ @Test
+ public void whenLinearComplexity_thenLinearRuntime() {
+ // Linear Time
+ System.out.println("**** Linear Time ****");
+ for (int i = 0; i < n; i++) {
+ // System.out.println("Hey - I'm busy looking at: " + i);
+ total++;
+ }
+ System.out.println("Total amount of times run: " + total);
+ System.out.println();
+
+ }
+
+ @Test
+ public void whenNLogNComplexity_thenNLogNRuntime() {
+ // N Log N Time
+ System.out.println("**** nlogn Time ****");
+ total = 0;
+ for (
+
+ int i = 1; i <= n; i++) {
+ for (int j = 1; j < n; j = j * 2) {
+ // System.out.println("Hey - I'm busy looking at: " + i + " and " + j);
+ total++;
+ }
+ }
+ System.out.println("Total amount of times run: " + total);
+ System.out.println();
+ }
+
+ @Test
+ public void whenQuadraticComplexity_thenQuadraticRuntime() {
+ // Quadratic Time
+ System.out.println("**** Quadratic Time ****");
+ total = 0;
+ for (
+
+ int i = 1; i <= n; i++) {
+ for (int j = 1; j <= n; j++) {
+ // System.out.println("Hey - I'm busy looking at: " + i + " and " + j);
+ total++;
+ }
+ }
+ System.out.println("Total amount of times run: " + total);
+ System.out.println();
+ }
+
+ @Test
+ public void whenCubicComplexity_thenCubicRuntime() {
+ // Cubic Time
+ System.out.println("**** Cubic Time ****");
+ total = 0;
+ for (
+
+ int i = 1; i <= n; i++) {
+ for (int j = 1; j <= n; j++) {
+ for (int k = 1; k <= n; k++) {
+ // System.out.println("Hey - I'm busy looking at: " + i + " and " + j + " and " + k);
+ total++;
+ }
+ }
+ }
+ System.out.println("Total amount of times run: " + total);
+ System.out.println();
+ }
+
+ @Test
+ public void whenExponentialComplexity_thenExponentialRuntime() {
+ // Exponential Time
+ System.out.println("**** Exponential Time ****");
+ total = 0;
+ for (
+
+ int i = 1; i <= Math.pow(2, n); i++) {
+ // System.out.println("Hey - I'm busy looking at: " + i);
+ total++;
+ }
+ System.out.println("Total amount of times run: " + total);
+ System.out.println();
+ }
+
+ @Test
+ public void whenFactorialComplexity_thenFactorialRuntime() {
+ // Factorial Time
+ System.out.println("**** Factorial Time ****");
+ total = 0;
+ for (
+
+ int i = 1; i <=
+
+ factorial(n); i++) {
+ // System.out.println("Hey - I'm busy looking at: " + i);
+ total++;
+ }
+ System.out.println("Total amount of times run: " + total);
+ }
+
+ static int factorial(int n) {
+ if (n == 0 || n == 1)
+ return 1;
+ else
+ return n * factorial(n - 1);
+ }
+}
diff --git a/algorithms/src/test/java/com/baeldung/algorithms/binarysearch/BinarySearchUnitTest.java b/algorithms/src/test/java/com/baeldung/algorithms/binarysearch/BinarySearchUnitTest.java
new file mode 100644
index 0000000000..826682d373
--- /dev/null
+++ b/algorithms/src/test/java/com/baeldung/algorithms/binarysearch/BinarySearchUnitTest.java
@@ -0,0 +1,43 @@
+package com.baeldung.algorithms.binarysearch;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.junit.Assert;
+import org.junit.Test;
+import com.baeldung.algorithms.binarysearch.BinarySearch;
+
+public class BinarySearchUnitTest {
+
+ int[] sortedArray = { 0, 1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9 };
+ int key = 6;
+ int expectedIndexForSearchKey = 7;
+ int low = 0;
+ int high = sortedArray.length - 1;
+ List sortedList = Arrays.asList(0, 1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9);
+
+ @Test
+ public void givenASortedArrayOfIntegers_whenBinarySearchRunIterativelyForANumber_thenGetIndexOfTheNumber() {
+ BinarySearch binSearch = new BinarySearch();
+ Assert.assertEquals(expectedIndexForSearchKey, binSearch.runBinarySearchIteratively(sortedArray, key, low, high));
+ }
+
+ @Test
+ public void givenASortedArrayOfIntegers_whenBinarySearchRunRecursivelyForANumber_thenGetIndexOfTheNumber() {
+ BinarySearch binSearch = new BinarySearch();
+ Assert.assertEquals(expectedIndexForSearchKey, binSearch.runBinarySearchRecursively(sortedArray, key, low, high));
+ }
+
+ @Test
+ public void givenASortedArrayOfIntegers_whenBinarySearchRunUsingArraysClassStaticMethodForANumber_thenGetIndexOfTheNumber() {
+ BinarySearch binSearch = new BinarySearch();
+ Assert.assertEquals(expectedIndexForSearchKey, binSearch.runBinarySearchUsingJavaArrays(sortedArray, key));
+ }
+
+ @Test
+ public void givenASortedListOfIntegers_whenBinarySearchRunUsingCollectionsClassStaticMethodForANumber_thenGetIndexOfTheNumber() {
+ BinarySearch binSearch = new BinarySearch();
+ Assert.assertEquals(expectedIndexForSearchKey, binSearch.runBinarySearchUsingJavaCollections(sortedList, key));
+ }
+
+}
diff --git a/algorithms/src/test/java/com/baeldung/algorithms/bubblesort/BubbleSortTest.java b/algorithms/src/test/java/com/baeldung/algorithms/bubblesort/BubbleSortTest.java
deleted file mode 100644
index 7774eb3e67..0000000000
--- a/algorithms/src/test/java/com/baeldung/algorithms/bubblesort/BubbleSortTest.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package com.baeldung.algorithms.bubblesort;
-
-import static org.junit.Assert.*;
-
-import org.junit.Test;
-
-public class BubbleSortTest {
-
- @Test
- public void givenIntegerArray_whenSortedWithBubbleSort_thenGetSortedArray() {
- Integer[] array = { 2, 1, 4, 6, 3, 5 };
- Integer[] sortedArray = { 1, 2, 3, 4, 5, 6 };
- BubbleSort bubbleSort = new BubbleSort();
- bubbleSort.bubbleSort(array);
- assertArrayEquals(array, sortedArray);
- }
-
- @Test
- public void givenIntegerArray_whenSortedWithOptimizedBubbleSort_thenGetSortedArray() {
- Integer[] array = { 2, 1, 4, 6, 3, 5 };
- Integer[] sortedArray = { 1, 2, 3, 4, 5, 6 };
- BubbleSort bubbleSort = new BubbleSort();
- bubbleSort.optimizedBubbleSort(array);
- assertArrayEquals(array, sortedArray);
- }
-}
\ No newline at end of file
diff --git a/algorithms/src/test/java/com/baeldung/algorithms/bubblesort/BubbleSortUnitTest.java b/algorithms/src/test/java/com/baeldung/algorithms/bubblesort/BubbleSortUnitTest.java
new file mode 100644
index 0000000000..c7f3f7dc38
--- /dev/null
+++ b/algorithms/src/test/java/com/baeldung/algorithms/bubblesort/BubbleSortUnitTest.java
@@ -0,0 +1,26 @@
+package com.baeldung.algorithms.bubblesort;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+
+public class BubbleSortUnitTest {
+
+ @Test
+ public void givenIntegerArray_whenSortedWithBubbleSort_thenGetSortedArray() {
+ Integer[] array = { 2, 1, 4, 6, 3, 5 };
+ Integer[] sortedArray = { 1, 2, 3, 4, 5, 6 };
+ BubbleSort bubbleSort = new BubbleSort();
+ bubbleSort.bubbleSort(array);
+ assertArrayEquals(array, sortedArray);
+ }
+
+ @Test
+ public void givenIntegerArray_whenSortedWithOptimizedBubbleSort_thenGetSortedArray() {
+ Integer[] array = { 2, 1, 4, 6, 3, 5 };
+ Integer[] sortedArray = { 1, 2, 3, 4, 5, 6 };
+ BubbleSort bubbleSort = new BubbleSort();
+ bubbleSort.optimizedBubbleSort(array);
+ assertArrayEquals(array, sortedArray);
+ }
+}
\ No newline at end of file
diff --git a/algorithms/src/test/java/com/baeldung/algorithms/conversion/ByteArrayConverterUnitTest.java b/algorithms/src/test/java/com/baeldung/algorithms/conversion/ByteArrayConverterUnitTest.java
new file mode 100644
index 0000000000..be61802705
--- /dev/null
+++ b/algorithms/src/test/java/com/baeldung/algorithms/conversion/ByteArrayConverterUnitTest.java
@@ -0,0 +1,127 @@
+package com.baeldung.algorithms.conversion;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+
+import org.apache.commons.codec.DecoderException;
+import org.hamcrest.text.IsEqualIgnoringCase;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.baeldung.algorithms.conversion.HexStringConverter;
+
+public class ByteArrayConverterUnitTest {
+
+ private HexStringConverter hexStringConverter;
+
+ @Before
+ public void setup() {
+ hexStringConverter = new HexStringConverter();
+ }
+
+ @Test
+ public void shouldEncodeByteArrayToHexStringUsingBigIntegerToString() {
+ byte[] bytes = getSampleBytes();
+ String hexString = getSampleHexString();
+ if(hexString.charAt(0) == '0') {
+ hexString = hexString.substring(1);
+ }
+ String output = hexStringConverter.encodeUsingBigIntegerToString(bytes);
+ assertThat(output, IsEqualIgnoringCase.equalToIgnoringCase(hexString));
+ }
+
+ @Test
+ public void shouldEncodeByteArrayToHexStringUsingBigIntegerStringFormat() {
+ byte[] bytes = getSampleBytes();
+ String hexString = getSampleHexString();
+ String output = hexStringConverter.encodeUsingBigIntegerStringFormat(bytes);
+ assertThat(output, IsEqualIgnoringCase.equalToIgnoringCase(hexString));
+ }
+
+ @Test
+ public void shouldDecodeHexStringToByteArrayUsingBigInteger() {
+ byte[] bytes = getSampleBytes();
+ String hexString = getSampleHexString();
+ byte[] output = hexStringConverter.decodeUsingBigInteger(hexString);
+ assertArrayEquals(bytes, output);
+ }
+
+ @Test
+ public void shouldEncodeByteArrayToHexStringUsingCharacterConversion() {
+ byte[] bytes = getSampleBytes();
+ String hexString = getSampleHexString();
+ String output = hexStringConverter.encodeHexString(bytes);
+ assertThat(output, IsEqualIgnoringCase.equalToIgnoringCase(hexString));
+ }
+
+ @Test
+ public void shouldDecodeHexStringToByteArrayUsingCharacterConversion() {
+ byte[] bytes = getSampleBytes();
+ String hexString = getSampleHexString();
+ byte[] output = hexStringConverter.decodeHexString(hexString);
+ assertArrayEquals(bytes, output);
+ }
+
+ @Test(expected=IllegalArgumentException.class)
+ public void shouldDecodeHexToByteWithInvalidHexCharacter() {
+ hexStringConverter.hexToByte("fg");
+ }
+
+ @Test
+ public void shouldEncodeByteArrayToHexStringDataTypeConverter() {
+ byte[] bytes = getSampleBytes();
+ String hexString = getSampleHexString();
+ String output = hexStringConverter.encodeUsingDataTypeConverter(bytes);
+ assertThat(output, IsEqualIgnoringCase.equalToIgnoringCase(hexString));
+ }
+
+ @Test
+ public void shouldDecodeHexStringToByteArrayUsingDataTypeConverter() {
+ byte[] bytes = getSampleBytes();
+ String hexString = getSampleHexString();
+ byte[] output = hexStringConverter.decodeUsingDataTypeConverter(hexString);
+ assertArrayEquals(bytes, output);
+ }
+
+ @Test
+ public void shouldEncodeByteArrayToHexStringUsingGuava() {
+ byte[] bytes = getSampleBytes();
+ String hexString = getSampleHexString();
+ String output = hexStringConverter.encodeUsingGuava(bytes);
+ assertThat(output, IsEqualIgnoringCase.equalToIgnoringCase(hexString));
+ }
+
+ @Test
+ public void shouldDecodeHexStringToByteArrayUsingGuava() {
+ byte[] bytes = getSampleBytes();
+ String hexString = getSampleHexString();
+ byte[] output = hexStringConverter.decodeUsingGuava(hexString);
+ assertArrayEquals(bytes, output);
+ }
+
+ @Test
+ public void shouldEncodeByteArrayToHexStringUsingApacheCommons() throws DecoderException {
+ byte[] bytes = getSampleBytes();
+ String hexString = getSampleHexString();
+ String output = hexStringConverter.encodeUsingApacheCommons(bytes);
+ assertThat(output, IsEqualIgnoringCase.equalToIgnoringCase(hexString));
+ }
+
+ @Test
+ public void shouldDecodeHexStringToByteArrayUsingApacheCommons() throws DecoderException {
+ byte[] bytes = getSampleBytes();
+ String hexString = getSampleHexString();
+ byte[] output = hexStringConverter.decodeUsingApacheCommons(hexString);
+ assertArrayEquals(bytes, output);
+ }
+
+ private String getSampleHexString() {
+ return "0af50c0e2d10";
+ }
+
+ private byte[] getSampleBytes() {
+ return new byte[] { 10, -11, 12, 14, 45, 16 };
+ }
+
+}
diff --git a/algorithms/src/test/java/com/baeldung/algorithms/distancebetweenpoints/DistanceBetweenPointsServiceUnitTest.java b/algorithms/src/test/java/com/baeldung/algorithms/distancebetweenpoints/DistanceBetweenPointsServiceUnitTest.java
new file mode 100644
index 0000000000..785afdbb2b
--- /dev/null
+++ b/algorithms/src/test/java/com/baeldung/algorithms/distancebetweenpoints/DistanceBetweenPointsServiceUnitTest.java
@@ -0,0 +1,54 @@
+package com.baeldung.algorithms.distancebetweenpoints;
+
+import org.junit.Test;
+
+import com.baeldung.algorithms.distancebetweenpoints.DistanceBetweenPointsService;
+
+import static org.junit.Assert.assertEquals;
+
+public class DistanceBetweenPointsServiceUnitTest {
+
+ private DistanceBetweenPointsService service = new DistanceBetweenPointsService();
+
+ @Test
+ public void givenTwoPoints_whenCalculateDistanceByFormula_thenCorrect() {
+
+ double x1 = 3;
+ double y1 = 4;
+ double x2 = 7;
+ double y2 = 1;
+
+ double distance = service.calculateDistanceBetweenPoints(x1, y1, x2, y2);
+
+ assertEquals(distance, 5, 0.001);
+
+ }
+
+ @Test
+ public void givenTwoPoints_whenCalculateDistanceWithHypot_thenCorrect() {
+
+ double x1 = 3;
+ double y1 = 4;
+ double x2 = 7;
+ double y2 = 1;
+
+ double distance = service.calculateDistanceBetweenPointsWithHypot(x1, y1, x2, y2);
+
+ assertEquals(distance, 5, 0.001);
+
+ }
+
+ @Test
+ public void givenTwoPoints_whenCalculateDistanceWithPoint2D_thenCorrect() {
+
+ double x1 = 3;
+ double y1 = 4;
+ double x2 = 7;
+ double y2 = 1;
+
+ double distance = service.calculateDistanceBetweenPointsWithPoint2D(x1, y1, x2, y2);
+
+ assertEquals(distance, 5, 0.001);
+
+ }
+}
diff --git a/algorithms/src/test/java/com/baeldung/algorithms/editdistance/EditDistanceTest.java b/algorithms/src/test/java/com/baeldung/algorithms/editdistance/EditDistanceTest.java
deleted file mode 100644
index bab2f480a5..0000000000
--- a/algorithms/src/test/java/com/baeldung/algorithms/editdistance/EditDistanceTest.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package com.baeldung.algorithms.editdistance;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-
-import static org.junit.Assert.assertEquals;
-
-@RunWith(Parameterized.class)
-public class EditDistanceTest extends EditDistanceDataProvider {
-
- private String x;
- private String y;
- private int result;
-
- public EditDistanceTest(String a, String b, int res) {
- super();
- x = a;
- y = b;
- result = res;
- }
-
- @Test
- public void testEditDistance_RecursiveImplementation() {
- assertEquals(result, EditDistanceRecursive.calculate(x, y));
- }
-
- @Test
- public void testEditDistance_givenDynamicProgrammingImplementation() {
- assertEquals(result, EditDistanceDynamicProgramming.calculate(x, y));
- }
-}
diff --git a/algorithms/src/test/java/com/baeldung/algorithms/editdistance/EditDistanceUnitTest.java b/algorithms/src/test/java/com/baeldung/algorithms/editdistance/EditDistanceUnitTest.java
new file mode 100644
index 0000000000..0df4715b80
--- /dev/null
+++ b/algorithms/src/test/java/com/baeldung/algorithms/editdistance/EditDistanceUnitTest.java
@@ -0,0 +1,32 @@
+package com.baeldung.algorithms.editdistance;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import static org.junit.Assert.assertEquals;
+
+@RunWith(Parameterized.class)
+public class EditDistanceUnitTest extends EditDistanceDataProvider {
+
+ private String x;
+ private String y;
+ private int result;
+
+ public EditDistanceUnitTest(String a, String b, int res) {
+ super();
+ x = a;
+ y = b;
+ result = res;
+ }
+
+ @Test
+ public void testEditDistance_RecursiveImplementation() {
+ assertEquals(result, EditDistanceRecursive.calculate(x, y));
+ }
+
+ @Test
+ public void testEditDistance_givenDynamicProgrammingImplementation() {
+ assertEquals(result, EditDistanceDynamicProgramming.calculate(x, y));
+ }
+}
diff --git a/algorithms/src/test/java/com/baeldung/algorithms/heapsort/HeapUnitTest.java b/algorithms/src/test/java/com/baeldung/algorithms/heapsort/HeapUnitTest.java
new file mode 100644
index 0000000000..96e4936eaf
--- /dev/null
+++ b/algorithms/src/test/java/com/baeldung/algorithms/heapsort/HeapUnitTest.java
@@ -0,0 +1,36 @@
+package com.baeldung.algorithms.heapsort;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.junit.Test;
+
+public class HeapUnitTest {
+
+ @Test
+ public void givenNotEmptyHeap_whenPopCalled_thenItShouldReturnSmallestElement() {
+ // given
+ Heap heap = Heap.of(3, 5, 1, 4, 2);
+
+ // when
+ int head = heap.pop();
+
+ // then
+ assertThat(head).isEqualTo(1);
+ }
+
+ @Test
+ public void givenNotEmptyIterable_whenSortCalled_thenItShouldReturnElementsInSortedList() {
+ // given
+ List elements = Arrays.asList(3, 5, 1, 4, 2);
+
+ // when
+ List sortedElements = Heap.sort(elements);
+
+ // then
+ assertThat(sortedElements).isEqualTo(Arrays.asList(1, 2, 3, 4, 5));
+ }
+
+}
diff --git a/algorithms/src/test/java/com/baeldung/algorithms/insertionsort/InsertionSortUnitTest.java b/algorithms/src/test/java/com/baeldung/algorithms/insertionsort/InsertionSortUnitTest.java
new file mode 100644
index 0000000000..b3d7e8c534
--- /dev/null
+++ b/algorithms/src/test/java/com/baeldung/algorithms/insertionsort/InsertionSortUnitTest.java
@@ -0,0 +1,25 @@
+package com.baeldung.algorithms.insertionsort;
+
+import com.baeldung.algorithms.insertionsort.InsertionSort;
+import org.junit.Test;
+
+import static org.junit.Assert.assertArrayEquals;
+
+public class InsertionSortUnitTest {
+
+ @Test
+ public void givenUnsortedArray_whenInsertionSortImperative_thenSortedAsc() {
+ int[] input = {6, 2, 3, 4, 5, 1};
+ InsertionSort.insertionSortImperative(input);
+ int[] expected = {1, 2, 3, 4, 5, 6};
+ assertArrayEquals("the two arrays are not equal", expected, input);
+ }
+
+ @Test
+ public void givenUnsortedArray_whenInsertionSortRecursive_thenSortedAsc() {
+ int[] input = {6, 4, 5, 2, 3, 1};
+ InsertionSort.insertionSortRecursive(input);
+ int[] expected = {1, 2, 3, 4, 5, 6};
+ assertArrayEquals("the two arrays are not equal", expected, input);
+ }
+}
diff --git a/algorithms/src/test/java/com/baeldung/algorithms/linesintersection/LinesIntersectionServiceUnitTest.java b/algorithms/src/test/java/com/baeldung/algorithms/linesintersection/LinesIntersectionServiceUnitTest.java
new file mode 100644
index 0000000000..22371107f3
--- /dev/null
+++ b/algorithms/src/test/java/com/baeldung/algorithms/linesintersection/LinesIntersectionServiceUnitTest.java
@@ -0,0 +1,40 @@
+package com.baeldung.algorithms.linesintersection;
+
+import java.awt.Point;
+import java.util.Optional;
+
+import org.junit.Test;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertEquals;
+
+public class LinesIntersectionServiceUnitTest {
+ private LinesIntersectionService service = new LinesIntersectionService();
+
+ @Test
+ public void givenNotParallelLines_whenCalculatePoint_thenPresent() {
+
+ double m1 = 0;
+ double b1 = 0;
+ double m2 = 1;
+ double b2 = -1;
+
+ Optional point = service.calculateIntersectionPoint(m1, b1, m2, b2);
+
+ assertTrue(point.isPresent());
+ assertEquals(point.get().getX(), 1, 0.001);
+ assertEquals(point.get().getY(), 0, 0.001);
+ }
+
+ @Test
+ public void givenParallelLines_whenCalculatePoint_thenEmpty() {
+ double m1 = 1;
+ double b1 = 0;
+ double m2 = 1;
+ double b2 = -1;
+
+ Optional point = service.calculateIntersectionPoint(m1, b1, m2, b2);
+
+ assertFalse(point.isPresent());
+ }
+}
diff --git a/algorithms/src/test/java/com/baeldung/algorithms/linkedlist/CycleDetectionBruteForceTest.java b/algorithms/src/test/java/com/baeldung/algorithms/linkedlist/CycleDetectionBruteForceTest.java
deleted file mode 100644
index 7f9b8acdbd..0000000000
--- a/algorithms/src/test/java/com/baeldung/algorithms/linkedlist/CycleDetectionBruteForceTest.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package com.baeldung.algorithms.linkedlist;
-
-import org.junit.Assert;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-
-@RunWith(value = Parameterized.class)
-public class CycleDetectionBruteForceTest extends CycleDetectionTestBase {
- boolean cycleExists;
- Node head;
-
- public CycleDetectionBruteForceTest(Node head, boolean cycleExists) {
- super();
- this.cycleExists = cycleExists;
- this.head = head;
- }
-
- @Test
- public void givenList_detectLoop() {
- Assert.assertEquals(cycleExists, CycleDetectionBruteForce.detectCycle(head).cycleExists);
- }
-}
diff --git a/algorithms/src/test/java/com/baeldung/algorithms/linkedlist/CycleDetectionBruteForceUnitTest.java b/algorithms/src/test/java/com/baeldung/algorithms/linkedlist/CycleDetectionBruteForceUnitTest.java
new file mode 100644
index 0000000000..af2430ec55
--- /dev/null
+++ b/algorithms/src/test/java/com/baeldung/algorithms/linkedlist/CycleDetectionBruteForceUnitTest.java
@@ -0,0 +1,23 @@
+package com.baeldung.algorithms.linkedlist;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@RunWith(value = Parameterized.class)
+public class CycleDetectionBruteForceUnitTest extends CycleDetectionTestBase {
+ boolean cycleExists;
+ Node head;
+
+ public CycleDetectionBruteForceUnitTest(Node head, boolean cycleExists) {
+ super();
+ this.cycleExists = cycleExists;
+ this.head = head;
+ }
+
+ @Test
+ public void givenList_detectLoop() {
+ Assert.assertEquals(cycleExists, CycleDetectionBruteForce.detectCycle(head).cycleExists);
+ }
+}
diff --git a/algorithms/src/test/java/com/baeldung/algorithms/linkedlist/CycleDetectionByFastAndSlowIteratorsTest.java b/algorithms/src/test/java/com/baeldung/algorithms/linkedlist/CycleDetectionByFastAndSlowIteratorsTest.java
deleted file mode 100644
index 17d339bc33..0000000000
--- a/algorithms/src/test/java/com/baeldung/algorithms/linkedlist/CycleDetectionByFastAndSlowIteratorsTest.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package com.baeldung.algorithms.linkedlist;
-
-import org.junit.Assert;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-
-@RunWith(value = Parameterized.class)
-public class CycleDetectionByFastAndSlowIteratorsTest extends CycleDetectionTestBase {
- boolean cycleExists;
- Node head;
-
- public CycleDetectionByFastAndSlowIteratorsTest(Node head, boolean cycleExists) {
- super();
- this.cycleExists = cycleExists;
- this.head = head;
- }
-
- @Test
- public void givenList_detectLoop() {
- Assert.assertEquals(cycleExists, CycleDetectionByFastAndSlowIterators.detectCycle(head).cycleExists);
- }
-}
diff --git a/algorithms/src/test/java/com/baeldung/algorithms/linkedlist/CycleDetectionByFastAndSlowIteratorsUnitTest.java b/algorithms/src/test/java/com/baeldung/algorithms/linkedlist/CycleDetectionByFastAndSlowIteratorsUnitTest.java
new file mode 100644
index 0000000000..ce31c84067
--- /dev/null
+++ b/algorithms/src/test/java/com/baeldung/algorithms/linkedlist/CycleDetectionByFastAndSlowIteratorsUnitTest.java
@@ -0,0 +1,23 @@
+package com.baeldung.algorithms.linkedlist;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@RunWith(value = Parameterized.class)
+public class CycleDetectionByFastAndSlowIteratorsUnitTest extends CycleDetectionTestBase {
+ boolean cycleExists;
+ Node head;
+
+ public CycleDetectionByFastAndSlowIteratorsUnitTest(Node head, boolean cycleExists) {
+ super();
+ this.cycleExists = cycleExists;
+ this.head = head;
+ }
+
+ @Test
+ public void givenList_detectLoop() {
+ Assert.assertEquals(cycleExists, CycleDetectionByFastAndSlowIterators.detectCycle(head).cycleExists);
+ }
+}
diff --git a/algorithms/src/test/java/com/baeldung/algorithms/linkedlist/CycleDetectionByHashingTest.java b/algorithms/src/test/java/com/baeldung/algorithms/linkedlist/CycleDetectionByHashingTest.java
deleted file mode 100644
index 73a2cc7861..0000000000
--- a/algorithms/src/test/java/com/baeldung/algorithms/linkedlist/CycleDetectionByHashingTest.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package com.baeldung.algorithms.linkedlist;
-
-import org.junit.Assert;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-
-@RunWith(value = Parameterized.class)
-public class CycleDetectionByHashingTest extends CycleDetectionTestBase {
- boolean cycleExists;
- Node head;
-
- public CycleDetectionByHashingTest(Node head, boolean cycleExists) {
- super();
- this.cycleExists = cycleExists;
- this.head = head;
- }
-
- @Test
- public void givenList_detectLoop() {
- Assert.assertEquals(cycleExists, CycleDetectionByHashing.detectCycle(head).cycleExists);
- }
-}
diff --git a/algorithms/src/test/java/com/baeldung/algorithms/linkedlist/CycleDetectionByHashingUnitTest.java b/algorithms/src/test/java/com/baeldung/algorithms/linkedlist/CycleDetectionByHashingUnitTest.java
new file mode 100644
index 0000000000..4451c3d3c9
--- /dev/null
+++ b/algorithms/src/test/java/com/baeldung/algorithms/linkedlist/CycleDetectionByHashingUnitTest.java
@@ -0,0 +1,23 @@
+package com.baeldung.algorithms.linkedlist;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@RunWith(value = Parameterized.class)
+public class CycleDetectionByHashingUnitTest extends CycleDetectionTestBase {
+ boolean cycleExists;
+ Node head;
+
+ public CycleDetectionByHashingUnitTest(Node head, boolean cycleExists) {
+ super();
+ this.cycleExists = cycleExists;
+ this.head = head;
+ }
+
+ @Test
+ public void givenList_detectLoop() {
+ Assert.assertEquals(cycleExists, CycleDetectionByHashing.detectCycle(head).cycleExists);
+ }
+}
diff --git a/algorithms/src/test/java/com/baeldung/algorithms/linkedlist/CycleRemovalBruteForceTest.java b/algorithms/src/test/java/com/baeldung/algorithms/linkedlist/CycleRemovalBruteForceTest.java
deleted file mode 100644
index 6484c9988e..0000000000
--- a/algorithms/src/test/java/com/baeldung/algorithms/linkedlist/CycleRemovalBruteForceTest.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package com.baeldung.algorithms.linkedlist;
-
-import org.junit.Assert;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-
-@RunWith(value = Parameterized.class)
-public class CycleRemovalBruteForceTest extends CycleDetectionTestBase {
- boolean cycleExists;
- Node head;
-
- public CycleRemovalBruteForceTest(Node head, boolean cycleExists) {
- super();
- this.cycleExists = cycleExists;
- this.head = head;
- }
-
- @Test
- public void givenList_ifLoopExists_thenDetectAndRemoveLoop() {
- Assert.assertEquals(cycleExists, CycleRemovalBruteForce.detectAndRemoveCycle(head));
- Assert.assertFalse(CycleDetectionByFastAndSlowIterators.detectCycle(head).cycleExists);
- }
-}
diff --git a/algorithms/src/test/java/com/baeldung/algorithms/linkedlist/CycleRemovalBruteForceUnitTest.java b/algorithms/src/test/java/com/baeldung/algorithms/linkedlist/CycleRemovalBruteForceUnitTest.java
new file mode 100644
index 0000000000..f69e3c35ba
--- /dev/null
+++ b/algorithms/src/test/java/com/baeldung/algorithms/linkedlist/CycleRemovalBruteForceUnitTest.java
@@ -0,0 +1,24 @@
+package com.baeldung.algorithms.linkedlist;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@RunWith(value = Parameterized.class)
+public class CycleRemovalBruteForceUnitTest extends CycleDetectionTestBase {
+ boolean cycleExists;
+ Node head;
+
+ public CycleRemovalBruteForceUnitTest(Node head, boolean cycleExists) {
+ super();
+ this.cycleExists = cycleExists;
+ this.head = head;
+ }
+
+ @Test
+ public void givenList_ifLoopExists_thenDetectAndRemoveLoop() {
+ Assert.assertEquals(cycleExists, CycleRemovalBruteForce.detectAndRemoveCycle(head));
+ Assert.assertFalse(CycleDetectionByFastAndSlowIterators.detectCycle(head).cycleExists);
+ }
+}
diff --git a/algorithms/src/test/java/com/baeldung/algorithms/linkedlist/CycleRemovalByCountingLoopNodesTest.java b/algorithms/src/test/java/com/baeldung/algorithms/linkedlist/CycleRemovalByCountingLoopNodesTest.java
deleted file mode 100644
index 7bfd89c502..0000000000
--- a/algorithms/src/test/java/com/baeldung/algorithms/linkedlist/CycleRemovalByCountingLoopNodesTest.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package com.baeldung.algorithms.linkedlist;
-
-import org.junit.Assert;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-
-@RunWith(value = Parameterized.class)
-public class CycleRemovalByCountingLoopNodesTest extends CycleDetectionTestBase {
- boolean cycleExists;
- Node head;
-
- public CycleRemovalByCountingLoopNodesTest(Node head, boolean cycleExists) {
- super();
- this.cycleExists = cycleExists;
- this.head = head;
- }
-
- @Test
- public void givenList_ifLoopExists_thenDetectAndRemoveLoop() {
- Assert.assertEquals(cycleExists, CycleRemovalByCountingLoopNodes.detectAndRemoveCycle(head));
- Assert.assertFalse(CycleDetectionByFastAndSlowIterators.detectCycle(head).cycleExists);
- }
-}
diff --git a/algorithms/src/test/java/com/baeldung/algorithms/linkedlist/CycleRemovalByCountingLoopNodesUnitTest.java b/algorithms/src/test/java/com/baeldung/algorithms/linkedlist/CycleRemovalByCountingLoopNodesUnitTest.java
new file mode 100644
index 0000000000..c17aa6eeab
--- /dev/null
+++ b/algorithms/src/test/java/com/baeldung/algorithms/linkedlist/CycleRemovalByCountingLoopNodesUnitTest.java
@@ -0,0 +1,24 @@
+package com.baeldung.algorithms.linkedlist;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@RunWith(value = Parameterized.class)
+public class CycleRemovalByCountingLoopNodesUnitTest extends CycleDetectionTestBase {
+ boolean cycleExists;
+ Node head;
+
+ public CycleRemovalByCountingLoopNodesUnitTest(Node head, boolean cycleExists) {
+ super();
+ this.cycleExists = cycleExists;
+ this.head = head;
+ }
+
+ @Test
+ public void givenList_ifLoopExists_thenDetectAndRemoveLoop() {
+ Assert.assertEquals(cycleExists, CycleRemovalByCountingLoopNodes.detectAndRemoveCycle(head));
+ Assert.assertFalse(CycleDetectionByFastAndSlowIterators.detectCycle(head).cycleExists);
+ }
+}
diff --git a/algorithms/src/test/java/com/baeldung/algorithms/linkedlist/CycleRemovalWithoutCountingLoopNodesTest.java b/algorithms/src/test/java/com/baeldung/algorithms/linkedlist/CycleRemovalWithoutCountingLoopNodesTest.java
deleted file mode 100644
index c77efb3e3e..0000000000
--- a/algorithms/src/test/java/com/baeldung/algorithms/linkedlist/CycleRemovalWithoutCountingLoopNodesTest.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package com.baeldung.algorithms.linkedlist;
-
-import org.junit.Assert;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-
-@RunWith(value = Parameterized.class)
-public class CycleRemovalWithoutCountingLoopNodesTest extends CycleDetectionTestBase {
- boolean cycleExists;
- Node head;
-
- public CycleRemovalWithoutCountingLoopNodesTest(Node head, boolean cycleExists) {
- super();
- this.cycleExists = cycleExists;
- this.head = head;
- }
-
- @Test
- public void givenList_ifLoopExists_thenDetectAndRemoveLoop() {
- Assert.assertEquals(cycleExists, CycleRemovalWithoutCountingLoopNodes.detectAndRemoveCycle(head));
- Assert.assertFalse(CycleDetectionByFastAndSlowIterators.detectCycle(head).cycleExists);
- }
-}
\ No newline at end of file
diff --git a/algorithms/src/test/java/com/baeldung/algorithms/linkedlist/CycleRemovalWithoutCountingLoopNodesUnitTest.java b/algorithms/src/test/java/com/baeldung/algorithms/linkedlist/CycleRemovalWithoutCountingLoopNodesUnitTest.java
new file mode 100644
index 0000000000..06ff840a59
--- /dev/null
+++ b/algorithms/src/test/java/com/baeldung/algorithms/linkedlist/CycleRemovalWithoutCountingLoopNodesUnitTest.java
@@ -0,0 +1,24 @@
+package com.baeldung.algorithms.linkedlist;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@RunWith(value = Parameterized.class)
+public class CycleRemovalWithoutCountingLoopNodesUnitTest extends CycleDetectionTestBase {
+ boolean cycleExists;
+ Node head;
+
+ public CycleRemovalWithoutCountingLoopNodesUnitTest(Node head, boolean cycleExists) {
+ super();
+ this.cycleExists = cycleExists;
+ this.head = head;
+ }
+
+ @Test
+ public void givenList_ifLoopExists_thenDetectAndRemoveLoop() {
+ Assert.assertEquals(cycleExists, CycleRemovalWithoutCountingLoopNodes.detectAndRemoveCycle(head));
+ Assert.assertFalse(CycleDetectionByFastAndSlowIterators.detectCycle(head).cycleExists);
+ }
+}
\ No newline at end of file
diff --git a/algorithms/src/test/java/com/baeldung/algorithms/mcts/MCTSUnitTest.java b/algorithms/src/test/java/com/baeldung/algorithms/mcts/MCTSUnitTest.java
new file mode 100644
index 0000000000..59afed65de
--- /dev/null
+++ b/algorithms/src/test/java/com/baeldung/algorithms/mcts/MCTSUnitTest.java
@@ -0,0 +1,92 @@
+package com.baeldung.algorithms.mcts;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.util.List;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import com.baeldung.algorithms.mcts.montecarlo.MonteCarloTreeSearch;
+import com.baeldung.algorithms.mcts.montecarlo.State;
+import com.baeldung.algorithms.mcts.montecarlo.UCT;
+import com.baeldung.algorithms.mcts.tictactoe.Board;
+import com.baeldung.algorithms.mcts.tictactoe.Position;
+import com.baeldung.algorithms.mcts.tree.Tree;
+
+public class MCTSUnitTest {
+ private Tree gameTree;
+ private MonteCarloTreeSearch mcts;
+
+ @Before
+ public void initGameTree() {
+ gameTree = new Tree();
+ mcts = new MonteCarloTreeSearch();
+ }
+
+ @Test
+ public void givenStats_whenGetUCTForNode_thenUCTMatchesWithManualData() {
+ double uctValue = 15.79;
+ assertEquals(UCT.uctValue(600, 300, 20), uctValue, 0.01);
+ }
+
+ @Test
+ public void giveninitBoardState_whenGetAllPossibleStates_thenNonEmptyList() {
+ State initState = gameTree.getRoot().getState();
+ List possibleStates = initState.getAllPossibleStates();
+ assertTrue(possibleStates.size() > 0);
+ }
+
+ @Test
+ public void givenEmptyBoard_whenPerformMove_thenLessAvailablePossitions() {
+ Board board = new Board();
+ int initAvailablePositions = board.getEmptyPositions().size();
+ board.performMove(Board.P1, new Position(1, 1));
+ int availablePositions = board.getEmptyPositions().size();
+ assertTrue(initAvailablePositions > availablePositions);
+ }
+
+ @Test
+ public void givenEmptyBoard_whenSimulateInterAIPlay_thenGameDraw() {
+ Board board = new Board();
+
+ int player = Board.P1;
+ int totalMoves = Board.DEFAULT_BOARD_SIZE * Board.DEFAULT_BOARD_SIZE;
+ for (int i = 0; i < totalMoves; i++) {
+ board = mcts.findNextMove(board, player);
+ if (board.checkStatus() != -1) {
+ break;
+ }
+ player = 3 - player;
+ }
+ int winStatus = board.checkStatus();
+ assertEquals(winStatus, Board.DRAW);
+ }
+
+ @Test
+ public void givenEmptyBoard_whenLevel1VsLevel3_thenLevel3WinsOrDraw() {
+ Board board = new Board();
+ MonteCarloTreeSearch mcts1 = new MonteCarloTreeSearch();
+ mcts1.setLevel(1);
+ MonteCarloTreeSearch mcts3 = new MonteCarloTreeSearch();
+ mcts3.setLevel(3);
+
+ int player = Board.P1;
+ int totalMoves = Board.DEFAULT_BOARD_SIZE * Board.DEFAULT_BOARD_SIZE;
+ for (int i = 0; i < totalMoves; i++) {
+ if (player == Board.P1)
+ board = mcts3.findNextMove(board, player);
+ else
+ board = mcts1.findNextMove(board, player);
+
+ if (board.checkStatus() != -1) {
+ break;
+ }
+ player = 3 - player;
+ }
+ int winStatus = board.checkStatus();
+ assertTrue(winStatus == Board.DRAW || winStatus == Board.P1);
+ }
+
+}
diff --git a/algorithms/src/test/java/com/baeldung/algorithms/mergesort/MergeSortUnitTest.java b/algorithms/src/test/java/com/baeldung/algorithms/mergesort/MergeSortUnitTest.java
new file mode 100644
index 0000000000..5cd14b7bd0
--- /dev/null
+++ b/algorithms/src/test/java/com/baeldung/algorithms/mergesort/MergeSortUnitTest.java
@@ -0,0 +1,17 @@
+package com.baeldung.algorithms.mergesort;
+
+import org.junit.Assert;
+
+import org.junit.Test;
+
+public class MergeSortUnitTest {
+
+ @Test
+ public void positiveTest() {
+ int[] actual = { 5, 1, 6, 2, 3, 4 };
+ int[] expected = { 1, 2, 3, 4, 5, 6 };
+ MergeSort.mergeSort(actual, actual.length);
+ Assert.assertArrayEquals(expected, actual);
+ }
+
+}
diff --git a/algorithms/src/test/java/com/baeldung/algorithms/minimax/MinimaxUnitTest.java b/algorithms/src/test/java/com/baeldung/algorithms/minimax/MinimaxUnitTest.java
new file mode 100644
index 0000000000..59f0fcf053
--- /dev/null
+++ b/algorithms/src/test/java/com/baeldung/algorithms/minimax/MinimaxUnitTest.java
@@ -0,0 +1,36 @@
+package com.baeldung.algorithms.minimax;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+import com.baeldung.algorithms.minimax.MiniMax;
+import com.baeldung.algorithms.minimax.Tree;
+
+public class MinimaxUnitTest {
+ private Tree gameTree;
+ private MiniMax miniMax;
+
+ @Before
+ public void initMiniMaxUtility() {
+ miniMax = new MiniMax();
+ }
+
+ @Test
+ public void givenMiniMax_whenConstructTree_thenNotNullTree() {
+ assertNull(gameTree);
+ miniMax.constructTree(6);
+ gameTree = miniMax.getTree();
+ assertNotNull(gameTree);
+ }
+
+ @Test
+ public void givenMiniMax_whenCheckWin_thenComputeOptimal() {
+ miniMax.constructTree(6);
+ boolean result = miniMax.checkWin();
+ assertTrue(result);
+ miniMax.constructTree(8);
+ result = miniMax.checkWin();
+ assertFalse(result);
+ }
+}
diff --git a/algorithms/src/test/java/com/baeldung/algorithms/moneywords/NumberWordConverterUnitTest.java b/algorithms/src/test/java/com/baeldung/algorithms/moneywords/NumberWordConverterUnitTest.java
new file mode 100644
index 0000000000..26643e9c1e
--- /dev/null
+++ b/algorithms/src/test/java/com/baeldung/algorithms/moneywords/NumberWordConverterUnitTest.java
@@ -0,0 +1,84 @@
+package com.baeldung.algorithms.moneywords;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+import com.baeldung.algorithms.numberwordconverter.NumberWordConverter;
+
+public class NumberWordConverterUnitTest {
+
+ @Test
+ public void whenMoneyNegative_thenReturnInvalidInput() {
+ assertEquals(NumberWordConverter.INVALID_INPUT_GIVEN, NumberWordConverter.getMoneyIntoWords(-13));
+ }
+
+ @Test
+ public void whenZeroDollarsGiven_thenReturnEmptyString() {
+ assertEquals("", NumberWordConverter.getMoneyIntoWords(0));
+ }
+
+ @Test
+ public void whenOnlyDollarsGiven_thenReturnWords() {
+ assertEquals("one dollar", NumberWordConverter.getMoneyIntoWords(1));
+ }
+
+ @Test
+ public void whenOnlyCentsGiven_thenReturnWords() {
+ assertEquals("sixty cents", NumberWordConverter.getMoneyIntoWords(0.6));
+ }
+
+ @Test
+ public void whenAlmostAMillioDollarsGiven_thenReturnWords() {
+ String expectedResult = "nine hundred ninety nine thousand nine hundred ninety nine dollars";
+ assertEquals(expectedResult, NumberWordConverter.getMoneyIntoWords(999_999));
+ }
+
+ @Test
+ public void whenThirtyMillionDollarsGiven_thenReturnWords() {
+ String expectedResult = "thirty three million three hundred forty eight thousand nine hundred seventy eight dollars";
+ assertEquals(expectedResult, NumberWordConverter.getMoneyIntoWords(33_348_978));
+ }
+
+ @Test
+ public void whenTwoBillionDollarsGiven_thenReturnWords() {
+ String expectedResult = "two billion one hundred thirty three million two hundred forty seven thousand eight hundred ten dollars";
+ assertEquals(expectedResult, NumberWordConverter.getMoneyIntoWords(2_133_247_810));
+ }
+
+ @Test
+ public void whenGivenDollarsAndCents_thenReturnWords() {
+ String expectedResult = "nine hundred twenty four dollars and sixty cents";
+ assertEquals(expectedResult, NumberWordConverter.getMoneyIntoWords(924.6));
+ }
+
+ @Test
+ public void whenOneDollarAndNoCents_thenReturnDollarSingular() {
+ assertEquals("one dollar", NumberWordConverter.getMoneyIntoWords(1));
+ }
+
+ @Test
+ public void whenNoDollarsAndOneCent_thenReturnCentSingular() {
+ assertEquals("one cent", NumberWordConverter.getMoneyIntoWords(0.01));
+ }
+
+ @Test
+ public void whenNoDollarsAndTwoCents_thenReturnCentsPlural() {
+ assertEquals("two cents", NumberWordConverter.getMoneyIntoWords(0.02));
+ }
+
+ @Test
+ public void whenNoDollarsAndNinetyNineCents_thenReturnWords() {
+ assertEquals("ninety nine cents", NumberWordConverter.getMoneyIntoWords(0.99));
+ }
+
+ @Test
+ public void whenNoDollarsAndNineFiveNineCents_thenCorrectRounding() {
+ assertEquals("ninety six cents", NumberWordConverter.getMoneyIntoWords(0.959));
+ }
+
+ @Test
+ public void whenGivenDollarsAndCents_thenReturnWordsVersionTwo() {
+ assertEquals("three hundred ten £ 00/100", NumberWordConverter.getMoneyIntoWords("310"));
+ }
+}
diff --git a/algorithms/src/test/java/com/baeldung/algorithms/multiswarm/LolFitnessFunction.java b/algorithms/src/test/java/com/baeldung/algorithms/multiswarm/LolFitnessFunction.java
new file mode 100644
index 0000000000..726d4c135d
--- /dev/null
+++ b/algorithms/src/test/java/com/baeldung/algorithms/multiswarm/LolFitnessFunction.java
@@ -0,0 +1,52 @@
+package com.baeldung.algorithms.multiswarm;
+
+/**
+ * Specific fitness function implementation to solve the League of Legends
+ * problem. This is the problem statement:
+ *
+ * In League of Legends, a player's Effective Health when defending against
+ * physical damage is given by E=H(100+A)/100, where H is health and A is armor.
+ * Health costs 2.5 gold per unit, and Armor costs 18 gold per unit. You have
+ * 3600 gold, and you need to optimize the effectiveness E of your health and
+ * armor to survive as long as possible against the enemy team's attacks. How
+ * much of each should you buy?
+ *
+ *
+ * @author Donato Rimenti
+ *
+ */
+public class LolFitnessFunction implements FitnessFunction {
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.baeldung.algorithms.multiswarm.FitnessFunction#getFitness(long[])
+ */
+ @Override
+ public double getFitness(long[] particlePosition) {
+
+ long health = particlePosition[0];
+ long armor = particlePosition[1];
+
+ // No negatives values accepted.
+ if (health < 0 && armor < 0) {
+ return -(health * armor);
+ } else if (health < 0) {
+ return health;
+ } else if (armor < 0) {
+ return armor;
+ }
+
+ // Checks if the solution is actually feasible provided our gold.
+ double cost = (health * 2.5) + (armor * 18);
+ if (cost > 3600) {
+ return 3600 - cost;
+ } else {
+ // Check how good is the solution.
+ long fitness = (health * (100 + armor)) / 100;
+ return fitness;
+ }
+ }
+
+}
diff --git a/algorithms/src/test/java/com/baeldung/algorithms/multiswarm/MultiswarmUnitTest.java b/algorithms/src/test/java/com/baeldung/algorithms/multiswarm/MultiswarmUnitTest.java
new file mode 100644
index 0000000000..3455cd3932
--- /dev/null
+++ b/algorithms/src/test/java/com/baeldung/algorithms/multiswarm/MultiswarmUnitTest.java
@@ -0,0 +1,54 @@
+package com.baeldung.algorithms.multiswarm;
+
+import org.junit.Assert;
+import org.junit.Rule;
+import org.junit.Test;
+
+import com.baeldung.algorithms.support.MayFailRule;
+
+/**
+ * Test for {@link Multiswarm}.
+ *
+ * @author Donato Rimenti
+ *
+ */
+public class MultiswarmUnitTest {
+
+ /**
+ * Rule for handling expected failures. We use this since this test may
+ * actually fail due to bad luck in the random generation.
+ */
+ @Rule
+ public MayFailRule mayFailRule = new MayFailRule();
+
+ /**
+ * Tests the multiswarm algorithm with a generic problem. The problem is the
+ * following:
+ *
+ * In League of Legends, a player's Effective Health when defending against
+ * physical damage is given by E=H(100+A)/100, where H is health and A is
+ * armor. Health costs 2.5 gold per unit, and Armor costs 18 gold per unit.
+ * You have 3600 gold, and you need to optimize the effectiveness E of your
+ * health and armor to survive as long as possible against the enemy team's
+ * attacks. How much of each should you buy?
+ *
+ * The solution is H = 1080, A = 50 for a total fitness of 1620. Tested with
+ * 50 swarms each with 1000 particles.
+ */
+ @Test
+ public void givenMultiswarm_whenThousandIteration_thenSolutionFound() {
+ Multiswarm multiswarm = new Multiswarm(50, 1000, new LolFitnessFunction());
+
+ // Iterates 1000 times through the main loop and prints the result.
+ for (int i = 0; i < 1000; i++) {
+ multiswarm.mainLoop();
+ }
+
+ System.out.println("Best fitness found: " + multiswarm.getBestFitness() + "[" + multiswarm.getBestPosition()[0]
+ + "," + multiswarm.getBestPosition()[1] + "]");
+ Assert.assertEquals(1080, multiswarm.getBestPosition()[0]);
+ Assert.assertEquals(50, multiswarm.getBestPosition()[1]);
+ Assert.assertEquals(1620, (int) multiswarm.getBestFitness());
+ }
+
+}
diff --git a/algorithms/src/test/java/com/baeldung/algorithms/prime/PrimeGeneratorTest.java b/algorithms/src/test/java/com/baeldung/algorithms/prime/PrimeGeneratorTest.java
deleted file mode 100644
index 4995e938b7..0000000000
--- a/algorithms/src/test/java/com/baeldung/algorithms/prime/PrimeGeneratorTest.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package com.baeldung.algorithms.prime;
-
-import static com.baeldung.algorithms.prime.PrimeGenerator.*;
-
-import java.util.Arrays;
-import java.util.List;
-import org.junit.Test;
-import static org.junit.Assert.*;
-
-public class PrimeGeneratorTest {
- @Test
- public void whenBruteForced_returnsSuccessfully() {
- final List primeNumbers = primeNumbersBruteForce(20);
- assertEquals(Arrays.asList(new Integer[] { 2, 3, 5, 7, 11, 13, 17, 19 }), primeNumbers);
- }
-
- @Test
- public void whenOptimized_returnsSuccessfully() {
- final List primeNumbers = primeNumbersTill(20);
- assertEquals(Arrays.asList(new Integer[] { 2, 3, 5, 7, 11, 13, 17, 19 }), primeNumbers);
- }
-
- @Test
- public void whenSieveOfEratosthenes_returnsSuccessfully() {
- final List primeNumbers = sieveOfEratosthenes(20);
- assertEquals(Arrays.asList(new Integer[] { 2, 3, 5, 7, 11, 13, 17, 19 }), primeNumbers);
- }
-}
diff --git a/algorithms/src/test/java/com/baeldung/algorithms/quicksort/QuickSortUnitTest.java b/algorithms/src/test/java/com/baeldung/algorithms/quicksort/QuickSortUnitTest.java
new file mode 100644
index 0000000000..c9af5b4bf8
--- /dev/null
+++ b/algorithms/src/test/java/com/baeldung/algorithms/quicksort/QuickSortUnitTest.java
@@ -0,0 +1,17 @@
+package com.baeldung.algorithms.quicksort;
+
+import com.baeldung.algorithms.quicksort.QuickSort;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class QuickSortUnitTest {
+
+ @Test
+ public void givenIntegerArray_whenSortedWithQuickSort_thenGetSortedArray() {
+ int[] actual = { 9, 5, 1, 0, 6, 2, 3, 4, 7, 8 };
+ int[] expected = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
+ QuickSort.quickSort(actual, 0, actual.length-1);
+ Assert.assertArrayEquals(expected, actual);
+ }
+
+}
diff --git a/algorithms/src/test/java/com/baeldung/algorithms/quicksort/ThreeWayQuickSortUnitTest.java b/algorithms/src/test/java/com/baeldung/algorithms/quicksort/ThreeWayQuickSortUnitTest.java
new file mode 100644
index 0000000000..cd8c7c1241
--- /dev/null
+++ b/algorithms/src/test/java/com/baeldung/algorithms/quicksort/ThreeWayQuickSortUnitTest.java
@@ -0,0 +1,15 @@
+package com.baeldung.algorithms.quicksort;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class ThreeWayQuickSortUnitTest {
+
+ @Test
+ public void givenIntegerArray_whenSortedWithThreeWayQuickSort_thenGetSortedArray() {
+ int[] actual = { 3, 5, 5, 5, 3, 7, 7, 3, 5, 5, 7, 3, 3 };
+ int[] expected = { 3, 3, 3, 3, 3, 5, 5, 5, 5, 5, 7, 7, 7 };
+ ThreeWayQuickSort.threeWayQuickSort(actual, 0, actual.length-1);
+ Assert.assertArrayEquals(expected, actual);
+ }
+}
diff --git a/algorithms/src/test/java/com/baeldung/algorithms/rectanglesoverlap/RectangleUnitTest.java b/algorithms/src/test/java/com/baeldung/algorithms/rectanglesoverlap/RectangleUnitTest.java
new file mode 100644
index 0000000000..6707b34477
--- /dev/null
+++ b/algorithms/src/test/java/com/baeldung/algorithms/rectanglesoverlap/RectangleUnitTest.java
@@ -0,0 +1,42 @@
+package com.baeldung.algorithms.rectanglesoverlap;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertFalse;
+import org.junit.Test;
+
+import com.baeldung.algorithms.rectanglesoverlap.Point;
+import com.baeldung.algorithms.rectanglesoverlap.Rectangle;
+
+public class RectangleUnitTest {
+
+ @Test
+ public void givenTwoOverlappingRectangles_whenisOverlappingCalled_shouldReturnTrue() {
+ Rectangle rectangle1 = new Rectangle(new Point(2, 1), new Point(4, 3));
+ Rectangle rectangle2 = new Rectangle(new Point(1, 1), new Point(6, 4));
+ assertTrue(rectangle1.isOverlapping(rectangle2));
+
+ rectangle1 = new Rectangle(new Point(-5, -2), new Point(2, 3));
+ rectangle2 = new Rectangle(new Point(-2, -1), new Point(5, 2));
+ assertTrue(rectangle1.isOverlapping(rectangle2));
+
+ rectangle1 = new Rectangle(new Point(-5, 1), new Point(2, 4));
+ rectangle2 = new Rectangle(new Point(-2, -2), new Point(5, 5));
+ assertTrue(rectangle1.isOverlapping(rectangle2));
+ }
+
+ @Test
+ public void givenTwoNonOverlappingRectangles_whenisOverlappingCalled_shouldReturnFalse() {
+ Rectangle rectangle1 = new Rectangle(new Point(-5, 1), new Point(-3, 4));
+ Rectangle rectangle2 = new Rectangle(new Point(-2, -2), new Point(5, 5));
+ assertFalse(rectangle1.isOverlapping(rectangle2));
+
+ rectangle1 = new Rectangle(new Point(-5, 1), new Point(3, 4));
+ rectangle2 = new Rectangle(new Point(-2, -2), new Point(5, -1));
+ assertFalse(rectangle1.isOverlapping(rectangle2));
+
+ rectangle1 = new Rectangle(new Point(-2, 1), new Point(0, 3));
+ rectangle2 = new Rectangle(new Point(3, 1), new Point(5, 4));
+ assertFalse(rectangle1.isOverlapping(rectangle2));
+ }
+
+}
diff --git a/algorithms/src/test/java/com/baeldung/algorithms/romannumerals/RomanArabicConverterUnitTest.java b/algorithms/src/test/java/com/baeldung/algorithms/romannumerals/RomanArabicConverterUnitTest.java
new file mode 100644
index 0000000000..b289ec6bc9
--- /dev/null
+++ b/algorithms/src/test/java/com/baeldung/algorithms/romannumerals/RomanArabicConverterUnitTest.java
@@ -0,0 +1,29 @@
+package com.baeldung.algorithms.romannumerals;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.junit.Test;
+
+public class RomanArabicConverterUnitTest {
+
+ @Test
+ public void given2018Roman_WhenConvertingToArabic_ThenReturn2018() {
+
+ String roman2018 = "MMXVIII";
+
+ int result = RomanArabicConverter.romanToArabic(roman2018);
+
+ assertThat(result).isEqualTo(2018);
+ }
+
+ @Test
+ public void given1999Arabic_WhenConvertingToRoman_ThenReturnMCMXCIX() {
+
+ int arabic1999 = 1999;
+
+ String result = RomanArabicConverter.arabicToRoman(arabic1999);
+
+ assertThat(result).isEqualTo("MCMXCIX");
+ }
+
+}
diff --git a/algorithms/src/test/java/com/baeldung/algorithms/string/EnglishAlphabetLettersUnitTest.java b/algorithms/src/test/java/com/baeldung/algorithms/string/EnglishAlphabetLettersUnitTest.java
new file mode 100644
index 0000000000..54863cddc8
--- /dev/null
+++ b/algorithms/src/test/java/com/baeldung/algorithms/string/EnglishAlphabetLettersUnitTest.java
@@ -0,0 +1,20 @@
+package com.baeldung.algorithms.string;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+public class EnglishAlphabetLettersUnitTest {
+
+ @Test
+ void givenString_whenContainsAllCharacter_thenTrue() {
+ String input = "Farmer jack realized that big yellow quilts were expensive";
+ Assertions.assertTrue(EnglishAlphabetLetters.checkStringForAllTheLetters(input));
+ }
+
+ @Test
+ void givenString_whenContainsAllCharacter_thenUsingStreamExpectTrue() {
+ String input = "Farmer jack realized that big yellow quilts were expensive";
+ Assertions.assertTrue(EnglishAlphabetLetters.checkStringForAllLetterUsingStream(input));
+ }
+
+}
diff --git a/algorithms/src/test/java/com/baeldung/algorithms/support/MayFailRule.java b/algorithms/src/test/java/com/baeldung/algorithms/support/MayFailRule.java
new file mode 100644
index 0000000000..91df78ce4a
--- /dev/null
+++ b/algorithms/src/test/java/com/baeldung/algorithms/support/MayFailRule.java
@@ -0,0 +1,38 @@
+package com.baeldung.algorithms.support;
+
+import org.junit.Rule;
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+/**
+ * JUnit custom rule for managing tests that may fail due to heuristics or
+ * randomness. In order to use this, just instantiate this object as a public
+ * field inside the test class and annotate it with {@link Rule}.
+ *
+ * @author Donato Rimenti
+ *
+ */
+public class MayFailRule implements TestRule {
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.junit.rules.TestRule#apply(org.junit.runners.model.Statement,
+ * org.junit.runner.Description)
+ */
+ @Override
+ public Statement apply(Statement base, Description description) {
+ return new Statement() {
+ @Override
+ public void evaluate() throws Throwable {
+ try {
+ base.evaluate();
+ } catch (Throwable e) {
+ // Ignore the exception since we expect this.
+ }
+ }
+ };
+ }
+
+}
diff --git a/algorithms/src/test/java/com/baeldung/jgrapht/CompleteGraphTest.java b/algorithms/src/test/java/com/baeldung/jgrapht/CompleteGraphTest.java
deleted file mode 100644
index c085d54689..0000000000
--- a/algorithms/src/test/java/com/baeldung/jgrapht/CompleteGraphTest.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package com.baeldung.jgrapht;
-
-import static org.junit.Assert.assertEquals;
-
-import java.util.List;
-
-import org.jgrapht.VertexFactory;
-import org.jgrapht.alg.HamiltonianCycle;
-import org.jgrapht.generate.CompleteGraphGenerator;
-import org.jgrapht.graph.DefaultEdge;
-import org.jgrapht.graph.SimpleWeightedGraph;
-import org.junit.Before;
-import org.junit.Test;
-
-public class CompleteGraphTest {
-
- static SimpleWeightedGraph completeGraph;
- static int size = 10;
-
- @Before
- public void createCompleteGraph() {
- completeGraph = new SimpleWeightedGraph<>(DefaultEdge.class);
- CompleteGraphGenerator completeGenerator = new CompleteGraphGenerator(size);
- VertexFactory vFactory = new VertexFactory() {
- private int id = 0;
- public String createVertex() {
- return "v" + id++;
- }
- };
- completeGenerator.generateGraph(completeGraph, vFactory, null);
- }
-
- @Test
- public void givenCompleteGraph_whenGetHamiltonianCyclePath_thenGetVerticeListInSequence() {
- List verticeList = HamiltonianCycle.getApproximateOptimalForCompleteGraph(completeGraph);
- assertEquals(verticeList.size(), completeGraph.vertexSet().size());
- }
-}
diff --git a/algorithms/src/test/java/com/baeldung/jgrapht/CompleteGraphUnitTest.java b/algorithms/src/test/java/com/baeldung/jgrapht/CompleteGraphUnitTest.java
new file mode 100644
index 0000000000..0b0d6ae822
--- /dev/null
+++ b/algorithms/src/test/java/com/baeldung/jgrapht/CompleteGraphUnitTest.java
@@ -0,0 +1,38 @@
+package com.baeldung.jgrapht;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.List;
+
+import org.jgrapht.VertexFactory;
+import org.jgrapht.alg.HamiltonianCycle;
+import org.jgrapht.generate.CompleteGraphGenerator;
+import org.jgrapht.graph.DefaultEdge;
+import org.jgrapht.graph.SimpleWeightedGraph;
+import org.junit.Before;
+import org.junit.Test;
+
+public class CompleteGraphUnitTest {
+
+ static SimpleWeightedGraph completeGraph;
+ static int size = 10;
+
+ @Before
+ public void createCompleteGraph() {
+ completeGraph = new SimpleWeightedGraph<>(DefaultEdge.class);
+ CompleteGraphGenerator completeGenerator = new CompleteGraphGenerator(size);
+ VertexFactory vFactory = new VertexFactory() {
+ private int id = 0;
+ public String createVertex() {
+ return "v" + id++;
+ }
+ };
+ completeGenerator.generateGraph(completeGraph, vFactory, null);
+ }
+
+ @Test
+ public void givenCompleteGraph_whenGetHamiltonianCyclePath_thenGetVerticeListInSequence() {
+ List verticeList = HamiltonianCycle.getApproximateOptimalForCompleteGraph(completeGraph);
+ assertEquals(verticeList.size(), completeGraph.vertexSet().size());
+ }
+}
diff --git a/algorithms/src/test/java/com/baeldung/jgrapht/DirectedGraphTests.java b/algorithms/src/test/java/com/baeldung/jgrapht/DirectedGraphTests.java
deleted file mode 100644
index 7f4cc99715..0000000000
--- a/algorithms/src/test/java/com/baeldung/jgrapht/DirectedGraphTests.java
+++ /dev/null
@@ -1,95 +0,0 @@
-package com.baeldung.jgrapht;
-
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Set;
-import java.util.stream.IntStream;
-
-import org.jgrapht.DirectedGraph;
-import org.jgrapht.GraphPath;
-import org.jgrapht.alg.CycleDetector;
-import org.jgrapht.alg.KosarajuStrongConnectivityInspector;
-import org.jgrapht.alg.interfaces.StrongConnectivityAlgorithm;
-import org.jgrapht.alg.shortestpath.AllDirectedPaths;
-import org.jgrapht.alg.shortestpath.BellmanFordShortestPath;
-import org.jgrapht.alg.shortestpath.DijkstraShortestPath;
-import org.jgrapht.graph.DefaultDirectedGraph;
-import org.jgrapht.graph.DefaultEdge;
-import org.jgrapht.graph.DirectedSubgraph;
-import org.jgrapht.traverse.BreadthFirstIterator;
-import org.jgrapht.traverse.DepthFirstIterator;
-import org.junit.Before;
-import org.junit.Test;
-
-public class DirectedGraphTests {
- DirectedGraph directedGraph;
-
- @Before
- public void createDirectedGraph() {
- directedGraph = new DefaultDirectedGraph(DefaultEdge.class);
- IntStream.range(1, 10).forEach(i -> {
- directedGraph.addVertex("v" + i);
- });
- directedGraph.addEdge("v1", "v2");
- directedGraph.addEdge("v2", "v4");
- directedGraph.addEdge("v4", "v3");
- directedGraph.addEdge("v3", "v1");
- directedGraph.addEdge("v5", "v4");
- directedGraph.addEdge("v5", "v6");
- directedGraph.addEdge("v6", "v7");
- directedGraph.addEdge("v7", "v5");
- directedGraph.addEdge("v8", "v5");
- directedGraph.addEdge("v9", "v8");
- }
-
- @Test
- public void givenDirectedGraph_whenGetStronglyConnectedSubgraphs_thenPathExistsBetweenStronglyconnectedVertices() {
- StrongConnectivityAlgorithm scAlg = new KosarajuStrongConnectivityInspector<>(directedGraph);
- List> stronglyConnectedSubgraphs = scAlg.stronglyConnectedSubgraphs();
- List stronglyConnectedVertices = new ArrayList<>(stronglyConnectedSubgraphs.get(3).vertexSet());
-
- String randomVertex1 = stronglyConnectedVertices.get(0);
- String randomVertex2 = stronglyConnectedVertices.get(3);
- AllDirectedPaths allDirectedPaths = new AllDirectedPaths<>(directedGraph);
-
- List> possiblePathList = allDirectedPaths.getAllPaths(randomVertex1, randomVertex2, false, stronglyConnectedVertices.size());
- assertTrue(possiblePathList.size() > 0);
- }
-
- @Test
- public void givenDirectedGraphWithCycle_whenCheckCycles_thenDetectCycles() {
- CycleDetector cycleDetector = new CycleDetector(directedGraph);
- assertTrue(cycleDetector.detectCycles());
- Set cycleVertices = cycleDetector.findCycles();
- assertTrue(cycleVertices.size() > 0);
- }
-
- @Test
- public void givenDirectedGraph_whenCreateInstanceDepthFirstIterator_thenGetIterator() {
- DepthFirstIterator depthFirstIterator = new DepthFirstIterator<>(directedGraph);
- assertNotNull(depthFirstIterator);
- }
-
- @Test
- public void givenDirectedGraph_whenCreateInstanceBreadthFirstIterator_thenGetIterator() {
- BreadthFirstIterator breadthFirstIterator = new BreadthFirstIterator<>(directedGraph);
- assertNotNull(breadthFirstIterator);
- }
-
- @Test
- public void givenDirectedGraph_whenGetDijkstraShortestPath_thenGetNotNullPath() {
- DijkstraShortestPath dijkstraShortestPath = new DijkstraShortestPath(directedGraph);
- List shortestPath = dijkstraShortestPath.getPath("v1", "v4").getVertexList();
- assertNotNull(shortestPath);
- }
-
- @Test
- public void givenDirectedGraph_whenGetBellmanFordShortestPath_thenGetNotNullPath() {
- BellmanFordShortestPath bellmanFordShortestPath = new BellmanFordShortestPath(directedGraph);
- List shortestPath = bellmanFordShortestPath.getPath("v1", "v4").getVertexList();
- assertNotNull(shortestPath);
- }
-}
diff --git a/algorithms/src/test/java/com/baeldung/jgrapht/DirectedGraphUnitTest.java b/algorithms/src/test/java/com/baeldung/jgrapht/DirectedGraphUnitTest.java
new file mode 100644
index 0000000000..3aebaf49a2
--- /dev/null
+++ b/algorithms/src/test/java/com/baeldung/jgrapht/DirectedGraphUnitTest.java
@@ -0,0 +1,95 @@
+package com.baeldung.jgrapht;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.IntStream;
+
+import org.jgrapht.DirectedGraph;
+import org.jgrapht.GraphPath;
+import org.jgrapht.alg.CycleDetector;
+import org.jgrapht.alg.KosarajuStrongConnectivityInspector;
+import org.jgrapht.alg.interfaces.StrongConnectivityAlgorithm;
+import org.jgrapht.alg.shortestpath.AllDirectedPaths;
+import org.jgrapht.alg.shortestpath.BellmanFordShortestPath;
+import org.jgrapht.alg.shortestpath.DijkstraShortestPath;
+import org.jgrapht.graph.DefaultDirectedGraph;
+import org.jgrapht.graph.DefaultEdge;
+import org.jgrapht.graph.DirectedSubgraph;
+import org.jgrapht.traverse.BreadthFirstIterator;
+import org.jgrapht.traverse.DepthFirstIterator;
+import org.junit.Before;
+import org.junit.Test;
+
+public class DirectedGraphUnitTest {
+ DirectedGraph directedGraph;
+
+ @Before
+ public void createDirectedGraph() {
+ directedGraph = new DefaultDirectedGraph(DefaultEdge.class);
+ IntStream.range(1, 10).forEach(i -> {
+ directedGraph.addVertex("v" + i);
+ });
+ directedGraph.addEdge("v1", "v2");
+ directedGraph.addEdge("v2", "v4");
+ directedGraph.addEdge("v4", "v3");
+ directedGraph.addEdge("v3", "v1");
+ directedGraph.addEdge("v5", "v4");
+ directedGraph.addEdge("v5", "v6");
+ directedGraph.addEdge("v6", "v7");
+ directedGraph.addEdge("v7", "v5");
+ directedGraph.addEdge("v8", "v5");
+ directedGraph.addEdge("v9", "v8");
+ }
+
+ @Test
+ public void givenDirectedGraph_whenGetStronglyConnectedSubgraphs_thenPathExistsBetweenStronglyconnectedVertices() {
+ StrongConnectivityAlgorithm scAlg = new KosarajuStrongConnectivityInspector<>(directedGraph);
+ List> stronglyConnectedSubgraphs = scAlg.stronglyConnectedSubgraphs();
+ List stronglyConnectedVertices = new ArrayList<>(stronglyConnectedSubgraphs.get(3).vertexSet());
+
+ String randomVertex1 = stronglyConnectedVertices.get(0);
+ String randomVertex2 = stronglyConnectedVertices.get(3);
+ AllDirectedPaths allDirectedPaths = new AllDirectedPaths<>(directedGraph);
+
+ List> possiblePathList = allDirectedPaths.getAllPaths(randomVertex1, randomVertex2, false, stronglyConnectedVertices.size());
+ assertTrue(possiblePathList.size() > 0);
+ }
+
+ @Test
+ public void givenDirectedGraphWithCycle_whenCheckCycles_thenDetectCycles() {
+ CycleDetector cycleDetector = new CycleDetector(directedGraph);
+ assertTrue(cycleDetector.detectCycles());
+ Set cycleVertices = cycleDetector.findCycles();
+ assertTrue(cycleVertices.size() > 0);
+ }
+
+ @Test
+ public void givenDirectedGraph_whenCreateInstanceDepthFirstIterator_thenGetIterator() {
+ DepthFirstIterator depthFirstIterator = new DepthFirstIterator<>(directedGraph);
+ assertNotNull(depthFirstIterator);
+ }
+
+ @Test
+ public void givenDirectedGraph_whenCreateInstanceBreadthFirstIterator_thenGetIterator() {
+ BreadthFirstIterator breadthFirstIterator = new BreadthFirstIterator<>(directedGraph);
+ assertNotNull(breadthFirstIterator);
+ }
+
+ @Test
+ public void givenDirectedGraph_whenGetDijkstraShortestPath_thenGetNotNullPath() {
+ DijkstraShortestPath dijkstraShortestPath = new DijkstraShortestPath(directedGraph);
+ List shortestPath = dijkstraShortestPath.getPath("v1", "v4").getVertexList();
+ assertNotNull(shortestPath);
+ }
+
+ @Test
+ public void givenDirectedGraph_whenGetBellmanFordShortestPath_thenGetNotNullPath() {
+ BellmanFordShortestPath bellmanFordShortestPath = new BellmanFordShortestPath(directedGraph);
+ List shortestPath = bellmanFordShortestPath.getPath("v1", "v4").getVertexList();
+ assertNotNull(shortestPath);
+ }
+}
diff --git a/algorithms/src/test/java/com/baeldung/jgrapht/EulerianCircuitTest.java b/algorithms/src/test/java/com/baeldung/jgrapht/EulerianCircuitTest.java
deleted file mode 100644
index 6f0fb92ab7..0000000000
--- a/algorithms/src/test/java/com/baeldung/jgrapht/EulerianCircuitTest.java
+++ /dev/null
@@ -1,42 +0,0 @@
-package com.baeldung.jgrapht;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import java.util.stream.IntStream;
-
-import org.jgrapht.GraphPath;
-import org.jgrapht.alg.cycle.HierholzerEulerianCycle;
-import org.jgrapht.graph.DefaultEdge;
-import org.jgrapht.graph.SimpleWeightedGraph;
-import org.junit.Before;
-import org.junit.Test;
-
-public class EulerianCircuitTest {
- SimpleWeightedGraph simpleGraph;
-
- @Before
- public void createGraphWithEulerianCircuit() {
- simpleGraph = new SimpleWeightedGraph<>(DefaultEdge.class);
- IntStream.range(1, 6).forEach(i -> {
- simpleGraph.addVertex("v" + i);
- });
- IntStream.range(1, 6).forEach(i -> {
- int endVertexNo = (i + 1) > 5 ? 1 : i + 1;
- simpleGraph.addEdge("v" + i, "v" + endVertexNo);
- });
- }
-
- @Test
- public void givenGraph_whenCheckEluerianCycle_thenGetResult() {
- HierholzerEulerianCycle eulerianCycle = new HierholzerEulerianCycle<>();
- assertTrue(eulerianCycle.isEulerian(simpleGraph));
- }
-
- @Test
- public void givenGraphWithEulerianCircuit_whenGetEulerianCycle_thenGetGraphPath() {
- HierholzerEulerianCycle eulerianCycle = new HierholzerEulerianCycle<>();
- GraphPath path = eulerianCycle.getEulerianCycle(simpleGraph);
- assertTrue(path.getEdgeList().containsAll(simpleGraph.edgeSet()));
- }
-}
diff --git a/algorithms/src/test/java/com/baeldung/jgrapht/EulerianCircuitUnitTest.java b/algorithms/src/test/java/com/baeldung/jgrapht/EulerianCircuitUnitTest.java
new file mode 100644
index 0000000000..8cf1b70898
--- /dev/null
+++ b/algorithms/src/test/java/com/baeldung/jgrapht/EulerianCircuitUnitTest.java
@@ -0,0 +1,42 @@
+package com.baeldung.jgrapht;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.util.stream.IntStream;
+
+import org.jgrapht.GraphPath;
+import org.jgrapht.alg.cycle.HierholzerEulerianCycle;
+import org.jgrapht.graph.DefaultEdge;
+import org.jgrapht.graph.SimpleWeightedGraph;
+import org.junit.Before;
+import org.junit.Test;
+
+public class EulerianCircuitUnitTest {
+ SimpleWeightedGraph simpleGraph;
+
+ @Before
+ public void createGraphWithEulerianCircuit() {
+ simpleGraph = new SimpleWeightedGraph<>(DefaultEdge.class);
+ IntStream.range(1, 6).forEach(i -> {
+ simpleGraph.addVertex("v" + i);
+ });
+ IntStream.range(1, 6).forEach(i -> {
+ int endVertexNo = (i + 1) > 5 ? 1 : i + 1;
+ simpleGraph.addEdge("v" + i, "v" + endVertexNo);
+ });
+ }
+
+ @Test
+ public void givenGraph_whenCheckEluerianCycle_thenGetResult() {
+ HierholzerEulerianCycle eulerianCycle = new HierholzerEulerianCycle<>();
+ assertTrue(eulerianCycle.isEulerian(simpleGraph));
+ }
+
+ @Test
+ public void givenGraphWithEulerianCircuit_whenGetEulerianCycle_thenGetGraphPath() {
+ HierholzerEulerianCycle eulerianCycle = new HierholzerEulerianCycle<>();
+ GraphPath path = eulerianCycle.getEulerianCycle(simpleGraph);
+ assertTrue(path.getEdgeList().containsAll(simpleGraph.edgeSet()));
+ }
+}
diff --git a/animal-sniffer-mvn-plugin/pom.xml b/animal-sniffer-mvn-plugin/pom.xml
index 2356c7d5a2..cdfb1fb2a3 100644
--- a/animal-sniffer-mvn-plugin/pom.xml
+++ b/animal-sniffer-mvn-plugin/pom.xml
@@ -1,57 +1,47 @@
- 4.0.0
- com.baeldung
- animal-sniffer-mvn-plugin
- jar
- 1.0-SNAPSHOT
- example-animal-sniffer-mvn-plugin
- http://maven.apache.org
-
-
- 3.7.0
-
-
-
-
- junit
- junit
- 3.8.1
- test
-
-
-
-
-
- maven-compiler-plugin
- 3.7.0
-
- 1.8
- 1.8
-
-
-
- org.codehaus.mojo
- animal-sniffer-maven-plugin
- 1.16
-
-
- org.codehaus.mojo.signature
- java16
- 1.0
-
-
-
-
- animal-sniffer
- verify
-
- check
-
-
-
-
-
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ 4.0.0
+ com.baeldung
+ animal-sniffer-mvn-plugin
+ jar
+ 1.0-SNAPSHOT
+ animal-sniffer-mvn-plugin
+ http://maven.apache.org
+
+ com.baeldung
+ parent-modules
+ 1.0.0-SNAPSHOT
+
+
+
+
+
+ org.codehaus.mojo
+ animal-sniffer-maven-plugin
+ ${animal-sniffer-maven-plugin.version}
+
+
+ org.codehaus.mojo.signature
+ java16
+ ${org.codehaus.mojo.signature.java16.version}
+
+
+
+
+ animal-sniffer
+ verify
+
+ check
+
+
+
+
+
+
+
+ 1.16
+ 1.0
+
\ No newline at end of file
diff --git a/animal-sniffer-mvn-plugin/src/main/resources/logback.xml b/animal-sniffer-mvn-plugin/src/main/resources/logback.xml
new file mode 100644
index 0000000000..7d900d8ea8
--- /dev/null
+++ b/animal-sniffer-mvn-plugin/src/main/resources/logback.xml
@@ -0,0 +1,13 @@
+
+
+
+
+ %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/animal-sniffer-mvn-plugin/src/test/java/com/baeldung/AppTest.java b/animal-sniffer-mvn-plugin/src/test/java/com/baeldung/AppTest.java
deleted file mode 100644
index 8ecb1bc629..0000000000
--- a/animal-sniffer-mvn-plugin/src/test/java/com/baeldung/AppTest.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package com.baeldung;
-
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-
-/**
- * Unit test for simple App.
- */
-public class AppTest
- extends TestCase
-{
- /**
- * Create the test case
- *
- * @param testName name of the test case
- */
- public AppTest( String testName )
- {
- super( testName );
- }
-
- /**
- * @return the suite of tests being tested
- */
- public static Test suite()
- {
- return new TestSuite( AppTest.class );
- }
-
- /**
- * Rigourous Test :-)
- */
- public void testApp()
- {
-
- assertTrue( true );
-
- }
-}
diff --git a/animal-sniffer-mvn-plugin/src/test/java/com/baeldung/AppUnitTest.java b/animal-sniffer-mvn-plugin/src/test/java/com/baeldung/AppUnitTest.java
new file mode 100644
index 0000000000..dcfd22ff87
--- /dev/null
+++ b/animal-sniffer-mvn-plugin/src/test/java/com/baeldung/AppUnitTest.java
@@ -0,0 +1,40 @@
+package com.baeldung;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+/**
+ * Unit test for simple App.
+ */
+public class AppUnitTest
+ extends TestCase
+{
+ /**
+ * Create the test case
+ *
+ * @param testName name of the test case
+ */
+ public AppUnitTest( String testName )
+ {
+ super( testName );
+ }
+
+ /**
+ * @return the suite of tests being tested
+ */
+ public static Test suite()
+ {
+ return new TestSuite( AppUnitTest.class );
+ }
+
+ /**
+ * Rigourous Test :-)
+ */
+ public void testApp()
+ {
+
+ assertTrue( true );
+
+ }
+}
diff --git a/annotations/annotation-processing/pom.xml b/annotations/annotation-processing/pom.xml
index b5219d57ba..8e53334521 100644
--- a/annotations/annotation-processing/pom.xml
+++ b/annotations/annotation-processing/pom.xml
@@ -1,8 +1,8 @@
-
4.0.0
+ annotation-processing
com.baeldung
@@ -11,40 +11,17 @@
../
- annotation-processing
-
-
- 1.0-rc2
- 3.7.0
-
-
-
com.google.auto.service
auto-service
${auto-service.version}
provided
-
-
-
-
-
-
- org.apache.maven.plugins
- maven-compiler-plugin
- ${maven-compiler-plugin.version}
-
- 1.8
- 1.8
-
-
-
-
-
-
+
+ 1.0-rc2
+
\ No newline at end of file
diff --git a/annotations/annotation-processing/src/main/resources/logback.xml b/annotations/annotation-processing/src/main/resources/logback.xml
new file mode 100644
index 0000000000..7d900d8ea8
--- /dev/null
+++ b/annotations/annotation-processing/src/main/resources/logback.xml
@@ -0,0 +1,13 @@
+
+
+
+
+ %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/annotations/annotation-user/pom.xml b/annotations/annotation-user/pom.xml
index eb827b2ea5..07ea9a5b5a 100644
--- a/annotations/annotation-user/pom.xml
+++ b/annotations/annotation-user/pom.xml
@@ -2,6 +2,7 @@
4.0.0
+ annotation-user
annotations
@@ -10,16 +11,12 @@
../
- annotation-user
-
-
com.baeldung
annotation-processing
${project.parent.version}
-
\ No newline at end of file
diff --git a/annotations/annotation-user/src/main/resources/logback.xml b/annotations/annotation-user/src/main/resources/logback.xml
new file mode 100644
index 0000000000..7d900d8ea8
--- /dev/null
+++ b/annotations/annotation-user/src/main/resources/logback.xml
@@ -0,0 +1,13 @@
+
+
+
+
+ %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/annotations/pom.xml b/annotations/pom.xml
index 0ddc17f8a7..2c73d3d91b 100644
--- a/annotations/pom.xml
+++ b/annotations/pom.xml
@@ -1,15 +1,15 @@
+ 4.0.0
+ annotations
+ pom
+
parent-modules
com.baeldung
1.0.0-SNAPSHOT
- 4.0.0
-
- annotations
- pom
annotation-processing
diff --git a/antlr/README.md b/antlr/README.md
new file mode 100644
index 0000000000..419d9ddfbb
--- /dev/null
+++ b/antlr/README.md
@@ -0,0 +1,3 @@
+### Relevant Articles:
+
+- [Java with ANTLR](http://www.baeldung.com/java-antlr)
diff --git a/antlr/pom.xml b/antlr/pom.xml
new file mode 100644
index 0000000000..ac66891598
--- /dev/null
+++ b/antlr/pom.xml
@@ -0,0 +1,58 @@
+
+ 4.0.0
+ antlr
+ antlr
+
+
+ com.baeldung
+ parent-modules
+ 1.0.0-SNAPSHOT
+
+
+
+
+
+ org.antlr
+ antlr4-maven-plugin
+ ${antlr.version}
+
+
+
+ antlr4
+
+
+
+
+
+ org.codehaus.mojo
+ build-helper-maven-plugin
+ ${mojo.version}
+
+
+ generate-sources
+
+ add-source
+
+
+
+ ${basedir}/target/generated-sources/antlr4
+
+
+
+
+
+
+
+
+
+ org.antlr
+ antlr4-runtime
+ ${antlr.version}
+
+
+
+ 4.7.1
+ 3.0.0
+
+
\ No newline at end of file
diff --git a/antlr/src/main/antlr4/com/baeldung/antlr/Java8.g4 b/antlr/src/main/antlr4/com/baeldung/antlr/Java8.g4
new file mode 100644
index 0000000000..5cde8f9ace
--- /dev/null
+++ b/antlr/src/main/antlr4/com/baeldung/antlr/Java8.g4
@@ -0,0 +1,1775 @@
+/*
+ * [The "BSD license"]
+ * Copyright (c) 2014 Terence Parr
+ * Copyright (c) 2014 Sam Harwell
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * A Java 8 grammar for ANTLR 4 derived from the Java Language Specification
+ * chapter 19.
+ *
+ * NOTE: This grammar results in a generated parser that is much slower
+ * than the Java 7 grammar in the grammars-v4/java directory. This
+ * one is, however, extremely close to the spec.
+ *
+ * You can test with
+ *
+ * $ antlr4 Java8.g4
+ * $ javac *.java
+ * $ grun Java8 compilationUnit *.java
+ *
+ * Or,
+~/antlr/code/grammars-v4/java8 $ java Test .
+/Users/parrt/antlr/code/grammars-v4/java8/./Java8BaseListener.java
+/Users/parrt/antlr/code/grammars-v4/java8/./Java8Lexer.java
+/Users/parrt/antlr/code/grammars-v4/java8/./Java8Listener.java
+/Users/parrt/antlr/code/grammars-v4/java8/./Java8Parser.java
+/Users/parrt/antlr/code/grammars-v4/java8/./Test.java
+Total lexer+parser dateTime 30844ms.
+ */
+grammar Java8;
+
+/*
+ * Productions from §3 (Lexical Structure)
+ */
+
+literal
+ : IntegerLiteral
+ | FloatingPointLiteral
+ | BooleanLiteral
+ | CharacterLiteral
+ | StringLiteral
+ | NullLiteral
+ ;
+
+/*
+ * Productions from §4 (Types, Values, and Variables)
+ */
+
+primitiveType
+ : annotation* numericType
+ | annotation* 'boolean'
+ ;
+
+numericType
+ : integralType
+ | floatingPointType
+ ;
+
+integralType
+ : 'byte'
+ | 'short'
+ | 'int'
+ | 'long'
+ | 'char'
+ ;
+
+floatingPointType
+ : 'float'
+ | 'double'
+ ;
+
+referenceType
+ : classOrInterfaceType
+ | typeVariable
+ | arrayType
+ ;
+
+classOrInterfaceType
+ : ( classType_lfno_classOrInterfaceType
+ | interfaceType_lfno_classOrInterfaceType
+ )
+ ( classType_lf_classOrInterfaceType
+ | interfaceType_lf_classOrInterfaceType
+ )*
+ ;
+
+classType
+ : annotation* Identifier typeArguments?
+ | classOrInterfaceType '.' annotation* Identifier typeArguments?
+ ;
+
+classType_lf_classOrInterfaceType
+ : '.' annotation* Identifier typeArguments?
+ ;
+
+classType_lfno_classOrInterfaceType
+ : annotation* Identifier typeArguments?
+ ;
+
+interfaceType
+ : classType
+ ;
+
+interfaceType_lf_classOrInterfaceType
+ : classType_lf_classOrInterfaceType
+ ;
+
+interfaceType_lfno_classOrInterfaceType
+ : classType_lfno_classOrInterfaceType
+ ;
+
+typeVariable
+ : annotation* Identifier
+ ;
+
+arrayType
+ : primitiveType dims
+ | classOrInterfaceType dims
+ | typeVariable dims
+ ;
+
+dims
+ : annotation* '[' ']' (annotation* '[' ']')*
+ ;
+
+typeParameter
+ : typeParameterModifier* Identifier typeBound?
+ ;
+
+typeParameterModifier
+ : annotation
+ ;
+
+typeBound
+ : 'extends' typeVariable
+ | 'extends' classOrInterfaceType additionalBound*
+ ;
+
+additionalBound
+ : '&' interfaceType
+ ;
+
+typeArguments
+ : '<' typeArgumentList '>'
+ ;
+
+typeArgumentList
+ : typeArgument (',' typeArgument)*
+ ;
+
+typeArgument
+ : referenceType
+ | wildcard
+ ;
+
+wildcard
+ : annotation* '?' wildcardBounds?
+ ;
+
+wildcardBounds
+ : 'extends' referenceType
+ | 'super' referenceType
+ ;
+
+/*
+ * Productions from §6 (Names)
+ */
+
+packageName
+ : Identifier
+ | packageName '.' Identifier
+ ;
+
+typeName
+ : Identifier
+ | packageOrTypeName '.' Identifier
+ ;
+
+packageOrTypeName
+ : Identifier
+ | packageOrTypeName '.' Identifier
+ ;
+
+expressionName
+ : Identifier
+ | ambiguousName '.' Identifier
+ ;
+
+methodName
+ : Identifier
+ ;
+
+ambiguousName
+ : Identifier
+ | ambiguousName '.' Identifier
+ ;
+
+/*
+ * Productions from §7 (Packages)
+ */
+
+compilationUnit
+ : packageDeclaration? importDeclaration* typeDeclaration* EOF
+ ;
+
+packageDeclaration
+ : packageModifier* 'package' packageName ';'
+ ;
+
+packageModifier
+ : annotation
+ ;
+
+importDeclaration
+ : singleTypeImportDeclaration
+ | typeImportOnDemandDeclaration
+ | singleStaticImportDeclaration
+ | staticImportOnDemandDeclaration
+ ;
+
+singleTypeImportDeclaration
+ : 'import' typeName ';'
+ ;
+
+typeImportOnDemandDeclaration
+ : 'import' packageOrTypeName '.' '*' ';'
+ ;
+
+singleStaticImportDeclaration
+ : 'import' 'static' typeName '.' Identifier ';'
+ ;
+
+staticImportOnDemandDeclaration
+ : 'import' 'static' typeName '.' '*' ';'
+ ;
+
+typeDeclaration
+ : classDeclaration
+ | interfaceDeclaration
+ | ';'
+ ;
+
+/*
+ * Productions from §8 (Classes)
+ */
+
+classDeclaration
+ : normalClassDeclaration
+ | enumDeclaration
+ ;
+
+normalClassDeclaration
+ : classModifier* 'class' Identifier typeParameters? superclass? superinterfaces? classBody
+ ;
+
+classModifier
+ : annotation
+ | 'public'
+ | 'protected'
+ | 'private'
+ | 'abstract'
+ | 'static'
+ | 'final'
+ | 'strictfp'
+ ;
+
+typeParameters
+ : '<' typeParameterList '>'
+ ;
+
+typeParameterList
+ : typeParameter (',' typeParameter)*
+ ;
+
+superclass
+ : 'extends' classType
+ ;
+
+superinterfaces
+ : 'implements' interfaceTypeList
+ ;
+
+interfaceTypeList
+ : interfaceType (',' interfaceType)*
+ ;
+
+classBody
+ : '{' classBodyDeclaration* '}'
+ ;
+
+classBodyDeclaration
+ : classMemberDeclaration
+ | instanceInitializer
+ | staticInitializer
+ | constructorDeclaration
+ ;
+
+classMemberDeclaration
+ : fieldDeclaration
+ | methodDeclaration
+ | classDeclaration
+ | interfaceDeclaration
+ | ';'
+ ;
+
+fieldDeclaration
+ : fieldModifier* unannType variableDeclaratorList ';'
+ ;
+
+fieldModifier
+ : annotation
+ | 'public'
+ | 'protected'
+ | 'private'
+ | 'static'
+ | 'final'
+ | 'transient'
+ | 'volatile'
+ ;
+
+variableDeclaratorList
+ : variableDeclarator (',' variableDeclarator)*
+ ;
+
+variableDeclarator
+ : variableDeclaratorId ('=' variableInitializer)?
+ ;
+
+variableDeclaratorId
+ : Identifier dims?
+ ;
+
+variableInitializer
+ : expression
+ | arrayInitializer
+ ;
+
+unannType
+ : unannPrimitiveType
+ | unannReferenceType
+ ;
+
+unannPrimitiveType
+ : numericType
+ | 'boolean'
+ ;
+
+unannReferenceType
+ : unannClassOrInterfaceType
+ | unannTypeVariable
+ | unannArrayType
+ ;
+
+unannClassOrInterfaceType
+ : ( unannClassType_lfno_unannClassOrInterfaceType
+ | unannInterfaceType_lfno_unannClassOrInterfaceType
+ )
+ ( unannClassType_lf_unannClassOrInterfaceType
+ | unannInterfaceType_lf_unannClassOrInterfaceType
+ )*
+ ;
+
+unannClassType
+ : Identifier typeArguments?
+ | unannClassOrInterfaceType '.' annotation* Identifier typeArguments?
+ ;
+
+unannClassType_lf_unannClassOrInterfaceType
+ : '.' annotation* Identifier typeArguments?
+ ;
+
+unannClassType_lfno_unannClassOrInterfaceType
+ : Identifier typeArguments?
+ ;
+
+unannInterfaceType
+ : unannClassType
+ ;
+
+unannInterfaceType_lf_unannClassOrInterfaceType
+ : unannClassType_lf_unannClassOrInterfaceType
+ ;
+
+unannInterfaceType_lfno_unannClassOrInterfaceType
+ : unannClassType_lfno_unannClassOrInterfaceType
+ ;
+
+unannTypeVariable
+ : Identifier
+ ;
+
+unannArrayType
+ : unannPrimitiveType dims
+ | unannClassOrInterfaceType dims
+ | unannTypeVariable dims
+ ;
+
+methodDeclaration
+ : methodModifier* methodHeader methodBody
+ ;
+
+methodModifier
+ : annotation
+ | 'public'
+ | 'protected'
+ | 'private'
+ | 'abstract'
+ | 'static'
+ | 'final'
+ | 'synchronized'
+ | 'native'
+ | 'strictfp'
+ ;
+
+methodHeader
+ : result methodDeclarator throws_?
+ | typeParameters annotation* result methodDeclarator throws_?
+ ;
+
+result
+ : unannType
+ | 'void'
+ ;
+
+methodDeclarator
+ : Identifier '(' formalParameterList? ')' dims?
+ ;
+
+formalParameterList
+ : receiverParameter
+ | formalParameters ',' lastFormalParameter
+ | lastFormalParameter
+ ;
+
+formalParameters
+ : formalParameter (',' formalParameter)*
+ | receiverParameter (',' formalParameter)*
+ ;
+
+formalParameter
+ : variableModifier* unannType variableDeclaratorId
+ ;
+
+variableModifier
+ : annotation
+ | 'final'
+ ;
+
+lastFormalParameter
+ : variableModifier* unannType annotation* '...' variableDeclaratorId
+ | formalParameter
+ ;
+
+receiverParameter
+ : annotation* unannType (Identifier '.')? 'this'
+ ;
+
+throws_
+ : 'throws' exceptionTypeList
+ ;
+
+exceptionTypeList
+ : exceptionType (',' exceptionType)*
+ ;
+
+exceptionType
+ : classType
+ | typeVariable
+ ;
+
+methodBody
+ : block
+ | ';'
+ ;
+
+instanceInitializer
+ : block
+ ;
+
+staticInitializer
+ : 'static' block
+ ;
+
+constructorDeclaration
+ : constructorModifier* constructorDeclarator throws_? constructorBody
+ ;
+
+constructorModifier
+ : annotation
+ | 'public'
+ | 'protected'
+ | 'private'
+ ;
+
+constructorDeclarator
+ : typeParameters? simpleTypeName '(' formalParameterList? ')'
+ ;
+
+simpleTypeName
+ : Identifier
+ ;
+
+constructorBody
+ : '{' explicitConstructorInvocation? blockStatements? '}'
+ ;
+
+explicitConstructorInvocation
+ : typeArguments? 'this' '(' argumentList? ')' ';'
+ | typeArguments? 'super' '(' argumentList? ')' ';'
+ | expressionName '.' typeArguments? 'super' '(' argumentList? ')' ';'
+ | primary '.' typeArguments? 'super' '(' argumentList? ')' ';'
+ ;
+
+enumDeclaration
+ : classModifier* 'enum' Identifier superinterfaces? enumBody
+ ;
+
+enumBody
+ : '{' enumConstantList? ','? enumBodyDeclarations? '}'
+ ;
+
+enumConstantList
+ : enumConstant (',' enumConstant)*
+ ;
+
+enumConstant
+ : enumConstantModifier* Identifier ('(' argumentList? ')')? classBody?
+ ;
+
+enumConstantModifier
+ : annotation
+ ;
+
+enumBodyDeclarations
+ : ';' classBodyDeclaration*
+ ;
+
+/*
+ * Productions from §9 (Interfaces)
+ */
+
+interfaceDeclaration
+ : normalInterfaceDeclaration
+ | annotationTypeDeclaration
+ ;
+
+normalInterfaceDeclaration
+ : interfaceModifier* 'interface' Identifier typeParameters? extendsInterfaces? interfaceBody
+ ;
+
+interfaceModifier
+ : annotation
+ | 'public'
+ | 'protected'
+ | 'private'
+ | 'abstract'
+ | 'static'
+ | 'strictfp'
+ ;
+
+extendsInterfaces
+ : 'extends' interfaceTypeList
+ ;
+
+interfaceBody
+ : '{' interfaceMemberDeclaration* '}'
+ ;
+
+interfaceMemberDeclaration
+ : constantDeclaration
+ | interfaceMethodDeclaration
+ | classDeclaration
+ | interfaceDeclaration
+ | ';'
+ ;
+
+constantDeclaration
+ : constantModifier* unannType variableDeclaratorList ';'
+ ;
+
+constantModifier
+ : annotation
+ | 'public'
+ | 'static'
+ | 'final'
+ ;
+
+interfaceMethodDeclaration
+ : interfaceMethodModifier* methodHeader methodBody
+ ;
+
+interfaceMethodModifier
+ : annotation
+ | 'public'
+ | 'abstract'
+ | 'default'
+ | 'static'
+ | 'strictfp'
+ ;
+
+annotationTypeDeclaration
+ : interfaceModifier* '@' 'interface' Identifier annotationTypeBody
+ ;
+
+annotationTypeBody
+ : '{' annotationTypeMemberDeclaration* '}'
+ ;
+
+annotationTypeMemberDeclaration
+ : annotationTypeElementDeclaration
+ | constantDeclaration
+ | classDeclaration
+ | interfaceDeclaration
+ | ';'
+ ;
+
+annotationTypeElementDeclaration
+ : annotationTypeElementModifier* unannType Identifier '(' ')' dims? defaultValue? ';'
+ ;
+
+annotationTypeElementModifier
+ : annotation
+ | 'public'
+ | 'abstract'
+ ;
+
+defaultValue
+ : 'default' elementValue
+ ;
+
+annotation
+ : normalAnnotation
+ | markerAnnotation
+ | singleElementAnnotation
+ ;
+
+normalAnnotation
+ : '@' typeName '(' elementValuePairList? ')'
+ ;
+
+elementValuePairList
+ : elementValuePair (',' elementValuePair)*
+ ;
+
+elementValuePair
+ : Identifier '=' elementValue
+ ;
+
+elementValue
+ : conditionalExpression
+ | elementValueArrayInitializer
+ | annotation
+ ;
+
+elementValueArrayInitializer
+ : '{' elementValueList? ','? '}'
+ ;
+
+elementValueList
+ : elementValue (',' elementValue)*
+ ;
+
+markerAnnotation
+ : '@' typeName
+ ;
+
+singleElementAnnotation
+ : '@' typeName '(' elementValue ')'
+ ;
+
+/*
+ * Productions from §10 (Arrays)
+ */
+
+arrayInitializer
+ : '{' variableInitializerList? ','? '}'
+ ;
+
+variableInitializerList
+ : variableInitializer (',' variableInitializer)*
+ ;
+
+/*
+ * Productions from §14 (Blocks and Statements)
+ */
+
+block
+ : '{' blockStatements? '}'
+ ;
+
+blockStatements
+ : blockStatement+
+ ;
+
+blockStatement
+ : localVariableDeclarationStatement
+ | classDeclaration
+ | statement
+ ;
+
+localVariableDeclarationStatement
+ : localVariableDeclaration ';'
+ ;
+
+localVariableDeclaration
+ : variableModifier* unannType variableDeclaratorList
+ ;
+
+statement
+ : statementWithoutTrailingSubstatement
+ | labeledStatement
+ | ifThenStatement
+ | ifThenElseStatement
+ | whileStatement
+ | forStatement
+ ;
+
+statementNoShortIf
+ : statementWithoutTrailingSubstatement
+ | labeledStatementNoShortIf
+ | ifThenElseStatementNoShortIf
+ | whileStatementNoShortIf
+ | forStatementNoShortIf
+ ;
+
+statementWithoutTrailingSubstatement
+ : block
+ | emptyStatement
+ | expressionStatement
+ | assertStatement
+ | switchStatement
+ | doStatement
+ | breakStatement
+ | continueStatement
+ | returnStatement
+ | synchronizedStatement
+ | throwStatement
+ | tryStatement
+ ;
+
+emptyStatement
+ : ';'
+ ;
+
+labeledStatement
+ : Identifier ':' statement
+ ;
+
+labeledStatementNoShortIf
+ : Identifier ':' statementNoShortIf
+ ;
+
+expressionStatement
+ : statementExpression ';'
+ ;
+
+statementExpression
+ : assignment
+ | preIncrementExpression
+ | preDecrementExpression
+ | postIncrementExpression
+ | postDecrementExpression
+ | methodInvocation
+ | classInstanceCreationExpression
+ ;
+
+ifThenStatement
+ : 'if' '(' expression ')' statement
+ ;
+
+ifThenElseStatement
+ : 'if' '(' expression ')' statementNoShortIf 'else' statement
+ ;
+
+ifThenElseStatementNoShortIf
+ : 'if' '(' expression ')' statementNoShortIf 'else' statementNoShortIf
+ ;
+
+assertStatement
+ : 'assert' expression ';'
+ | 'assert' expression ':' expression ';'
+ ;
+
+switchStatement
+ : 'switch' '(' expression ')' switchBlock
+ ;
+
+switchBlock
+ : '{' switchBlockStatementGroup* switchLabel* '}'
+ ;
+
+switchBlockStatementGroup
+ : switchLabels blockStatements
+ ;
+
+switchLabels
+ : switchLabel switchLabel*
+ ;
+
+switchLabel
+ : 'case' constantExpression ':'
+ | 'case' enumConstantName ':'
+ | 'default' ':'
+ ;
+
+enumConstantName
+ : Identifier
+ ;
+
+whileStatement
+ : 'while' '(' expression ')' statement
+ ;
+
+whileStatementNoShortIf
+ : 'while' '(' expression ')' statementNoShortIf
+ ;
+
+doStatement
+ : 'do' statement 'while' '(' expression ')' ';'
+ ;
+
+forStatement
+ : basicForStatement
+ | enhancedForStatement
+ ;
+
+forStatementNoShortIf
+ : basicForStatementNoShortIf
+ | enhancedForStatementNoShortIf
+ ;
+
+basicForStatement
+ : 'for' '(' forInit? ';' expression? ';' forUpdate? ')' statement
+ ;
+
+basicForStatementNoShortIf
+ : 'for' '(' forInit? ';' expression? ';' forUpdate? ')' statementNoShortIf
+ ;
+
+forInit
+ : statementExpressionList
+ | localVariableDeclaration
+ ;
+
+forUpdate
+ : statementExpressionList
+ ;
+
+statementExpressionList
+ : statementExpression (',' statementExpression)*
+ ;
+
+enhancedForStatement
+ : 'for' '(' variableModifier* unannType variableDeclaratorId ':' expression ')' statement
+ ;
+
+enhancedForStatementNoShortIf
+ : 'for' '(' variableModifier* unannType variableDeclaratorId ':' expression ')' statementNoShortIf
+ ;
+
+breakStatement
+ : 'break' Identifier? ';'
+ ;
+
+continueStatement
+ : 'continue' Identifier? ';'
+ ;
+
+returnStatement
+ : 'return' expression? ';'
+ ;
+
+throwStatement
+ : 'throw' expression ';'
+ ;
+
+synchronizedStatement
+ : 'synchronized' '(' expression ')' block
+ ;
+
+tryStatement
+ : 'try' block catches
+ | 'try' block catches? finally_
+ | tryWithResourcesStatement
+ ;
+
+catches
+ : catchClause catchClause*
+ ;
+
+catchClause
+ : 'catch' '(' catchFormalParameter ')' block
+ ;
+
+catchFormalParameter
+ : variableModifier* catchType variableDeclaratorId
+ ;
+
+catchType
+ : unannClassType ('|' classType)*
+ ;
+
+finally_
+ : 'finally' block
+ ;
+
+tryWithResourcesStatement
+ : 'try' resourceSpecification block catches? finally_?
+ ;
+
+resourceSpecification
+ : '(' resourceList ';'? ')'
+ ;
+
+resourceList
+ : resource (';' resource)*
+ ;
+
+resource
+ : variableModifier* unannType variableDeclaratorId '=' expression
+ ;
+
+/*
+ * Productions from §15 (Expressions)
+ */
+
+primary
+ : ( primaryNoNewArray_lfno_primary
+ | arrayCreationExpression
+ )
+ ( primaryNoNewArray_lf_primary
+ )*
+ ;
+
+primaryNoNewArray
+ : literal
+ | typeName ('[' ']')* '.' 'class'
+ | 'void' '.' 'class'
+ | 'this'
+ | typeName '.' 'this'
+ | '(' expression ')'
+ | classInstanceCreationExpression
+ | fieldAccess
+ | arrayAccess
+ | methodInvocation
+ | methodReference
+ ;
+
+primaryNoNewArray_lf_arrayAccess
+ :
+ ;
+
+primaryNoNewArray_lfno_arrayAccess
+ : literal
+ | typeName ('[' ']')* '.' 'class'
+ | 'void' '.' 'class'
+ | 'this'
+ | typeName '.' 'this'
+ | '(' expression ')'
+ | classInstanceCreationExpression
+ | fieldAccess
+ | methodInvocation
+ | methodReference
+ ;
+
+primaryNoNewArray_lf_primary
+ : classInstanceCreationExpression_lf_primary
+ | fieldAccess_lf_primary
+ | arrayAccess_lf_primary
+ | methodInvocation_lf_primary
+ | methodReference_lf_primary
+ ;
+
+primaryNoNewArray_lf_primary_lf_arrayAccess_lf_primary
+ :
+ ;
+
+primaryNoNewArray_lf_primary_lfno_arrayAccess_lf_primary
+ : classInstanceCreationExpression_lf_primary
+ | fieldAccess_lf_primary
+ | methodInvocation_lf_primary
+ | methodReference_lf_primary
+ ;
+
+primaryNoNewArray_lfno_primary
+ : literal
+ | typeName ('[' ']')* '.' 'class'
+ | unannPrimitiveType ('[' ']')* '.' 'class'
+ | 'void' '.' 'class'
+ | 'this'
+ | typeName '.' 'this'
+ | '(' expression ')'
+ | classInstanceCreationExpression_lfno_primary
+ | fieldAccess_lfno_primary
+ | arrayAccess_lfno_primary
+ | methodInvocation_lfno_primary
+ | methodReference_lfno_primary
+ ;
+
+primaryNoNewArray_lfno_primary_lf_arrayAccess_lfno_primary
+ :
+ ;
+
+primaryNoNewArray_lfno_primary_lfno_arrayAccess_lfno_primary
+ : literal
+ | typeName ('[' ']')* '.' 'class'
+ | unannPrimitiveType ('[' ']')* '.' 'class'
+ | 'void' '.' 'class'
+ | 'this'
+ | typeName '.' 'this'
+ | '(' expression ')'
+ | classInstanceCreationExpression_lfno_primary
+ | fieldAccess_lfno_primary
+ | methodInvocation_lfno_primary
+ | methodReference_lfno_primary
+ ;
+
+classInstanceCreationExpression
+ : 'new' typeArguments? annotation* Identifier ('.' annotation* Identifier)* typeArgumentsOrDiamond? '(' argumentList? ')' classBody?
+ | expressionName '.' 'new' typeArguments? annotation* Identifier typeArgumentsOrDiamond? '(' argumentList? ')' classBody?
+ | primary '.' 'new' typeArguments? annotation* Identifier typeArgumentsOrDiamond? '(' argumentList? ')' classBody?
+ ;
+
+classInstanceCreationExpression_lf_primary
+ : '.' 'new' typeArguments? annotation* Identifier typeArgumentsOrDiamond? '(' argumentList? ')' classBody?
+ ;
+
+classInstanceCreationExpression_lfno_primary
+ : 'new' typeArguments? annotation* Identifier ('.' annotation* Identifier)* typeArgumentsOrDiamond? '(' argumentList? ')' classBody?
+ | expressionName '.' 'new' typeArguments? annotation* Identifier typeArgumentsOrDiamond? '(' argumentList? ')' classBody?
+ ;
+
+typeArgumentsOrDiamond
+ : typeArguments
+ | '<' '>'
+ ;
+
+fieldAccess
+ : primary '.' Identifier
+ | 'super' '.' Identifier
+ | typeName '.' 'super' '.' Identifier
+ ;
+
+fieldAccess_lf_primary
+ : '.' Identifier
+ ;
+
+fieldAccess_lfno_primary
+ : 'super' '.' Identifier
+ | typeName '.' 'super' '.' Identifier
+ ;
+
+arrayAccess
+ : ( expressionName '[' expression ']'
+ | primaryNoNewArray_lfno_arrayAccess '[' expression ']'
+ )
+ ( primaryNoNewArray_lf_arrayAccess '[' expression ']'
+ )*
+ ;
+
+arrayAccess_lf_primary
+ : ( primaryNoNewArray_lf_primary_lfno_arrayAccess_lf_primary '[' expression ']'
+ )
+ ( primaryNoNewArray_lf_primary_lf_arrayAccess_lf_primary '[' expression ']'
+ )*
+ ;
+
+arrayAccess_lfno_primary
+ : ( expressionName '[' expression ']'
+ | primaryNoNewArray_lfno_primary_lfno_arrayAccess_lfno_primary '[' expression ']'
+ )
+ ( primaryNoNewArray_lfno_primary_lf_arrayAccess_lfno_primary '[' expression ']'
+ )*
+ ;
+
+methodInvocation
+ : methodName '(' argumentList? ')'
+ | typeName '.' typeArguments? Identifier '(' argumentList? ')'
+ | expressionName '.' typeArguments? Identifier '(' argumentList? ')'
+ | primary '.' typeArguments? Identifier '(' argumentList? ')'
+ | 'super' '.' typeArguments? Identifier '(' argumentList? ')'
+ | typeName '.' 'super' '.' typeArguments? Identifier '(' argumentList? ')'
+ ;
+
+methodInvocation_lf_primary
+ : '.' typeArguments? Identifier '(' argumentList? ')'
+ ;
+
+methodInvocation_lfno_primary
+ : methodName '(' argumentList? ')'
+ | typeName '.' typeArguments? Identifier '(' argumentList? ')'
+ | expressionName '.' typeArguments? Identifier '(' argumentList? ')'
+ | 'super' '.' typeArguments? Identifier '(' argumentList? ')'
+ | typeName '.' 'super' '.' typeArguments? Identifier '(' argumentList? ')'
+ ;
+
+argumentList
+ : expression (',' expression)*
+ ;
+
+methodReference
+ : expressionName '::' typeArguments? Identifier
+ | referenceType '::' typeArguments? Identifier
+ | primary '::' typeArguments? Identifier
+ | 'super' '::' typeArguments? Identifier
+ | typeName '.' 'super' '::' typeArguments? Identifier
+ | classType '::' typeArguments? 'new'
+ | arrayType '::' 'new'
+ ;
+
+methodReference_lf_primary
+ : '::' typeArguments? Identifier
+ ;
+
+methodReference_lfno_primary
+ : expressionName '::' typeArguments? Identifier
+ | referenceType '::' typeArguments? Identifier
+ | 'super' '::' typeArguments? Identifier
+ | typeName '.' 'super' '::' typeArguments? Identifier
+ | classType '::' typeArguments? 'new'
+ | arrayType '::' 'new'
+ ;
+
+arrayCreationExpression
+ : 'new' primitiveType dimExprs dims?
+ | 'new' classOrInterfaceType dimExprs dims?
+ | 'new' primitiveType dims arrayInitializer
+ | 'new' classOrInterfaceType dims arrayInitializer
+ ;
+
+dimExprs
+ : dimExpr dimExpr*
+ ;
+
+dimExpr
+ : annotation* '[' expression ']'
+ ;
+
+constantExpression
+ : expression
+ ;
+
+expression
+ : lambdaExpression
+ | assignmentExpression
+ ;
+
+lambdaExpression
+ : lambdaParameters '->' lambdaBody
+ ;
+
+lambdaParameters
+ : Identifier
+ | '(' formalParameterList? ')'
+ | '(' inferredFormalParameterList ')'
+ ;
+
+inferredFormalParameterList
+ : Identifier (',' Identifier)*
+ ;
+
+lambdaBody
+ : expression
+ | block
+ ;
+
+assignmentExpression
+ : conditionalExpression
+ | assignment
+ ;
+
+assignment
+ : leftHandSide assignmentOperator expression
+ ;
+
+leftHandSide
+ : expressionName
+ | fieldAccess
+ | arrayAccess
+ ;
+
+assignmentOperator
+ : '='
+ | '*='
+ | '/='
+ | '%='
+ | '+='
+ | '-='
+ | '<<='
+ | '>>='
+ | '>>>='
+ | '&='
+ | '^='
+ | '|='
+ ;
+
+conditionalExpression
+ : conditionalOrExpression
+ | conditionalOrExpression '?' expression ':' conditionalExpression
+ ;
+
+conditionalOrExpression
+ : conditionalAndExpression
+ | conditionalOrExpression '||' conditionalAndExpression
+ ;
+
+conditionalAndExpression
+ : inclusiveOrExpression
+ | conditionalAndExpression '&&' inclusiveOrExpression
+ ;
+
+inclusiveOrExpression
+ : exclusiveOrExpression
+ | inclusiveOrExpression '|' exclusiveOrExpression
+ ;
+
+exclusiveOrExpression
+ : andExpression
+ | exclusiveOrExpression '^' andExpression
+ ;
+
+andExpression
+ : equalityExpression
+ | andExpression '&' equalityExpression
+ ;
+
+equalityExpression
+ : relationalExpression
+ | equalityExpression '==' relationalExpression
+ | equalityExpression '!=' relationalExpression
+ ;
+
+relationalExpression
+ : shiftExpression
+ | relationalExpression '<' shiftExpression
+ | relationalExpression '>' shiftExpression
+ | relationalExpression '<=' shiftExpression
+ | relationalExpression '>=' shiftExpression
+ | relationalExpression 'instanceof' referenceType
+ ;
+
+shiftExpression
+ : additiveExpression
+ | shiftExpression '<' '<' additiveExpression
+ | shiftExpression '>' '>' additiveExpression
+ | shiftExpression '>' '>' '>' additiveExpression
+ ;
+
+additiveExpression
+ : multiplicativeExpression
+ | additiveExpression '+' multiplicativeExpression
+ | additiveExpression '-' multiplicativeExpression
+ ;
+
+multiplicativeExpression
+ : unaryExpression
+ | multiplicativeExpression '*' unaryExpression
+ | multiplicativeExpression '/' unaryExpression
+ | multiplicativeExpression '%' unaryExpression
+ ;
+
+unaryExpression
+ : preIncrementExpression
+ | preDecrementExpression
+ | '+' unaryExpression
+ | '-' unaryExpression
+ | unaryExpressionNotPlusMinus
+ ;
+
+preIncrementExpression
+ : '++' unaryExpression
+ ;
+
+preDecrementExpression
+ : '--' unaryExpression
+ ;
+
+unaryExpressionNotPlusMinus
+ : postfixExpression
+ | '~' unaryExpression
+ | '!' unaryExpression
+ | castExpression
+ ;
+
+postfixExpression
+ : ( primary
+ | expressionName
+ )
+ ( postIncrementExpression_lf_postfixExpression
+ | postDecrementExpression_lf_postfixExpression
+ )*
+ ;
+
+postIncrementExpression
+ : postfixExpression '++'
+ ;
+
+postIncrementExpression_lf_postfixExpression
+ : '++'
+ ;
+
+postDecrementExpression
+ : postfixExpression '--'
+ ;
+
+postDecrementExpression_lf_postfixExpression
+ : '--'
+ ;
+
+castExpression
+ : '(' primitiveType ')' unaryExpression
+ | '(' referenceType additionalBound* ')' unaryExpressionNotPlusMinus
+ | '(' referenceType additionalBound* ')' lambdaExpression
+ ;
+
+// LEXER
+
+// §3.9 Keywords
+
+ABSTRACT : 'abstract';
+ASSERT : 'assert';
+BOOLEAN : 'boolean';
+BREAK : 'break';
+BYTE : 'byte';
+CASE : 'case';
+CATCH : 'catch';
+CHAR : 'char';
+CLASS : 'class';
+CONST : 'const';
+CONTINUE : 'continue';
+DEFAULT : 'default';
+DO : 'do';
+DOUBLE : 'double';
+ELSE : 'else';
+ENUM : 'enum';
+EXTENDS : 'extends';
+FINAL : 'final';
+FINALLY : 'finally';
+FLOAT : 'float';
+FOR : 'for';
+IF : 'if';
+GOTO : 'goto';
+IMPLEMENTS : 'implements';
+IMPORT : 'import';
+INSTANCEOF : 'instanceof';
+INT : 'int';
+INTERFACE : 'interface';
+LONG : 'long';
+NATIVE : 'native';
+NEW : 'new';
+PACKAGE : 'package';
+PRIVATE : 'private';
+PROTECTED : 'protected';
+PUBLIC : 'public';
+RETURN : 'return';
+SHORT : 'short';
+STATIC : 'static';
+STRICTFP : 'strictfp';
+SUPER : 'super';
+SWITCH : 'switch';
+SYNCHRONIZED : 'synchronized';
+THIS : 'this';
+THROW : 'throw';
+THROWS : 'throws';
+TRANSIENT : 'transient';
+TRY : 'try';
+VOID : 'void';
+VOLATILE : 'volatile';
+WHILE : 'while';
+
+// §3.10.1 Integer Literals
+
+IntegerLiteral
+ : DecimalIntegerLiteral
+ | HexIntegerLiteral
+ | OctalIntegerLiteral
+ | BinaryIntegerLiteral
+ ;
+
+fragment
+DecimalIntegerLiteral
+ : DecimalNumeral IntegerTypeSuffix?
+ ;
+
+fragment
+HexIntegerLiteral
+ : HexNumeral IntegerTypeSuffix?
+ ;
+
+fragment
+OctalIntegerLiteral
+ : OctalNumeral IntegerTypeSuffix?
+ ;
+
+fragment
+BinaryIntegerLiteral
+ : BinaryNumeral IntegerTypeSuffix?
+ ;
+
+fragment
+IntegerTypeSuffix
+ : [lL]
+ ;
+
+fragment
+DecimalNumeral
+ : '0'
+ | NonZeroDigit (Digits? | Underscores Digits)
+ ;
+
+fragment
+Digits
+ : Digit (DigitsAndUnderscores? Digit)?
+ ;
+
+fragment
+Digit
+ : '0'
+ | NonZeroDigit
+ ;
+
+fragment
+NonZeroDigit
+ : [1-9]
+ ;
+
+fragment
+DigitsAndUnderscores
+ : DigitOrUnderscore+
+ ;
+
+fragment
+DigitOrUnderscore
+ : Digit
+ | '_'
+ ;
+
+fragment
+Underscores
+ : '_'+
+ ;
+
+fragment
+HexNumeral
+ : '0' [xX] HexDigits
+ ;
+
+fragment
+HexDigits
+ : HexDigit (HexDigitsAndUnderscores? HexDigit)?
+ ;
+
+fragment
+HexDigit
+ : [0-9a-fA-F]
+ ;
+
+fragment
+HexDigitsAndUnderscores
+ : HexDigitOrUnderscore+
+ ;
+
+fragment
+HexDigitOrUnderscore
+ : HexDigit
+ | '_'
+ ;
+
+fragment
+OctalNumeral
+ : '0' Underscores? OctalDigits
+ ;
+
+fragment
+OctalDigits
+ : OctalDigit (OctalDigitsAndUnderscores? OctalDigit)?
+ ;
+
+fragment
+OctalDigit
+ : [0-7]
+ ;
+
+fragment
+OctalDigitsAndUnderscores
+ : OctalDigitOrUnderscore+
+ ;
+
+fragment
+OctalDigitOrUnderscore
+ : OctalDigit
+ | '_'
+ ;
+
+fragment
+BinaryNumeral
+ : '0' [bB] BinaryDigits
+ ;
+
+fragment
+BinaryDigits
+ : BinaryDigit (BinaryDigitsAndUnderscores? BinaryDigit)?
+ ;
+
+fragment
+BinaryDigit
+ : [01]
+ ;
+
+fragment
+BinaryDigitsAndUnderscores
+ : BinaryDigitOrUnderscore+
+ ;
+
+fragment
+BinaryDigitOrUnderscore
+ : BinaryDigit
+ | '_'
+ ;
+
+// §3.10.2 Floating-Point Literals
+
+FloatingPointLiteral
+ : DecimalFloatingPointLiteral
+ | HexadecimalFloatingPointLiteral
+ ;
+
+fragment
+DecimalFloatingPointLiteral
+ : Digits '.' Digits? ExponentPart? FloatTypeSuffix?
+ | '.' Digits ExponentPart? FloatTypeSuffix?
+ | Digits ExponentPart FloatTypeSuffix?
+ | Digits FloatTypeSuffix
+ ;
+
+fragment
+ExponentPart
+ : ExponentIndicator SignedInteger
+ ;
+
+fragment
+ExponentIndicator
+ : [eE]
+ ;
+
+fragment
+SignedInteger
+ : Sign? Digits
+ ;
+
+fragment
+Sign
+ : [+-]
+ ;
+
+fragment
+FloatTypeSuffix
+ : [fFdD]
+ ;
+
+fragment
+HexadecimalFloatingPointLiteral
+ : HexSignificand BinaryExponent FloatTypeSuffix?
+ ;
+
+fragment
+HexSignificand
+ : HexNumeral '.'?
+ | '0' [xX] HexDigits? '.' HexDigits
+ ;
+
+fragment
+BinaryExponent
+ : BinaryExponentIndicator SignedInteger
+ ;
+
+fragment
+BinaryExponentIndicator
+ : [pP]
+ ;
+
+// §3.10.3 Boolean Literals
+
+BooleanLiteral
+ : 'true'
+ | 'false'
+ ;
+
+// §3.10.4 Character Literals
+
+CharacterLiteral
+ : '\'' SingleCharacter '\''
+ | '\'' EscapeSequence '\''
+ ;
+
+fragment
+SingleCharacter
+ : ~['\\\r\n]
+ ;
+
+// §3.10.5 String Literals
+
+StringLiteral
+ : '"' StringCharacters? '"'
+ ;
+
+fragment
+StringCharacters
+ : StringCharacter+
+ ;
+
+fragment
+StringCharacter
+ : ~["\\\r\n]
+ | EscapeSequence
+ ;
+
+// §3.10.6 Escape Sequences for Character and String Literals
+
+fragment
+EscapeSequence
+ : '\\' [btnfr"'\\]
+ | OctalEscape
+ | UnicodeEscape // This is not in the spec but prevents having to preprocess the input
+ ;
+
+fragment
+OctalEscape
+ : '\\' OctalDigit
+ | '\\' OctalDigit OctalDigit
+ | '\\' ZeroToThree OctalDigit OctalDigit
+ ;
+
+fragment
+ZeroToThree
+ : [0-3]
+ ;
+
+// This is not in the spec but prevents having to preprocess the input
+fragment
+UnicodeEscape
+ : '\\' 'u'+ HexDigit HexDigit HexDigit HexDigit
+ ;
+
+// §3.10.7 The Null Literal
+
+NullLiteral
+ : 'null'
+ ;
+
+// §3.11 Separators
+
+LPAREN : '(';
+RPAREN : ')';
+LBRACE : '{';
+RBRACE : '}';
+LBRACK : '[';
+RBRACK : ']';
+SEMI : ';';
+COMMA : ',';
+DOT : '.';
+
+// §3.12 Operators
+
+ASSIGN : '=';
+GT : '>';
+LT : '<';
+BANG : '!';
+TILDE : '~';
+QUESTION : '?';
+COLON : ':';
+EQUAL : '==';
+LE : '<=';
+GE : '>=';
+NOTEQUAL : '!=';
+AND : '&&';
+OR : '||';
+INC : '++';
+DEC : '--';
+ADD : '+';
+SUB : '-';
+MUL : '*';
+DIV : '/';
+BITAND : '&';
+BITOR : '|';
+CARET : '^';
+MOD : '%';
+ARROW : '->';
+COLONCOLON : '::';
+
+ADD_ASSIGN : '+=';
+SUB_ASSIGN : '-=';
+MUL_ASSIGN : '*=';
+DIV_ASSIGN : '/=';
+AND_ASSIGN : '&=';
+OR_ASSIGN : '|=';
+XOR_ASSIGN : '^=';
+MOD_ASSIGN : '%=';
+LSHIFT_ASSIGN : '<<=';
+RSHIFT_ASSIGN : '>>=';
+URSHIFT_ASSIGN : '>>>=';
+
+// §3.8 Identifiers (must appear after all keywords in the grammar)
+
+Identifier
+ : JavaLetter JavaLetterOrDigit*
+ ;
+
+fragment
+JavaLetter
+ : [a-zA-Z$_] // these are the "java letters" below 0x7F
+ | // covers all characters above 0x7F which are not a surrogate
+ ~[\u0000-\u007F\uD800-\uDBFF]
+ {Character.isJavaIdentifierStart(_input.LA(-1))}?
+ | // covers UTF-16 surrogate pairs encodings for U+10000 to U+10FFFF
+ [\uD800-\uDBFF] [\uDC00-\uDFFF]
+ {Character.isJavaIdentifierStart(Character.toCodePoint((char)_input.LA(-2), (char)_input.LA(-1)))}?
+ ;
+
+fragment
+JavaLetterOrDigit
+ : [a-zA-Z0-9$_] // these are the "java letters or digits" below 0x7F
+ | // covers all characters above 0x7F which are not a surrogate
+ ~[\u0000-\u007F\uD800-\uDBFF]
+ {Character.isJavaIdentifierPart(_input.LA(-1))}?
+ | // covers UTF-16 surrogate pairs encodings for U+10000 to U+10FFFF
+ [\uD800-\uDBFF] [\uDC00-\uDFFF]
+ {Character.isJavaIdentifierPart(Character.toCodePoint((char)_input.LA(-2), (char)_input.LA(-1)))}?
+ ;
+
+//
+// Additional symbols not defined in the lexical specification
+//
+
+AT : '@';
+ELLIPSIS : '...';
+
+//
+// Whitespace and comments
+//
+
+WS : [ \t\r\n\u000C]+ -> skip
+ ;
+
+COMMENT
+ : '/*' .*? '*/' -> skip
+ ;
+
+LINE_COMMENT
+ : '//' ~[\r\n]* -> skip
+ ;
\ No newline at end of file
diff --git a/antlr/src/main/antlr4/com/baeldung/antlr/Log.g4 b/antlr/src/main/antlr4/com/baeldung/antlr/Log.g4
new file mode 100644
index 0000000000..3ecb966f50
--- /dev/null
+++ b/antlr/src/main/antlr4/com/baeldung/antlr/Log.g4
@@ -0,0 +1,16 @@
+grammar Log;
+
+log : entry+;
+entry : timestamp ' ' level ' ' message CRLF;
+timestamp : DATE ' ' TIME;
+level : 'ERROR' | 'INFO' | 'DEBUG';
+message : (TEXT | ' ')+;
+
+fragment DIGIT : [0-9];
+fragment TWODIGIT : DIGIT DIGIT;
+fragment LETTER : [A-Za-z];
+
+DATE : TWODIGIT TWODIGIT '-' LETTER LETTER LETTER '-' TWODIGIT;
+TIME : TWODIGIT ':' TWODIGIT ':' TWODIGIT;
+TEXT : LETTER+;
+CRLF : '\r'? '\n' | '\r';
\ No newline at end of file
diff --git a/antlr/src/main/java/com/baeldung/antlr/java/UppercaseMethodListener.java b/antlr/src/main/java/com/baeldung/antlr/java/UppercaseMethodListener.java
new file mode 100644
index 0000000000..5092359b72
--- /dev/null
+++ b/antlr/src/main/java/com/baeldung/antlr/java/UppercaseMethodListener.java
@@ -0,0 +1,28 @@
+package com.baeldung.antlr.java;
+
+import com.baeldung.antlr.Java8BaseListener;
+import com.baeldung.antlr.Java8Parser;
+import org.antlr.v4.runtime.tree.TerminalNode;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+public class UppercaseMethodListener extends Java8BaseListener {
+
+ private List errors = new ArrayList();
+
+ @Override
+ public void enterMethodDeclarator(Java8Parser.MethodDeclaratorContext ctx) {
+ TerminalNode node = ctx.Identifier();
+ String methodName = node.getText();
+
+ if (Character.isUpperCase(methodName.charAt(0))){
+ errors.add(String.format("Method %s is uppercased!", methodName));
+ }
+ }
+
+ public List getErrors(){
+ return Collections.unmodifiableList(errors);
+ }
+}
diff --git a/antlr/src/main/java/com/baeldung/antlr/log/LogListener.java b/antlr/src/main/java/com/baeldung/antlr/log/LogListener.java
new file mode 100644
index 0000000000..1f6d91df95
--- /dev/null
+++ b/antlr/src/main/java/com/baeldung/antlr/log/LogListener.java
@@ -0,0 +1,51 @@
+package com.baeldung.antlr.log;
+
+import com.baeldung.antlr.LogBaseListener;
+import com.baeldung.antlr.LogParser;
+import com.baeldung.antlr.log.model.LogLevel;
+import com.baeldung.antlr.log.model.LogEntry;
+
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Locale;
+
+public class LogListener extends LogBaseListener {
+
+ private static final DateTimeFormatter DEFAULT_DATETIME_FORMATTER
+ = DateTimeFormatter.ofPattern("yyyy-MMM-dd HH:mm:ss", Locale.ENGLISH);
+
+ private List entries = new ArrayList<>();
+ private LogEntry currentLogEntry;
+
+ @Override
+ public void enterEntry(LogParser.EntryContext ctx) {
+ this.currentLogEntry = new LogEntry();
+ }
+
+ @Override
+ public void exitEntry(LogParser.EntryContext ctx) {
+ entries.add(currentLogEntry);
+ }
+
+ @Override
+ public void enterTimestamp(LogParser.TimestampContext ctx) {
+ currentLogEntry.setTimestamp(LocalDateTime.parse(ctx.getText(), DEFAULT_DATETIME_FORMATTER));
+ }
+
+ @Override
+ public void enterMessage(LogParser.MessageContext ctx) {
+ currentLogEntry.setMessage(ctx.getText());
+ }
+
+ @Override
+ public void enterLevel(LogParser.LevelContext ctx) {
+ currentLogEntry.setLevel(LogLevel.valueOf(ctx.getText()));
+ }
+
+ public List getEntries() {
+ return Collections.unmodifiableList(entries);
+ }
+}
diff --git a/antlr/src/main/java/com/baeldung/antlr/log/model/LogEntry.java b/antlr/src/main/java/com/baeldung/antlr/log/model/LogEntry.java
new file mode 100644
index 0000000000..2b406c4ae9
--- /dev/null
+++ b/antlr/src/main/java/com/baeldung/antlr/log/model/LogEntry.java
@@ -0,0 +1,35 @@
+package com.baeldung.antlr.log.model;
+
+
+import java.time.LocalDateTime;
+
+public class LogEntry {
+
+ private LogLevel level;
+ private String message;
+ private LocalDateTime timestamp;
+
+ public LogLevel getLevel() {
+ return level;
+ }
+
+ public void setLevel(LogLevel level) {
+ this.level = level;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public LocalDateTime getTimestamp() {
+ return timestamp;
+ }
+
+ public void setTimestamp(LocalDateTime timestamp) {
+ this.timestamp = timestamp;
+ }
+}
diff --git a/antlr/src/main/java/com/baeldung/antlr/log/model/LogLevel.java b/antlr/src/main/java/com/baeldung/antlr/log/model/LogLevel.java
new file mode 100644
index 0000000000..004d9c6e8c
--- /dev/null
+++ b/antlr/src/main/java/com/baeldung/antlr/log/model/LogLevel.java
@@ -0,0 +1,5 @@
+package com.baeldung.antlr.log.model;
+
+public enum LogLevel {
+ DEBUG, INFO, ERROR
+}
diff --git a/antlr/src/main/resources/logback.xml b/antlr/src/main/resources/logback.xml
new file mode 100644
index 0000000000..7d900d8ea8
--- /dev/null
+++ b/antlr/src/main/resources/logback.xml
@@ -0,0 +1,13 @@
+
+
+
+
+ %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/antlr/src/test/java/com/baeldung/antlr/JavaParserUnitTest.java b/antlr/src/test/java/com/baeldung/antlr/JavaParserUnitTest.java
new file mode 100644
index 0000000000..0d43e0f284
--- /dev/null
+++ b/antlr/src/test/java/com/baeldung/antlr/JavaParserUnitTest.java
@@ -0,0 +1,30 @@
+package com.baeldung.antlr;
+
+import com.baeldung.antlr.java.UppercaseMethodListener;
+import org.antlr.v4.runtime.CharStreams;
+import org.antlr.v4.runtime.CommonTokenStream;
+import org.antlr.v4.runtime.tree.ParseTree;
+import org.antlr.v4.runtime.tree.ParseTreeWalker;
+import org.junit.Test;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+public class JavaParserUnitTest {
+
+ @Test
+ public void whenOneMethodStartsWithUpperCase_thenOneErrorReturned() throws Exception{
+
+ String javaClassContent = "public class SampleClass { void DoSomething(){} }";
+ Java8Lexer java8Lexer = new Java8Lexer(CharStreams.fromString(javaClassContent));
+ CommonTokenStream tokens = new CommonTokenStream(java8Lexer);
+ Java8Parser java8Parser = new Java8Parser(tokens);
+ ParseTree tree = java8Parser.compilationUnit();
+ ParseTreeWalker walker = new ParseTreeWalker();
+ UppercaseMethodListener uppercaseMethodListener = new UppercaseMethodListener();
+ walker.walk(uppercaseMethodListener, tree);
+
+ assertThat(uppercaseMethodListener.getErrors().size(), is(1));
+ assertThat(uppercaseMethodListener.getErrors().get(0),
+ is("Method DoSomething is uppercased!"));
+ }
+}
diff --git a/antlr/src/test/java/com/baeldung/antlr/LogParserUnitTest.java b/antlr/src/test/java/com/baeldung/antlr/LogParserUnitTest.java
new file mode 100644
index 0000000000..d263c2bd19
--- /dev/null
+++ b/antlr/src/test/java/com/baeldung/antlr/LogParserUnitTest.java
@@ -0,0 +1,36 @@
+package com.baeldung.antlr;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import com.baeldung.antlr.log.LogListener;
+import com.baeldung.antlr.log.model.LogLevel;
+import com.baeldung.antlr.log.model.LogEntry;
+import org.antlr.v4.runtime.CharStreams;
+import org.antlr.v4.runtime.CommonTokenStream;
+import org.antlr.v4.runtime.tree.ParseTreeWalker;
+import org.junit.Test;
+
+import java.time.LocalDateTime;
+
+
+public class LogParserUnitTest {
+
+ @Test
+ public void whenLogContainsOneErrorLogEntry_thenOneErrorIsReturned() throws Exception {
+ String logLines = "2018-May-05 14:20:21 DEBUG entering awesome method\r\n" +
+ "2018-May-05 14:20:24 ERROR Bad thing happened\r\n";
+ LogLexer serverLogLexer = new LogLexer(CharStreams.fromString(logLines));
+ CommonTokenStream tokens = new CommonTokenStream( serverLogLexer );
+ LogParser logParser = new LogParser(tokens);
+ ParseTreeWalker walker = new ParseTreeWalker();
+ LogListener logWalker = new LogListener();
+ walker.walk(logWalker, logParser.log());
+
+ assertThat(logWalker.getEntries().size(), is(2));
+ LogEntry error = logWalker.getEntries().get(1);
+ assertThat(error.getLevel(), is(LogLevel.ERROR));
+ assertThat(error.getMessage(), is("Bad thing happened"));
+ assertThat(error.getTimestamp(), is(LocalDateTime.of(2018,5,5,14,20,24)));
+ }
+}
diff --git a/apache-avro/README.md b/apache-avro/README.md
new file mode 100644
index 0000000000..32d84ecc76
--- /dev/null
+++ b/apache-avro/README.md
@@ -0,0 +1,2 @@
+### Relevant Articles:
+- [Guide to Apache Avro](http://www.baeldung.com/java-apache-avro)
diff --git a/apache-avro/pom.xml b/apache-avro/pom.xml
new file mode 100644
index 0000000000..ddf5844271
--- /dev/null
+++ b/apache-avro/pom.xml
@@ -0,0 +1,89 @@
+
+
+ 4.0.0
+ com.baeldung
+ apache-avro
+ 0.0.1-SNAPSHOT
+ Apache Avro
+
+
+ UTF-8
+ 3.5
+ 1.8.2
+ 1.8
+ 1.7.25
+
+
+
+ com.baeldung
+ parent-modules
+ 1.0.0-SNAPSHOT
+
+
+
+
+ junit
+ junit
+ 4.10
+ test
+
+
+ org.slf4j
+ slf4j-simple
+ ${slf4j.version}
+ compile
+
+
+ org.apache.avro
+ avro
+ ${avro.version}
+
+
+ org.apache.avro
+ avro-compiler
+ ${avro.version}
+
+
+
+ org.apache.avro
+ avro-maven-plugin
+ ${avro.version}
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ ${compiler-plugin.version}
+
+ ${java.version}
+ ${java.version}
+
+
+
+ org.apache.avro
+ avro-maven-plugin
+ ${avro.version}
+
+
+ schemas
+ generate-sources
+
+ schema
+ protocol
+ idl-protocol
+
+
+ ${project.basedir}/src/main/resources/
+ ${project.basedir}/src/main/java/
+
+
+
+
+
+
+
diff --git a/apache-avro/src/main/java/com/baeldung/avro/util/AvroClassGenerator.java b/apache-avro/src/main/java/com/baeldung/avro/util/AvroClassGenerator.java
new file mode 100644
index 0000000000..718b62a752
--- /dev/null
+++ b/apache-avro/src/main/java/com/baeldung/avro/util/AvroClassGenerator.java
@@ -0,0 +1,14 @@
+package com.baeldung.avro.util;
+
+import org.apache.avro.Schema;
+import org.apache.avro.compiler.specific.SpecificCompiler;
+
+import java.io.File;
+import java.io.IOException;
+
+public class AvroClassGenerator {
+ public void generateAvroClasses() throws IOException {
+ SpecificCompiler compiler = new SpecificCompiler(new Schema.Parser().parse(new File("src/main/resources/avroHttpRequest-schema.avsc")));
+ compiler.compileToDestination(new File("src/main/resources"), new File("src/main/java"));
+ }
+}
diff --git a/apache-avro/src/main/java/com/baeldung/avro/util/AvroSchemaBuilder.java b/apache-avro/src/main/java/com/baeldung/avro/util/AvroSchemaBuilder.java
new file mode 100644
index 0000000000..4a1314cd00
--- /dev/null
+++ b/apache-avro/src/main/java/com/baeldung/avro/util/AvroSchemaBuilder.java
@@ -0,0 +1,24 @@
+package com.baeldung.avro.util;
+
+
+import org.apache.avro.Schema;
+import org.apache.avro.SchemaBuilder;
+
+public class AvroSchemaBuilder {
+
+ public Schema createAvroHttpRequestSchema(){
+
+ Schema clientIdentifier = SchemaBuilder.record("ClientIdentifier").namespace("com.baeldung.avro.model")
+ .fields().requiredString("hostName").requiredString("ipAddress").endRecord();
+
+ Schema avroHttpRequest = SchemaBuilder.record("AvroHttpRequest").namespace("com.baeldung.avro.model").fields()
+ .requiredLong("requestTime")
+ .name("clientIdentifier").type(clientIdentifier).noDefault()
+ .name("employeeNames").type().array().items().stringType().arrayDefault(null)
+ .name("active").type().enumeration("Active").symbols("YES", "NO").noDefault()
+ .endRecord();
+ return avroHttpRequest;
+ }
+}
+
+
diff --git a/apache-avro/src/main/java/com/baeldung/avro/util/model/Active.java b/apache-avro/src/main/java/com/baeldung/avro/util/model/Active.java
new file mode 100644
index 0000000000..3ae0508394
--- /dev/null
+++ b/apache-avro/src/main/java/com/baeldung/avro/util/model/Active.java
@@ -0,0 +1,13 @@
+/**
+ * Autogenerated by Avro
+ *
+ * DO NOT EDIT DIRECTLY
+ */
+package com.baeldung.avro.util.model;
+@SuppressWarnings("all")
+@org.apache.avro.specific.AvroGenerated
+public enum Active {
+ YES, NO ;
+ public static final org.apache.avro.Schema SCHEMA$ = new org.apache.avro.Schema.Parser().parse("{\"type\":\"enum\",\"name\":\"Active\",\"namespace\":\"com.baeldung.avro.model\",\"symbols\":[\"YES\",\"NO\"]}");
+ public static org.apache.avro.Schema getClassSchema() { return SCHEMA$; }
+}
diff --git a/apache-avro/src/main/java/com/baeldung/avro/util/model/AvroHttpRequest.java b/apache-avro/src/main/java/com/baeldung/avro/util/model/AvroHttpRequest.java
new file mode 100644
index 0000000000..56b36050a5
--- /dev/null
+++ b/apache-avro/src/main/java/com/baeldung/avro/util/model/AvroHttpRequest.java
@@ -0,0 +1,491 @@
+/**
+ * Autogenerated by Avro
+ *
+ * DO NOT EDIT DIRECTLY
+ */
+package com.baeldung.avro.util.model;
+
+import org.apache.avro.specific.SpecificData;
+import org.apache.avro.message.BinaryMessageEncoder;
+import org.apache.avro.message.BinaryMessageDecoder;
+import org.apache.avro.message.SchemaStore;
+
+@SuppressWarnings("all")
+@org.apache.avro.specific.AvroGenerated
+public class AvroHttpRequest extends org.apache.avro.specific.SpecificRecordBase implements org.apache.avro.specific.SpecificRecord {
+ private static final long serialVersionUID = -8649010116827875312L;
+ public static final org.apache.avro.Schema SCHEMA$ = new org.apache.avro.Schema.Parser().parse("{\"type\":\"record\",\"name\":\"AvroHttpRequest\",\"namespace\":\"com.baeldung.avro.model\",\"fields\":[{\"name\":\"requestTime\",\"type\":\"long\"},{\"name\":\"clientIdentifier\",\"type\":{\"type\":\"record\",\"name\":\"ClientIdentifier\",\"fields\":[{\"name\":\"hostName\",\"type\":\"string\"},{\"name\":\"ipAddress\",\"type\":\"string\"}]}},{\"name\":\"employeeNames\",\"type\":{\"type\":\"array\",\"items\":\"string\"},\"default\":null},{\"name\":\"active\",\"type\":{\"type\":\"enum\",\"name\":\"Active\",\"symbols\":[\"YES\",\"NO\"]}}]}");
+ public static org.apache.avro.Schema getClassSchema() { return SCHEMA$; }
+
+ private static SpecificData MODEL$ = new SpecificData();
+
+ private static final BinaryMessageEncoder ENCODER =
+ new BinaryMessageEncoder(MODEL$, SCHEMA$);
+
+ private static final BinaryMessageDecoder DECODER =
+ new BinaryMessageDecoder(MODEL$, SCHEMA$);
+
+ /**
+ * Return the BinaryMessageDecoder instance used by this class.
+ */
+ public static BinaryMessageDecoder getDecoder() {
+ return DECODER;
+ }
+
+ /**
+ * Create a new BinaryMessageDecoder instance for this class that uses the specified {@link SchemaStore}.
+ * @param resolver a {@link SchemaStore} used to find schemas by fingerprint
+ */
+ public static BinaryMessageDecoder createDecoder(SchemaStore resolver) {
+ return new BinaryMessageDecoder(MODEL$, SCHEMA$, resolver);
+ }
+
+ /** Serializes this AvroHttpRequest to a ByteBuffer. */
+ public java.nio.ByteBuffer toByteBuffer() throws java.io.IOException {
+ return ENCODER.encode(this);
+ }
+
+ /** Deserializes a AvroHttpRequest from a ByteBuffer. */
+ public static AvroHttpRequest fromByteBuffer(
+ java.nio.ByteBuffer b) throws java.io.IOException {
+ return DECODER.decode(b);
+ }
+
+ @Deprecated public long requestTime;
+ @Deprecated public ClientIdentifier clientIdentifier;
+ @Deprecated public java.util.List employeeNames;
+ @Deprecated public Active active;
+
+ /**
+ * Default constructor. Note that this does not initialize fields
+ * to their default values from the schema. If that is desired then
+ * one should use newBuilder()
.
+ */
+ public AvroHttpRequest() {}
+
+ /**
+ * All-args constructor.
+ * @param requestTime The new value for requestTime
+ * @param clientIdentifier The new value for clientIdentifier
+ * @param employeeNames The new value for employeeNames
+ * @param active The new value for active
+ */
+ public AvroHttpRequest(java.lang.Long requestTime, ClientIdentifier clientIdentifier, java.util.List employeeNames, Active active) {
+ this.requestTime = requestTime;
+ this.clientIdentifier = clientIdentifier;
+ this.employeeNames = employeeNames;
+ this.active = active;
+ }
+
+ public org.apache.avro.Schema getSchema() { return SCHEMA$; }
+ // Used by DatumWriter. Applications should not call.
+ public java.lang.Object get(int field$) {
+ switch (field$) {
+ case 0: return requestTime;
+ case 1: return clientIdentifier;
+ case 2: return employeeNames;
+ case 3: return active;
+ default: throw new org.apache.avro.AvroRuntimeException("Bad index");
+ }
+ }
+
+ // Used by DatumReader. Applications should not call.
+ @SuppressWarnings(value="unchecked")
+ public void put(int field$, java.lang.Object value$) {
+ switch (field$) {
+ case 0: requestTime = (java.lang.Long)value$; break;
+ case 1: clientIdentifier = (ClientIdentifier)value$; break;
+ case 2: employeeNames = (java.util.List)value$; break;
+ case 3: active = (Active)value$; break;
+ default: throw new org.apache.avro.AvroRuntimeException("Bad index");
+ }
+ }
+
+ /**
+ * Gets the value of the 'requestTime' field.
+ * @return The value of the 'requestTime' field.
+ */
+ public java.lang.Long getRequestTime() {
+ return requestTime;
+ }
+
+ /**
+ * Sets the value of the 'requestTime' field.
+ * @param value the value to set.
+ */
+ public void setRequestTime(java.lang.Long value) {
+ this.requestTime = value;
+ }
+
+ /**
+ * Gets the value of the 'clientIdentifier' field.
+ * @return The value of the 'clientIdentifier' field.
+ */
+ public ClientIdentifier getClientIdentifier() {
+ return clientIdentifier;
+ }
+
+ /**
+ * Sets the value of the 'clientIdentifier' field.
+ * @param value the value to set.
+ */
+ public void setClientIdentifier(ClientIdentifier value) {
+ this.clientIdentifier = value;
+ }
+
+ /**
+ * Gets the value of the 'employeeNames' field.
+ * @return The value of the 'employeeNames' field.
+ */
+ public java.util.List getEmployeeNames() {
+ return employeeNames;
+ }
+
+ /**
+ * Sets the value of the 'employeeNames' field.
+ * @param value the value to set.
+ */
+ public void setEmployeeNames(java.util.List value) {
+ this.employeeNames = value;
+ }
+
+ /**
+ * Gets the value of the 'active' field.
+ * @return The value of the 'active' field.
+ */
+ public Active getActive() {
+ return active;
+ }
+
+ /**
+ * Sets the value of the 'active' field.
+ * @param value the value to set.
+ */
+ public void setActive(Active value) {
+ this.active = value;
+ }
+
+ /**
+ * Creates a new AvroHttpRequest RecordBuilder.
+ * @return A new AvroHttpRequest RecordBuilder
+ */
+ public static AvroHttpRequest.Builder newBuilder() {
+ return new AvroHttpRequest.Builder();
+ }
+
+ /**
+ * Creates a new AvroHttpRequest RecordBuilder by copying an existing Builder.
+ * @param other The existing builder to copy.
+ * @return A new AvroHttpRequest RecordBuilder
+ */
+ public static AvroHttpRequest.Builder newBuilder(AvroHttpRequest.Builder other) {
+ return new AvroHttpRequest.Builder(other);
+ }
+
+ /**
+ * Creates a new AvroHttpRequest RecordBuilder by copying an existing AvroHttpRequest instance.
+ * @param other The existing instance to copy.
+ * @return A new AvroHttpRequest RecordBuilder
+ */
+ public static AvroHttpRequest.Builder newBuilder(AvroHttpRequest other) {
+ return new AvroHttpRequest.Builder(other);
+ }
+
+ /**
+ * RecordBuilder for AvroHttpRequest instances.
+ */
+ public static class Builder extends org.apache.avro.specific.SpecificRecordBuilderBase
+ implements org.apache.avro.data.RecordBuilder {
+
+ private long requestTime;
+ private ClientIdentifier clientIdentifier;
+ private ClientIdentifier.Builder clientIdentifierBuilder;
+ private java.util.List employeeNames;
+ private Active active;
+
+ /** Creates a new Builder */
+ private Builder() {
+ super(SCHEMA$);
+ }
+
+ /**
+ * Creates a Builder by copying an existing Builder.
+ * @param other The existing Builder to copy.
+ */
+ private Builder(AvroHttpRequest.Builder other) {
+ super(other);
+ if (isValidValue(fields()[0], other.requestTime)) {
+ this.requestTime = data().deepCopy(fields()[0].schema(), other.requestTime);
+ fieldSetFlags()[0] = true;
+ }
+ if (isValidValue(fields()[1], other.clientIdentifier)) {
+ this.clientIdentifier = data().deepCopy(fields()[1].schema(), other.clientIdentifier);
+ fieldSetFlags()[1] = true;
+ }
+ if (other.hasClientIdentifierBuilder()) {
+ this.clientIdentifierBuilder = ClientIdentifier.newBuilder(other.getClientIdentifierBuilder());
+ }
+ if (isValidValue(fields()[2], other.employeeNames)) {
+ this.employeeNames = data().deepCopy(fields()[2].schema(), other.employeeNames);
+ fieldSetFlags()[2] = true;
+ }
+ if (isValidValue(fields()[3], other.active)) {
+ this.active = data().deepCopy(fields()[3].schema(), other.active);
+ fieldSetFlags()[3] = true;
+ }
+ }
+
+ /**
+ * Creates a Builder by copying an existing AvroHttpRequest instance
+ * @param other The existing instance to copy.
+ */
+ private Builder(AvroHttpRequest other) {
+ super(SCHEMA$);
+ if (isValidValue(fields()[0], other.requestTime)) {
+ this.requestTime = data().deepCopy(fields()[0].schema(), other.requestTime);
+ fieldSetFlags()[0] = true;
+ }
+ if (isValidValue(fields()[1], other.clientIdentifier)) {
+ this.clientIdentifier = data().deepCopy(fields()[1].schema(), other.clientIdentifier);
+ fieldSetFlags()[1] = true;
+ }
+ this.clientIdentifierBuilder = null;
+ if (isValidValue(fields()[2], other.employeeNames)) {
+ this.employeeNames = data().deepCopy(fields()[2].schema(), other.employeeNames);
+ fieldSetFlags()[2] = true;
+ }
+ if (isValidValue(fields()[3], other.active)) {
+ this.active = data().deepCopy(fields()[3].schema(), other.active);
+ fieldSetFlags()[3] = true;
+ }
+ }
+
+ /**
+ * Gets the value of the 'requestTime' field.
+ * @return The value.
+ */
+ public java.lang.Long getRequestTime() {
+ return requestTime;
+ }
+
+ /**
+ * Sets the value of the 'requestTime' field.
+ * @param value The value of 'requestTime'.
+ * @return This builder.
+ */
+ public AvroHttpRequest.Builder setRequestTime(long value) {
+ validate(fields()[0], value);
+ this.requestTime = value;
+ fieldSetFlags()[0] = true;
+ return this;
+ }
+
+ /**
+ * Checks whether the 'requestTime' field has been set.
+ * @return True if the 'requestTime' field has been set, false otherwise.
+ */
+ public boolean hasRequestTime() {
+ return fieldSetFlags()[0];
+ }
+
+
+ /**
+ * Clears the value of the 'requestTime' field.
+ * @return This builder.
+ */
+ public AvroHttpRequest.Builder clearRequestTime() {
+ fieldSetFlags()[0] = false;
+ return this;
+ }
+
+ /**
+ * Gets the value of the 'clientIdentifier' field.
+ * @return The value.
+ */
+ public ClientIdentifier getClientIdentifier() {
+ return clientIdentifier;
+ }
+
+ /**
+ * Sets the value of the 'clientIdentifier' field.
+ * @param value The value of 'clientIdentifier'.
+ * @return This builder.
+ */
+ public AvroHttpRequest.Builder setClientIdentifier(ClientIdentifier value) {
+ validate(fields()[1], value);
+ this.clientIdentifierBuilder = null;
+ this.clientIdentifier = value;
+ fieldSetFlags()[1] = true;
+ return this;
+ }
+
+ /**
+ * Checks whether the 'clientIdentifier' field has been set.
+ * @return True if the 'clientIdentifier' field has been set, false otherwise.
+ */
+ public boolean hasClientIdentifier() {
+ return fieldSetFlags()[1];
+ }
+
+ /**
+ * Gets the Builder instance for the 'clientIdentifier' field and creates one if it doesn't exist yet.
+ * @return This builder.
+ */
+ public ClientIdentifier.Builder getClientIdentifierBuilder() {
+ if (clientIdentifierBuilder == null) {
+ if (hasClientIdentifier()) {
+ setClientIdentifierBuilder(ClientIdentifier.newBuilder(clientIdentifier));
+ } else {
+ setClientIdentifierBuilder(ClientIdentifier.newBuilder());
+ }
+ }
+ return clientIdentifierBuilder;
+ }
+
+ /**
+ * Sets the Builder instance for the 'clientIdentifier' field
+ * @param value The builder instance that must be set.
+ * @return This builder.
+ */
+ public AvroHttpRequest.Builder setClientIdentifierBuilder(ClientIdentifier.Builder value) {
+ clearClientIdentifier();
+ clientIdentifierBuilder = value;
+ return this;
+ }
+
+ /**
+ * Checks whether the 'clientIdentifier' field has an active Builder instance
+ * @return True if the 'clientIdentifier' field has an active Builder instance
+ */
+ public boolean hasClientIdentifierBuilder() {
+ return clientIdentifierBuilder != null;
+ }
+
+ /**
+ * Clears the value of the 'clientIdentifier' field.
+ * @return This builder.
+ */
+ public AvroHttpRequest.Builder clearClientIdentifier() {
+ clientIdentifier = null;
+ clientIdentifierBuilder = null;
+ fieldSetFlags()[1] = false;
+ return this;
+ }
+
+ /**
+ * Gets the value of the 'employeeNames' field.
+ * @return The value.
+ */
+ public java.util.List getEmployeeNames() {
+ return employeeNames;
+ }
+
+ /**
+ * Sets the value of the 'employeeNames' field.
+ * @param value The value of 'employeeNames'.
+ * @return This builder.
+ */
+ public AvroHttpRequest.Builder setEmployeeNames(java.util.List value) {
+ validate(fields()[2], value);
+ this.employeeNames = value;
+ fieldSetFlags()[2] = true;
+ return this;
+ }
+
+ /**
+ * Checks whether the 'employeeNames' field has been set.
+ * @return True if the 'employeeNames' field has been set, false otherwise.
+ */
+ public boolean hasEmployeeNames() {
+ return fieldSetFlags()[2];
+ }
+
+
+ /**
+ * Clears the value of the 'employeeNames' field.
+ * @return This builder.
+ */
+ public AvroHttpRequest.Builder clearEmployeeNames() {
+ employeeNames = null;
+ fieldSetFlags()[2] = false;
+ return this;
+ }
+
+ /**
+ * Gets the value of the 'active' field.
+ * @return The value.
+ */
+ public Active getActive() {
+ return active;
+ }
+
+ /**
+ * Sets the value of the 'active' field.
+ * @param value The value of 'active'.
+ * @return This builder.
+ */
+ public AvroHttpRequest.Builder setActive(Active value) {
+ validate(fields()[3], value);
+ this.active = value;
+ fieldSetFlags()[3] = true;
+ return this;
+ }
+
+ /**
+ * Checks whether the 'active' field has been set.
+ * @return True if the 'active' field has been set, false otherwise.
+ */
+ public boolean hasActive() {
+ return fieldSetFlags()[3];
+ }
+
+
+ /**
+ * Clears the value of the 'active' field.
+ * @return This builder.
+ */
+ public AvroHttpRequest.Builder clearActive() {
+ active = null;
+ fieldSetFlags()[3] = false;
+ return this;
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public AvroHttpRequest build() {
+ try {
+ AvroHttpRequest record = new AvroHttpRequest();
+ record.requestTime = fieldSetFlags()[0] ? this.requestTime : (java.lang.Long) defaultValue(fields()[0]);
+ if (clientIdentifierBuilder != null) {
+ record.clientIdentifier = this.clientIdentifierBuilder.build();
+ } else {
+ record.clientIdentifier = fieldSetFlags()[1] ? this.clientIdentifier : (ClientIdentifier) defaultValue(fields()[1]);
+ }
+ record.employeeNames = fieldSetFlags()[2] ? this.employeeNames : (java.util.List) defaultValue(fields()[2]);
+ record.active = fieldSetFlags()[3] ? this.active : (Active) defaultValue(fields()[3]);
+ return record;
+ } catch (java.lang.Exception e) {
+ throw new org.apache.avro.AvroRuntimeException(e);
+ }
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private static final org.apache.avro.io.DatumWriter
+ WRITER$ = (org.apache.avro.io.DatumWriter)MODEL$.createDatumWriter(SCHEMA$);
+
+ @Override public void writeExternal(java.io.ObjectOutput out)
+ throws java.io.IOException {
+ WRITER$.write(this, SpecificData.getEncoder(out));
+ }
+
+ @SuppressWarnings("unchecked")
+ private static final org.apache.avro.io.DatumReader
+ READER$ = (org.apache.avro.io.DatumReader)MODEL$.createDatumReader(SCHEMA$);
+
+ @Override public void readExternal(java.io.ObjectInput in)
+ throws java.io.IOException {
+ READER$.read(this, SpecificData.getDecoder(in));
+ }
+
+}
diff --git a/apache-avro/src/main/java/com/baeldung/avro/util/model/ClientIdentifier.java b/apache-avro/src/main/java/com/baeldung/avro/util/model/ClientIdentifier.java
new file mode 100644
index 0000000000..503dde40df
--- /dev/null
+++ b/apache-avro/src/main/java/com/baeldung/avro/util/model/ClientIdentifier.java
@@ -0,0 +1,308 @@
+/**
+ * Autogenerated by Avro
+ *
+ * DO NOT EDIT DIRECTLY
+ */
+package com.baeldung.avro.util.model;
+
+import org.apache.avro.specific.SpecificData;
+import org.apache.avro.message.BinaryMessageEncoder;
+import org.apache.avro.message.BinaryMessageDecoder;
+import org.apache.avro.message.SchemaStore;
+
+@SuppressWarnings("all")
+@org.apache.avro.specific.AvroGenerated
+public class ClientIdentifier extends org.apache.avro.specific.SpecificRecordBase implements org.apache.avro.specific.SpecificRecord {
+ private static final long serialVersionUID = 8754570983127295424L;
+ public static final org.apache.avro.Schema SCHEMA$ = new org.apache.avro.Schema.Parser().parse("{\"type\":\"record\",\"name\":\"ClientIdentifier\",\"namespace\":\"com.baeldung.avro.model\",\"fields\":[{\"name\":\"hostName\",\"type\":\"string\"},{\"name\":\"ipAddress\",\"type\":\"string\"}]}");
+ public static org.apache.avro.Schema getClassSchema() { return SCHEMA$; }
+
+ private static SpecificData MODEL$ = new SpecificData();
+
+ private static final BinaryMessageEncoder ENCODER =
+ new BinaryMessageEncoder(MODEL$, SCHEMA$);
+
+ private static final BinaryMessageDecoder DECODER =
+ new BinaryMessageDecoder(MODEL$, SCHEMA$);
+
+ /**
+ * Return the BinaryMessageDecoder instance used by this class.
+ */
+ public static BinaryMessageDecoder getDecoder() {
+ return DECODER;
+ }
+
+ /**
+ * Create a new BinaryMessageDecoder instance for this class that uses the specified {@link SchemaStore}.
+ * @param resolver a {@link SchemaStore} used to find schemas by fingerprint
+ */
+ public static BinaryMessageDecoder createDecoder(SchemaStore resolver) {
+ return new BinaryMessageDecoder(MODEL$, SCHEMA$, resolver);
+ }
+
+ /** Serializes this ClientIdentifier to a ByteBuffer. */
+ public java.nio.ByteBuffer toByteBuffer() throws java.io.IOException {
+ return ENCODER.encode(this);
+ }
+
+ /** Deserializes a ClientIdentifier from a ByteBuffer. */
+ public static ClientIdentifier fromByteBuffer(
+ java.nio.ByteBuffer b) throws java.io.IOException {
+ return DECODER.decode(b);
+ }
+
+ @Deprecated public java.lang.CharSequence hostName;
+ @Deprecated public java.lang.CharSequence ipAddress;
+
+ /**
+ * Default constructor. Note that this does not initialize fields
+ * to their default values from the schema. If that is desired then
+ * one should use newBuilder()
.
+ */
+ public ClientIdentifier() {}
+
+ /**
+ * All-args constructor.
+ * @param hostName The new value for hostName
+ * @param ipAddress The new value for ipAddress
+ */
+ public ClientIdentifier(java.lang.CharSequence hostName, java.lang.CharSequence ipAddress) {
+ this.hostName = hostName;
+ this.ipAddress = ipAddress;
+ }
+
+ public org.apache.avro.Schema getSchema() { return SCHEMA$; }
+ // Used by DatumWriter. Applications should not call.
+ public java.lang.Object get(int field$) {
+ switch (field$) {
+ case 0: return hostName;
+ case 1: return ipAddress;
+ default: throw new org.apache.avro.AvroRuntimeException("Bad index");
+ }
+ }
+
+ // Used by DatumReader. Applications should not call.
+ @SuppressWarnings(value="unchecked")
+ public void put(int field$, java.lang.Object value$) {
+ switch (field$) {
+ case 0: hostName = (java.lang.CharSequence)value$; break;
+ case 1: ipAddress = (java.lang.CharSequence)value$; break;
+ default: throw new org.apache.avro.AvroRuntimeException("Bad index");
+ }
+ }
+
+ /**
+ * Gets the value of the 'hostName' field.
+ * @return The value of the 'hostName' field.
+ */
+ public java.lang.CharSequence getHostName() {
+ return hostName;
+ }
+
+ /**
+ * Sets the value of the 'hostName' field.
+ * @param value the value to set.
+ */
+ public void setHostName(java.lang.CharSequence value) {
+ this.hostName = value;
+ }
+
+ /**
+ * Gets the value of the 'ipAddress' field.
+ * @return The value of the 'ipAddress' field.
+ */
+ public java.lang.CharSequence getIpAddress() {
+ return ipAddress;
+ }
+
+ /**
+ * Sets the value of the 'ipAddress' field.
+ * @param value the value to set.
+ */
+ public void setIpAddress(java.lang.CharSequence value) {
+ this.ipAddress = value;
+ }
+
+ /**
+ * Creates a new ClientIdentifier RecordBuilder.
+ * @return A new ClientIdentifier RecordBuilder
+ */
+ public static ClientIdentifier.Builder newBuilder() {
+ return new ClientIdentifier.Builder();
+ }
+
+ /**
+ * Creates a new ClientIdentifier RecordBuilder by copying an existing Builder.
+ * @param other The existing builder to copy.
+ * @return A new ClientIdentifier RecordBuilder
+ */
+ public static ClientIdentifier.Builder newBuilder(ClientIdentifier.Builder other) {
+ return new ClientIdentifier.Builder(other);
+ }
+
+ /**
+ * Creates a new ClientIdentifier RecordBuilder by copying an existing ClientIdentifier instance.
+ * @param other The existing instance to copy.
+ * @return A new ClientIdentifier RecordBuilder
+ */
+ public static ClientIdentifier.Builder newBuilder(ClientIdentifier other) {
+ return new ClientIdentifier.Builder(other);
+ }
+
+ /**
+ * RecordBuilder for ClientIdentifier instances.
+ */
+ public static class Builder extends org.apache.avro.specific.SpecificRecordBuilderBase
+ implements org.apache.avro.data.RecordBuilder {
+
+ private java.lang.CharSequence hostName;
+ private java.lang.CharSequence ipAddress;
+
+ /** Creates a new Builder */
+ private Builder() {
+ super(SCHEMA$);
+ }
+
+ /**
+ * Creates a Builder by copying an existing Builder.
+ * @param other The existing Builder to copy.
+ */
+ private Builder(ClientIdentifier.Builder other) {
+ super(other);
+ if (isValidValue(fields()[0], other.hostName)) {
+ this.hostName = data().deepCopy(fields()[0].schema(), other.hostName);
+ fieldSetFlags()[0] = true;
+ }
+ if (isValidValue(fields()[1], other.ipAddress)) {
+ this.ipAddress = data().deepCopy(fields()[1].schema(), other.ipAddress);
+ fieldSetFlags()[1] = true;
+ }
+ }
+
+ /**
+ * Creates a Builder by copying an existing ClientIdentifier instance
+ * @param other The existing instance to copy.
+ */
+ private Builder(ClientIdentifier other) {
+ super(SCHEMA$);
+ if (isValidValue(fields()[0], other.hostName)) {
+ this.hostName = data().deepCopy(fields()[0].schema(), other.hostName);
+ fieldSetFlags()[0] = true;
+ }
+ if (isValidValue(fields()[1], other.ipAddress)) {
+ this.ipAddress = data().deepCopy(fields()[1].schema(), other.ipAddress);
+ fieldSetFlags()[1] = true;
+ }
+ }
+
+ /**
+ * Gets the value of the 'hostName' field.
+ * @return The value.
+ */
+ public java.lang.CharSequence getHostName() {
+ return hostName;
+ }
+
+ /**
+ * Sets the value of the 'hostName' field.
+ * @param value The value of 'hostName'.
+ * @return This builder.
+ */
+ public ClientIdentifier.Builder setHostName(java.lang.CharSequence value) {
+ validate(fields()[0], value);
+ this.hostName = value;
+ fieldSetFlags()[0] = true;
+ return this;
+ }
+
+ /**
+ * Checks whether the 'hostName' field has been set.
+ * @return True if the 'hostName' field has been set, false otherwise.
+ */
+ public boolean hasHostName() {
+ return fieldSetFlags()[0];
+ }
+
+
+ /**
+ * Clears the value of the 'hostName' field.
+ * @return This builder.
+ */
+ public ClientIdentifier.Builder clearHostName() {
+ hostName = null;
+ fieldSetFlags()[0] = false;
+ return this;
+ }
+
+ /**
+ * Gets the value of the 'ipAddress' field.
+ * @return The value.
+ */
+ public java.lang.CharSequence getIpAddress() {
+ return ipAddress;
+ }
+
+ /**
+ * Sets the value of the 'ipAddress' field.
+ * @param value The value of 'ipAddress'.
+ * @return This builder.
+ */
+ public ClientIdentifier.Builder setIpAddress(java.lang.CharSequence value) {
+ validate(fields()[1], value);
+ this.ipAddress = value;
+ fieldSetFlags()[1] = true;
+ return this;
+ }
+
+ /**
+ * Checks whether the 'ipAddress' field has been set.
+ * @return True if the 'ipAddress' field has been set, false otherwise.
+ */
+ public boolean hasIpAddress() {
+ return fieldSetFlags()[1];
+ }
+
+
+ /**
+ * Clears the value of the 'ipAddress' field.
+ * @return This builder.
+ */
+ public ClientIdentifier.Builder clearIpAddress() {
+ ipAddress = null;
+ fieldSetFlags()[1] = false;
+ return this;
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public ClientIdentifier build() {
+ try {
+ ClientIdentifier record = new ClientIdentifier();
+ record.hostName = fieldSetFlags()[0] ? this.hostName : (java.lang.CharSequence) defaultValue(fields()[0]);
+ record.ipAddress = fieldSetFlags()[1] ? this.ipAddress : (java.lang.CharSequence) defaultValue(fields()[1]);
+ return record;
+ } catch (java.lang.Exception e) {
+ throw new org.apache.avro.AvroRuntimeException(e);
+ }
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private static final org.apache.avro.io.DatumWriter
+ WRITER$ = (org.apache.avro.io.DatumWriter)MODEL$.createDatumWriter(SCHEMA$);
+
+ @Override public void writeExternal(java.io.ObjectOutput out)
+ throws java.io.IOException {
+ WRITER$.write(this, SpecificData.getEncoder(out));
+ }
+
+ @SuppressWarnings("unchecked")
+ private static final org.apache.avro.io.DatumReader
+ READER$ = (org.apache.avro.io.DatumReader)MODEL$.createDatumReader(SCHEMA$);
+
+ @Override public void readExternal(java.io.ObjectInput in)
+ throws java.io.IOException {
+ READER$.read(this, SpecificData.getDecoder(in));
+ }
+
+}
diff --git a/apache-avro/src/main/java/com/baeldung/avro/util/serealization/AvroDeSerealizer.java b/apache-avro/src/main/java/com/baeldung/avro/util/serealization/AvroDeSerealizer.java
new file mode 100644
index 0000000000..7d30c3d1ee
--- /dev/null
+++ b/apache-avro/src/main/java/com/baeldung/avro/util/serealization/AvroDeSerealizer.java
@@ -0,0 +1,41 @@
+package com.baeldung.avro.util.serealization;
+
+import com.baeldung.avro.util.model.AvroHttpRequest;
+import org.apache.avro.io.DatumReader;
+import org.apache.avro.io.Decoder;
+import org.apache.avro.io.DecoderFactory;
+import org.apache.avro.specific.SpecificDatumReader;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+
+public class AvroDeSerealizer {
+
+ private static Logger logger = LoggerFactory.getLogger(AvroDeSerealizer.class);
+
+ public AvroHttpRequest deSerealizeAvroHttpRequestJSON(byte[] data) {
+ DatumReader reader = new SpecificDatumReader<>(AvroHttpRequest.class);
+ Decoder decoder = null;
+ try {
+ decoder = DecoderFactory.get()
+ .jsonDecoder(AvroHttpRequest.getClassSchema(), new String(data));
+ return reader.read(null, decoder);
+ } catch (IOException e) {
+ logger.error("Deserialization error" + e.getMessage());
+ }
+ return null;
+ }
+
+ public AvroHttpRequest deSerealizeAvroHttpRequestBinary(byte[] data) {
+ DatumReader employeeReader = new SpecificDatumReader<>(AvroHttpRequest.class);
+ Decoder decoder = DecoderFactory.get()
+ .binaryDecoder(data, null);
+ try {
+ return employeeReader.read(null, decoder);
+ } catch (IOException e) {
+ logger.error("Deserialization error" + e.getMessage());
+ }
+ return null;
+ }
+}
diff --git a/apache-avro/src/main/java/com/baeldung/avro/util/serealization/AvroSerealizer.java b/apache-avro/src/main/java/com/baeldung/avro/util/serealization/AvroSerealizer.java
new file mode 100644
index 0000000000..767b688dea
--- /dev/null
+++ b/apache-avro/src/main/java/com/baeldung/avro/util/serealization/AvroSerealizer.java
@@ -0,0 +1,50 @@
+package com.baeldung.avro.util.serealization;
+
+import com.baeldung.avro.util.model.AvroHttpRequest;
+import org.apache.avro.io.*;
+import org.apache.avro.specific.SpecificDatumWriter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+public class AvroSerealizer {
+
+ private static final Logger logger = LoggerFactory.getLogger(AvroSerealizer.class);
+
+ public byte[] serealizeAvroHttpRequestJSON(AvroHttpRequest request) {
+ DatumWriter writer = new SpecificDatumWriter<>(AvroHttpRequest.class);
+ byte[] data = new byte[0];
+ ByteArrayOutputStream stream = new ByteArrayOutputStream();
+ Encoder jsonEncoder = null;
+ try {
+ jsonEncoder = EncoderFactory.get()
+ .jsonEncoder(AvroHttpRequest.getClassSchema(), stream);
+ writer.write(request, jsonEncoder);
+ jsonEncoder.flush();
+ data = stream.toByteArray();
+ } catch (IOException e) {
+ logger.error("Serialization error " + e.getMessage());
+ }
+ return data;
+ }
+
+ public byte[] serealizeAvroHttpRequestBinary(AvroHttpRequest request) {
+ DatumWriter writer = new SpecificDatumWriter<>(AvroHttpRequest.class);
+ byte[] data = new byte[0];
+ ByteArrayOutputStream stream = new ByteArrayOutputStream();
+ Encoder jsonEncoder = EncoderFactory.get()
+ .binaryEncoder(stream, null);
+ try {
+ writer.write(request, jsonEncoder);
+ jsonEncoder.flush();
+ data = stream.toByteArray();
+ } catch (IOException e) {
+ logger.error("Serialization error " + e.getMessage());
+ }
+
+ return data;
+ }
+
+}
diff --git a/apache-avro/src/main/resources/avroHttpRequest-schema.avsc b/apache-avro/src/main/resources/avroHttpRequest-schema.avsc
new file mode 100644
index 0000000000..18179a9cde
--- /dev/null
+++ b/apache-avro/src/main/resources/avroHttpRequest-schema.avsc
@@ -0,0 +1,47 @@
+{
+ "type":"record",
+ "name":"AvroHttpRequest",
+ "namespace":"com.baeldung.avro.model",
+ "fields":[
+ {
+ "name":"requestTime",
+ "type":"long"
+ },
+ {
+ "name":"clientIdentifier",
+ "type":{
+ "type":"record",
+ "name":"ClientIdentifier",
+ "fields":[
+ {
+ "name":"hostName",
+ "type":"string"
+ },
+ {
+ "name":"ipAddress",
+ "type":"string"
+ }
+ ]
+ }
+ },
+ {
+ "name":"employeeNames",
+ "type":{
+ "type":"array",
+ "items":"string"
+ },
+ "default":null
+ },
+ {
+ "name":"active",
+ "type":{
+ "type":"enum",
+ "name":"Active",
+ "symbols":[
+ "YES",
+ "NO"
+ ]
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/apache-avro/src/main/resources/logback.xml b/apache-avro/src/main/resources/logback.xml
new file mode 100644
index 0000000000..7d900d8ea8
--- /dev/null
+++ b/apache-avro/src/main/resources/logback.xml
@@ -0,0 +1,13 @@
+
+
+
+
+ %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/apache-avro/src/test/java/com/baeldung/avro/util/serealization/AvroSerealizerDeSerealizerUnitTest.java b/apache-avro/src/test/java/com/baeldung/avro/util/serealization/AvroSerealizerDeSerealizerUnitTest.java
new file mode 100644
index 0000000000..992ea806c3
--- /dev/null
+++ b/apache-avro/src/test/java/com/baeldung/avro/util/serealization/AvroSerealizerDeSerealizerUnitTest.java
@@ -0,0 +1,83 @@
+package com.baeldung.avro.util.serealization;
+
+import com.baeldung.avro.util.model.Active;
+import com.baeldung.avro.util.model.AvroHttpRequest;
+import com.baeldung.avro.util.model.ClientIdentifier;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+import static org.junit.Assert.*;
+
+public class AvroSerealizerDeSerealizerUnitTest {
+
+ AvroSerealizer serealizer;
+ AvroDeSerealizer deSerealizer;
+ AvroHttpRequest request;
+
+ @Before
+ public void setUp() throws Exception {
+ serealizer = new AvroSerealizer();
+ deSerealizer = new AvroDeSerealizer();
+
+ ClientIdentifier clientIdentifier = ClientIdentifier.newBuilder()
+ .setHostName("localhost")
+ .setIpAddress("255.255.255.0")
+ .build();
+
+ List employees = new ArrayList();
+ employees.add("James");
+ employees.add("Alice");
+ employees.add("David");
+ employees.add("Han");
+
+ request = AvroHttpRequest.newBuilder()
+ .setRequestTime(01l)
+ .setActive(Active.YES)
+ .setClientIdentifier(clientIdentifier)
+ .setEmployeeNames(employees)
+ .build();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+ @Test
+ public void WhenSerializedUsingJSONEncoder_thenObjectGetsSerialized() {
+ byte[] data = serealizer.serealizeAvroHttpRequestJSON(request);
+ assertTrue(Objects.nonNull(data));
+ assertTrue(data.length > 0);
+ }
+
+ @Test
+ public void WhenSerializedUsingBinaryEncoder_thenObjectGetsSerialized() {
+ byte[] data = serealizer.serealizeAvroHttpRequestBinary(request);
+ assertTrue(Objects.nonNull(data));
+ assertTrue(data.length > 0);
+ }
+
+ @Test
+ public void WhenDeserializeUsingJSONDecoder_thenActualAndExpectedObjectsAreEqual() {
+ byte[] data = serealizer.serealizeAvroHttpRequestJSON(request);
+ AvroHttpRequest actualRequest = deSerealizer.deSerealizeAvroHttpRequestJSON(data);
+ assertEquals(actualRequest, request);
+ assertTrue(actualRequest.getRequestTime()
+ .equals(request.getRequestTime()));
+ }
+
+ @Test
+ public void WhenDeserializeUsingBinaryecoder_thenActualAndExpectedObjectsAreEqual() {
+ byte[] data = serealizer.serealizeAvroHttpRequestBinary(request);
+ AvroHttpRequest actualRequest = deSerealizer.deSerealizeAvroHttpRequestBinary(data);
+ assertEquals(actualRequest, request);
+ assertTrue(actualRequest.getRequestTime()
+ .equals(request.getRequestTime()));
+ }
+
+}
+
diff --git a/apache-bval/pom.xml b/apache-bval/pom.xml
index 1cc0a33702..5ddb1ecb59 100644
--- a/apache-bval/pom.xml
+++ b/apache-bval/pom.xml
@@ -1,34 +1,37 @@
- 4.0.0
- apache-bval
- apache-bval
- 0.0.1-SNAPSHOT
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ 4.0.0
+ apache-bval
+ apache-bval
+ 0.0.1-SNAPSHOT
-
- com.baeldung
- parent-modules
- 1.0.0-SNAPSHOT
-
-
-
- org.apache.bval
- bval-jsr
- ${bval.version}
-
-
- javax.validation
- validation-api
- 1.1.0.Final
-
-
- org.apache.bval
- bval-extras
- ${bval.version}
-
-
+
+ com.baeldung
+ parent-modules
+ 1.0.0-SNAPSHOT
+
+
+
+
+ org.apache.bval
+ bval-jsr
+ ${bval.version}
+
+
+ javax.validation
+ validation-api
+ ${javax.validation.validation-api.version}
+
+
+ org.apache.bval
+ bval-extras
+ ${bval.version}
+
+
+
+
+ 1.1.2
+ 1.1.0.Final
+
-
- 1.1.2
-
\ No newline at end of file
diff --git a/apache-bval/src/main/resources/logback.xml b/apache-bval/src/main/resources/logback.xml
new file mode 100644
index 0000000000..7d900d8ea8
--- /dev/null
+++ b/apache-bval/src/main/resources/logback.xml
@@ -0,0 +1,13 @@
+
+
+
+
+ %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/apache-cayenne/pom.xml b/apache-cayenne/pom.xml
index 52631e8594..591809d47f 100644
--- a/apache-cayenne/pom.xml
+++ b/apache-cayenne/pom.xml
@@ -1,59 +1,48 @@
- 4.0.0
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ 4.0.0
- apache-cayenne
- 0.0.1-SNAPSHOT
- jar
+ apache-cayenne
+ 0.0.1-SNAPSHOT
+ jar
+ apache-cayenne
+ Introduction to Apache Cayenne
- apache-cayenne
- Introduction to Apache Cayenne
-
-
- com.baeldung
- parent-modules
- 1.0.0-SNAPSHOT
-
-
-
- UTF-8
- UTF-8
- 1.8
- 5.1.44
- 4.0.M5
- 4.12
-
-
-
-
- org.apache.cayenne
- cayenne-server
- ${cayenne.version}
-
-
- mysql
- mysql-connector-java
- ${mysql.connector.version}
- runtime
-
+
+ com.baeldung
+ parent-modules
+ 1.0.0-SNAPSHOT
+
+
- junit
- junit
- ${junit.version}
- test
+ org.apache.cayenne
+ cayenne-server
+ ${cayenne.version}
+
+ mysql
+ mysql-connector-java
+ ${mysql.connector.version}
+ runtime
+
+
-
-
+
+
org.apache.cayenne.plugins
cayenne-modeler-maven-plugin
${cayenne.version}
-
-
+
+
+
+
+ 5.1.44
+ 4.0.M5
+
diff --git a/apache-cayenne/src/main/resources/logback.xml b/apache-cayenne/src/main/resources/logback.xml
new file mode 100644
index 0000000000..7d900d8ea8
--- /dev/null
+++ b/apache-cayenne/src/main/resources/logback.xml
@@ -0,0 +1,13 @@
+
+
+
+
+ %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/apache-cayenne/src/test/java/com/baeldung/apachecayenne/CayenneAdvancedOperationLiveTest.java b/apache-cayenne/src/test/java/com/baeldung/apachecayenne/CayenneAdvancedOperationLiveTest.java
new file mode 100644
index 0000000000..b54b62ca02
--- /dev/null
+++ b/apache-cayenne/src/test/java/com/baeldung/apachecayenne/CayenneAdvancedOperationLiveTest.java
@@ -0,0 +1,256 @@
+package com.baeldung.apachecayenne;
+
+import com.baeldung.apachecayenne.persistent.Author;
+import org.apache.cayenne.ObjectContext;
+import org.apache.cayenne.QueryResponse;
+import org.apache.cayenne.configuration.server.ServerRuntime;
+import org.apache.cayenne.exp.Expression;
+import org.apache.cayenne.exp.ExpressionFactory;
+import org.apache.cayenne.query.*;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import static junit.framework.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+public class CayenneAdvancedOperationLiveTest {
+ private static ObjectContext context = null;
+
+ @BeforeClass
+ public static void setupTheCayenneContext() {
+ ServerRuntime cayenneRuntime = ServerRuntime.builder()
+ .addConfig("cayenne-project.xml")
+ .build();
+ context = cayenneRuntime.newContext();
+ }
+
+ @Before
+ public void saveThreeAuthors() {
+ Author authorOne = context.newObject(Author.class);
+ authorOne.setName("Paul Xavier");
+ Author authorTwo = context.newObject(Author.class);
+ authorTwo.setName("pAuL Smith");
+ Author authorThree = context.newObject(Author.class);
+ authorThree.setName("Vicky Sarra");
+ context.commitChanges();
+ }
+
+ @After
+ public void deleteAllAuthors() {
+ SQLTemplate deleteAuthors = new SQLTemplate(Author.class, "delete from author");
+ context.performGenericQuery(deleteAuthors);
+ }
+
+ @Test
+ public void givenAuthors_whenFindAllSQLTmplt_thenWeGetThreeAuthors() {
+ SQLTemplate select = new SQLTemplate(Author.class, "select * from Author");
+ List authors = context.performQuery(select);
+
+ assertEquals(authors.size(), 3);
+ }
+
+ @Test
+ public void givenAuthors_whenFindByNameSQLTmplt_thenWeGetOneAuthor() {
+ SQLTemplate select = new SQLTemplate(Author.class, "select * from Author where name = 'Vicky Sarra'");
+ List authors = context.performQuery(select);
+ Author author = authors.get(0);
+
+ assertEquals(authors.size(), 1);
+ assertEquals(author.getName(), "Vicky Sarra");
+ }
+
+ @Test
+ public void givenAuthors_whenLikeSltQry_thenWeGetOneAuthor() {
+ Expression qualifier = ExpressionFactory.likeExp(Author.NAME.getName(), "Paul%");
+ SelectQuery query = new SelectQuery(Author.class, qualifier);
+ List authorsTwo = context.performQuery(query);
+
+ assertEquals(authorsTwo.size(), 1);
+ }
+
+ @Test
+ public void givenAuthors_whenCtnsIgnorCaseSltQry_thenWeGetTwoAuthors() {
+ Expression qualifier = ExpressionFactory.containsIgnoreCaseExp(Author.NAME.getName(), "Paul");
+ SelectQuery query = new SelectQuery(Author.class, qualifier);
+ List authors = context.performQuery(query);
+
+ assertEquals(authors.size(), 2);
+ }
+
+ @Test
+ public void givenAuthors_whenCtnsIgnorCaseEndsWSltQry_thenWeGetTwoAuthors() {
+ Expression qualifier = ExpressionFactory.containsIgnoreCaseExp(Author.NAME.getName(), "Paul")
+ .andExp(ExpressionFactory.endsWithExp(Author.NAME.getName(), "h"));
+ SelectQuery query = new SelectQuery(Author.class, qualifier);
+ List authors = context.performQuery(query);
+
+ Author author = authors.get(0);
+
+ assertEquals(authors.size(), 1);
+ assertEquals(author.getName(), "pAuL Smith");
+ }
+
+ @Test
+ public void givenAuthors_whenAscOrderingSltQry_thenWeGetOrderedAuthors() {
+ SelectQuery query = new SelectQuery(Author.class);
+ query.addOrdering(Author.NAME.asc());
+
+ List authors = query.select(context);
+ Author firstAuthor = authors.get(0);
+
+ assertEquals(authors.size(), 3);
+ assertEquals(firstAuthor.getName(), "Paul Xavier");
+ }
+
+ @Test
+ public void givenAuthors_whenDescOrderingSltQry_thenWeGetOrderedAuthors() {
+ SelectQuery query = new SelectQuery(Author.class);
+ query.addOrdering(Author.NAME.desc());
+
+ List authors = query.select(context);
+ Author firstAuthor = authors.get(0);
+
+ assertEquals(authors.size(), 3);
+ assertEquals(firstAuthor.getName(), "pAuL Smith");
+ }
+
+ @Test
+ public void givenAuthors_onContainsObjS_thenWeGetOneRecord() {
+ List authors = ObjectSelect.query(Author.class)
+ .where(Author.NAME.contains("Paul"))
+ .select(context);
+
+ assertEquals(authors.size(), 1);
+ }
+
+ @Test
+ public void givenAuthors_whenLikeObjS_thenWeGetTwoAuthors() {
+ List authors = ObjectSelect.query(Author.class)
+ .where(Author.NAME.likeIgnoreCase("Paul%"))
+ .select(context);
+
+ assertEquals(authors.size(), 2);
+ }
+
+ @Test
+ public void givenTwoAuthor_whenEndsWithObjS_thenWeGetOrderedAuthors() {
+ List authors = ObjectSelect.query(Author.class)
+ .where(Author.NAME.endsWith("Sarra"))
+ .select(context);
+ Author firstAuthor = authors.get(0);
+
+ assertEquals(authors.size(), 1);
+ assertEquals(firstAuthor.getName(), "Vicky Sarra");
+ }
+
+ @Test
+ public void givenTwoAuthor_whenInObjS_thenWeGetAuthors() {
+ List names = Arrays.asList("Paul Xavier", "pAuL Smith", "Vicky Sarra");
+ List authors = ObjectSelect.query(Author.class)
+ .where(Author.NAME.in(names))
+ .select(context);
+
+ assertEquals(authors.size(), 3);
+ }
+
+ @Test
+ public void givenTwoAuthor_whenNinObjS_thenWeGetAuthors() {
+ List names = Arrays.asList("Paul Xavier", "pAuL Smith");
+ List authors = ObjectSelect.query(Author.class)
+ .where(Author.NAME.nin(names))
+ .select(context);
+ Author author = authors.get(0);
+
+ assertEquals(authors.size(), 1);
+ assertEquals(author.getName(), "Vicky Sarra");
+ }
+
+ @Test
+ public void givenTwoAuthor_whenIsNotNullObjS_thenWeGetAuthors() {
+ List authors = ObjectSelect.query(Author.class)
+ .where(Author.NAME.isNotNull())
+ .select(context);
+
+ assertEquals(authors.size(), 3);
+ }
+
+ @Test
+ public void givenAuthors_whenFindAllEJBQL_thenWeGetThreeAuthors() {
+ EJBQLQuery query = new EJBQLQuery("select a FROM Author a");
+ List authors = context.performQuery(query);
+
+ assertEquals(authors.size(), 3);
+ }
+
+ @Test
+ public void givenAuthors_whenFindByNameEJBQL_thenWeGetOneAuthor() {
+ EJBQLQuery query = new EJBQLQuery("select a FROM Author a WHERE a.name = 'Vicky Sarra'");
+ List authors = context.performQuery(query);
+ Author author = authors.get(0);
+
+ assertEquals(authors.size(), 1);
+ assertEquals(author.getName(), "Vicky Sarra");
+ }
+
+ @Test
+ public void givenAuthors_whenUpdadingByNameEJBQL_thenWeGetTheUpdatedAuthor() {
+ EJBQLQuery query = new EJBQLQuery("UPDATE Author AS a SET a.name = 'Vicky Edison' WHERE a.name = 'Vicky Sarra'");
+ QueryResponse queryResponse = context.performGenericQuery(query);
+
+ EJBQLQuery queryUpdatedAuthor = new EJBQLQuery("select a FROM Author a WHERE a.name = 'Vicky Edison'");
+ List authors = context.performQuery(queryUpdatedAuthor);
+ Author author = authors.get(0);
+
+ assertNotNull(author);
+ }
+
+ @Test
+ public void givenAuthors_whenSeletingNamesEJBQL_thenWeGetListWithSizeThree() {
+ String [] args = {"Paul Xavier", "pAuL Smith", "Vicky Sarra"};
+ List names = Arrays.asList(args);
+ EJBQLQuery query = new EJBQLQuery("select a.name FROM Author a");
+ List nameList = context.performQuery(query);
+
+ Collections.sort(names);
+ Collections.sort(nameList);
+
+ assertEquals(names.size(), 3);
+ assertEquals(nameList.size(), 3);
+ assertEquals(names, nameList);
+ }
+
+ @Test
+ public void givenAuthors_whenDeletingAllWithEJB_thenWeGetNoAuthor() {
+ EJBQLQuery deleteQuery = new EJBQLQuery("delete FROM Author");
+ EJBQLQuery findAllQuery = new EJBQLQuery("select a FROM Author a");
+
+ context.performQuery(deleteQuery);
+ List objects = context.performQuery(findAllQuery);
+
+ assertEquals(objects.size(), 0);
+ }
+
+ @Test
+ public void givenAuthors_whenInsertingSQLExec_thenWeGetNewAuthor() {
+ int inserted = SQLExec
+ .query("INSERT INTO Author (name) VALUES ('Baeldung')")
+ .update(context);
+
+ assertEquals(inserted, 1);
+ }
+
+ @Test
+ public void givenAuthors_whenUpdatingSQLExec_thenItsUpdated() {
+ int updated = SQLExec
+ .query("UPDATE Author SET name = 'Baeldung' WHERE name = 'Vicky Sarra'")
+ .update(context);
+
+ assertEquals(updated, 1);
+ }
+}
diff --git a/apache-cayenne/src/test/java/com/baeldung/apachecayenne/CayenneAdvancedOperationTests.java b/apache-cayenne/src/test/java/com/baeldung/apachecayenne/CayenneAdvancedOperationTests.java
deleted file mode 100644
index cd563b6270..0000000000
--- a/apache-cayenne/src/test/java/com/baeldung/apachecayenne/CayenneAdvancedOperationTests.java
+++ /dev/null
@@ -1,256 +0,0 @@
-package com.baeldung.apachecayenne;
-
-import com.baeldung.apachecayenne.persistent.Author;
-import org.apache.cayenne.ObjectContext;
-import org.apache.cayenne.QueryResponse;
-import org.apache.cayenne.configuration.server.ServerRuntime;
-import org.apache.cayenne.exp.Expression;
-import org.apache.cayenne.exp.ExpressionFactory;
-import org.apache.cayenne.query.*;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-import static junit.framework.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-
-public class CayenneAdvancedOperationTests {
- private static ObjectContext context = null;
-
- @BeforeClass
- public static void setupTheCayenneContext() {
- ServerRuntime cayenneRuntime = ServerRuntime.builder()
- .addConfig("cayenne-project.xml")
- .build();
- context = cayenneRuntime.newContext();
- }
-
- @Before
- public void saveThreeAuthors() {
- Author authorOne = context.newObject(Author.class);
- authorOne.setName("Paul Xavier");
- Author authorTwo = context.newObject(Author.class);
- authorTwo.setName("pAuL Smith");
- Author authorThree = context.newObject(Author.class);
- authorThree.setName("Vicky Sarra");
- context.commitChanges();
- }
-
- @After
- public void deleteAllAuthors() {
- SQLTemplate deleteAuthors = new SQLTemplate(Author.class, "delete from author");
- context.performGenericQuery(deleteAuthors);
- }
-
- @Test
- public void givenAuthors_whenFindAllSQLTmplt_thenWeGetThreeAuthors() {
- SQLTemplate select = new SQLTemplate(Author.class, "select * from Author");
- List authors = context.performQuery(select);
-
- assertEquals(authors.size(), 3);
- }
-
- @Test
- public void givenAuthors_whenFindByNameSQLTmplt_thenWeGetOneAuthor() {
- SQLTemplate select = new SQLTemplate(Author.class, "select * from Author where name = 'Vicky Sarra'");
- List authors = context.performQuery(select);
- Author author = authors.get(0);
-
- assertEquals(authors.size(), 1);
- assertEquals(author.getName(), "Vicky Sarra");
- }
-
- @Test
- public void givenAuthors_whenLikeSltQry_thenWeGetOneAuthor() {
- Expression qualifier = ExpressionFactory.likeExp(Author.NAME.getName(), "Paul%");
- SelectQuery query = new SelectQuery(Author.class, qualifier);
- List authorsTwo = context.performQuery(query);
-
- assertEquals(authorsTwo.size(), 1);
- }
-
- @Test
- public void givenAuthors_whenCtnsIgnorCaseSltQry_thenWeGetTwoAuthors() {
- Expression qualifier = ExpressionFactory.containsIgnoreCaseExp(Author.NAME.getName(), "Paul");
- SelectQuery query = new SelectQuery(Author.class, qualifier);
- List authors = context.performQuery(query);
-
- assertEquals(authors.size(), 2);
- }
-
- @Test
- public void givenAuthors_whenCtnsIgnorCaseEndsWSltQry_thenWeGetTwoAuthors() {
- Expression qualifier = ExpressionFactory.containsIgnoreCaseExp(Author.NAME.getName(), "Paul")
- .andExp(ExpressionFactory.endsWithExp(Author.NAME.getName(), "h"));
- SelectQuery query = new SelectQuery(Author.class, qualifier);
- List authors = context.performQuery(query);
-
- Author author = authors.get(0);
-
- assertEquals(authors.size(), 1);
- assertEquals(author.getName(), "pAuL Smith");
- }
-
- @Test
- public void givenAuthors_whenAscOrderingSltQry_thenWeGetOrderedAuthors() {
- SelectQuery query = new SelectQuery(Author.class);
- query.addOrdering(Author.NAME.asc());
-
- List authors = query.select(context);
- Author firstAuthor = authors.get(0);
-
- assertEquals(authors.size(), 3);
- assertEquals(firstAuthor.getName(), "Paul Xavier");
- }
-
- @Test
- public void givenAuthors_whenDescOrderingSltQry_thenWeGetOrderedAuthors() {
- SelectQuery query = new SelectQuery(Author.class);
- query.addOrdering(Author.NAME.desc());
-
- List authors = query.select(context);
- Author firstAuthor = authors.get(0);
-
- assertEquals(authors.size(), 3);
- assertEquals(firstAuthor.getName(), "pAuL Smith");
- }
-
- @Test
- public void givenAuthors_onContainsObjS_thenWeGetOneRecord() {
- List authors = ObjectSelect.query(Author.class)
- .where(Author.NAME.contains("Paul"))
- .select(context);
-
- assertEquals(authors.size(), 1);
- }
-
- @Test
- public void givenAuthors_whenLikeObjS_thenWeGetTwoAuthors() {
- List authors = ObjectSelect.query(Author.class)
- .where(Author.NAME.likeIgnoreCase("Paul%"))
- .select(context);
-
- assertEquals(authors.size(), 2);
- }
-
- @Test
- public void givenTwoAuthor_whenEndsWithObjS_thenWeGetOrderedAuthors() {
- List authors = ObjectSelect.query(Author.class)
- .where(Author.NAME.endsWith("Sarra"))
- .select(context);
- Author firstAuthor = authors.get(0);
-
- assertEquals(authors.size(), 1);
- assertEquals(firstAuthor.getName(), "Vicky Sarra");
- }
-
- @Test
- public void givenTwoAuthor_whenInObjS_thenWeGetAuthors() {
- List names = Arrays.asList("Paul Xavier", "pAuL Smith", "Vicky Sarra");
- List authors = ObjectSelect.query(Author.class)
- .where(Author.NAME.in(names))
- .select(context);
-
- assertEquals(authors.size(), 3);
- }
-
- @Test
- public void givenTwoAuthor_whenNinObjS_thenWeGetAuthors() {
- List names = Arrays.asList("Paul Xavier", "pAuL Smith");
- List authors = ObjectSelect.query(Author.class)
- .where(Author.NAME.nin(names))
- .select(context);
- Author author = authors.get(0);
-
- assertEquals(authors.size(), 1);
- assertEquals(author.getName(), "Vicky Sarra");
- }
-
- @Test
- public void givenTwoAuthor_whenIsNotNullObjS_thenWeGetAuthors() {
- List authors = ObjectSelect.query(Author.class)
- .where(Author.NAME.isNotNull())
- .select(context);
-
- assertEquals(authors.size(), 3);
- }
-
- @Test
- public void givenAuthors_whenFindAllEJBQL_thenWeGetThreeAuthors() {
- EJBQLQuery query = new EJBQLQuery("select a FROM Author a");
- List authors = context.performQuery(query);
-
- assertEquals(authors.size(), 3);
- }
-
- @Test
- public void givenAuthors_whenFindByNameEJBQL_thenWeGetOneAuthor() {
- EJBQLQuery query = new EJBQLQuery("select a FROM Author a WHERE a.name = 'Vicky Sarra'");
- List authors = context.performQuery(query);
- Author author = authors.get(0);
-
- assertEquals(authors.size(), 1);
- assertEquals(author.getName(), "Vicky Sarra");
- }
-
- @Test
- public void givenAuthors_whenUpdadingByNameEJBQL_thenWeGetTheUpdatedAuthor() {
- EJBQLQuery query = new EJBQLQuery("UPDATE Author AS a SET a.name = 'Vicky Edison' WHERE a.name = 'Vicky Sarra'");
- QueryResponse queryResponse = context.performGenericQuery(query);
-
- EJBQLQuery queryUpdatedAuthor = new EJBQLQuery("select a FROM Author a WHERE a.name = 'Vicky Edison'");
- List authors = context.performQuery(queryUpdatedAuthor);
- Author author = authors.get(0);
-
- assertNotNull(author);
- }
-
- @Test
- public void givenAuthors_whenSeletingNamesEJBQL_thenWeGetListWithSizeThree() {
- String [] args = {"Paul Xavier", "pAuL Smith", "Vicky Sarra"};
- List names = Arrays.asList(args);
- EJBQLQuery query = new EJBQLQuery("select a.name FROM Author a");
- List nameList = context.performQuery(query);
-
- Collections.sort(names);
- Collections.sort(nameList);
-
- assertEquals(names.size(), 3);
- assertEquals(nameList.size(), 3);
- assertEquals(names, nameList);
- }
-
- @Test
- public void givenAuthors_whenDeletingAllWithEJB_thenWeGetNoAuthor() {
- EJBQLQuery deleteQuery = new EJBQLQuery("delete FROM Author");
- EJBQLQuery findAllQuery = new EJBQLQuery("select a FROM Author a");
-
- context.performQuery(deleteQuery);
- List objects = context.performQuery(findAllQuery);
-
- assertEquals(objects.size(), 0);
- }
-
- @Test
- public void givenAuthors_whenInsertingSQLExec_thenWeGetNewAuthor() {
- int inserted = SQLExec
- .query("INSERT INTO Author (name) VALUES ('Baeldung')")
- .update(context);
-
- assertEquals(inserted, 1);
- }
-
- @Test
- public void givenAuthors_whenUpdatingSQLExec_thenItsUpdated() {
- int updated = SQLExec
- .query("UPDATE Author SET name = 'Baeldung' WHERE name = 'Vicky Sarra'")
- .update(context);
-
- assertEquals(updated, 1);
- }
-}
diff --git a/apache-cayenne/src/test/java/com/baeldung/apachecayenne/CayenneOperationLiveTest.java b/apache-cayenne/src/test/java/com/baeldung/apachecayenne/CayenneOperationLiveTest.java
new file mode 100644
index 0000000000..e6ca4a3634
--- /dev/null
+++ b/apache-cayenne/src/test/java/com/baeldung/apachecayenne/CayenneOperationLiveTest.java
@@ -0,0 +1,131 @@
+package com.baeldung.apachecayenne;
+
+import com.baeldung.apachecayenne.persistent.Article;
+import com.baeldung.apachecayenne.persistent.Author;
+import org.apache.cayenne.ObjectContext;
+import org.apache.cayenne.configuration.server.ServerRuntime;
+import org.apache.cayenne.query.ObjectSelect;
+import org.apache.cayenne.query.SQLTemplate;
+import org.junit.After;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import java.util.List;
+
+import static junit.framework.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+
+public class CayenneOperationLiveTest {
+ private static ObjectContext context = null;
+
+ @BeforeClass
+ public static void setupTheCayenneContext() {
+ ServerRuntime cayenneRuntime = ServerRuntime.builder()
+ .addConfig("cayenne-project.xml")
+ .build();
+ context = cayenneRuntime.newContext();
+ }
+
+ @After
+ public void deleteAllRecords() {
+ SQLTemplate deleteArticles = new SQLTemplate(Article.class, "delete from article");
+ SQLTemplate deleteAuthors = new SQLTemplate(Author.class, "delete from author");
+
+ context.performGenericQuery(deleteArticles);
+ context.performGenericQuery(deleteAuthors);
+ }
+
+ @Test
+ public void givenAuthor_whenInsert_thenWeGetOneRecordInTheDatabase() {
+ Author author = context.newObject(Author.class);
+ author.setName("Paul");
+
+ context.commitChanges();
+
+ long records = ObjectSelect.dataRowQuery(Author.class).selectCount(context);
+ assertEquals(1, records);
+ }
+
+ @Test
+ public void givenAuthor_whenInsert_andQueryByFirstName_thenWeGetTheAuthor() {
+ Author author = context.newObject(Author.class);
+ author.setName("Paul");
+
+ context.commitChanges();
+
+ Author expectedAuthor = ObjectSelect.query(Author.class)
+ .where(Author.NAME.eq("Paul"))
+ .selectOne(context);
+
+ assertEquals("Paul", expectedAuthor.getName());
+ }
+
+ @Test
+ public void givenTwoAuthor_whenInsert_andQueryAll_thenWeGetTwoAuthors() {
+ Author firstAuthor = context.newObject(Author.class);
+ firstAuthor.setName("Paul");
+
+ Author secondAuthor = context.newObject(Author.class);
+ secondAuthor.setName("Ludovic");
+
+ context.commitChanges();
+
+ List authors = ObjectSelect.query(Author.class).select(context);
+ assertEquals(2, authors.size());
+ }
+
+ @Test
+ public void givenAuthor_whenUpdating_thenWeGetAnUpatedeAuthor() {
+ Author author = context.newObject(Author.class);
+ author.setName("Paul");
+ context.commitChanges();
+
+ Author expectedAuthor = ObjectSelect.query(Author.class)
+ .where(Author.NAME.eq("Paul"))
+ .selectOne(context);
+ expectedAuthor.setName("Garcia");
+ context.commitChanges();
+
+ assertEquals(author.getName(), expectedAuthor.getName());
+ }
+
+ @Test
+ public void givenAuthor_whenDeleting_thenWeLostHisDetails() {
+ Author author = context.newObject(Author.class);
+ author.setName("Paul");
+ context.commitChanges();
+
+ Author savedAuthor = ObjectSelect.query(Author.class)
+ .where(Author.NAME.eq("Paul")).selectOne(context);
+ if(savedAuthor != null) {
+ context.deleteObjects(author);
+ context.commitChanges();
+ }
+
+ Author expectedAuthor = ObjectSelect.query(Author.class)
+ .where(Author.NAME.eq("Paul")).selectOne(context);
+ assertNull(expectedAuthor);
+ }
+
+ @Test
+ public void givenAuthor_whenAttachingToArticle_thenTheRelationIsMade() {
+ Author author = context.newObject(Author.class);
+ author.setName("Paul");
+
+ Article article = context.newObject(Article.class);
+ article.setTitle("My post title");
+ article.setContent("The content");
+ article.setAuthor(author);
+
+ context.commitChanges();
+
+ Author expectedAuthor = ObjectSelect.query(Author.class)
+ .where(Author.NAME.eq("Paul"))
+ .selectOne(context);
+
+ Article expectedArticle = (expectedAuthor.getArticles()).get(0);
+ assertEquals(article.getTitle(), expectedArticle.getTitle());
+ }
+
+}
diff --git a/apache-cayenne/src/test/java/com/baeldung/apachecayenne/CayenneOperationTests.java b/apache-cayenne/src/test/java/com/baeldung/apachecayenne/CayenneOperationTests.java
deleted file mode 100644
index 8a0d210d8d..0000000000
--- a/apache-cayenne/src/test/java/com/baeldung/apachecayenne/CayenneOperationTests.java
+++ /dev/null
@@ -1,131 +0,0 @@
-package com.baeldung.apachecayenne;
-
-import com.baeldung.apachecayenne.persistent.Article;
-import com.baeldung.apachecayenne.persistent.Author;
-import org.apache.cayenne.ObjectContext;
-import org.apache.cayenne.configuration.server.ServerRuntime;
-import org.apache.cayenne.query.ObjectSelect;
-import org.apache.cayenne.query.SQLTemplate;
-import org.junit.After;
-import org.junit.BeforeClass;
-import org.junit.Test;
-
-import java.util.List;
-
-import static junit.framework.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-
-
-public class CayenneOperationTests {
- private static ObjectContext context = null;
-
- @BeforeClass
- public static void setupTheCayenneContext() {
- ServerRuntime cayenneRuntime = ServerRuntime.builder()
- .addConfig("cayenne-project.xml")
- .build();
- context = cayenneRuntime.newContext();
- }
-
- @After
- public void deleteAllRecords() {
- SQLTemplate deleteArticles = new SQLTemplate(Article.class, "delete from article");
- SQLTemplate deleteAuthors = new SQLTemplate(Author.class, "delete from author");
-
- context.performGenericQuery(deleteArticles);
- context.performGenericQuery(deleteAuthors);
- }
-
- @Test
- public void givenAuthor_whenInsert_thenWeGetOneRecordInTheDatabase() {
- Author author = context.newObject(Author.class);
- author.setName("Paul");
-
- context.commitChanges();
-
- long records = ObjectSelect.dataRowQuery(Author.class).selectCount(context);
- assertEquals(1, records);
- }
-
- @Test
- public void givenAuthor_whenInsert_andQueryByFirstName_thenWeGetTheAuthor() {
- Author author = context.newObject(Author.class);
- author.setName("Paul");
-
- context.commitChanges();
-
- Author expectedAuthor = ObjectSelect.query(Author.class)
- .where(Author.NAME.eq("Paul"))
- .selectOne(context);
-
- assertEquals("Paul", expectedAuthor.getName());
- }
-
- @Test
- public void givenTwoAuthor_whenInsert_andQueryAll_thenWeGetTwoAuthors() {
- Author firstAuthor = context.newObject(Author.class);
- firstAuthor.setName("Paul");
-
- Author secondAuthor = context.newObject(Author.class);
- secondAuthor.setName("Ludovic");
-
- context.commitChanges();
-
- List authors = ObjectSelect.query(Author.class).select(context);
- assertEquals(2, authors.size());
- }
-
- @Test
- public void givenAuthor_whenUpdating_thenWeGetAnUpatedeAuthor() {
- Author author = context.newObject(Author.class);
- author.setName("Paul");
- context.commitChanges();
-
- Author expectedAuthor = ObjectSelect.query(Author.class)
- .where(Author.NAME.eq("Paul"))
- .selectOne(context);
- expectedAuthor.setName("Garcia");
- context.commitChanges();
-
- assertEquals(author.getName(), expectedAuthor.getName());
- }
-
- @Test
- public void givenAuthor_whenDeleting_thenWeLostHisDetails() {
- Author author = context.newObject(Author.class);
- author.setName("Paul");
- context.commitChanges();
-
- Author savedAuthor = ObjectSelect.query(Author.class)
- .where(Author.NAME.eq("Paul")).selectOne(context);
- if(savedAuthor != null) {
- context.deleteObjects(author);
- context.commitChanges();
- }
-
- Author expectedAuthor = ObjectSelect.query(Author.class)
- .where(Author.NAME.eq("Paul")).selectOne(context);
- assertNull(expectedAuthor);
- }
-
- @Test
- public void givenAuthor_whenAttachingToArticle_thenTheRelationIsMade() {
- Author author = context.newObject(Author.class);
- author.setName("Paul");
-
- Article article = context.newObject(Article.class);
- article.setTitle("My post title");
- article.setContent("The content");
- article.setAuthor(author);
-
- context.commitChanges();
-
- Author expectedAuthor = ObjectSelect.query(Author.class)
- .where(Author.NAME.eq("Paul"))
- .selectOne(context);
-
- Article expectedArticle = (expectedAuthor.getArticles()).get(0);
- assertEquals(article.getTitle(), expectedArticle.getTitle());
- }
-
-}
diff --git a/apache-curator/README.md b/apache-curator/README.md
new file mode 100644
index 0000000000..9bda573292
--- /dev/null
+++ b/apache-curator/README.md
@@ -0,0 +1,3 @@
+### Relevant Articles:
+
+- [Introduction to Apache Curator](http://www.baeldung.com/apache-curator)
diff --git a/apache-curator/pom.xml b/apache-curator/pom.xml
new file mode 100644
index 0000000000..ac10811e7a
--- /dev/null
+++ b/apache-curator/pom.xml
@@ -0,0 +1,67 @@
+
+ 4.0.0
+ apache-curator
+ 0.0.1-SNAPSHOT
+ jar
+
+
+ com.baeldung
+ parent-modules
+ 1.0.0-SNAPSHOT
+
+
+
+
+
+ org.apache.curator
+ curator-x-async
+ ${curator.version}
+
+
+ org.apache.zookeeper
+ zookeeper
+
+
+
+
+ org.apache.curator
+ curator-recipes
+ ${curator.version}
+
+
+ org.apache.zookeeper
+ zookeeper
+ ${zookeeper.version}
+
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+ ${jackson-databind.version}
+
+
+
+ org.assertj
+ assertj-core
+ ${assertj.version}
+ test
+
+
+ com.jayway.awaitility
+ awaitility
+ ${avaitility.version}
+ test
+
+
+
+
+ 4.0.1
+ 3.4.11
+ 2.9.4
+
+ 3.6.1
+ 1.7.0
+
+
+
\ No newline at end of file
diff --git a/apache-curator/src/main/java/com/baeldung/apache/curator/modeled/HostConfig.java b/apache-curator/src/main/java/com/baeldung/apache/curator/modeled/HostConfig.java
new file mode 100644
index 0000000000..bab7133742
--- /dev/null
+++ b/apache-curator/src/main/java/com/baeldung/apache/curator/modeled/HostConfig.java
@@ -0,0 +1,31 @@
+package com.baeldung.apache.curator.modeled;
+
+public class HostConfig {
+ private String hostname;
+ private int port;
+
+ public HostConfig() {
+
+ }
+
+ public HostConfig(String hostname, int port) {
+ this.hostname = hostname;
+ this.port = port;
+ }
+
+ public int getPort() {
+ return port;
+ }
+
+ public void setPort(int port) {
+ this.port = port;
+ }
+
+ public String getHostname() {
+ return hostname;
+ }
+
+ public void setHostname(String hostname) {
+ this.hostname = hostname;
+ }
+}
diff --git a/apache-curator/src/main/resources/logback.xml b/apache-curator/src/main/resources/logback.xml
new file mode 100644
index 0000000000..7d900d8ea8
--- /dev/null
+++ b/apache-curator/src/main/resources/logback.xml
@@ -0,0 +1,13 @@
+
+
+
+
+ %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/apache-curator/src/test/java/com/baeldung/apache/curator/BaseManualTest.java b/apache-curator/src/test/java/com/baeldung/apache/curator/BaseManualTest.java
new file mode 100644
index 0000000000..5722228b26
--- /dev/null
+++ b/apache-curator/src/test/java/com/baeldung/apache/curator/BaseManualTest.java
@@ -0,0 +1,22 @@
+package com.baeldung.apache.curator;
+
+import org.apache.curator.RetryPolicy;
+import org.apache.curator.framework.CuratorFramework;
+import org.apache.curator.framework.CuratorFrameworkFactory;
+import org.apache.curator.retry.RetryNTimes;
+import org.junit.Before;
+
+public abstract class BaseManualTest {
+
+ @Before
+ public void setup() {
+ org.apache.log4j.BasicConfigurator.configure();
+ }
+
+ protected CuratorFramework newClient() {
+ int sleepMsBetweenRetries = 100;
+ int maxRetries = 3;
+ RetryPolicy retryPolicy = new RetryNTimes(maxRetries, sleepMsBetweenRetries);
+ return CuratorFrameworkFactory.newClient("127.0.0.1:2181", retryPolicy);
+ }
+}
diff --git a/apache-curator/src/test/java/com/baeldung/apache/curator/configuration/ConfigurationManagementManualTest.java b/apache-curator/src/test/java/com/baeldung/apache/curator/configuration/ConfigurationManagementManualTest.java
new file mode 100644
index 0000000000..1a6fe6ccd0
--- /dev/null
+++ b/apache-curator/src/test/java/com/baeldung/apache/curator/configuration/ConfigurationManagementManualTest.java
@@ -0,0 +1,89 @@
+package com.baeldung.apache.curator.configuration;
+
+import static com.jayway.awaitility.Awaitility.await;
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.apache.curator.framework.CuratorFramework;
+import org.apache.curator.x.async.AsyncCuratorFramework;
+import org.junit.Test;
+
+import com.baeldung.apache.curator.BaseManualTest;
+
+public class ConfigurationManagementManualTest extends BaseManualTest {
+
+ private static final String KEY_FORMAT = "/%s";
+
+ @Test
+ public void givenPath_whenCreateKey_thenValueIsStored() throws Exception {
+ try (CuratorFramework client = newClient()) {
+ client.start();
+ AsyncCuratorFramework async = AsyncCuratorFramework.wrap(client);
+ String key = getKey();
+ String expected = "my_value";
+
+ // Create key nodes structure
+ client.create()
+ .forPath(key);
+
+ // Set data value for our key
+ async.setData()
+ .forPath(key, expected.getBytes());
+
+ // Get data value
+ AtomicBoolean isEquals = new AtomicBoolean();
+ async.getData()
+ .forPath(key)
+ .thenAccept(
+ data -> isEquals.set(new String(data).equals(expected)));
+
+ await().until(() -> assertThat(isEquals.get()).isTrue());
+ }
+ }
+
+ @Test
+ public void givenPath_whenWatchAKeyAndStoreAValue_thenWatcherIsTriggered()
+ throws Exception {
+ try (CuratorFramework client = newClient()) {
+ client.start();
+ AsyncCuratorFramework async = AsyncCuratorFramework.wrap(client);
+ String key = getKey();
+ String expected = "my_value";
+
+ // Create key structure
+ async.create()
+ .forPath(key);
+
+ List changes = new ArrayList<>();
+
+ // Watch data value
+ async.watched()
+ .getData()
+ .forPath(key)
+ .event()
+ .thenAccept(watchedEvent -> {
+ try {
+ changes.add(new String(client.getData()
+ .forPath(watchedEvent.getPath())));
+ } catch (Exception e) {
+ // fail ...
+ }
+ });
+
+ // Set data value for our key
+ async.setData()
+ .forPath(key, expected.getBytes());
+
+ await().until(() -> assertThat(changes.size() > 0).isTrue());
+ }
+ }
+
+ private String getKey() {
+ return String.format(KEY_FORMAT, UUID.randomUUID()
+ .toString());
+ }
+}
diff --git a/apache-curator/src/test/java/com/baeldung/apache/curator/connection/ConnectionManagementManualTest.java b/apache-curator/src/test/java/com/baeldung/apache/curator/connection/ConnectionManagementManualTest.java
new file mode 100644
index 0000000000..61fa1c7c2c
--- /dev/null
+++ b/apache-curator/src/test/java/com/baeldung/apache/curator/connection/ConnectionManagementManualTest.java
@@ -0,0 +1,79 @@
+package com.baeldung.apache.curator.connection;
+
+import static com.jayway.awaitility.Awaitility.await;
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.apache.curator.RetryPolicy;
+import org.apache.curator.framework.CuratorFramework;
+import org.apache.curator.framework.CuratorFrameworkFactory;
+import org.apache.curator.retry.RetryNTimes;
+import org.apache.curator.x.async.AsyncCuratorFramework;
+import org.junit.Test;
+
+public class ConnectionManagementManualTest {
+
+ @Test
+ public void givenRunningZookeeper_whenOpenConnection_thenClientIsOpened()
+ throws Exception {
+ int sleepMsBetweenRetries = 100;
+ int maxRetries = 3;
+ RetryPolicy retryPolicy = new RetryNTimes(maxRetries,
+ sleepMsBetweenRetries);
+
+ try (CuratorFramework client = CuratorFrameworkFactory
+ .newClient("127.0.0.1:2181", retryPolicy)) {
+ client.start();
+
+ assertThat(client.checkExists()
+ .forPath("/")).isNotNull();
+ }
+ }
+
+ @Test
+ public void givenRunningZookeeper_whenOpenConnectionUsingAsyncNotBlocking_thenClientIsOpened()
+ throws InterruptedException {
+ int sleepMsBetweenRetries = 100;
+ int maxRetries = 3;
+ RetryPolicy retryPolicy = new RetryNTimes(maxRetries,
+ sleepMsBetweenRetries);
+
+ try (CuratorFramework client = CuratorFrameworkFactory
+ .newClient("127.0.0.1:2181", retryPolicy)) {
+ client.start();
+ AsyncCuratorFramework async = AsyncCuratorFramework.wrap(client);
+
+ AtomicBoolean exists = new AtomicBoolean(false);
+
+ async.checkExists()
+ .forPath("/")
+ .thenAcceptAsync(s -> exists.set(s != null));
+
+ await().until(() -> assertThat(exists.get()).isTrue());
+ }
+ }
+
+ @Test
+ public void givenRunningZookeeper_whenOpenConnectionUsingAsyncBlocking_thenClientIsOpened()
+ throws InterruptedException {
+ int sleepMsBetweenRetries = 100;
+ int maxRetries = 3;
+ RetryPolicy retryPolicy = new RetryNTimes(maxRetries,
+ sleepMsBetweenRetries);
+
+ try (CuratorFramework client = CuratorFrameworkFactory
+ .newClient("127.0.0.1:2181", retryPolicy)) {
+ client.start();
+ AsyncCuratorFramework async = AsyncCuratorFramework.wrap(client);
+
+ AtomicBoolean exists = new AtomicBoolean(false);
+
+ async.checkExists()
+ .forPath("/")
+ .thenAccept(s -> exists.set(s != null));
+
+ await().until(() -> assertThat(exists.get()).isTrue());
+ }
+ }
+}
diff --git a/apache-curator/src/test/java/com/baeldung/apache/curator/modeled/ModelTypedExamplesManualTest.java b/apache-curator/src/test/java/com/baeldung/apache/curator/modeled/ModelTypedExamplesManualTest.java
new file mode 100644
index 0000000000..d7caa18ce9
--- /dev/null
+++ b/apache-curator/src/test/java/com/baeldung/apache/curator/modeled/ModelTypedExamplesManualTest.java
@@ -0,0 +1,49 @@
+package com.baeldung.apache.curator.modeled;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.fail;
+
+import org.apache.curator.framework.CuratorFramework;
+import org.apache.curator.x.async.AsyncCuratorFramework;
+import org.apache.curator.x.async.modeled.JacksonModelSerializer;
+import org.apache.curator.x.async.modeled.ModelSpec;
+import org.apache.curator.x.async.modeled.ModeledFramework;
+import org.apache.curator.x.async.modeled.ZPath;
+import org.junit.Test;
+
+import com.baeldung.apache.curator.BaseManualTest;
+
+public class ModelTypedExamplesManualTest extends BaseManualTest {
+
+ @Test
+ public void givenPath_whenStoreAModel_thenNodesAreCreated()
+ throws InterruptedException {
+
+ ModelSpec mySpec = ModelSpec
+ .builder(ZPath.parseWithIds("/config/dev"),
+ JacksonModelSerializer.build(HostConfig.class))
+ .build();
+
+ try (CuratorFramework client = newClient()) {
+ client.start();
+ AsyncCuratorFramework async = AsyncCuratorFramework.wrap(client);
+ ModeledFramework modeledClient = ModeledFramework
+ .wrap(async, mySpec);
+
+ modeledClient.set(new HostConfig("host-name", 8080));
+
+ modeledClient.read()
+ .whenComplete((value, e) -> {
+ if (e != null) {
+ fail("Cannot read host config", e);
+ } else {
+ assertThat(value).isNotNull();
+ assertThat(value.getHostname()).isEqualTo("host-name");
+ assertThat(value.getPort()).isEqualTo(8080);
+ }
+
+ });
+ }
+
+ }
+}
diff --git a/apache-curator/src/test/java/com/baeldung/apache/curator/recipes/RecipesManualTest.java b/apache-curator/src/test/java/com/baeldung/apache/curator/recipes/RecipesManualTest.java
new file mode 100644
index 0000000000..0c5890ad59
--- /dev/null
+++ b/apache-curator/src/test/java/com/baeldung/apache/curator/recipes/RecipesManualTest.java
@@ -0,0 +1,74 @@
+package com.baeldung.apache.curator.recipes;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.apache.curator.framework.CuratorFramework;
+import org.apache.curator.framework.recipes.leader.LeaderSelector;
+import org.apache.curator.framework.recipes.leader.LeaderSelectorListener;
+import org.apache.curator.framework.recipes.locks.InterProcessSemaphoreMutex;
+import org.apache.curator.framework.recipes.shared.SharedCount;
+import org.apache.curator.framework.state.ConnectionState;
+import org.junit.Test;
+
+import com.baeldung.apache.curator.BaseManualTest;
+
+public class RecipesManualTest extends BaseManualTest {
+
+ @Test
+ public void givenRunningZookeeper_whenUsingLeaderElection_thenNoErrors() {
+ try (CuratorFramework client = newClient()) {
+ client.start();
+ LeaderSelector leaderSelector = new LeaderSelector(client, "/mutex/select/leader/for/job/A", new LeaderSelectorListener() {
+
+ @Override
+ public void stateChanged(CuratorFramework client, ConnectionState newState) {
+
+ }
+
+ @Override
+ public void takeLeadership(CuratorFramework client) throws Exception {
+ // I'm the leader of the job A !
+ }
+
+ });
+
+ leaderSelector.start();
+
+ // Wait until the job A is done among all the members
+
+ leaderSelector.close();
+ }
+ }
+
+ @Test
+ public void givenRunningZookeeper_whenUsingSharedLock_thenNoErrors() throws Exception {
+ try (CuratorFramework client = newClient()) {
+ client.start();
+ InterProcessSemaphoreMutex sharedLock = new InterProcessSemaphoreMutex(client, "/mutex/process/A");
+
+ sharedLock.acquire();
+
+ // Do process A
+
+ sharedLock.release();
+ }
+ }
+
+ @Test
+ public void givenRunningZookeeper_whenUsingSharedCounter_thenCounterIsIncrement() throws Exception {
+ try (CuratorFramework client = newClient()) {
+ client.start();
+
+ try (SharedCount counter = new SharedCount(client, "/counters/A", 0)) {
+ counter.start();
+
+ counter.setCount(0);
+ counter.setCount(counter.getCount() + 1);
+
+ assertThat(counter.getCount()).isEqualTo(1);
+ }
+
+ }
+ }
+
+}
diff --git a/apache-cxf/README.md b/apache-cxf/README.md
index 1e66ce5da8..d03999dce3 100644
--- a/apache-cxf/README.md
+++ b/apache-cxf/README.md
@@ -3,3 +3,4 @@
- [Apache CXF Support for RESTful Web Services](http://www.baeldung.com/apache-cxf-rest-api)
- [A Guide to Apache CXF with Spring](http://www.baeldung.com/apache-cxf-with-spring)
- [Introduction to Apache CXF](http://www.baeldung.com/introduction-to-apache-cxf)
+- [Server-Sent Events (SSE) In JAX-RS](https://www.baeldung.com/java-ee-jax-rs-sse)
diff --git a/apache-cxf/cxf-aegis/pom.xml b/apache-cxf/cxf-aegis/pom.xml
index 6d8aa85679..b7e9e426a2 100644
--- a/apache-cxf/cxf-aegis/pom.xml
+++ b/apache-cxf/cxf-aegis/pom.xml
@@ -2,14 +2,13 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
4.0.0
cxf-aegis
+
com.baeldung
apache-cxf
0.0.1-SNAPSHOT
-
- 3.1.8
-
+
org.apache.cxf
@@ -17,4 +16,5 @@
${cxf.version}
+
diff --git a/apache-cxf/cxf-aegis/src/main/resources/logback.xml b/apache-cxf/cxf-aegis/src/main/resources/logback.xml
new file mode 100644
index 0000000000..7d900d8ea8
--- /dev/null
+++ b/apache-cxf/cxf-aegis/src/main/resources/logback.xml
@@ -0,0 +1,13 @@
+
+
+
+
+ %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/apache-cxf/cxf-introduction/pom.xml b/apache-cxf/cxf-introduction/pom.xml
index 1b9ba22230..a9e82c16b3 100644
--- a/apache-cxf/cxf-introduction/pom.xml
+++ b/apache-cxf/cxf-introduction/pom.xml
@@ -11,32 +11,6 @@
0.0.1-SNAPSHOT
-
- 3.1.8
- 2.19.1
-
-
-
-
-
- org.codehaus.mojo
- exec-maven-plugin
-
- com.baeldung.cxf.introduction.Server
-
-
-
- maven-surefire-plugin
- ${surefire.version}
-
-
- **/*LiveTest.java
-
-
-
-
-
-
org.apache.cxf
@@ -50,4 +24,16 @@
+
+
+
+ org.codehaus.mojo
+ exec-maven-plugin
+
+ com.baeldung.cxf.introduction.Server
+
+
+
+
+