diff --git a/.travis.yml b/.travis.yml index 3d28a5cd76..0393b2304e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,7 @@ before_install: - echo "MAVEN_OPTS='-Xmx2048M -Xss128M -XX:+CMSClassUnloadingEnabled -XX:+UseG1GC -XX:-UseGCOverheadLimit'" > ~/.mavenrc install: skip -script: travis_wait 60 mvn -q test -fae +script: travis_wait 60 mvn -q test sudo: required diff --git a/algorithms/README.md b/algorithms/README.md index 3401b6d935..31cb8076d9 100644 --- a/algorithms/README.md +++ b/algorithms/README.md @@ -16,3 +16,4 @@ - [Introduction to Minimax Algorithm](http://www.baeldung.com/java-minimax-algorithm) - [How to Calculate Levenshtein Distance in Java?](http://www.baeldung.com/java-levenshtein-distance) - [How to Find the Kth Largest Element in Java](http://www.baeldung.com/java-kth-largest-element) +- [Multi-Swarm Optimization Algorithm in Java](http://www.baeldung.com/java-multi-swarm-algorithm) diff --git a/algorithms/pom.xml b/algorithms/pom.xml index 2eb8cd42b6..8751cf45c0 100644 --- a/algorithms/pom.xml +++ b/algorithms/pom.xml @@ -9,6 +9,7 @@ 1.5.0 1.16.12 3.6.1 + 1.0.1 @@ -39,6 +40,11 @@ jgrapht-core 1.0.1 + + pl.allegro.finance + tradukisto + ${tradukisto.version} + org.assertj assertj-core @@ -46,7 +52,6 @@ test - @@ -77,4 +82,4 @@ - + \ No newline at end of file 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/sudoku/BacktrackingAlgorithm.java b/algorithms/src/main/java/com/baeldung/algorithms/sudoku/BacktrackingAlgorithm.java index ff426cbe68..4b37558aab 100644 --- a/algorithms/src/main/java/com/baeldung/algorithms/sudoku/BacktrackingAlgorithm.java +++ b/algorithms/src/main/java/com/baeldung/algorithms/sudoku/BacktrackingAlgorithm.java @@ -40,15 +40,15 @@ public class BacktrackingAlgorithm { } private boolean solve(int[][] board) { - for (int r = BOARD_START_INDEX; r < BOARD_SIZE; r++) { - for (int c = BOARD_START_INDEX; c < BOARD_SIZE; c++) { - if (board[r][c] == NO_VALUE) { + 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[r][c] = k; - if (isValid(board, r, c) && solve(board)) { + board[row][column] = k; + if (isValid(board, row, column) && solve(board)) { return true; } - board[r][c] = NO_VALUE; + board[row][column] = NO_VALUE; } return false; } @@ -57,44 +57,44 @@ public class BacktrackingAlgorithm { return true; } - private boolean isValid(int[][] board, int r, int c) { - return rowConstraint(board, r) && - columnConstraint(board, c) && - subsectionConstraint(board, r, c); + 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 r, int c) { + private boolean subsectionConstraint(int[][] board, int row, int column) { boolean[] constraint = new boolean[BOARD_SIZE]; - int subsectionRowStart = (r / SUBSECTION_SIZE) * SUBSECTION_SIZE; + int subsectionRowStart = (row / SUBSECTION_SIZE) * SUBSECTION_SIZE; int subsectionRowEnd = subsectionRowStart + SUBSECTION_SIZE; - int subsectionColumnStart = (c / SUBSECTION_SIZE) * SUBSECTION_SIZE; + int subsectionColumnStart = (column / SUBSECTION_SIZE) * SUBSECTION_SIZE; int subsectionColumnEnd = subsectionColumnStart + SUBSECTION_SIZE; - for (int i = subsectionRowStart; i < subsectionRowEnd; i++) { - for (int j = subsectionColumnStart; j < subsectionColumnEnd; j++) { - if (!checkConstraint(board, i, constraint, j)) return false; + 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 c) { + private boolean columnConstraint(int[][] board, int column) { boolean[] constraint = new boolean[BOARD_SIZE]; return IntStream.range(BOARD_START_INDEX, BOARD_SIZE) - .allMatch(i -> checkConstraint(board, i, constraint, c)); + .allMatch(row -> checkConstraint(board, row, constraint, column)); } - private boolean rowConstraint(int[][] board, int r) { + private boolean rowConstraint(int[][] board, int row) { boolean[] constraint = new boolean[BOARD_SIZE]; return IntStream.range(BOARD_START_INDEX, BOARD_SIZE) - .allMatch(i -> checkConstraint(board, r, constraint, i)); + .allMatch(column -> checkConstraint(board, row, constraint, column)); } - private boolean checkConstraint(int[][] board, int r, boolean[] constraint, int c) { - if (board[r][c] != NO_VALUE) { - if (!constraint[board[r][c] - 1]) { - constraint[board[r][c] - 1] = true; + 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; } diff --git a/algorithms/src/main/java/com/baeldung/algorithms/sudoku/DancingLinksAlgorithm.java b/algorithms/src/main/java/com/baeldung/algorithms/sudoku/DancingLinksAlgorithm.java index 76b686afa6..df02ff3d11 100644 --- a/algorithms/src/main/java/com/baeldung/algorithms/sudoku/DancingLinksAlgorithm.java +++ b/algorithms/src/main/java/com/baeldung/algorithms/sudoku/DancingLinksAlgorithm.java @@ -34,8 +34,8 @@ public class DancingLinksAlgorithm { dlx.runSolver(); } - private int getIndex(int row, int col, int num) { - return (row - 1) * BOARD_SIZE * BOARD_SIZE + (col - 1) * BOARD_SIZE + (num - 1); + 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() { @@ -51,12 +51,12 @@ public class DancingLinksAlgorithm { } private int checkSubsectionConstraint(boolean[][] coverBoard, int hBase) { - for (int br = COVER_START_INDEX; br <= BOARD_SIZE; br += SUBSECTION_SIZE) { - for (int bc = COVER_START_INDEX; bc <= BOARD_SIZE; bc += SUBSECTION_SIZE) { + 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 rDelta = 0; rDelta < SUBSECTION_SIZE; rDelta++) { - for (int cDelta = 0; cDelta < SUBSECTION_SIZE; cDelta++) { - int index = getIndex(br + rDelta, bc + cDelta, n); + 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; } } @@ -67,10 +67,10 @@ public class DancingLinksAlgorithm { } private int checkColumnConstraint(boolean[][] coverBoard, int hBase) { - for (int c = COVER_START_INDEX; c <= BOARD_SIZE; c++) { + for (int column = COVER_START_INDEX; column <= BOARD_SIZE; column++) { for (int n = COVER_START_INDEX; n <= BOARD_SIZE; n++, hBase++) { - for (int r1 = COVER_START_INDEX; r1 <= BOARD_SIZE; r1++) { - int index = getIndex(r1, c, n); + for (int row = COVER_START_INDEX; row <= BOARD_SIZE; row++) { + int index = getIndex(row, column, n); coverBoard[index][hBase] = true; } } @@ -79,10 +79,10 @@ public class DancingLinksAlgorithm { } private int checkRowConstraint(boolean[][] coverBoard, int hBase) { - for (int r = COVER_START_INDEX; r <= BOARD_SIZE; r++) { + for (int row = COVER_START_INDEX; row <= BOARD_SIZE; row++) { for (int n = COVER_START_INDEX; n <= BOARD_SIZE; n++, hBase++) { - for (int c1 = COVER_START_INDEX; c1 <= BOARD_SIZE; c1++) { - int index = getIndex(r, c1, n); + for (int column = COVER_START_INDEX; column <= BOARD_SIZE; column++) { + int index = getIndex(row, column, n); coverBoard[index][hBase] = true; } } @@ -91,10 +91,10 @@ public class DancingLinksAlgorithm { } private int checkCellConstraint(boolean[][] coverBoard, int hBase) { - for (int r = COVER_START_INDEX; r <= BOARD_SIZE; r++) { - for (int c = COVER_START_INDEX; c <= BOARD_SIZE; c++, 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(r, c, n); + int index = getIndex(row, column, n); coverBoard[index][hBase] = true; } } @@ -104,13 +104,13 @@ public class DancingLinksAlgorithm { private boolean[][] initializeExactCoverBoard(int[][] board) { boolean[][] coverBoard = createExactCoverBoard(); - for (int i = COVER_START_INDEX; i <= BOARD_SIZE; i++) { - for (int j = COVER_START_INDEX; j <= BOARD_SIZE; j++) { - int n = board[i - 1][j - 1]; + 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(i, j, num)], false); + Arrays.fill(coverBoard[getIndex(row, column, num)], false); } } } diff --git a/algorithms/src/main/java/com/baeldung/algorithms/sudoku/DancingNode.java b/algorithms/src/main/java/com/baeldung/algorithms/sudoku/DancingNode.java index b494eba9ef..2422ff0dff 100644 --- a/algorithms/src/main/java/com/baeldung/algorithms/sudoku/DancingNode.java +++ b/algorithms/src/main/java/com/baeldung/algorithms/sudoku/DancingNode.java @@ -4,21 +4,21 @@ class DancingNode { DancingNode L, R, U, D; ColumnNode C; - DancingNode hookDown(DancingNode n1) { - assert (this.C == n1.C); - n1.D = this.D; - n1.D.U = n1; - n1.U = this; - this.D = n1; - return n1; + 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 n1) { - n1.R = this.R; - n1.R.L = n1; - n1.L = this; - this.R = n1; - return n1; + DancingNode hookRight(DancingNode node) { + node.R = this.R; + node.R.L = node; + node.L = this; + this.R = node; + return node; } void unlinkLR() { diff --git a/algorithms/src/test/java/com/baeldung/algorithms/moneywords/NumberWordConverterTest.java b/algorithms/src/test/java/com/baeldung/algorithms/moneywords/NumberWordConverterTest.java new file mode 100644 index 0000000000..a4a169f158 --- /dev/null +++ b/algorithms/src/test/java/com/baeldung/algorithms/moneywords/NumberWordConverterTest.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 NumberWordConverterTest { + + @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/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/apache-curator/pom.xml b/apache-curator/pom.xml new file mode 100644 index 0000000000..35549861c8 --- /dev/null +++ b/apache-curator/pom.xml @@ -0,0 +1,76 @@ + + 4.0.0 + apache-curator + 0.0.1-SNAPSHOT + jar + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + + + + 4.0.1 + 3.4.11 + 2.9.4 + + + 3.6.1 + 1.7.0 + + + + + + + + + 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 + + + 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/test/java/com/baeldung/apache/curator/BaseTest.java b/apache-curator/src/test/java/com/baeldung/apache/curator/BaseTest.java new file mode 100644 index 0000000000..cfac3ee3f2 --- /dev/null +++ b/apache-curator/src/test/java/com/baeldung/apache/curator/BaseTest.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 BaseTest { + + @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..d02ef8131d --- /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.BaseTest; + +public class ConfigurationManagementManualTest extends BaseTest { + + 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..4400c1d1aa --- /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.BaseTest; + +public class ModelTypedExamplesManualTest extends BaseTest { + + @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..04f4104e6b --- /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.BaseTest; + +public class RecipesManualTest extends BaseTest { + + @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-tika/pom.xml b/apache-tika/pom.xml new file mode 100644 index 0000000000..34013dee89 --- /dev/null +++ b/apache-tika/pom.xml @@ -0,0 +1,25 @@ + + 4.0.0 + com.baeldung + apache-tika + 0.0.1-SNAPSHOT + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + + + + 1.17 + + + + + org.apache.tika + tika-parsers + ${tika.version} + + + \ No newline at end of file diff --git a/apache-tika/src/main/java/com/baeldung/tika/TikaAnalysis.java b/apache-tika/src/main/java/com/baeldung/tika/TikaAnalysis.java new file mode 100644 index 0000000000..85eafc7c08 --- /dev/null +++ b/apache-tika/src/main/java/com/baeldung/tika/TikaAnalysis.java @@ -0,0 +1,67 @@ +package com.baeldung.tika; + +import java.io.IOException; +import java.io.InputStream; + +import org.apache.tika.Tika; +import org.apache.tika.detect.DefaultDetector; +import org.apache.tika.detect.Detector; +import org.apache.tika.exception.TikaException; +import org.apache.tika.metadata.Metadata; +import org.apache.tika.mime.MediaType; +import org.apache.tika.parser.AutoDetectParser; +import org.apache.tika.parser.ParseContext; +import org.apache.tika.parser.Parser; +import org.apache.tika.sax.BodyContentHandler; +import org.xml.sax.ContentHandler; +import org.xml.sax.SAXException; + +public class TikaAnalysis { + public static String detectDocTypeUsingDetector(InputStream stream) throws IOException { + Detector detector = new DefaultDetector(); + Metadata metadata = new Metadata(); + + MediaType mediaType = detector.detect(stream, metadata); + return mediaType.toString(); + } + + public static String detectDocTypeUsingFacade(InputStream stream) throws IOException { + Tika tika = new Tika(); + String mediaType = tika.detect(stream); + return mediaType; + } + + public static String extractContentUsingParser(InputStream stream) throws IOException, TikaException, SAXException { + Parser parser = new AutoDetectParser(); + ContentHandler handler = new BodyContentHandler(); + Metadata metadata = new Metadata(); + ParseContext context = new ParseContext(); + + parser.parse(stream, handler, metadata, context); + return handler.toString(); + } + + public static String extractContentUsingFacade(InputStream stream) throws IOException, TikaException { + Tika tika = new Tika(); + String content = tika.parseToString(stream); + return content; + } + + public static Metadata extractMetadatatUsingParser(InputStream stream) throws IOException, SAXException, TikaException { + Parser parser = new AutoDetectParser(); + ContentHandler handler = new BodyContentHandler(); + Metadata metadata = new Metadata(); + ParseContext context = new ParseContext(); + + parser.parse(stream, handler, metadata, context); + return metadata; + } + + public static Metadata extractMetadatatUsingFacade(InputStream stream) throws IOException, TikaException { + Tika tika = new Tika(); + Metadata metadata = new Metadata(); + + tika.parse(stream, metadata); + return metadata; + } +} diff --git a/apache-tika/src/test/java/com/baeldung/tika/TikaUnitTest.java b/apache-tika/src/test/java/com/baeldung/tika/TikaUnitTest.java new file mode 100644 index 0000000000..f8c2372d1f --- /dev/null +++ b/apache-tika/src/test/java/com/baeldung/tika/TikaUnitTest.java @@ -0,0 +1,79 @@ +package com.baeldung.tika; + +import static org.hamcrest.CoreMatchers.containsString; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; + +import java.io.IOException; +import java.io.InputStream; + +import org.apache.tika.exception.TikaException; +import org.apache.tika.metadata.Metadata; +import org.junit.Test; +import org.xml.sax.SAXException; + +public class TikaUnitTest { + @Test + public void whenUsingDetector_thenDocumentTypeIsReturned() throws IOException { + InputStream stream = this.getClass().getClassLoader().getResourceAsStream("tika.txt"); + String mediaType = TikaAnalysis.detectDocTypeUsingDetector(stream); + + assertEquals("application/pdf", mediaType); + + stream.close(); + } + + @Test + public void whenUsingFacade_thenDocumentTypeIsReturned() throws IOException { + InputStream stream = this.getClass().getClassLoader().getResourceAsStream("tika.txt"); + String mediaType = TikaAnalysis.detectDocTypeUsingFacade(stream); + + assertEquals("application/pdf", mediaType); + + stream.close(); + } + + @Test + public void whenUsingParser_thenContentIsReturned() throws IOException, TikaException, SAXException { + InputStream stream = this.getClass().getClassLoader().getResourceAsStream("tika.docx"); + String content = TikaAnalysis.extractContentUsingParser(stream); + + assertThat(content, containsString("Apache Tika - a content analysis toolkit")); + assertThat(content, containsString("detects and extracts metadata and text")); + + stream.close(); + } + + @Test + public void whenUsingFacade_thenContentIsReturned() throws IOException, TikaException { + InputStream stream = this.getClass().getClassLoader().getResourceAsStream("tika.docx"); + String content = TikaAnalysis.extractContentUsingFacade(stream); + + assertThat(content, containsString("Apache Tika - a content analysis toolkit")); + assertThat(content, containsString("detects and extracts metadata and text")); + + stream.close(); + } + + @Test + public void whenUsingParser_thenMetadataIsReturned() throws IOException, TikaException, SAXException { + InputStream stream = this.getClass().getClassLoader().getResourceAsStream("tika.xlsx"); + Metadata metadata = TikaAnalysis.extractMetadatatUsingParser(stream); + + assertEquals("org.apache.tika.parser.DefaultParser", metadata.get("X-Parsed-By")); + assertEquals("Microsoft Office User", metadata.get("Author")); + + stream.close(); + } + + @Test + public void whenUsingFacade_thenMetadataIsReturned() throws IOException, TikaException { + InputStream stream = this.getClass().getClassLoader().getResourceAsStream("tika.xlsx"); + Metadata metadata = TikaAnalysis.extractMetadatatUsingFacade(stream); + + assertEquals("org.apache.tika.parser.DefaultParser", metadata.get("X-Parsed-By")); + assertEquals("Microsoft Office User", metadata.get("Author")); + + stream.close(); + } +} diff --git a/apache-tika/src/test/resources/tika.docx b/apache-tika/src/test/resources/tika.docx new file mode 100644 index 0000000000..0a01ccef55 Binary files /dev/null and b/apache-tika/src/test/resources/tika.docx differ diff --git a/apache-tika/src/test/resources/tika.txt b/apache-tika/src/test/resources/tika.txt new file mode 100644 index 0000000000..26923836de Binary files /dev/null and b/apache-tika/src/test/resources/tika.txt differ diff --git a/apache-tika/src/test/resources/tika.xlsx b/apache-tika/src/test/resources/tika.xlsx new file mode 100644 index 0000000000..110a0b2dd5 Binary files /dev/null and b/apache-tika/src/test/resources/tika.xlsx differ diff --git a/apache-zookeeper/pom.xml b/apache-zookeeper/pom.xml new file mode 100644 index 0000000000..b08da534a5 --- /dev/null +++ b/apache-zookeeper/pom.xml @@ -0,0 +1,23 @@ + + 4.0.0 + com.baeldung + apache-zookeeper + 0.0.1-SNAPSHOT + jar + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + + + + + org.apache.zookeeper + zookeeper + 3.4.11 + + + + diff --git a/apache-zookeeper/src/main/java/com/baeldung/zookeeper/connection/ZKConnection.java b/apache-zookeeper/src/main/java/com/baeldung/zookeeper/connection/ZKConnection.java new file mode 100644 index 0000000000..0678250d57 --- /dev/null +++ b/apache-zookeeper/src/main/java/com/baeldung/zookeeper/connection/ZKConnection.java @@ -0,0 +1,33 @@ +package com.baeldung.zookeeper.connection; + +import java.io.IOException; +import java.util.concurrent.CountDownLatch; + +import org.apache.zookeeper.WatchedEvent; +import org.apache.zookeeper.Watcher; +import org.apache.zookeeper.Watcher.Event.KeeperState; +import org.apache.zookeeper.ZooKeeper; + +public class ZKConnection { + private ZooKeeper zoo; + final CountDownLatch connectionLatch = new CountDownLatch(1); + + public ZKConnection() { + } + + public ZooKeeper connect(String host) throws IOException, InterruptedException { + zoo = new ZooKeeper(host, 2000, new Watcher() { + public void process(WatchedEvent we) { + if (we.getState() == KeeperState.SyncConnected) { + connectionLatch.countDown(); + } + } + }); + connectionLatch.await(); + return zoo; + } + + public void close() throws InterruptedException { + zoo.close(); + } +} diff --git a/apache-zookeeper/src/main/java/com/baeldung/zookeeper/manager/ZKManager.java b/apache-zookeeper/src/main/java/com/baeldung/zookeeper/manager/ZKManager.java new file mode 100644 index 0000000000..0c0ad52123 --- /dev/null +++ b/apache-zookeeper/src/main/java/com/baeldung/zookeeper/manager/ZKManager.java @@ -0,0 +1,35 @@ +package com.baeldung.zookeeper.manager; + +import org.apache.zookeeper.KeeperException; + +public interface ZKManager { + /** + * Create a Znode and save some data + * + * @param path + * @param data + * @throws KeeperException + * @throws InterruptedException + */ + public void create(String path, byte[] data) throws KeeperException, InterruptedException; + + /** + * Get ZNode Data + * + * @param path + * @param boolean watchFlag + * @throws KeeperException + * @throws InterruptedException + */ + public Object getZNodeData(String path, boolean watchFlag); + + /** + * Update the ZNode Data + * + * @param path + * @param data + * @throws KeeperException + * @throws InterruptedException + */ + public void update(String path, byte[] data) throws KeeperException, InterruptedException, KeeperException; +} diff --git a/apache-zookeeper/src/main/java/com/baeldung/zookeeper/manager/ZKManagerImpl.java b/apache-zookeeper/src/main/java/com/baeldung/zookeeper/manager/ZKManagerImpl.java new file mode 100644 index 0000000000..adf76bc0f2 --- /dev/null +++ b/apache-zookeeper/src/main/java/com/baeldung/zookeeper/manager/ZKManagerImpl.java @@ -0,0 +1,58 @@ +package com.baeldung.zookeeper.manager; + +import org.apache.zookeeper.CreateMode; +import org.apache.zookeeper.KeeperException; +import org.apache.zookeeper.ZooDefs; +import org.apache.zookeeper.ZooKeeper; + +import com.baeldung.zookeeper.connection.ZKConnection; + +public class ZKManagerImpl implements ZKManager { + private static ZooKeeper zkeeper; + private static ZKConnection zkConnection; + + public ZKManagerImpl() { + initialize(); + } + + /** * Initialize connection */ + private void initialize() { + try { + zkConnection = new ZKConnection(); + zkeeper = zkConnection.connect("localhost"); + } catch (Exception e) { + System.out.println(e.getMessage()); + } + } + + public void closeConnection() { + try { + zkConnection.close(); + } catch (InterruptedException e) { + System.out.println(e.getMessage()); + } + } + + public void create(String path, byte[] data) throws KeeperException, InterruptedException { + zkeeper.create(path, data, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); + } + + public Object getZNodeData(String path, boolean watchFlag) { + try { + byte[] b = null; + b = zkeeper.getData(path, null, null); + String data = new String(b, "UTF-8"); + System.out.println(data); + return data; + } catch (Exception e) { + System.out.println(e.getMessage()); + } + return null; + } + + public void update(String path, byte[] data) throws KeeperException, InterruptedException { + int version = zkeeper.exists(path, true) + .getVersion(); + zkeeper.setData(path, data, version); + } +} diff --git a/aws/README.md b/aws/README.md index b6d0b79d91..f179ddc3f6 100644 --- a/aws/README.md +++ b/aws/README.md @@ -3,4 +3,5 @@ - [AWS Lambda Using DynamoDB With Java](http://www.baeldung.com/aws-lambda-dynamodb-java) - [AWS S3 with Java](http://www.baeldung.com/aws-s3-java) - [AWS Lambda With Java](http://www.baeldung.com/java-aws-lambda) +- [Managing EC2 Instances in Java] (http://www.baeldung.com/ec2-java) diff --git a/aws/pom.xml b/aws/pom.xml index c66c420fae..33fc3b0cba 100644 --- a/aws/pom.xml +++ b/aws/pom.xml @@ -18,7 +18,7 @@ 1.3.0 1.1.0 2.8.0 - 1.11.154 + 1.11.290 4.12 2.8.9 3.8.0 diff --git a/aws/src/main/java/com/baeldung/ec2/EC2Application.java b/aws/src/main/java/com/baeldung/ec2/EC2Application.java new file mode 100644 index 0000000000..6755188fcd --- /dev/null +++ b/aws/src/main/java/com/baeldung/ec2/EC2Application.java @@ -0,0 +1,137 @@ +package com.baeldung.ec2; + +import java.util.Arrays; + +import com.amazonaws.auth.AWSCredentials; +import com.amazonaws.auth.AWSStaticCredentialsProvider; +import com.amazonaws.auth.BasicAWSCredentials; +import com.amazonaws.regions.Regions; +import com.amazonaws.services.ec2.AmazonEC2; +import com.amazonaws.services.ec2.AmazonEC2ClientBuilder; +import com.amazonaws.services.ec2.model.AuthorizeSecurityGroupIngressRequest; +import com.amazonaws.services.ec2.model.CreateKeyPairRequest; +import com.amazonaws.services.ec2.model.CreateKeyPairResult; +import com.amazonaws.services.ec2.model.CreateSecurityGroupRequest; +import com.amazonaws.services.ec2.model.DescribeInstancesRequest; +import com.amazonaws.services.ec2.model.DescribeInstancesResult; +import com.amazonaws.services.ec2.model.DescribeKeyPairsRequest; +import com.amazonaws.services.ec2.model.DescribeKeyPairsResult; +import com.amazonaws.services.ec2.model.IpPermission; +import com.amazonaws.services.ec2.model.IpRange; +import com.amazonaws.services.ec2.model.MonitorInstancesRequest; +import com.amazonaws.services.ec2.model.RebootInstancesRequest; +import com.amazonaws.services.ec2.model.RunInstancesRequest; +import com.amazonaws.services.ec2.model.StartInstancesRequest; +import com.amazonaws.services.ec2.model.StopInstancesRequest; +import com.amazonaws.services.ec2.model.UnmonitorInstancesRequest; + +public class EC2Application { + + private static final AWSCredentials credentials; + + static { + // put your accesskey and secretkey here + credentials = new BasicAWSCredentials( + "", + "" + ); + } + + public static void main(String[] args) { + + // Set up the client + AmazonEC2 ec2Client = AmazonEC2ClientBuilder.standard() + .withCredentials(new AWSStaticCredentialsProvider(credentials)) + .withRegion(Regions.US_EAST_1) + .build(); + + // Create a security group + CreateSecurityGroupRequest createSecurityGroupRequest = new CreateSecurityGroupRequest().withGroupName("BaeldungSecurityGroup") + .withDescription("Baeldung Security Group"); + ec2Client.createSecurityGroup(createSecurityGroupRequest); + + // Allow HTTP and SSH traffic + IpRange ipRange1 = new IpRange().withCidrIp("0.0.0.0/0"); + + IpPermission ipPermission1 = new IpPermission().withIpv4Ranges(Arrays.asList(new IpRange[] { ipRange1 })) + .withIpProtocol("tcp") + .withFromPort(80) + .withToPort(80); + + IpPermission ipPermission2 = new IpPermission().withIpv4Ranges(Arrays.asList(new IpRange[] { ipRange1 })) + .withIpProtocol("tcp") + .withFromPort(22) + .withToPort(22); + + AuthorizeSecurityGroupIngressRequest authorizeSecurityGroupIngressRequest = new AuthorizeSecurityGroupIngressRequest() + .withGroupName("BaeldungSecurityGroup") + .withIpPermissions(ipPermission1, ipPermission2); + + ec2Client.authorizeSecurityGroupIngress(authorizeSecurityGroupIngressRequest); + + // Create KeyPair + CreateKeyPairRequest createKeyPairRequest = new CreateKeyPairRequest() + .withKeyName("baeldung-key-pair"); + CreateKeyPairResult createKeyPairResult = ec2Client.createKeyPair(createKeyPairRequest); + String privateKey = createKeyPairResult + .getKeyPair() + .getKeyMaterial(); // make sure you keep it, the private key, Amazon doesn't store the private key + + // See what key-pairs you've got + DescribeKeyPairsRequest describeKeyPairsRequest = new DescribeKeyPairsRequest(); + DescribeKeyPairsResult describeKeyPairsResult = ec2Client.describeKeyPairs(describeKeyPairsRequest); + + // Launch an Amazon Instance + RunInstancesRequest runInstancesRequest = new RunInstancesRequest().withImageId("ami-97785bed") // https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AMIs.html | https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/usingsharedamis-finding.html + .withInstanceType("t2.micro") // https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-types.html + .withMinCount(1) + .withMaxCount(1) + .withKeyName("baeldung-key-pair") // optional - if not present, can't connect to instance + .withSecurityGroups("BaeldungSecurityGroup"); + + String yourInstanceId = ec2Client.runInstances(runInstancesRequest).getReservation().getInstances().get(0).getInstanceId(); + + // Start an Instance + StartInstancesRequest startInstancesRequest = new StartInstancesRequest() + .withInstanceIds(yourInstanceId); + + ec2Client.startInstances(startInstancesRequest); + + // Monitor Instances + MonitorInstancesRequest monitorInstancesRequest = new MonitorInstancesRequest() + .withInstanceIds(yourInstanceId); + + ec2Client.monitorInstances(monitorInstancesRequest); + + UnmonitorInstancesRequest unmonitorInstancesRequest = new UnmonitorInstancesRequest() + .withInstanceIds(yourInstanceId); + + ec2Client.unmonitorInstances(unmonitorInstancesRequest); + + // Reboot an Instance + + RebootInstancesRequest rebootInstancesRequest = new RebootInstancesRequest() + .withInstanceIds(yourInstanceId); + + ec2Client.rebootInstances(rebootInstancesRequest); + + // Stop an Instance + StopInstancesRequest stopInstancesRequest = new StopInstancesRequest() + .withInstanceIds(yourInstanceId); + + ec2Client.stopInstances(stopInstancesRequest) + .getStoppingInstances() + .get(0) + .getPreviousState() + .getName(); + + // Describe an Instance + DescribeInstancesRequest describeInstancesRequest = new DescribeInstancesRequest(); + DescribeInstancesResult response = ec2Client.describeInstances(describeInstancesRequest); + System.out.println(response.getReservations() + .get(0) + .getInstances() + .get(0) + .getKernelId()); + } +} diff --git a/aws/src/main/java/com/baeldung/s3/MultipartUpload.java b/aws/src/main/java/com/baeldung/s3/MultipartUpload.java new file mode 100644 index 0000000000..711046c112 --- /dev/null +++ b/aws/src/main/java/com/baeldung/s3/MultipartUpload.java @@ -0,0 +1,56 @@ +package com.baeldung.s3; + +import com.amazonaws.AmazonClientException; +import com.amazonaws.auth.DefaultAWSCredentialsProviderChain; +import com.amazonaws.event.ProgressListener; +import com.amazonaws.regions.Regions; +import com.amazonaws.services.s3.AmazonS3; +import com.amazonaws.services.s3.AmazonS3ClientBuilder; +import com.amazonaws.services.s3.model.PutObjectRequest; +import com.amazonaws.services.s3.transfer.TransferManager; +import com.amazonaws.services.s3.transfer.TransferManagerBuilder; +import com.amazonaws.services.s3.transfer.Upload; + +import java.io.File; +import java.util.concurrent.Executors; + +public class MultipartUpload { + + public static void main(String[] args) throws Exception { + String existingBucketName = "baeldung-bucket"; + String keyName = "my-picture.jpg"; + String filePath = "documents/my-picture.jpg"; + + AmazonS3 amazonS3 = AmazonS3ClientBuilder + .standard() + .withCredentials(new DefaultAWSCredentialsProviderChain()) + .withRegion(Regions.DEFAULT_REGION) + .build(); + + int maxUploadThreads = 5; + + TransferManager tm = TransferManagerBuilder + .standard() + .withS3Client(amazonS3) + .withMultipartUploadThreshold((long) (5 * 1024 * 1024)) + .withExecutorFactory(() -> Executors.newFixedThreadPool(maxUploadThreads)) + .build(); + + ProgressListener progressListener = + progressEvent -> System.out.println("Transferred bytes: " + progressEvent.getBytesTransferred()); + + PutObjectRequest request = new PutObjectRequest(existingBucketName, keyName, new File(filePath)); + + request.setGeneralProgressListener(progressListener); + + Upload upload = tm.upload(request); + + try { + upload.waitForCompletion(); + System.out.println("Upload complete."); + } catch (AmazonClientException e) { + System.out.println("Error occurred while uploading file"); + e.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/aws/src/test/java/com/baeldung/s3/MultipartUploadTest.java b/aws/src/test/java/com/baeldung/s3/MultipartUploadTest.java new file mode 100644 index 0000000000..bc8d517a0e --- /dev/null +++ b/aws/src/test/java/com/baeldung/s3/MultipartUploadTest.java @@ -0,0 +1,61 @@ +package com.baeldung.s3; + +import com.amazonaws.event.ProgressListener; +import com.amazonaws.services.s3.AmazonS3; +import com.amazonaws.services.s3.model.PutObjectRequest; +import com.amazonaws.services.s3.model.PutObjectResult; +import com.amazonaws.services.s3.transfer.TransferManager; +import com.amazonaws.services.s3.transfer.TransferManagerBuilder; +import com.amazonaws.services.s3.transfer.Upload; +import org.junit.Before; +import org.junit.Test; + +import java.io.File; +import java.util.concurrent.Executors; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +public class MultipartUploadTest { + + private static final String BUCKET_NAME = "bucket_name"; + private static final String KEY_NAME = "picture.jpg"; + + private AmazonS3 amazonS3; + private TransferManager tm; + private ProgressListener progressListener; + + @Before + public void setup() { + amazonS3 = mock(AmazonS3.class); + tm = TransferManagerBuilder + .standard() + .withS3Client(amazonS3) + .withMultipartUploadThreshold((long) (5 * 1024 * 1025)) + .withExecutorFactory(() -> Executors.newFixedThreadPool(5)) + .build(); + progressListener = + progressEvent -> System.out.println("Transferred bytes: " + progressEvent.getBytesTransferred()); + } + + @Test + public void whenUploadingFileWithTransferManager_thenVerifyUploadRequested() { + File file = mock(File.class); + PutObjectResult s3Result = mock(PutObjectResult.class); + + when(amazonS3.putObject(anyString(), anyString(), (File) any())).thenReturn(s3Result); + when(file.getName()).thenReturn(KEY_NAME); + + PutObjectRequest request = new PutObjectRequest(BUCKET_NAME, KEY_NAME, file); + request.setGeneralProgressListener(progressListener); + + Upload upload = tm.upload(request); + + assertThat(upload).isNotNull(); + verify(amazonS3).putObject(request); + } +} diff --git a/checker-plugin/pom.xml b/checker-plugin/pom.xml new file mode 100644 index 0000000000..bc7a669d4f --- /dev/null +++ b/checker-plugin/pom.xml @@ -0,0 +1,114 @@ + + 4.0.0 + com.baeldung + checker-plugin + jar + 1.0-SNAPSHOT + checker-plugin + http://maven.apache.org + + + + + + ${org.checkerframework:jdk8:jar} + + + + + + + + + + org.checkerframework + checker-qual + 2.3.1 + + + org.checkerframework + checker + 2.3.1 + + + org.checkerframework + jdk8 + 2.3.1 + + + + org.checkerframework + compiler + 2.3.1 + + + + + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + + + properties + + + + + + + maven-compiler-plugin + 3.6.1 + + 1.8 + 1.8 + + + + 10000 + 10000 + + + + org.checkerframework.checker.nullness.NullnessChecker + org.checkerframework.checker.interning.InterningChecker + org.checkerframework.checker.fenum.FenumChecker + org.checkerframework.checker.formatter.FormatterChecker + org.checkerframework.checker.regex.RegexChecker + + + -AprintErrorStack + + + -Xbootclasspath/p:${annotatedJdk} + + + + + + -Awarns + + + + + + + diff --git a/checker-plugin/src/main/java/com/baeldung/typechecker/FakeNumExample.java b/checker-plugin/src/main/java/com/baeldung/typechecker/FakeNumExample.java new file mode 100644 index 0000000000..f1769cfdea --- /dev/null +++ b/checker-plugin/src/main/java/com/baeldung/typechecker/FakeNumExample.java @@ -0,0 +1,42 @@ +package com.baeldung.typechecker; + +import org.checkerframework.checker.fenum.qual.Fenum; + +//@SuppressWarnings("fenum:assignment.type.incompatible") +public class FakeNumExample { + + // Here we use some String constants to represents countries. + static final @Fenum("country") String ITALY = "IT"; + static final @Fenum("country") String US = "US"; + static final @Fenum("country") String UNITED_KINGDOM = "UK"; + + // Here we use other String constants to represent planets instead. + static final @Fenum("planet") String MARS = "Mars"; + static final @Fenum("planet") String EARTH = "Earth"; + static final @Fenum("planet") String VENUS = "Venus"; + + // Now we write this method and we want to be sure that + // the String parameter has a value of a country, not that is just a String. + void greetCountries(@Fenum("country") String country) { + System.out.println("Hello " + country); + } + + // Similarly we're enforcing here that the provided + // parameter is a String that represent a planet. + void greetPlanets(@Fenum("planet") String planet) { + System.out.println("Hello " + planet); + } + + public static void main(String[] args) { + + FakeNumExample obj = new FakeNumExample(); + + // This will fail because we pass a planet-String to a method that + // accept a country-String. + obj.greetCountries(MARS); + + // Here the opposite happens. + obj.greetPlanets(US); + } + +} diff --git a/checker-plugin/src/main/java/com/baeldung/typechecker/FormatExample.java b/checker-plugin/src/main/java/com/baeldung/typechecker/FormatExample.java new file mode 100644 index 0000000000..2fa53ff2c2 --- /dev/null +++ b/checker-plugin/src/main/java/com/baeldung/typechecker/FormatExample.java @@ -0,0 +1,23 @@ +package com.baeldung.typechecker; + +public class FormatExample { + + public static void main(String[] args) { + + // Just enabling org.checkerframework.checker.formatter.FormatterChecker + // we can be sure at compile time that the format strings we pass to format() + // are correct. Normally we would have those errors raised just at runtime. + // All those formats are in fact wrong. + + String.format("%y", 7); // error: invalid format string + + String.format("%d", "a string"); // error: invalid argument type for %d + + String.format("%d %s", 7); // error: missing argument for %s + + String.format("%d", 7, 3); // warning: unused argument 3 + + String.format("{0}", 7); // warning: unused argument 7, because {0} is wrong syntax + } + +} diff --git a/checker-plugin/src/main/java/com/baeldung/typechecker/KeyForExample.java b/checker-plugin/src/main/java/com/baeldung/typechecker/KeyForExample.java new file mode 100644 index 0000000000..b3072b72ee --- /dev/null +++ b/checker-plugin/src/main/java/com/baeldung/typechecker/KeyForExample.java @@ -0,0 +1,31 @@ +package com.baeldung.typechecker; + +import org.checkerframework.checker.nullness.qual.KeyFor; + +import java.util.HashMap; +import java.util.Map; + +public class KeyForExample { + + private final Map config = new HashMap<>(); + + KeyForExample() { + + // Here we initialize a map to store + // some config data. + config.put("url", "http://1.2.3.4"); + config.put("name", "foobaz"); + } + + public void dumpPort() { + + // Here, we want to dump the port value stored in the + // config, so we declare that this key has to be + // present in the config map. + // Obviously that will fail because such key is not present + // in the map. + @KeyFor("config") String key = "port"; + System.out.println( config.get(key) ); + } + +} diff --git a/checker-plugin/src/main/java/com/baeldung/typechecker/MonotonicNotNullExample.java b/checker-plugin/src/main/java/com/baeldung/typechecker/MonotonicNotNullExample.java new file mode 100644 index 0000000000..c4b9c6afe1 --- /dev/null +++ b/checker-plugin/src/main/java/com/baeldung/typechecker/MonotonicNotNullExample.java @@ -0,0 +1,28 @@ +package com.baeldung.typechecker; + +import org.checkerframework.checker.nullness.qual.MonotonicNonNull; + +import java.util.Date; + +public class MonotonicNotNullExample { + + // The idea is we need this field to be to lazily initialized, + // so it starts as null but once it becomes not null + // it cannot return null. + // In these cases, we can use @MonotonicNonNull + @MonotonicNonNull private Date firstCall; + + public Date getFirstCall() { + if (firstCall == null) { + firstCall = new Date(); + } + return firstCall; + } + + public void reset() { + // This is reported as error because + // we wrongly set the field back to null. + firstCall = null; + } + +} diff --git a/checker-plugin/src/main/java/com/baeldung/typechecker/NonNullExample.java b/checker-plugin/src/main/java/com/baeldung/typechecker/NonNullExample.java new file mode 100644 index 0000000000..c929eea23f --- /dev/null +++ b/checker-plugin/src/main/java/com/baeldung/typechecker/NonNullExample.java @@ -0,0 +1,27 @@ +package com.baeldung.typechecker; + +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; + +public class NonNullExample { + + // This method's parameter is annotated in order + // to tell the pluggable type system that it can never be null. + private static int countArgs(@NonNull String[] args) { + return args.length; + } + + // This method's parameter is annotated in order + // to tell the pluggable type system that it may be null. + public static void main(@Nullable String[] args) { + + // Here lies a potential error, + // because we pass a potential null reference to a method + // that does not accept nulls. + // The Checker Framework will spot this problem at compile time + // instead of runtime. + System.out.println(countArgs(args)); + + } + +} diff --git a/checker-plugin/src/main/java/com/baeldung/typechecker/RegexExample.java b/checker-plugin/src/main/java/com/baeldung/typechecker/RegexExample.java new file mode 100644 index 0000000000..9503865214 --- /dev/null +++ b/checker-plugin/src/main/java/com/baeldung/typechecker/RegexExample.java @@ -0,0 +1,18 @@ +package com.baeldung.typechecker; + +import org.checkerframework.checker.regex.qual.Regex; + +public class RegexExample { + + // For some reason we want to be sure that this regex + // contains at least one capturing group. + // However, we do an error and we forgot to define such + // capturing group in it. + @Regex(1) private static String findNumbers = "\\d*"; + + public static void main(String[] args) { + String message = "My phone number is +3911223344."; + message.matches(findNumbers); + } + +} diff --git a/intelliJ/README.md b/core-groovy/README.md similarity index 66% rename from intelliJ/README.md rename to core-groovy/README.md index ff12555376..5954a8ab7e 100644 --- a/intelliJ/README.md +++ b/core-groovy/README.md @@ -1 +1,4 @@ +# Groovy + ## Relevant articles: + diff --git a/core-groovy/build.gradle b/core-groovy/build.gradle new file mode 100644 index 0000000000..300827ee7c --- /dev/null +++ b/core-groovy/build.gradle @@ -0,0 +1,13 @@ +group 'com.baeldung' +version '1.0-SNAPSHOT' + +apply plugin: 'groovy' + +repositories { + mavenCentral() +} + +dependencies { + compile 'org.codehaus.groovy:groovy-all:2.4.13' + testCompile 'org.spockframework:spock-core:1.1-groovy-2.4' +} diff --git a/core-groovy/pom.xml b/core-groovy/pom.xml new file mode 100644 index 0000000000..91cbe66e35 --- /dev/null +++ b/core-groovy/pom.xml @@ -0,0 +1,128 @@ + + + 4.0.0 + + core-groovy + 1.0-SNAPSHOT + jar + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + + + + + central + http://jcenter.bintray.com + + + + + + org.codehaus.groovy + groovy + 2.4.13 + + + org.codehaus.groovy + groovy-all + 2.4.13 + + + org.codehaus.groovy + groovy-sql + 2.4.13 + + + org.junit.jupiter + junit-jupiter-engine + ${junit.jupiter.version} + test + + + org.junit.platform + junit-platform-runner + ${junit.platform.version} + test + + + org.hsqldb + hsqldb + 2.4.0 + test + + + org.spockframework + spock-core + 1.1-groovy-2.4 + test + + + + + + + org.codehaus.gmavenplus + gmavenplus-plugin + 1.6 + + + + addSources + addTestSources + compile + compileTests + + + + + + maven-surefire-plugin + ${maven-surefire-plugin.version} + + + maven-failsafe-plugin + 2.19.1 + + + org.junit.platform + junit-platform-surefire-provider + ${junit.platform.version} + + + + + junit5 + + integration-test + verify + + + + **/*Test5.java + + + + + + + + + + UTF-8 + 1.1.2 + 1.1.2 + 1.1.2 + 1.1.2 + 0.15 + 1.5.0 + + 5.0.0 + 1.0.0 + 4.12.0 + 4.12 + + + diff --git a/core-groovy/src/main/groovy/com/baeldung/json/Account.groovy b/core-groovy/src/main/groovy/com/baeldung/json/Account.groovy new file mode 100644 index 0000000000..84b294f0bd --- /dev/null +++ b/core-groovy/src/main/groovy/com/baeldung/json/Account.groovy @@ -0,0 +1,7 @@ +package com.baeldung.json + +class Account { + String id + BigDecimal value + Date createdAt +} \ No newline at end of file diff --git a/core-groovy/src/main/groovy/com/baeldung/json/JsonParser.groovy b/core-groovy/src/main/groovy/com/baeldung/json/JsonParser.groovy new file mode 100644 index 0000000000..6cda7c6fbd --- /dev/null +++ b/core-groovy/src/main/groovy/com/baeldung/json/JsonParser.groovy @@ -0,0 +1,27 @@ +package com.baeldung.json + +import groovy.json.JsonOutput +import groovy.json.JsonParserType +import groovy.json.JsonSlurper + +class JsonParser { + + Account toObject(String json) { + JsonSlurper jsonSlurper = new JsonSlurper() + jsonSlurper.parseText(json) as Account + } + + Account toObjectWithIndexOverlay(String json) { + JsonSlurper jsonSlurper = new JsonSlurper(type: JsonParserType.INDEX_OVERLAY) + jsonSlurper.parseText(json) as Account + } + + String toJson(Account account) { + JsonOutput.toJson(account) + } + + String prettyfy(String json) { + JsonOutput.prettyPrint(json) + } + +} diff --git a/core-groovy/src/test/groovy/com/baeldung/groovy/sql/SqlTest.groovy b/core-groovy/src/test/groovy/com/baeldung/groovy/sql/SqlTest.groovy new file mode 100644 index 0000000000..ac96a55773 --- /dev/null +++ b/core-groovy/src/test/groovy/com/baeldung/groovy/sql/SqlTest.groovy @@ -0,0 +1,229 @@ +package com.baeldung.groovy.sql + +import groovy.sql.GroovyResultSet +import groovy.sql.GroovyRowResult +import groovy.sql.Sql +import groovy.transform.CompileStatic +import static org.junit.Assert.* +import org.junit.Test + +class SqlTest { + + final Map dbConnParams = [url: 'jdbc:hsqldb:mem:testDB', user: 'sa', password: '', driver: 'org.hsqldb.jdbc.JDBCDriver'] + + @Test + void whenNewSqlInstance_thenDbIsAccessed() { + def sql = Sql.newInstance(dbConnParams) + sql.close() + sql.close() + } + + @Test + void whenTableDoesNotExist_thenSelectFails() { + try { + Sql.withInstance(dbConnParams) { Sql sql -> + sql.eachRow('select * from PROJECT') {} + } + + fail("An exception should have been thrown") + } catch (ignored) { + //Ok + } + } + + @Test + void whenTableCreated_thenSelectIsPossible() { + Sql.withInstance(dbConnParams) { Sql sql -> + def result = sql.execute 'create table PROJECT_1 (id integer not null, name varchar(50), url varchar(100))' + + assertEquals(0, sql.updateCount) + assertFalse(result) + + result = sql.execute('select * from PROJECT_1') + + assertTrue(result) + } + } + + @Test + void whenIdentityColumn_thenInsertReturnsNewId() { + Sql.withInstance(dbConnParams) { Sql sql -> + sql.execute 'create table PROJECT_2 (ID IDENTITY, NAME VARCHAR (50), URL VARCHAR (100))' + def ids = sql.executeInsert("INSERT INTO PROJECT_2 (NAME, URL) VALUES ('tutorials', 'github.com/eugenp/tutorials')") + + assertEquals(0, ids[0][0]) + + ids = sql.executeInsert("INSERT INTO PROJECT_2 (NAME, URL) VALUES ('REST with Spring', 'github.com/eugenp/REST-With-Spring')") + + assertEquals(1, ids[0][0]) + } + } + + @Test + void whenUpdate_thenNumberOfAffectedRows() { + Sql.withInstance(dbConnParams) { Sql sql -> + sql.execute 'create table PROJECT_3 (ID IDENTITY, NAME VARCHAR (50), URL VARCHAR (100))' + sql.executeInsert("INSERT INTO PROJECT_3 (NAME, URL) VALUES ('tutorials', 'github.com/eugenp/tutorials')") + sql.executeInsert("INSERT INTO PROJECT_3 (NAME, URL) VALUES ('REST with Spring', 'github.com/eugenp/REST-With-Spring')") + def count = sql.executeUpdate("UPDATE PROJECT_3 SET URL = 'https://' + URL") + + assertEquals(2, count) + } + } + + @Test + void whenEachRow_thenResultSetHasProperties() { + Sql.withInstance(dbConnParams) { Sql sql -> + sql.execute 'create table PROJECT_4 (ID IDENTITY, NAME VARCHAR (50), URL VARCHAR (100))' + sql.executeInsert("INSERT INTO PROJECT_4 (NAME, URL) VALUES ('tutorials', 'https://github.com/eugenp/tutorials')") + sql.executeInsert("INSERT INTO PROJECT_4 (NAME, URL) VALUES ('REST with Spring', 'https://github.com/eugenp/REST-With-Spring')") + + sql.eachRow("SELECT * FROM PROJECT_4") { GroovyResultSet rs -> + assertNotNull(rs.name) + assertNotNull(rs.url) + assertNotNull(rs[0]) + assertNotNull(rs[1]) + assertNotNull(rs[2]) + assertEquals(rs.name, rs['name']) + assertEquals(rs.url, rs['url']) + } + } + } + + @Test + void whenPagination_thenSubsetIsReturned() { + Sql.withInstance(dbConnParams) { Sql sql -> + sql.execute 'create table PROJECT_5 (ID IDENTITY, NAME VARCHAR (50), URL VARCHAR (100))' + sql.executeInsert("INSERT INTO PROJECT_5 (NAME, URL) VALUES ('tutorials', 'github.com/eugenp/tutorials')") + sql.executeInsert("INSERT INTO PROJECT_5 (NAME, URL) VALUES ('REST with Spring', 'github.com/eugenp/REST-With-Spring')") + def rows = sql.rows('SELECT * FROM PROJECT_5 ORDER BY NAME', 1, 1) + + assertEquals(1, rows.size()) + assertEquals('REST with Spring', rows[0].name) + } + } + + @Test + void whenParameters_thenReplacement() { + Sql.withInstance(dbConnParams) { Sql sql -> + sql.execute 'create table PROJECT_6 (ID IDENTITY, NAME VARCHAR (50), URL VARCHAR (100))' + sql.execute('INSERT INTO PROJECT_6 (NAME, URL) VALUES (?, ?)', 'tutorials', 'github.com/eugenp/tutorials') + sql.execute("INSERT INTO PROJECT_6 (NAME, URL) VALUES (:name, :url)", [name: 'REST with Spring', url: 'github.com/eugenp/REST-With-Spring']) + + def rows = sql.rows("SELECT * FROM PROJECT_6 WHERE NAME = 'tutorials'") + + assertEquals(1, rows.size()) + + rows = sql.rows("SELECT * FROM PROJECT_6 WHERE NAME = 'REST with Spring'") + + assertEquals(1, rows.size()) + } + } + + @Test + void whenParametersInGString_thenReplacement() { + Sql.withInstance(dbConnParams) { Sql sql -> + sql.execute 'create table PROJECT_7 (ID IDENTITY, NAME VARCHAR (50), URL VARCHAR (100))' + sql.execute "INSERT INTO PROJECT_7 (NAME, URL) VALUES (${'tutorials'}, ${'github.com/eugenp/tutorials'})" + def name = 'REST with Spring' + def url = 'github.com/eugenp/REST-With-Spring' + sql.execute "INSERT INTO PROJECT_7 (NAME, URL) VALUES (${name}, ${url})" + + def rows = sql.rows("SELECT * FROM PROJECT_7 WHERE NAME = 'tutorials'") + + assertEquals(1, rows.size()) + + rows = sql.rows("SELECT * FROM PROJECT_7 WHERE NAME = 'REST with Spring'") + + assertEquals(1, rows.size()) + } + } + + @Test + void whenTransactionRollback_thenNoDataInserted() { + Sql.withInstance(dbConnParams) { Sql sql -> + sql.withTransaction { + sql.execute 'create table PROJECT_8 (ID IDENTITY, NAME VARCHAR (50), URL VARCHAR (100))' + sql.executeInsert("INSERT INTO PROJECT_8 (NAME, URL) VALUES ('tutorials', 'https://github.com/eugenp/tutorials')") + sql.executeInsert("INSERT INTO PROJECT_8 (NAME, URL) VALUES ('REST with Spring', 'https://github.com/eugenp/REST-With-Spring')") + sql.rollback() + + def rows = sql.rows("SELECT * FROM PROJECT_8") + + assertEquals(0, rows.size()) + } + } + } + + @Test + void whenTransactionRollbackThenCommit_thenOnlyLastInserted() { + Sql.withInstance(dbConnParams) { Sql sql -> + sql.withTransaction { + sql.execute 'create table PROJECT_9 (ID IDENTITY, NAME VARCHAR (50), URL VARCHAR (100))' + sql.executeInsert("INSERT INTO PROJECT_9 (NAME, URL) VALUES ('tutorials', 'https://github.com/eugenp/tutorials')") + sql.rollback() + sql.executeInsert("INSERT INTO PROJECT_9 (NAME, URL) VALUES ('REST with Spring', 'https://github.com/eugenp/REST-With-Spring')") + sql.rollback() + sql.executeInsert("INSERT INTO PROJECT_9 (NAME, URL) VALUES ('tutorials', 'https://github.com/eugenp/tutorials')") + sql.executeInsert("INSERT INTO PROJECT_9 (NAME, URL) VALUES ('REST with Spring', 'https://github.com/eugenp/REST-With-Spring')") + } + + def rows = sql.rows("SELECT * FROM PROJECT_9") + + assertEquals(2, rows.size()) + } + } + + @Test + void whenException_thenTransactionIsRolledBack() { + Sql.withInstance(dbConnParams) { Sql sql -> + try { + sql.withTransaction { + sql.execute 'create table PROJECT_10 (ID IDENTITY, NAME VARCHAR (50), URL VARCHAR (100))' + sql.executeInsert("INSERT INTO PROJECT_10 (NAME, URL) VALUES ('tutorials', 'https://github.com/eugenp/tutorials')") + throw new Exception('rollback') + } + } catch (ignored) {} + + def rows = sql.rows("SELECT * FROM PROJECT_10") + + assertEquals(0, rows.size()) + } + } + + @Test + void givenCachedConnection_whenException_thenDataIsPersisted() { + Sql.withInstance(dbConnParams) { Sql sql -> + try { + sql.cacheConnection { + sql.execute 'create table PROJECT_11 (ID IDENTITY, NAME VARCHAR (50), URL VARCHAR (100))' + sql.executeInsert("INSERT INTO PROJECT_11 (NAME, URL) VALUES ('tutorials', 'https://github.com/eugenp/tutorials')") + throw new Exception('This does not rollback') + } + } catch (ignored) {} + + def rows = sql.rows("SELECT * FROM PROJECT_11") + + assertEquals(1, rows.size()) + } + } + + /*@Test + void whenModifyResultSet_thenDataIsChanged() { + Sql.withInstance(dbConnParams) { Sql sql -> + sql.execute 'create table PROJECT_5 (ID IDENTITY, NAME VARCHAR (50), URL VARCHAR (100))' + sql.executeInsert("INSERT INTO PROJECT_5 (NAME, URL) VALUES ('tutorials', 'github.com/eugenp/tutorials')") + sql.executeInsert("INSERT INTO PROJECT_5 (NAME, URL) VALUES ('REST with Spring', 'github.com/eugenp/REST-With-Spring')") + + sql.eachRow("SELECT * FROM PROJECT_5 FOR UPDATE ") { GroovyResultSet rs -> + rs['name'] = "The great ${rs.name}!" as String + rs.updateRow() + } + + sql.eachRow("SELECT * FROM PROJECT_5") { GroovyResultSet rs -> + assertTrue(rs.name.startsWith('The great ')) + } + } + }*/ + +} diff --git a/core-groovy/src/test/groovy/com/baeldung/json/JsonParserTest.groovy b/core-groovy/src/test/groovy/com/baeldung/json/JsonParserTest.groovy new file mode 100644 index 0000000000..c3842340a5 --- /dev/null +++ b/core-groovy/src/test/groovy/com/baeldung/json/JsonParserTest.groovy @@ -0,0 +1,66 @@ +package com.baeldung.json + +import spock.lang.Specification + +import java.text.SimpleDateFormat + +class JsonParserTest extends Specification { + + JsonParser jsonParser + + void setup () { + jsonParser = new JsonParser() + } + + def 'Should parse to Account given Json String' () { + given: + def json = '{"id":"1234","value":15.6}' + when: + def account = jsonParser.toObject(json) + then: + account + account instanceof Account + account.id == '1234' + account.value == 15.6 + } + + def 'Should parse to Account given Json String with date property' () { + given: + def json = '{"id":"1234","value":15.6,"createdAt":"2018-01-01T00:00:00+0000"}' + when: + def account = jsonParser.toObjectWithIndexOverlay(json) + then: + account + account instanceof Account + account.id == '1234' + account.value == 15.6 + println account.createdAt + account.createdAt == Date.parse('yyyy-MM-dd', '2018-01-01') + } + + def 'Should parse to Json given an Account object' () { + given: + Account account = new Account( + id: '123', + value: 15.6, + createdAt: new SimpleDateFormat('MM/dd/yyyy').parse('01/01/2018') + ) + when: + def json = jsonParser.toJson(account) + then: + json + json == '{"value":15.6,"createdAt":"2018-01-01T00:00:00+0000","id":"123"}' + } + + def 'Should prettify given a json string' () { + given: + String json = '{"value":15.6,"createdAt":"01/01/2018","id":"123456"}' + when: + def jsonPretty = jsonParser.prettyfy(json) + then: + jsonPretty + jsonPretty == '{\n "value": 15.6,\n "createdAt": "01/01/2018",\n "id": "123456"\n}' + } + + +} diff --git a/core-java-8/README.md b/core-java-8/README.md index 9260e3d447..949577df19 100644 --- a/core-java-8/README.md +++ b/core-java-8/README.md @@ -40,3 +40,6 @@ - [Efficient Word Frequency Calculator in Java](http://www.baeldung.com/java-word-frequency) - [Primitive Type Streams in Java 8](http://www.baeldung.com/java-8-primitive-streams) - [Fail-Safe Iterator vs Fail-Fast Iterator](http://www.baeldung.com/java-fail-safe-vs-fail-fast-iterator) +- [Shuffling Collections In Java](http://www.baeldung.com/java-shuffle-collection) +- [Java 8 StringJoiner](http://www.baeldung.com/java-string-joiner) +- [Introduction to Spliterator in Java](http://www.baeldung.com/java-spliterator) diff --git a/core-java-8/src/main/java/com/baeldung/findanelement/FindElementInAList.java b/core-java-8/src/main/java/com/baeldung/findanelement/FindElementInAList.java new file mode 100644 index 0000000000..2f402ee72b --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/findanelement/FindElementInAList.java @@ -0,0 +1,71 @@ +package com.baeldung.findanelement; + +import java.util.List; +import java.util.ListIterator; +import org.apache.commons.collections4.IterableUtils; +import com.google.common.base.Predicate; +import com.google.common.collect.Iterables; + +public class FindElementInAList { + + public T findUsingIndexOf(T element, List list) { + int index = list.indexOf(element); + if (index >= 0) { + return element; + } + return null; + } + + public boolean findUsingListIterator(T element, List list) { + ListIterator listIterator = list.listIterator(); + while (listIterator.hasNext()) { + T elementFromList = listIterator.next(); + if (elementFromList.equals(element)) { + return true; + } + } + return false; + } + + public boolean findUsingEnhancedForLoop(T element, List list) { + for (T elementFromList : list) { + if (element.equals(elementFromList)) { + return true; + } + } + return false; + } + + public T findUsingStream(T element, List list) { + return list.stream() + .filter(integer -> integer.equals(element)) + .findFirst() + .orElse(null); + } + + public T findUsingParallelStream(T element, List list) { + return list.parallelStream() + .filter(integer -> integer.equals(element)) + .findAny() + .orElse(null); + } + + public T findUsingGuava(T element, List list) { + T foundElement = Iterables.tryFind(list, new Predicate() { + public boolean apply(T input) { + return element.equals(input); + } + }).orNull(); + return foundElement; + } + + public T findUsingApacheCommon(T element, List list) { + T foundElement = IterableUtils.find(list, new org.apache.commons.collections4.Predicate() { + public boolean evaluate(T input) { + return element.equals(input); + } + }); + return foundElement; + } + +} \ No newline at end of file diff --git a/core-java-8/src/test/java/com/baeldung/findanelement/FindAnElementTest.java b/core-java-8/src/test/java/com/baeldung/findanelement/FindAnElementTest.java new file mode 100644 index 0000000000..1fef2d98e7 --- /dev/null +++ b/core-java-8/src/test/java/com/baeldung/findanelement/FindAnElementTest.java @@ -0,0 +1,116 @@ +package com.baeldung.findanelement; + +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import java.util.ArrayList; +import java.util.List; +import org.junit.Test; + +public class FindAnElementTest { + + private static List scores = new ArrayList<>(); + static { + scores.add(0); + scores.add(1); + scores.add(2); + } + + private static FindElementInAList findElementInAList = new FindElementInAList<>(); + + @Test + public void givenElement_whenFoundUsingIndexOf_thenReturnElement() { + Integer scoreToFind = 1; + Integer score = findElementInAList.findUsingIndexOf(scoreToFind, scores); + assertTrue(score.equals(scoreToFind)); + } + + @Test + public void givenElement_whenNotFoundUsingListIterator_thenReturnNull() { + boolean found = findElementInAList.findUsingListIterator(5, scores); + assertTrue(!found); + } + + @Test + public void givenElement_whenFoundListIterator_thenReturnElement() { + Integer scoreToFind = 1; + boolean found = findElementInAList.findUsingListIterator(scoreToFind, scores); + assertTrue(found); + } + + @Test + public void givenElement_whenNotFoundUsingIndexOf_thenReturnNull() { + Integer score = findElementInAList.findUsingIndexOf(5, scores); + assertNull(score); + } + + @Test + public void givenElement_whenFoundUsingEnhancedForLoop_thenReturnElement() { + Integer scoreToFind = 1; + boolean found = findElementInAList.findUsingEnhancedForLoop(scoreToFind, scores); + assertTrue(found); + } + + @Test + public void givenElement_whenNotFoundUsingEnhancedForLoop_thenReturnNull() { + Integer scoreToFind = 5; + boolean found = findElementInAList.findUsingEnhancedForLoop(scoreToFind, scores); + assertTrue(!found); + } + + @Test + public void givenElement_whenFoundUsingStream_thenReturnElement() { + Integer scoreToFind = 1; + Integer score = findElementInAList.findUsingStream(scoreToFind, scores); + assertTrue(score.equals(scoreToFind)); + } + + @Test + public void givenElement_whenNotFoundUsingStream_thenReturnNull() { + Integer scoreToFind = 5; + Integer score = findElementInAList.findUsingStream(scoreToFind, scores); + assertNull(score); + } + + @Test + public void givenElement_whenFoundUsingParallelStream_thenReturnElement() { + Integer scoreToFind = 1; + Integer score = findElementInAList.findUsingParallelStream(scoreToFind, scores); + assertTrue(score.equals(scoreToFind)); + } + + @Test + public void givenElement_whenNotFoundUsingParallelStream_thenReturnNull() { + Integer scoreToFind = 5; + Integer score = findElementInAList.findUsingParallelStream(scoreToFind, scores); + assertNull(score); + } + + @Test + public void givenElement_whenFoundUsingGuava_thenReturnElement() { + Integer scoreToFind = 1; + Integer score = findElementInAList.findUsingGuava(scoreToFind, scores); + assertTrue(score.equals(scoreToFind)); + } + + @Test + public void givenElement_whenNotFoundUsingGuava_thenReturnNull() { + Integer scoreToFind = 5; + Integer score = findElementInAList.findUsingGuava(scoreToFind, scores); + assertNull(score); + } + + @Test + public void givenElement_whenFoundUsingApacheCommons_thenReturnElement() { + Integer scoreToFind = 1; + Integer score = findElementInAList.findUsingApacheCommon(scoreToFind, scores); + assertTrue(score.equals(scoreToFind)); + } + + @Test + public void givenElement_whenNotFoundUsingApacheCommons_thenReturnNull() { + Integer scoreToFind = 5; + Integer score = findElementInAList.findUsingApacheCommon(scoreToFind, scores); + assertNull(score); + } + +} \ No newline at end of file diff --git a/core-java-8/src/test/java/com/baeldung/math/MathNewMethodsUnitTest.java b/core-java-8/src/test/java/com/baeldung/math/MathNewMethodsUnitTest.java new file mode 100644 index 0000000000..da96376009 --- /dev/null +++ b/core-java-8/src/test/java/com/baeldung/math/MathNewMethodsUnitTest.java @@ -0,0 +1,89 @@ +package com.baeldung.math; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +public class MathNewMethodsUnitTest { + + @Test + public void whenAddExactToInteger_thenExpectCorrectArithmeticResult() { + assertEquals(150, Math.addExact(100, 50)); // Returns 150 + } + + @Test + public void whenSubstractExactFromInteger_thenExpectCorrectArithmeticResult() { + assertEquals(50, Math.subtractExact(100, 50)); // Returns 50 + } + + @Test + public void whenDecrementExactInteger_thenExpectCorrectArithmeticResult() { + assertEquals(99, Math.decrementExact(100)); // Returns 99 + } + + @Test + public void whenIncrementExactToInteger_thenExpectCorrectArithmeticResult() { + assertEquals(101, Math.incrementExact(100)); // Returns 101 + } + + @Test + public void whenMultiplyExactTwoIntegers_thenExpectCorrectArithmeticResult() { + assertEquals(500, Math.multiplyExact(100, 5)); // Returns 500 + } + + @Test + public void whenNegateExactInteger_thenExpectCorrectArithmeticResult() { + assertEquals(-100, Math.negateExact(100)); // Returns -100 + } + + @Test(expected = ArithmeticException.class) + public void whenAddToMaxInteger_thenThrowsArithmeticException() { + Math.addExact(Integer.MAX_VALUE, 1); // Throws ArithmeticException + } + + @Test(expected = ArithmeticException.class) + public void whenDecrementMinInteger_thenThrowsArithmeticException() { + Math.decrementExact(Integer.MIN_VALUE); // Throws ArithmeticException + } + + @Test(expected = ArithmeticException.class) + public void whenIncrementMaxLong_thenThrowsArithmeticException() { + Math.incrementExact(Long.MAX_VALUE); // Throws ArithmeticException + } + + @Test(expected = ArithmeticException.class) + public void whenMultiplyMaxLong_thenThrowsArithmeticException() { + Math.multiplyExact(Long.MAX_VALUE, 2); // Throws ArithmeticException + } + + @Test(expected = ArithmeticException.class) + public void whenNegateMinInteger_thenThrowsArithmeticException() { + Math.negateExact(Integer.MIN_VALUE); // MinInt value: −2.147.483.648, but MaxInt Value: 2.147.483.647 => Throws ArithmeticException + } + + @Test(expected = ArithmeticException.class) + public void whenSubstractFromMinInteger_thenThrowsArithmeticException() { + Math.subtractExact(Integer.MIN_VALUE, 1); + } + + @Test + public void whenFloorDivTwoIntegers_thenExpectCorrectArithmeticResult() { + assertEquals(3, Math.floorDiv(7, 2)); // Exact quotient is 3.5 so floor(3.5) == 3 + assertEquals(-4, Math.floorDiv(-7, 2)); // Exact quotient is -3.5 so floor(-3.5) == -4 + } + + @Test + public void whenModDivTwoIntegers_thenExpectCorrectArithmeticResult() { + assertEquals(2, Math.floorMod(5, 3)); // Returns 2: floorMod for positive numbers returns the same as % operator + assertEquals(1, Math.floorMod(-5, 3)); // Returns 1 and not 2 because floorDiv(-5, 3) is -2 and not -1 and (-2*3) + (1) = -5 + } + + @Test + public void whenNextDownOfDouble_thenExpectCorrectNumber() { + double number = 3.0; + double expected = 2.999999999999; + double delta = 0.00000001; + assertEquals(expected, Math.nextDown(number), delta); // The delta defines the accepted error range + } + +} diff --git a/core-java-8/src/test/java/com/baeldung/shufflingcollections/ShufflingCollectionsUnitTest.java b/core-java-8/src/test/java/com/baeldung/shufflingcollections/ShufflingCollectionsUnitTest.java new file mode 100644 index 0000000000..d013907c9a --- /dev/null +++ b/core-java-8/src/test/java/com/baeldung/shufflingcollections/ShufflingCollectionsUnitTest.java @@ -0,0 +1,70 @@ +package com.baeldung.shufflingcollections; + +import org.junit.Test; + +import java.util.*; +import java.util.stream.Collectors; + +import static org.assertj.core.api.Assertions.assertThat; + +public class ShufflingCollectionsUnitTest { + + @Test + public void whenShufflingList_thenListIsShuffled() { + List students = Arrays.asList("Foo", "Bar", "Baz", "Qux"); + + System.out.println("List before shuffling:"); + System.out.println(students); + + Collections.shuffle(students); + System.out.println("List after shuffling:"); + System.out.println(students); + } + + @Test + public void whenShufflingMapEntries_thenValuesAreShuffled() { + Map studentsById = new HashMap<>(); + studentsById.put(1, "Foo"); + studentsById.put(2, "Bar"); + studentsById.put(3, "Baz"); + studentsById.put(4, "Qux"); + + System.out.println("Students before shuffling:"); + System.out.println(studentsById.values()); + + List> shuffledStudentEntries = new ArrayList<>(studentsById.entrySet()); + Collections.shuffle(shuffledStudentEntries); + + List shuffledStudents = shuffledStudentEntries.stream() + .map(Map.Entry::getValue) + .collect(Collectors.toList()); + + System.out.println("Students after shuffling"); + System.out.println(shuffledStudents); + } + + @Test + public void whenShufflingSet_thenElementsAreShuffled() { + Set students = new HashSet<>(Arrays.asList("Foo", "Bar", "Baz", "Qux")); + + System.out.println("Set before shuffling:"); + System.out.println(students); + + List studentList = new ArrayList<>(students); + + Collections.shuffle(studentList); + System.out.println("Shuffled set elements:"); + System.out.println(studentList); + } + + @Test + public void whenShufflingWithSameRandomness_thenElementsAreShuffledDeterministically() { + List students_1 = Arrays.asList("Foo", "Bar", "Baz", "Qux"); + List students_2 = Arrays.asList("Foo", "Bar", "Baz", "Qux"); + + Collections.shuffle(students_1, new Random(5)); + Collections.shuffle(students_2, new Random(5)); + + assertThat(students_1).isEqualTo(students_2); + } +} diff --git a/core-java-9/src/main/java/com/baeldung/java9/methodhandles/Book.java b/core-java-9/src/main/java/com/baeldung/java9/methodhandles/Book.java new file mode 100644 index 0000000000..479f62cb4e --- /dev/null +++ b/core-java-9/src/main/java/com/baeldung/java9/methodhandles/Book.java @@ -0,0 +1,17 @@ +package com.baeldung.java9.methodhandles; + +public class Book { + + String id; + String title; + + public Book(String id, String title) { + this.id = id; + this.title = title; + } + + @SuppressWarnings("unused") + private String formatBook() { + return id + " > " + title; + } +} diff --git a/core-java-9/src/test/java/com/baeldung/java9/httpclient/SimpleHttpRequestsUnitTest.java b/core-java-9/src/test/java/com/baeldung/java9/httpclient/SimpleHttpRequestsUnitTest.java deleted file mode 100644 index 4a704139a1..0000000000 --- a/core-java-9/src/test/java/com/baeldung/java9/httpclient/SimpleHttpRequestsUnitTest.java +++ /dev/null @@ -1,126 +0,0 @@ -package com.baeldung.java9.httpclient; - -import static java.net.HttpURLConnection.HTTP_OK; -import static org.junit.Assert.assertTrue; - -import java.io.IOException; -import java.net.CookieManager; -import java.net.CookiePolicy; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.http.HttpClient; -import java.net.http.HttpHeaders; -import java.net.http.HttpRequest; -import java.net.http.HttpResponse; -import java.security.NoSuchAlgorithmException; -import java.util.List; -import java.util.Map; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; - -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLParameters; - -import org.junit.Before; -import org.junit.Test; - -public class SimpleHttpRequestsUnitTest { - - private URI httpURI; - - @Before - public void init() throws URISyntaxException { - httpURI = new URI("http://www.baeldung.com/"); - } - - @Test - public void quickGet() throws IOException, InterruptedException, URISyntaxException { - HttpRequest request = HttpRequest.create(httpURI).GET(); - HttpResponse response = request.response(); - int responseStatusCode = response.statusCode(); - String responseBody = response.body(HttpResponse.asString()); - assertTrue("Get response status code is bigger then 400", responseStatusCode < 400); - } - - @Test - public void asynchronousGet() throws URISyntaxException, IOException, InterruptedException, ExecutionException { - HttpRequest request = HttpRequest.create(httpURI).GET(); - long before = System.currentTimeMillis(); - CompletableFuture futureResponse = request.responseAsync(); - futureResponse.thenAccept(response -> { - String responseBody = response.body(HttpResponse.asString()); - }); - HttpResponse resp = futureResponse.get(); - HttpHeaders hs = resp.headers(); - assertTrue("There should be more then 1 header.", hs.map().size() > 1); - } - - @Test - public void postMehtod() throws URISyntaxException, IOException, InterruptedException { - HttpRequest.Builder requestBuilder = HttpRequest.create(httpURI); - requestBuilder.body(HttpRequest.fromString("param1=foo,param2=bar")).followRedirects(HttpClient.Redirect.SECURE); - HttpRequest request = requestBuilder.POST(); - HttpResponse response = request.response(); - int statusCode = response.statusCode(); - assertTrue("HTTP return code", statusCode == HTTP_OK); - } - - @Test - public void configureHttpClient() throws NoSuchAlgorithmException, URISyntaxException, IOException, InterruptedException { - CookieManager cManager = new CookieManager(); - cManager.setCookiePolicy(CookiePolicy.ACCEPT_ORIGINAL_SERVER); - - SSLParameters sslParam = new SSLParameters(new String[] { "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256" }, new String[] { "TLSv1.2" }); - - HttpClient.Builder hcBuilder = HttpClient.create(); - hcBuilder.cookieManager(cManager).sslContext(SSLContext.getDefault()).sslParameters(sslParam); - HttpClient httpClient = hcBuilder.build(); - HttpRequest.Builder reqBuilder = httpClient.request(new URI("https://www.facebook.com")); - - HttpRequest request = reqBuilder.followRedirects(HttpClient.Redirect.ALWAYS).GET(); - HttpResponse response = request.response(); - int statusCode = response.statusCode(); - assertTrue("HTTP return code", statusCode == HTTP_OK); - } - - SSLParameters getDefaultSSLParameters() throws NoSuchAlgorithmException { - SSLParameters sslP1 = SSLContext.getDefault().getSupportedSSLParameters(); - String[] proto = sslP1.getApplicationProtocols(); - String[] cifers = sslP1.getCipherSuites(); - System.out.println(printStringArr(proto)); - System.out.println(printStringArr(cifers)); - return sslP1; - } - - String printStringArr(String... args) { - if (args == null) { - return null; - } - StringBuilder sb = new StringBuilder(); - for (String s : args) { - sb.append(s); - sb.append("\n"); - } - return sb.toString(); - } - - String printHeaders(HttpHeaders h) { - if (h == null) { - return null; - } - - StringBuilder sb = new StringBuilder(); - Map> hMap = h.map(); - for (String k : hMap.keySet()) { - sb.append(k).append(":"); - List l = hMap.get(k); - if (l != null) { - l.forEach(s -> { - sb.append(s).append(","); - }); - } - sb.append("\n"); - } - return sb.toString(); - } -} diff --git a/core-java-9/src/test/java/com/baeldung/java9/methodhandles/MethodHandlesTest.java b/core-java-9/src/test/java/com/baeldung/java9/methodhandles/MethodHandlesTest.java new file mode 100644 index 0000000000..7646755358 --- /dev/null +++ b/core-java-9/src/test/java/com/baeldung/java9/methodhandles/MethodHandlesTest.java @@ -0,0 +1,152 @@ +package com.baeldung.java9.methodhandles; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.*; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; +import java.lang.invoke.WrongMethodTypeException; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.List; + +import org.junit.Test; + +/** + * Test case for the {@link MethodHandles} API + */ +public class MethodHandlesTest { + + @Test + public void givenConcatMethodHandle_whenInvoked_thenCorrectlyConcatenated() throws Throwable { + + MethodHandles.Lookup publicLookup = MethodHandles.publicLookup(); + MethodType mt = MethodType.methodType(String.class, String.class); + MethodHandle concatMH = publicLookup.findVirtual(String.class, "concat", mt); + + String output = (String) concatMH.invoke("Effective ", "Java"); + + assertEquals("Effective Java", output); + } + + @Test + public void givenAsListMethodHandle_whenInvokingWithArguments_thenCorrectlyInvoked() throws Throwable { + MethodHandles.Lookup publicLookup = MethodHandles.publicLookup(); + MethodType mt = MethodType.methodType(List.class, Object[].class); + MethodHandle asListMH = publicLookup.findStatic(Arrays.class, "asList", mt); + + List list = (List) asListMH.invokeWithArguments(1, 2); + + assertThat(Arrays.asList(1, 2), is(list)); + } + + @Test + public void givenConstructorMethodHandle_whenInvoked_thenObjectCreatedCorrectly() throws Throwable { + MethodHandles.Lookup publicLookup = MethodHandles.publicLookup(); + MethodType mt = MethodType.methodType(void.class, String.class); + MethodHandle newIntegerMH = publicLookup.findConstructor(Integer.class, mt); + + Integer integer = (Integer) newIntegerMH.invoke("1"); + + assertEquals(1, integer.intValue()); + } + + @Test + public void givenAFieldWithoutGetter_whenCreatingAGetter_thenCorrectlyInvoked() throws Throwable { + MethodHandles.Lookup lookup = MethodHandles.lookup(); + MethodHandle getTitleMH = lookup.findGetter(Book.class, "title", String.class); + + Book book = new Book("ISBN-1234", "Effective Java"); + + assertEquals("Effective Java", getTitleMH.invoke(book)); + } + + @Test + public void givenPrivateMethod_whenCreatingItsMethodHandle_thenCorrectlyInvoked() throws Throwable { + MethodHandles.Lookup lookup = MethodHandles.lookup(); + Method formatBookMethod = Book.class.getDeclaredMethod("formatBook"); + formatBookMethod.setAccessible(true); + + MethodHandle formatBookMH = lookup.unreflect(formatBookMethod); + + Book book = new Book("ISBN-123", "Java in Action"); + + assertEquals("ISBN-123 > Java in Action", formatBookMH.invoke(book)); + } + + @Test + public void givenReplaceMethod_whenUsingReflectionAndInvoked_thenCorrectlyReplaced() throws Throwable { + Method replaceMethod = String.class.getMethod("replace", char.class, char.class); + + String string = (String) replaceMethod.invoke("jovo", 'o', 'a'); + + assertEquals("java", string); + } + + @Test + public void givenReplaceMethodHandle_whenInvoked_thenCorrectlyReplaced() throws Throwable { + MethodHandles.Lookup publicLookup = MethodHandles.publicLookup(); + MethodType mt = MethodType.methodType(String.class, char.class, char.class); + MethodHandle replaceMH = publicLookup.findVirtual(String.class, "replace", mt); + + String replacedString = (String) replaceMH.invoke("jovo", Character.valueOf('o'), 'a'); + + assertEquals("java", replacedString); + } + + @Test + public void givenReplaceMethodHandle_whenInvokingExact_thenCorrectlyReplaced() throws Throwable { + MethodHandles.Lookup lookup = MethodHandles.lookup(); + MethodType mt = MethodType.methodType(String.class, char.class, char.class); + MethodHandle replaceMH = lookup.findVirtual(String.class, "replace", mt); + + String s = (String) replaceMH.invokeExact("jovo", 'o', 'a'); + + assertEquals("java", s); + } + + @Test + public void givenSumMethodHandle_whenInvokingExact_thenSumIsCorrect() throws Throwable { + MethodHandles.Lookup lookup = MethodHandles.lookup(); + MethodType mt = MethodType.methodType(int.class, int.class, int.class); + MethodHandle sumMH = lookup.findStatic(Integer.class, "sum", mt); + + int sum = (int) sumMH.invokeExact(1, 11); + + assertEquals(12, sum); + } + + @Test(expected = WrongMethodTypeException.class) + public void givenSumMethodHandleAndIncompatibleArguments_whenInvokingExact_thenException() throws Throwable { + MethodHandles.Lookup lookup = MethodHandles.lookup(); + MethodType mt = MethodType.methodType(int.class, int.class, int.class); + MethodHandle sumMH = lookup.findStatic(Integer.class, "sum", mt); + + sumMH.invokeExact(Integer.valueOf(1), 11); + } + + @Test + public void givenSpreadedEqualsMethodHandle_whenInvokedOnArray_thenCorrectlyEvaluated() throws Throwable { + MethodHandles.Lookup publicLookup = MethodHandles.publicLookup(); + MethodType mt = MethodType.methodType(boolean.class, Object.class); + MethodHandle equalsMH = publicLookup.findVirtual(String.class, "equals", mt); + + MethodHandle methodHandle = equalsMH.asSpreader(Object[].class, 2); + + assertTrue((boolean) methodHandle.invoke(new Object[] { "java", "java" })); + assertFalse((boolean) methodHandle.invoke(new Object[] { "java", "jova" })); + } + + @Test + public void givenConcatMethodHandle_whenBindToAString_thenCorrectlyConcatenated() throws Throwable { + MethodHandles.Lookup publicLookup = MethodHandles.publicLookup(); + MethodType mt = MethodType.methodType(String.class, String.class); + MethodHandle concatMH = publicLookup.findVirtual(String.class, "concat", mt); + + MethodHandle bindedConcatMH = concatMH.bindTo("Hello "); + + assertEquals("Hello World!", bindedConcatMH.invoke("World!")); + } +} diff --git a/core-java-concurrency/src/main/java/com/baeldung/concurrent/prioritytaskexecution/Job.java b/core-java-concurrency/src/main/java/com/baeldung/concurrent/prioritytaskexecution/Job.java index a70041ed7d..9900d1c63d 100644 --- a/core-java-concurrency/src/main/java/com/baeldung/concurrent/prioritytaskexecution/Job.java +++ b/core-java-concurrency/src/main/java/com/baeldung/concurrent/prioritytaskexecution/Job.java @@ -16,7 +16,8 @@ public class Job implements Runnable { @Override public void run() { try { - System.out.println("Job:" + jobName + " Priority:" + jobPriority); + System.out.println("Job:" + jobName + + " Priority:" + jobPriority); Thread.sleep(1000); } catch (InterruptedException ignored) { } diff --git a/core-java-concurrency/src/main/java/com/baeldung/concurrent/prioritytaskexecution/PriorityJobScheduler.java b/core-java-concurrency/src/main/java/com/baeldung/concurrent/prioritytaskexecution/PriorityJobScheduler.java index 70fd1710c0..ba55696d5a 100644 --- a/core-java-concurrency/src/main/java/com/baeldung/concurrent/prioritytaskexecution/PriorityJobScheduler.java +++ b/core-java-concurrency/src/main/java/com/baeldung/concurrent/prioritytaskexecution/PriorityJobScheduler.java @@ -9,21 +9,21 @@ import java.util.concurrent.TimeUnit; public class PriorityJobScheduler { private ExecutorService priorityJobPoolExecutor; - private ExecutorService priorityJobScheduler; - private PriorityBlockingQueue priorityQueue; + private ExecutorService priorityJobScheduler = + Executors.newSingleThreadExecutor(); + private PriorityBlockingQueue priorityQueue; public PriorityJobScheduler(Integer poolSize, Integer queueSize) { priorityJobPoolExecutor = Executors.newFixedThreadPool(poolSize); - Comparator jobComparator = Comparator.comparing(Job::getJobPriority); - priorityQueue = new PriorityBlockingQueue(queueSize, - (Comparator) jobComparator); + priorityQueue = new PriorityBlockingQueue(queueSize, + Comparator.comparing(Job::getJobPriority)); - priorityJobScheduler = Executors.newSingleThreadExecutor(); priorityJobScheduler.execute(()->{ while (true) { try { priorityJobPoolExecutor.execute(priorityQueue.take()); } catch (InterruptedException e) { + // exception needs special handling break; } } diff --git a/core-java-concurrency/src/main/java/com/baeldung/concurrent/threadlifecycle/BlockedState.java b/core-java-concurrency/src/main/java/com/baeldung/concurrent/threadlifecycle/BlockedState.java new file mode 100644 index 0000000000..19c6d08c2d --- /dev/null +++ b/core-java-concurrency/src/main/java/com/baeldung/concurrent/threadlifecycle/BlockedState.java @@ -0,0 +1,31 @@ +package com.baeldung.concurrent.threadlifecycle; + +public class BlockedState { + public static void main(String[] args) throws InterruptedException { + Thread t1 = new Thread(new DemoThreadB()); + Thread t2 = new Thread(new DemoThreadB()); + + t1.start(); + t2.start(); + + Thread.sleep(1000); + + System.out.println(t2.getState()); + System.exit(0); + } +} + +class DemoThreadB implements Runnable { + @Override + public void run() { + commonResource(); + } + + public static synchronized void commonResource() { + while(true) { + // Infinite loop to mimic heavy processing + // Thread 't1' won't leave this method + // when Thread 't2' enters this + } + } +} \ No newline at end of file diff --git a/core-java-concurrency/src/main/java/com/baeldung/concurrent/threadlifecycle/NewState.java b/core-java-concurrency/src/main/java/com/baeldung/concurrent/threadlifecycle/NewState.java new file mode 100644 index 0000000000..b524cc5ec7 --- /dev/null +++ b/core-java-concurrency/src/main/java/com/baeldung/concurrent/threadlifecycle/NewState.java @@ -0,0 +1,14 @@ +package com.baeldung.concurrent.threadlifecycle; + +public class NewState implements Runnable { + public static void main(String[] args) { + Runnable runnable = new NewState(); + Thread t = new Thread(runnable); + System.out.println(t.getState()); + } + + @Override + public void run() { + + } +} \ No newline at end of file diff --git a/core-java-concurrency/src/main/java/com/baeldung/concurrent/threadlifecycle/RunnableState.java b/core-java-concurrency/src/main/java/com/baeldung/concurrent/threadlifecycle/RunnableState.java new file mode 100644 index 0000000000..4aa8b36a76 --- /dev/null +++ b/core-java-concurrency/src/main/java/com/baeldung/concurrent/threadlifecycle/RunnableState.java @@ -0,0 +1,15 @@ +package com.baeldung.concurrent.threadlifecycle; + +public class RunnableState implements Runnable { + public static void main(String[] args) { + Runnable runnable = new NewState(); + Thread t = new Thread(runnable); + t.start(); + System.out.println(t.getState()); + } + + @Override + public void run() { + + } +} \ No newline at end of file diff --git a/core-java-concurrency/src/main/java/com/baeldung/concurrent/threadlifecycle/TerminatedState.java b/core-java-concurrency/src/main/java/com/baeldung/concurrent/threadlifecycle/TerminatedState.java new file mode 100644 index 0000000000..7c8884dc22 --- /dev/null +++ b/core-java-concurrency/src/main/java/com/baeldung/concurrent/threadlifecycle/TerminatedState.java @@ -0,0 +1,15 @@ +package com.baeldung.concurrent.threadlifecycle; + +public class TerminatedState implements Runnable { + public static void main(String[] args) throws InterruptedException { + Thread t1 = new Thread(new TerminatedState()); + t1.start(); + Thread.sleep(1000); + System.out.println(t1.getState()); + } + + @Override + public void run() { + // No processing in this block + } +} \ No newline at end of file diff --git a/core-java-concurrency/src/main/java/com/baeldung/concurrent/threadlifecycle/TimedWaitingState.java b/core-java-concurrency/src/main/java/com/baeldung/concurrent/threadlifecycle/TimedWaitingState.java new file mode 100644 index 0000000000..8d005352eb --- /dev/null +++ b/core-java-concurrency/src/main/java/com/baeldung/concurrent/threadlifecycle/TimedWaitingState.java @@ -0,0 +1,25 @@ +package com.baeldung.concurrent.threadlifecycle; + +public class TimedWaitingState { + public static void main(String[] args) throws InterruptedException { + DemoThread obj1 = new DemoThread(); + Thread t1 = new Thread(obj1); + t1.start(); + // The following sleep will give enough time for ThreadScheduler + // to start processing of thread t1 + Thread.sleep(1000); + System.out.println(t1.getState()); + } +} + +class DemoThread implements Runnable { + @Override + public void run() { + try { + Thread.sleep(5000); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + e.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/core-java-concurrency/src/main/java/com/baeldung/concurrent/threadlifecycle/WaitingState.java b/core-java-concurrency/src/main/java/com/baeldung/concurrent/threadlifecycle/WaitingState.java new file mode 100644 index 0000000000..98a6844309 --- /dev/null +++ b/core-java-concurrency/src/main/java/com/baeldung/concurrent/threadlifecycle/WaitingState.java @@ -0,0 +1,35 @@ +package com.baeldung.concurrent.threadlifecycle; + +public class WaitingState implements Runnable { + public static Thread t1; + + public static void main(String[] args) { + t1 = new Thread(new WaitingState()); + t1.start(); + } + + public void run() { + Thread t2 = new Thread(new DemoThreadWS()); + t2.start(); + + try { + t2.join(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + e.printStackTrace(); + } + } +} + +class DemoThreadWS implements Runnable { + public void run() { + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + e.printStackTrace(); + } + + System.out.println(WaitingState.t1.getState()); + } +} \ No newline at end of file diff --git a/core-java-concurrency/src/test/java/com/baeldung/concurrent/prioritytaskexecution/PriorityJobSchedulerUnitTest.java b/core-java-concurrency/src/test/java/com/baeldung/concurrent/prioritytaskexecution/PriorityJobSchedulerUnitTest.java index 902bada3a2..1e67fe45c1 100644 --- a/core-java-concurrency/src/test/java/com/baeldung/concurrent/prioritytaskexecution/PriorityJobSchedulerUnitTest.java +++ b/core-java-concurrency/src/test/java/com/baeldung/concurrent/prioritytaskexecution/PriorityJobSchedulerUnitTest.java @@ -30,7 +30,9 @@ public class PriorityJobSchedulerUnitTest { // delay to avoid job sleep (added for demo) being interrupted try { Thread.sleep(2000); - } catch (InterruptedException ignored) { + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new RuntimeException(e); } pjs.closeScheduler(); diff --git a/core-java-concurrency/src/test/java/com/baeldung/concurrent/stopping/StopThreadTest.java b/core-java-concurrency/src/test/java/com/baeldung/concurrent/stopping/StopThreadManualTest.java similarity index 97% rename from core-java-concurrency/src/test/java/com/baeldung/concurrent/stopping/StopThreadTest.java rename to core-java-concurrency/src/test/java/com/baeldung/concurrent/stopping/StopThreadManualTest.java index af54d6932e..9ea40824ca 100644 --- a/core-java-concurrency/src/test/java/com/baeldung/concurrent/stopping/StopThreadTest.java +++ b/core-java-concurrency/src/test/java/com/baeldung/concurrent/stopping/StopThreadManualTest.java @@ -10,7 +10,7 @@ import org.junit.Test; import com.jayway.awaitility.Awaitility; -public class StopThreadTest { +public class StopThreadManualTest { @Test public void whenStoppedThreadIsStopped() throws InterruptedException { diff --git a/core-java-io/.gitignore b/core-java-io/.gitignore index 3de4cc647e..c61d35324d 100644 --- a/core-java-io/.gitignore +++ b/core-java-io/.gitignore @@ -1,26 +1,5 @@ -*.class - 0.* -#folders# -/target -/neoDb* -/data -/src/main/webapp/WEB-INF/classes -*/META-INF/* -.resourceCache - -# Packaged files # -*.jar -*.war -*.ear - # Files generated by integration tests -*.txt -backup-pom.xml -/bin/ -/temp - -#IntelliJ specific -.idea/ -*.iml \ No newline at end of file +# *.txt +/temp \ No newline at end of file diff --git a/core-java-io/pom.xml b/core-java-io/pom.xml index 9aa8743aa6..b9fdca3502 100644 --- a/core-java-io/pom.xml +++ b/core-java-io/pom.xml @@ -1,5 +1,4 @@ - + 4.0.0 com.baeldung core-java-io @@ -211,16 +210,6 @@ jmh-generator-annprocess 1.19 - - org.springframework - spring-web - 4.3.4.RELEASE - - - org.springframework.boot - spring-boot-starter - 1.5.8.RELEASE - org.hsqldb hsqldb @@ -264,99 +253,6 @@ - - org.apache.maven.plugins - maven-dependency-plugin - - - copy-dependencies - prepare-package - - copy-dependencies - - - ${project.build.directory}/libs - - - - - - - org.apache.maven.plugins - maven-jar-plugin - - - - true - libs/ - org.baeldung.executable.ExecutableMavenJar - - - - - - - org.apache.maven.plugins - maven-assembly-plugin - - - package - - single - - - ${project.basedir} - - - org.baeldung.executable.ExecutableMavenJar - - - - jar-with-dependencies - - - - - - - - org.apache.maven.plugins - maven-shade-plugin - - - - shade - - - true - - - org.baeldung.executable.ExecutableMavenJar - - - - - - - - - com.jolira - onejar-maven-plugin - - - - org.baeldung.executable.ExecutableMavenJar - true - ${project.build.finalName}-onejar.${project.packaging} - - - one-jar - - - - - org.springframework.boot spring-boot-maven-plugin @@ -384,19 +280,19 @@ -Xmx300m -XX:+UseParallelGC -classpath - + com.baeldung.outofmemoryerror.OutOfMemoryGCLimitExceed - + org.apache.maven.plugins maven-javadoc-plugin 3.0.0-M1 1.8 - 1.8 + 1.8 @@ -442,7 +338,7 @@ run-benchmarks - + none exec @@ -452,7 +348,7 @@ java -classpath - + org.openjdk.jmh.Main .* @@ -490,7 +386,7 @@ 1.13 0.6.5 0.9.0 - + 1.3 4.12 diff --git a/core-java-io/src/main/java/com/baeldung/java/nio2/watcher/DirectoryWatcherExample.java b/core-java-io/src/main/java/com/baeldung/java/nio2/watcher/DirectoryWatcherExample.java index 35955032dc..4c35ffdb22 100644 --- a/core-java-io/src/main/java/com/baeldung/java/nio2/watcher/DirectoryWatcherExample.java +++ b/core-java-io/src/main/java/com/baeldung/java/nio2/watcher/DirectoryWatcherExample.java @@ -10,7 +10,7 @@ import java.nio.file.WatchKey; import java.nio.file.WatchService; public class DirectoryWatcherExample { - + public static void main(String[] args) throws IOException, InterruptedException { WatchService watchService = FileSystems.getDefault().newWatchService(); Path path = Paths.get(System.getProperty("user.home")); @@ -25,5 +25,5 @@ public class DirectoryWatcherExample { watchService.close(); } - + } diff --git a/core-java-io/src/main/resources/targetFile.tmp b/core-java-io/src/main/resources/targetFile.tmp deleted file mode 100644 index 20f137b416..0000000000 --- a/core-java-io/src/main/resources/targetFile.tmp +++ /dev/null @@ -1,2 +0,0 @@ -line 1 -a second line \ No newline at end of file diff --git a/core-java-io/src/test/java/com/baeldung/copyfiles/FileCopierTest.java b/core-java-io/src/test/java/com/baeldung/copyfiles/FileCopierTest.java index 973436a26a..6d96d2fc0b 100644 --- a/core-java-io/src/test/java/com/baeldung/copyfiles/FileCopierTest.java +++ b/core-java-io/src/test/java/com/baeldung/copyfiles/FileCopierTest.java @@ -19,52 +19,51 @@ import org.junit.Test; import static org.assertj.core.api.Assertions.*; public class FileCopierTest { - File original = new File("src/test/resources/original.txt"); + File original = new File("src/test/resources/original.txt"); - @Before - public void init() throws IOException { - if (!original.exists()) - Files.createFile(original.toPath()); - } + @Before + public void init() throws IOException { + if (!original.exists()) + Files.createFile(original.toPath()); + } - @Test - public void givenIoAPI_whenCopied_thenCopyExistsWithSameContents() throws IOException { - File copied = new File("src/test/resources/copiedWithIo.txt"); - try (InputStream in = new BufferedInputStream(new FileInputStream(original)); - OutputStream out = new BufferedOutputStream(new FileOutputStream(copied))) { - byte[] buffer = new byte[1024]; - int lengthRead; - while ((lengthRead = in.read(buffer)) > 0) { - out.write(buffer, 0, lengthRead); - out.flush(); - } - } - assertThat(copied).exists(); - assertThat(Files.readAllLines(original.toPath()).equals(Files.readAllLines(copied.toPath()))); - } + @Test + public void givenIoAPI_whenCopied_thenCopyExistsWithSameContents() throws IOException { + File copied = new File("src/test/resources/copiedWithIo.txt"); + try (InputStream in = new BufferedInputStream(new FileInputStream(original)); OutputStream out = new BufferedOutputStream(new FileOutputStream(copied))) { + byte[] buffer = new byte[1024]; + int lengthRead; + while ((lengthRead = in.read(buffer)) > 0) { + out.write(buffer, 0, lengthRead); + out.flush(); + } + } + assertThat(copied).exists(); + assertThat(Files.readAllLines(original.toPath()).equals(Files.readAllLines(copied.toPath()))); + } - @Test - public void givenCommonsIoAPI_whenCopied_thenCopyExistsWithSameContents() throws IOException { - File copied = new File("src/test/resources/copiedWithApacheCommons.txt"); - FileUtils.copyFile(original, copied); - assertThat(copied).exists(); - assertThat(Files.readAllLines(original.toPath()).equals(Files.readAllLines(copied.toPath()))); - } + @Test + public void givenCommonsIoAPI_whenCopied_thenCopyExistsWithSameContents() throws IOException { + File copied = new File("src/test/resources/copiedWithApacheCommons.txt"); + FileUtils.copyFile(original, copied); + assertThat(copied).exists(); + assertThat(Files.readAllLines(original.toPath()).equals(Files.readAllLines(copied.toPath()))); + } - @Test - public void givenNIO2_whenCopied_thenCopyExistsWithSameContents() throws IOException { - Path copied = Paths.get("src/test/resources/copiedWithNio.txt"); - Path originalPath = original.toPath(); - Files.copy(originalPath, copied, StandardCopyOption.REPLACE_EXISTING); - assertThat(copied).exists(); - assertThat(Files.readAllLines(originalPath).equals(Files.readAllLines(copied))); - } + @Test + public void givenNIO2_whenCopied_thenCopyExistsWithSameContents() throws IOException { + Path copied = Paths.get("src/test/resources/copiedWithNio.txt"); + Path originalPath = original.toPath(); + Files.copy(originalPath, copied, StandardCopyOption.REPLACE_EXISTING); + assertThat(copied).exists(); + assertThat(Files.readAllLines(originalPath).equals(Files.readAllLines(copied))); + } - @Test - public void givenGuava_whenCopied_thenCopyExistsWithSameContents() throws IOException { - File copied = new File("src/test/resources/copiedWithApacheCommons.txt"); - com.google.common.io.Files.copy(original, copied); - assertThat(copied).exists(); - assertThat(Files.readAllLines(original.toPath()).equals(Files.readAllLines(copied.toPath()))); - } + @Test + public void givenGuava_whenCopied_thenCopyExistsWithSameContents() throws IOException { + File copied = new File("src/test/resources/copiedWithApacheCommons.txt"); + com.google.common.io.Files.copy(original, copied); + assertThat(copied).exists(); + assertThat(Files.readAllLines(original.toPath()).equals(Files.readAllLines(copied.toPath()))); + } } diff --git a/core-java-io/src/test/java/com/baeldung/file/FileOperationsManualTest.java b/core-java-io/src/test/java/com/baeldung/file/FileOperationsManualTest.java index ea71d1b5c1..7968967679 100644 --- a/core-java-io/src/test/java/com/baeldung/file/FileOperationsManualTest.java +++ b/core-java-io/src/test/java/com/baeldung/file/FileOperationsManualTest.java @@ -3,7 +3,6 @@ package com.baeldung.file; import org.apache.commons.io.FileUtils; import org.hamcrest.CoreMatchers; import org.hamcrest.Matchers; -import org.junit.Assert; import org.junit.Test; import java.io.BufferedReader; diff --git a/core-java-io/src/test/java/com/baeldung/file/FilesTest.java b/core-java-io/src/test/java/com/baeldung/file/FilesTest.java index c5a5b8a3a1..a35cda8b23 100644 --- a/core-java-io/src/test/java/com/baeldung/file/FilesTest.java +++ b/core-java-io/src/test/java/com/baeldung/file/FilesTest.java @@ -42,19 +42,14 @@ public class FilesTest { CharSink chs = com.google.common.io.Files.asCharSink(file, Charsets.UTF_8, FileWriteMode.APPEND); chs.write("Spain\r\n"); - assertThat(StreamUtils.getStringFromInputStream( - new FileInputStream(fileName))) - .isEqualTo("UK\r\n" + "US\r\n" + "Germany\r\n" + "Spain\r\n"); + assertThat(StreamUtils.getStringFromInputStream(new FileInputStream(fileName))).isEqualTo("UK\r\n" + "US\r\n" + "Germany\r\n" + "Spain\r\n"); } - @Test public void whenAppendToFileUsingFiles_thenCorrect() throws IOException { Files.write(Paths.get(fileName), "Spain\r\n".getBytes(), StandardOpenOption.APPEND); - assertThat(StreamUtils.getStringFromInputStream( - new FileInputStream(fileName))) - .isEqualTo("UK\r\n" + "US\r\n" + "Germany\r\n" + "Spain\r\n"); + assertThat(StreamUtils.getStringFromInputStream(new FileInputStream(fileName))).isEqualTo("UK\r\n" + "US\r\n" + "Germany\r\n" + "Spain\r\n"); } @Test @@ -62,9 +57,7 @@ public class FilesTest { File file = new File(fileName); FileUtils.writeStringToFile(file, "Spain\r\n", StandardCharsets.UTF_8, true); - assertThat(StreamUtils.getStringFromInputStream( - new FileInputStream(fileName))) - .isEqualTo("UK\r\n" + "US\r\n" + "Germany\r\n" + "Spain\r\n"); + assertThat(StreamUtils.getStringFromInputStream(new FileInputStream(fileName))).isEqualTo("UK\r\n" + "US\r\n" + "Germany\r\n" + "Spain\r\n"); } @Test @@ -73,9 +66,7 @@ public class FilesTest { fos.write("Spain\r\n".getBytes()); fos.close(); - assertThat(StreamUtils.getStringFromInputStream( - new FileInputStream(fileName))) - .isEqualTo("UK\r\n" + "US\r\n" + "Germany\r\n" + "Spain\r\n"); + assertThat(StreamUtils.getStringFromInputStream(new FileInputStream(fileName))).isEqualTo("UK\r\n" + "US\r\n" + "Germany\r\n" + "Spain\r\n"); } @Test @@ -86,9 +77,6 @@ public class FilesTest { bw.newLine(); bw.close(); - assertThat( - StreamUtils.getStringFromInputStream( - new FileInputStream(fileName))) - .isEqualTo("UK\r\n" + "US\r\n" + "Germany\r\n" + "Spain\n"); + assertThat(StreamUtils.getStringFromInputStream(new FileInputStream(fileName))).isEqualTo("UK\r\n" + "US\r\n" + "Germany\r\n" + "Spain\n"); } } \ No newline at end of file diff --git a/core-java-io/src/test/java/com/baeldung/filesystem/jndi/test/LookupFSJNDIIntegrationTest.java b/core-java-io/src/test/java/com/baeldung/filesystem/jndi/test/LookupFSJNDIIntegrationTest.java index 330ec3aee3..023a47cb97 100644 --- a/core-java-io/src/test/java/com/baeldung/filesystem/jndi/test/LookupFSJNDIIntegrationTest.java +++ b/core-java-io/src/test/java/com/baeldung/filesystem/jndi/test/LookupFSJNDIIntegrationTest.java @@ -35,7 +35,7 @@ public class LookupFSJNDIIntegrationTest { @Test public void givenInitialContext_whenLokupFileExists_thenSuccess() { - File file = fsjndi.getFile(FILENAME); - assertNotNull("File exists", file); + File file = fsjndi.getFile(FILENAME); + assertNotNull("File exists", file); } } diff --git a/core-java-io/src/test/java/com/baeldung/java/nio2/PathManualTest.java b/core-java-io/src/test/java/com/baeldung/java/nio2/PathManualTest.java index acfb2c08e9..969dff1da2 100644 --- a/core-java-io/src/test/java/com/baeldung/java/nio2/PathManualTest.java +++ b/core-java-io/src/test/java/com/baeldung/java/nio2/PathManualTest.java @@ -9,7 +9,6 @@ import java.net.URI; import java.nio.file.NoSuchFileException; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.Date; import org.junit.Test; diff --git a/core-java-io/src/test/java/com/baeldung/java/nio2/async/AsyncFileIntegrationTest.java b/core-java-io/src/test/java/com/baeldung/java/nio2/async/AsyncFileIntegrationTest.java index e2f7a0303a..cf37b92565 100644 --- a/core-java-io/src/test/java/com/baeldung/java/nio2/async/AsyncFileIntegrationTest.java +++ b/core-java-io/src/test/java/com/baeldung/java/nio2/async/AsyncFileIntegrationTest.java @@ -17,18 +17,19 @@ import java.util.concurrent.Future; import static org.junit.Assert.assertEquals; public class AsyncFileIntegrationTest { + @Test public void givenPath_whenReadsContentWithFuture_thenCorrect() throws IOException, ExecutionException, InterruptedException { - Path path = Paths.get(URI.create(this.getClass().getClassLoader().getResource("file.txt").toString())); - AsynchronousFileChannel fileChannel = AsynchronousFileChannel.open(path, StandardOpenOption.READ); + final Path path = Paths.get(URI.create(this.getClass().getClassLoader().getResource("file.txt").toString())); + final AsynchronousFileChannel fileChannel = AsynchronousFileChannel.open(path, StandardOpenOption.READ); - ByteBuffer buffer = ByteBuffer.allocate(1024); + final ByteBuffer buffer = ByteBuffer.allocate(1024); - Future operation = fileChannel.read(buffer, 0); + final Future operation = fileChannel.read(buffer, 0); operation.get(); - String fileContent = new String(buffer.array()).trim(); + final String fileContent = new String(buffer.array()).trim(); buffer.clear(); assertEquals(fileContent, "baeldung.com"); @@ -36,18 +37,16 @@ public class AsyncFileIntegrationTest { @Test public void givenPath_whenReadsContentWithCompletionHandler_thenCorrect() throws IOException { - Path path = Paths.get(URI.create(AsyncFileIntegrationTest.class.getResource("/file.txt").toString())); - AsynchronousFileChannel fileChannel = AsynchronousFileChannel.open(path, StandardOpenOption.READ); + final Path path = Paths.get(URI.create(this.getClass().getClassLoader().getResource("file.txt").toString())); + final AsynchronousFileChannel fileChannel = AsynchronousFileChannel.open(path, StandardOpenOption.READ); - ByteBuffer buffer = ByteBuffer.allocate(1024); + final ByteBuffer buffer = ByteBuffer.allocate(1024); fileChannel.read(buffer, 0, buffer, new CompletionHandler() { - @Override public void completed(Integer result, ByteBuffer attachment) { // result is number of bytes read // attachment is the buffer - } @Override @@ -59,42 +58,40 @@ public class AsyncFileIntegrationTest { @Test public void givenPathAndContent_whenWritesToFileWithFuture_thenCorrect() throws IOException, ExecutionException, InterruptedException { - String fileName = "temp"; - Path path = Paths.get(fileName); - AsynchronousFileChannel fileChannel = AsynchronousFileChannel.open(path, StandardOpenOption.WRITE, StandardOpenOption.CREATE); + final String fileName = "temp"; + final Path path = Paths.get(fileName); + final AsynchronousFileChannel fileChannel = AsynchronousFileChannel.open(path, StandardOpenOption.WRITE, StandardOpenOption.CREATE); - ByteBuffer buffer = ByteBuffer.allocate(1024); - long position = 0; + final ByteBuffer buffer = ByteBuffer.allocate(1024); + final long position = 0; buffer.put("hello world".getBytes()); buffer.flip(); - Future operation = fileChannel.write(buffer, position); + final Future operation = fileChannel.write(buffer, position); buffer.clear(); operation.get(); - String content = readContent(path); + final String content = readContent(path); assertEquals("hello world", content); } @Test public void givenPathAndContent_whenWritesToFileWithHandler_thenCorrect() throws IOException { - String fileName = UUID.randomUUID().toString(); - Path path = Paths.get(fileName); - AsynchronousFileChannel fileChannel = AsynchronousFileChannel.open(path, StandardOpenOption.WRITE, StandardOpenOption.CREATE, StandardOpenOption.DELETE_ON_CLOSE); + final String fileName = UUID.randomUUID().toString(); + final Path path = Paths.get(fileName); + final AsynchronousFileChannel fileChannel = AsynchronousFileChannel.open(path, StandardOpenOption.WRITE, StandardOpenOption.CREATE, StandardOpenOption.DELETE_ON_CLOSE); - ByteBuffer buffer = ByteBuffer.allocate(1024); + final ByteBuffer buffer = ByteBuffer.allocate(1024); buffer.put("hello world".getBytes()); buffer.flip(); fileChannel.write(buffer, 0, buffer, new CompletionHandler() { - @Override public void completed(Integer result, ByteBuffer attachment) { // result is number of bytes written // attachment is the buffer - } @Override @@ -104,23 +101,25 @@ public class AsyncFileIntegrationTest { }); } - public static String readContent(Path file) throws ExecutionException, InterruptedException { + // + + private String readContent(Path file) throws ExecutionException, InterruptedException { AsynchronousFileChannel fileChannel = null; try { fileChannel = AsynchronousFileChannel.open(file, StandardOpenOption.READ); } catch (IOException e) { - // TODO Auto-generated catch block e.printStackTrace(); } - ByteBuffer buffer = ByteBuffer.allocate(1024); + final ByteBuffer buffer = ByteBuffer.allocate(1024); - Future operation = fileChannel.read(buffer, 0); + final Future operation = fileChannel.read(buffer, 0); operation.get(); - String fileContent = new String(buffer.array()).trim(); + final String fileContent = new String(buffer.array()).trim(); buffer.clear(); return fileContent; } + } \ No newline at end of file diff --git a/core-java-io/src/test/java/com/baeldung/java/nio2/attributes/BasicAttribsIntegrationTest.java b/core-java-io/src/test/java/com/baeldung/java/nio2/attributes/BasicAttribsIntegrationTest.java index 9f84aa60d6..4b6302e93c 100644 --- a/core-java-io/src/test/java/com/baeldung/java/nio2/attributes/BasicAttribsIntegrationTest.java +++ b/core-java-io/src/test/java/com/baeldung/java/nio2/attributes/BasicAttribsIntegrationTest.java @@ -20,7 +20,6 @@ public class BasicAttribsIntegrationTest { private static final Logger LOG = LoggerFactory.getLogger(BasicAttribsIntegrationTest.class); - private static final String HOME = System.getProperty("user.home"); private static BasicFileAttributes basicAttribs; diff --git a/core-java-io/src/test/java/com/baeldung/java8/JavaFolderSizeUnitTest.java b/core-java-io/src/test/java/com/baeldung/java8/JavaFolderSizeUnitTest.java index 7f83e379cd..1f3b380772 100644 --- a/core-java-io/src/test/java/com/baeldung/java8/JavaFolderSizeUnitTest.java +++ b/core-java-io/src/test/java/com/baeldung/java8/JavaFolderSizeUnitTest.java @@ -55,12 +55,7 @@ public class JavaFolderSizeUnitTest { @Test public void whenGetFolderSizeUsingJava8_thenCorrect() throws IOException { final Path folder = Paths.get(path); - final long size = Files.walk(folder) - .filter(p -> p.toFile() - .isFile()) - .mapToLong(p -> p.toFile() - .length()) - .sum(); + final long size = Files.walk(folder).filter(p -> p.toFile().isFile()).mapToLong(p -> p.toFile().length()).sum(); assertEquals(EXPECTED_SIZE, size); } @@ -77,12 +72,8 @@ public class JavaFolderSizeUnitTest { public void whenGetFolderSizeUsingGuava_thenCorrect() { final File folder = new File(path); - final Iterable files = com.google.common.io.Files.fileTreeTraverser() - .breadthFirstTraversal(folder); - final long size = StreamSupport.stream(files.spliterator(), false) - .filter(File::isFile) - .mapToLong(File::length) - .sum(); + final Iterable files = com.google.common.io.Files.fileTreeTraverser().breadthFirstTraversal(folder); + final long size = StreamSupport.stream(files.spliterator(), false).filter(File::isFile).mapToLong(File::length).sum(); assertEquals(EXPECTED_SIZE, size); } diff --git a/core-java-io/src/test/java/com/baeldung/mappedbytebuffer/MappedByteBufferUnitTest.java b/core-java-io/src/test/java/com/baeldung/mappedbytebuffer/MappedByteBufferUnitTest.java index 0a0993a0d7..bb87529783 100644 --- a/core-java-io/src/test/java/com/baeldung/mappedbytebuffer/MappedByteBufferUnitTest.java +++ b/core-java-io/src/test/java/com/baeldung/mappedbytebuffer/MappedByteBufferUnitTest.java @@ -18,14 +18,13 @@ import static org.junit.Assert.assertNotNull; public class MappedByteBufferUnitTest { - @Test public void givenFileChannel_whenReadToTheMappedByteBuffer_thenShouldSuccess() throws Exception { - //given + // given CharBuffer charBuffer = null; Path pathToRead = getFileURIFromResources("fileToRead.txt"); - //when + // when try (FileChannel fileChannel = (FileChannel) Files.newByteChannel(pathToRead, EnumSet.of(StandardOpenOption.READ))) { MappedByteBuffer mappedByteBuffer = fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, fileChannel.size()); @@ -34,20 +33,19 @@ public class MappedByteBufferUnitTest { } } - //then + // then assertNotNull(charBuffer); assertEquals(charBuffer.toString(), "This is a content of the file"); } @Test public void givenPath_whenWriteToItUsingMappedByteBuffer_thenShouldSuccessfullyWrite() throws Exception { - //given - CharBuffer charBuffer = CharBuffer.wrap("This will be written to the file"); - Path pathToWrite = getFileURIFromResources("fileToWriteTo.txt"); + // given + final CharBuffer charBuffer = CharBuffer.wrap("This will be written to the file"); + final Path pathToWrite = getFileURIFromResources("fileToWriteTo.txt"); - //when - try (FileChannel fileChannel = (FileChannel) Files.newByteChannel(pathToWrite, - EnumSet.of(StandardOpenOption.READ, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING))) { + // when + try (FileChannel fileChannel = (FileChannel) Files.newByteChannel(pathToWrite, EnumSet.of(StandardOpenOption.READ, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING))) { MappedByteBuffer mappedByteBuffer = fileChannel.map(FileChannel.MapMode.READ_WRITE, 0, charBuffer.length()); if (mappedByteBuffer != null) { @@ -55,14 +53,16 @@ public class MappedByteBufferUnitTest { } } - //then - List fileContent = Files.readAllLines(pathToWrite); + // then + final List fileContent = Files.readAllLines(pathToWrite); assertEquals(fileContent.get(0), "This will be written to the file"); } - private Path getFileURIFromResources(String fileName) throws Exception { - ClassLoader classLoader = getClass().getClassLoader(); + // + + private final Path getFileURIFromResources(String fileName) throws Exception { + final ClassLoader classLoader = getClass().getClassLoader(); return Paths.get(classLoader.getResource(fileName).toURI()); } } diff --git a/core-java-io/src/test/java/com/baeldung/stream/FileCopyTest.java b/core-java-io/src/test/java/com/baeldung/stream/FileCopyTest.java deleted file mode 100644 index 3b915a3829..0000000000 --- a/core-java-io/src/test/java/com/baeldung/stream/FileCopyTest.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.baeldung.stream; - -import static org.junit.Assert.assertTrue; - -import java.io.File; -import java.io.IOException; - -import org.junit.Test; - -public class FileCopyTest { - - @Test - public void whenUsingStream_thenCopyFile() throws IOException { - File src = new File("src" + File.separator + "test" + File.separator + "resources" + File.separator + "copyTest" + File.separator + "src" + File.separator + "test_stream.txt"); - File dest = new File("src" + File.separator + "test" + File.separator + "resources" + File.separator + "copyTest" + File.separator + "dest" + File.separator + "test_stream.txt"); - FileCopy.copyFileUsingStream(src, dest); - assertTrue(dest.exists()); - dest.delete(); - } - - @Test - public void whenUsingFiles_thenCopyFile() throws IOException { - File src = new File("src" + File.separator + "test" + File.separator + "resources" + File.separator + "copyTest" + File.separator + "src" + File.separator + "test_files.txt"); - File dest = new File("src" + File.separator + "test" + File.separator + "resources" + File.separator + "copyTest" + File.separator + "dest" + File.separator + "test_files.txt"); - FileCopy.copyFileUsingJavaFiles(src, dest); - assertTrue(dest.exists()); - dest.delete(); - } - - @Test - public void whenUsingChannel_thenCopyFile() throws IOException { - File src = new File("src" + File.separator + "test" + File.separator + "resources" + File.separator + "copyTest" + File.separator + "src" + File.separator + "test_channel.txt"); - File dest = new File("src" + File.separator + "test" + File.separator + "resources" + File.separator + "copyTest" + File.separator + "dest" + File.separator + "test_channel.txt"); - FileCopy.copyFileUsingChannel(src, dest); - assertTrue(dest.exists()); - dest.delete(); - } - - @Test - public void whenUsingApache_thenCopyFile() throws IOException { - File src = new File("src" + File.separator + "test" + File.separator + "resources" + File.separator + "copyTest" + File.separator + "src" + File.separator + "test_apache.txt"); - File dest = new File("src" + File.separator + "test" + File.separator + "resources" + File.separator + "copyTest" + File.separator + "dest" + File.separator + "test_apache.txt"); - FileCopy.copyFileUsingApacheCommonsIO(src, dest); - assertTrue(dest.exists()); - dest.delete(); - } -} diff --git a/core-java-io/src/test/java/com/baeldung/stream/FileCopyUnitTest.java b/core-java-io/src/test/java/com/baeldung/stream/FileCopyUnitTest.java new file mode 100644 index 0000000000..b4641083b9 --- /dev/null +++ b/core-java-io/src/test/java/com/baeldung/stream/FileCopyUnitTest.java @@ -0,0 +1,52 @@ +package com.baeldung.stream; + +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.io.IOException; + +import org.junit.Test; + +public class FileCopyUnitTest { + + @Test + public void whenUsingStream_thenCopyFile() throws IOException { + final File src = new File("src" + File.separator + "test" + File.separator + "resources" + File.separator + "copyTest" + File.separator + "src" + File.separator + "test_stream.txt"); + final File dest = new File("src" + File.separator + "test" + File.separator + "resources" + File.separator + "copyTest" + File.separator + "dest" + File.separator + "test_stream.txt"); + FileCopy.copyFileUsingStream(src, dest); + + assertTrue(dest.exists()); + dest.delete(); + } + + @Test + public void whenUsingFiles_thenCopyFile() throws IOException { + final File src = new File("src" + File.separator + "test" + File.separator + "resources" + File.separator + "copyTest" + File.separator + "src" + File.separator + "test_files.txt"); + final File dest = new File("src" + File.separator + "test" + File.separator + "resources" + File.separator + "copyTest" + File.separator + "dest" + File.separator + "test_files.txt"); + FileCopy.copyFileUsingJavaFiles(src, dest); + + assertTrue(dest.exists()); + dest.delete(); + } + + @Test + public void whenUsingChannel_thenCopyFile() throws IOException { + final File src = new File("src" + File.separator + "test" + File.separator + "resources" + File.separator + "copyTest" + File.separator + "src" + File.separator + "test_channel.txt"); + final File dest = new File("src" + File.separator + "test" + File.separator + "resources" + File.separator + "copyTest" + File.separator + "dest" + File.separator + "test_channel.txt"); + FileCopy.copyFileUsingChannel(src, dest); + + assertTrue(dest.exists()); + dest.delete(); + } + + @Test + public void whenUsingApache_thenCopyFile() throws IOException { + final File src = new File("src" + File.separator + "test" + File.separator + "resources" + File.separator + "copyTest" + File.separator + "src" + File.separator + "test_apache.txt"); + final File dest = new File("src" + File.separator + "test" + File.separator + "resources" + File.separator + "copyTest" + File.separator + "dest" + File.separator + "test_apache.txt"); + FileCopy.copyFileUsingApacheCommonsIO(src, dest); + + assertTrue(dest.exists()); + dest.delete(); + } + +} diff --git a/core-java-io/src/test/java/org/baeldung/java/io/JavaInputStreamToXUnitTest.java b/core-java-io/src/test/java/org/baeldung/java/io/JavaInputStreamToXUnitTest.java index 0e20e75869..f1bea1eefb 100644 --- a/core-java-io/src/test/java/org/baeldung/java/io/JavaInputStreamToXUnitTest.java +++ b/core-java-io/src/test/java/org/baeldung/java/io/JavaInputStreamToXUnitTest.java @@ -152,11 +152,11 @@ public class JavaInputStreamToXUnitTest { @Test public final void whenConvertingToFile_thenCorrect() throws IOException { - final InputStream initialStream = new FileInputStream(new File("src/main/resources/sample.txt")); + final InputStream initialStream = new FileInputStream(new File("src/test/resources/sample.txt")); final byte[] buffer = new byte[initialStream.available()]; initialStream.read(buffer); - final File targetFile = new File("src/main/resources/targetFile.tmp"); + final File targetFile = new File("src/test/resources/targetFile.tmp"); final OutputStream outStream = new FileOutputStream(targetFile); outStream.write(buffer); @@ -166,8 +166,8 @@ public class JavaInputStreamToXUnitTest { @Test public final void whenConvertingInProgressToFile_thenCorrect() throws IOException { - final InputStream initialStream = new FileInputStream(new File("src/main/resources/sample.txt")); - final File targetFile = new File("src/main/resources/targetFile.tmp"); + final InputStream initialStream = new FileInputStream(new File("src/test/resources/sample.txt")); + final File targetFile = new File("src/test/resources/targetFile.tmp"); final OutputStream outStream = new FileOutputStream(targetFile); final byte[] buffer = new byte[8 * 1024]; @@ -182,8 +182,8 @@ public class JavaInputStreamToXUnitTest { @Test public final void whenConvertingAnInProgressInputStreamToFile_thenCorrect2() throws IOException { - final InputStream initialStream = new FileInputStream(new File("src/main/resources/sample.txt")); - final File targetFile = new File("src/main/resources/targetFile.tmp"); + final InputStream initialStream = new FileInputStream(new File("src/test/resources/sample.txt")); + final File targetFile = new File("src/test/resources/targetFile.tmp"); java.nio.file.Files.copy(initialStream, targetFile.toPath(), StandardCopyOption.REPLACE_EXISTING); @@ -192,11 +192,11 @@ public class JavaInputStreamToXUnitTest { @Test public final void whenConvertingInputStreamToFile_thenCorrect3() throws IOException { - final InputStream initialStream = new FileInputStream(new File("src/main/resources/sample.txt")); + final InputStream initialStream = new FileInputStream(new File("src/test/resources/sample.txt")); final byte[] buffer = new byte[initialStream.available()]; initialStream.read(buffer); - final File targetFile = new File("src/main/resources/targetFile.tmp"); + final File targetFile = new File("src/test/resources/targetFile.tmp"); Files.write(buffer, targetFile); IOUtils.closeQuietly(initialStream); @@ -204,13 +204,13 @@ public class JavaInputStreamToXUnitTest { @Test public final void whenConvertingInputStreamToFile_thenCorrect4() throws IOException { - final InputStream initialStream = FileUtils.openInputStream(new File("src/main/resources/sample.txt")); + final InputStream initialStream = FileUtils.openInputStream(new File("src/test/resources/sample.txt")); - final File targetFile = new File("src/main/resources/targetFile.tmp"); + final File targetFile = new File("src/test/resources/targetFile.tmp"); FileUtils.copyInputStreamToFile(initialStream, targetFile); } - + @Test public final void givenUsingPlainJava_whenConvertingAnInputStreamToString_thenCorrect() throws IOException { String originalString = randomAlphabetic(8); @@ -225,7 +225,7 @@ public class JavaInputStreamToXUnitTest { buffer.flush(); byte[] byteArray = buffer.toByteArray(); - + String text = new String(byteArray, StandardCharsets.UTF_8); assertThat(text, equalTo(originalString)); } diff --git a/core-java-io/src/test/java/org/baeldung/java/io/JavaReadFromFileUnitTest.java b/core-java-io/src/test/java/org/baeldung/java/io/JavaReadFromFileUnitTest.java index 41d0a8a02a..b56841117e 100644 --- a/core-java-io/src/test/java/org/baeldung/java/io/JavaReadFromFileUnitTest.java +++ b/core-java-io/src/test/java/org/baeldung/java/io/JavaReadFromFileUnitTest.java @@ -18,7 +18,6 @@ import static org.junit.Assert.assertTrue; public class JavaReadFromFileUnitTest { - private static final Logger LOG = LoggerFactory.getLogger(JavaReadFromFileUnitTest.class); @Test @@ -107,11 +106,12 @@ public class JavaReadFromFileUnitTest { @Test public void whenReadUTFEncodedFile_thenCorrect() throws IOException { - final String expected_value = "青空"; + final String expected_value = "é�’空"; final BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream("src/test/resources/test_read7.in"), "UTF-8")); final String currentLine = reader.readLine(); reader.close(); LOG.debug(currentLine); + assertEquals(expected_value, currentLine); } diff --git a/core-java-io/src/test/java/org/baeldung/java/io/JavaXToInputStreamUnitTest.java b/core-java-io/src/test/java/org/baeldung/java/io/JavaXToInputStreamUnitTest.java index f58d66818b..08a4c673cd 100644 --- a/core-java-io/src/test/java/org/baeldung/java/io/JavaXToInputStreamUnitTest.java +++ b/core-java-io/src/test/java/org/baeldung/java/io/JavaXToInputStreamUnitTest.java @@ -68,7 +68,7 @@ public class JavaXToInputStreamUnitTest { @Test public final void givenUsingPlainJava_whenConvertingFileToInputStream_thenCorrect() throws IOException { - final File initialFile = new File("src/main/resources/sample.txt"); + final File initialFile = new File("src/test/resources/sample.txt"); final InputStream targetStream = new FileInputStream(initialFile); IOUtils.closeQuietly(targetStream); @@ -76,7 +76,7 @@ public class JavaXToInputStreamUnitTest { @Test public final void givenUsingGuava_whenConvertingFileToInputStream_thenCorrect() throws IOException { - final File initialFile = new File("src/main/resources/sample.txt"); + final File initialFile = new File("src/test/resources/sample.txt"); final InputStream targetStream = Files.asByteSource(initialFile).openStream(); IOUtils.closeQuietly(targetStream); @@ -84,7 +84,7 @@ public class JavaXToInputStreamUnitTest { @Test public final void givenUsingCommonsIO_whenConvertingFileToInputStream_thenCorrect() throws IOException { - final File initialFile = new File("src/main/resources/sample.txt"); + final File initialFile = new File("src/test/resources/sample.txt"); final InputStream targetStream = FileUtils.openInputStream(initialFile); IOUtils.closeQuietly(targetStream); diff --git a/core-java/src/test/resources/fileToWriteTo.txt b/core-java-io/src/test/resources/copiedWithApacheCommons.txt similarity index 100% rename from core-java/src/test/resources/fileToWriteTo.txt rename to core-java-io/src/test/resources/copiedWithApacheCommons.txt diff --git a/spring-cloud/spring-cloud-security/oauth2client/src/main/resources/application.properties b/core-java-io/src/test/resources/copiedWithIo.txt similarity index 100% rename from spring-cloud/spring-cloud-security/oauth2client/src/main/resources/application.properties rename to core-java-io/src/test/resources/copiedWithIo.txt diff --git a/core-java-io/src/test/resources/copiedWithNio.txt b/core-java-io/src/test/resources/copiedWithNio.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/core-java/src/test/resources/copyTest/dest/readme.txt b/core-java-io/src/test/resources/copyTest/dest/readme.txt similarity index 100% rename from core-java/src/test/resources/copyTest/dest/readme.txt rename to core-java-io/src/test/resources/copyTest/dest/readme.txt diff --git a/core-java/src/test/resources/copyTest/src/test_apache.txt b/core-java-io/src/test/resources/copyTest/src/test_apache.txt similarity index 100% rename from core-java/src/test/resources/copyTest/src/test_apache.txt rename to core-java-io/src/test/resources/copyTest/src/test_apache.txt diff --git a/core-java/src/test/resources/copyTest/src/test_channel.txt b/core-java-io/src/test/resources/copyTest/src/test_channel.txt similarity index 100% rename from core-java/src/test/resources/copyTest/src/test_channel.txt rename to core-java-io/src/test/resources/copyTest/src/test_channel.txt diff --git a/core-java/src/test/resources/copyTest/src/test_files.txt b/core-java-io/src/test/resources/copyTest/src/test_files.txt similarity index 100% rename from core-java/src/test/resources/copyTest/src/test_files.txt rename to core-java-io/src/test/resources/copyTest/src/test_files.txt diff --git a/core-java/src/test/resources/copyTest/src/test_stream.txt b/core-java-io/src/test/resources/copyTest/src/test_stream.txt similarity index 100% rename from core-java/src/test/resources/copyTest/src/test_stream.txt rename to core-java-io/src/test/resources/copyTest/src/test_stream.txt diff --git a/core-java/src/test/resources/file.txt b/core-java-io/src/test/resources/file.txt similarity index 100% rename from core-java/src/test/resources/file.txt rename to core-java-io/src/test/resources/file.txt diff --git a/core-java/src/test/resources/fileToRead.txt b/core-java-io/src/test/resources/fileToRead.txt similarity index 100% rename from core-java/src/test/resources/fileToRead.txt rename to core-java-io/src/test/resources/fileToRead.txt diff --git a/core-java-io/src/test/resources/fileToWriteTo.txt b/core-java-io/src/test/resources/fileToWriteTo.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/core-java-io/src/test/resources/initialFile.txt b/core-java-io/src/test/resources/initialFile.txt new file mode 100644 index 0000000000..7d572d5b9d --- /dev/null +++ b/core-java-io/src/test/resources/initialFile.txt @@ -0,0 +1 @@ +With Commons IO \ No newline at end of file diff --git a/core-java-io/src/test/resources/original.txt b/core-java-io/src/test/resources/original.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/core-java-io/src/test/resources/sample.txt b/core-java-io/src/test/resources/sample.txt new file mode 100644 index 0000000000..5e1c309dae --- /dev/null +++ b/core-java-io/src/test/resources/sample.txt @@ -0,0 +1 @@ +Hello World \ No newline at end of file diff --git a/core-java-io/src/test/resources/targetFile.tmp b/core-java-io/src/test/resources/targetFile.tmp new file mode 100644 index 0000000000..5e1c309dae --- /dev/null +++ b/core-java-io/src/test/resources/targetFile.tmp @@ -0,0 +1 @@ +Hello World \ No newline at end of file diff --git a/core-java-io/src/test/resources/targetFile.txt b/core-java-io/src/test/resources/targetFile.txt new file mode 100644 index 0000000000..424a8d0d1e --- /dev/null +++ b/core-java-io/src/test/resources/targetFile.txt @@ -0,0 +1 @@ +Some textSome text \ No newline at end of file diff --git a/core-java-io/src/test/resources/test_write.txt b/core-java-io/src/test/resources/test_write.txt new file mode 100644 index 0000000000..a15aad69b5 --- /dev/null +++ b/core-java-io/src/test/resources/test_write.txt @@ -0,0 +1 @@ +Some StringProduct name is iPhone and its price is 1000 $ \ No newline at end of file diff --git a/core-java-io/src/test/resources/test_write_1.txt b/core-java-io/src/test/resources/test_write_1.txt new file mode 100644 index 0000000000..5727d54bfc Binary files /dev/null and b/core-java-io/src/test/resources/test_write_1.txt differ diff --git a/core-java-io/src/test/resources/test_write_2.txt b/core-java-io/src/test/resources/test_write_2.txt new file mode 100644 index 0000000000..6a87dfc075 Binary files /dev/null and b/core-java-io/src/test/resources/test_write_2.txt differ diff --git a/core-java-io/src/test/resources/test_write_3.txt b/core-java-io/src/test/resources/test_write_3.txt new file mode 100644 index 0000000000..5e1c309dae --- /dev/null +++ b/core-java-io/src/test/resources/test_write_3.txt @@ -0,0 +1 @@ +Hello World \ No newline at end of file diff --git a/core-java-io/src/test/resources/test_write_4.txt b/core-java-io/src/test/resources/test_write_4.txt new file mode 100644 index 0000000000..f14fca61f6 Binary files /dev/null and b/core-java-io/src/test/resources/test_write_4.txt differ diff --git a/core-java-io/src/test/resources/test_write_5.txt b/core-java-io/src/test/resources/test_write_5.txt new file mode 100644 index 0000000000..5ab2f8a432 --- /dev/null +++ b/core-java-io/src/test/resources/test_write_5.txt @@ -0,0 +1 @@ +Hello \ No newline at end of file diff --git a/core-java/src/main/resources/META-INF/services/com.sun.source.util.Plugin b/core-java-sun/src/main/resources/META-INF/services/com.sun.source.util.Plugin similarity index 100% rename from core-java/src/main/resources/META-INF/services/com.sun.source.util.Plugin rename to core-java-sun/src/main/resources/META-INF/services/com.sun.source.util.Plugin diff --git a/core-java/README.md b/core-java/README.md index ed60db855c..298c936539 100644 --- a/core-java/README.md +++ b/core-java/README.md @@ -127,3 +127,18 @@ - [Polymorphism in Java](http://www.baeldung.com/java-polymorphism) - [Recursion In Java](http://www.baeldung.com/java-recursion) - [A Guide to the finalize Method in Java](http://www.baeldung.com/java-finalize) +- [Compiling Java *.class Files with javac](http://www.baeldung.com/javac) +- [Method Overloading and Overriding in Java](http://www.baeldung.com/java-method-overload-override) +- [A Guide to TreeSet in Java](http://www.baeldung.com/java-tree-set) +- [Guide to ThreadLocalRandom in Java](http://www.baeldung.com/java-thread-local-random) +- [Java TreeMap vs HashMap](http://www.baeldung.com/java-treemap-vs-hashmap) +- [A Guide to Iterator in Java](http://www.baeldung.com/java-iterator) +- [The Trie Data Structure in Java](http://www.baeldung.com/trie-java) +- [Introduction to Javadoc](http://www.baeldung.com/javadoc) +- [How to TDD a List Implementation](http://jira.baeldung.com/browse/BAEL-1537) +- [How to Make a Deep Copy of an Object in Java](http://www.baeldung.com/java-deep-copy) +- [Check if a String is a Palindrome](http://www.baeldung.com/java-palindrome) +- [Comparing Strings in Java](http://www.baeldung.com/java-compare-strings) +- [Guide to Inheritance in Java](http://www.baeldung.com/java-inheritance) +- [Guide to Externalizable Interface in Java](http://www.baeldung.com/java-externalizable) + diff --git a/core-java/pom.xml b/core-java/pom.xml index 5c1e9fcad0..e2983de9dd 100644 --- a/core-java/pom.xml +++ b/core-java/pom.xml @@ -78,6 +78,11 @@ jackson-databind ${jackson.version} + + com.google.code.gson + gson + ${gson.version} + @@ -468,6 +473,7 @@ 2.8.5 + 2.8.2 1.7.21 diff --git a/core-java/src/main/java/com/baeldung/array/Find2ndLargestInArray.java b/core-java/src/main/java/com/baeldung/array/Find2ndLargestInArray.java new file mode 100644 index 0000000000..d424bd429f --- /dev/null +++ b/core-java/src/main/java/com/baeldung/array/Find2ndLargestInArray.java @@ -0,0 +1,20 @@ +package com.baeldung.array; + +public class Find2ndLargestInArray { + + public static int find2ndLargestElement(int[] array) { + int maxElement = array[0]; + int secondLargestElement = -1; + + for (int index = 0; index < array.length; index++) { + if (maxElement <= array[index]) { + secondLargestElement = maxElement; + maxElement = array[index]; + } else if (secondLargestElement < array[index]) { + secondLargestElement = array[index]; + } + } + return secondLargestElement; + } + +} diff --git a/core-java/src/main/java/com/baeldung/array/FindElementInArray.java b/core-java/src/main/java/com/baeldung/array/FindElementInArray.java new file mode 100644 index 0000000000..6da889fe91 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/array/FindElementInArray.java @@ -0,0 +1,22 @@ +package com.baeldung.array; + +import java.util.Arrays; + +public class FindElementInArray { + + public static boolean findGivenElementInArrayWithoutUsingStream(int[] array, int element) { + boolean actualResult = false; + + for (int index = 0; index < array.length; index++) { + if (element == array[index]) { + actualResult = true; + break; + } + } + return actualResult; + } + + public static boolean findGivenElementInArrayUsingStream(int[] array, int element) { + return Arrays.stream(array).filter(x -> element == x).findFirst().isPresent(); + } +} diff --git a/core-java/src/main/java/com/baeldung/array/SumAndAverageInArray.java b/core-java/src/main/java/com/baeldung/array/SumAndAverageInArray.java new file mode 100644 index 0000000000..da64c5e9a7 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/array/SumAndAverageInArray.java @@ -0,0 +1,27 @@ +package com.baeldung.array; + +import java.util.Arrays; + +public class SumAndAverageInArray { + + public static int findSumWithoutUsingStream(int[] array) { + int sum = 0; + for (int value : array) { + sum += value; + } + return sum; + } + + public static int findSumUsingStream(int[] array) { + return Arrays.stream(array).sum(); + } + + public static double findAverageWithoutUsingStream(int[] array) { + int sum = findSumWithoutUsingStream(array); + return (double) sum / array.length; + } + + public static double findAverageUsingStream(int[] array) { + return Arrays.stream(array).average().orElse(Double.NaN); + } +} diff --git a/core-java/src/main/java/com/baeldung/asciiart/AsciiArt.java b/core-java/src/main/java/com/baeldung/asciiart/AsciiArt.java new file mode 100644 index 0000000000..081717b4fa --- /dev/null +++ b/core-java/src/main/java/com/baeldung/asciiart/AsciiArt.java @@ -0,0 +1,62 @@ +package com.baeldung.asciiart; + +import java.awt.Font; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.RenderingHints; +import java.awt.image.BufferedImage; + +public class AsciiArt { + + public AsciiArt() { + } + + public void drawString(String text, String artChar, Settings settings) { + BufferedImage image = getImageIntegerMode(settings.width, settings.height); + + Graphics2D graphics2D = getGraphics2D(image.getGraphics(), settings); + graphics2D.drawString(text, 6, ((int) (settings.height * 0.67))); + + for (int y = 0; y < settings.height; y++) { + StringBuilder stringBuilder = new StringBuilder(); + + for (int x = 0; x < settings.width; x++) { + stringBuilder.append(image.getRGB(x, y) == -16777216 ? " " : artChar); + } + + if (stringBuilder.toString() + .trim() + .isEmpty()) { + continue; + } + + System.out.println(stringBuilder); + } + + } + + private BufferedImage getImageIntegerMode(int width, int height) { + return new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + } + + private Graphics2D getGraphics2D(Graphics graphics, Settings settings) { + graphics.setFont(settings.font); + + Graphics2D graphics2D = (Graphics2D) graphics; + graphics2D.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); + + return graphics2D; + } + + public class Settings { + public Font font; + public int width; + public int height; + + public Settings(Font font, int width, int height) { + this.font = font; + this.width = width; + this.height = height; + } + } +} diff --git a/core-java/src/main/java/com/baeldung/casting/Animal.java b/core-java/src/main/java/com/baeldung/casting/Animal.java new file mode 100644 index 0000000000..9f31c1dda3 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/casting/Animal.java @@ -0,0 +1,13 @@ +package com.baeldung.casting; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class Animal { + private static final Logger LOGGER = LoggerFactory.getLogger(Animal.class); + + public void eat() { + LOGGER.info("animal is eating"); + } + +} diff --git a/core-java/src/main/java/com/baeldung/casting/AnimalFeeder.java b/core-java/src/main/java/com/baeldung/casting/AnimalFeeder.java new file mode 100644 index 0000000000..89b972e5c2 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/casting/AnimalFeeder.java @@ -0,0 +1,23 @@ +package com.baeldung.casting; + +import java.util.List; + +public class AnimalFeeder { + + public void feed(List animals) { + animals.forEach(animal -> { + animal.eat(); + if (animal instanceof Cat) { + ((Cat) animal).meow(); + } + }); + } + + public void uncheckedFeed(List animals) { + animals.forEach(animal -> { + animal.eat(); + ((Cat) animal).meow(); + }); + } + +} diff --git a/core-java/src/main/java/com/baeldung/casting/AnimalFeederGeneric.java b/core-java/src/main/java/com/baeldung/casting/AnimalFeederGeneric.java new file mode 100644 index 0000000000..5fbd2415c7 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/casting/AnimalFeederGeneric.java @@ -0,0 +1,24 @@ +package com.baeldung.casting; + +import java.util.ArrayList; +import java.util.List; + +public class AnimalFeederGeneric { + private Class type; + + public AnimalFeederGeneric(Class type) { + this.type = type; + } + + public List feed(List animals) { + List list = new ArrayList(); + animals.forEach(animal -> { + if (type.isInstance(animal)) { + T objAsType = type.cast(animal); + list.add(objAsType); + } + }); + return list; + } + +} diff --git a/core-java/src/main/java/com/baeldung/casting/Cat.java b/core-java/src/main/java/com/baeldung/casting/Cat.java new file mode 100644 index 0000000000..aa9a9a881a --- /dev/null +++ b/core-java/src/main/java/com/baeldung/casting/Cat.java @@ -0,0 +1,16 @@ +package com.baeldung.casting; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class Cat extends Animal implements Mew { + private static final Logger LOGGER = LoggerFactory.getLogger(Cat.class); + + public void eat() { + LOGGER.info("cat is eating"); + } + + public void meow() { + LOGGER.info("meow"); + } +} diff --git a/core-java/src/main/java/com/baeldung/casting/Dog.java b/core-java/src/main/java/com/baeldung/casting/Dog.java new file mode 100644 index 0000000000..763c6b4785 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/casting/Dog.java @@ -0,0 +1,12 @@ +package com.baeldung.casting; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class Dog extends Animal { + private static final Logger LOGGER = LoggerFactory.getLogger(Dog.class); + + public void eat() { + LOGGER.info("dog is eating"); + } +} diff --git a/core-java/src/main/java/com/baeldung/casting/Mew.java b/core-java/src/main/java/com/baeldung/casting/Mew.java new file mode 100644 index 0000000000..f3c7324551 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/casting/Mew.java @@ -0,0 +1,5 @@ +package com.baeldung.casting; + +public interface Mew { + public void meow(); +} diff --git a/core-java/src/main/java/com/baeldung/classloader/CustomClassLoader.java b/core-java/src/main/java/com/baeldung/classloader/CustomClassLoader.java new file mode 100644 index 0000000000..c44e863776 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/classloader/CustomClassLoader.java @@ -0,0 +1,29 @@ +package com.baeldung.classloader; + +import java.io.*; + +public class CustomClassLoader extends ClassLoader { + + + public Class getClass(String name) throws ClassNotFoundException { + byte[] b = loadClassFromFile(name); + return defineClass(name, b, 0, b.length); + } + + private byte[] loadClassFromFile(String fileName) { + InputStream inputStream = getClass().getClassLoader().getResourceAsStream( + fileName.replace('.', File.separatorChar) + ".class"); + byte[] buffer; + ByteArrayOutputStream byteStream = new ByteArrayOutputStream(); + int nextValue = 0; + try { + while ( (nextValue = inputStream.read()) != -1 ) { + byteStream.write(nextValue); + } + } catch (IOException e) { + e.printStackTrace(); + } + buffer = byteStream.toByteArray(); + return buffer; + } +} diff --git a/core-java/src/main/java/com/baeldung/classloader/PrintClassLoader.java b/core-java/src/main/java/com/baeldung/classloader/PrintClassLoader.java new file mode 100644 index 0000000000..09ee68bf6e --- /dev/null +++ b/core-java/src/main/java/com/baeldung/classloader/PrintClassLoader.java @@ -0,0 +1,22 @@ +package com.baeldung.classloader; + +import com.sun.javafx.util.Logging; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLConnection; +import java.util.ArrayList; + +public class PrintClassLoader { + + public void printClassLoaders() throws ClassNotFoundException { + + System.out.println("Classloader of this class:" + PrintClassLoader.class.getClassLoader()); + System.out.println("Classloader of Logging:" + Logging.class.getClassLoader()); + System.out.println("Classloader of ArrayList:" + ArrayList.class.getClassLoader()); + + } +} diff --git a/core-java/src/main/java/com/baeldung/deepcopy/Address.java b/core-java/src/main/java/com/baeldung/deepcopy/Address.java new file mode 100644 index 0000000000..4e010ea92b --- /dev/null +++ b/core-java/src/main/java/com/baeldung/deepcopy/Address.java @@ -0,0 +1,59 @@ +package com.baeldung.deepcopy; + +import java.io.Serializable; + +public class Address implements Serializable, Cloneable { + + @Override + public Object clone() { + try { + return (Address) super.clone(); + } catch (CloneNotSupportedException e) { + return new Address(this.street, this.getCity(), this.getCountry()); + } + } + + private static final long serialVersionUID = 1740913841244949416L; + private String street; + private String city; + + private String country; + + public Address(Address that) { + this(that.getStreet(), that.getCity(), that.getCountry()); + } + + public Address(String street, String city, String country) { + this.street = street; + this.city = city; + this.country = country; + } + + public Address() { + } + + public String getStreet() { + return street; + } + + public String getCity() { + return city; + } + + public String getCountry() { + return country; + } + + public void setStreet(String street) { + this.street = street; + } + + public void setCity(String city) { + this.city = city; + } + + public void setCountry(String country) { + this.country = country; + } +} + diff --git a/core-java/src/main/java/com/baeldung/deepcopy/User.java b/core-java/src/main/java/com/baeldung/deepcopy/User.java new file mode 100644 index 0000000000..329cfc6b27 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/deepcopy/User.java @@ -0,0 +1,48 @@ +package com.baeldung.deepcopy; + +import java.io.Serializable; + +public class User implements Serializable, Cloneable { + + private static final long serialVersionUID = -3427002229954777557L; + private String firstName; + private String lastName; + private Address address; + + public User(String firstName, String lastName, Address address) { + this.firstName = firstName; + this.lastName = lastName; + this.address = address; + } + + public User(User that) { + this(that.getFirstName(), that.getLastName(), new Address(that.getAddress())); + } + + public User() { + } + + @Override + public Object clone() { + User user; + try { + user = (User) super.clone(); + } catch (CloneNotSupportedException e) { + user = new User(this.getFirstName(), this.getLastName(), this.getAddress()); + } + user.address = (Address) this.address.clone(); + return user; + } + + public String getFirstName() { + return firstName; + } + + public String getLastName() { + return lastName; + } + + public Address getAddress() { + return address; + } +} diff --git a/core-java/src/main/java/com/baeldung/designpatterns/flyweight/Car.java b/core-java/src/main/java/com/baeldung/designpatterns/flyweight/Car.java new file mode 100644 index 0000000000..50f62cafaa --- /dev/null +++ b/core-java/src/main/java/com/baeldung/designpatterns/flyweight/Car.java @@ -0,0 +1,85 @@ +package com.baeldung.designpatterns.flyweight; + +import java.awt.Color; + +import javax.annotation.concurrent.Immutable; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Represents a car. This class is immutable. + * + * @author Donato Rimenti + */ +@Immutable +public class Car implements Vehicle { + + /** + * Logger. + */ + private final static Logger LOG = LoggerFactory.getLogger(Car.class); + + /** + * The car's engine. + */ + private Engine engine; + + /** + * The car's color. + */ + private Color color; + + /** + * Instantiates a new Car. + * + * @param engine + * the {@link #engine} + * @param color + * the {@link #color} + */ + public Car(Engine engine, Color color) { + this.engine = engine; + this.color = color; + + // Building a new car is a very expensive operation! + try { + Thread.sleep(2000); + } catch (InterruptedException e) { + LOG.error("Error while creating a new car", e); + } + } + + /* + * (non-Javadoc) + * + * @see com.baeldung.designpatterns.flyweight.Vehicle#start() + */ + @Override + public void start() { + LOG.info("Car is starting!"); + engine.start(); + } + + /* + * (non-Javadoc) + * + * @see com.baeldung.designpatterns.flyweight.Vehicle#stop() + */ + @Override + public void stop() { + LOG.info("Car is stopping!"); + engine.stop(); + } + + /* + * (non-Javadoc) + * + * @see com.baeldung.designpatterns.flyweight.Vehicle#getColor() + */ + @Override + public Color getColor() { + return this.color; + } + +} diff --git a/core-java/src/main/java/com/baeldung/designpatterns/flyweight/Engine.java b/core-java/src/main/java/com/baeldung/designpatterns/flyweight/Engine.java new file mode 100644 index 0000000000..05d9ca98b8 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/designpatterns/flyweight/Engine.java @@ -0,0 +1,31 @@ +package com.baeldung.designpatterns.flyweight; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Engine for a vehicle. + * + * @author Donato Rimenti + */ +public class Engine { + + /** + * Logger. + */ + private final static Logger LOG = LoggerFactory.getLogger(Engine.class); + + /** + * Starts the engine. + */ + public void start() { + LOG.info("Engine is starting!"); + } + + /** + * Stops the engine. + */ + public void stop() { + LOG.info("Engine is stopping!"); + } +} diff --git a/core-java/src/main/java/com/baeldung/designpatterns/flyweight/Vehicle.java b/core-java/src/main/java/com/baeldung/designpatterns/flyweight/Vehicle.java new file mode 100644 index 0000000000..c285f9fcff --- /dev/null +++ b/core-java/src/main/java/com/baeldung/designpatterns/flyweight/Vehicle.java @@ -0,0 +1,29 @@ +package com.baeldung.designpatterns.flyweight; + +import java.awt.Color; + +/** + * Interface for a vehicle. + * + * @author Donato Rimenti + */ +public interface Vehicle { + + /** + * Starts the vehicle. + */ + public void start(); + + /** + * Stops the vehicle. + */ + public void stop(); + + /** + * Gets the color of the vehicle. + * + * @return the color of the vehicle + */ + public Color getColor(); + +} \ No newline at end of file diff --git a/core-java/src/main/java/com/baeldung/designpatterns/flyweight/VehicleFactory.java b/core-java/src/main/java/com/baeldung/designpatterns/flyweight/VehicleFactory.java new file mode 100644 index 0000000000..2854b7dab1 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/designpatterns/flyweight/VehicleFactory.java @@ -0,0 +1,45 @@ +package com.baeldung.designpatterns.flyweight; + +import java.awt.Color; +import java.util.HashMap; +import java.util.Map; + +/** + * Factory which implements the Flyweight pattern to return an existing vehicle + * if present or a new one otherwise. + * + * @author Donato Rimenti + */ +public class VehicleFactory { + + /** + * Stores the already created vehicles. + */ + private static Map vehiclesCache = new HashMap(); + + /** + * Private constructor to prevent this class instantiation. + */ + private VehicleFactory() { + } + + /** + * Returns a vehicle of the same color passed as argument. If that vehicle + * was already created by this factory, that vehicle is returned, otherwise + * a new one is created and returned. + * + * @param color + * the color of the vehicle to return + * @return a vehicle of the specified color + */ + public static Vehicle createVehicle(Color color) { + // Looks for the requested vehicle into the cache. + // If the vehicle doesn't exist, a new one is created. + Vehicle newVehicle = vehiclesCache.computeIfAbsent(color, newColor -> { + // Creates the new car. + Engine newEngine = new Engine(); + return new Car(newEngine, newColor); + }); + return newVehicle; + } +} diff --git a/core-java/src/main/java/com/baeldung/externalizable/Community.java b/core-java/src/main/java/com/baeldung/externalizable/Community.java new file mode 100644 index 0000000000..bdbec9f547 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/externalizable/Community.java @@ -0,0 +1,23 @@ +package com.baeldung.externalizable; + +import java.io.*; + +public class Community implements Serializable { + + private int id; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + @Override + public String toString() { + return "Community{" + + "id=" + id + + '}'; + } +} diff --git a/core-java/src/main/java/com/baeldung/externalizable/Country.java b/core-java/src/main/java/com/baeldung/externalizable/Country.java new file mode 100644 index 0000000000..9fa95002f5 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/externalizable/Country.java @@ -0,0 +1,62 @@ +package com.baeldung.externalizable; + +import java.io.Externalizable; +import java.io.IOException; +import java.io.ObjectInput; +import java.io.ObjectOutput; + +public class Country implements Externalizable { + + private static final long serialVersionUID = 1L; + + private String name; + private String capital; + private int code; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getCapital() { + return capital; + } + + public void setCapital(String capital) { + this.capital = capital; + } + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + @Override + public void writeExternal(ObjectOutput out) throws IOException { + out.writeUTF(name); + out.writeUTF(capital); + out.writeInt(code); + } + + @Override + public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { + this.name = in.readUTF(); + this.capital = in.readUTF(); + this.code = in.readInt(); + } + + @Override + public String toString() { + return "Country{" + + "name='" + name + '\'' + + ", capital='" + capital + '\'' + + ", code=" + code + + '}'; + } +} diff --git a/core-java/src/main/java/com/baeldung/externalizable/Region.java b/core-java/src/main/java/com/baeldung/externalizable/Region.java new file mode 100644 index 0000000000..3ddb694291 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/externalizable/Region.java @@ -0,0 +1,57 @@ +package com.baeldung.externalizable; + +import java.io.Externalizable; +import java.io.IOException; +import java.io.ObjectInput; +import java.io.ObjectOutput; + +public class Region extends Country implements Externalizable { + + private static final long serialVersionUID = 1L; + + private String climate; + private Double population; + private Community community; + + public String getClimate() { + return climate; + } + + public void setClimate(String climate) { + this.climate = climate; + } + + public Double getPopulation() { + return population; + } + + public void setPopulation(Double population) { + this.population = population; + } + + @Override + public void writeExternal(ObjectOutput out) throws IOException { + super.writeExternal(out); + out.writeUTF(climate); + community = new Community(); + community.setId(5); + out.writeObject(community); + } + + @Override + public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { + super.readExternal(in); + this.climate = in.readUTF(); + community = (Community) in.readObject(); + } + + @Override + public String toString() { + return "Region = {" + + "country='" + super.toString() + '\'' + + "community='" + community.toString() + '\'' + + "climate='" + climate + '\'' + + ", population=" + population + + '}'; + } +} diff --git a/core-java/src/main/java/com/baeldung/finalkeyword/BlackCat.java b/core-java/src/main/java/com/baeldung/finalkeyword/BlackCat.java new file mode 100644 index 0000000000..7a978d3c3d --- /dev/null +++ b/core-java/src/main/java/com/baeldung/finalkeyword/BlackCat.java @@ -0,0 +1,5 @@ +package com.baeldung.finalkeyword; + +public class BlackCat { + +} diff --git a/core-java/src/main/java/com/baeldung/finalkeyword/BlackDog.java b/core-java/src/main/java/com/baeldung/finalkeyword/BlackDog.java new file mode 100644 index 0000000000..096bad3a96 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/finalkeyword/BlackDog.java @@ -0,0 +1,6 @@ +package com.baeldung.finalkeyword; + +public class BlackDog extends Dog { + // public void sound() { + // } +} diff --git a/core-java/src/main/java/com/baeldung/finalkeyword/Cat.java b/core-java/src/main/java/com/baeldung/finalkeyword/Cat.java new file mode 100644 index 0000000000..bfb24cd26f --- /dev/null +++ b/core-java/src/main/java/com/baeldung/finalkeyword/Cat.java @@ -0,0 +1,18 @@ +package com.baeldung.finalkeyword; + +public final class Cat { + + private int weight; + + public int getWeight() { + return weight; + } + + public void setWeight(int weight) { + this.weight = weight; + } + + public void methodWithFinalArguments(final int x) { + // x=1; + } +} diff --git a/core-java/src/main/java/com/baeldung/finalkeyword/Dog.java b/core-java/src/main/java/com/baeldung/finalkeyword/Dog.java new file mode 100644 index 0000000000..f1163b1f41 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/finalkeyword/Dog.java @@ -0,0 +1,7 @@ +package com.baeldung.finalkeyword; + +public class Dog { + + public final void sound() { + } +} diff --git a/core-java/src/main/java/com/baeldung/inheritance/ArmoredCar.java b/core-java/src/main/java/com/baeldung/inheritance/ArmoredCar.java new file mode 100644 index 0000000000..b6bb5181b8 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/inheritance/ArmoredCar.java @@ -0,0 +1,43 @@ +package com.baeldung.inheritance; + +public class ArmoredCar extends Car implements Floatable, Flyable{ + private int bulletProofWindows; + private String model; + + public void remoteStartCar() { + // this vehicle can be started by using a remote control + } + + public String registerModel() { + return model; + } + + public String getAValue() { + return super.model; // returns value of model defined in base class Car + // return this.model; // will return value of model defined in ArmoredCar + // return model; // will return value of model defined in ArmoredCar + } + + public static String msg() { + // return super.msg(); // this won't compile. + return "ArmoredCar"; + } + + @Override + public void floatOnWater() { + System.out.println("I can float!"); + } + + @Override + public void fly() { + System.out.println("I can fly!"); + } + + public void aMethod() { + // System.out.println(duration); // Won't compile + System.out.println(Floatable.duration); // outputs 10 + System.out.println(Flyable.duration); // outputs 20 + } + + +} diff --git a/core-java/src/main/java/com/baeldung/inheritance/BMW.java b/core-java/src/main/java/com/baeldung/inheritance/BMW.java new file mode 100644 index 0000000000..8ad3bb683f --- /dev/null +++ b/core-java/src/main/java/com/baeldung/inheritance/BMW.java @@ -0,0 +1,12 @@ +package com.baeldung.inheritance; + +public class BMW extends Car { + public BMW() { + super(5, "BMW"); + } + + @Override + public String toString() { + return model; + } +} diff --git a/core-java/src/main/java/com/baeldung/inheritance/Car.java b/core-java/src/main/java/com/baeldung/inheritance/Car.java new file mode 100644 index 0000000000..21ea9ea569 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/inheritance/Car.java @@ -0,0 +1,32 @@ +package com.baeldung.inheritance; + +public class Car { + private final int DEFAULT_WHEEL_COUNT = 5; + private final String DEFAULT_MODEL = "Basic"; + + protected int wheels; + protected String model; + + public Car() { + this.wheels = DEFAULT_WHEEL_COUNT; + this.model = DEFAULT_MODEL; + } + + public Car(int wheels, String model) { + this.wheels = wheels; + this.model = model; + } + + public void start() { + // Check essential parts + // If okay, start. + } + public static int count = 10; + public static String msg() { + return "Car"; + } + + public String toString() { + return model; + } +} \ No newline at end of file diff --git a/core-java/src/main/java/com/baeldung/inheritance/Employee.java b/core-java/src/main/java/com/baeldung/inheritance/Employee.java new file mode 100644 index 0000000000..599a1d7331 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/inheritance/Employee.java @@ -0,0 +1,15 @@ +package com.baeldung.inheritance; + +public class Employee { + private String name; + private Car car; + + public Employee(String name, Car car) { + this.name = name; + this.car = car; + } + + public Car getCar() { + return car; + } +} \ No newline at end of file diff --git a/core-java/src/main/java/com/baeldung/inheritance/Floatable.java b/core-java/src/main/java/com/baeldung/inheritance/Floatable.java new file mode 100644 index 0000000000..c0b456dffb --- /dev/null +++ b/core-java/src/main/java/com/baeldung/inheritance/Floatable.java @@ -0,0 +1,10 @@ +package com.baeldung.inheritance; + +public interface Floatable { + int duration = 10; + void floatOnWater(); + + default void repair() { + System.out.println("Repairing Floatable object"); + } +} diff --git a/core-java/src/main/java/com/baeldung/inheritance/Flyable.java b/core-java/src/main/java/com/baeldung/inheritance/Flyable.java new file mode 100644 index 0000000000..cb8244cf5b --- /dev/null +++ b/core-java/src/main/java/com/baeldung/inheritance/Flyable.java @@ -0,0 +1,13 @@ +package com.baeldung.inheritance; + +public interface Flyable { + int duration = 10; + void fly(); + + /* + * Commented + */ + //default void repair() { + // System.out.println("Repairing Flyable object"); + //} +} diff --git a/core-java/src/main/java/com/baeldung/inheritance/SpaceCar.java b/core-java/src/main/java/com/baeldung/inheritance/SpaceCar.java new file mode 100644 index 0000000000..8c23b26da9 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/inheritance/SpaceCar.java @@ -0,0 +1,18 @@ +package com.baeldung.inheritance; + +public class SpaceCar extends Car implements SpaceTraveller { + @Override + public void floatOnWater() { + System.out.println("SpaceCar floating!"); + } + + @Override + public void fly() { + System.out.println("SpaceCar flying!"); + } + + @Override + public void remoteControl() { + System.out.println("SpaceCar being controlled remotely!"); + } +} diff --git a/core-java/src/main/java/com/baeldung/inheritance/SpaceTraveller.java b/core-java/src/main/java/com/baeldung/inheritance/SpaceTraveller.java new file mode 100644 index 0000000000..9b66441791 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/inheritance/SpaceTraveller.java @@ -0,0 +1,6 @@ +package com.baeldung.inheritance; + +public interface SpaceTraveller extends Floatable, Flyable { + int duration = 10; + void remoteControl(); +} \ No newline at end of file diff --git a/core-java/src/main/java/com/baeldung/java/list/CustomList.java b/core-java/src/main/java/com/baeldung/java/list/CustomList.java new file mode 100644 index 0000000000..8b91fca32f --- /dev/null +++ b/core-java/src/main/java/com/baeldung/java/list/CustomList.java @@ -0,0 +1,210 @@ +package com.baeldung.java.list; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.ListIterator; + +public class CustomList implements List { + private Object[] internal = {}; + + @Override + public boolean isEmpty() { + // the first cycle + // return true; + + // the second cycle + // if (internal.length != 0) { + // return false; + // } else { + // return true; + // } + + // refactoring + return internal.length == 0; + } + + @Override + public int size() { + // the first cycle + // if (isEmpty()) { + // return 0; + // } else { + // return internal.length; + // } + + // refactoring + return internal.length; + } + + @SuppressWarnings("unchecked") + @Override + public E get(int index) { + // the first cycle + // return (E) internal[0]; + + // improvement + return (E) internal[index]; + } + + @Override + public boolean add(E element) { + // the first cycle + // internal = new Object[] { element }; + // return true; + + // the second cycle + Object[] temp = Arrays.copyOf(internal, internal.length + 1); + temp[internal.length] = element; + internal = temp; + return true; + } + + @Override + public void add(int index, E element) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean addAll(Collection collection) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean addAll(int index, Collection collection) { + throw new UnsupportedOperationException(); + } + + @Override + public E remove(int index) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean remove(Object object) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean removeAll(Collection collection) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean retainAll(Collection collection) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean contains(Object object) { + for (Object element : internal) { + if (object.equals(element)) { + return true; + } + } + return false; + } + + @Override + public boolean containsAll(Collection collection) { + for (Object element : collection) + if (!contains(element)) { + return false; + } + return true; + } + + @SuppressWarnings("unchecked") + @Override + public E set(int index, E element) { + E oldElement = (E) internal[index]; + internal[index] = element; + return oldElement; + } + + @Override + public void clear() { + internal = new Object[0]; + } + + @Override + public int indexOf(Object object) { + for (int i = 0; i < internal.length; i++) { + if (object.equals(internal[i])) { + return i; + } + } + return -1; + } + + @Override + public int lastIndexOf(Object object) { + for (int i = internal.length - 1; i >= 0; i--) { + if (object.equals(internal[i])) { + return i; + } + } + return -1; + } + + @SuppressWarnings("unchecked") + @Override + public List subList(int fromIndex, int toIndex) { + Object[] temp = new Object[toIndex - fromIndex]; + System.arraycopy(internal, fromIndex, temp, 0, temp.length); + return (List) Arrays.asList(temp); + } + + @Override + public Object[] toArray() { + return Arrays.copyOf(internal, internal.length); + } + + @SuppressWarnings("unchecked") + @Override + public T[] toArray(T[] array) { + if (array.length < internal.length) { + return (T[]) Arrays.copyOf(internal, internal.length, array.getClass()); + } + + System.arraycopy(internal, 0, array, 0, internal.length); + if (array.length > internal.length) { + array[internal.length] = null; + } + return array; + } + + @Override + public Iterator iterator() { + return new CustomIterator(); + } + + @Override + public ListIterator listIterator() { + return null; + } + + @Override + public ListIterator listIterator(int index) { + // ignored for brevity + return null; + } + + private class CustomIterator implements Iterator { + int index; + + @Override + public boolean hasNext() { + return index != internal.length; + } + + @SuppressWarnings("unchecked") + @Override + public E next() { + E element = (E) CustomList.this.internal[index]; + index++; + return element; + } + } +} diff --git a/core-java/src/main/java/com/baeldung/javadoc/SuperHero.java b/core-java/src/main/java/com/baeldung/javadoc/SuperHero.java index 029a779cdb..561430f66f 100644 --- a/core-java/src/main/java/com/baeldung/javadoc/SuperHero.java +++ b/core-java/src/main/java/com/baeldung/javadoc/SuperHero.java @@ -23,9 +23,15 @@ public class SuperHero extends Person { * @return the amount of health hero has after attack * @see HERO-402 * @since 1.0 + * @deprecated As of version 1.1, use . . . instead + * @version 1.2 + * @throws IllegalArgumentException if incomingDamage is negative */ - public int successfullyAttacked(int incomingDamage, String damageType) { + public int successfullyAttacked(int incomingDamage, String damageType) throws Exception { // do things + if (incomingDamage < 0) { + throw new IllegalArgumentException ("Cannot cause negative damage"); + } return 0; } diff --git a/core-java/src/main/java/com/baeldung/methodoverloadingoverriding/application/Application.java b/core-java/src/main/java/com/baeldung/methodoverloadingoverriding/application/Application.java new file mode 100644 index 0000000000..6e023e9fa8 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/methodoverloadingoverriding/application/Application.java @@ -0,0 +1,26 @@ +package com.baeldung.methodoverloadingoverriding.application; + +import com.baeldung.methodoverloadingoverriding.model.Car; +import com.baeldung.methodoverloadingoverriding.model.Vehicle; +import com.baeldung.methodoverloadingoverriding.util.Multiplier; + +public class Application { + + public static void main(String[] args) { + Multiplier multiplier = new Multiplier(); + System.out.println(multiplier.multiply(10, 10)); + System.out.println(multiplier.multiply(10, 10, 10)); + System.out.println(multiplier.multiply(10, 10.5)); + System.out.println(multiplier.multiply(10.5, 10.5)); + + Vehicle vehicle = new Vehicle(); + System.out.println(vehicle.accelerate(100)); + System.out.println(vehicle.run()); + System.out.println(vehicle.stop()); + + Vehicle car = new Car(); + System.out.println(car.accelerate(80)); + System.out.println(car.run()); + System.out.println(car.stop()); + } +} diff --git a/core-java/src/main/java/com/baeldung/methodoverloadingoverriding/model/Car.java b/core-java/src/main/java/com/baeldung/methodoverloadingoverriding/model/Car.java new file mode 100644 index 0000000000..aa5bdcaec9 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/methodoverloadingoverriding/model/Car.java @@ -0,0 +1,9 @@ +package com.baeldung.methodoverloadingoverriding.model; + +public class Car extends Vehicle { + + @Override + public String accelerate(long mph) { + return "The car accelerates at : " + mph + " MPH."; + } +} diff --git a/core-java/src/main/java/com/baeldung/methodoverloadingoverriding/model/Vehicle.java b/core-java/src/main/java/com/baeldung/methodoverloadingoverriding/model/Vehicle.java new file mode 100644 index 0000000000..eb59e8ca23 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/methodoverloadingoverriding/model/Vehicle.java @@ -0,0 +1,16 @@ +package com.baeldung.methodoverloadingoverriding.model; + +public class Vehicle { + + public String accelerate(long mph) { + return "The vehicle accelerates at : " + mph + " MPH."; + } + + public String stop() { + return "The vehicle has stopped."; + } + + public String run() { + return "The vehicle is running."; + } +} diff --git a/core-java/src/main/java/com/baeldung/methodoverloadingoverriding/util/Multiplier.java b/core-java/src/main/java/com/baeldung/methodoverloadingoverriding/util/Multiplier.java new file mode 100644 index 0000000000..c43e61c78f --- /dev/null +++ b/core-java/src/main/java/com/baeldung/methodoverloadingoverriding/util/Multiplier.java @@ -0,0 +1,16 @@ +package com.baeldung.methodoverloadingoverriding.util; + +public class Multiplier { + + public int multiply(int a, int b) { + return a * b; + } + + public int multiply(int a, int b, int c) { + return a * b * c; + } + + public double multiply(double a, double b) { + return a * b; + } +} diff --git a/core-java/src/main/java/com/baeldung/recursion/BinaryNode.java b/core-java/src/main/java/com/baeldung/recursion/BinaryNode.java new file mode 100644 index 0000000000..0c3f0ecc40 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/recursion/BinaryNode.java @@ -0,0 +1,31 @@ +package com.baeldung.recursion; + +public class BinaryNode { + int value; + BinaryNode left; + BinaryNode right; + + public BinaryNode(int value){ + this.value = value; + } + + public int getValue() { + return value; + } + public void setValue(int value) { + this.value = value; + } + public BinaryNode getLeft() { + return left; + } + public void setLeft(BinaryNode left) { + this.left = left; + } + public BinaryNode getRight() { + return right; + } + public void setRight(BinaryNode right) { + this.right = right; + } + +} diff --git a/core-java/src/main/java/com/baeldung/recursion/RecursionExample.java b/core-java/src/main/java/com/baeldung/recursion/RecursionExample.java new file mode 100644 index 0000000000..649c0e0587 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/recursion/RecursionExample.java @@ -0,0 +1,64 @@ +package com.baeldung.recursion; + +public class RecursionExample { + + public int sum(int n){ + if (n >= 1){ + return sum(n - 1) + n; + } + return n; + } + + public int tailSum(int currentSum, int n){ + if (n <= 1) { + return currentSum + n; + } + return tailSum(currentSum + n, n - 1); + } + + public int iterativeSum(int n){ + int sum = 0; + if(n < 0){ + return -1; + } + for(int i=0; i<=n; i++){ + sum += i; + } + return sum; + } + + public int powerOf10(int n){ + if (n == 0){ + return 1; + } + return powerOf10(n-1)*10; + } + + public int fibonacci(int n){ + if (n <=1 ){ + return n; + } + return fibonacci(n-1) + fibonacci(n-2); + } + + public String toBinary(int n){ + if (n <= 1 ){ + return String.valueOf(n); + } + return toBinary(n / 2) + String.valueOf(n % 2); + } + + public int calculateTreeHeight(BinaryNode root){ + if (root!= null){ + if (root.getLeft() != null || root.getRight() != null){ + return 1 + max(calculateTreeHeight(root.left) , calculateTreeHeight(root.right)); + } + } + return 0; + } + + public int max(int a,int b){ + return a>b ? a:b; + } + +} diff --git a/core-java/src/main/java/com/baeldung/resourcebundle/ExampleControl.java b/core-java/src/main/java/com/baeldung/resourcebundle/ExampleControl.java new file mode 100644 index 0000000000..88ce36c27f --- /dev/null +++ b/core-java/src/main/java/com/baeldung/resourcebundle/ExampleControl.java @@ -0,0 +1,15 @@ +package com.baeldung.resourcebundle; + +import java.util.Arrays; +import java.util.List; +import java.util.Locale; +import java.util.ResourceBundle; + +public class ExampleControl extends ResourceBundle.Control { + + @Override + public List getCandidateLocales(String s, Locale locale) { + return Arrays.asList(new Locale("pl", "PL")); + } + +} diff --git a/core-java/src/main/java/com/baeldung/resourcebundle/ExampleResource.java b/core-java/src/main/java/com/baeldung/resourcebundle/ExampleResource.java new file mode 100644 index 0000000000..52ccc80f52 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/resourcebundle/ExampleResource.java @@ -0,0 +1,14 @@ +package com.baeldung.resourcebundle; + +import java.util.ListResourceBundle; + +public class ExampleResource extends ListResourceBundle { + + @Override + protected Object[][] getContents() { + return new Object[][] { + { "greeting", "hello" } + }; + } + +} diff --git a/core-java/src/main/java/com/baeldung/resourcebundle/ExampleResource_pl.java b/core-java/src/main/java/com/baeldung/resourcebundle/ExampleResource_pl.java new file mode 100644 index 0000000000..7d4f11a5d3 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/resourcebundle/ExampleResource_pl.java @@ -0,0 +1,15 @@ +package com.baeldung.resourcebundle; + +import java.util.ListResourceBundle; + +public class ExampleResource_pl extends ListResourceBundle { + + @Override + protected Object[][] getContents() { + return new Object[][] { + { "greeting", "cześć" }, + { "language", "polish" }, + }; + } + +} diff --git a/core-java/src/main/java/com/baeldung/resourcebundle/ExampleResource_pl_PL.java b/core-java/src/main/java/com/baeldung/resourcebundle/ExampleResource_pl_PL.java new file mode 100644 index 0000000000..252bfcb9cf --- /dev/null +++ b/core-java/src/main/java/com/baeldung/resourcebundle/ExampleResource_pl_PL.java @@ -0,0 +1,17 @@ +package com.baeldung.resourcebundle; + +import java.math.BigDecimal; +import java.util.ListResourceBundle; + +public class ExampleResource_pl_PL extends ListResourceBundle { + + @Override + protected Object[][] getContents() { + return new Object[][] { + { "currency", "polish zloty" }, + { "toUsdRate", new BigDecimal("3.401") }, + { "cities", new String[] { "Warsaw", "Cracow" } } + }; + } + +} diff --git a/core-java/src/main/java/com/baeldung/string/Palindrome.java b/core-java/src/main/java/com/baeldung/string/Palindrome.java index 03b65d1a84..97d4d36d07 100644 --- a/core-java/src/main/java/com/baeldung/string/Palindrome.java +++ b/core-java/src/main/java/com/baeldung/string/Palindrome.java @@ -1,53 +1,66 @@ package com.baeldung.string; +import java.util.stream.IntStream; + public class Palindrome { public boolean isPalindrome(String text) { - text = text.replaceAll("\\s+", "") - .toLowerCase(); - int length = text.length(); + String clean = text.replaceAll("\\s+", "").toLowerCase(); + int length = clean.length(); int forward = 0; int backward = length - 1; - boolean palindrome = true; while (backward > forward) { - char forwardChar = text.charAt(forward++); - char backwardChar = text.charAt(backward--); + char forwardChar = clean.charAt(forward++); + char backwardChar = clean.charAt(backward--); if (forwardChar != backwardChar) return false; } - return palindrome; + return true; } public boolean isPalindromeReverseTheString(String text) { - String reverse = ""; - text = text.replaceAll("\\s+", "").toLowerCase(); - char[] plain = text.toCharArray(); + StringBuilder reverse = new StringBuilder(); + String clean = text.replaceAll("\\s+", "").toLowerCase(); + char[] plain = clean.toCharArray(); for (int i = plain.length - 1; i >= 0; i--) - reverse += plain[i]; - return reverse.equals(text); + reverse.append(plain[i]); + return (reverse.toString()).equals(clean); } public boolean isPalindromeUsingStringBuilder(String text) { - StringBuilder plain = new StringBuilder(text); + String clean = text.replaceAll("\\s+", "").toLowerCase(); + StringBuilder plain = new StringBuilder(clean); StringBuilder reverse = plain.reverse(); - return reverse.equals(plain); + return (reverse.toString()).equals(clean); } public boolean isPalindromeUsingStringBuffer(String text) { - StringBuffer plain = new StringBuffer(text); + String clean = text.replaceAll("\\s+", "").toLowerCase(); + StringBuffer plain = new StringBuffer(clean); StringBuffer reverse = plain.reverse(); - return reverse.equals(plain); + return (reverse.toString()).equals(clean); } - public boolean isPalindromeRecursive(String text, int forward, int backward) { + public boolean isPalindromeRecursive(String text) { + String clean = text.replaceAll("\\s+", "").toLowerCase(); + return recursivePalindrome(clean, 0, clean.length() - 1); + } + + private boolean recursivePalindrome(String text, int forward, int backward) { if (forward == backward) return true; if ((text.charAt(forward)) != (text.charAt(backward))) return false; if (forward < backward + 1) { - return isPalindromeRecursive(text, forward + 1, backward - 1); + return recursivePalindrome(text, forward + 1, backward - 1); } return true; } + + public boolean isPalindromeUsingIntStream(String text) { + String temp = text.replaceAll("\\s+", "").toLowerCase(); + return IntStream.range(0, temp.length() / 2) + .noneMatch(i -> temp.charAt(i) != temp.charAt(temp.length() - i - 1)); + } } diff --git a/core-java/src/main/java/com/baeldung/system/DetectOS.java b/core-java/src/main/java/com/baeldung/system/DetectOS.java new file mode 100644 index 0000000000..2d605fe49f --- /dev/null +++ b/core-java/src/main/java/com/baeldung/system/DetectOS.java @@ -0,0 +1,18 @@ +package com.baeldung.system; + +import org.apache.commons.lang3.SystemUtils; + +public class DetectOS { + + public String getOperatingSystem() { + String os = System.getProperty("os.name"); + System.out.println("Using System Property: " + os); + return os; + } + + public String getOperatingSystemSystemUtils() { + String os = SystemUtils.OS_NAME; + System.out.println("Using SystemUtils: " + os); + return os; + } +} diff --git a/core-java/src/main/resources/resourcebundle/resource.properties b/core-java/src/main/resources/resourcebundle/resource.properties new file mode 100644 index 0000000000..edeae3ef4b --- /dev/null +++ b/core-java/src/main/resources/resourcebundle/resource.properties @@ -0,0 +1,6 @@ +# Buttons +cancelButton=cancel +continueButton continue + +! Labels +helloLabel:hello diff --git a/core-java/src/main/resources/resourcebundle/resource_en.properties b/core-java/src/main/resources/resourcebundle/resource_en.properties new file mode 100644 index 0000000000..5d72b65e2f --- /dev/null +++ b/core-java/src/main/resources/resourcebundle/resource_en.properties @@ -0,0 +1 @@ +deleteButton=delete \ No newline at end of file diff --git a/core-java/src/main/resources/resourcebundle/resource_pl_PL.properties b/core-java/src/main/resources/resourcebundle/resource_pl_PL.properties new file mode 100644 index 0000000000..37dea822ad --- /dev/null +++ b/core-java/src/main/resources/resourcebundle/resource_pl_PL.properties @@ -0,0 +1,3 @@ +backButton=cofnij +helloLabel=cze\u015b\u0107 +helloLabelNoEncoding=cześć \ No newline at end of file diff --git a/core-java/src/main/resources/targetFile.tmp b/core-java/src/main/resources/targetFile.tmp deleted file mode 100644 index 20f137b416..0000000000 --- a/core-java/src/main/resources/targetFile.tmp +++ /dev/null @@ -1,2 +0,0 @@ -line 1 -a second line \ No newline at end of file diff --git a/core-java/src/test/java/com/baeldung/array/Find2ndLargestInArrayTest.java b/core-java/src/test/java/com/baeldung/array/Find2ndLargestInArrayTest.java new file mode 100644 index 0000000000..ec916af092 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/array/Find2ndLargestInArrayTest.java @@ -0,0 +1,16 @@ +package com.baeldung.array; + +import org.junit.Assert; +import org.junit.Test; + +public class Find2ndLargestInArrayTest { + @Test + public void givenAnIntArray_thenFind2ndLargestElement() { + int[] array = { 1, 3, 24, 16, 87, 20 }; + int expected2ndLargest = 24; + + int actualSecondLargestElement = Find2ndLargestInArray.find2ndLargestElement(array); + + Assert.assertEquals(expected2ndLargest, actualSecondLargestElement); + } +} diff --git a/core-java/src/test/java/com/baeldung/array/FindElementInArrayTest.java b/core-java/src/test/java/com/baeldung/array/FindElementInArrayTest.java new file mode 100644 index 0000000000..ba9188fa7b --- /dev/null +++ b/core-java/src/test/java/com/baeldung/array/FindElementInArrayTest.java @@ -0,0 +1,35 @@ +package com.baeldung.array; + +import org.junit.Assert; +import org.junit.Test; + +public class FindElementInArrayTest { + @Test + public void givenAnIntArray_whenNotUsingStream_thenFindAnElement() { + int[] array = { 1, 3, 4, 8, 19, 20 }; + int element = 19; + boolean expectedResult = true; + boolean actualResult = FindElementInArray.findGivenElementInArrayWithoutUsingStream(array, element); + Assert.assertEquals(expectedResult, actualResult); + + element = 78; + expectedResult = false; + actualResult = FindElementInArray.findGivenElementInArrayWithoutUsingStream(array, element); + Assert.assertEquals(expectedResult, actualResult); + } + + @Test + public void givenAnIntArray_whenUsingStream_thenFindAnElement() { + int[] array = { 15, 16, 12, 18 }; + int element = 16; + boolean expectedResult = true; + boolean actualResult = FindElementInArray.findGivenElementInArrayUsingStream(array, element); + Assert.assertEquals(expectedResult, actualResult); + + element = 20; + expectedResult = false; + actualResult = FindElementInArray.findGivenElementInArrayUsingStream(array, element); + Assert.assertEquals(expectedResult, actualResult); + } + +} diff --git a/core-java/src/test/java/com/baeldung/array/SumAndAverageInArrayTest.java b/core-java/src/test/java/com/baeldung/array/SumAndAverageInArrayTest.java new file mode 100644 index 0000000000..5597dbd542 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/array/SumAndAverageInArrayTest.java @@ -0,0 +1,50 @@ +package com.baeldung.array; + +import org.junit.Assert; +import org.junit.Test; + +public class SumAndAverageInArrayTest { + @Test + public void givenAnIntArray_whenNotUsingStream_thenFindSum() { + int[] array = { 1, 3, 4, 8, 19, 20 }; + int expectedSumOfArray = 55; + int actualSumOfArray = SumAndAverageInArray.findSumWithoutUsingStream(array); + Assert.assertEquals(expectedSumOfArray, actualSumOfArray); + } + + @Test + public void givenAnIntArray_whenUsingStream_thenFindSum() { + int[] array = { 1, 3, 4, 8, 19, 20 }; + int expectedSumOfArray = 55; + int actualSumOfArray = SumAndAverageInArray.findSumUsingStream(array); + + Assert.assertEquals(expectedSumOfArray, actualSumOfArray); + } + + @Test + public void givenAnIntArray_whenNotUsingStream_thenFindAverage() { + int[] array = { 1, 3, 4, 8, 19, 20 }; + double expectedAvgOfArray = 9.17; + double actualAvgOfArray = SumAndAverageInArray.findAverageWithoutUsingStream(array); + + Assert.assertEquals(expectedAvgOfArray, actualAvgOfArray, 0.0034); + } + + @Test + public void givenAnIntArray_whenUsingStream_thenFindAverage() { + int[] array = { 1, 3, 4, 8, 19, 20 }; + double expectedAvgOfArray = 9.17; + double actualAvgOfArray = SumAndAverageInArray.findAverageUsingStream(array); + + Assert.assertEquals(expectedAvgOfArray, actualAvgOfArray, 0.0034); + } + + @Test + public void givenAnEmptyIntArray_whenUsingStream_thenFindAverage() { + int[] array = {}; + double expectedAvgOfArray = Double.NaN; + double actualAvgOfArray = SumAndAverageInArray.findAverageUsingStream(array); + + Assert.assertEquals(expectedAvgOfArray, actualAvgOfArray, 0.00); + } +} diff --git a/core-java/src/test/java/com/baeldung/asciiart/AsciiArtTest.java b/core-java/src/test/java/com/baeldung/asciiart/AsciiArtTest.java new file mode 100644 index 0000000000..103681894e --- /dev/null +++ b/core-java/src/test/java/com/baeldung/asciiart/AsciiArtTest.java @@ -0,0 +1,20 @@ +package com.baeldung.asciiart; + +import java.awt.Font; + +import org.junit.Test; + +import com.baeldung.asciiart.AsciiArt.Settings; + +public class AsciiArtTest { + + @Test + public void givenTextWithAsciiCharacterAndSettings_shouldPrintAsciiArt() { + AsciiArt asciiArt = new AsciiArt(); + String text = "BAELDUNG"; + Settings settings = asciiArt.new Settings(new Font("SansSerif", Font.BOLD, 24), text.length() * 30, 30); // 30 pixel width per character + + asciiArt.drawString(text, "*", settings); + } + +} diff --git a/core-java/src/test/java/com/baeldung/casting/CastingTest.java b/core-java/src/test/java/com/baeldung/casting/CastingTest.java new file mode 100644 index 0000000000..dd95e0dd80 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/casting/CastingTest.java @@ -0,0 +1,80 @@ +package com.baeldung.casting; + +import org.junit.Test; +import static org.junit.Assert.*; +import java.util.ArrayList; +import java.util.List; + +public class CastingTest { + + @Test + public void whenPrimitiveConverted_thenValueChanged() { + double myDouble = 1.1; + int myInt = (int) myDouble; + + assertNotEquals(myDouble, myInt); + } + + @Test + public void whenUpcast_thenInstanceUnchanged() { + Cat cat = new Cat(); + Animal animal = cat; + animal = (Animal) cat; + assertTrue(animal instanceof Cat); + } + + @Test + public void whenUpcastToObject_thenInstanceUnchanged() { + Object object = new Animal(); + assertTrue(object instanceof Animal); + } + + @Test + public void whenUpcastToInterface_thenInstanceUnchanged() { + Mew mew = new Cat(); + assertTrue(mew instanceof Cat); + } + + @Test + public void whenUpcastToAnimal_thenOverridenMethodsCalled() { + List animals = new ArrayList<>(); + animals.add(new Cat()); + animals.add(new Dog()); + new AnimalFeeder().feed(animals); + } + + @Test + public void whenDowncastToCat_thenMeowIsCalled() { + Animal animal = new Cat(); + ((Cat) animal).meow(); + } + + @Test(expected = ClassCastException.class) + public void whenDownCastWithoutCheck_thenExceptionThrown() { + List animals = new ArrayList<>(); + animals.add(new Cat()); + animals.add(new Dog()); + new AnimalFeeder().uncheckedFeed(animals); + } + + @Test + public void whenDowncastToCatWithCastMethod_thenMeowIsCalled() { + Animal animal = new Cat(); + if (Cat.class.isInstance(animal)) { + Cat cat = Cat.class.cast(animal); + cat.meow(); + } + } + + @Test + public void whenParameterCat_thenOnlyCatsFed() { + List animals = new ArrayList<>(); + animals.add(new Cat()); + animals.add(new Dog()); + AnimalFeederGeneric catFeeder = new AnimalFeederGeneric(Cat.class); + List fedAnimals = catFeeder.feed(animals); + + assertTrue(fedAnimals.size() == 1); + assertTrue(fedAnimals.get(0) instanceof Cat); + } +} diff --git a/core-java/src/test/java/com/baeldung/classloader/CustomClassLoaderTest.java b/core-java/src/test/java/com/baeldung/classloader/CustomClassLoaderTest.java new file mode 100644 index 0000000000..9f3c751805 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/classloader/CustomClassLoaderTest.java @@ -0,0 +1,23 @@ +package com.baeldung.classloader; + +import org.junit.Test; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +public class CustomClassLoaderTest { + + @Test + public void customLoader() throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException { + + CustomClassLoader customClassLoader = new CustomClassLoader(); + Class c = customClassLoader.getClass(PrintClassLoader.class.getName()); + + Object ob = c.newInstance(); + + Method md = c.getMethod("printClassLoaders"); + md.invoke(ob); + + } + +} diff --git a/core-java/src/test/java/com/baeldung/classloader/PrintClassLoaderTest.java b/core-java/src/test/java/com/baeldung/classloader/PrintClassLoaderTest.java new file mode 100644 index 0000000000..f44a5cef09 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/classloader/PrintClassLoaderTest.java @@ -0,0 +1,14 @@ +package com.baeldung.classloader; + +import org.junit.Test; + +import static org.junit.Assert.*; + +public class PrintClassLoaderTest { + @Test(expected = ClassNotFoundException.class) + public void givenAppClassLoader_whenParentClassLoader_thenClassNotFoundException() throws Exception { + PrintClassLoader sampleClassLoader = (PrintClassLoader) Class.forName(PrintClassLoader.class.getName()).newInstance(); + sampleClassLoader.printClassLoaders(); + Class.forName(PrintClassLoader.class.getName(), true, PrintClassLoader.class.getClassLoader().getParent()); + } +} \ No newline at end of file diff --git a/core-java/src/test/java/com/baeldung/decimalformat/DecimalFormatExamplesTest.java b/core-java/src/test/java/com/baeldung/decimalformat/DecimalFormatExamplesTest.java new file mode 100644 index 0000000000..8acd4e023e --- /dev/null +++ b/core-java/src/test/java/com/baeldung/decimalformat/DecimalFormatExamplesTest.java @@ -0,0 +1,116 @@ +package com.baeldung.decimalformat; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.math.BigDecimal; +import java.text.DecimalFormat; +import java.text.DecimalFormatSymbols; +import java.text.NumberFormat; +import java.text.ParseException; +import java.util.Locale; + +import org.junit.Test; + +public class DecimalFormatExamplesTest { + + double d = 1234567.89; + + @Test + public void givenSimpleDecimal_WhenFormatting_ThenCorrectOutput() { + + assertThat(new DecimalFormat("#.##", new DecimalFormatSymbols(Locale.ENGLISH)).format(d)) + .isEqualTo("1234567.89"); + + assertThat(new DecimalFormat("0.00", new DecimalFormatSymbols(Locale.ENGLISH)).format(d)) + .isEqualTo("1234567.89"); + + assertThat(new DecimalFormat("#########.###", new DecimalFormatSymbols(Locale.ENGLISH)).format(d)) + .isEqualTo("1234567.89"); + + assertThat(new DecimalFormat("000000000.000", new DecimalFormatSymbols(Locale.ENGLISH)).format(d)) + .isEqualTo("001234567.890"); + + } + + @Test + public void givenSmallerDecimalPattern_WhenFormatting_ThenRounding() { + + assertThat(new DecimalFormat("#.#", new DecimalFormatSymbols(Locale.ENGLISH)).format(d)).isEqualTo("1234567.9"); + + assertThat(new DecimalFormat("#", new DecimalFormatSymbols(Locale.ENGLISH)).format(d)).isEqualTo("1234568"); + + } + + @Test + public void givenGroupingSeparator_WhenFormatting_ThenGroupedOutput() { + + assertThat(new DecimalFormat("#,###.#", new DecimalFormatSymbols(Locale.ENGLISH)).format(d)) + .isEqualTo("1,234,567.9"); + + assertThat(new DecimalFormat("#,###", new DecimalFormatSymbols(Locale.ENGLISH)).format(d)) + .isEqualTo("1,234,568"); + + } + + @Test + public void givenMixedPattern_WhenFormatting_ThenCorrectOutput() { + + assertThat(new DecimalFormat("The # number", new DecimalFormatSymbols(Locale.ENGLISH)).format(d)) + .isEqualTo("The 1234568 number"); + + assertThat(new DecimalFormat("The '#' # number", new DecimalFormatSymbols(Locale.ENGLISH)).format(d)) + .isEqualTo("The # 1234568 number"); + + } + + @Test + public void givenLocales_WhenFormatting_ThenCorrectOutput() { + + assertThat(new DecimalFormat("#,###.##", new DecimalFormatSymbols(Locale.ENGLISH)).format(d)) + .isEqualTo("1,234,567.89"); + + assertThat(new DecimalFormat("#,###.##", new DecimalFormatSymbols(Locale.ITALIAN)).format(d)) + .isEqualTo("1.234.567,89"); + + assertThat(new DecimalFormat("#,###.##", DecimalFormatSymbols.getInstance(new Locale("it", "IT"))).format(d)) + .isEqualTo("1.234.567,89"); + + } + + @Test + public void givenE_WhenFormatting_ThenScientificNotation() { + + assertThat(new DecimalFormat("00.#######E0", new DecimalFormatSymbols(Locale.ENGLISH)).format(d)) + .isEqualTo("12.3456789E5"); + + assertThat(new DecimalFormat("000.000000E0", new DecimalFormatSymbols(Locale.ENGLISH)).format(d)) + .isEqualTo("123.456789E4"); + + assertThat(new DecimalFormat("##0.######E0", new DecimalFormatSymbols(Locale.ENGLISH)).format(d)) + .isEqualTo("1.23456789E6"); + + assertThat(new DecimalFormat("###.000000E0", new DecimalFormatSymbols(Locale.ENGLISH)).format(d)) + .isEqualTo("1.23456789E6"); + + } + + @Test + public void givenString_WhenParsing_ThenCorrectOutput() throws ParseException { + + assertThat(new DecimalFormat("", new DecimalFormatSymbols(Locale.ENGLISH)).parse("1234567.89")) + .isEqualTo(1234567.89); + + assertThat(new DecimalFormat("", new DecimalFormatSymbols(Locale.ITALIAN)).parse("1.234.567,89")) + .isEqualTo(1234567.89); + + } + + @Test + public void givenStringAndBigDecimalFlag_WhenParsing_ThenCorrectOutput() throws ParseException { + + NumberFormat nf = new DecimalFormat("", new DecimalFormatSymbols(Locale.ENGLISH)); + ((DecimalFormat) nf).setParseBigDecimal(true); + assertThat(nf.parse("1234567.89")).isEqualTo(BigDecimal.valueOf(1234567.89)); + } + +} diff --git a/core-java/src/test/java/com/baeldung/deepcopy/DeepCopyUnitTest.java b/core-java/src/test/java/com/baeldung/deepcopy/DeepCopyUnitTest.java new file mode 100644 index 0000000000..196b69fbf7 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/deepcopy/DeepCopyUnitTest.java @@ -0,0 +1,128 @@ +package com.baeldung.deepcopy; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.IOException; + +import org.apache.commons.lang.SerializationUtils; +import org.junit.Ignore; +import org.junit.Test; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.gson.Gson; + +public class DeepCopyUnitTest { + + @Test + public void whenCreatingDeepCopyWithCopyConstructor_thenObjectsShouldNotBeSame() { + + Address address = new Address("Downing St 10", "London", "England"); + User pm = new User("Prime", "Minister", address); + + User deepCopy = new User(pm); + + assertThat(deepCopy).isNotSameAs(pm); + } + + @Test + public void whenModifyingOriginalObject_thenConstructorCopyShouldNotChange() { + Address address = new Address("Downing St 10", "London", "England"); + User pm = new User("Prime", "Minister", address); + User deepCopy = new User(pm); + + address.setCountry("Great Britain"); + + assertThat(deepCopy.getAddress().getCountry()).isNotEqualTo(pm.getAddress().getCountry()); + } + + @Test + public void whenModifyingOriginalObject_thenCloneCopyShouldNotChange() { + Address address = new Address("Downing St 10", "London", "England"); + User pm = new User("Prime", "Minister", address); + User deepCopy = (User) pm.clone(); + + address.setCountry("Great Britain"); + + assertThat(deepCopy.getAddress().getCountry()).isNotEqualTo(pm.getAddress().getCountry()); + } + + @Test + public void whenModifyingOriginalObject_thenCommonsCloneShouldNotChange() { + Address address = new Address("Downing St 10", "London", "England"); + User pm = new User("Prime", "Minister", address); + User deepCopy = (User) SerializationUtils.clone(pm); + + address.setCountry("Great Britain"); + + assertThat(deepCopy.getAddress().getCountry()).isNotEqualTo(pm.getAddress().getCountry()); + } + + @Test + public void whenModifyingOriginalObject_thenGsonCloneShouldNotChange() { + Address address = new Address("Downing St 10", "London", "England"); + User pm = new User("Prime", "Minister", address); + Gson gson = new Gson(); + User deepCopy = gson.fromJson(gson.toJson(pm), User.class); + + address.setCountry("Great Britain"); + + assertThat(deepCopy.getAddress().getCountry()).isNotEqualTo(pm.getAddress().getCountry()); + } + + @Test + public void whenModifyingOriginalObject_thenJacksonCopyShouldNotChange() throws IOException { + Address address = new Address("Downing St 10", "London", "England"); + User pm = new User("Prime", "Minister", address); + ObjectMapper objectMapper = new ObjectMapper(); + User deepCopy = objectMapper.readValue(objectMapper.writeValueAsString(pm), User.class); + + address.setCountry("Great Britain"); + + assertThat(deepCopy.getAddress().getCountry()).isNotEqualTo(pm.getAddress().getCountry()); + } + + @Test + @Ignore + public void whenMakingCopies_thenShowHowLongEachMethodTakes() throws CloneNotSupportedException, IOException { + int times = 1000000; + Address address = new Address("Downing St 10", "London", "England"); + User pm = new User("Prime", "Minister", address); + + long start = System.currentTimeMillis(); + for (int i = 0; i < times; i++) { + User primeMinisterClone = (User) SerializationUtils.clone(pm); + } + long end = System.currentTimeMillis(); + System.out.println("Cloning with Apache Commons Lang took " + (end - start) + " milliseconds."); + + start = System.currentTimeMillis(); + Gson gson = new Gson(); + for (int i = 0; i < times; i++) { + User primeMinisterClone = gson.fromJson(gson.toJson(pm), User.class); + } + end = System.currentTimeMillis(); + System.out.println("Cloning with Gson took " + (end - start) + " milliseconds."); + + start = System.currentTimeMillis(); + for (int i = 0; i < times; i++) { + User primeMinisterClone = new User(pm); + } + end = System.currentTimeMillis(); + System.out.println("Cloning with the copy constructor took " + (end - start) + " milliseconds."); + + start = System.currentTimeMillis(); + for (int i = 0; i < times; i++) { + User primeMinisterClone = (User) pm.clone(); + } + end = System.currentTimeMillis(); + System.out.println("Cloning with Cloneable interface took " + (end - start) + " milliseconds."); + + start = System.currentTimeMillis(); + ObjectMapper objectMapper = new ObjectMapper(); + for (int i = 0; i < times; i++) { + User primeMinisterClone = objectMapper.readValue(objectMapper.writeValueAsString(pm), User.class); + } + end = System.currentTimeMillis(); + System.out.println("Cloning with Jackson took " + (end - start) + " milliseconds."); + } +} diff --git a/core-java/src/test/java/com/baeldung/deepcopy/ShallowCopyUnitTest.java b/core-java/src/test/java/com/baeldung/deepcopy/ShallowCopyUnitTest.java new file mode 100644 index 0000000000..57660fadf1 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/deepcopy/ShallowCopyUnitTest.java @@ -0,0 +1,33 @@ +package com.baeldung.deepcopy; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.Test; + +public class ShallowCopyUnitTest { + + + @Test + public void whenShallowCopying_thenObjectsShouldNotBeSame() { + + Address address = new Address("Downing St 10", "London", "England"); + User pm = new User("Prime", "Minister", address); + + User shallowCopy = new User(pm.getFirstName(), pm.getLastName(), pm.getAddress()); + + assertThat(shallowCopy) + .isNotSameAs(pm); + } + + @Test + public void whenModifyingOriginalObject_thenCopyShouldChange() { + Address address = new Address("Downing St 10", "London", "England"); + User pm = new User("Prime", "Minister", address); + User shallowCopy = new User(pm.getFirstName(), pm.getLastName(), pm.getAddress()); + + address.setCountry("Great Britain"); + + assertThat(shallowCopy.getAddress().getCountry()) + .isEqualTo(pm.getAddress().getCountry()); + } +} diff --git a/core-java/src/test/java/com/baeldung/designpatterns/flyweight/FlyweightUnitTest.java b/core-java/src/test/java/com/baeldung/designpatterns/flyweight/FlyweightUnitTest.java new file mode 100644 index 0000000000..645e2fd459 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/designpatterns/flyweight/FlyweightUnitTest.java @@ -0,0 +1,42 @@ +package com.baeldung.designpatterns.flyweight; + +import java.awt.Color; + +import org.junit.Assert; +import org.junit.Test; + +/** + * Unit test for {@link VehicleFactory}. + * + * @author Donato Rimenti + */ +public class FlyweightUnitTest { + + /** + * Checks that when the {@link VehicleFactory} is asked to provide two + * vehicles of different colors, the objects returned are different. + */ + @Test + public void givenDifferentFlyweightObjects_whenEquals_thenFalse() { + Vehicle blackVehicle = VehicleFactory.createVehicle(Color.BLACK); + Vehicle blueVehicle = VehicleFactory.createVehicle(Color.BLUE); + + Assert.assertNotNull("Object returned by the factory is null!", blackVehicle); + Assert.assertNotNull("Object returned by the factory is null!", blueVehicle); + Assert.assertNotEquals("Objects returned by the factory are equals!", blackVehicle, blueVehicle); + } + + /** + * Checks that when the {@link VehicleFactory} is asked to provide two + * vehicles of the same colors, the same object is returned twice. + */ + @Test + public void givenSameFlyweightObjects_whenEquals_thenTrue() { + Vehicle blackVehicle = VehicleFactory.createVehicle(Color.BLACK); + Vehicle anotherBlackVehicle = VehicleFactory.createVehicle(Color.BLACK); + + Assert.assertNotNull("Object returned by the factory is null!", blackVehicle); + Assert.assertNotNull("Object returned by the factory is null!", anotherBlackVehicle); + Assert.assertEquals("Objects returned by the factory are not equals!", blackVehicle, anotherBlackVehicle); + } +} diff --git a/core-java/src/test/java/com/baeldung/dst/DaylightSavingTimeExamplesTest.java b/core-java/src/test/java/com/baeldung/dst/DaylightSavingTimeExamplesTest.java new file mode 100644 index 0000000000..8fec58f111 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/dst/DaylightSavingTimeExamplesTest.java @@ -0,0 +1,69 @@ +package com.baeldung.dst; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; +import java.util.Locale; +import java.util.TimeZone; + +import org.junit.Ignore; +import org.junit.Test; + +public class DaylightSavingTimeExamplesTest { + + @Test + public void givenItalianTimeZone_WhenDSTHappens_ThenCorrectlyShiftTimeZone() throws ParseException { + TimeZone.setDefault(TimeZone.getTimeZone("Europe/Rome")); + + TimeZone tz = TimeZone.getTimeZone("Europe/Rome"); + Calendar cal = Calendar.getInstance(tz, Locale.ITALIAN); + DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.ITALIAN); + Date dateBeforeDST = df.parse("2018-03-25 01:55"); + prettyPrint(cal.getTimeZone()); + + cal.setTime(dateBeforeDST); + System.out.println("Before DST (00:55 UTC - 01:55 GMT+1) = " + dateBeforeDST); + + System.out.println("With this Calendar " + (cal.get(Calendar.ZONE_OFFSET) + cal.get(Calendar.DST_OFFSET)) / (60 * 1000) + " minutes must be added to UTC (GMT TimeZone) to get a correct date for this TimeZone\n"); + assertThat(cal.get(Calendar.ZONE_OFFSET)).isEqualTo(3600000); + assertThat(cal.get(Calendar.DST_OFFSET)).isEqualTo(0); + + cal.add(Calendar.MINUTE, 10); + + Date dateAfterDST = cal.getTime(); + + System.out.println(" After DST (01:05 UTC - 03:05 GMT+2) = " + dateAfterDST); + System.out.println("With this Calendar " + (cal.get(Calendar.ZONE_OFFSET) + cal.get(Calendar.DST_OFFSET)) / (60 * 1000) + " minutes must be added to UTC (GMT TimeZone) to get a correct date for this TimeZone\n"); + assertThat(cal.get(Calendar.DST_OFFSET)).isEqualTo(3600000); + assertThat(dateAfterDST).isEqualTo(df.parse("2018-03-25 03:05")); + + Long deltaBetweenDatesInMillis = dateAfterDST.getTime() - dateBeforeDST.getTime(); + Long tenMinutesInMillis = (1000L * 60 * 10); + assertThat(deltaBetweenDatesInMillis).isEqualTo(tenMinutesInMillis); + } + + private void prettyPrint(TimeZone tz) { + + //@formatter:off + System.out.println(String.format( + " Zone ID = %s (%s)\n" + + " RawOffset = %s minutes\n" + + " DST = %s minutes\n" + + " -----------------------------------------", + tz.getID(), tz.getDisplayName(), tz.getRawOffset()/60000, tz.getDSTSavings()/60000)); + //@formatter:on + } + + @Test + @Ignore + public void whenIterating_ThenPrintAllTimeZones() { + for (String id : TimeZone.getAvailableIDs()) { + TimeZone tz = TimeZone.getTimeZone(id); + prettyPrint(tz); + } + } +} diff --git a/core-java/src/test/java/com/baeldung/dst/DaylightSavingTimeJavaTimeExamplesTest.java b/core-java/src/test/java/com/baeldung/dst/DaylightSavingTimeJavaTimeExamplesTest.java new file mode 100644 index 0000000000..78847033ac --- /dev/null +++ b/core-java/src/test/java/com/baeldung/dst/DaylightSavingTimeJavaTimeExamplesTest.java @@ -0,0 +1,56 @@ +package com.baeldung.dst; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.text.ParseException; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.time.temporal.ChronoUnit; +import java.util.TimeZone; + +import org.junit.Test; + +public class DaylightSavingTimeJavaTimeExamplesTest { + + @Test + public void givenItalianTimeZone_WhenDSTHappens_ThenCorrectlyShiftTimeZone() throws ParseException { + ZoneId italianZoneId = ZoneId.of("Europe/Rome"); + + LocalDateTime localDateTimeBeforeDST = LocalDateTime.of(2018, 3, 25, 1, 55); + System.out.println(localDateTimeBeforeDST); + assertThat(localDateTimeBeforeDST.toString()).isEqualTo("2018-03-25T01:55"); + + ZonedDateTime zonedDateTimeBeforeDST = localDateTimeBeforeDST.atZone(italianZoneId); + prettyPrint(zonedDateTimeBeforeDST); + assertThat(zonedDateTimeBeforeDST.toString()).isEqualTo("2018-03-25T01:55+01:00[Europe/Rome]"); + + ZonedDateTime zonedDateTimeAfterDST = zonedDateTimeBeforeDST.plus(10, ChronoUnit.MINUTES); + prettyPrint(zonedDateTimeAfterDST); + assertThat(zonedDateTimeAfterDST.toString()).isEqualTo("2018-03-25T03:05+02:00[Europe/Rome]"); + + Long deltaBetweenDatesInMinutes = ChronoUnit.MINUTES.between(zonedDateTimeBeforeDST, zonedDateTimeAfterDST); + assertThat(deltaBetweenDatesInMinutes).isEqualTo(10); + + } + + private void prettyPrint(ZonedDateTime zdt) { + //@formatter:off + System.out.println(String.format( + " ZonedDateTime = %s\n" + + " Zone ID = %s (%s)\n" + + " RawOffset = %s minutes\n" + + " -----------------------------------------", + zdt, zdt.getZone(), zdt.getZone().getId(), zdt.getOffset().getTotalSeconds()/60)); + //@formatter:on + } + + @Test + public void whenCounting_ThenPrintDifferencesBetweenAPIs() { + System.out.println("Total java.time.ZoneId count : " + ZoneId.getAvailableZoneIds() + .size()); + System.out.println("Total java.util.TimeZone Id count : " + TimeZone.getAvailableIDs().length); + } + + +} diff --git a/core-java/src/test/java/com/baeldung/externalizable/ExternalizableUnitTest.java b/core-java/src/test/java/com/baeldung/externalizable/ExternalizableUnitTest.java new file mode 100644 index 0000000000..651364fb13 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/externalizable/ExternalizableUnitTest.java @@ -0,0 +1,71 @@ +package com.baeldung.externalizable; + +import org.junit.Test; + +import java.io.*; + +import static org.junit.Assert.assertTrue; + +public class ExternalizableUnitTest { + + private final static String OUTPUT_FILE = "externalizable.txt"; + + @Test + public void whenSerializing_thenUseExternalizable() throws IOException, ClassNotFoundException { + + Country c = new Country(); + c.setCapital("Yerevan"); + c.setCode(374); + c.setName("Armenia"); + + FileOutputStream fileOutputStream = new FileOutputStream(OUTPUT_FILE); + ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream); + c.writeExternal(objectOutputStream); + + objectOutputStream.flush(); + objectOutputStream.close(); + fileOutputStream.close(); + + FileInputStream fileInputStream = new FileInputStream(OUTPUT_FILE); + ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream); + + Country c2 = new Country(); + c2.readExternal(objectInputStream); + + objectInputStream.close(); + fileInputStream.close(); + + assertTrue(c2.getCode() == c.getCode()); + assertTrue(c2.getName().equals(c.getName())); + } + + @Test + public void whenInheritanceSerialization_then_UseExternalizable() throws IOException, ClassNotFoundException { + + Region r = new Region(); + r.setCapital("Yerevan"); + r.setCode(374); + r.setName("Armenia"); + r.setClimate("Mediterranean"); + r.setPopulation(120.000); + + FileOutputStream fileOutputStream = new FileOutputStream(OUTPUT_FILE); + ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream); + r.writeExternal(objectOutputStream); + + objectOutputStream.flush(); + objectOutputStream.close(); + fileOutputStream.close(); + + FileInputStream fileInputStream = new FileInputStream(OUTPUT_FILE); + ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream); + + Region r2 = new Region(); + r2.readExternal(objectInputStream); + + objectInputStream.close(); + fileInputStream.close(); + + assertTrue(r2.getPopulation() == null); + } +} diff --git a/core-java/src/test/java/com/baeldung/finalkeyword/FinalUnitTest.java b/core-java/src/test/java/com/baeldung/finalkeyword/FinalUnitTest.java new file mode 100644 index 0000000000..b09a9ec0bb --- /dev/null +++ b/core-java/src/test/java/com/baeldung/finalkeyword/FinalUnitTest.java @@ -0,0 +1,33 @@ +package com.baeldung.finalkeyword; + +import org.junit.Test; +import static org.junit.Assert.*; + +public class FinalUnitTest { + + @Test + public void whenChangedFinalClassProperties_thenChanged() { + Cat cat = new Cat(); + cat.setWeight(1); + + assertEquals(1, cat.getWeight()); + + } + + @Test + public void whenFinalVariableAssign_thenOnlyOnce() { + final int i; + i = 1; + // i=2; + } + + @Test + public void whenChangedFinalReference_thenChanged() { + + final Cat cat = new Cat(); + // cat=new Cat(); + cat.setWeight(5); + + assertEquals(5, cat.getWeight()); + } +} diff --git a/core-java/src/test/java/com/baeldung/inheritance/AppTest.java b/core-java/src/test/java/com/baeldung/inheritance/AppTest.java new file mode 100644 index 0000000000..1235761aba --- /dev/null +++ b/core-java/src/test/java/com/baeldung/inheritance/AppTest.java @@ -0,0 +1,46 @@ +package com.baeldung.inheritance; + +import com.baeldung.inheritance.*; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +public class AppTest extends TestCase { + + public AppTest(String testName) { + super( testName ); + } + + public static Test suite() { + return new TestSuite(AppTest.class); + } + + @SuppressWarnings("static-access") + public void testStaticMethodUsingBaseClassVariable() { + Car first = new ArmoredCar(); + assertEquals("Car", first.msg()); + } + + @SuppressWarnings("static-access") + public void testStaticMethodUsingDerivedClassVariable() { + ArmoredCar second = new ArmoredCar(); + assertEquals("ArmoredCar", second.msg()); + } + + public void testAssignArmoredCarToCar() { + Employee e1 = new Employee("Shreya", new ArmoredCar()); + assertNotNull(e1.getCar()); + } + + public void testAssignSpaceCarToCar() { + Employee e2 = new Employee("Paul", new SpaceCar()); + assertNotNull(e2.getCar()); + } + + public void testBMWToCar() { + Employee e3 = new Employee("Pavni", new BMW()); + assertNotNull(e3.getCar()); + } + +} diff --git a/core-java/src/test/java/com/baeldung/java/list/CustomListUnitTest.java b/core-java/src/test/java/com/baeldung/java/list/CustomListUnitTest.java new file mode 100644 index 0000000000..9ea42e88e8 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/java/list/CustomListUnitTest.java @@ -0,0 +1,296 @@ +package com.baeldung.java.list; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +import org.junit.Test; + +public class CustomListUnitTest { + @Test + public void givenEmptyList_whenIsEmpty_thenTrueIsReturned() { + List list = new CustomList<>(); + + assertTrue(list.isEmpty()); + } + + @Test + public void givenNonEmptyList_whenIsEmpty_thenFalseIsReturned() { + List list = new CustomList<>(); + list.add(null); + + assertFalse(list.isEmpty()); + } + + @Test + public void givenListWithAnElement_whenSize_thenOneIsReturned() { + List list = new CustomList<>(); + list.add(null); + + assertEquals(1, list.size()); + } + + @Test + public void givenListWithAnElement_whenGet_thenThatElementIsReturned() { + List list = new CustomList<>(); + list.add("baeldung"); + Object element = list.get(0); + + assertEquals("baeldung", element); + } + + @Test + public void givenEmptyList_whenElementIsAdded_thenGetReturnsThatElement() { + List list = new CustomList<>(); + boolean succeeded = list.add(null); + + assertTrue(succeeded); + } + + @Test + public void givenListWithAnElement_whenAnotherIsAdded_thenGetReturnsBoth() { + List list = new CustomList<>(); + list.add("baeldung"); + list.add(".com"); + Object element1 = list.get(0); + Object element2 = list.get(1); + + assertEquals("baeldung", element1); + assertEquals(".com", element2); + } + + @Test(expected = UnsupportedOperationException.class) + public void whenAddToSpecifiedIndex_thenExceptionIsThrown() { + new CustomList<>().add(0, null); + } + + @Test(expected = UnsupportedOperationException.class) + public void whenAddAllToTheEnd_thenExceptionIsThrown() { + Collection collection = new ArrayList<>(); + List list = new CustomList<>(); + list.addAll(collection); + } + + @Test(expected = UnsupportedOperationException.class) + public void whenAddAllToSpecifiedIndex_thenExceptionIsThrown() { + Collection collection = new ArrayList<>(); + List list = new CustomList<>(); + list.addAll(0, collection); + } + + @Test(expected = UnsupportedOperationException.class) + public void whenRemoveAtSpecifiedIndex_thenExceptionIsThrown() { + List list = new CustomList<>(); + list.add("baeldung"); + list.remove(0); + } + + @Test(expected = UnsupportedOperationException.class) + public void whenRemoveSpecifiedElement_thenExceptionIsThrown() { + List list = new CustomList<>(); + list.add("baeldung"); + list.remove("baeldung"); + } + + @Test(expected = UnsupportedOperationException.class) + public void whenRemoveAll_thenExceptionIsThrown() { + Collection collection = new ArrayList<>(); + collection.add("baeldung"); + List list = new CustomList<>(); + list.removeAll(collection); + } + + @Test(expected = UnsupportedOperationException.class) + public void whenRetainAll_thenExceptionIsThrown() { + Collection collection = new ArrayList<>(); + collection.add("baeldung"); + List list = new CustomList<>(); + list.add("baeldung"); + list.retainAll(collection); + } + + @Test + public void givenEmptyList_whenContains_thenFalseIsReturned() { + List list = new CustomList<>(); + + assertFalse(list.contains(null)); + } + + @Test + public void givenListWithAnElement_whenContains_thenTrueIsReturned() { + List list = new CustomList<>(); + list.add("baeldung"); + + assertTrue(list.contains("baeldung")); + } + + @Test + public void givenListWithAnElement_whenContainsAll_thenTrueIsReturned() { + Collection collection = new ArrayList<>(); + collection.add("baeldung"); + List list = new CustomList<>(); + list.add("baeldung"); + + assertTrue(list.containsAll(collection)); + } + + @Test + public void givenList_whenContainsAll_thenEitherTrueOrFalseIsReturned() { + Collection collection1 = new ArrayList<>(); + collection1.add("baeldung"); + collection1.add(".com"); + Collection collection2 = new ArrayList<>(); + collection2.add("baeldung"); + + List list = new CustomList<>(); + list.add("baeldung"); + + assertFalse(list.containsAll(collection1)); + assertTrue(list.containsAll(collection2)); + } + + @Test + public void givenList_whenSet_thenOldElementIsReturned() { + List list = new CustomList<>(); + list.add("baeldung"); + Object element = list.set(0, null); + + assertEquals("baeldung", element); + assertNull(list.get(0)); + } + + @Test + public void givenList_whenClear_thenAllElementsAreRemoved() { + List list = new CustomList<>(); + list.add("baeldung"); + list.clear(); + + assertTrue(list.isEmpty()); + } + + @Test + public void givenList_whenIndexOf_thenIndexZeroIsReturned() { + List list = new CustomList<>(); + list.add("baeldung"); + + assertEquals(0, list.indexOf("baeldung")); + } + + @Test + public void givenList_whenIndexOf_thenPositiveIndexOrMinusOneIsReturned() { + List list = new CustomList<>(); + list.add("baeldung"); + list.add(".com"); + list.add(".com"); + + assertEquals(1, list.indexOf(".com")); + assertEquals(-1, list.indexOf("com")); + } + + @Test + public void whenLastIndexOf_thenIndexZeroIsReturned() { + List list = new CustomList<>(); + list.add("baeldung"); + + assertEquals(0, list.lastIndexOf("baeldung")); + } + + @Test + public void whenLastIndexOf_thenPositiveIndexOrMinusOneIsReturned() { + List list = new CustomList<>(); + list.add("baeldung"); + list.add("baeldung"); + list.add(".com"); + + assertEquals(1, list.lastIndexOf("baeldung")); + assertEquals(-1, list.indexOf("com")); + } + + @Test + public void whenSubListZeroToOne_thenListContainingFirstElementIsReturned() { + List list = new CustomList<>(); + list.add("baeldung"); + List subList = list.subList(0, 1); + + assertEquals("baeldung", subList.get(0)); + } + + @Test + public void whenSubListOneToTwo_thenListContainingSecondElementIsReturned() { + List list = new CustomList<>(); + list.add("baeldung"); + list.add("."); + list.add("com"); + List subList = list.subList(1, 2); + + assertEquals(1, subList.size()); + assertEquals(".", subList.get(0)); + } + + @Test + public void givenListWithElements_whenToArray_thenArrayContainsThose() { + List list = new CustomList<>(); + list.add("baeldung"); + list.add(".com"); + Object[] array = list.toArray(); + + assertArrayEquals(new Object[] { "baeldung", ".com" }, array); + } + + @Test + public void givenListWithAnElement_whenToArray_thenInputArrayIsReturned() { + List list = new CustomList<>(); + list.add("baeldung"); + String[] input = new String[1]; + String[] output = list.toArray(input); + + assertArrayEquals(new String[] { "baeldung" }, input); + } + + @Test + public void whenToArrayIsCalledWithEmptyInputArray_thenNewArrayIsReturned() { + List list = new CustomList<>(); + list.add("baeldung"); + String[] input = {}; + String[] output = list.toArray(input); + + assertArrayEquals(new String[] { "baeldung" }, output); + } + + @Test + public void whenToArrayIsCalledWithLargerInput_thenOutputHasTrailingNull() { + List list = new CustomList<>(); + list.add("baeldung"); + String[] input = new String[2]; + String[] output = list.toArray(input); + + assertArrayEquals(new String[] { "baeldung", null }, output); + } + + @Test + public void givenListWithOneElement_whenIterator_thenThisElementIsNext() { + List list = new CustomList<>(); + list.add("baeldung"); + Iterator iterator = list.iterator(); + + assertTrue(iterator.hasNext()); + assertEquals("baeldung", iterator.next()); + } + + @Test + public void whenIteratorHasNextIsCalledTwice_thenTheSecondReturnsFalse() { + List list = new CustomList<>(); + list.add("baeldung"); + Iterator iterator = list.iterator(); + + iterator.next(); + assertFalse(iterator.hasNext()); + } +} diff --git a/core-java/src/test/java/com/baeldung/methodoverloadingoverriding/test/MethodOverloadingUnitTest.java b/core-java/src/test/java/com/baeldung/methodoverloadingoverriding/test/MethodOverloadingUnitTest.java new file mode 100644 index 0000000000..081a30c34a --- /dev/null +++ b/core-java/src/test/java/com/baeldung/methodoverloadingoverriding/test/MethodOverloadingUnitTest.java @@ -0,0 +1,41 @@ +package com.baeldung.methodoverloadingoverriding.test; + +import com.baeldung.methodoverloadingoverriding.util.Multiplier; +import org.junit.BeforeClass; +import org.junit.Test; +import static org.assertj.core.api.Assertions.*; + +public class MethodOverloadingUnitTest { + + private static Multiplier multiplier; + + @BeforeClass + public static void setUpMultiplierInstance() { + multiplier = new Multiplier(); + } + + @Test + public void givenMultiplierInstance_whenCalledMultiplyWithTwoIntegers_thenOneAssertion() { + assertThat(multiplier.multiply(10, 10)).isEqualTo(100); + } + + @Test + public void givenMultiplierInstance_whenCalledMultiplyWithTreeIntegers_thenOneAssertion() { + assertThat(multiplier.multiply(10, 10, 10)).isEqualTo(1000); + } + + @Test + public void givenMultiplierInstance_whenCalledMultiplyWithIntDouble_thenOneAssertion() { + assertThat(multiplier.multiply(10, 10.5)).isEqualTo(105.0); + } + + @Test + public void givenMultiplierInstance_whenCalledMultiplyWithDoubleDouble_thenOneAssertion() { + assertThat(multiplier.multiply(10.5, 10.5)).isEqualTo(110.25); + } + + @Test + public void givenMultiplierInstance_whenCalledMultiplyWithIntIntAndMatching_thenNoTypePromotion() { + assertThat(multiplier.multiply(10, 10)).isEqualTo(100); + } +} diff --git a/core-java/src/test/java/com/baeldung/methodoverloadingoverriding/test/MethodOverridingUnitTest.java b/core-java/src/test/java/com/baeldung/methodoverloadingoverriding/test/MethodOverridingUnitTest.java new file mode 100644 index 0000000000..554ac121bc --- /dev/null +++ b/core-java/src/test/java/com/baeldung/methodoverloadingoverriding/test/MethodOverridingUnitTest.java @@ -0,0 +1,68 @@ +package com.baeldung.methodoverloadingoverriding.test; + +import com.baeldung.methodoverloadingoverriding.model.Car; +import com.baeldung.methodoverloadingoverriding.model.Vehicle; +import org.junit.BeforeClass; +import org.junit.Test; +import static org.assertj.core.api.Assertions.*; + +public class MethodOverridingUnitTest { + + private static Vehicle vehicle; + private static Car car; + + @BeforeClass + public static void setUpVehicleInstance() { + vehicle = new Vehicle(); + } + + @BeforeClass + public static void setUpCarInstance() { + car = new Car(); + } + + @Test + public void givenVehicleInstance_whenCalledAccelerate_thenOneAssertion() { + assertThat(vehicle.accelerate(100)).isEqualTo("The vehicle accelerates at : 100 MPH."); + } + + @Test + public void givenVehicleInstance_whenCalledRun_thenOneAssertion() { + assertThat(vehicle.run()).isEqualTo("The vehicle is running."); + } + + @Test + public void givenVehicleInstance_whenCalledStop_thenOneAssertion() { + assertThat(vehicle.stop()).isEqualTo("The vehicle has stopped."); + } + + @Test + public void givenCarInstance_whenCalledAccelerate_thenOneAssertion() { + assertThat(car.accelerate(80)).isEqualTo("The car accelerates at : 80 MPH."); + } + + @Test + public void givenCarInstance_whenCalledRun_thenOneAssertion() { + assertThat(car.run()).isEqualTo("The vehicle is running."); + } + + @Test + public void givenCarInstance_whenCalledStop_thenOneAssertion() { + assertThat(car.stop()).isEqualTo("The vehicle has stopped."); + } + + @Test + public void givenVehicleCarInstances_whenCalledAccelerateWithSameArgument_thenNotEqual() { + assertThat(vehicle.accelerate(100)).isNotEqualTo(car.accelerate(100)); + } + + @Test + public void givenVehicleCarInstances_whenCalledRun_thenEqual() { + assertThat(vehicle.run()).isEqualTo(car.run()); + } + + @Test + public void givenVehicleCarInstances_whenCalledStop_thenEqual() { + assertThat(vehicle.stop()).isEqualTo(car.stop()); + } +} diff --git a/core-java/src/test/java/com/baeldung/recursion/RecursionExampleTest.java b/core-java/src/test/java/com/baeldung/recursion/RecursionExampleTest.java new file mode 100644 index 0000000000..c65be24240 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/recursion/RecursionExampleTest.java @@ -0,0 +1,61 @@ +package com.baeldung.recursion; + +import org.junit.Assert; +import org.junit.Test; + +public class RecursionExampleTest { + + RecursionExample recursion = new RecursionExample(); + + @Test + public void testPowerOf10() { + int p0 = recursion.powerOf10(0); + int p1 = recursion.powerOf10(1); + int p4 = recursion.powerOf10(4); + + Assert.assertEquals(1, p0); + Assert.assertEquals(10, p1); + Assert.assertEquals(10000, p4); + } + + @Test + public void testFibonacci() { + int n0 = recursion.fibonacci(0); + int n1 = recursion.fibonacci(1); + int n7 = recursion.fibonacci(7); + + Assert.assertEquals(0, n0); + Assert.assertEquals(1, n1); + Assert.assertEquals(13, n7); + } + + @Test + public void testToBinary() { + String b0 = recursion.toBinary(0); + String b1 = recursion.toBinary(1); + String b10 = recursion.toBinary(10); + + Assert.assertEquals("0", b0); + Assert.assertEquals("1", b1); + Assert.assertEquals("1010", b10); + } + + @Test + public void testCalculateTreeHeight() { + BinaryNode root = new BinaryNode(1); + root.setLeft(new BinaryNode(1)); + root.setRight(new BinaryNode(1)); + + root.getLeft().setLeft(new BinaryNode(1)); + root.getLeft().getLeft().setRight(new BinaryNode(1)); + root.getLeft().getLeft().getRight().setLeft(new BinaryNode(1)); + + root.getRight().setLeft(new BinaryNode(1)); + root.getRight().getLeft().setRight(new BinaryNode(1)); + + int height = recursion.calculateTreeHeight(root); + + Assert.assertEquals(4, height); + } + +} diff --git a/core-java/src/test/java/com/baeldung/resourcebundle/ExampleResourceUnitTest.java b/core-java/src/test/java/com/baeldung/resourcebundle/ExampleResourceUnitTest.java new file mode 100644 index 0000000000..1ce4f1bb8f --- /dev/null +++ b/core-java/src/test/java/com/baeldung/resourcebundle/ExampleResourceUnitTest.java @@ -0,0 +1,39 @@ +package com.baeldung.resourcebundle; + +import org.junit.Test; + +import java.math.BigDecimal; +import java.util.Arrays; +import java.util.Locale; +import java.util.ResourceBundle; + +import static org.junit.Assert.*; + +public class ExampleResourceUnitTest { + + @Test + public void whenGetBundleExampleResourceForLocalePlPl_thenItShouldInheritPropertiesGreetingAndLanguage() { + Locale plLocale = new Locale("pl", "PL"); + + ResourceBundle exampleBundle = ResourceBundle.getBundle("com.baeldung.resourcebundle.ExampleResource", plLocale); + + assertTrue(exampleBundle.keySet() + .containsAll(Arrays.asList("toUsdRate", "cities", "greeting", "currency", "language"))); + assertEquals(exampleBundle.getString("greeting"), "cześć"); + assertEquals(exampleBundle.getObject("toUsdRate"), new BigDecimal("3.401")); + assertArrayEquals(exampleBundle.getStringArray("cities"), new String[] { "Warsaw", "Cracow" }); + } + + @Test + public void whenGetBundleExampleResourceForLocaleUs_thenItShouldContainOnlyGreeting() { + Locale usLocale = Locale.US; + + ResourceBundle exampleBundle = ResourceBundle.getBundle("com.baeldung.resourcebundle.ExampleResource", usLocale); + + assertFalse(exampleBundle.keySet() + .containsAll(Arrays.asList("toUsdRate", "cities", "currency", "language"))); + assertTrue(exampleBundle.keySet() + .containsAll(Arrays.asList("greeting"))); + } + +} diff --git a/core-java/src/test/java/com/baeldung/resourcebundle/PropertyResourceUnitTest.java b/core-java/src/test/java/com/baeldung/resourcebundle/PropertyResourceUnitTest.java new file mode 100644 index 0000000000..4da71567e1 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/resourcebundle/PropertyResourceUnitTest.java @@ -0,0 +1,62 @@ +package com.baeldung.resourcebundle; + +import org.junit.Test; + +import java.util.Arrays; +import java.util.Locale; +import java.util.ResourceBundle; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class PropertyResourceUnitTest { + + @Test + public void givenLocaleUsAsDefualt_whenGetBundleForLocalePlPl_thenItShouldContain3ButtonsAnd1Label() { + Locale.setDefault(Locale.US); + + ResourceBundle bundle = ResourceBundle.getBundle("resourcebundle.resource", new Locale("pl", "PL")); + + assertTrue(bundle.keySet() + .containsAll(Arrays.asList("backButton", "helloLabel", "cancelButton", "continueButton", "helloLabelNoEncoding"))); + } + + @Test + public void givenLocaleUsAsDefualt_whenGetBundleForLocaleFrFr_thenItShouldContainKeys1To3AndKey4() { + Locale.setDefault(Locale.US); + + ResourceBundle bundle = ResourceBundle.getBundle("resourcebundle.resource", new Locale("fr", "FR")); + + assertTrue(bundle.keySet() + .containsAll(Arrays.asList("deleteButton", "helloLabel", "cancelButton", "continueButton"))); + } + + @Test + public void givenLocaleChinaAsDefualt_whenGetBundleForLocaleFrFr_thenItShouldOnlyContainKeys1To3() { + Locale.setDefault(Locale.CHINA); + + ResourceBundle bundle = ResourceBundle.getBundle("resourcebundle.resource", new Locale("fr", "FR")); + + assertTrue(bundle.keySet() + .containsAll(Arrays.asList("continueButton", "helloLabel", "cancelButton"))); + } + + @Test + public void givenLocaleChinaAsDefualt_whenGetBundleForLocaleFrFrAndExampleControl_thenItShouldOnlyContainKey5() { + Locale.setDefault(Locale.CHINA); + + ResourceBundle bundle = ResourceBundle.getBundle("resourcebundle.resource", new Locale("fr", "FR"), new ExampleControl()); + + assertTrue(bundle.keySet() + .containsAll(Arrays.asList("backButton", "helloLabel"))); + } + + @Test + public void givenValuesDifferentlyEncoded_whenGetBundleForLocalePlPl_thenItShouldContain3ButtonsAnd1Label() { + ResourceBundle bundle = ResourceBundle.getBundle("resourcebundle.resource", new Locale("pl", "PL")); + + assertEquals(bundle.getString("helloLabel"), "cześć"); + assertEquals(bundle.getString("helloLabelNoEncoding"), "czeÅ\u009BÄ\u0087"); + } + +} diff --git a/core-java/src/test/java/com/baeldung/string/PalindromeTest.java b/core-java/src/test/java/com/baeldung/string/PalindromeTest.java new file mode 100644 index 0000000000..bc6fee2cd9 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/string/PalindromeTest.java @@ -0,0 +1,97 @@ +package com.baeldung.string; + +import static org.junit.Assert.*; +import org.junit.Test; + +public class PalindromeTest { + + private String[] words = { + "Anna", + "Civic", + "Kayak", + "Level", + "Madam", + }; + + private String[] sentences = { + "Sore was I ere I saw Eros", + "Euston saw I was not Sue", + "Too hot to hoot", + "No mists or frost Simon", + "Stella won no wallets" + }; + + private Palindrome palindrome = new Palindrome(); + + @Test + public void whenWord_shouldBePalindrome() { + for (String word : words) + assertTrue(palindrome.isPalindrome(word)); + } + + @Test + public void whenSentence_shouldBePalindrome() { + for (String sentence : sentences) + assertTrue(palindrome.isPalindrome(sentence)); + } + + @Test + public void whenReverseWord_shouldBePalindrome() { + for (String word : words) + assertTrue(palindrome.isPalindromeReverseTheString(word)); + } + + @Test + public void whenReverseSentence_shouldBePalindrome() { + for (String sentence : sentences) + assertTrue(palindrome.isPalindromeReverseTheString(sentence)); + } + + @Test + public void whenStringBuilderWord_shouldBePalindrome() { + for (String word : words) + assertTrue(palindrome.isPalindromeUsingStringBuilder(word)); + } + + @Test + public void whenStringBuilderSentence_shouldBePalindrome() { + for (String sentence : sentences) + assertTrue(palindrome.isPalindromeUsingStringBuilder(sentence)); + } + + @Test + public void whenStringBufferWord_shouldBePalindrome() { + for (String word : words) + assertTrue(palindrome.isPalindromeUsingStringBuffer(word)); + } + + @Test + public void whenStringBufferSentence_shouldBePalindrome() { + for (String sentence : sentences) + assertTrue(palindrome.isPalindromeUsingStringBuffer(sentence)); + } + + @Test + public void whenPalindromeRecursive_wordShouldBePalindrome() { + for (String word : words) + assertTrue(palindrome.isPalindromeRecursive(word)); + } + + @Test + public void whenPalindromeRecursive_sentenceShouldBePalindrome() { + for (String sentence : sentences) + assertTrue(palindrome.isPalindromeRecursive(sentence)); + } + + @Test + public void whenPalindromeStreams_wordShouldBePalindrome() { + for (String word : words) + assertTrue(palindrome.isPalindromeUsingIntStream(word)); + } + + @Test + public void whenPalindromeStreams_sentenceShouldBePalindrome() { + for (String sentence : sentences) + assertTrue(palindrome.isPalindromeUsingIntStream(sentence)); + } +} diff --git a/core-java/src/test/java/com/baeldung/string/StringComparisonTest.java b/core-java/src/test/java/com/baeldung/string/StringComparisonTest.java new file mode 100644 index 0000000000..5869676004 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/string/StringComparisonTest.java @@ -0,0 +1,154 @@ +package com.baeldung.string; + +import org.apache.commons.lang3.StringUtils; +import org.junit.Test; + +import java.util.Objects; + +import static org.assertj.core.api.Assertions.assertThat; + +public class StringComparisonTest { + + @Test + public void whenUsingComparisonOperator_ThenComparingStrings(){ + + String string1 = "using comparison operator"; + String string2 = "using comparison operator"; + String string3 = new String("using comparison operator"); + + assertThat(string1 == string2).isTrue(); + assertThat(string1 == string3).isFalse(); + } + + @Test + public void whenUsingEqualsMethod_ThenComparingStrings(){ + + String string1 = "using equals method"; + String string2 = "using equals method"; + + String string3 = "using EQUALS method"; + String string4 = new String("using equals method"); + + assertThat(string1.equals(string2)).isTrue(); + assertThat(string1.equals(string4)).isTrue(); + + assertThat(string1.equals(null)).isFalse(); + assertThat(string1.equals(string3)).isFalse(); + } + + @Test + public void whenUsingEqualsIgnoreCase_ThenComparingStrings(){ + + String string1 = "using equals ignore case"; + String string2 = "USING EQUALS IGNORE CASE"; + + assertThat(string1.equalsIgnoreCase(string2)).isTrue(); + } + + @Test + public void whenUsingCompareTo_ThenComparingStrings(){ + + String author = "author"; + String book = "book"; + String duplicateBook = "book"; + + assertThat(author.compareTo(book)).isEqualTo(-1); + assertThat(book.compareTo(author)).isEqualTo(1); + assertThat(duplicateBook.compareTo(book)).isEqualTo(0); + } + + @Test + public void whenUsingCompareToIgnoreCase_ThenComparingStrings(){ + + String author = "Author"; + String book = "book"; + String duplicateBook = "BOOK"; + + assertThat(author.compareToIgnoreCase(book)).isEqualTo(-1); + assertThat(book.compareToIgnoreCase(author)).isEqualTo(1); + assertThat(duplicateBook.compareToIgnoreCase(book)).isEqualTo(0); + } + + @Test + public void whenUsingObjectsEqualsMethod_ThenComparingStrings(){ + + String string1 = "using objects equals"; + String string2 = "using objects equals"; + String string3 = new String("using objects equals"); + + assertThat(Objects.equals(string1, string2)).isTrue(); + assertThat(Objects.equals(string1, string3)).isTrue(); + + assertThat(Objects.equals(null, null)).isTrue(); + assertThat(Objects.equals(null, string1)).isFalse(); + } + + @Test + public void whenUsingEqualsOfApacheCommons_ThenComparingStrings(){ + + assertThat(StringUtils.equals(null, null)).isTrue(); + assertThat(StringUtils.equals(null, "equals method")).isFalse(); + assertThat(StringUtils.equals("equals method", "equals method")).isTrue(); + assertThat(StringUtils.equals("equals method", "EQUALS METHOD")).isFalse(); + } + + @Test + public void whenUsingEqualsIgnoreCaseOfApacheCommons_ThenComparingStrings(){ + + assertThat(StringUtils.equalsIgnoreCase(null, null)).isTrue(); + assertThat(StringUtils.equalsIgnoreCase(null, "equals method")).isFalse(); + assertThat(StringUtils.equalsIgnoreCase("equals method", "equals method")).isTrue(); + assertThat(StringUtils.equalsIgnoreCase("equals method", "EQUALS METHOD")).isTrue(); + } + + @Test + public void whenUsingEqualsAnyOf_ThenComparingStrings(){ + + assertThat(StringUtils.equalsAny(null, null, null)).isTrue(); + assertThat(StringUtils.equalsAny("equals any", "equals any", "any")).isTrue(); + assertThat(StringUtils.equalsAny("equals any", null, "equals any")).isTrue(); + assertThat(StringUtils.equalsAny(null, "equals", "any")).isFalse(); + assertThat(StringUtils.equalsAny("equals any", "EQUALS ANY", "ANY")).isFalse(); + } + + @Test + public void whenUsingEqualsAnyIgnoreCase_ThenComparingStrings(){ + + assertThat(StringUtils.equalsAnyIgnoreCase(null, null, null)).isTrue(); + assertThat(StringUtils.equalsAnyIgnoreCase("equals any", "equals any", "any")).isTrue(); + assertThat(StringUtils.equalsAnyIgnoreCase("equals any", null, "equals any")).isTrue(); + assertThat(StringUtils.equalsAnyIgnoreCase(null, "equals", "any")).isFalse(); + assertThat(StringUtils.equalsAnyIgnoreCase( + "equals any ignore case", "EQUALS ANY IGNORE CASE", "any")).isTrue(); + } + + @Test + public void whenUsingCompare_thenComparingStringsWithNulls(){ + + assertThat(StringUtils.compare(null, null)).isEqualTo(0); + assertThat(StringUtils.compare(null, "abc")).isEqualTo(-1); + + assertThat(StringUtils.compare("abc", "bbc")).isEqualTo(-1); + assertThat(StringUtils.compare("bbc", "abc")).isEqualTo(1); + assertThat(StringUtils.compare("abc", "abc")).isEqualTo(0); + } + + @Test + public void whenUsingCompareIgnoreCase_ThenComparingStringsWithNulls(){ + + assertThat(StringUtils.compareIgnoreCase(null, null)).isEqualTo(0); + assertThat(StringUtils.compareIgnoreCase(null, "abc")).isEqualTo(-1); + + assertThat(StringUtils.compareIgnoreCase("Abc", "bbc")).isEqualTo(-1); + assertThat(StringUtils.compareIgnoreCase("bbc", "ABC")).isEqualTo(1); + assertThat(StringUtils.compareIgnoreCase("abc", "ABC")).isEqualTo(0); + } + + @Test + public void whenUsingCompareWithNullIsLessOption_ThenComparingStrings(){ + + assertThat(StringUtils.compare(null, "abc", true)).isEqualTo(-1); + assertThat(StringUtils.compare(null, "abc", false)).isEqualTo(1); + } + +} diff --git a/core-java/src/test/java/com/baeldung/string/WhenCheckingPalindrome.java b/core-java/src/test/java/com/baeldung/string/WhenCheckingPalindrome.java deleted file mode 100644 index e3655a3140..0000000000 --- a/core-java/src/test/java/com/baeldung/string/WhenCheckingPalindrome.java +++ /dev/null @@ -1,114 +0,0 @@ -package com.baeldung.string; - -import java.util.Arrays; - -import org.junit.Assert; -import org.junit.Test; - -public class WhenCheckingPalindrome { - - private String[] words = { - "Anna", - "Civic", - "Kayak", - "Level", - "Madam", - }; - - private String[] sentences = { - "Sore was I ere I saw Eros", - "Euston saw I was not Sue", - "Too hot to hoot", - "No mists or frost Simon", - "Stella won no wallets" - }; - - private Palindrome palindrome = new Palindrome(); - - @Test - public void whenWord_shouldBePalindrome() { - for(String word:words) - Assert.assertTrue(palindrome.isPalindrome(word)); - } - - @Test - public void whenSentence_shouldBePalindrome() { - for(String sentence:sentences) - Assert.assertTrue(palindrome.isPalindrome(sentence)); - } - - @Test - public void whenReverseWord_shouldBePalindrome() { - for(String word:words) - Assert.assertTrue(palindrome.isPalindromeReverseTheString(word)); - } - - @Test - public void whenReverseSentence_shouldBePalindrome() { - for(String sentence:sentences) - Assert.assertTrue(palindrome.isPalindromeReverseTheString(sentence)); - } - - @Test - public void whenStringBuilderWord_shouldBePalindrome() { - for(String word:words) - Assert.assertTrue(palindrome.isPalindromeUsingStringBuilder(word)); - } - - @Test - public void whenStringBuilderSentence_shouldBePalindrome() { - for(String sentence:sentences) - Assert.assertTrue(palindrome.isPalindromeUsingStringBuilder(sentence)); - } - - @Test - public void whenStringBufferWord_shouldBePalindrome() { - for(String word:words) - Assert.assertTrue(palindrome.isPalindromeUsingStringBuffer(word)); - } - - @Test - public void whenStringBufferSentence_shouldBePalindrome() { - for(String sentence:sentences) - - Assert.assertTrue(palindrome.isPalindromeUsingStringBuffer(sentence)); - } - - @Test - public void whenPalindromeRecursive_wordShouldBePalindrome() { - for(String word:words) { - word = word.replaceAll("\\s+", "").toLowerCase(); - int backward = word.length()-1; - - Assert.assertTrue(palindrome.isPalindromeRecursive(word,0,backward)); - } - } - - @Test - public void whenPalindromeRecursive_sentenceShouldBePalindrome() { - for(String sentence:sentences) { - sentence = sentence.replaceAll("\\s+", "").toLowerCase(); - int backward = sentence.length()-1; - - Assert.assertTrue(palindrome.isPalindromeRecursive(sentence,0,backward)); - } - } - - @Test - public void whenPalindromeStreams_wordShouldBePalindrome() { - String[] expected = Arrays.stream(words) - .filter(palindrome::isPalindrome) - .toArray(String[]::new); - - Assert.assertArrayEquals(expected, words); - } - - @Test - public void whenPalindromeStreams_sentenceShouldBePalindrome() { - String[] expected = Arrays.stream(sentences) - .filter(palindrome::isPalindrome) - .toArray(String[]::new); - - Assert.assertArrayEquals(expected, sentences); - } -} diff --git a/core-java/src/test/java/com/baeldung/system/WhenDetectingOSTest.java b/core-java/src/test/java/com/baeldung/system/WhenDetectingOSTest.java new file mode 100644 index 0000000000..77901f6524 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/system/WhenDetectingOSTest.java @@ -0,0 +1,25 @@ +package com.baeldung.system; + +import org.junit.Assert; +import org.junit.Ignore; +import org.junit.Test; + +@Ignore +public class WhenDetectingOSTest { + + private DetectOS os = new DetectOS(); + + @Test + public void whenUsingSystemProperty_shouldReturnOS() { + String expected = "Windows 10"; + String actual = os.getOperatingSystem(); + Assert.assertEquals(expected, actual); + } + + @Test + public void whenUsingSystemUtils_shouldReturnOS() { + String expected = "Windows 10"; + String actual = os.getOperatingSystemSystemUtils(); + Assert.assertEquals(expected, actual); + } +} diff --git a/core-java/src/test/resources/testFolder/sample_file_2.in b/core-java/src/test/resources/testFolder/sample_file_2.in deleted file mode 100644 index 93b493a513..0000000000 --- a/core-java/src/test/resources/testFolder/sample_file_2.in +++ /dev/null @@ -1 +0,0 @@ -Hello world ! \ No newline at end of file diff --git a/core-kotlin/README.md b/core-kotlin/README.md index 5908d480b7..b8cea19c58 100644 --- a/core-kotlin/README.md +++ b/core-kotlin/README.md @@ -17,4 +17,7 @@ - [Sealed Classes in Kotlin](http://www.baeldung.com/kotlin-sealed-classes) - [JUnit 5 for Kotlin Developers](http://www.baeldung.com/junit-5-kotlin) - [Extension Methods in Kotlin](http://www.baeldung.com/kotlin-extension-methods) - +- [Infix Functions in Kotlin](http://www.baeldung.com/kotlin-infix-functions) +- [Try-with-resources in Kotlin](http://www.baeldung.com/kotlin-try-with-resources) +- [HTTP Requests with Kotlin and khttp](http://www.baeldung.com/kotlin-khttp) +- [Kotlin Dependency Injection with Kodein](http://www.baeldung.com/kotlin-kodein-dependency-injection) diff --git a/core-kotlin/pom.xml b/core-kotlin/pom.xml index 33bdbf719f..36298ca084 100644 --- a/core-kotlin/pom.xml +++ b/core-kotlin/pom.xml @@ -76,7 +76,18 @@ mockito-kotlin ${mockito-kotlin.version} test - + + + com.github.salomonbrys.kodein + kodein + ${kodein.version} + + + org.assertj + assertj-core + ${assertj.version} + test + @@ -189,11 +200,13 @@ 1.1.2 0.15 1.5.0 + 4.1.0 5.0.0 1.0.0 4.12.0 4.12 + 3.9.1 diff --git a/core-kotlin/src/main/kotlin/com/baeldung/kotlin/kodein/Controller.kt b/core-kotlin/src/main/kotlin/com/baeldung/kotlin/kodein/Controller.kt new file mode 100644 index 0000000000..721bdb04bc --- /dev/null +++ b/core-kotlin/src/main/kotlin/com/baeldung/kotlin/kodein/Controller.kt @@ -0,0 +1,3 @@ +package com.baeldung.kotlin.kodein + +class Controller(private val service : Service) \ No newline at end of file diff --git a/core-kotlin/src/main/kotlin/com/baeldung/kotlin/kodein/Dao.kt b/core-kotlin/src/main/kotlin/com/baeldung/kotlin/kodein/Dao.kt new file mode 100644 index 0000000000..a0be7ef0e0 --- /dev/null +++ b/core-kotlin/src/main/kotlin/com/baeldung/kotlin/kodein/Dao.kt @@ -0,0 +1,3 @@ +package com.baeldung.kotlin.kodein + +interface Dao \ No newline at end of file diff --git a/core-kotlin/src/main/kotlin/com/baeldung/kotlin/kodein/JdbcDao.kt b/core-kotlin/src/main/kotlin/com/baeldung/kotlin/kodein/JdbcDao.kt new file mode 100644 index 0000000000..0a09b95dbf --- /dev/null +++ b/core-kotlin/src/main/kotlin/com/baeldung/kotlin/kodein/JdbcDao.kt @@ -0,0 +1,3 @@ +package com.baeldung.kotlin.kodein + +class JdbcDao : Dao \ No newline at end of file diff --git a/core-kotlin/src/main/kotlin/com/baeldung/kotlin/kodein/MongoDao.kt b/core-kotlin/src/main/kotlin/com/baeldung/kotlin/kodein/MongoDao.kt new file mode 100644 index 0000000000..06436fcd21 --- /dev/null +++ b/core-kotlin/src/main/kotlin/com/baeldung/kotlin/kodein/MongoDao.kt @@ -0,0 +1,3 @@ +package com.baeldung.kotlin.kodein + +class MongoDao : Dao \ No newline at end of file diff --git a/core-kotlin/src/main/kotlin/com/baeldung/kotlin/kodein/Service.kt b/core-kotlin/src/main/kotlin/com/baeldung/kotlin/kodein/Service.kt new file mode 100644 index 0000000000..bb24a5cc21 --- /dev/null +++ b/core-kotlin/src/main/kotlin/com/baeldung/kotlin/kodein/Service.kt @@ -0,0 +1,3 @@ +package com.baeldung.kotlin.kodein + +class Service(private val dao: Dao, private val tag: String) \ No newline at end of file diff --git a/core-kotlin/src/test/kotlin/com/baeldung/kotlin/kodein/KodeinUnitTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/kodein/KodeinUnitTest.kt new file mode 100644 index 0000000000..7776eebd52 --- /dev/null +++ b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/kodein/KodeinUnitTest.kt @@ -0,0 +1,191 @@ +package com.baeldung.kotlin.kodein + +import com.github.salomonbrys.kodein.* +import org.assertj.core.api.Assertions.assertThat +import org.junit.Test + +class KodeinUnitTest { + + class InMemoryDao : Dao + + @Test + fun whenSingletonBinding_thenSingleInstanceIsCreated() { + var created = false + val kodein = Kodein { + bind() with singleton { + created = true + MongoDao() + } + } + + assertThat(created).isFalse() + + val dao1: Dao = kodein.instance() + + assertThat(created).isTrue() + + val dao2: Dao = kodein.instance() + + assertThat(dao1).isSameAs(dao2) + } + + @Test + fun whenFactoryBinding_thenNewInstanceIsCreated() { + val kodein = Kodein { + bind() with singleton { MongoDao() } + bind() with factory { tag: String -> Service(instance(), tag) } + } + val service1: Service = kodein.with("myTag").instance() + val service2: Service = kodein.with("myTag").instance() + + assertThat(service1).isNotSameAs(service2) + } + + @Test + fun whenProviderBinding_thenNewInstanceIsCreated() { + val kodein = Kodein { + bind() with provider { MongoDao() } + } + val dao1: Dao = kodein.instance() + val dao2: Dao = kodein.instance() + + assertThat(dao1).isNotSameAs(dao2) + } + + @Test + fun whenTaggedBinding_thenMultipleInstancesOfSameTypeCanBeRegistered() { + val kodein = Kodein { + bind("dao1") with singleton { MongoDao() } + bind("dao2") with singleton { MongoDao() } + } + val dao1: Dao = kodein.instance("dao1") + val dao2: Dao = kodein.instance("dao2") + + assertThat(dao1).isNotSameAs(dao2) + } + + @Test + fun whenEagerSingletonBinding_thenCreationIsEager() { + var created = false + val kodein = Kodein { + bind() with eagerSingleton { + created = true + MongoDao() + } + } + + assertThat(created).isTrue() + val dao1: Dao = kodein.instance() + val dao2: Dao = kodein.instance() + + assertThat(dao1).isSameAs(dao2) + } + + @Test + fun whenMultitonBinding_thenInstancesAreReused() { + val kodein = Kodein { + bind() with singleton { MongoDao() } + bind() with multiton { tag: String -> Service(instance(), tag) } + } + val service1: Service = kodein.with("myTag").instance() + val service2: Service = kodein.with("myTag").instance() + + assertThat(service1).isSameAs(service2) + } + + @Test + fun whenInstanceBinding_thenItIsReused() { + val dao = MongoDao() + val kodein = Kodein { + bind() with instance(dao) + } + val fromContainer: Dao = kodein.instance() + + assertThat(dao).isSameAs(fromContainer) + } + + @Test + fun whenConstantBinding_thenItIsAvailable() { + val kodein = Kodein { + constant("magic") with 42 + } + val fromContainer: Int = kodein.instance("magic") + + assertThat(fromContainer).isEqualTo(42) + } + + @Test + fun whenUsingModules_thenTransitiveDependenciesAreSuccessfullyResolved() { + val jdbcModule = Kodein.Module { + bind() with singleton { JdbcDao() } + } + val kodein = Kodein { + import(jdbcModule) + bind() with singleton { Controller(instance()) } + bind() with singleton { Service(instance(), "myService") } + } + + val dao: Dao = kodein.instance() + assertThat(dao).isInstanceOf(JdbcDao::class.java) + } + + @Test + fun whenComposition_thenBeansAreReUsed() { + val persistenceContainer = Kodein { + bind() with singleton { MongoDao() } + } + val serviceContainer = Kodein { + extend(persistenceContainer) + bind() with singleton { Service(instance(), "myService") } + } + val fromPersistence: Dao = persistenceContainer.instance() + val fromService: Dao = serviceContainer.instance() + + assertThat(fromPersistence).isSameAs(fromService) + } + + @Test + fun whenOverriding_thenRightBeanIsUsed() { + val commonModule = Kodein.Module { + bind() with singleton { MongoDao() } + bind() with singleton { Service(instance(), "myService") } + } + val testContainer = Kodein { + import(commonModule) + bind(overrides = true) with singleton { InMemoryDao() } + } + val dao: Dao = testContainer.instance() + + assertThat(dao).isInstanceOf(InMemoryDao::class.java) + } + + @Test + fun whenMultiBinding_thenWorks() { + val kodein = Kodein { + bind() from setBinding() + bind().inSet() with singleton { MongoDao() } + bind().inSet() with singleton { JdbcDao() } + } + val daos: Set = kodein.instance() + + assertThat(daos.map { it.javaClass as Class<*> }).containsOnly(MongoDao::class.java, JdbcDao::class.java) + } + + @Test + fun whenInjector_thenWorks() { + class Controller2 { + private val injector = KodeinInjector() + val service: Service by injector.instance() + fun injectDependencies(kodein: Kodein) = injector.inject(kodein) + } + + val kodein = Kodein { + bind() with singleton { MongoDao() } + bind() with singleton { Service(instance(), "myService") } + } + val controller = Controller2() + controller.injectDependencies(kodein) + + assertThat(controller.service).isNotNull + } +} \ No newline at end of file diff --git a/data-structures/.gitignore b/data-structures/.gitignore new file mode 100644 index 0000000000..b83d22266a --- /dev/null +++ b/data-structures/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/data-structures/README.md b/data-structures/README.md new file mode 100644 index 0000000000..b3b1196ce0 --- /dev/null +++ b/data-structures/README.md @@ -0,0 +1,4 @@ +## Relevant articles: + +- [The Trie Data Structure in Java](http://www.baeldung.com/trie-java) +- [Implementing a Binary Tree in Java](http://www.baeldung.com/java-binary-tree) diff --git a/data-structures/pom.xml b/data-structures/pom.xml new file mode 100644 index 0000000000..68174a41df --- /dev/null +++ b/data-structures/pom.xml @@ -0,0 +1,24 @@ + + 4.0.0 + com.baeldung + data-structures + 0.0.1-SNAPSHOT + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + + + + + + org.codehaus.mojo + exec-maven-plugin + ${exec-maven-plugin.version} + + + + + diff --git a/core-java/src/main/java/com/baeldung/tree/BinaryTree.java b/data-structures/src/main/java/com/baeldung/tree/BinaryTree.java similarity index 100% rename from core-java/src/main/java/com/baeldung/tree/BinaryTree.java rename to data-structures/src/main/java/com/baeldung/tree/BinaryTree.java diff --git a/core-java/src/main/java/com/baeldung/trie/Trie.java b/data-structures/src/main/java/com/baeldung/trie/Trie.java similarity index 100% rename from core-java/src/main/java/com/baeldung/trie/Trie.java rename to data-structures/src/main/java/com/baeldung/trie/Trie.java diff --git a/core-java/src/main/java/com/baeldung/trie/TrieNode.java b/data-structures/src/main/java/com/baeldung/trie/TrieNode.java similarity index 100% rename from core-java/src/main/java/com/baeldung/trie/TrieNode.java rename to data-structures/src/main/java/com/baeldung/trie/TrieNode.java diff --git a/core-java/src/test/java/com/baeldung/tree/BinaryTreeTest.java b/data-structures/src/test/java/com/baeldung/tree/BinaryTreeTest.java similarity index 100% rename from core-java/src/test/java/com/baeldung/tree/BinaryTreeTest.java rename to data-structures/src/test/java/com/baeldung/tree/BinaryTreeTest.java diff --git a/core-java/src/test/java/com/baeldung/trie/TrieTest.java b/data-structures/src/test/java/com/baeldung/trie/TrieTest.java similarity index 100% rename from core-java/src/test/java/com/baeldung/trie/TrieTest.java rename to data-structures/src/test/java/com/baeldung/trie/TrieTest.java diff --git a/ethereumj/pom.xml b/ethereumj/pom.xml index c9f5924d7a..9676106e38 100644 --- a/ethereumj/pom.xml +++ b/ethereumj/pom.xml @@ -1,6 +1,5 @@ - + 4.0.0 com.baeldung.ethereumj ethereumj @@ -8,16 +7,11 @@ 1.0.0 ethereumj - - UTF-8 - 1.8 - 8.5.4 - - - org.springframework.boot - spring-boot-starter-parent - 1.5.6.RELEASE + parent-boot-5 + com.baeldung + 0.0.1-SNAPSHOT + ../parent-boot-5 @@ -38,14 +32,12 @@ org.springframework.boot spring-boot-starter-tomcat - org.springframework.boot spring-boot-starter-test - 1.5.6.RELEASE test @@ -107,4 +99,11 @@ + + + UTF-8 + 1.8 + 8.5.4 + + \ No newline at end of file diff --git a/flips/README.md b/flips/README.md new file mode 100644 index 0000000000..0c62173b6a --- /dev/null +++ b/flips/README.md @@ -0,0 +1,2 @@ +### Relevant Articles: +- [Guide to Flips For Spring](http://www.baeldung.com/guide-to-flips-for-spring/) diff --git a/flips/pom.xml b/flips/pom.xml new file mode 100644 index 0000000000..ecc2af4a47 --- /dev/null +++ b/flips/pom.xml @@ -0,0 +1,65 @@ + + 4.0.0 + + flips + flips + 0.0.1-SNAPSHOT + jar + + flips + + + UTF-8 + 1.8 + 1.8 + + + + + + org.springframework.boot + spring-boot-starter-web + 1.5.10.RELEASE + + + + org.springframework.boot + spring-boot-starter-test + 1.5.9.RELEASE + + + + com.github.feature-flip + flips-web + 1.0.1 + + + + org.projectlombok + lombok + + 1.16.18 + provided + + + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + + + + + diff --git a/flips/src/main/java/com/baeldung/flips/ApplicationConfig.java b/flips/src/main/java/com/baeldung/flips/ApplicationConfig.java new file mode 100644 index 0000000000..7001aeb991 --- /dev/null +++ b/flips/src/main/java/com/baeldung/flips/ApplicationConfig.java @@ -0,0 +1,15 @@ +package com.baeldung.flips; + +import org.flips.describe.config.FlipWebContextConfiguration; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Import; + +@SpringBootApplication +@Import(FlipWebContextConfiguration.class) +public class ApplicationConfig { + + public static void main(String[] args) { + SpringApplication.run(ApplicationConfig.class, args); + } +} \ No newline at end of file diff --git a/flips/src/main/java/com/baeldung/flips/controller/FlipController.java b/flips/src/main/java/com/baeldung/flips/controller/FlipController.java new file mode 100644 index 0000000000..50458023b3 --- /dev/null +++ b/flips/src/main/java/com/baeldung/flips/controller/FlipController.java @@ -0,0 +1,65 @@ +package com.baeldung.flips.controller; + +import com.baeldung.flips.model.Foo; +import com.baeldung.flips.service.FlipService; +import org.flips.annotation.FlipOnDateTime; +import org.flips.annotation.FlipOnDaysOfWeek; +import org.flips.annotation.FlipOnEnvironmentProperty; +import org.flips.annotation.FlipOnProfiles; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RestController; + +import java.time.DayOfWeek; +import java.util.List; + +@RestController +public class FlipController { + + private FlipService flipService; + + @Autowired + public FlipController(FlipService flipService) { + this.flipService = flipService; + } + + @RequestMapping(value = "/foos", method = RequestMethod.GET) + @FlipOnProfiles(activeProfiles = "dev") + public List getAllFoos() { + return flipService.getAllFoos(); + } + + @RequestMapping(value = "/foo/{id}", method = RequestMethod.GET) + @FlipOnDaysOfWeek(daysOfWeek = { + DayOfWeek.MONDAY, DayOfWeek.TUESDAY, DayOfWeek.WEDNESDAY, DayOfWeek.THURSDAY, + DayOfWeek.FRIDAY, DayOfWeek.SATURDAY, DayOfWeek.SUNDAY + }) + public Foo getFooByNewId(@PathVariable int id) { + return flipService.getFooById(id).orElse(new Foo("Not Found", -1)); + } + + @RequestMapping(value = "/foo/last", method = RequestMethod.GET) + @FlipOnDateTime(cutoffDateTimeProperty = "last.active.after") + public Foo getLastFoo() { + return flipService.getLastFoo(); + } + + @RequestMapping(value = "/foo/first", method = RequestMethod.GET) + @FlipOnDateTime(cutoffDateTimeProperty = "first.active.after") + public Foo getFirstFoo() { + return flipService.getLastFoo(); + } + + @RequestMapping(value = "/foos/{id}", method = RequestMethod.GET) + @FlipOnEnvironmentProperty(property = "feature.foo.by.id", expectedValue = "Y") + public Foo getFooById(@PathVariable int id) { + return flipService.getFooById(id).orElse(new Foo("Not Found", -1)); + } + + @RequestMapping(value = "/foo/new", method = RequestMethod.GET) + public Foo getNewThing() { + return flipService.getNewFoo(); + } +} \ No newline at end of file diff --git a/flips/src/main/java/com/baeldung/flips/model/Foo.java b/flips/src/main/java/com/baeldung/flips/model/Foo.java new file mode 100644 index 0000000000..d98abb79a9 --- /dev/null +++ b/flips/src/main/java/com/baeldung/flips/model/Foo.java @@ -0,0 +1,11 @@ +package com.baeldung.flips.model; + +import lombok.Data; +import lombok.RequiredArgsConstructor; + +@Data +@RequiredArgsConstructor +public class Foo { + private final String name; + private final int id; +} diff --git a/flips/src/main/java/com/baeldung/flips/service/FlipService.java b/flips/src/main/java/com/baeldung/flips/service/FlipService.java new file mode 100644 index 0000000000..9f7fb325a5 --- /dev/null +++ b/flips/src/main/java/com/baeldung/flips/service/FlipService.java @@ -0,0 +1,50 @@ +package com.baeldung.flips.service; + +import com.baeldung.flips.model.Foo; +import org.flips.annotation.FlipBean; +import org.flips.annotation.FlipOnSpringExpression; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +@Service +public class FlipService { + + private final List foos; + + public FlipService() { + foos = new ArrayList<>(); + foos.add(new Foo("Foo1", 1)); + foos.add(new Foo("Foo2", 2)); + foos.add(new Foo("Foo3", 3)); + foos.add(new Foo("Foo4", 4)); + foos.add(new Foo("Foo5", 5)); + foos.add(new Foo("Foo6", 6)); + + } + + public List getAllFoos() { + return foos; + } + + public Optional getFooById(int id) { + return foos.stream().filter(foo -> (foo.getId() == id)).findFirst(); + } + + @FlipBean(with = NewFlipService.class) + @FlipOnSpringExpression(expression = "(2 + 2) == 4") + public Foo getNewFoo() { + return new Foo("New Foo!", 99); + } + + public Foo getLastFoo() { + return foos.get(foos.size() - 1); + } + + public Foo getFirstFoo() { + return foos.get(0); + } + +} \ No newline at end of file diff --git a/flips/src/main/java/com/baeldung/flips/service/NewFlipService.java b/flips/src/main/java/com/baeldung/flips/service/NewFlipService.java new file mode 100644 index 0000000000..1dcda9b6ca --- /dev/null +++ b/flips/src/main/java/com/baeldung/flips/service/NewFlipService.java @@ -0,0 +1,13 @@ +package com.baeldung.flips.service; + +import com.baeldung.flips.model.Foo; +import org.springframework.stereotype.Service; + +@Service +public class NewFlipService { + + public Foo getNewFoo() { + return new Foo("Shiny New Foo!", 100); + } + +} \ No newline at end of file diff --git a/flips/src/main/resources/application.properties b/flips/src/main/resources/application.properties new file mode 100644 index 0000000000..274896be15 --- /dev/null +++ b/flips/src/main/resources/application.properties @@ -0,0 +1,5 @@ +feature.foo.by.id=Y +feature.new.foo=Y +last.active.after=2018-03-14T00:00:00Z +first.active.after=2999-03-15T00:00:00Z +logging.level.org.flips=info \ No newline at end of file diff --git a/flips/src/test/java/com/baeldung/flips/controller/FlipControllerTest.java b/flips/src/test/java/com/baeldung/flips/controller/FlipControllerTest.java new file mode 100644 index 0000000000..1b8c78e2a4 --- /dev/null +++ b/flips/src/test/java/com/baeldung/flips/controller/FlipControllerTest.java @@ -0,0 +1,74 @@ +package com.baeldung.flips.controller; + +import org.hamcrest.Matchers; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; +import org.springframework.test.web.servlet.result.MockMvcResultMatchers; + +@RunWith(SpringRunner.class) +@SpringBootTest(properties = { + "feature.foo.by.id=Y", + "feature.new.foo=Y", + "last.active.after=2018-03-14T00:00:00Z", + "first.active.after=2999-03-15T00:00:00Z", + "logging.level.org.flips=info" + +}) +@AutoConfigureMockMvc +@ActiveProfiles("dev") +public class FlipControllerTest { + + @Autowired private MockMvc mvc; + + @Test + public void givenValidDayOfWeek_APIAvailable() throws Exception { + mvc.perform(MockMvcRequestBuilders.get("/foo/1")) + .andExpect(MockMvcResultMatchers.status().is(200)) + .andExpect(MockMvcResultMatchers.jsonPath("$.name", Matchers.equalTo("Foo1"))) + .andExpect(MockMvcResultMatchers.jsonPath("$.id", Matchers.equalTo(1))); + } + + @Test + public void givenValidDate_APIAvailable() throws Exception { + mvc.perform(MockMvcRequestBuilders.get("/foo/last")) + .andExpect(MockMvcResultMatchers.status().is(200)) + .andExpect(MockMvcResultMatchers.jsonPath("$.name", Matchers.equalTo("Foo6"))) + .andExpect(MockMvcResultMatchers.jsonPath("$.id", Matchers.equalTo(6))); + } + + @Test + public void givenInvalidDate_APINotAvailable() throws Exception { + mvc.perform(MockMvcRequestBuilders.get("/foo/first")) + .andExpect(MockMvcResultMatchers.status().is(501)); + } + + @Test + public void givenCorrectProfile_APIAvailable() throws Exception { + mvc.perform(MockMvcRequestBuilders.get("/foos")) + .andExpect(MockMvcResultMatchers.status().isOk()) + .andExpect(MockMvcResultMatchers.jsonPath("$", Matchers.hasSize(6))); + } + + @Test + public void givenPropertySet_APIAvailable() throws Exception { + mvc.perform(MockMvcRequestBuilders.get("/foos/1")) + .andExpect(MockMvcResultMatchers.status().isOk()) + .andExpect(MockMvcResultMatchers.jsonPath("$.name", Matchers.equalTo("Foo1"))) + .andExpect(MockMvcResultMatchers.jsonPath("$.id", Matchers.equalTo(1))); + } + + @Test + public void getValidExpression_FlipBean() throws Exception { + mvc.perform(MockMvcRequestBuilders.get("/foo/new")) + .andExpect(MockMvcResultMatchers.status().is(200)) + .andExpect(MockMvcResultMatchers.jsonPath("$.name", Matchers.equalTo("Shiny New Foo!"))) + .andExpect(MockMvcResultMatchers.jsonPath("$.id", Matchers.equalTo(100))); + } +} \ No newline at end of file diff --git a/geotools/src/test/java/com/baeldung/geotools/GeoToolsUnitTest.java b/geotools/src/test/java/com/baeldung/geotools/GeoToolsUnitTest.java index 053932b2a7..4a63c44c8b 100644 --- a/geotools/src/test/java/com/baeldung/geotools/GeoToolsUnitTest.java +++ b/geotools/src/test/java/com/baeldung/geotools/GeoToolsUnitTest.java @@ -3,7 +3,6 @@ package com.baeldung.geotools; import static org.junit.Assert.assertNotNull; import org.geotools.feature.DefaultFeatureCollection; -import org.geotools.feature.simple.SimpleFeatureBuilder; import org.junit.Test; import org.opengis.feature.simple.SimpleFeatureType; @@ -19,4 +18,5 @@ public class GeoToolsUnitTest { assertNotNull(collection); } + } diff --git a/google-cloud/README.md b/google-cloud/README.md new file mode 100644 index 0000000000..6022796a0e --- /dev/null +++ b/google-cloud/README.md @@ -0,0 +1,16 @@ +## Google Cloud Tutorial Project + +### Relevant Article: +- [Intro to Google Cloud Storage With Java](http://www.baeldung.com/intro-to-google-cloud-storage-with-java/) + +### Overview +This Maven project contains the Java code for the article linked above. + +### Package Organization +Java classes for the intro tutorial are in the org.baeldung.google.cloud package. Please note that Google Cloud requires +a user account and credentials, as explained in the tutorial. + + +### Running the tests + +``` diff --git a/google-cloud/pom.xml b/google-cloud/pom.xml new file mode 100644 index 0000000000..0f1eff36f8 --- /dev/null +++ b/google-cloud/pom.xml @@ -0,0 +1,38 @@ + + + 4.0.0 + google-cloud + 0.1-SNAPSHOT + jar + google-cloud + Google Cloud Tutorials + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + + + + + com.google.cloud + google-cloud-storage + 1.16.0 + + + org.projectlombok + lombok + + ${lombok.version} + provided + + + + + 1.16.18 + 1.8 + UTF-8 + + + diff --git a/google-cloud/src/main/java/com/baeldung/google/cloud/storage/GoogleCloudStorage.java b/google-cloud/src/main/java/com/baeldung/google/cloud/storage/GoogleCloudStorage.java new file mode 100644 index 0000000000..a69171f1db --- /dev/null +++ b/google-cloud/src/main/java/com/baeldung/google/cloud/storage/GoogleCloudStorage.java @@ -0,0 +1,105 @@ +package com.baeldung.google.cloud.storage; + +import com.google.api.gax.paging.Page; +import com.google.auth.Credentials; +import com.google.auth.oauth2.GoogleCredentials; +import com.google.cloud.storage.*; +import lombok.extern.slf4j.Slf4j; + +import java.io.FileInputStream; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.channels.WritableByteChannel; + +import static java.nio.charset.StandardCharsets.UTF_8; + +/** + * Simple class for creating, reading and modifying text blobs on Google Cloud + */ +@Slf4j +public class GoogleCloudStorage { + + private Storage storage; + private Bucket bucket; + + public static void main(String[] args) throws Exception { + + // Use this variation to read the Google authorization JSON from the resources directory with a path + // and a project name. + GoogleCloudStorage googleCloudStorage = + new GoogleCloudStorage("google-cloud/src/main/resources/google_auth.json", "baeldung-cloud-tutorial"); + + // Bucket require globally unique names, so you'll probably need to change this + Bucket bucket = googleCloudStorage.getBucket("baeldung-1-bucket"); + + // Save a simple string + BlobId blobId = googleCloudStorage.saveString("my-first-blob", "Hi there!", bucket); + + // Get it by blob id this time + String value = googleCloudStorage.getString(blobId); + + log.info("Read data: {}", value); + + googleCloudStorage.updateString(blobId, "Bye now!"); + + // Get the string by blob name + value = googleCloudStorage.getString("my-first-blob"); + + log.info("Read modified data: {}", value); + + + } + + + // Use path and project name + private GoogleCloudStorage(String pathToConfig, String projectId) throws IOException { + Credentials credentials = GoogleCredentials.fromStream(new FileInputStream(pathToConfig)); + storage = StorageOptions.newBuilder().setCredentials(credentials).setProjectId(projectId).build().getService(); + } + + // Check for bucket existence and create if needed. + private Bucket getBucket(String bucketName) { + bucket = storage.get(bucketName); + if (bucket == null) { + System.out.println("Creating new bucket."); + bucket = storage.create(BucketInfo.of(bucketName)); + } + return bucket; + } + + // Save a string to a blob + private BlobId saveString(String blobName, String value, Bucket bucket) { + byte[] bytes = value.getBytes(UTF_8); + Blob blob = bucket.create(blobName, bytes); + return blob.getBlobId(); + } + + + // get a blob by id + private String getString(BlobId blobId) { + Blob blob = storage.get(blobId); + return new String(blob.getContent()); + } + + + // get a blob by name + private String getString(String name) { + Page blobs = bucket.list(); + for (Blob blob: blobs.getValues()) { + if (name.equals(blob.getName())) { + return new String(blob.getContent()); + } + } + return "Blob not found"; + } + + // Update a blob + private void updateString(BlobId blobId, String newString) throws IOException { + Blob blob = storage.get(blobId); + if (blob != null) { + WritableByteChannel channel = blob.writer(); + channel.write(ByteBuffer.wrap(newString.getBytes(UTF_8))); + channel.close(); + } + } +} \ No newline at end of file diff --git a/gradle/build.gradle b/gradle/build.gradle index dcc592a2b4..2e5d984fba 100644 --- a/gradle/build.gradle +++ b/gradle/build.gradle @@ -33,3 +33,60 @@ task execSecondTest { } println 'This will be executed during the configuration phase as well.' } + +task welcome { + doLast { + println 'Welcome on the Baeldung!' + } +} + +task welcomeWithGroup { + group 'Sample category' + doLast { + println 'Welcome on the Baeldung!' + } +} + +task welcomeWithGroupAndDescription { + group 'Sample category' + description 'Tasks which shows welcome message' + doLast { + println 'Welcome on the Baeldung!' + } +} + +class PrintToolVersionTask extends DefaultTask { + String tool + + @TaskAction + void printToolVersion() { + switch (tool) { + case 'java': + println System.getProperty("java.version") + break + case 'groovy': + println GroovySystem.version + break + default: + throw new IllegalArgumentException("Unknown tool") + } + } +} + +task printJavaVersion(type : PrintToolVersionTask) { + tool 'java' +} + +task printGroovyVersion(type : PrintToolVersionTask) { + tool 'groovy' +} + +import com.baeldung.PrintToolVersionBuildSrcTask + +task printJavaVersionBuildSrc(type : PrintToolVersionBuildSrcTask) { + tool 'java' +} + +task printGroovyVersionBuildSrc(type : PrintToolVersionBuildSrcTask) { + tool 'groovy' +} \ No newline at end of file diff --git a/gradle/buildSrc/src/main/groovy/com/baeldung/PrintToolVersionBuildSrcTask.groovy b/gradle/buildSrc/src/main/groovy/com/baeldung/PrintToolVersionBuildSrcTask.groovy new file mode 100644 index 0000000000..0fbd71db56 --- /dev/null +++ b/gradle/buildSrc/src/main/groovy/com/baeldung/PrintToolVersionBuildSrcTask.groovy @@ -0,0 +1,22 @@ +package com.baeldung + +import org.gradle.api.DefaultTask +import org.gradle.api.tasks.TaskAction + +class PrintToolVersionBuildSrcTask extends DefaultTask { + String tool + + @TaskAction + void printToolVersion() { + switch (tool) { + case 'java': + println System.getProperty("java.version") + break + case 'groovy': + println GroovySystem.version + break + default: + throw new IllegalArgumentException("Unknown tool") + } + } +} \ No newline at end of file diff --git a/grails/.gitignore b/grails/.gitignore new file mode 100644 index 0000000000..f33ace2782 --- /dev/null +++ b/grails/.gitignore @@ -0,0 +1,12 @@ +Thumbs.db +.DS_Store +.gradle +build/ +out/ +.idea +*.iml +*.ipr +*.iws +.project +.settings +.classpath diff --git a/grails/build.gradle b/grails/build.gradle new file mode 100644 index 0000000000..88e3ee3f24 --- /dev/null +++ b/grails/build.gradle @@ -0,0 +1,80 @@ +buildscript { + repositories { + mavenLocal() + maven { url "https://repo.grails.org/grails/core" } + } + dependencies { + classpath "org.grails:grails-gradle-plugin:$grailsVersion" + classpath "org.grails.plugins:hibernate5:${gormVersion-".RELEASE"}" + classpath "com.bertramlabs.plugins:asset-pipeline-gradle:2.14.8" + } +} + +version "0.1" +group "grails" + +apply plugin:"eclipse" +apply plugin:"idea" +apply plugin:"war" +apply plugin:"org.grails.grails-web" +apply plugin:"asset-pipeline" +apply plugin:"org.grails.grails-gsp" + +repositories { + mavenLocal() + maven { url "https://repo.grails.org/grails/core" } +} + +dependencies { + compile "org.springframework.boot:spring-boot-starter-logging" + compile "org.springframework.boot:spring-boot-autoconfigure" + compile "org.grails:grails-core" + compile "org.springframework.boot:spring-boot-starter-actuator" + compile "org.springframework.boot:spring-boot-starter-tomcat" + compile "org.grails:grails-web-boot" + compile "org.grails:grails-logging" + compile "org.grails:grails-plugin-rest" + compile "org.grails:grails-plugin-databinding" + compile "org.grails:grails-plugin-i18n" + compile "org.grails:grails-plugin-services" + compile "org.grails:grails-plugin-url-mappings" + compile "org.grails:grails-plugin-interceptors" + compile "org.grails.plugins:cache" + compile "org.grails.plugins:async" + compile "org.grails.plugins:scaffolding" + compile "org.grails.plugins:events" + compile "org.grails.plugins:hibernate5" + compile "org.hibernate:hibernate-core:5.1.5.Final" + compile "org.grails.plugins:gsp" + console "org.grails:grails-console" + profile "org.grails.profiles:web" + runtime "org.glassfish.web:el-impl:2.1.2-b03" + runtime "com.h2database:h2" + runtime "org.apache.tomcat:tomcat-jdbc" + runtime "com.bertramlabs.plugins:asset-pipeline-grails:2.14.8" + testCompile "org.grails:grails-gorm-testing-support" + testCompile "org.grails:grails-web-testing-support" + testCompile "org.grails.plugins:geb:1.1.2" + testRuntime "org.seleniumhq.selenium:selenium-chrome-driver:2.47.1" + testRuntime "org.seleniumhq.selenium:selenium-htmlunit-driver:2.47.1" + testRuntime "net.sourceforge.htmlunit:htmlunit:2.18" +} + +bootRun { + jvmArgs('-Dspring.output.ansi.enabled=always') + addResources = true + String springProfilesActive = 'spring.profiles.active' + systemProperty springProfilesActive, System.getProperty(springProfilesActive) +} + +tasks.withType(Test) { + systemProperty "geb.env", System.getProperty('geb.env') + systemProperty "geb.build.reportsDir", reporting.file("geb/integrationTest") + systemProperty "webdriver.chrome.driver", System.getProperty('webdriver.chrome.driver') + systemProperty "webdriver.gecko.driver", System.getProperty('webdriver.gecko.driver') +} + +assets { + minifyJs = true + minifyCss = true +} diff --git a/grails/gradle.properties b/grails/gradle.properties new file mode 100644 index 0000000000..e7bb689af0 --- /dev/null +++ b/grails/gradle.properties @@ -0,0 +1,3 @@ +grailsVersion=3.3.3 +gormVersion=6.1.9.RELEASE +gradleWrapperVersion=3.5 diff --git a/grails/gradle/wrapper/gradle-wrapper.properties b/grails/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000000..ca9ec11b99 --- /dev/null +++ b/grails/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Fri Nov 27 23:09:32 CET 2015 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-3.5-bin.zip diff --git a/grails/gradlew b/grails/gradlew new file mode 100644 index 0000000000..9d82f78915 --- /dev/null +++ b/grails/gradlew @@ -0,0 +1,160 @@ +#!/usr/bin/env bash + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn ( ) { + echo "$*" +} + +die ( ) { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; +esac + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules +function splitJvmOpts() { + JVM_OPTS=("$@") +} +eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS +JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" + +exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/grails/gradlew.bat b/grails/gradlew.bat new file mode 100644 index 0000000000..8a0b282aa6 --- /dev/null +++ b/grails/gradlew.bat @@ -0,0 +1,90 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windowz variants + +if not "%OS%" == "Windows_NT" goto win9xME_args +if "%@eval[2+2]" == "4" goto 4NT_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* +goto execute + +:4NT_args +@rem Get arguments from the 4NT Shell from JP Software +set CMD_LINE_ARGS=%$ + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/grails/grails-app/assets/images/apple-touch-icon-retina.png b/grails/grails-app/assets/images/apple-touch-icon-retina.png new file mode 100644 index 0000000000..d5bc4c0da0 Binary files /dev/null and b/grails/grails-app/assets/images/apple-touch-icon-retina.png differ diff --git a/grails/grails-app/assets/images/apple-touch-icon.png b/grails/grails-app/assets/images/apple-touch-icon.png new file mode 100644 index 0000000000..c3681cc467 Binary files /dev/null and b/grails/grails-app/assets/images/apple-touch-icon.png differ diff --git a/grails/grails-app/assets/images/favicon.ico b/grails/grails-app/assets/images/favicon.ico new file mode 100644 index 0000000000..76e4b11fed Binary files /dev/null and b/grails/grails-app/assets/images/favicon.ico differ diff --git a/grails/grails-app/assets/images/grails-cupsonly-logo-white.svg b/grails/grails-app/assets/images/grails-cupsonly-logo-white.svg new file mode 100644 index 0000000000..d3fe882c4b --- /dev/null +++ b/grails/grails-app/assets/images/grails-cupsonly-logo-white.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/grails/grails-app/assets/images/grails.svg b/grails/grails-app/assets/images/grails.svg new file mode 100644 index 0000000000..79f698b698 --- /dev/null +++ b/grails/grails-app/assets/images/grails.svg @@ -0,0 +1,13 @@ + + + + grails + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/grails/grails-app/assets/images/skin/database_add.png b/grails/grails-app/assets/images/skin/database_add.png new file mode 100644 index 0000000000..802bd6cde0 Binary files /dev/null and b/grails/grails-app/assets/images/skin/database_add.png differ diff --git a/grails/grails-app/assets/images/skin/database_delete.png b/grails/grails-app/assets/images/skin/database_delete.png new file mode 100644 index 0000000000..cce652e845 Binary files /dev/null and b/grails/grails-app/assets/images/skin/database_delete.png differ diff --git a/grails/grails-app/assets/images/skin/database_edit.png b/grails/grails-app/assets/images/skin/database_edit.png new file mode 100644 index 0000000000..e501b668c7 Binary files /dev/null and b/grails/grails-app/assets/images/skin/database_edit.png differ diff --git a/grails/grails-app/assets/images/skin/database_save.png b/grails/grails-app/assets/images/skin/database_save.png new file mode 100644 index 0000000000..44c06dddf1 Binary files /dev/null and b/grails/grails-app/assets/images/skin/database_save.png differ diff --git a/grails/grails-app/assets/images/skin/database_table.png b/grails/grails-app/assets/images/skin/database_table.png new file mode 100644 index 0000000000..693709cbc1 Binary files /dev/null and b/grails/grails-app/assets/images/skin/database_table.png differ diff --git a/grails/grails-app/assets/images/skin/exclamation.png b/grails/grails-app/assets/images/skin/exclamation.png new file mode 100644 index 0000000000..c37bd062e6 Binary files /dev/null and b/grails/grails-app/assets/images/skin/exclamation.png differ diff --git a/grails/grails-app/assets/images/skin/house.png b/grails/grails-app/assets/images/skin/house.png new file mode 100644 index 0000000000..fed62219f5 Binary files /dev/null and b/grails/grails-app/assets/images/skin/house.png differ diff --git a/grails/grails-app/assets/images/skin/information.png b/grails/grails-app/assets/images/skin/information.png new file mode 100644 index 0000000000..12cd1aef90 Binary files /dev/null and b/grails/grails-app/assets/images/skin/information.png differ diff --git a/grails/grails-app/assets/images/skin/shadow.jpg b/grails/grails-app/assets/images/skin/shadow.jpg new file mode 100644 index 0000000000..b7ed44fadc Binary files /dev/null and b/grails/grails-app/assets/images/skin/shadow.jpg differ diff --git a/grails/grails-app/assets/images/skin/sorted_asc.gif b/grails/grails-app/assets/images/skin/sorted_asc.gif new file mode 100644 index 0000000000..6b179c11cf Binary files /dev/null and b/grails/grails-app/assets/images/skin/sorted_asc.gif differ diff --git a/grails/grails-app/assets/images/skin/sorted_desc.gif b/grails/grails-app/assets/images/skin/sorted_desc.gif new file mode 100644 index 0000000000..38b3a01d07 Binary files /dev/null and b/grails/grails-app/assets/images/skin/sorted_desc.gif differ diff --git a/grails/grails-app/assets/images/spinner.gif b/grails/grails-app/assets/images/spinner.gif new file mode 100644 index 0000000000..1ed786f2ec Binary files /dev/null and b/grails/grails-app/assets/images/spinner.gif differ diff --git a/grails/grails-app/assets/javascripts/application.js b/grails/grails-app/assets/javascripts/application.js new file mode 100644 index 0000000000..5c6a18d085 --- /dev/null +++ b/grails/grails-app/assets/javascripts/application.js @@ -0,0 +1,21 @@ +// This is a manifest file that'll be compiled into application.js. +// +// Any JavaScript file within this directory can be referenced here using a relative path. +// +// You're free to add application-wide JavaScript to this file, but it's generally better +// to create separate JavaScript files as needed. +// +//= require jquery-2.2.0.min +//= require bootstrap +//= require_tree . +//= require_self + +if (typeof jQuery !== 'undefined') { + (function($) { + $(document).ajaxStart(function() { + $('#spinner').fadeIn(); + }).ajaxStop(function() { + $('#spinner').fadeOut(); + }); + })(jQuery); +} diff --git a/grails/grails-app/assets/javascripts/bootstrap.js b/grails/grails-app/assets/javascripts/bootstrap.js new file mode 100644 index 0000000000..01fbbcbaa9 --- /dev/null +++ b/grails/grails-app/assets/javascripts/bootstrap.js @@ -0,0 +1,2363 @@ +/*! + * Bootstrap v3.3.6 (http://getbootstrap.com) + * Copyright 2011-2015 Twitter, Inc. + * Licensed under the MIT license + */ + +if (typeof jQuery === 'undefined') { + throw new Error('Bootstrap\'s JavaScript requires jQuery') +} + ++function ($) { + 'use strict'; + var version = $.fn.jquery.split(' ')[0].split('.') + if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1) || (version[0] > 2)) { + throw new Error('Bootstrap\'s JavaScript requires jQuery version 1.9.1 or higher, but lower than version 3') + } +}(jQuery); + +/* ======================================================================== + * Bootstrap: transition.js v3.3.6 + * http://getbootstrap.com/javascript/#transitions + * ======================================================================== + * Copyright 2011-2015 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/) + // ============================================================ + + function transitionEnd() { + var el = document.createElement('bootstrap') + + var transEndEventNames = { + WebkitTransition : 'webkitTransitionEnd', + MozTransition : 'transitionend', + OTransition : 'oTransitionEnd otransitionend', + transition : 'transitionend' + } + + for (var name in transEndEventNames) { + if (el.style[name] !== undefined) { + return { end: transEndEventNames[name] } + } + } + + return false // explicit for ie8 ( ._.) + } + + // http://blog.alexmaccaw.com/css-transitions + $.fn.emulateTransitionEnd = function (duration) { + var called = false + var $el = this + $(this).one('bsTransitionEnd', function () { called = true }) + var callback = function () { if (!called) $($el).trigger($.support.transition.end) } + setTimeout(callback, duration) + return this + } + + $(function () { + $.support.transition = transitionEnd() + + if (!$.support.transition) return + + $.event.special.bsTransitionEnd = { + bindType: $.support.transition.end, + delegateType: $.support.transition.end, + handle: function (e) { + if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments) + } + } + }) + +}(jQuery); + +/* ======================================================================== + * Bootstrap: alert.js v3.3.6 + * http://getbootstrap.com/javascript/#alerts + * ======================================================================== + * Copyright 2011-2015 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // ALERT CLASS DEFINITION + // ====================== + + var dismiss = '[data-dismiss="alert"]' + var Alert = function (el) { + $(el).on('click', dismiss, this.close) + } + + Alert.VERSION = '3.3.6' + + Alert.TRANSITION_DURATION = 150 + + Alert.prototype.close = function (e) { + var $this = $(this) + var selector = $this.attr('data-target') + + if (!selector) { + selector = $this.attr('href') + selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 + } + + var $parent = $(selector) + + if (e) e.preventDefault() + + if (!$parent.length) { + $parent = $this.closest('.alert') + } + + $parent.trigger(e = $.Event('close.bs.alert')) + + if (e.isDefaultPrevented()) return + + $parent.removeClass('in') + + function removeElement() { + // detach from parent, fire event then clean up data + $parent.detach().trigger('closed.bs.alert').remove() + } + + $.support.transition && $parent.hasClass('fade') ? + $parent + .one('bsTransitionEnd', removeElement) + .emulateTransitionEnd(Alert.TRANSITION_DURATION) : + removeElement() + } + + + // ALERT PLUGIN DEFINITION + // ======================= + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.alert') + + if (!data) $this.data('bs.alert', (data = new Alert(this))) + if (typeof option == 'string') data[option].call($this) + }) + } + + var old = $.fn.alert + + $.fn.alert = Plugin + $.fn.alert.Constructor = Alert + + + // ALERT NO CONFLICT + // ================= + + $.fn.alert.noConflict = function () { + $.fn.alert = old + return this + } + + + // ALERT DATA-API + // ============== + + $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close) + +}(jQuery); + +/* ======================================================================== + * Bootstrap: button.js v3.3.6 + * http://getbootstrap.com/javascript/#buttons + * ======================================================================== + * Copyright 2011-2015 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // BUTTON PUBLIC CLASS DEFINITION + // ============================== + + var Button = function (element, options) { + this.$element = $(element) + this.options = $.extend({}, Button.DEFAULTS, options) + this.isLoading = false + } + + Button.VERSION = '3.3.6' + + Button.DEFAULTS = { + loadingText: 'loading...' + } + + Button.prototype.setState = function (state) { + var d = 'disabled' + var $el = this.$element + var val = $el.is('input') ? 'val' : 'html' + var data = $el.data() + + state += 'Text' + + if (data.resetText == null) $el.data('resetText', $el[val]()) + + // push to event loop to allow forms to submit + setTimeout($.proxy(function () { + $el[val](data[state] == null ? this.options[state] : data[state]) + + if (state == 'loadingText') { + this.isLoading = true + $el.addClass(d).attr(d, d) + } else if (this.isLoading) { + this.isLoading = false + $el.removeClass(d).removeAttr(d) + } + }, this), 0) + } + + Button.prototype.toggle = function () { + var changed = true + var $parent = this.$element.closest('[data-toggle="buttons"]') + + if ($parent.length) { + var $input = this.$element.find('input') + if ($input.prop('type') == 'radio') { + if ($input.prop('checked')) changed = false + $parent.find('.active').removeClass('active') + this.$element.addClass('active') + } else if ($input.prop('type') == 'checkbox') { + if (($input.prop('checked')) !== this.$element.hasClass('active')) changed = false + this.$element.toggleClass('active') + } + $input.prop('checked', this.$element.hasClass('active')) + if (changed) $input.trigger('change') + } else { + this.$element.attr('aria-pressed', !this.$element.hasClass('active')) + this.$element.toggleClass('active') + } + } + + + // BUTTON PLUGIN DEFINITION + // ======================== + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.button') + var options = typeof option == 'object' && option + + if (!data) $this.data('bs.button', (data = new Button(this, options))) + + if (option == 'toggle') data.toggle() + else if (option) data.setState(option) + }) + } + + var old = $.fn.button + + $.fn.button = Plugin + $.fn.button.Constructor = Button + + + // BUTTON NO CONFLICT + // ================== + + $.fn.button.noConflict = function () { + $.fn.button = old + return this + } + + + // BUTTON DATA-API + // =============== + + $(document) + .on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) { + var $btn = $(e.target) + if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn') + Plugin.call($btn, 'toggle') + if (!($(e.target).is('input[type="radio"]') || $(e.target).is('input[type="checkbox"]'))) e.preventDefault() + }) + .on('focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^="button"]', function (e) { + $(e.target).closest('.btn').toggleClass('focus', /^focus(in)?$/.test(e.type)) + }) + +}(jQuery); + +/* ======================================================================== + * Bootstrap: carousel.js v3.3.6 + * http://getbootstrap.com/javascript/#carousel + * ======================================================================== + * Copyright 2011-2015 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // CAROUSEL CLASS DEFINITION + // ========================= + + var Carousel = function (element, options) { + this.$element = $(element) + this.$indicators = this.$element.find('.carousel-indicators') + this.options = options + this.paused = null + this.sliding = null + this.interval = null + this.$active = null + this.$items = null + + this.options.keyboard && this.$element.on('keydown.bs.carousel', $.proxy(this.keydown, this)) + + this.options.pause == 'hover' && !('ontouchstart' in document.documentElement) && this.$element + .on('mouseenter.bs.carousel', $.proxy(this.pause, this)) + .on('mouseleave.bs.carousel', $.proxy(this.cycle, this)) + } + + Carousel.VERSION = '3.3.6' + + Carousel.TRANSITION_DURATION = 600 + + Carousel.DEFAULTS = { + interval: 5000, + pause: 'hover', + wrap: true, + keyboard: true + } + + Carousel.prototype.keydown = function (e) { + if (/input|textarea/i.test(e.target.tagName)) return + switch (e.which) { + case 37: this.prev(); break + case 39: this.next(); break + default: return + } + + e.preventDefault() + } + + Carousel.prototype.cycle = function (e) { + e || (this.paused = false) + + this.interval && clearInterval(this.interval) + + this.options.interval + && !this.paused + && (this.interval = setInterval($.proxy(this.next, this), this.options.interval)) + + return this + } + + Carousel.prototype.getItemIndex = function (item) { + this.$items = item.parent().children('.item') + return this.$items.index(item || this.$active) + } + + Carousel.prototype.getItemForDirection = function (direction, active) { + var activeIndex = this.getItemIndex(active) + var willWrap = (direction == 'prev' && activeIndex === 0) + || (direction == 'next' && activeIndex == (this.$items.length - 1)) + if (willWrap && !this.options.wrap) return active + var delta = direction == 'prev' ? -1 : 1 + var itemIndex = (activeIndex + delta) % this.$items.length + return this.$items.eq(itemIndex) + } + + Carousel.prototype.to = function (pos) { + var that = this + var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active')) + + if (pos > (this.$items.length - 1) || pos < 0) return + + if (this.sliding) return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, "slid" + if (activeIndex == pos) return this.pause().cycle() + + return this.slide(pos > activeIndex ? 'next' : 'prev', this.$items.eq(pos)) + } + + Carousel.prototype.pause = function (e) { + e || (this.paused = true) + + if (this.$element.find('.next, .prev').length && $.support.transition) { + this.$element.trigger($.support.transition.end) + this.cycle(true) + } + + this.interval = clearInterval(this.interval) + + return this + } + + Carousel.prototype.next = function () { + if (this.sliding) return + return this.slide('next') + } + + Carousel.prototype.prev = function () { + if (this.sliding) return + return this.slide('prev') + } + + Carousel.prototype.slide = function (type, next) { + var $active = this.$element.find('.item.active') + var $next = next || this.getItemForDirection(type, $active) + var isCycling = this.interval + var direction = type == 'next' ? 'left' : 'right' + var that = this + + if ($next.hasClass('active')) return (this.sliding = false) + + var relatedTarget = $next[0] + var slideEvent = $.Event('slide.bs.carousel', { + relatedTarget: relatedTarget, + direction: direction + }) + this.$element.trigger(slideEvent) + if (slideEvent.isDefaultPrevented()) return + + this.sliding = true + + isCycling && this.pause() + + if (this.$indicators.length) { + this.$indicators.find('.active').removeClass('active') + var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)]) + $nextIndicator && $nextIndicator.addClass('active') + } + + var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, "slid" + if ($.support.transition && this.$element.hasClass('slide')) { + $next.addClass(type) + $next[0].offsetWidth // force reflow + $active.addClass(direction) + $next.addClass(direction) + $active + .one('bsTransitionEnd', function () { + $next.removeClass([type, direction].join(' ')).addClass('active') + $active.removeClass(['active', direction].join(' ')) + that.sliding = false + setTimeout(function () { + that.$element.trigger(slidEvent) + }, 0) + }) + .emulateTransitionEnd(Carousel.TRANSITION_DURATION) + } else { + $active.removeClass('active') + $next.addClass('active') + this.sliding = false + this.$element.trigger(slidEvent) + } + + isCycling && this.cycle() + + return this + } + + + // CAROUSEL PLUGIN DEFINITION + // ========================== + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.carousel') + var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option) + var action = typeof option == 'string' ? option : options.slide + + if (!data) $this.data('bs.carousel', (data = new Carousel(this, options))) + if (typeof option == 'number') data.to(option) + else if (action) data[action]() + else if (options.interval) data.pause().cycle() + }) + } + + var old = $.fn.carousel + + $.fn.carousel = Plugin + $.fn.carousel.Constructor = Carousel + + + // CAROUSEL NO CONFLICT + // ==================== + + $.fn.carousel.noConflict = function () { + $.fn.carousel = old + return this + } + + + // CAROUSEL DATA-API + // ================= + + var clickHandler = function (e) { + var href + var $this = $(this) + var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) // strip for ie7 + if (!$target.hasClass('carousel')) return + var options = $.extend({}, $target.data(), $this.data()) + var slideIndex = $this.attr('data-slide-to') + if (slideIndex) options.interval = false + + Plugin.call($target, options) + + if (slideIndex) { + $target.data('bs.carousel').to(slideIndex) + } + + e.preventDefault() + } + + $(document) + .on('click.bs.carousel.data-api', '[data-slide]', clickHandler) + .on('click.bs.carousel.data-api', '[data-slide-to]', clickHandler) + + $(window).on('load', function () { + $('[data-ride="carousel"]').each(function () { + var $carousel = $(this) + Plugin.call($carousel, $carousel.data()) + }) + }) + +}(jQuery); + +/* ======================================================================== + * Bootstrap: collapse.js v3.3.6 + * http://getbootstrap.com/javascript/#collapse + * ======================================================================== + * Copyright 2011-2015 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // COLLAPSE PUBLIC CLASS DEFINITION + // ================================ + + var Collapse = function (element, options) { + this.$element = $(element) + this.options = $.extend({}, Collapse.DEFAULTS, options) + this.$trigger = $('[data-toggle="collapse"][href="#' + element.id + '"],' + + '[data-toggle="collapse"][data-target="#' + element.id + '"]') + this.transitioning = null + + if (this.options.parent) { + this.$parent = this.getParent() + } else { + this.addAriaAndCollapsedClass(this.$element, this.$trigger) + } + + if (this.options.toggle) this.toggle() + } + + Collapse.VERSION = '3.3.6' + + Collapse.TRANSITION_DURATION = 350 + + Collapse.DEFAULTS = { + toggle: true + } + + Collapse.prototype.dimension = function () { + var hasWidth = this.$element.hasClass('width') + return hasWidth ? 'width' : 'height' + } + + Collapse.prototype.show = function () { + if (this.transitioning || this.$element.hasClass('in')) return + + var activesData + var actives = this.$parent && this.$parent.children('.panel').children('.in, .collapsing') + + if (actives && actives.length) { + activesData = actives.data('bs.collapse') + if (activesData && activesData.transitioning) return + } + + var startEvent = $.Event('show.bs.collapse') + this.$element.trigger(startEvent) + if (startEvent.isDefaultPrevented()) return + + if (actives && actives.length) { + Plugin.call(actives, 'hide') + activesData || actives.data('bs.collapse', null) + } + + var dimension = this.dimension() + + this.$element + .removeClass('collapse') + .addClass('collapsing')[dimension](0) + .attr('aria-expanded', true) + + this.$trigger + .removeClass('collapsed') + .attr('aria-expanded', true) + + this.transitioning = 1 + + var complete = function () { + this.$element + .removeClass('collapsing') + .addClass('collapse in')[dimension]('') + this.transitioning = 0 + this.$element + .trigger('shown.bs.collapse') + } + + if (!$.support.transition) return complete.call(this) + + var scrollSize = $.camelCase(['scroll', dimension].join('-')) + + this.$element + .one('bsTransitionEnd', $.proxy(complete, this)) + .emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize]) + } + + Collapse.prototype.hide = function () { + if (this.transitioning || !this.$element.hasClass('in')) return + + var startEvent = $.Event('hide.bs.collapse') + this.$element.trigger(startEvent) + if (startEvent.isDefaultPrevented()) return + + var dimension = this.dimension() + + this.$element[dimension](this.$element[dimension]())[0].offsetHeight + + this.$element + .addClass('collapsing') + .removeClass('collapse in') + .attr('aria-expanded', false) + + this.$trigger + .addClass('collapsed') + .attr('aria-expanded', false) + + this.transitioning = 1 + + var complete = function () { + this.transitioning = 0 + this.$element + .removeClass('collapsing') + .addClass('collapse') + .trigger('hidden.bs.collapse') + } + + if (!$.support.transition) return complete.call(this) + + this.$element + [dimension](0) + .one('bsTransitionEnd', $.proxy(complete, this)) + .emulateTransitionEnd(Collapse.TRANSITION_DURATION) + } + + Collapse.prototype.toggle = function () { + this[this.$element.hasClass('in') ? 'hide' : 'show']() + } + + Collapse.prototype.getParent = function () { + return $(this.options.parent) + .find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]') + .each($.proxy(function (i, element) { + var $element = $(element) + this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element) + }, this)) + .end() + } + + Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) { + var isOpen = $element.hasClass('in') + + $element.attr('aria-expanded', isOpen) + $trigger + .toggleClass('collapsed', !isOpen) + .attr('aria-expanded', isOpen) + } + + function getTargetFromTrigger($trigger) { + var href + var target = $trigger.attr('data-target') + || (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7 + + return $(target) + } + + + // COLLAPSE PLUGIN DEFINITION + // ========================== + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.collapse') + var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option) + + if (!data && options.toggle && /show|hide/.test(option)) options.toggle = false + if (!data) $this.data('bs.collapse', (data = new Collapse(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + var old = $.fn.collapse + + $.fn.collapse = Plugin + $.fn.collapse.Constructor = Collapse + + + // COLLAPSE NO CONFLICT + // ==================== + + $.fn.collapse.noConflict = function () { + $.fn.collapse = old + return this + } + + + // COLLAPSE DATA-API + // ================= + + $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) { + var $this = $(this) + + if (!$this.attr('data-target')) e.preventDefault() + + var $target = getTargetFromTrigger($this) + var data = $target.data('bs.collapse') + var option = data ? 'toggle' : $this.data() + + Plugin.call($target, option) + }) + +}(jQuery); + +/* ======================================================================== + * Bootstrap: dropdown.js v3.3.6 + * http://getbootstrap.com/javascript/#dropdowns + * ======================================================================== + * Copyright 2011-2015 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // DROPDOWN CLASS DEFINITION + // ========================= + + var backdrop = '.dropdown-backdrop' + var toggle = '[data-toggle="dropdown"]' + var Dropdown = function (element) { + $(element).on('click.bs.dropdown', this.toggle) + } + + Dropdown.VERSION = '3.3.6' + + function getParent($this) { + var selector = $this.attr('data-target') + + if (!selector) { + selector = $this.attr('href') + selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 + } + + var $parent = selector && $(selector) + + return $parent && $parent.length ? $parent : $this.parent() + } + + function clearMenus(e) { + if (e && e.which === 3) return + $(backdrop).remove() + $(toggle).each(function () { + var $this = $(this) + var $parent = getParent($this) + var relatedTarget = { relatedTarget: this } + + if (!$parent.hasClass('open')) return + + if (e && e.type == 'click' && /input|textarea/i.test(e.target.tagName) && $.contains($parent[0], e.target)) return + + $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget)) + + if (e.isDefaultPrevented()) return + + $this.attr('aria-expanded', 'false') + $parent.removeClass('open').trigger($.Event('hidden.bs.dropdown', relatedTarget)) + }) + } + + Dropdown.prototype.toggle = function (e) { + var $this = $(this) + + if ($this.is('.disabled, :disabled')) return + + var $parent = getParent($this) + var isActive = $parent.hasClass('open') + + clearMenus() + + if (!isActive) { + if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) { + // if mobile we use a backdrop because click events don't delegate + $(document.createElement('div')) + .addClass('dropdown-backdrop') + .insertAfter($(this)) + .on('click', clearMenus) + } + + var relatedTarget = { relatedTarget: this } + $parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget)) + + if (e.isDefaultPrevented()) return + + $this + .trigger('focus') + .attr('aria-expanded', 'true') + + $parent + .toggleClass('open') + .trigger($.Event('shown.bs.dropdown', relatedTarget)) + } + + return false + } + + Dropdown.prototype.keydown = function (e) { + if (!/(38|40|27|32)/.test(e.which) || /input|textarea/i.test(e.target.tagName)) return + + var $this = $(this) + + e.preventDefault() + e.stopPropagation() + + if ($this.is('.disabled, :disabled')) return + + var $parent = getParent($this) + var isActive = $parent.hasClass('open') + + if (!isActive && e.which != 27 || isActive && e.which == 27) { + if (e.which == 27) $parent.find(toggle).trigger('focus') + return $this.trigger('click') + } + + var desc = ' li:not(.disabled):visible a' + var $items = $parent.find('.dropdown-menu' + desc) + + if (!$items.length) return + + var index = $items.index(e.target) + + if (e.which == 38 && index > 0) index-- // up + if (e.which == 40 && index < $items.length - 1) index++ // down + if (!~index) index = 0 + + $items.eq(index).trigger('focus') + } + + + // DROPDOWN PLUGIN DEFINITION + // ========================== + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.dropdown') + + if (!data) $this.data('bs.dropdown', (data = new Dropdown(this))) + if (typeof option == 'string') data[option].call($this) + }) + } + + var old = $.fn.dropdown + + $.fn.dropdown = Plugin + $.fn.dropdown.Constructor = Dropdown + + + // DROPDOWN NO CONFLICT + // ==================== + + $.fn.dropdown.noConflict = function () { + $.fn.dropdown = old + return this + } + + + // APPLY TO STANDARD DROPDOWN ELEMENTS + // =================================== + + $(document) + .on('click.bs.dropdown.data-api', clearMenus) + .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() }) + .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle) + .on('keydown.bs.dropdown.data-api', toggle, Dropdown.prototype.keydown) + .on('keydown.bs.dropdown.data-api', '.dropdown-menu', Dropdown.prototype.keydown) + +}(jQuery); + +/* ======================================================================== + * Bootstrap: modal.js v3.3.6 + * http://getbootstrap.com/javascript/#modals + * ======================================================================== + * Copyright 2011-2015 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // MODAL CLASS DEFINITION + // ====================== + + var Modal = function (element, options) { + this.options = options + this.$body = $(document.body) + this.$element = $(element) + this.$dialog = this.$element.find('.modal-dialog') + this.$backdrop = null + this.isShown = null + this.originalBodyPad = null + this.scrollbarWidth = 0 + this.ignoreBackdropClick = false + + if (this.options.remote) { + this.$element + .find('.modal-content') + .load(this.options.remote, $.proxy(function () { + this.$element.trigger('loaded.bs.modal') + }, this)) + } + } + + Modal.VERSION = '3.3.6' + + Modal.TRANSITION_DURATION = 300 + Modal.BACKDROP_TRANSITION_DURATION = 150 + + Modal.DEFAULTS = { + backdrop: true, + keyboard: true, + show: true + } + + Modal.prototype.toggle = function (_relatedTarget) { + return this.isShown ? this.hide() : this.show(_relatedTarget) + } + + Modal.prototype.show = function (_relatedTarget) { + var that = this + var e = $.Event('show.bs.modal', { relatedTarget: _relatedTarget }) + + this.$element.trigger(e) + + if (this.isShown || e.isDefaultPrevented()) return + + this.isShown = true + + this.checkScrollbar() + this.setScrollbar() + this.$body.addClass('modal-open') + + this.escape() + this.resize() + + this.$element.on('click.dismiss.bs.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this)) + + this.$dialog.on('mousedown.dismiss.bs.modal', function () { + that.$element.one('mouseup.dismiss.bs.modal', function (e) { + if ($(e.target).is(that.$element)) that.ignoreBackdropClick = true + }) + }) + + this.backdrop(function () { + var transition = $.support.transition && that.$element.hasClass('fade') + + if (!that.$element.parent().length) { + that.$element.appendTo(that.$body) // don't move modals dom position + } + + that.$element + .show() + .scrollTop(0) + + that.adjustDialog() + + if (transition) { + that.$element[0].offsetWidth // force reflow + } + + that.$element.addClass('in') + + that.enforceFocus() + + var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget }) + + transition ? + that.$dialog // wait for modal to slide in + .one('bsTransitionEnd', function () { + that.$element.trigger('focus').trigger(e) + }) + .emulateTransitionEnd(Modal.TRANSITION_DURATION) : + that.$element.trigger('focus').trigger(e) + }) + } + + Modal.prototype.hide = function (e) { + if (e) e.preventDefault() + + e = $.Event('hide.bs.modal') + + this.$element.trigger(e) + + if (!this.isShown || e.isDefaultPrevented()) return + + this.isShown = false + + this.escape() + this.resize() + + $(document).off('focusin.bs.modal') + + this.$element + .removeClass('in') + .off('click.dismiss.bs.modal') + .off('mouseup.dismiss.bs.modal') + + this.$dialog.off('mousedown.dismiss.bs.modal') + + $.support.transition && this.$element.hasClass('fade') ? + this.$element + .one('bsTransitionEnd', $.proxy(this.hideModal, this)) + .emulateTransitionEnd(Modal.TRANSITION_DURATION) : + this.hideModal() + } + + Modal.prototype.enforceFocus = function () { + $(document) + .off('focusin.bs.modal') // guard against infinite focus loop + .on('focusin.bs.modal', $.proxy(function (e) { + if (this.$element[0] !== e.target && !this.$element.has(e.target).length) { + this.$element.trigger('focus') + } + }, this)) + } + + Modal.prototype.escape = function () { + if (this.isShown && this.options.keyboard) { + this.$element.on('keydown.dismiss.bs.modal', $.proxy(function (e) { + e.which == 27 && this.hide() + }, this)) + } else if (!this.isShown) { + this.$element.off('keydown.dismiss.bs.modal') + } + } + + Modal.prototype.resize = function () { + if (this.isShown) { + $(window).on('resize.bs.modal', $.proxy(this.handleUpdate, this)) + } else { + $(window).off('resize.bs.modal') + } + } + + Modal.prototype.hideModal = function () { + var that = this + this.$element.hide() + this.backdrop(function () { + that.$body.removeClass('modal-open') + that.resetAdjustments() + that.resetScrollbar() + that.$element.trigger('hidden.bs.modal') + }) + } + + Modal.prototype.removeBackdrop = function () { + this.$backdrop && this.$backdrop.remove() + this.$backdrop = null + } + + Modal.prototype.backdrop = function (callback) { + var that = this + var animate = this.$element.hasClass('fade') ? 'fade' : '' + + if (this.isShown && this.options.backdrop) { + var doAnimate = $.support.transition && animate + + this.$backdrop = $(document.createElement('div')) + .addClass('modal-backdrop ' + animate) + .appendTo(this.$body) + + this.$element.on('click.dismiss.bs.modal', $.proxy(function (e) { + if (this.ignoreBackdropClick) { + this.ignoreBackdropClick = false + return + } + if (e.target !== e.currentTarget) return + this.options.backdrop == 'static' + ? this.$element[0].focus() + : this.hide() + }, this)) + + if (doAnimate) this.$backdrop[0].offsetWidth // force reflow + + this.$backdrop.addClass('in') + + if (!callback) return + + doAnimate ? + this.$backdrop + .one('bsTransitionEnd', callback) + .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) : + callback() + + } else if (!this.isShown && this.$backdrop) { + this.$backdrop.removeClass('in') + + var callbackRemove = function () { + that.removeBackdrop() + callback && callback() + } + $.support.transition && this.$element.hasClass('fade') ? + this.$backdrop + .one('bsTransitionEnd', callbackRemove) + .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) : + callbackRemove() + + } else if (callback) { + callback() + } + } + + // these following methods are used to handle overflowing modals + + Modal.prototype.handleUpdate = function () { + this.adjustDialog() + } + + Modal.prototype.adjustDialog = function () { + var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight + + this.$element.css({ + paddingLeft: !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '', + paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : '' + }) + } + + Modal.prototype.resetAdjustments = function () { + this.$element.css({ + paddingLeft: '', + paddingRight: '' + }) + } + + Modal.prototype.checkScrollbar = function () { + var fullWindowWidth = window.innerWidth + if (!fullWindowWidth) { // workaround for missing window.innerWidth in IE8 + var documentElementRect = document.documentElement.getBoundingClientRect() + fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left) + } + this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth + this.scrollbarWidth = this.measureScrollbar() + } + + Modal.prototype.setScrollbar = function () { + var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10) + this.originalBodyPad = document.body.style.paddingRight || '' + if (this.bodyIsOverflowing) this.$body.css('padding-right', bodyPad + this.scrollbarWidth) + } + + Modal.prototype.resetScrollbar = function () { + this.$body.css('padding-right', this.originalBodyPad) + } + + Modal.prototype.measureScrollbar = function () { // thx walsh + var scrollDiv = document.createElement('div') + scrollDiv.className = 'modal-scrollbar-measure' + this.$body.append(scrollDiv) + var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth + this.$body[0].removeChild(scrollDiv) + return scrollbarWidth + } + + + // MODAL PLUGIN DEFINITION + // ======================= + + function Plugin(option, _relatedTarget) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.modal') + var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option) + + if (!data) $this.data('bs.modal', (data = new Modal(this, options))) + if (typeof option == 'string') data[option](_relatedTarget) + else if (options.show) data.show(_relatedTarget) + }) + } + + var old = $.fn.modal + + $.fn.modal = Plugin + $.fn.modal.Constructor = Modal + + + // MODAL NO CONFLICT + // ================= + + $.fn.modal.noConflict = function () { + $.fn.modal = old + return this + } + + + // MODAL DATA-API + // ============== + + $(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) { + var $this = $(this) + var href = $this.attr('href') + var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) // strip for ie7 + var option = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data()) + + if ($this.is('a')) e.preventDefault() + + $target.one('show.bs.modal', function (showEvent) { + if (showEvent.isDefaultPrevented()) return // only register focus restorer if modal will actually get shown + $target.one('hidden.bs.modal', function () { + $this.is(':visible') && $this.trigger('focus') + }) + }) + Plugin.call($target, option, this) + }) + +}(jQuery); + +/* ======================================================================== + * Bootstrap: tooltip.js v3.3.6 + * http://getbootstrap.com/javascript/#tooltip + * Inspired by the original jQuery.tipsy by Jason Frame + * ======================================================================== + * Copyright 2011-2015 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // TOOLTIP PUBLIC CLASS DEFINITION + // =============================== + + var Tooltip = function (element, options) { + this.type = null + this.options = null + this.enabled = null + this.timeout = null + this.hoverState = null + this.$element = null + this.inState = null + + this.init('tooltip', element, options) + } + + Tooltip.VERSION = '3.3.6' + + Tooltip.TRANSITION_DURATION = 150 + + Tooltip.DEFAULTS = { + animation: true, + placement: 'top', + selector: false, + template: '', + trigger: 'hover focus', + title: '', + delay: 0, + html: false, + container: false, + viewport: { + selector: 'body', + padding: 0 + } + } + + Tooltip.prototype.init = function (type, element, options) { + this.enabled = true + this.type = type + this.$element = $(element) + this.options = this.getOptions(options) + this.$viewport = this.options.viewport && $($.isFunction(this.options.viewport) ? this.options.viewport.call(this, this.$element) : (this.options.viewport.selector || this.options.viewport)) + this.inState = { click: false, hover: false, focus: false } + + if (this.$element[0] instanceof document.constructor && !this.options.selector) { + throw new Error('`selector` option must be specified when initializing ' + this.type + ' on the window.document object!') + } + + var triggers = this.options.trigger.split(' ') + + for (var i = triggers.length; i--;) { + var trigger = triggers[i] + + if (trigger == 'click') { + this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this)) + } else if (trigger != 'manual') { + var eventIn = trigger == 'hover' ? 'mouseenter' : 'focusin' + var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout' + + this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this)) + this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this)) + } + } + + this.options.selector ? + (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) : + this.fixTitle() + } + + Tooltip.prototype.getDefaults = function () { + return Tooltip.DEFAULTS + } + + Tooltip.prototype.getOptions = function (options) { + options = $.extend({}, this.getDefaults(), this.$element.data(), options) + + if (options.delay && typeof options.delay == 'number') { + options.delay = { + show: options.delay, + hide: options.delay + } + } + + return options + } + + Tooltip.prototype.getDelegateOptions = function () { + var options = {} + var defaults = this.getDefaults() + + this._options && $.each(this._options, function (key, value) { + if (defaults[key] != value) options[key] = value + }) + + return options + } + + Tooltip.prototype.enter = function (obj) { + var self = obj instanceof this.constructor ? + obj : $(obj.currentTarget).data('bs.' + this.type) + + if (!self) { + self = new this.constructor(obj.currentTarget, this.getDelegateOptions()) + $(obj.currentTarget).data('bs.' + this.type, self) + } + + if (obj instanceof $.Event) { + self.inState[obj.type == 'focusin' ? 'focus' : 'hover'] = true + } + + if (self.tip().hasClass('in') || self.hoverState == 'in') { + self.hoverState = 'in' + return + } + + clearTimeout(self.timeout) + + self.hoverState = 'in' + + if (!self.options.delay || !self.options.delay.show) return self.show() + + self.timeout = setTimeout(function () { + if (self.hoverState == 'in') self.show() + }, self.options.delay.show) + } + + Tooltip.prototype.isInStateTrue = function () { + for (var key in this.inState) { + if (this.inState[key]) return true + } + + return false + } + + Tooltip.prototype.leave = function (obj) { + var self = obj instanceof this.constructor ? + obj : $(obj.currentTarget).data('bs.' + this.type) + + if (!self) { + self = new this.constructor(obj.currentTarget, this.getDelegateOptions()) + $(obj.currentTarget).data('bs.' + this.type, self) + } + + if (obj instanceof $.Event) { + self.inState[obj.type == 'focusout' ? 'focus' : 'hover'] = false + } + + if (self.isInStateTrue()) return + + clearTimeout(self.timeout) + + self.hoverState = 'out' + + if (!self.options.delay || !self.options.delay.hide) return self.hide() + + self.timeout = setTimeout(function () { + if (self.hoverState == 'out') self.hide() + }, self.options.delay.hide) + } + + Tooltip.prototype.show = function () { + var e = $.Event('show.bs.' + this.type) + + if (this.hasContent() && this.enabled) { + this.$element.trigger(e) + + var inDom = $.contains(this.$element[0].ownerDocument.documentElement, this.$element[0]) + if (e.isDefaultPrevented() || !inDom) return + var that = this + + var $tip = this.tip() + + var tipId = this.getUID(this.type) + + this.setContent() + $tip.attr('id', tipId) + this.$element.attr('aria-describedby', tipId) + + if (this.options.animation) $tip.addClass('fade') + + var placement = typeof this.options.placement == 'function' ? + this.options.placement.call(this, $tip[0], this.$element[0]) : + this.options.placement + + var autoToken = /\s?auto?\s?/i + var autoPlace = autoToken.test(placement) + if (autoPlace) placement = placement.replace(autoToken, '') || 'top' + + $tip + .detach() + .css({ top: 0, left: 0, display: 'block' }) + .addClass(placement) + .data('bs.' + this.type, this) + + this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element) + this.$element.trigger('inserted.bs.' + this.type) + + var pos = this.getPosition() + var actualWidth = $tip[0].offsetWidth + var actualHeight = $tip[0].offsetHeight + + if (autoPlace) { + var orgPlacement = placement + var viewportDim = this.getPosition(this.$viewport) + + placement = placement == 'bottom' && pos.bottom + actualHeight > viewportDim.bottom ? 'top' : + placement == 'top' && pos.top - actualHeight < viewportDim.top ? 'bottom' : + placement == 'right' && pos.right + actualWidth > viewportDim.width ? 'left' : + placement == 'left' && pos.left - actualWidth < viewportDim.left ? 'right' : + placement + + $tip + .removeClass(orgPlacement) + .addClass(placement) + } + + var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight) + + this.applyPlacement(calculatedOffset, placement) + + var complete = function () { + var prevHoverState = that.hoverState + that.$element.trigger('shown.bs.' + that.type) + that.hoverState = null + + if (prevHoverState == 'out') that.leave(that) + } + + $.support.transition && this.$tip.hasClass('fade') ? + $tip + .one('bsTransitionEnd', complete) + .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) : + complete() + } + } + + Tooltip.prototype.applyPlacement = function (offset, placement) { + var $tip = this.tip() + var width = $tip[0].offsetWidth + var height = $tip[0].offsetHeight + + // manually read margins because getBoundingClientRect includes difference + var marginTop = parseInt($tip.css('margin-top'), 10) + var marginLeft = parseInt($tip.css('margin-left'), 10) + + // we must check for NaN for ie 8/9 + if (isNaN(marginTop)) marginTop = 0 + if (isNaN(marginLeft)) marginLeft = 0 + + offset.top += marginTop + offset.left += marginLeft + + // $.fn.offset doesn't round pixel values + // so we use setOffset directly with our own function B-0 + $.offset.setOffset($tip[0], $.extend({ + using: function (props) { + $tip.css({ + top: Math.round(props.top), + left: Math.round(props.left) + }) + } + }, offset), 0) + + $tip.addClass('in') + + // check to see if placing tip in new offset caused the tip to resize itself + var actualWidth = $tip[0].offsetWidth + var actualHeight = $tip[0].offsetHeight + + if (placement == 'top' && actualHeight != height) { + offset.top = offset.top + height - actualHeight + } + + var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight) + + if (delta.left) offset.left += delta.left + else offset.top += delta.top + + var isVertical = /top|bottom/.test(placement) + var arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight + var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight' + + $tip.offset(offset) + this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical) + } + + Tooltip.prototype.replaceArrow = function (delta, dimension, isVertical) { + this.arrow() + .css(isVertical ? 'left' : 'top', 50 * (1 - delta / dimension) + '%') + .css(isVertical ? 'top' : 'left', '') + } + + Tooltip.prototype.setContent = function () { + var $tip = this.tip() + var title = this.getTitle() + + $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title) + $tip.removeClass('fade in top bottom left right') + } + + Tooltip.prototype.hide = function (callback) { + var that = this + var $tip = $(this.$tip) + var e = $.Event('hide.bs.' + this.type) + + function complete() { + if (that.hoverState != 'in') $tip.detach() + that.$element + .removeAttr('aria-describedby') + .trigger('hidden.bs.' + that.type) + callback && callback() + } + + this.$element.trigger(e) + + if (e.isDefaultPrevented()) return + + $tip.removeClass('in') + + $.support.transition && $tip.hasClass('fade') ? + $tip + .one('bsTransitionEnd', complete) + .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) : + complete() + + this.hoverState = null + + return this + } + + Tooltip.prototype.fixTitle = function () { + var $e = this.$element + if ($e.attr('title') || typeof $e.attr('data-original-title') != 'string') { + $e.attr('data-original-title', $e.attr('title') || '').attr('title', '') + } + } + + Tooltip.prototype.hasContent = function () { + return this.getTitle() + } + + Tooltip.prototype.getPosition = function ($element) { + $element = $element || this.$element + + var el = $element[0] + var isBody = el.tagName == 'BODY' + + var elRect = el.getBoundingClientRect() + if (elRect.width == null) { + // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093 + elRect = $.extend({}, elRect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top }) + } + var elOffset = isBody ? { top: 0, left: 0 } : $element.offset() + var scroll = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() } + var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null + + return $.extend({}, elRect, scroll, outerDims, elOffset) + } + + Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) { + return placement == 'bottom' ? { top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2 } : + placement == 'top' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } : + placement == 'left' ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } : + /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width } + + } + + Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) { + var delta = { top: 0, left: 0 } + if (!this.$viewport) return delta + + var viewportPadding = this.options.viewport && this.options.viewport.padding || 0 + var viewportDimensions = this.getPosition(this.$viewport) + + if (/right|left/.test(placement)) { + var topEdgeOffset = pos.top - viewportPadding - viewportDimensions.scroll + var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight + if (topEdgeOffset < viewportDimensions.top) { // top overflow + delta.top = viewportDimensions.top - topEdgeOffset + } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow + delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset + } + } else { + var leftEdgeOffset = pos.left - viewportPadding + var rightEdgeOffset = pos.left + viewportPadding + actualWidth + if (leftEdgeOffset < viewportDimensions.left) { // left overflow + delta.left = viewportDimensions.left - leftEdgeOffset + } else if (rightEdgeOffset > viewportDimensions.right) { // right overflow + delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset + } + } + + return delta + } + + Tooltip.prototype.getTitle = function () { + var title + var $e = this.$element + var o = this.options + + title = $e.attr('data-original-title') + || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title) + + return title + } + + Tooltip.prototype.getUID = function (prefix) { + do prefix += ~~(Math.random() * 1000000) + while (document.getElementById(prefix)) + return prefix + } + + Tooltip.prototype.tip = function () { + if (!this.$tip) { + this.$tip = $(this.options.template) + if (this.$tip.length != 1) { + throw new Error(this.type + ' `template` option must consist of exactly 1 top-level element!') + } + } + return this.$tip + } + + Tooltip.prototype.arrow = function () { + return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow')) + } + + Tooltip.prototype.enable = function () { + this.enabled = true + } + + Tooltip.prototype.disable = function () { + this.enabled = false + } + + Tooltip.prototype.toggleEnabled = function () { + this.enabled = !this.enabled + } + + Tooltip.prototype.toggle = function (e) { + var self = this + if (e) { + self = $(e.currentTarget).data('bs.' + this.type) + if (!self) { + self = new this.constructor(e.currentTarget, this.getDelegateOptions()) + $(e.currentTarget).data('bs.' + this.type, self) + } + } + + if (e) { + self.inState.click = !self.inState.click + if (self.isInStateTrue()) self.enter(self) + else self.leave(self) + } else { + self.tip().hasClass('in') ? self.leave(self) : self.enter(self) + } + } + + Tooltip.prototype.destroy = function () { + var that = this + clearTimeout(this.timeout) + this.hide(function () { + that.$element.off('.' + that.type).removeData('bs.' + that.type) + if (that.$tip) { + that.$tip.detach() + } + that.$tip = null + that.$arrow = null + that.$viewport = null + }) + } + + + // TOOLTIP PLUGIN DEFINITION + // ========================= + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.tooltip') + var options = typeof option == 'object' && option + + if (!data && /destroy|hide/.test(option)) return + if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + var old = $.fn.tooltip + + $.fn.tooltip = Plugin + $.fn.tooltip.Constructor = Tooltip + + + // TOOLTIP NO CONFLICT + // =================== + + $.fn.tooltip.noConflict = function () { + $.fn.tooltip = old + return this + } + +}(jQuery); + +/* ======================================================================== + * Bootstrap: popover.js v3.3.6 + * http://getbootstrap.com/javascript/#popovers + * ======================================================================== + * Copyright 2011-2015 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // POPOVER PUBLIC CLASS DEFINITION + // =============================== + + var Popover = function (element, options) { + this.init('popover', element, options) + } + + if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js') + + Popover.VERSION = '3.3.6' + + Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, { + placement: 'right', + trigger: 'click', + content: '', + template: '' + }) + + + // NOTE: POPOVER EXTENDS tooltip.js + // ================================ + + Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype) + + Popover.prototype.constructor = Popover + + Popover.prototype.getDefaults = function () { + return Popover.DEFAULTS + } + + Popover.prototype.setContent = function () { + var $tip = this.tip() + var title = this.getTitle() + var content = this.getContent() + + $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title) + $tip.find('.popover-content').children().detach().end()[ // we use append for html objects to maintain js events + this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text' + ](content) + + $tip.removeClass('fade top bottom left right in') + + // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do + // this manually by checking the contents. + if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide() + } + + Popover.prototype.hasContent = function () { + return this.getTitle() || this.getContent() + } + + Popover.prototype.getContent = function () { + var $e = this.$element + var o = this.options + + return $e.attr('data-content') + || (typeof o.content == 'function' ? + o.content.call($e[0]) : + o.content) + } + + Popover.prototype.arrow = function () { + return (this.$arrow = this.$arrow || this.tip().find('.arrow')) + } + + + // POPOVER PLUGIN DEFINITION + // ========================= + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.popover') + var options = typeof option == 'object' && option + + if (!data && /destroy|hide/.test(option)) return + if (!data) $this.data('bs.popover', (data = new Popover(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + var old = $.fn.popover + + $.fn.popover = Plugin + $.fn.popover.Constructor = Popover + + + // POPOVER NO CONFLICT + // =================== + + $.fn.popover.noConflict = function () { + $.fn.popover = old + return this + } + +}(jQuery); + +/* ======================================================================== + * Bootstrap: scrollspy.js v3.3.6 + * http://getbootstrap.com/javascript/#scrollspy + * ======================================================================== + * Copyright 2011-2015 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // SCROLLSPY CLASS DEFINITION + // ========================== + + function ScrollSpy(element, options) { + this.$body = $(document.body) + this.$scrollElement = $(element).is(document.body) ? $(window) : $(element) + this.options = $.extend({}, ScrollSpy.DEFAULTS, options) + this.selector = (this.options.target || '') + ' .nav li > a' + this.offsets = [] + this.targets = [] + this.activeTarget = null + this.scrollHeight = 0 + + this.$scrollElement.on('scroll.bs.scrollspy', $.proxy(this.process, this)) + this.refresh() + this.process() + } + + ScrollSpy.VERSION = '3.3.6' + + ScrollSpy.DEFAULTS = { + offset: 10 + } + + ScrollSpy.prototype.getScrollHeight = function () { + return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight) + } + + ScrollSpy.prototype.refresh = function () { + var that = this + var offsetMethod = 'offset' + var offsetBase = 0 + + this.offsets = [] + this.targets = [] + this.scrollHeight = this.getScrollHeight() + + if (!$.isWindow(this.$scrollElement[0])) { + offsetMethod = 'position' + offsetBase = this.$scrollElement.scrollTop() + } + + this.$body + .find(this.selector) + .map(function () { + var $el = $(this) + var href = $el.data('target') || $el.attr('href') + var $href = /^#./.test(href) && $(href) + + return ($href + && $href.length + && $href.is(':visible') + && [[$href[offsetMethod]().top + offsetBase, href]]) || null + }) + .sort(function (a, b) { return a[0] - b[0] }) + .each(function () { + that.offsets.push(this[0]) + that.targets.push(this[1]) + }) + } + + ScrollSpy.prototype.process = function () { + var scrollTop = this.$scrollElement.scrollTop() + this.options.offset + var scrollHeight = this.getScrollHeight() + var maxScroll = this.options.offset + scrollHeight - this.$scrollElement.height() + var offsets = this.offsets + var targets = this.targets + var activeTarget = this.activeTarget + var i + + if (this.scrollHeight != scrollHeight) { + this.refresh() + } + + if (scrollTop >= maxScroll) { + return activeTarget != (i = targets[targets.length - 1]) && this.activate(i) + } + + if (activeTarget && scrollTop < offsets[0]) { + this.activeTarget = null + return this.clear() + } + + for (i = offsets.length; i--;) { + activeTarget != targets[i] + && scrollTop >= offsets[i] + && (offsets[i + 1] === undefined || scrollTop < offsets[i + 1]) + && this.activate(targets[i]) + } + } + + ScrollSpy.prototype.activate = function (target) { + this.activeTarget = target + + this.clear() + + var selector = this.selector + + '[data-target="' + target + '"],' + + this.selector + '[href="' + target + '"]' + + var active = $(selector) + .parents('li') + .addClass('active') + + if (active.parent('.dropdown-menu').length) { + active = active + .closest('li.dropdown') + .addClass('active') + } + + active.trigger('activate.bs.scrollspy') + } + + ScrollSpy.prototype.clear = function () { + $(this.selector) + .parentsUntil(this.options.target, '.active') + .removeClass('active') + } + + + // SCROLLSPY PLUGIN DEFINITION + // =========================== + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.scrollspy') + var options = typeof option == 'object' && option + + if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + var old = $.fn.scrollspy + + $.fn.scrollspy = Plugin + $.fn.scrollspy.Constructor = ScrollSpy + + + // SCROLLSPY NO CONFLICT + // ===================== + + $.fn.scrollspy.noConflict = function () { + $.fn.scrollspy = old + return this + } + + + // SCROLLSPY DATA-API + // ================== + + $(window).on('load.bs.scrollspy.data-api', function () { + $('[data-spy="scroll"]').each(function () { + var $spy = $(this) + Plugin.call($spy, $spy.data()) + }) + }) + +}(jQuery); + +/* ======================================================================== + * Bootstrap: tab.js v3.3.6 + * http://getbootstrap.com/javascript/#tabs + * ======================================================================== + * Copyright 2011-2015 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // TAB CLASS DEFINITION + // ==================== + + var Tab = function (element) { + // jscs:disable requireDollarBeforejQueryAssignment + this.element = $(element) + // jscs:enable requireDollarBeforejQueryAssignment + } + + Tab.VERSION = '3.3.6' + + Tab.TRANSITION_DURATION = 150 + + Tab.prototype.show = function () { + var $this = this.element + var $ul = $this.closest('ul:not(.dropdown-menu)') + var selector = $this.data('target') + + if (!selector) { + selector = $this.attr('href') + selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 + } + + if ($this.parent('li').hasClass('active')) return + + var $previous = $ul.find('.active:last a') + var hideEvent = $.Event('hide.bs.tab', { + relatedTarget: $this[0] + }) + var showEvent = $.Event('show.bs.tab', { + relatedTarget: $previous[0] + }) + + $previous.trigger(hideEvent) + $this.trigger(showEvent) + + if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return + + var $target = $(selector) + + this.activate($this.closest('li'), $ul) + this.activate($target, $target.parent(), function () { + $previous.trigger({ + type: 'hidden.bs.tab', + relatedTarget: $this[0] + }) + $this.trigger({ + type: 'shown.bs.tab', + relatedTarget: $previous[0] + }) + }) + } + + Tab.prototype.activate = function (element, container, callback) { + var $active = container.find('> .active') + var transition = callback + && $.support.transition + && ($active.length && $active.hasClass('fade') || !!container.find('> .fade').length) + + function next() { + $active + .removeClass('active') + .find('> .dropdown-menu > .active') + .removeClass('active') + .end() + .find('[data-toggle="tab"]') + .attr('aria-expanded', false) + + element + .addClass('active') + .find('[data-toggle="tab"]') + .attr('aria-expanded', true) + + if (transition) { + element[0].offsetWidth // reflow for transition + element.addClass('in') + } else { + element.removeClass('fade') + } + + if (element.parent('.dropdown-menu').length) { + element + .closest('li.dropdown') + .addClass('active') + .end() + .find('[data-toggle="tab"]') + .attr('aria-expanded', true) + } + + callback && callback() + } + + $active.length && transition ? + $active + .one('bsTransitionEnd', next) + .emulateTransitionEnd(Tab.TRANSITION_DURATION) : + next() + + $active.removeClass('in') + } + + + // TAB PLUGIN DEFINITION + // ===================== + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.tab') + + if (!data) $this.data('bs.tab', (data = new Tab(this))) + if (typeof option == 'string') data[option]() + }) + } + + var old = $.fn.tab + + $.fn.tab = Plugin + $.fn.tab.Constructor = Tab + + + // TAB NO CONFLICT + // =============== + + $.fn.tab.noConflict = function () { + $.fn.tab = old + return this + } + + + // TAB DATA-API + // ============ + + var clickHandler = function (e) { + e.preventDefault() + Plugin.call($(this), 'show') + } + + $(document) + .on('click.bs.tab.data-api', '[data-toggle="tab"]', clickHandler) + .on('click.bs.tab.data-api', '[data-toggle="pill"]', clickHandler) + +}(jQuery); + +/* ======================================================================== + * Bootstrap: affix.js v3.3.6 + * http://getbootstrap.com/javascript/#affix + * ======================================================================== + * Copyright 2011-2015 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // AFFIX CLASS DEFINITION + // ====================== + + var Affix = function (element, options) { + this.options = $.extend({}, Affix.DEFAULTS, options) + + this.$target = $(this.options.target) + .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this)) + .on('click.bs.affix.data-api', $.proxy(this.checkPositionWithEventLoop, this)) + + this.$element = $(element) + this.affixed = null + this.unpin = null + this.pinnedOffset = null + + this.checkPosition() + } + + Affix.VERSION = '3.3.6' + + Affix.RESET = 'affix affix-top affix-bottom' + + Affix.DEFAULTS = { + offset: 0, + target: window + } + + Affix.prototype.getState = function (scrollHeight, height, offsetTop, offsetBottom) { + var scrollTop = this.$target.scrollTop() + var position = this.$element.offset() + var targetHeight = this.$target.height() + + if (offsetTop != null && this.affixed == 'top') return scrollTop < offsetTop ? 'top' : false + + if (this.affixed == 'bottom') { + if (offsetTop != null) return (scrollTop + this.unpin <= position.top) ? false : 'bottom' + return (scrollTop + targetHeight <= scrollHeight - offsetBottom) ? false : 'bottom' + } + + var initializing = this.affixed == null + var colliderTop = initializing ? scrollTop : position.top + var colliderHeight = initializing ? targetHeight : height + + if (offsetTop != null && scrollTop <= offsetTop) return 'top' + if (offsetBottom != null && (colliderTop + colliderHeight >= scrollHeight - offsetBottom)) return 'bottom' + + return false + } + + Affix.prototype.getPinnedOffset = function () { + if (this.pinnedOffset) return this.pinnedOffset + this.$element.removeClass(Affix.RESET).addClass('affix') + var scrollTop = this.$target.scrollTop() + var position = this.$element.offset() + return (this.pinnedOffset = position.top - scrollTop) + } + + Affix.prototype.checkPositionWithEventLoop = function () { + setTimeout($.proxy(this.checkPosition, this), 1) + } + + Affix.prototype.checkPosition = function () { + if (!this.$element.is(':visible')) return + + var height = this.$element.height() + var offset = this.options.offset + var offsetTop = offset.top + var offsetBottom = offset.bottom + var scrollHeight = Math.max($(document).height(), $(document.body).height()) + + if (typeof offset != 'object') offsetBottom = offsetTop = offset + if (typeof offsetTop == 'function') offsetTop = offset.top(this.$element) + if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element) + + var affix = this.getState(scrollHeight, height, offsetTop, offsetBottom) + + if (this.affixed != affix) { + if (this.unpin != null) this.$element.css('top', '') + + var affixType = 'affix' + (affix ? '-' + affix : '') + var e = $.Event(affixType + '.bs.affix') + + this.$element.trigger(e) + + if (e.isDefaultPrevented()) return + + this.affixed = affix + this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null + + this.$element + .removeClass(Affix.RESET) + .addClass(affixType) + .trigger(affixType.replace('affix', 'affixed') + '.bs.affix') + } + + if (affix == 'bottom') { + this.$element.offset({ + top: scrollHeight - height - offsetBottom + }) + } + } + + + // AFFIX PLUGIN DEFINITION + // ======================= + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.affix') + var options = typeof option == 'object' && option + + if (!data) $this.data('bs.affix', (data = new Affix(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + var old = $.fn.affix + + $.fn.affix = Plugin + $.fn.affix.Constructor = Affix + + + // AFFIX NO CONFLICT + // ================= + + $.fn.affix.noConflict = function () { + $.fn.affix = old + return this + } + + + // AFFIX DATA-API + // ============== + + $(window).on('load', function () { + $('[data-spy="affix"]').each(function () { + var $spy = $(this) + var data = $spy.data() + + data.offset = data.offset || {} + + if (data.offsetBottom != null) data.offset.bottom = data.offsetBottom + if (data.offsetTop != null) data.offset.top = data.offsetTop + + Plugin.call($spy, data) + }) + }) + +}(jQuery); diff --git a/grails/grails-app/assets/javascripts/jquery-2.2.0.min.js b/grails/grails-app/assets/javascripts/jquery-2.2.0.min.js new file mode 100644 index 0000000000..06ac263150 --- /dev/null +++ b/grails/grails-app/assets/javascripts/jquery-2.2.0.min.js @@ -0,0 +1,4 @@ +/*! jQuery v2.2.0 | (c) jQuery Foundation | jquery.org/license */ +!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=a.document,e=c.slice,f=c.concat,g=c.push,h=c.indexOf,i={},j=i.toString,k=i.hasOwnProperty,l={},m="2.2.0",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return e.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:e.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a){return n.each(this,a)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(e.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor()},push:g,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(n.isPlainObject(d)||(e=n.isArray(d)))?(e?(e=!1,f=c&&n.isArray(c)?c:[]):f=c&&n.isPlainObject(c)?c:{},g[b]=n.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray,isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){var b=a&&a.toString();return!n.isArray(a)&&b-parseFloat(b)+1>=0},isPlainObject:function(a){return"object"!==n.type(a)||a.nodeType||n.isWindow(a)?!1:a.constructor&&!k.call(a.constructor.prototype,"isPrototypeOf")?!1:!0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?i[j.call(a)]||"object":typeof a},globalEval:function(a){var b,c=eval;a=n.trim(a),a&&(1===a.indexOf("use strict")?(b=d.createElement("script"),b.text=a,d.head.appendChild(b).parentNode.removeChild(b)):c(a))},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b){var c,d=0;if(s(a)){for(c=a.length;c>d;d++)if(b.call(a[d],d,a[d])===!1)break}else for(d in a)if(b.call(a[d],d,a[d])===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):g.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:h.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;c>d;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,e,g=0,h=[];if(s(a))for(d=a.length;d>g;g++)e=b(a[g],g,c),null!=e&&h.push(e);else for(g in a)e=b(a[g],g,c),null!=e&&h.push(e);return f.apply([],h)},guid:1,proxy:function(a,b){var c,d,f;return"string"==typeof b&&(c=a[b],b=a,a=c),n.isFunction(a)?(d=e.call(arguments,2),f=function(){return a.apply(b||this,d.concat(e.call(arguments)))},f.guid=a.guid=a.guid||n.guid++,f):void 0},now:Date.now,support:l}),"function"==typeof Symbol&&(n.fn[Symbol.iterator]=c[Symbol.iterator]),n.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(a,b){i["[object "+b+"]"]=b.toLowerCase()});function s(a){var b=!!a&&"length"in a&&a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ga(),z=ga(),A=ga(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+M+"))|)"+L+"*\\]",O=":("+M+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+N+")*)|.*)\\)|)",P=new RegExp(L+"+","g"),Q=new RegExp("^"+L+"+|((?:^|[^\\\\])(?:\\\\.)*)"+L+"+$","g"),R=new RegExp("^"+L+"*,"+L+"*"),S=new RegExp("^"+L+"*([>+~]|"+L+")"+L+"*"),T=new RegExp("="+L+"*([^\\]'\"]*?)"+L+"*\\]","g"),U=new RegExp(O),V=new RegExp("^"+M+"$"),W={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),TAG:new RegExp("^("+M+"|[*])"),ATTR:new RegExp("^"+N),PSEUDO:new RegExp("^"+O),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+L+"*(even|odd|(([+-]|)(\\d*)n|)"+L+"*(?:([+-]|)"+L+"*(\\d+)|))"+L+"*\\)|)","i"),bool:new RegExp("^(?:"+K+")$","i"),needsContext:new RegExp("^"+L+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+L+"*((?:-\\d)?\\d*)"+L+"*\\)|)(?=[^-]|$)","i")},X=/^(?:input|select|textarea|button)$/i,Y=/^h\d$/i,Z=/^[^{]+\{\s*\[native \w/,$=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,_=/[+~]/,aa=/'|\\/g,ba=new RegExp("\\\\([\\da-f]{1,6}"+L+"?|("+L+")|.)","ig"),ca=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},da=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(ea){H={apply:E.length?function(a,b){G.apply(a,I.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function fa(a,b,d,e){var f,h,j,k,l,o,r,s,w=b&&b.ownerDocument,x=b?b.nodeType:9;if(d=d||[],"string"!=typeof a||!a||1!==x&&9!==x&&11!==x)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==x&&(o=$.exec(a)))if(f=o[1]){if(9===x){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(w&&(j=w.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(o[2])return H.apply(d,b.getElementsByTagName(a)),d;if((f=o[3])&&c.getElementsByClassName&&b.getElementsByClassName)return H.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+" "]&&(!q||!q.test(a))){if(1!==x)w=b,s=a;else if("object"!==b.nodeName.toLowerCase()){(k=b.getAttribute("id"))?k=k.replace(aa,"\\$&"):b.setAttribute("id",k=u),r=g(a),h=r.length,l=V.test(k)?"#"+k:"[id='"+k+"']";while(h--)r[h]=l+" "+qa(r[h]);s=r.join(","),w=_.test(a)&&oa(b.parentNode)||b}if(s)try{return H.apply(d,w.querySelectorAll(s)),d}catch(y){}finally{k===u&&b.removeAttribute("id")}}}return i(a.replace(Q,"$1"),b,d,e)}function ga(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ha(a){return a[u]=!0,a}function ia(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ja(a,b){var c=a.split("|"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function ka(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||C)-(~a.sourceIndex||C);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function la(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function na(a){return ha(function(b){return b=+b,ha(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function oa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=fa.support={},f=fa.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=fa.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",da,!1):e.attachEvent&&e.attachEvent("onunload",da)),c.attributes=ia(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ia(function(a){return a.appendChild(n.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Z.test(n.getElementsByClassName),c.getById=ia(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ba,ca);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ba,ca);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return"undefined"!=typeof b.getElementsByClassName&&p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=Z.test(n.querySelectorAll))&&(ia(function(a){o.appendChild(a).innerHTML="",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+L+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+L+"*(?:value|"+K+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ia(function(a){var b=n.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+L+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=Z.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ia(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",O)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=Z.test(o.compareDocumentPosition),t=b||Z.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?J(k,a)-J(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return ka(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?ka(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},fa.matches=function(a,b){return fa(a,null,null,b)},fa.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(T,"='$1']"),c.matchesSelector&&p&&!A[b+" "]&&(!r||!r.test(b))&&(!q||!q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return fa(b,n,null,[a]).length>0},fa.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},fa.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},fa.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},fa.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=fa.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=fa.selectors={cacheLength:50,createPseudo:ha,match:W,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ba,ca),a[3]=(a[3]||a[4]||a[5]||"").replace(ba,ca),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||fa.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&fa.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return W.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&U.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ba,ca).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+L+")"+a+"("+L+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=fa.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(P," ")+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||fa.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ha(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ha(function(a){var b=[],c=[],d=h(a.replace(Q,"$1"));return d[u]?ha(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ha(function(a){return function(b){return fa(a,b).length>0}}),contains:ha(function(a){return a=a.replace(ba,ca),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ha(function(a){return V.test(a||"")||fa.error("unsupported lang: "+a),a=a.replace(ba,ca).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Y.test(a.nodeName)},input:function(a){return X.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:na(function(){return[0]}),last:na(function(a,b){return[b-1]}),eq:na(function(a,b,c){return[0>c?c+b:c]}),even:na(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:na(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:na(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:na(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function ra(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j,k=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(j=b[u]||(b[u]={}),i=j[b.uniqueID]||(j[b.uniqueID]={}),(h=i[d])&&h[0]===w&&h[1]===f)return k[2]=h[2];if(i[d]=k,k[2]=a(b,c,g))return!0}}}function sa(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function ta(a,b,c){for(var d=0,e=b.length;e>d;d++)fa(a,b[d],c);return c}function ua(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function va(a,b,c,d,e,f){return d&&!d[u]&&(d=va(d)),e&&!e[u]&&(e=va(e,f)),ha(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ta(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:ua(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=ua(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?J(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=ua(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function wa(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=ra(function(a){return a===b},h,!0),l=ra(function(a){return J(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[ra(sa(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return va(i>1&&sa(m),i>1&&qa(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(Q,"$1"),c,e>i&&wa(a.slice(i,e)),f>e&&wa(a=a.slice(e)),f>e&&qa(a))}m.push(c)}return sa(m)}function xa(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s="0",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG("*",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=F.call(i));u=ua(u)}H.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&fa.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ha(f):f}return h=fa.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=wa(b[c]),f[u]?d.push(f):e.push(f);f=A(a,xa(e,d)),f.selector=a}return f},i=fa.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(ba,ca),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=W.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(ba,ca),_.test(j[0].type)&&oa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&qa(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,!b||_.test(a)&&oa(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ia(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ia(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||ja("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ia(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ja("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ia(function(a){return null==a.getAttribute("disabled")})||ja(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),fa}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.uniqueSort=n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&n(a).is(c))break;d.push(a)}return d},v=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},w=n.expr.match.needsContext,x=/^<([\w-]+)\s*\/?>(?:<\/\1>|)$/,y=/^.[^:#\[\.,]*$/;function z(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(y.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return h.call(b,a)>-1!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=this.length,d=[],e=this;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;c>b;b++)if(n.contains(e[b],this))return!0}));for(b=0;c>b;b++)n.find(a,e[b],d);return d=this.pushStack(c>1?n.unique(d):d),d.selector=this.selector?this.selector+" "+a:a,d},filter:function(a){return this.pushStack(z(this,a||[],!1))},not:function(a){return this.pushStack(z(this,a||[],!0))},is:function(a){return!!z(this,"string"==typeof a&&w.test(a)?n(a):a||[],!1).length}});var A,B=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,C=n.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||A,"string"==typeof a){if(e="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:B.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),x.test(e[1])&&n.isPlainObject(b))for(e in b)n.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}return f=d.getElementById(e[2]),f&&f.parentNode&&(this.length=1,this[0]=f),this.context=d,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?void 0!==c.ready?c.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};C.prototype=n.fn,A=n(d);var D=/^(?:parents|prev(?:Until|All))/,E={children:!0,contents:!0,next:!0,prev:!0};n.fn.extend({has:function(a){var b=n(a,this),c=b.length;return this.filter(function(){for(var a=0;c>a;a++)if(n.contains(this,b[a]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=w.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.uniqueSort(f):f)},index:function(a){return a?"string"==typeof a?h.call(n(a),this[0]):h.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.uniqueSort(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function F(a,b){while((a=a[b])&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return u(a,"parentNode")},parentsUntil:function(a,b,c){return u(a,"parentNode",c)},next:function(a){return F(a,"nextSibling")},prev:function(a){return F(a,"previousSibling")},nextAll:function(a){return u(a,"nextSibling")},prevAll:function(a){return u(a,"previousSibling")},nextUntil:function(a,b,c){return u(a,"nextSibling",c)},prevUntil:function(a,b,c){return u(a,"previousSibling",c)},siblings:function(a){return v((a.parentNode||{}).firstChild,a)},children:function(a){return v(a.firstChild)},contents:function(a){return a.contentDocument||n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(E[a]||n.uniqueSort(e),D.test(a)&&e.reverse()),this.pushStack(e)}});var G=/\S+/g;function H(a){var b={};return n.each(a.match(G)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?H(a):n.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h-1)f.splice(c,1),h>=c&&h--}),this},has:function(a){return a?n.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c="",this},disabled:function(){return!f},lock:function(){return e=g=[],c||(f=c=""),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().progress(c.notify).done(c.resolve).fail(c.reject):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=e.call(arguments),d=c.length,f=1!==d||a&&n.isFunction(a.promise)?d:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(d){b[a]=this,c[a]=arguments.length>1?e.call(arguments):d,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(d>1)for(i=new Array(d),j=new Array(d),k=new Array(d);d>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().progress(h(b,j,i)).done(h(b,k,c)).fail(g.reject):--f;return f||g.resolveWith(k,c),g.promise()}});var I;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){(a===!0?--n.readyWait:n.isReady)||(n.isReady=!0,a!==!0&&--n.readyWait>0||(I.resolveWith(d,[n]),n.fn.triggerHandler&&(n(d).triggerHandler("ready"),n(d).off("ready"))))}});function J(){d.removeEventListener("DOMContentLoaded",J),a.removeEventListener("load",J),n.ready()}n.ready.promise=function(b){return I||(I=n.Deferred(),"complete"===d.readyState||"loading"!==d.readyState&&!d.documentElement.doScroll?a.setTimeout(n.ready):(d.addEventListener("DOMContentLoaded",J),a.addEventListener("load",J))),I.promise(b)},n.ready.promise();var K=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===n.type(c)){e=!0;for(h in c)K(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,n.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(n(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},L=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function M(){this.expando=n.expando+M.uid++}M.uid=1,M.prototype={register:function(a,b){var c=b||{};return a.nodeType?a[this.expando]=c:Object.defineProperty(a,this.expando,{value:c,writable:!0,configurable:!0}),a[this.expando]},cache:function(a){if(!L(a))return{};var b=a[this.expando];return b||(b={},L(a)&&(a.nodeType?a[this.expando]=b:Object.defineProperty(a,this.expando,{value:b,configurable:!0}))),b},set:function(a,b,c){var d,e=this.cache(a);if("string"==typeof b)e[b]=c;else for(d in b)e[d]=b[d];return e},get:function(a,b){return void 0===b?this.cache(a):a[this.expando]&&a[this.expando][b]},access:function(a,b,c){var d;return void 0===b||b&&"string"==typeof b&&void 0===c?(d=this.get(a,b),void 0!==d?d:this.get(a,n.camelCase(b))):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d,e,f=a[this.expando];if(void 0!==f){if(void 0===b)this.register(a);else{n.isArray(b)?d=b.concat(b.map(n.camelCase)):(e=n.camelCase(b),b in f?d=[b,e]:(d=e,d=d in f?[d]:d.match(G)||[])),c=d.length;while(c--)delete f[d[c]]}(void 0===b||n.isEmptyObject(f))&&(a.nodeType?a[this.expando]=void 0:delete a[this.expando])}},hasData:function(a){var b=a[this.expando];return void 0!==b&&!n.isEmptyObject(b)}};var N=new M,O=new M,P=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,Q=/[A-Z]/g;function R(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(Q,"-$&").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:P.test(c)?n.parseJSON(c):c}catch(e){}O.set(a,b,c); +}else c=void 0;return c}n.extend({hasData:function(a){return O.hasData(a)||N.hasData(a)},data:function(a,b,c){return O.access(a,b,c)},removeData:function(a,b){O.remove(a,b)},_data:function(a,b,c){return N.access(a,b,c)},_removeData:function(a,b){N.remove(a,b)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=O.get(f),1===f.nodeType&&!N.get(f,"hasDataAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),R(f,d,e[d])));N.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){O.set(this,a)}):K(this,function(b){var c,d;if(f&&void 0===b){if(c=O.get(f,a)||O.get(f,a.replace(Q,"-$&").toLowerCase()),void 0!==c)return c;if(d=n.camelCase(a),c=O.get(f,d),void 0!==c)return c;if(c=R(f,d,void 0),void 0!==c)return c}else d=n.camelCase(a),this.each(function(){var c=O.get(this,d);O.set(this,d,b),a.indexOf("-")>-1&&void 0!==c&&O.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){O.remove(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=N.get(a,b),c&&(!d||n.isArray(c)?d=N.access(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return N.get(a,c)||N.access(a,c,{empty:n.Callbacks("once memory").add(function(){N.remove(a,[b+"queue",c])})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length",""],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};$.optgroup=$.option,$.tbody=$.tfoot=$.colgroup=$.caption=$.thead,$.th=$.td;function _(a,b){var c="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):[];return void 0===b||b&&n.nodeName(a,b)?n.merge([a],c):c}function aa(a,b){for(var c=0,d=a.length;d>c;c++)N.set(a[c],"globalEval",!b||N.get(b[c],"globalEval"))}var ba=/<|&#?\w+;/;function ca(a,b,c,d,e){for(var f,g,h,i,j,k,l=b.createDocumentFragment(),m=[],o=0,p=a.length;p>o;o++)if(f=a[o],f||0===f)if("object"===n.type(f))n.merge(m,f.nodeType?[f]:f);else if(ba.test(f)){g=g||l.appendChild(b.createElement("div")),h=(Y.exec(f)||["",""])[1].toLowerCase(),i=$[h]||$._default,g.innerHTML=i[1]+n.htmlPrefilter(f)+i[2],k=i[0];while(k--)g=g.lastChild;n.merge(m,g.childNodes),g=l.firstChild,g.textContent=""}else m.push(b.createTextNode(f));l.textContent="",o=0;while(f=m[o++])if(d&&n.inArray(f,d)>-1)e&&e.push(f);else if(j=n.contains(f.ownerDocument,f),g=_(l.appendChild(f),"script"),j&&aa(g),c){k=0;while(f=g[k++])Z.test(f.type||"")&&c.push(f)}return l}!function(){var a=d.createDocumentFragment(),b=a.appendChild(d.createElement("div")),c=d.createElement("input");c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),b.appendChild(c),l.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML="",l.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var da=/^key/,ea=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,fa=/^([^.]*)(?:\.(.+)|)/;function ga(){return!0}function ha(){return!1}function ia(){try{return d.activeElement}catch(a){}}function ja(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)ja(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=ha;else if(!e)return this;return 1===f&&(g=e,e=function(a){return n().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=n.guid++)),a.each(function(){n.event.add(this,b,e,d,c)})}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=N.get(a);if(r){c.handler&&(f=c,c=f.handler,e=f.selector),c.guid||(c.guid=n.guid++),(i=r.events)||(i=r.events={}),(g=r.handle)||(g=r.handle=function(b){return"undefined"!=typeof n&&n.event.triggered!==b.type?n.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(G)||[""],j=b.length;while(j--)h=fa.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o&&(l=n.event.special[o]||{},o=(e?l.delegateType:l.bindType)||o,l=n.event.special[o]||{},k=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},f),(m=i[o])||(m=i[o]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,p,g)!==!1||a.addEventListener&&a.addEventListener(o,g)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),n.event.global[o]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=N.hasData(a)&&N.get(a);if(r&&(i=r.events)){b=(b||"").match(G)||[""],j=b.length;while(j--)if(h=fa.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=i[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&q!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete i[o])}else for(o in i)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(i)&&N.remove(a,"handle events")}},dispatch:function(a){a=n.event.fix(a);var b,c,d,f,g,h=[],i=e.call(arguments),j=(N.get(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())(!a.rnamespace||a.rnamespace.test(g.namespace))&&(a.handleObj=g,a.data=g.data,d=((n.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==d&&(a.result=d)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&("click"!==a.type||isNaN(a.button)||a.button<1))for(;i!==this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?n(e,this).index(i)>-1:n.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h]*)\/>/gi,la=/\s*$/g;function pa(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a:a}function qa(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function ra(a){var b=na.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function sa(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(N.hasData(a)&&(f=N.access(a),g=N.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;d>c;c++)n.event.add(b,e,j[e][c])}O.hasData(a)&&(h=O.access(a),i=n.extend({},h),O.set(b,i))}}function ta(a,b){var c=b.nodeName.toLowerCase();"input"===c&&X.test(a.type)?b.checked=a.checked:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}function ua(a,b,c,d){b=f.apply([],b);var e,g,h,i,j,k,m=0,o=a.length,p=o-1,q=b[0],r=n.isFunction(q);if(r||o>1&&"string"==typeof q&&!l.checkClone&&ma.test(q))return a.each(function(e){var f=a.eq(e);r&&(b[0]=q.call(this,e,f.html())),ua(f,b,c,d)});if(o&&(e=ca(b,a[0].ownerDocument,!1,a,d),g=e.firstChild,1===e.childNodes.length&&(e=g),g||d)){for(h=n.map(_(e,"script"),qa),i=h.length;o>m;m++)j=e,m!==p&&(j=n.clone(j,!0,!0),i&&n.merge(h,_(j,"script"))),c.call(a[m],j,m);if(i)for(k=h[h.length-1].ownerDocument,n.map(h,ra),m=0;i>m;m++)j=h[m],Z.test(j.type||"")&&!N.access(j,"globalEval")&&n.contains(k,j)&&(j.src?n._evalUrl&&n._evalUrl(j.src):n.globalEval(j.textContent.replace(oa,"")))}return a}function va(a,b,c){for(var d,e=b?n.filter(b,a):a,f=0;null!=(d=e[f]);f++)c||1!==d.nodeType||n.cleanData(_(d)),d.parentNode&&(c&&n.contains(d.ownerDocument,d)&&aa(_(d,"script")),d.parentNode.removeChild(d));return a}n.extend({htmlPrefilter:function(a){return a.replace(ka,"<$1>")},clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=n.contains(a.ownerDocument,a);if(!(l.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(g=_(h),f=_(a),d=0,e=f.length;e>d;d++)ta(f[d],g[d]);if(b)if(c)for(f=f||_(a),g=g||_(h),d=0,e=f.length;e>d;d++)sa(f[d],g[d]);else sa(a,h);return g=_(h,"script"),g.length>0&&aa(g,!i&&_(a,"script")),h},cleanData:function(a){for(var b,c,d,e=n.event.special,f=0;void 0!==(c=a[f]);f++)if(L(c)){if(b=c[N.expando]){if(b.events)for(d in b.events)e[d]?n.event.remove(c,d):n.removeEvent(c,d,b.handle);c[N.expando]=void 0}c[O.expando]&&(c[O.expando]=void 0)}}}),n.fn.extend({domManip:ua,detach:function(a){return va(this,a,!0)},remove:function(a){return va(this,a)},text:function(a){return K(this,function(a){return void 0===a?n.text(this):this.empty().each(function(){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&(this.textContent=a)})},null,a,arguments.length)},append:function(){return ua(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=pa(this,a);b.appendChild(a)}})},prepend:function(){return ua(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=pa(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return ua(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return ua(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(n.cleanData(_(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return K(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!la.test(a)&&!$[(Y.exec(a)||["",""])[1].toLowerCase()]){a=n.htmlPrefilter(a);try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(_(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=[];return ua(this,arguments,function(b){var c=this.parentNode;n.inArray(this,a)<0&&(n.cleanData(_(this)),c&&c.replaceChild(b,this))},a)}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=[],e=n(a),f=e.length-1,h=0;f>=h;h++)c=h===f?this:this.clone(!0),n(e[h])[b](c),g.apply(d,c.get());return this.pushStack(d)}});var wa,xa={HTML:"block",BODY:"block"};function ya(a,b){var c=n(b.createElement(a)).appendTo(b.body),d=n.css(c[0],"display");return c.detach(),d}function za(a){var b=d,c=xa[a];return c||(c=ya(a,b),"none"!==c&&c||(wa=(wa||n("