diff --git a/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/astar/Graph.java b/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/astar/Graph.java new file mode 100644 index 0000000000..8145c03e7a --- /dev/null +++ b/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/astar/Graph.java @@ -0,0 +1,30 @@ +package com.baeldung.algorithms.astar; + +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + + +public class Graph { + private final Set nodes; + + private final Map> connections; + + public Graph(Set nodes, Map> connections) { + this.nodes = nodes; + this.connections = connections; + } + + public T getNode(String id) { + return nodes.stream() + .filter(node -> node.getId().equals(id)) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException("No node found with ID")); + } + + public Set getConnections(T node) { + return connections.get(node.getId()).stream() + .map(this::getNode) + .collect(Collectors.toSet()); + } +} diff --git a/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/astar/GraphNode.java b/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/astar/GraphNode.java new file mode 100644 index 0000000000..8d0539ead2 --- /dev/null +++ b/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/astar/GraphNode.java @@ -0,0 +1,5 @@ +package com.baeldung.algorithms.astar; + +public interface GraphNode { + String getId(); +} diff --git a/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/astar/RouteFinder.java b/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/astar/RouteFinder.java new file mode 100644 index 0000000000..35458093c5 --- /dev/null +++ b/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/astar/RouteFinder.java @@ -0,0 +1,66 @@ +package com.baeldung.algorithms.astar; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.PriorityQueue; +import java.util.Queue; +import java.util.stream.Collectors; + +public class RouteFinder { + private final Graph graph; + private final Scorer nextNodeScorer; + private final Scorer targetScorer; + + public RouteFinder(Graph graph, Scorer nextNodeScorer, Scorer targetScorer) { + this.graph = graph; + this.nextNodeScorer = nextNodeScorer; + this.targetScorer = targetScorer; + } + + public List findRoute(T from, T to) { + Map> allNodes = new HashMap<>(); + Queue openSet = new PriorityQueue<>(); + + RouteNode start = new RouteNode<>(from, null, 0d, targetScorer.computeCost(from, to)); + allNodes.put(from, start); + openSet.add(start); + + while (!openSet.isEmpty()) { + System.out.println("Open Set contains: " + openSet.stream().map(RouteNode::getCurrent).collect(Collectors.toSet())); + RouteNode next = openSet.poll(); + System.out.println("Looking at node: " + next); + if (next.getCurrent().equals(to)) { + System.out.println("Found our destination!"); + + List route = new ArrayList<>(); + RouteNode current = next; + do { + route.add(0, current.getCurrent()); + current = allNodes.get(current.getPrevious()); + } while (current != null); + + System.out.println("Route: " + route); + return route; + } + + graph.getConnections(next.getCurrent()).forEach(connection -> { + double newScore = next.getRouteScore() + nextNodeScorer.computeCost(next.getCurrent(), connection); + RouteNode nextNode = allNodes.getOrDefault(connection, new RouteNode<>(connection)); + allNodes.put(connection, nextNode); + + if (nextNode.getRouteScore() > newScore) { + nextNode.setPrevious(next.getCurrent()); + nextNode.setRouteScore(newScore); + nextNode.setEstimatedScore(newScore + targetScorer.computeCost(connection, to)); + openSet.add(nextNode); + System.out.println("Found a better route to node: " + nextNode); + } + }); + } + + throw new IllegalStateException("No route found"); + } + +} diff --git a/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/astar/RouteNode.java b/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/astar/RouteNode.java new file mode 100644 index 0000000000..842e50179d --- /dev/null +++ b/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/astar/RouteNode.java @@ -0,0 +1,67 @@ +package com.baeldung.algorithms.astar; + +import java.util.StringJoiner; + +class RouteNode implements Comparable { + private final T current; + private T previous; + private double routeScore; + private double estimatedScore; + + RouteNode(T current) { + this(current, null, Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY); + } + + RouteNode(T current, T previous, double routeScore, double estimatedScore) { + this.current = current; + this.previous = previous; + this.routeScore = routeScore; + this.estimatedScore = estimatedScore; + } + + T getCurrent() { + return current; + } + + T getPrevious() { + return previous; + } + + double getRouteScore() { + return routeScore; + } + + double getEstimatedScore() { + return estimatedScore; + } + + void setPrevious(T previous) { + this.previous = previous; + } + + void setRouteScore(double routeScore) { + this.routeScore = routeScore; + } + + void setEstimatedScore(double estimatedScore) { + this.estimatedScore = estimatedScore; + } + + @Override + public int compareTo(RouteNode other) { + if (this.estimatedScore > other.estimatedScore) { + return 1; + } else if (this.estimatedScore < other.estimatedScore) { + return -1; + } else { + return 0; + } + } + + @Override + public String toString() { + return new StringJoiner(", ", RouteNode.class.getSimpleName() + "[", "]").add("current=" + current) + .add("previous=" + previous).add("routeScore=" + routeScore).add("estimatedScore=" + estimatedScore) + .toString(); + } +} diff --git a/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/astar/Scorer.java b/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/astar/Scorer.java new file mode 100644 index 0000000000..64eb1e546f --- /dev/null +++ b/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/astar/Scorer.java @@ -0,0 +1,5 @@ +package com.baeldung.algorithms.astar; + +public interface Scorer { + double computeCost(T from, T to); +} diff --git a/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/astar/underground/HaversineScorer.java b/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/astar/underground/HaversineScorer.java new file mode 100644 index 0000000000..97564ee154 --- /dev/null +++ b/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/astar/underground/HaversineScorer.java @@ -0,0 +1,19 @@ +package com.baeldung.algorithms.astar.underground; + +import com.baeldung.algorithms.astar.Scorer; + +public class HaversineScorer implements Scorer { + @Override + public double computeCost(Station from, Station to) { + double R = 6372.8; // In kilometers + + double dLat = Math.toRadians(to.getLatitude() - from.getLatitude()); + double dLon = Math.toRadians(to.getLongitude() - from.getLongitude()); + double lat1 = Math.toRadians(from.getLatitude()); + double lat2 = Math.toRadians(to.getLatitude()); + + double a = Math.pow(Math.sin(dLat / 2),2) + Math.pow(Math.sin(dLon / 2),2) * Math.cos(lat1) * Math.cos(lat2); + double c = 2 * Math.asin(Math.sqrt(a)); + return R * c; + } +} diff --git a/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/astar/underground/RouteFinderIntegrationTest.java b/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/astar/underground/RouteFinderIntegrationTest.java new file mode 100644 index 0000000000..1e4ad56d94 --- /dev/null +++ b/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/astar/underground/RouteFinderIntegrationTest.java @@ -0,0 +1,643 @@ +package com.baeldung.algorithms.astar.underground; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import com.baeldung.algorithms.astar.Graph; +import com.baeldung.algorithms.astar.RouteFinder; +import org.junit.Before; +import org.junit.Test; + +public class RouteFinderIntegrationTest { + + private Graph underground; + + private RouteFinder routeFinder; + + @Before + public void setUp() throws Exception { + Set stations = new HashSet<>(); + Map> connections = new HashMap<>(); + + stations.add(new Station("1", "Acton Town", 51.5028, -0.2801)); + stations.add(new Station("2", "Aldgate", 51.5143, -0.0755)); + stations.add(new Station("3", "Aldgate East", 51.5154, -0.0726)); + stations.add(new Station("4", "All Saints", 51.5107, -0.013)); + stations.add(new Station("5", "Alperton", 51.5407, -0.2997)); + stations.add(new Station("6", "Amersham", 51.6736, -0.607)); + stations.add(new Station("7", "Angel", 51.5322, -0.1058)); + stations.add(new Station("8", "Archway", 51.5653, -0.1353)); + stations.add(new Station("9", "Arnos Grove", 51.6164, -0.1331)); + stations.add(new Station("10", "Arsenal", 51.5586, -0.1059)); + stations.add(new Station("11", "Baker Street", 51.5226, -0.1571)); + stations.add(new Station("12", "Balham", 51.4431, -0.1525)); + stations.add(new Station("13", "Bank", 51.5133, -0.0886)); + stations.add(new Station("14", "Barbican", 51.5204, -0.0979)); + stations.add(new Station("15", "Barking", 51.5396, 0.081)); + stations.add(new Station("16", "Barkingside", 51.5856, 0.0887)); + stations.add(new Station("17", "Barons Court", 51.4905, -0.2139)); + stations.add(new Station("18", "Bayswater", 51.5121, -0.1879)); + stations.add(new Station("19", "Beckton", 51.5148, 0.0613)); + stations.add(new Station("20", "Beckton Park", 51.5087, 0.055)); + stations.add(new Station("21", "Becontree", 51.5403, 0.127)); + stations.add(new Station("22", "Belsize Park", 51.5504, -0.1642)); + stations.add(new Station("23", "Bermondsey", 51.4979, -0.0637)); + stations.add(new Station("24", "Bethnal Green", 51.527, -0.0549)); + stations.add(new Station("25", "Blackfriars", 51.512, -0.1031)); + stations.add(new Station("26", "Blackhorse Road", 51.5867, -0.0417)); + stations.add(new Station("27", "Blackwall", 51.5079, -0.0066)); + stations.add(new Station("28", "Bond Street", 51.5142, -0.1494)); + stations.add(new Station("29", "Borough", 51.5011, -0.0943)); + stations.add(new Station("30", "Boston Manor", 51.4956, -0.325)); + stations.add(new Station("31", "Bounds Green", 51.6071, -0.1243)); + stations.add(new Station("32", "Bow Church", 51.5273, -0.0208)); + stations.add(new Station("33", "Bow Road", 51.5269, -0.0247)); + stations.add(new Station("34", "Brent Cross", 51.5766, -0.2136)); + stations.add(new Station("35", "Brixton", 51.4627, -0.1145)); + stations.add(new Station("36", "Bromley-By-Bow", 51.5248, -0.0119)); + stations.add(new Station("37", "Buckhurst Hill", 51.6266, 0.0471)); + stations.add(new Station("38", "Burnt Oak", 51.6028, -0.2641)); + stations.add(new Station("39", "Caledonian Road", 51.5481, -0.1188)); + stations.add(new Station("40", "Camden Town", 51.5392, -0.1426)); + stations.add(new Station("41", "Canada Water", 51.4982, -0.0502)); + stations.add(new Station("42", "Canary Wharf", 51.5051, -0.0209)); + stations.add(new Station("43", "Canning Town", 51.5147, 0.0082)); + stations.add(new Station("44", "Cannon Street", 51.5113, -0.0904)); + stations.add(new Station("45", "Canons Park", 51.6078, -0.2947)); + stations.add(new Station("46", "Chalfont & Latimer", 51.6679, -0.561)); + stations.add(new Station("47", "Chalk Farm", 51.5441, -0.1538)); + stations.add(new Station("48", "Chancery Lane", 51.5185, -0.1111)); + stations.add(new Station("49", "Charing Cross", 51.508, -0.1247)); + stations.add(new Station("50", "Chesham", 51.7052, -0.611)); + stations.add(new Station("51", "Chigwell", 51.6177, 0.0755)); + stations.add(new Station("52", "Chiswick Park", 51.4946, -0.2678)); + stations.add(new Station("53", "Chorleywood", 51.6543, -0.5183)); + stations.add(new Station("54", "Clapham Common", 51.4618, -0.1384)); + stations.add(new Station("55", "Clapham North", 51.4649, -0.1299)); + stations.add(new Station("56", "Clapham South", 51.4527, -0.148)); + stations.add(new Station("57", "Cockfosters", 51.6517, -0.1496)); + stations.add(new Station("58", "Colindale", 51.5955, -0.2502)); + stations.add(new Station("59", "Colliers Wood", 51.418, -0.1778)); + stations.add(new Station("60", "Covent Garden", 51.5129, -0.1243)); + stations.add(new Station("61", "Crossharbour & London Arena", 51.4957, -0.0144)); + stations.add(new Station("62", "Croxley", 51.647, -0.4412)); + stations.add(new Station("63", "Custom House", 51.5095, 0.0276)); + stations.add(new Station("64", "Cutty Sark", 51.4827, -0.0096)); + stations.add(new Station("65", "Cyprus", 51.5085, 0.064)); + stations.add(new Station("66", "Dagenham East", 51.5443, 0.1655)); + stations.add(new Station("67", "Dagenham Heathway", 51.5417, 0.1469)); + stations.add(new Station("68", "Debden", 51.6455, 0.0838)); + stations.add(new Station("69", "Deptford Bridge", 51.474, -0.0216)); + stations.add(new Station("70", "Devons Road", 51.5223, -0.0173)); + stations.add(new Station("71", "Dollis Hill", 51.552, -0.2387)); + stations.add(new Station("72", "Ealing Broadway", 51.5152, -0.3017)); + stations.add(new Station("73", "Ealing Common", 51.5101, -0.2882)); + stations.add(new Station("74", "Earl's Court", 51.492, -0.1973)); + stations.add(new Station("75", "Eastcote", 51.5765, -0.397)); + stations.add(new Station("76", "East Acton", 51.5168, -0.2474)); + stations.add(new Station("77", "East Finchley", 51.5874, -0.165)); + stations.add(new Station("78", "East Ham", 51.5394, 0.0518)); + stations.add(new Station("79", "East India", 51.5093, -0.0021)); + stations.add(new Station("80", "East Putney", 51.4586, -0.2112)); + stations.add(new Station("81", "Edgware", 51.6137, -0.275)); + stations.add(new Station("82", "Edgware Road (B)", 51.5199, -0.1679)); + stations.add(new Station("83", "Edgware Road (C)", 51.5203, -0.17)); + stations.add(new Station("84", "Elephant & Castle", 51.4943, -0.1001)); + stations.add(new Station("85", "Elm Park", 51.5496, 0.1977)); + stations.add(new Station("86", "Elverson Road", 51.4693, -0.0174)); + stations.add(new Station("87", "Embankment", 51.5074, -0.1223)); + stations.add(new Station("88", "Epping", 51.6937, 0.1139)); + stations.add(new Station("89", "Euston", 51.5282, -0.1337)); + stations.add(new Station("90", "Euston Square", 51.526, -0.1359)); + stations.add(new Station("91", "Fairlop", 51.596, 0.0912)); + stations.add(new Station("92", "Farringdon", 51.5203, -0.1053)); + stations.add(new Station("93", "Finchley Central", 51.6012, -0.1932)); + stations.add(new Station("94", "Finchley Road", 51.5472, -0.1803)); + stations.add(new Station("95", "Finsbury Park", 51.5642, -0.1065)); + stations.add(new Station("96", "Fulham Broadway", 51.4804, -0.195)); + stations.add(new Station("97", "Gallions Reach", 51.5096, 0.0716)); + stations.add(new Station("98", "Gants Hill", 51.5765, 0.0663)); + stations.add(new Station("99", "Gloucester Road", 51.4945, -0.1829)); + stations.add(new Station("100", "Golders Green", 51.5724, -0.1941)); + stations.add(new Station("101", "Goldhawk Road", 51.5018, -0.2267)); + stations.add(new Station("102", "Goodge Street", 51.5205, -0.1347)); + stations.add(new Station("103", "Grange Hill", 51.6132, 0.0923)); + stations.add(new Station("104", "Great Portland Street", 51.5238, -0.1439)); + stations.add(new Station("105", "Greenford", 51.5423, -0.3456)); + stations.add(new Station("106", "Greenwich", 51.4781, -0.0149)); + stations.add(new Station("107", "Green Park", 51.5067, -0.1428)); + stations.add(new Station("108", "Gunnersbury", 51.4915, -0.2754)); + stations.add(new Station("109", "Hainault", 51.603, 0.0933)); + stations.add(new Station("110", "Hammersmith", 51.4936, -0.2251)); + stations.add(new Station("111", "Hampstead", 51.5568, -0.178)); + stations.add(new Station("112", "Hanger Lane", 51.5302, -0.2933)); + stations.add(new Station("113", "Harlesden", 51.5362, -0.2575)); + stations.add(new Station("114", "Harrow & Wealdston", 51.5925, -0.3351)); + stations.add(new Station("115", "Harrow-on-the-Hill", 51.5793, -0.3366)); + stations.add(new Station("116", "Hatton Cross", 51.4669, -0.4227)); + stations.add(new Station("117", "Heathrow Terminals 1, 2 & 3", 51.4713, -0.4524)); + stations.add(new Station("118", "Heathrow Terminal 4", 51.4598, -0.4476)); + stations.add(new Station("119", "Hendon Central", 51.5829, -0.2259)); + stations.add(new Station("120", "Heron Quays", 51.5033, -0.0215)); + stations.add(new Station("121", "High Barnet", 51.6503, -0.1943)); + stations.add(new Station("122", "High Street Kensington", 51.5009, -0.1925)); + stations.add(new Station("123", "Highbury & Islington", 51.546, -0.104)); + stations.add(new Station("124", "Highgate", 51.5777, -0.1458)); + stations.add(new Station("125", "Hillingdon", 51.5538, -0.4499)); + stations.add(new Station("126", "Holborn", 51.5174, -0.12)); + stations.add(new Station("127", "Holland Park", 51.5075, -0.206)); + stations.add(new Station("128", "Holloway Road", 51.5526, -0.1132)); + stations.add(new Station("129", "Hornchurch", 51.5539, 0.2184)); + stations.add(new Station("130", "Hounslow Central", 51.4713, -0.3665)); + stations.add(new Station("131", "Hounslow East", 51.4733, -0.3564)); + stations.add(new Station("132", "Hounslow West", 51.4734, -0.3855)); + stations.add(new Station("133", "Hyde Park Corner", 51.5027, -0.1527)); + stations.add(new Station("134", "Ickenham", 51.5619, -0.4421)); + stations.add(new Station("135", "Island Gardens", 51.4871, -0.0101)); + stations.add(new Station("136", "Kennington", 51.4884, -0.1053)); + stations.add(new Station("137", "Kensal Green", 51.5304, -0.225)); + stations.add(new Station("138", "Kensington (Olympia)", 51.4983, -0.2106)); + stations.add(new Station("139", "Kentish Town", 51.5507, -0.1402)); + stations.add(new Station("140", "Kenton", 51.5816, -0.3162)); + stations.add(new Station("141", "Kew Gardens", 51.477, -0.285)); + stations.add(new Station("142", "Kilburn", 51.5471, -0.2047)); + stations.add(new Station("143", "Kilburn Park", 51.5351, -0.1939)); + stations.add(new Station("144", "Kingsbury", 51.5846, -0.2786)); + stations.add(new Station("145", "King's Cross St. Pancras", 51.5308, -0.1238)); + stations.add(new Station("146", "Knightsbridge", 51.5015, -0.1607)); + stations.add(new Station("147", "Ladbroke Grove", 51.5172, -0.2107)); + stations.add(new Station("148", "Lambeth North", 51.4991, -0.1115)); + stations.add(new Station("149", "Lancaster Gate", 51.5119, -0.1756)); + stations.add(new Station("150", "Latimer Road", 51.5139, -0.2172)); + stations.add(new Station("151", "Leicester Square", 51.5113, -0.1281)); + stations.add(new Station("152", "Lewisham", 51.4657, -0.0142)); + stations.add(new Station("153", "Leyton", 51.5566, -0.0053)); + stations.add(new Station("154", "Leytonstone", 51.5683, 0.0083)); + stations.add(new Station("155", "Limehouse", 51.5123, -0.0396)); + stations.add(new Station("156", "Liverpool Street", 51.5178, -0.0823)); + stations.add(new Station("157", "London Bridge", 51.5052, -0.0864)); + stations.add(new Station("158", "Loughton", 51.6412, 0.0558)); + stations.add(new Station("159", "Maida Vale", 51.53, -0.1854)); + stations.add(new Station("160", "Manor House", 51.5712, -0.0958)); + stations.add(new Station("161", "Mansion House", 51.5122, -0.094)); + stations.add(new Station("162", "Marble Arch", 51.5136, -0.1586)); + stations.add(new Station("163", "Marylebone", 51.5225, -0.1631)); + stations.add(new Station("164", "Mile End", 51.5249, -0.0332)); + stations.add(new Station("165", "Mill Hill East", 51.6082, -0.2103)); + stations.add(new Station("166", "Monument", 51.5108, -0.0863)); + stations.add(new Station("167", "Moorgate", 51.5186, -0.0886)); + stations.add(new Station("168", "Moor Park", 51.6294, -0.432)); + stations.add(new Station("169", "Morden", 51.4022, -0.1948)); + stations.add(new Station("170", "Mornington Crescent", 51.5342, -0.1387)); + stations.add(new Station("171", "Mudchute", 51.4902, -0.0145)); + stations.add(new Station("172", "Neasden", 51.5542, -0.2503)); + stations.add(new Station("173", "Newbury Park", 51.5756, 0.0899)); + stations.add(new Station("174", "New Cross", 51.4767, -0.0327)); + stations.add(new Station("175", "New Cross Gate", 51.4757, -0.0402)); + stations.add(new Station("176", "Northfields", 51.4995, -0.3142)); + stations.add(new Station("177", "Northolt", 51.5483, -0.3687)); + stations.add(new Station("178", "Northwick Park", 51.5784, -0.3184)); + stations.add(new Station("179", "Northwood", 51.6111, -0.424)); + stations.add(new Station("180", "Northwood Hills", 51.6004, -0.4092)); + stations.add(new Station("181", "North Acton", 51.5237, -0.2597)); + stations.add(new Station("182", "North Ealing", 51.5175, -0.2887)); + stations.add(new Station("183", "North Greenwich", 51.5005, 0.0039)); + stations.add(new Station("184", "North Harrow", 51.5846, -0.3626)); + stations.add(new Station("185", "North Wembley", 51.5621, -0.3034)); + stations.add(new Station("186", "Notting Hill Gate", 51.5094, -0.1967)); + stations.add(new Station("187", "Oakwood", 51.6476, -0.1318)); + stations.add(new Station("188", "Old Street", 51.5263, -0.0873)); + stations.add(new Station("189", "Osterley", 51.4813, -0.3522)); + stations.add(new Station("190", "Oval", 51.4819, -0.113)); + stations.add(new Station("191", "Oxford Circus", 51.515, -0.1415)); + stations.add(new Station("192", "Paddington", 51.5154, -0.1755)); + stations.add(new Station("193", "Park Royal", 51.527, -0.2841)); + stations.add(new Station("194", "Parsons Green", 51.4753, -0.2011)); + stations.add(new Station("195", "Perivale", 51.5366, -0.3232)); + stations.add(new Station("196", "Picadilly Circus", 51.5098, -0.1342)); + stations.add(new Station("197", "Pimlico", 51.4893, -0.1334)); + stations.add(new Station("198", "Pinner", 51.5926, -0.3805)); + stations.add(new Station("199", "Plaistow", 51.5313, 0.0172)); + stations.add(new Station("200", "Poplar", 51.5077, -0.0173)); + stations.add(new Station("201", "Preston Road", 51.572, -0.2954)); + stations.add(new Station("202", "Prince Regent", 51.5093, 0.0336)); + stations.add(new Station("203", "Pudding Mill Lane", 51.5343, -0.0139)); + stations.add(new Station("204", "Putney Bridge", 51.4682, -0.2089)); + stations.add(new Station("205", "Queen's Park", 51.5341, -0.2047)); + stations.add(new Station("206", "Queensbury", 51.5942, -0.2861)); + stations.add(new Station("207", "Queensway", 51.5107, -0.1877)); + stations.add(new Station("208", "Ravenscourt Park", 51.4942, -0.2359)); + stations.add(new Station("209", "Rayners Lane", 51.5753, -0.3714)); + stations.add(new Station("210", "Redbridge", 51.5763, 0.0454)); + stations.add(new Station("211", "Regent's Park", 51.5234, -0.1466)); + stations.add(new Station("212", "Richmond", 51.4633, -0.3013)); + stations.add(new Station("213", "Rickmansworth", 51.6404, -0.4733)); + stations.add(new Station("214", "Roding Valley", 51.6171, 0.0439)); + stations.add(new Station("215", "Rotherhithe", 51.501, -0.0525)); + stations.add(new Station("216", "Royal Albert", 51.5084, 0.0465)); + stations.add(new Station("217", "Royal Oak", 51.519, -0.188)); + stations.add(new Station("218", "Royal Victoria", 51.5091, 0.0181)); + stations.add(new Station("219", "Ruislip", 51.5715, -0.4213)); + stations.add(new Station("220", "Ruislip Gardens", 51.5606, -0.4103)); + stations.add(new Station("221", "Ruislip Manor", 51.5732, -0.4125)); + stations.add(new Station("222", "Russell Square", 51.523, -0.1244)); + stations.add(new Station("223", "Seven Sisters", 51.5822, -0.0749)); + stations.add(new Station("224", "Shadwell", 51.5117, -0.056)); + stations.add(new Station("225", "Shepherd's Bush (C)", 51.5046, -0.2187)); + stations.add(new Station("226", "Shepherd's Bush (H)", 51.5058, -0.2265)); + stations.add(new Station("227", "Shoreditch", 51.5227, -0.0708)); + stations.add(new Station("228", "Sloane Square", 51.4924, -0.1565)); + stations.add(new Station("229", "Snaresbrook", 51.5808, 0.0216)); + stations.add(new Station("230", "Southfields", 51.4454, -0.2066)); + stations.add(new Station("231", "Southgate", 51.6322, -0.128)); + stations.add(new Station("232", "Southwark", 51.501, -0.1052)); + stations.add(new Station("233", "South Ealing", 51.5011, -0.3072)); + stations.add(new Station("234", "South Harrow", 51.5646, -0.3521)); + stations.add(new Station("235", "South Kensington", 51.4941, -0.1738)); + stations.add(new Station("236", "South Kenton", 51.5701, -0.3081)); + stations.add(new Station("237", "South Quay", 51.5007, -0.0191)); + stations.add(new Station("238", "South Ruislip", 51.5569, -0.3988)); + stations.add(new Station("239", "South Wimbledon", 51.4154, -0.1919)); + stations.add(new Station("240", "South Woodford", 51.5917, 0.0275)); + stations.add(new Station("241", "Stamford Brook", 51.495, -0.2459)); + stations.add(new Station("242", "Stanmore", 51.6194, -0.3028)); + stations.add(new Station("243", "Stepney Green", 51.5221, -0.047)); + stations.add(new Station("244", "Stockwell", 51.4723, -0.123)); + stations.add(new Station("245", "Stonebridge Park", 51.5439, -0.2759)); + stations.add(new Station("246", "Stratford", 51.5416, -0.0042)); + stations.add(new Station("247", "St. James's Park", 51.4994, -0.1335)); + stations.add(new Station("248", "St. John's Wood", 51.5347, -0.174)); + stations.add(new Station("249", "St. Paul's", 51.5146, -0.0973)); + stations.add(new Station("250", "Sudbury Hill", 51.5569, -0.3366)); + stations.add(new Station("251", "Sudbury Town", 51.5507, -0.3156)); + stations.add(new Station("252", "Surrey Quays", 51.4933, -0.0478)); + stations.add(new Station("253", "Swiss Cottage", 51.5432, -0.1738)); + stations.add(new Station("254", "Temple", 51.5111, -0.1141)); + stations.add(new Station("255", "Theydon Bois", 51.6717, 0.1033)); + stations.add(new Station("256", "Tooting Bec", 51.4361, -0.1598)); + stations.add(new Station("257", "Tooting Broadway", 51.4275, -0.168)); + stations.add(new Station("258", "Tottenham Court Road", 51.5165, -0.131)); + stations.add(new Station("259", "Tottenham Hale", 51.5882, -0.0594)); + stations.add(new Station("260", "Totteridge & Whetstone", 51.6302, -0.1791)); + stations.add(new Station("261", "Tower Gateway", 51.5106, -0.0743)); + stations.add(new Station("262", "Tower Hill", 51.5098, -0.0766)); + stations.add(new Station("263", "Tufnell Park", 51.5567, -0.1374)); + stations.add(new Station("264", "Turnham Green", 51.4951, -0.2547)); + stations.add(new Station("265", "Turnpike Lane", 51.5904, -0.1028)); + stations.add(new Station("266", "Upminster", 51.559, 0.251)); + stations.add(new Station("267", "Upminster Bridge", 51.5582, 0.2343)); + stations.add(new Station("268", "Upney", 51.5385, 0.1014)); + stations.add(new Station("269", "Upton Park", 51.5352, 0.0343)); + stations.add(new Station("270", "Uxbridge", 51.5463, -0.4786)); + stations.add(new Station("271", "Vauxhall", 51.4861, -0.1253)); + stations.add(new Station("272", "Victoria", 51.4965, -0.1447)); + stations.add(new Station("273", "Walthamstow Central", 51.583, -0.0195)); + stations.add(new Station("274", "Wanstead", 51.5775, 0.0288)); + stations.add(new Station("275", "Wapping", 51.5043, -0.0558)); + stations.add(new Station("276", "Warren Street", 51.5247, -0.1384)); + stations.add(new Station("277", "Warwick Avenue", 51.5235, -0.1835)); + stations.add(new Station("278", "Waterloo", 51.5036, -0.1143)); + stations.add(new Station("279", "Watford", 51.6573, -0.4177)); + stations.add(new Station("280", "Wembley Central", 51.5519, -0.2963)); + stations.add(new Station("281", "Wembley Park", 51.5635, -0.2795)); + stations.add(new Station("282", "Westbourne Park", 51.521, -0.2011)); + stations.add(new Station("283", "Westferry", 51.5097, -0.0265)); + stations.add(new Station("284", "Westminster", 51.501, -0.1254)); + stations.add(new Station("285", "West Acton", 51.518, -0.2809)); + stations.add(new Station("286", "West Brompton", 51.4872, -0.1953)); + stations.add(new Station("287", "West Finchley", 51.6095, -0.1883)); + stations.add(new Station("288", "West Ham", 51.5287, 0.0056)); + stations.add(new Station("289", "West Hampstead", 51.5469, -0.1906)); + stations.add(new Station("290", "West Harrow", 51.5795, -0.3533)); + stations.add(new Station("291", "West India Quay", 51.507, -0.0203)); + stations.add(new Station("292", "West Kensington", 51.4907, -0.2065)); + stations.add(new Station("293", "West Ruislip", 51.5696, -0.4376)); + stations.add(new Station("294", "Whitechapel", 51.5194, -0.0612)); + stations.add(new Station("295", "White City", 51.512, -0.2239)); + stations.add(new Station("296", "Willesden Green", 51.5492, -0.2215)); + stations.add(new Station("297", "Willesden Junction", 51.5326, -0.2478)); + stations.add(new Station("298", "Wimbledon", 51.4214, -0.2064)); + stations.add(new Station("299", "Wimbledon Park", 51.4343, -0.1992)); + stations.add(new Station("300", "Woodford", 51.607, 0.0341)); + stations.add(new Station("301", "Woodside Park", 51.6179, -0.1856)); + stations.add(new Station("302", "Wood Green", 51.5975, -0.1097)); + + connections.put("1", Stream.of("52","73","73","233","264").collect(Collectors.toSet())); + connections.put("2", Stream.of("156","262","156").collect(Collectors.toSet())); + connections.put("3", Stream.of("262","294","156","294").collect(Collectors.toSet())); + connections.put("4", Stream.of("70","200").collect(Collectors.toSet())); + connections.put("5", Stream.of("193","251").collect(Collectors.toSet())); + connections.put("6", Stream.of("46").collect(Collectors.toSet())); + connections.put("7", Stream.of("145","188").collect(Collectors.toSet())); + connections.put("8", Stream.of("124","263").collect(Collectors.toSet())); + connections.put("9", Stream.of("31","231").collect(Collectors.toSet())); + connections.put("10", Stream.of("95","128").collect(Collectors.toSet())); + connections.put("11", Stream.of("163","211","83","104","83","104","28","248","94","104").collect(Collectors.toSet())); + connections.put("12", Stream.of("56","256").collect(Collectors.toSet())); + connections.put("13", Stream.of("156","249","224","157","167","278").collect(Collectors.toSet())); + connections.put("14", Stream.of("92","167","92","167","92","167").collect(Collectors.toSet())); + connections.put("15", Stream.of("78","268","78").collect(Collectors.toSet())); + connections.put("16", Stream.of("91","173").collect(Collectors.toSet())); + connections.put("17", Stream.of("110","292","74","110").collect(Collectors.toSet())); + connections.put("18", Stream.of("186","192","186","192").collect(Collectors.toSet())); + connections.put("19", Stream.of("97").collect(Collectors.toSet())); + connections.put("20", Stream.of("65","216").collect(Collectors.toSet())); + connections.put("21", Stream.of("67","268").collect(Collectors.toSet())); + connections.put("22", Stream.of("47","111").collect(Collectors.toSet())); + connections.put("23", Stream.of("41","157").collect(Collectors.toSet())); + connections.put("24", Stream.of("156","164").collect(Collectors.toSet())); + connections.put("25", Stream.of("161","254","161","254").collect(Collectors.toSet())); + connections.put("26", Stream.of("259","273").collect(Collectors.toSet())); + connections.put("27", Stream.of("79","200").collect(Collectors.toSet())); + connections.put("28", Stream.of("162","191","11","107").collect(Collectors.toSet())); + connections.put("29", Stream.of("84","157").collect(Collectors.toSet())); + connections.put("30", Stream.of("176","189").collect(Collectors.toSet())); + connections.put("31", Stream.of("9","302").collect(Collectors.toSet())); + connections.put("32", Stream.of("70","203").collect(Collectors.toSet())); + connections.put("33", Stream.of("36","164","36","164").collect(Collectors.toSet())); + connections.put("34", Stream.of("100","119").collect(Collectors.toSet())); + connections.put("35", Stream.of("244").collect(Collectors.toSet())); + connections.put("36", Stream.of("33","288","33","288").collect(Collectors.toSet())); + connections.put("37", Stream.of("158","300").collect(Collectors.toSet())); + connections.put("38", Stream.of("58","81").collect(Collectors.toSet())); + connections.put("39", Stream.of("128","145").collect(Collectors.toSet())); + connections.put("40", Stream.of("47","89","139","170").collect(Collectors.toSet())); + connections.put("41", Stream.of("215","252","23","42").collect(Collectors.toSet())); + connections.put("42", Stream.of("120","291","41","183").collect(Collectors.toSet())); + connections.put("43", Stream.of("79","218","183","288").collect(Collectors.toSet())); + connections.put("44", Stream.of("161","166","161","166").collect(Collectors.toSet())); + connections.put("45", Stream.of("206","242").collect(Collectors.toSet())); + connections.put("46", Stream.of("6","50","53").collect(Collectors.toSet())); + connections.put("47", Stream.of("22","40").collect(Collectors.toSet())); + connections.put("48", Stream.of("126","249").collect(Collectors.toSet())); + connections.put("49", Stream.of("87","196","87","151").collect(Collectors.toSet())); + connections.put("50", Stream.of("46").collect(Collectors.toSet())); + connections.put("51", Stream.of("103","214").collect(Collectors.toSet())); + connections.put("52", Stream.of("1","264").collect(Collectors.toSet())); + connections.put("53", Stream.of("46","213").collect(Collectors.toSet())); + connections.put("54", Stream.of("55","56").collect(Collectors.toSet())); + connections.put("55", Stream.of("54","244").collect(Collectors.toSet())); + connections.put("56", Stream.of("12","54").collect(Collectors.toSet())); + connections.put("57", Stream.of("187").collect(Collectors.toSet())); + connections.put("58", Stream.of("38","119").collect(Collectors.toSet())); + connections.put("59", Stream.of("239","257").collect(Collectors.toSet())); + connections.put("60", Stream.of("126","151").collect(Collectors.toSet())); + connections.put("61", Stream.of("171","237").collect(Collectors.toSet())); + connections.put("62", Stream.of("168","279").collect(Collectors.toSet())); + connections.put("63", Stream.of("202","218").collect(Collectors.toSet())); + connections.put("64", Stream.of("106","135").collect(Collectors.toSet())); + connections.put("65", Stream.of("20","97").collect(Collectors.toSet())); + connections.put("66", Stream.of("67","85").collect(Collectors.toSet())); + connections.put("67", Stream.of("21","66").collect(Collectors.toSet())); + connections.put("68", Stream.of("158","255").collect(Collectors.toSet())); + connections.put("69", Stream.of("86","106").collect(Collectors.toSet())); + connections.put("70", Stream.of("4","32").collect(Collectors.toSet())); + connections.put("71", Stream.of("172","296").collect(Collectors.toSet())); + connections.put("72", Stream.of("285","73").collect(Collectors.toSet())); + connections.put("73", Stream.of("72","1","1","182").collect(Collectors.toSet())); + connections.put("74", Stream.of("99","122","138","286","292","17","99").collect(Collectors.toSet())); + connections.put("75", Stream.of("209","221","209","221").collect(Collectors.toSet())); + connections.put("76", Stream.of("181","295").collect(Collectors.toSet())); + connections.put("77", Stream.of("93","124").collect(Collectors.toSet())); + connections.put("78", Stream.of("15","269","15","269").collect(Collectors.toSet())); + connections.put("79", Stream.of("27","43").collect(Collectors.toSet())); + connections.put("80", Stream.of("204","230").collect(Collectors.toSet())); + connections.put("81", Stream.of("38").collect(Collectors.toSet())); + connections.put("82", Stream.of("163","192").collect(Collectors.toSet())); + connections.put("83", Stream.of("11","192","192","11","192").collect(Collectors.toSet())); + connections.put("84", Stream.of("148","29","136").collect(Collectors.toSet())); + connections.put("85", Stream.of("66","129").collect(Collectors.toSet())); + connections.put("86", Stream.of("69","152").collect(Collectors.toSet())); + connections.put("87", Stream.of("49","278","254","284","254","284","49","278").collect(Collectors.toSet())); + connections.put("88", Stream.of("255").collect(Collectors.toSet())); + connections.put("89", Stream.of("40","145","170","276","145","276").collect(Collectors.toSet())); + connections.put("90", Stream.of("104","145","104","145","104","145").collect(Collectors.toSet())); + connections.put("91", Stream.of("16","109").collect(Collectors.toSet())); + connections.put("92", Stream.of("14","145","14","145","14","145").collect(Collectors.toSet())); + connections.put("93", Stream.of("77","165","287").collect(Collectors.toSet())); + connections.put("94", Stream.of("253","289","11","281").collect(Collectors.toSet())); + connections.put("95", Stream.of("10","160","123","223").collect(Collectors.toSet())); + connections.put("96", Stream.of("194","286").collect(Collectors.toSet())); + connections.put("97", Stream.of("19","65").collect(Collectors.toSet())); + connections.put("98", Stream.of("173","210").collect(Collectors.toSet())); + connections.put("99", Stream.of("122","235","74","235","74","235").collect(Collectors.toSet())); + connections.put("100", Stream.of("34","111").collect(Collectors.toSet())); + connections.put("101", Stream.of("110","226").collect(Collectors.toSet())); + connections.put("102", Stream.of("258","276").collect(Collectors.toSet())); + connections.put("103", Stream.of("51","109").collect(Collectors.toSet())); + connections.put("104", Stream.of("11","90","11","90","11","90").collect(Collectors.toSet())); + connections.put("105", Stream.of("177","195").collect(Collectors.toSet())); + connections.put("106", Stream.of("64","69").collect(Collectors.toSet())); + connections.put("107", Stream.of("28","284","133","196","191","272").collect(Collectors.toSet())); + connections.put("108", Stream.of("141","264").collect(Collectors.toSet())); + connections.put("109", Stream.of("91","103").collect(Collectors.toSet())); + connections.put("110", Stream.of("17","208","101","17","264").collect(Collectors.toSet())); + connections.put("111", Stream.of("22","100").collect(Collectors.toSet())); + connections.put("112", Stream.of("181","195").collect(Collectors.toSet())); + connections.put("113", Stream.of("245","297").collect(Collectors.toSet())); + connections.put("114", Stream.of("140").collect(Collectors.toSet())); + connections.put("115", Stream.of("178","184","290").collect(Collectors.toSet())); + connections.put("116", Stream.of("117","118","132").collect(Collectors.toSet())); + connections.put("117", Stream.of("116","118").collect(Collectors.toSet())); + connections.put("118", Stream.of("116","117").collect(Collectors.toSet())); + connections.put("119", Stream.of("34","58").collect(Collectors.toSet())); + connections.put("120", Stream.of("42","237").collect(Collectors.toSet())); + connections.put("121", Stream.of("260").collect(Collectors.toSet())); + connections.put("122", Stream.of("99","186","74","186").collect(Collectors.toSet())); + connections.put("123", Stream.of("95","145").collect(Collectors.toSet())); + connections.put("124", Stream.of("8","77").collect(Collectors.toSet())); + connections.put("125", Stream.of("134","270","134","270").collect(Collectors.toSet())); + connections.put("126", Stream.of("48","258","60","222").collect(Collectors.toSet())); + connections.put("127", Stream.of("186","225").collect(Collectors.toSet())); + connections.put("128", Stream.of("10","39").collect(Collectors.toSet())); + connections.put("129", Stream.of("85","267").collect(Collectors.toSet())); + connections.put("130", Stream.of("131","132").collect(Collectors.toSet())); + connections.put("131", Stream.of("130","189").collect(Collectors.toSet())); + connections.put("132", Stream.of("116","130").collect(Collectors.toSet())); + connections.put("133", Stream.of("107","146").collect(Collectors.toSet())); + connections.put("134", Stream.of("125","219","125","219").collect(Collectors.toSet())); + connections.put("135", Stream.of("64","171").collect(Collectors.toSet())); + connections.put("136", Stream.of("84","190","278").collect(Collectors.toSet())); + connections.put("137", Stream.of("205","297").collect(Collectors.toSet())); + connections.put("138", Stream.of("74").collect(Collectors.toSet())); + connections.put("139", Stream.of("40","263").collect(Collectors.toSet())); + connections.put("140", Stream.of("114","236").collect(Collectors.toSet())); + connections.put("141", Stream.of("108","212").collect(Collectors.toSet())); + connections.put("142", Stream.of("289","296").collect(Collectors.toSet())); + connections.put("143", Stream.of("159","205").collect(Collectors.toSet())); + connections.put("144", Stream.of("206","281").collect(Collectors.toSet())); + connections.put("145", Stream.of("90","92","90","92","90","92","7","89","39","222","89","123").collect(Collectors.toSet())); + connections.put("146", Stream.of("133","235").collect(Collectors.toSet())); + connections.put("147", Stream.of("150","282").collect(Collectors.toSet())); + connections.put("148", Stream.of("84","278").collect(Collectors.toSet())); + connections.put("149", Stream.of("162","207").collect(Collectors.toSet())); + connections.put("150", Stream.of("147","226").collect(Collectors.toSet())); + connections.put("151", Stream.of("49","258","60","196").collect(Collectors.toSet())); + connections.put("152", Stream.of("86").collect(Collectors.toSet())); + connections.put("153", Stream.of("154","246").collect(Collectors.toSet())); + connections.put("154", Stream.of("153","229","274").collect(Collectors.toSet())); + connections.put("155", Stream.of("224","283").collect(Collectors.toSet())); + connections.put("156", Stream.of("13","24","2","167","3","167","2","167").collect(Collectors.toSet())); + connections.put("157", Stream.of("23","232","13","29").collect(Collectors.toSet())); + connections.put("158", Stream.of("37","68").collect(Collectors.toSet())); + connections.put("159", Stream.of("143","277").collect(Collectors.toSet())); + connections.put("160", Stream.of("95","265").collect(Collectors.toSet())); + connections.put("161", Stream.of("25","44","25","44").collect(Collectors.toSet())); + connections.put("162", Stream.of("28","149").collect(Collectors.toSet())); + connections.put("163", Stream.of("11","82").collect(Collectors.toSet())); + connections.put("164", Stream.of("24","246","33","243","33","243").collect(Collectors.toSet())); + connections.put("165", Stream.of("93").collect(Collectors.toSet())); + connections.put("166", Stream.of("44","262","44","262").collect(Collectors.toSet())); + connections.put("167", Stream.of("14","156","14","156","14","156","13","188").collect(Collectors.toSet())); + connections.put("168", Stream.of("62","179","213").collect(Collectors.toSet())); + connections.put("169", Stream.of("239").collect(Collectors.toSet())); + connections.put("170", Stream.of("40","89").collect(Collectors.toSet())); + connections.put("171", Stream.of("61","135").collect(Collectors.toSet())); + connections.put("172", Stream.of("71","281").collect(Collectors.toSet())); + connections.put("173", Stream.of("16","98").collect(Collectors.toSet())); + connections.put("174", Stream.of("252").collect(Collectors.toSet())); + connections.put("175", Stream.of("252").collect(Collectors.toSet())); + connections.put("176", Stream.of("30","233").collect(Collectors.toSet())); + connections.put("177", Stream.of("105","238").collect(Collectors.toSet())); + connections.put("178", Stream.of("115","201").collect(Collectors.toSet())); + connections.put("179", Stream.of("168","180").collect(Collectors.toSet())); + connections.put("180", Stream.of("179","198").collect(Collectors.toSet())); + connections.put("181", Stream.of("76","112","285").collect(Collectors.toSet())); + connections.put("182", Stream.of("73","193").collect(Collectors.toSet())); + connections.put("183", Stream.of("42","43").collect(Collectors.toSet())); + connections.put("184", Stream.of("115","198").collect(Collectors.toSet())); + connections.put("185", Stream.of("236","280").collect(Collectors.toSet())); + connections.put("186", Stream.of("127","207","18","122","18","122").collect(Collectors.toSet())); + connections.put("187", Stream.of("57","231").collect(Collectors.toSet())); + connections.put("188", Stream.of("7","167").collect(Collectors.toSet())); + connections.put("189", Stream.of("30","131").collect(Collectors.toSet())); + connections.put("190", Stream.of("136","244").collect(Collectors.toSet())); + connections.put("191", Stream.of("196","211","28","258","107","276").collect(Collectors.toSet())); + connections.put("192", Stream.of("82","277","18","83","18","83","83","217").collect(Collectors.toSet())); + connections.put("193", Stream.of("5","182").collect(Collectors.toSet())); + connections.put("194", Stream.of("96","204").collect(Collectors.toSet())); + connections.put("195", Stream.of("105","112").collect(Collectors.toSet())); + connections.put("196", Stream.of("49","191","107","151").collect(Collectors.toSet())); + connections.put("197", Stream.of("271","272").collect(Collectors.toSet())); + connections.put("198", Stream.of("180","184").collect(Collectors.toSet())); + connections.put("199", Stream.of("269","288","269","288").collect(Collectors.toSet())); + connections.put("200", Stream.of("4","27","283","291").collect(Collectors.toSet())); + connections.put("201", Stream.of("178","281").collect(Collectors.toSet())); + connections.put("202", Stream.of("63","216").collect(Collectors.toSet())); + connections.put("203", Stream.of("32","246").collect(Collectors.toSet())); + connections.put("204", Stream.of("80","194").collect(Collectors.toSet())); + connections.put("205", Stream.of("137","143").collect(Collectors.toSet())); + connections.put("206", Stream.of("45","144").collect(Collectors.toSet())); + connections.put("207", Stream.of("149","186").collect(Collectors.toSet())); + connections.put("208", Stream.of("110","241").collect(Collectors.toSet())); + connections.put("209", Stream.of("75","290","75","234").collect(Collectors.toSet())); + connections.put("210", Stream.of("98","274").collect(Collectors.toSet())); + connections.put("211", Stream.of("11","191").collect(Collectors.toSet())); + connections.put("212", Stream.of("141").collect(Collectors.toSet())); + connections.put("213", Stream.of("53","168").collect(Collectors.toSet())); + connections.put("214", Stream.of("51","300").collect(Collectors.toSet())); + connections.put("215", Stream.of("41","275").collect(Collectors.toSet())); + connections.put("216", Stream.of("20","202").collect(Collectors.toSet())); + connections.put("217", Stream.of("192","282").collect(Collectors.toSet())); + connections.put("218", Stream.of("43","63").collect(Collectors.toSet())); + connections.put("219", Stream.of("134","221","134","221").collect(Collectors.toSet())); + connections.put("220", Stream.of("238","293").collect(Collectors.toSet())); + connections.put("221", Stream.of("75","219","75","219").collect(Collectors.toSet())); + connections.put("222", Stream.of("126","145").collect(Collectors.toSet())); + connections.put("223", Stream.of("95","259").collect(Collectors.toSet())); + connections.put("224", Stream.of("13","155","261","275","294").collect(Collectors.toSet())); + connections.put("225", Stream.of("127","295").collect(Collectors.toSet())); + connections.put("226", Stream.of("101","150").collect(Collectors.toSet())); + connections.put("227", Stream.of("294").collect(Collectors.toSet())); + connections.put("228", Stream.of("235","272","235","272").collect(Collectors.toSet())); + connections.put("229", Stream.of("154","240").collect(Collectors.toSet())); + connections.put("230", Stream.of("80","299").collect(Collectors.toSet())); + connections.put("231", Stream.of("9","187").collect(Collectors.toSet())); + connections.put("232", Stream.of("157","278").collect(Collectors.toSet())); + connections.put("233", Stream.of("1","176").collect(Collectors.toSet())); + connections.put("234", Stream.of("209","250").collect(Collectors.toSet())); + connections.put("235", Stream.of("99","228","99","228","99","146").collect(Collectors.toSet())); + connections.put("236", Stream.of("140","185").collect(Collectors.toSet())); + connections.put("237", Stream.of("61","120").collect(Collectors.toSet())); + connections.put("238", Stream.of("177","220").collect(Collectors.toSet())); + connections.put("239", Stream.of("59","169").collect(Collectors.toSet())); + connections.put("240", Stream.of("229","300").collect(Collectors.toSet())); + connections.put("241", Stream.of("208","264").collect(Collectors.toSet())); + connections.put("242", Stream.of("45").collect(Collectors.toSet())); + connections.put("243", Stream.of("164","294","164","294").collect(Collectors.toSet())); + connections.put("244", Stream.of("55","190","35","271").collect(Collectors.toSet())); + connections.put("245", Stream.of("113","280").collect(Collectors.toSet())); + connections.put("246", Stream.of("153","164","203","288").collect(Collectors.toSet())); + connections.put("247", Stream.of("272","284","272","284").collect(Collectors.toSet())); + connections.put("248", Stream.of("11","253").collect(Collectors.toSet())); + connections.put("249", Stream.of("13","48").collect(Collectors.toSet())); + connections.put("250", Stream.of("234","251").collect(Collectors.toSet())); + connections.put("251", Stream.of("5","250").collect(Collectors.toSet())); + connections.put("252", Stream.of("41","174","175").collect(Collectors.toSet())); + connections.put("253", Stream.of("94","248").collect(Collectors.toSet())); + connections.put("254", Stream.of("25","87","25","87").collect(Collectors.toSet())); + connections.put("255", Stream.of("68","88").collect(Collectors.toSet())); + connections.put("256", Stream.of("12","257").collect(Collectors.toSet())); + connections.put("257", Stream.of("59","256").collect(Collectors.toSet())); + connections.put("258", Stream.of("126","191","102","151").collect(Collectors.toSet())); + connections.put("259", Stream.of("26","223").collect(Collectors.toSet())); + connections.put("260", Stream.of("121","301").collect(Collectors.toSet())); + connections.put("261", Stream.of("224").collect(Collectors.toSet())); + connections.put("262", Stream.of("2","166","3","166").collect(Collectors.toSet())); + connections.put("263", Stream.of("8","139").collect(Collectors.toSet())); + connections.put("264", Stream.of("52","108","241","1","110").collect(Collectors.toSet())); + connections.put("265", Stream.of("160","302").collect(Collectors.toSet())); + connections.put("266", Stream.of("267").collect(Collectors.toSet())); + connections.put("267", Stream.of("129","266").collect(Collectors.toSet())); + connections.put("268", Stream.of("15","21").collect(Collectors.toSet())); + connections.put("269", Stream.of("78","199","78","199").collect(Collectors.toSet())); + connections.put("270", Stream.of("125","125").collect(Collectors.toSet())); + connections.put("271", Stream.of("197","244").collect(Collectors.toSet())); + connections.put("272", Stream.of("228","247","228","247","107","197").collect(Collectors.toSet())); + connections.put("273", Stream.of("26").collect(Collectors.toSet())); + connections.put("274", Stream.of("154","210").collect(Collectors.toSet())); + connections.put("275", Stream.of("215","224").collect(Collectors.toSet())); + connections.put("276", Stream.of("89","102","89","191").collect(Collectors.toSet())); + connections.put("277", Stream.of("159","192").collect(Collectors.toSet())); + connections.put("278", Stream.of("87","148","232","284","87","136","13").collect(Collectors.toSet())); + connections.put("279", Stream.of("62").collect(Collectors.toSet())); + connections.put("280", Stream.of("185","245").collect(Collectors.toSet())); + connections.put("281", Stream.of("144","172","94","201").collect(Collectors.toSet())); + connections.put("282", Stream.of("147","217").collect(Collectors.toSet())); + connections.put("283", Stream.of("155","200","291").collect(Collectors.toSet())); + connections.put("284", Stream.of("87","247","87","247","107","278").collect(Collectors.toSet())); + connections.put("285", Stream.of("72","181").collect(Collectors.toSet())); + connections.put("286", Stream.of("74","96").collect(Collectors.toSet())); + connections.put("287", Stream.of("93","301").collect(Collectors.toSet())); + connections.put("288", Stream.of("36","199","36","199","43","246").collect(Collectors.toSet())); + connections.put("289", Stream.of("94","142").collect(Collectors.toSet())); + connections.put("290", Stream.of("115","209").collect(Collectors.toSet())); + connections.put("291", Stream.of("42","200","283").collect(Collectors.toSet())); + connections.put("292", Stream.of("17","74").collect(Collectors.toSet())); + connections.put("293", Stream.of("220").collect(Collectors.toSet())); + connections.put("294", Stream.of("3","243","224","227","3","243").collect(Collectors.toSet())); + connections.put("295", Stream.of("76","225").collect(Collectors.toSet())); + connections.put("296", Stream.of("71","142").collect(Collectors.toSet())); + connections.put("297", Stream.of("113","137").collect(Collectors.toSet())); + connections.put("298", Stream.of("299").collect(Collectors.toSet())); + connections.put("299", Stream.of("230","298").collect(Collectors.toSet())); + connections.put("300", Stream.of("37","214","240").collect(Collectors.toSet())); + connections.put("301", Stream.of("260","287").collect(Collectors.toSet())); + connections.put("302", Stream.of("31","265").collect(Collectors.toSet())); + + underground = new Graph<>(stations, connections); + routeFinder = new RouteFinder<>(underground, new HaversineScorer(), new HaversineScorer()); + } + + @Test + public void findRoute() { + List route = routeFinder.findRoute(underground.getNode("74"), underground.getNode("7")); + + System.out.println(route.stream().map(Station::getName).collect(Collectors.toList())); + } +} diff --git a/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/astar/underground/Station.java b/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/astar/underground/Station.java new file mode 100644 index 0000000000..59bd8d62c2 --- /dev/null +++ b/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/astar/underground/Station.java @@ -0,0 +1,42 @@ +package com.baeldung.algorithms.astar.underground; + +import java.util.StringJoiner; + +import com.baeldung.algorithms.astar.GraphNode; + +public class Station implements GraphNode { + private final String id; + private final String name; + private final double latitude; + private final double longitude; + + public Station(String id, String name, double latitude, double longitude) { + this.id = id; + this.name = name; + this.latitude = latitude; + this.longitude = longitude; + } + + @Override + public String getId() { + return id; + } + + public String getName() { + return name; + } + + public double getLatitude() { + return latitude; + } + + public double getLongitude() { + return longitude; + } + + @Override + public String toString() { + return new StringJoiner(", ", Station.class.getSimpleName() + "[", "]").add("id='" + id + "'") + .add("name='" + name + "'").add("latitude=" + latitude).add("longitude=" + longitude).toString(); + } +} diff --git a/algorithms-miscellaneous-2/src/test/resources/graph.png b/algorithms-miscellaneous-2/src/test/resources/graph.png index 7165a51782..12af62c131 100644 Binary files a/algorithms-miscellaneous-2/src/test/resources/graph.png and b/algorithms-miscellaneous-2/src/test/resources/graph.png differ diff --git a/algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/smallestinteger/SmallestMissingPositiveInteger.java b/algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/smallestinteger/SmallestMissingPositiveInteger.java new file mode 100644 index 0000000000..b08eea2a66 --- /dev/null +++ b/algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/smallestinteger/SmallestMissingPositiveInteger.java @@ -0,0 +1,37 @@ +package com.baeldung.algorithms.smallestinteger; + +import java.util.Arrays; + +public class SmallestMissingPositiveInteger { + public static int searchInSortedArray(int[] input) { + for (int i = 0; i < input.length; i++) { + if (i != input[i]) { + return i; + } + } + + return input.length; + } + + public static int searchInUnsortedArraySortingFirst(int[] input) { + Arrays.sort(input); + return searchInSortedArray(input); + } + + public static int searchInUnsortedArrayBooleanArray(int[] input) { + boolean[] flags = new boolean[input.length]; + for (int number : input) { + if (number < flags.length) { + flags[number] = true; + } + } + + for (int i = 0; i < flags.length; i++) { + if (!flags[i]) { + return i; + } + } + + return flags.length; + } +} diff --git a/algorithms-miscellaneous-4/src/test/java/com/baeldung/algorithms/smallestinteger/SmallestMissingPositiveIntegerUnitTest.java b/algorithms-miscellaneous-4/src/test/java/com/baeldung/algorithms/smallestinteger/SmallestMissingPositiveIntegerUnitTest.java new file mode 100644 index 0000000000..8bb7151b41 --- /dev/null +++ b/algorithms-miscellaneous-4/src/test/java/com/baeldung/algorithms/smallestinteger/SmallestMissingPositiveIntegerUnitTest.java @@ -0,0 +1,88 @@ +package com.baeldung.algorithms.smallestinteger; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +class SmallestMissingPositiveIntegerUnitTest { + @Test + void givenArrayWithThreeMissing_whenSearchInSortedArray_thenThree() { + int[] input = new int[] {0, 1, 2, 4, 5}; + + int result = SmallestMissingPositiveInteger.searchInSortedArray(input); + + assertThat(result).isEqualTo(3); + } + + @Test + void givenArrayWithOneAndThreeMissing_whenSearchInSortedArray_thenOne() { + int[] input = new int[] {0, 2, 4, 5}; + + int result = SmallestMissingPositiveInteger.searchInSortedArray(input); + + assertThat(result).isEqualTo(1); + } + + @Test + void givenArrayWithoutMissingInteger_whenSearchInSortedArray_thenArrayLength() { + int[] input = new int[] {0, 1, 2, 3, 4, 5}; + + int result = SmallestMissingPositiveInteger.searchInSortedArray(input); + + assertThat(result).isEqualTo(input.length); + } + + @Test + void givenArrayWithThreeMissing_whenSearchInUnsortedArraySortingFirst_thenThree() { + int[] input = new int[] {1, 4, 0, 5, 2}; + + int result = SmallestMissingPositiveInteger.searchInUnsortedArraySortingFirst(input); + + assertThat(result).isEqualTo(3); + } + + @Test + void givenArrayWithOneAndThreeMissing_whenSearchInUnsortedArraySortingFirst_thenOne() { + int[] input = new int[] {4, 2, 0, 5}; + + int result = SmallestMissingPositiveInteger.searchInUnsortedArraySortingFirst(input); + + assertThat(result).isEqualTo(1); + } + + @Test + void givenArrayWithoutMissingInteger_whenSearchInUnsortedArraySortingFirst_thenArrayLength() { + int[] input = new int[] {4, 5, 1, 3, 0, 2}; + + int result = SmallestMissingPositiveInteger.searchInUnsortedArraySortingFirst(input); + + assertThat(result).isEqualTo(input.length); + } + + @Test + void givenArrayWithThreeMissing_whenSearchInUnsortedArrayBooleanArray_thenThree() { + int[] input = new int[] {1, 4, 0, 5, 2}; + + int result = SmallestMissingPositiveInteger.searchInUnsortedArrayBooleanArray(input); + + assertThat(result).isEqualTo(3); + } + + @Test + void givenArrayWithOneAndThreeMissing_whenSearchInUnsortedArrayBooleanArray_thenOne() { + int[] input = new int[] {4, 2, 0, 5}; + + int result = SmallestMissingPositiveInteger.searchInUnsortedArrayBooleanArray(input); + + assertThat(result).isEqualTo(1); + } + + @Test + void givenArrayWithoutMissingInteger_whenSearchInUnsortedArrayBooleanArray_thenArrayLength() { + int[] input = new int[] {4, 5, 1, 3, 0, 2}; + + int result = SmallestMissingPositiveInteger.searchInUnsortedArrayBooleanArray(input); + + assertThat(result).isEqualTo(input.length); + } +} \ No newline at end of file diff --git a/algorithms-miscellaneous-5/README.md b/algorithms-miscellaneous-5/README.md index 7a8f2e0a36..598fbab8b5 100644 --- a/algorithms-miscellaneous-5/README.md +++ b/algorithms-miscellaneous-5/README.md @@ -8,4 +8,5 @@ This module contains articles about algorithms. Some classes of algorithms, e.g. - [Converting Between Byte Arrays and Hexadecimal Strings in Java](https://www.baeldung.com/java-byte-arrays-hex-strings) - [Reversing a Binary Tree in Java](https://www.baeldung.com/java-reversing-a-binary-tree) - [Find If Two Numbers Are Relatively Prime in Java](https://www.baeldung.com/java-two-relatively-prime-numbers) +- [Knapsack Problem Implementation in Java](https://www.baeldung.com/java-knapsack) - More articles: [[<-- prev]](/../algorithms-miscellaneous-4) diff --git a/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/balancedbinarytree/BalancedBinaryTree.java b/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/balancedbinarytree/BalancedBinaryTree.java new file mode 100644 index 0000000000..84180473e2 --- /dev/null +++ b/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/balancedbinarytree/BalancedBinaryTree.java @@ -0,0 +1,33 @@ +package com.baeldung.algorithms.balancedbinarytree; + +public class BalancedBinaryTree { + + public static boolean isBalanced(Tree tree) { + return isBalancedRecursive(tree, -1).isBalanced; + } + + private static Result isBalancedRecursive(Tree tree, int depth) { + if (tree == null) { + return new Result(true, -1); + } + + Result leftSubtreeResult = isBalancedRecursive(tree.left(), depth + 1); + Result rightSubtreeResult = isBalancedRecursive(tree.right(), depth + 1); + + boolean isBalanced = Math.abs(leftSubtreeResult.height - rightSubtreeResult.height) <= 1; + boolean subtreesAreBalanced = leftSubtreeResult.isBalanced && rightSubtreeResult.isBalanced; + int height = Math.max(leftSubtreeResult.height, rightSubtreeResult.height) + 1; + + return new Result(isBalanced && subtreesAreBalanced, height); + } + + private static final class Result { + private final boolean isBalanced; + private final int height; + + private Result(boolean isBalanced, int height) { + this.isBalanced = isBalanced; + this.height = height; + } + } +} diff --git a/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/balancedbinarytree/Tree.java b/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/balancedbinarytree/Tree.java new file mode 100644 index 0000000000..8e091408c9 --- /dev/null +++ b/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/balancedbinarytree/Tree.java @@ -0,0 +1,34 @@ +package com.baeldung.algorithms.balancedbinarytree; + +public class Tree { + private final int value; + private final Tree left; + private final Tree right; + + public Tree(int value, Tree left, Tree right) { + this.value = value; + this.left = left; + this.right = right; + } + + public int value() { + return value; + } + + public Tree left() { + return left; + } + + public Tree right() { + return right; + } + + @Override + public String toString() { + return String.format("[%s, %s, %s]", + value, + left == null ? "null" : left.toString(), + right == null ? "null" : right.toString() + ); + } +} diff --git a/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/binarygap/BinaryGap.java b/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/binarygap/BinaryGap.java new file mode 100644 index 0000000000..e31e9870a0 --- /dev/null +++ b/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/binarygap/BinaryGap.java @@ -0,0 +1,17 @@ +package com.baeldung.algorithms.binarygap; + +public class BinaryGap { + static int calculateBinaryGap(int n) { + return calculateBinaryGap(n >>> Integer.numberOfTrailingZeros(n), 0, 0); + } + + static int calculateBinaryGap(int n, int current, int maximum) { + if (n == 0) { + return maximum; + } else if ((n & 1) == 0) { + return calculateBinaryGap(n >>> 1, current + 1, maximum); + } else { + return calculateBinaryGap(n >>> 1, 0, Math.max(maximum, current)); + } + } +} diff --git a/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/balancedbinarytree/BalancedBinaryTreeUnitTest.java b/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/balancedbinarytree/BalancedBinaryTreeUnitTest.java new file mode 100644 index 0000000000..25f313f991 --- /dev/null +++ b/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/balancedbinarytree/BalancedBinaryTreeUnitTest.java @@ -0,0 +1,26 @@ +package com.baeldung.algorithms.balancedbinarytree; + +import org.junit.Test; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertFalse; + +public class BalancedBinaryTreeUnitTest extends BinaryTreeDataProvider { + + @Test + public void givenBalancedTrees_whenCallingIsBalanced_ShouldReturnTrue() { + for (Tree tree : balancedTrees()) { + assertTrue(toString(tree) + " should be balanced", BalancedBinaryTree.isBalanced(tree)); + } + } + + @Test + public void givenUnbalancedTrees_whenCallingIsBalanced_ShouldReturnFalse() { + for (Tree tree : unbalancedTrees()) { + assertFalse(toString(tree) + " should not be balanced", BalancedBinaryTree.isBalanced(tree)); + } + } + + private String toString(Tree tree) { + return tree != null ? tree.toString() : "null"; + } +} diff --git a/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/balancedbinarytree/BinaryTreeDataProvider.java b/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/balancedbinarytree/BinaryTreeDataProvider.java new file mode 100644 index 0000000000..3f4318afbc --- /dev/null +++ b/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/balancedbinarytree/BinaryTreeDataProvider.java @@ -0,0 +1,69 @@ +package com.baeldung.algorithms.balancedbinarytree; + +import java.util.Arrays; +import java.util.Collection; + +class BinaryTreeDataProvider { + + static Collection balancedTrees() { + return Arrays.asList( + null, + leaf(1), + tree(1, leaf(2), leaf(3)), + tree( + 1, + leaf(2), + tree(3, leaf(4), null) + ), + tree( + 1, + tree( + 2, + tree(3, leaf(4), null), + leaf(5) + ), + tree( + 6, + leaf(7), + tree(8, null, leaf(9)) + ) + ) + ); + } + + static Collection unbalancedTrees() { + return Arrays.asList( + tree( + 1, + tree(2, leaf(3), null), + null + ), + tree( + 1, + tree( + 2, + tree(3, leaf(4), leaf(5)), + null + ), + tree(6, leaf(7), null) + ), + tree( + 1, + tree(2, leaf(3), null), + tree( + 4, + tree(5, leaf(6), leaf(7)), + null + ) + ) + ); + } + + private static Tree leaf(int value) { + return new Tree(value, null, null); + } + + private static Tree tree(int value, Tree left, Tree right) { + return new Tree(value, left, right); + } +} diff --git a/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/binarygap/BinaryGapUnitTest.java b/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/binarygap/BinaryGapUnitTest.java new file mode 100644 index 0000000000..304d36e2bb --- /dev/null +++ b/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/binarygap/BinaryGapUnitTest.java @@ -0,0 +1,34 @@ +package com.baeldung.algorithms.binarygap; + +import static com.baeldung.algorithms.binarygap.BinaryGap.calculateBinaryGap; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class BinaryGapUnitTest { + + @Test public void givenNoOccurrenceOfBoundedZeros_whenCalculateBinaryGap_thenOutputCorrectResult() { + + int result = calculateBinaryGap(63); + assertEquals(0, result); + } + + @Test public void givenTrailingZeros_whenCalculateBinaryGap_thenOutputCorrectResult() { + + int result = calculateBinaryGap(40); + assertEquals(1, result); + } + + @Test public void givenSingleOccurrenceOfBoundedZeros_whenCalculateBinaryGap_thenOutputCorrectResult() { + + int result = calculateBinaryGap(9); + assertEquals(2, result); + } + + @Test public void givenMultipleOccurrenceOfBoundedZeros_whenCalculateBinaryGap_thenOutputCorrectResult() { + + int result = calculateBinaryGap(145); + assertEquals(3, result); + } + +} diff --git a/core-java-modules/README.md b/core-java-modules/README.md index 55dacca916..fa77846b45 100644 --- a/core-java-modules/README.md +++ b/core-java-modules/README.md @@ -5,6 +5,5 @@ This module contains modules about core Java ## Relevant articles: - [Multi-Module Maven Application with Java Modules](https://www.baeldung.com/maven-multi-module-project-java-jpms) -- [Guide to Java FileChannel](https://www.baeldung.com/java-filechannel) - [Understanding the NumberFormatException in Java](https://www.baeldung.com/java-number-format-exception) - [Will an Error Be Caught by Catch Block in Java?](https://www.baeldung.com/java-error-catch) diff --git a/core-java-modules/core-java-9-improvements/README.md b/core-java-modules/core-java-9-improvements/README.md new file mode 100644 index 0000000000..b0baccba7f --- /dev/null +++ b/core-java-modules/core-java-9-improvements/README.md @@ -0,0 +1,17 @@ +## Core Java 9 + +This module contains articles about the improvements to core Java features introduced with Java 9. + +### Relevant Articles: + +- [New Stream Collectors in Java 9](http://www.baeldung.com/java9-stream-collectors) +- [Java 9 Optional API Additions](https://www.baeldung.com/java-9-optional) +- [Java 9 Convenience Factory Methods for Collections](https://www.baeldung.com/java-9-collections-factory-methods) +- [Java 9 Stream API Improvements](https://www.baeldung.com/java-9-stream-api) +- [Java 9 java.util.Objects Additions](https://www.baeldung.com/java-9-objects-new) +- [Java 9 CompletableFuture API Improvements](https://www.baeldung.com/java-9-completablefuture) + +#### Relevant articles not in this module: + +- [Java 9 Process API Improvements](https://www.baeldung.com/java-9-process-api) (see the [core-java-os](/core-java-os) module) + diff --git a/core-java-modules/core-java-9-improvements/pom.xml b/core-java-modules/core-java-9-improvements/pom.xml new file mode 100644 index 0000000000..aee289c79f --- /dev/null +++ b/core-java-modules/core-java-9-improvements/pom.xml @@ -0,0 +1,73 @@ + + 4.0.0 + core-java-9 + 0.2-SNAPSHOT + core-java-9 + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + ../../ + + + + + com.jayway.awaitility + awaitility + ${awaitility.version} + test + + + org.assertj + assertj-core + ${assertj.version} + test + + + com.google.guava + guava + ${guava.version} + + + org.junit.platform + junit-platform-runner + ${junit.platform.version} + test + + + + + core-java-9 + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + ${maven.compiler.source} + ${maven.compiler.target} + + + + + + + + apache.snapshots + http://repository.apache.org/snapshots/ + + + + + + 3.10.0 + 1.2.0 + 1.7.0 + 1.9 + 1.9 + 25.1-jre + + + diff --git a/core-java-modules/core-java-9/src/test/java/com/baeldung/java9/Java9OptionalTest.java b/core-java-modules/core-java-9-improvements/src/test/java/com/baeldung/java9/Java9OptionalTest.java similarity index 100% rename from core-java-modules/core-java-9/src/test/java/com/baeldung/java9/Java9OptionalTest.java rename to core-java-modules/core-java-9-improvements/src/test/java/com/baeldung/java9/Java9OptionalTest.java diff --git a/core-java-modules/core-java-9/src/test/java/com/baeldung/java9/concurrent/future/CompletableFutureUnitTest.java b/core-java-modules/core-java-9-improvements/src/test/java/com/baeldung/java9/concurrent/future/CompletableFutureUnitTest.java similarity index 100% rename from core-java-modules/core-java-9/src/test/java/com/baeldung/java9/concurrent/future/CompletableFutureUnitTest.java rename to core-java-modules/core-java-9-improvements/src/test/java/com/baeldung/java9/concurrent/future/CompletableFutureUnitTest.java diff --git a/core-java-modules/core-java-9/src/test/java/com/baeldung/java9/language/Java9ObjectsAPIUnitTest.java b/core-java-modules/core-java-9-improvements/src/test/java/com/baeldung/java9/language/Java9ObjectsAPIUnitTest.java similarity index 100% rename from core-java-modules/core-java-9/src/test/java/com/baeldung/java9/language/Java9ObjectsAPIUnitTest.java rename to core-java-modules/core-java-9-improvements/src/test/java/com/baeldung/java9/language/Java9ObjectsAPIUnitTest.java diff --git a/core-java-modules/core-java-9/src/test/java/com/baeldung/java9/language/collections/ListFactoryMethodsUnitTest.java b/core-java-modules/core-java-9-improvements/src/test/java/com/baeldung/java9/language/collections/ListFactoryMethodsUnitTest.java similarity index 100% rename from core-java-modules/core-java-9/src/test/java/com/baeldung/java9/language/collections/ListFactoryMethodsUnitTest.java rename to core-java-modules/core-java-9-improvements/src/test/java/com/baeldung/java9/language/collections/ListFactoryMethodsUnitTest.java diff --git a/core-java-modules/core-java-9/src/test/java/com/baeldung/java9/language/collections/MapFactoryMethodsUnitTest.java b/core-java-modules/core-java-9-improvements/src/test/java/com/baeldung/java9/language/collections/MapFactoryMethodsUnitTest.java similarity index 100% rename from core-java-modules/core-java-9/src/test/java/com/baeldung/java9/language/collections/MapFactoryMethodsUnitTest.java rename to core-java-modules/core-java-9-improvements/src/test/java/com/baeldung/java9/language/collections/MapFactoryMethodsUnitTest.java diff --git a/core-java-modules/core-java-9/src/test/java/com/baeldung/java9/language/collections/SetFactoryMethodsUnitTest.java b/core-java-modules/core-java-9-improvements/src/test/java/com/baeldung/java9/language/collections/SetFactoryMethodsUnitTest.java similarity index 100% rename from core-java-modules/core-java-9/src/test/java/com/baeldung/java9/language/collections/SetFactoryMethodsUnitTest.java rename to core-java-modules/core-java-9-improvements/src/test/java/com/baeldung/java9/language/collections/SetFactoryMethodsUnitTest.java diff --git a/core-java-modules/core-java-9/src/test/java/com/baeldung/java9/language/stream/CollectorImprovementUnitTest.java b/core-java-modules/core-java-9-improvements/src/test/java/com/baeldung/java9/language/stream/CollectorImprovementUnitTest.java similarity index 100% rename from core-java-modules/core-java-9/src/test/java/com/baeldung/java9/language/stream/CollectorImprovementUnitTest.java rename to core-java-modules/core-java-9-improvements/src/test/java/com/baeldung/java9/language/stream/CollectorImprovementUnitTest.java diff --git a/core-java-modules/core-java-9/src/test/java/com/baeldung/java9/language/stream/StreamFeaturesUnitTest.java b/core-java-modules/core-java-9-improvements/src/test/java/com/baeldung/java9/language/stream/StreamFeaturesUnitTest.java similarity index 100% rename from core-java-modules/core-java-9/src/test/java/com/baeldung/java9/language/stream/StreamFeaturesUnitTest.java rename to core-java-modules/core-java-9-improvements/src/test/java/com/baeldung/java9/language/stream/StreamFeaturesUnitTest.java diff --git a/core-java-modules/core-java-9-jigsaw/README.md b/core-java-modules/core-java-9-jigsaw/README.md new file mode 100644 index 0000000000..b1a401d48c --- /dev/null +++ b/core-java-modules/core-java-9-jigsaw/README.md @@ -0,0 +1,11 @@ +## Core Java 9 + +This module contains articles about Project Jigsaw and the Java Platform Module System (JPMS), introduced with Java 9. + +### Relevant Articles: + +- [Introduction to Project Jigsaw](http://www.baeldung.com/project-jigsaw-java-modularity) +- [A Guide to Java 9 Modularity](https://www.baeldung.com/java-9-modularity) +- [Java 9 java.lang.Module API](https://www.baeldung.com/java-9-module-api) + + diff --git a/core-java-modules/core-java-9/compile-simple-modules.sh b/core-java-modules/core-java-9-jigsaw/compile-simple-modules.sh similarity index 100% rename from core-java-modules/core-java-9/compile-simple-modules.sh rename to core-java-modules/core-java-9-jigsaw/compile-simple-modules.sh diff --git a/core-java-modules/core-java-9/compile-student-client.bat b/core-java-modules/core-java-9-jigsaw/compile-student-client.bat similarity index 100% rename from core-java-modules/core-java-9/compile-student-client.bat rename to core-java-modules/core-java-9-jigsaw/compile-student-client.bat diff --git a/core-java-modules/core-java-9/compile-student-model.bat b/core-java-modules/core-java-9-jigsaw/compile-student-model.bat similarity index 100% rename from core-java-modules/core-java-9/compile-student-model.bat rename to core-java-modules/core-java-9-jigsaw/compile-student-model.bat diff --git a/core-java-modules/core-java-9/compile-student-service-dbimpl.bat b/core-java-modules/core-java-9-jigsaw/compile-student-service-dbimpl.bat similarity index 100% rename from core-java-modules/core-java-9/compile-student-service-dbimpl.bat rename to core-java-modules/core-java-9-jigsaw/compile-student-service-dbimpl.bat diff --git a/core-java-modules/core-java-9/compile-student-service.bat b/core-java-modules/core-java-9-jigsaw/compile-student-service.bat similarity index 100% rename from core-java-modules/core-java-9/compile-student-service.bat rename to core-java-modules/core-java-9-jigsaw/compile-student-service.bat diff --git a/core-java-modules/core-java-9-jigsaw/pom.xml b/core-java-modules/core-java-9-jigsaw/pom.xml new file mode 100644 index 0000000000..8194ae9d00 --- /dev/null +++ b/core-java-modules/core-java-9-jigsaw/pom.xml @@ -0,0 +1,35 @@ + + 4.0.0 + core-java-9-jigsaw + 0.2-SNAPSHOT + core-java-9 + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + ../../ + + + + core-java-9-jigsaw + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + ${maven.compiler.source} + ${maven.compiler.target} + + + + + + + 1.9 + 1.9 + + + diff --git a/core-java-modules/core-java-9/run-simple-module-app.sh b/core-java-modules/core-java-9-jigsaw/run-simple-module-app.sh similarity index 100% rename from core-java-modules/core-java-9/run-simple-module-app.sh rename to core-java-modules/core-java-9-jigsaw/run-simple-module-app.sh diff --git a/core-java-modules/core-java-9/run-student-client.bat b/core-java-modules/core-java-9-jigsaw/run-student-client.bat similarity index 100% rename from core-java-modules/core-java-9/run-student-client.bat rename to core-java-modules/core-java-9-jigsaw/run-student-client.bat diff --git a/core-java-modules/core-java-9/run-student-client.sh b/core-java-modules/core-java-9-jigsaw/run-student-client.sh similarity index 100% rename from core-java-modules/core-java-9/run-student-client.sh rename to core-java-modules/core-java-9-jigsaw/run-student-client.sh diff --git a/core-java-modules/core-java-9/src/modules/com.baeldung.student.client/com/baeldung/student/client/StudentClient.java b/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.student.client/com/baeldung/student/client/StudentClient.java similarity index 100% rename from core-java-modules/core-java-9/src/modules/com.baeldung.student.client/com/baeldung/student/client/StudentClient.java rename to core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.student.client/com/baeldung/student/client/StudentClient.java diff --git a/core-java-modules/core-java-9/src/modules/com.baeldung.student.client/module-info.java b/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.student.client/module-info.java similarity index 100% rename from core-java-modules/core-java-9/src/modules/com.baeldung.student.client/module-info.java rename to core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.student.client/module-info.java diff --git a/core-java-modules/core-java-9/src/modules/com.baeldung.student.model/com/baeldung/student/model/Student.java b/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.student.model/com/baeldung/student/model/Student.java similarity index 100% rename from core-java-modules/core-java-9/src/modules/com.baeldung.student.model/com/baeldung/student/model/Student.java rename to core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.student.model/com/baeldung/student/model/Student.java diff --git a/core-java-modules/core-java-9/src/modules/com.baeldung.student.model/module-info.java b/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.student.model/module-info.java similarity index 100% rename from core-java-modules/core-java-9/src/modules/com.baeldung.student.model/module-info.java rename to core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.student.model/module-info.java diff --git a/core-java-modules/core-java-9/src/modules/com.baeldung.student.service.dbimpl/com/baeldung/student/service/dbimpl/StudentDbService.java b/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.student.service.dbimpl/com/baeldung/student/service/dbimpl/StudentDbService.java similarity index 100% rename from core-java-modules/core-java-9/src/modules/com.baeldung.student.service.dbimpl/com/baeldung/student/service/dbimpl/StudentDbService.java rename to core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.student.service.dbimpl/com/baeldung/student/service/dbimpl/StudentDbService.java diff --git a/core-java-modules/core-java-9/src/modules/com.baeldung.student.service.dbimpl/module-info.java b/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.student.service.dbimpl/module-info.java similarity index 100% rename from core-java-modules/core-java-9/src/modules/com.baeldung.student.service.dbimpl/module-info.java rename to core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.student.service.dbimpl/module-info.java diff --git a/core-java-modules/core-java-9/src/modules/com.baeldung.student.service/com/baeldung/student/service/StudentService.java b/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.student.service/com/baeldung/student/service/StudentService.java similarity index 100% rename from core-java-modules/core-java-9/src/modules/com.baeldung.student.service/com/baeldung/student/service/StudentService.java rename to core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.student.service/com/baeldung/student/service/StudentService.java diff --git a/core-java-modules/core-java-9/src/modules/com.baeldung.student.service/module-info.java b/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.student.service/module-info.java similarity index 100% rename from core-java-modules/core-java-9/src/modules/com.baeldung.student.service/module-info.java rename to core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.student.service/module-info.java diff --git a/core-java-modules/core-java-9/src/simple-modules/hello.modules/com/baeldung/modules/hello/HelloInterface.java b/core-java-modules/core-java-9-jigsaw/src/simple-modules/hello.modules/com/baeldung/modules/hello/HelloInterface.java similarity index 100% rename from core-java-modules/core-java-9/src/simple-modules/hello.modules/com/baeldung/modules/hello/HelloInterface.java rename to core-java-modules/core-java-9-jigsaw/src/simple-modules/hello.modules/com/baeldung/modules/hello/HelloInterface.java diff --git a/core-java-modules/core-java-9/src/simple-modules/hello.modules/com/baeldung/modules/hello/HelloModules.java b/core-java-modules/core-java-9-jigsaw/src/simple-modules/hello.modules/com/baeldung/modules/hello/HelloModules.java similarity index 100% rename from core-java-modules/core-java-9/src/simple-modules/hello.modules/com/baeldung/modules/hello/HelloModules.java rename to core-java-modules/core-java-9-jigsaw/src/simple-modules/hello.modules/com/baeldung/modules/hello/HelloModules.java diff --git a/core-java-modules/core-java-9/src/simple-modules/hello.modules/module-info.java b/core-java-modules/core-java-9-jigsaw/src/simple-modules/hello.modules/module-info.java similarity index 100% rename from core-java-modules/core-java-9/src/simple-modules/hello.modules/module-info.java rename to core-java-modules/core-java-9-jigsaw/src/simple-modules/hello.modules/module-info.java diff --git a/core-java-modules/core-java-9/src/simple-modules/main.app/com/baeldung/modules/main/MainApp.java b/core-java-modules/core-java-9-jigsaw/src/simple-modules/main.app/com/baeldung/modules/main/MainApp.java similarity index 100% rename from core-java-modules/core-java-9/src/simple-modules/main.app/com/baeldung/modules/main/MainApp.java rename to core-java-modules/core-java-9-jigsaw/src/simple-modules/main.app/com/baeldung/modules/main/MainApp.java diff --git a/core-java-modules/core-java-9/src/simple-modules/main.app/module-info.java b/core-java-modules/core-java-9-jigsaw/src/simple-modules/main.app/module-info.java similarity index 100% rename from core-java-modules/core-java-9/src/simple-modules/main.app/module-info.java rename to core-java-modules/core-java-9-jigsaw/src/simple-modules/main.app/module-info.java diff --git a/core-java-modules/core-java-9/src/test/java/com/baeldung/java9/modules/ModuleAPIUnitTest.java b/core-java-modules/core-java-9-jigsaw/src/test/java/com/baeldung/java9/modules/ModuleAPIUnitTest.java similarity index 100% rename from core-java-modules/core-java-9/src/test/java/com/baeldung/java9/modules/ModuleAPIUnitTest.java rename to core-java-modules/core-java-9-jigsaw/src/test/java/com/baeldung/java9/modules/ModuleAPIUnitTest.java diff --git a/core-java-modules/core-java-9-new-features/README.md b/core-java-modules/core-java-9-new-features/README.md new file mode 100644 index 0000000000..d547b9a221 --- /dev/null +++ b/core-java-modules/core-java-9-new-features/README.md @@ -0,0 +1,14 @@ +## Core Java 9 + +This module contains articles about core Java features that have been introduced in Java 9. + +### Relevant Articles: + +- [Java 9 New Features](https://www.baeldung.com/new-java-9) +- [Java 9 Variable Handles Demystified](http://www.baeldung.com/java-variable-handles) +- [Exploring the New HTTP Client in Java 9 and 11](http://www.baeldung.com/java-9-http-client) +- [Multi-Release Jar Files](https://www.baeldung.com/java-multi-release-jar) +- [Ahead of Time Compilation (AoT)](https://www.baeldung.com/ahead-of-time-compilation) +- [Introduction to Java 9 StackWalking API](https://www.baeldung.com/java-9-stackwalking-api) +- [Java 9 Platform Logging API](https://www.baeldung.com/java-9-logging-api) +- [Java 9 Reactive Streams](https://www.baeldung.com/java-9-reactive-streams) diff --git a/core-java-modules/core-java-9/compile-aot.sh b/core-java-modules/core-java-9-new-features/compile-aot.sh similarity index 100% rename from core-java-modules/core-java-9/compile-aot.sh rename to core-java-modules/core-java-9-new-features/compile-aot.sh diff --git a/core-java-modules/core-java-9/compile-httpclient.bat b/core-java-modules/core-java-9-new-features/compile-httpclient.bat similarity index 100% rename from core-java-modules/core-java-9/compile-httpclient.bat rename to core-java-modules/core-java-9-new-features/compile-httpclient.bat diff --git a/core-java-modules/core-java-9/compile-modules.sh b/core-java-modules/core-java-9-new-features/compile-modules.sh similarity index 100% rename from core-java-modules/core-java-9/compile-modules.sh rename to core-java-modules/core-java-9-new-features/compile-modules.sh diff --git a/core-java-modules/core-java-9/logging.sh b/core-java-modules/core-java-9-new-features/logging.sh similarity index 100% rename from core-java-modules/core-java-9/logging.sh rename to core-java-modules/core-java-9-new-features/logging.sh diff --git a/core-java-modules/core-java-9/mods/logback.xml b/core-java-modules/core-java-9-new-features/mods/logback.xml similarity index 100% rename from core-java-modules/core-java-9/mods/logback.xml rename to core-java-modules/core-java-9-new-features/mods/logback.xml diff --git a/core-java-modules/core-java-9-new-features/pom.xml b/core-java-modules/core-java-9-new-features/pom.xml new file mode 100644 index 0000000000..cfdbb285d4 --- /dev/null +++ b/core-java-modules/core-java-9-new-features/pom.xml @@ -0,0 +1,60 @@ + + 4.0.0 + core-java-9-new-features + 0.2-SNAPSHOT + core-java-9 + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + ../../ + + + + + org.assertj + assertj-core + ${assertj.version} + test + + + org.junit.platform + junit-platform-runner + ${junit.platform.version} + test + + + + + core-java-9-new-features + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + ${maven.compiler.source} + ${maven.compiler.target} + + + + + + + + apache.snapshots + http://repository.apache.org/snapshots/ + + + + + + 3.10.0 + 1.2.0 + 1.9 + 1.9 + + + diff --git a/core-java-modules/core-java-9/run-aot.sh b/core-java-modules/core-java-9-new-features/run-aot.sh similarity index 100% rename from core-java-modules/core-java-9/run-aot.sh rename to core-java-modules/core-java-9-new-features/run-aot.sh diff --git a/core-java-modules/core-java-9/run-httpclient.bat b/core-java-modules/core-java-9-new-features/run-httpclient.bat similarity index 100% rename from core-java-modules/core-java-9/run-httpclient.bat rename to core-java-modules/core-java-9-new-features/run-httpclient.bat diff --git a/core-java-modules/core-java-9/src/main/java/com/baeldung/java9/aot/JaotCompilation.java b/core-java-modules/core-java-9-new-features/src/main/java/com/baeldung/java9/aot/JaotCompilation.java similarity index 100% rename from core-java-modules/core-java-9/src/main/java/com/baeldung/java9/aot/JaotCompilation.java rename to core-java-modules/core-java-9-new-features/src/main/java/com/baeldung/java9/aot/JaotCompilation.java diff --git a/core-java-modules/core-java-9/src/main/java/com/baeldung/java9/language/PrivateInterface.java b/core-java-modules/core-java-9-new-features/src/main/java/com/baeldung/java9/language/PrivateInterface.java similarity index 100% rename from core-java-modules/core-java-9/src/main/java/com/baeldung/java9/language/PrivateInterface.java rename to core-java-modules/core-java-9-new-features/src/main/java/com/baeldung/java9/language/PrivateInterface.java diff --git a/core-java-modules/core-java-9/src/main/java/com/baeldung/java9/reactive/BaeldungBatchSubscriberImpl.java b/core-java-modules/core-java-9-new-features/src/main/java/com/baeldung/java9/reactive/BaeldungBatchSubscriberImpl.java similarity index 100% rename from core-java-modules/core-java-9/src/main/java/com/baeldung/java9/reactive/BaeldungBatchSubscriberImpl.java rename to core-java-modules/core-java-9-new-features/src/main/java/com/baeldung/java9/reactive/BaeldungBatchSubscriberImpl.java diff --git a/core-java-modules/core-java-9/src/main/java/com/baeldung/java9/reactive/BaeldungSubscriberImpl.java b/core-java-modules/core-java-9-new-features/src/main/java/com/baeldung/java9/reactive/BaeldungSubscriberImpl.java similarity index 100% rename from core-java-modules/core-java-9/src/main/java/com/baeldung/java9/reactive/BaeldungSubscriberImpl.java rename to core-java-modules/core-java-9-new-features/src/main/java/com/baeldung/java9/reactive/BaeldungSubscriberImpl.java diff --git a/core-java-modules/core-java-9/src/main/java/com/baeldung/java9/stackwalker/StackWalkerDemo.java b/core-java-modules/core-java-9-new-features/src/main/java/com/baeldung/java9/stackwalker/StackWalkerDemo.java similarity index 100% rename from core-java-modules/core-java-9/src/main/java/com/baeldung/java9/stackwalker/StackWalkerDemo.java rename to core-java-modules/core-java-9-new-features/src/main/java/com/baeldung/java9/stackwalker/StackWalkerDemo.java diff --git a/core-java-modules/core-java-9/src/main/java/com/baeldung/java9/streams.reactive/EndSubscriber.java b/core-java-modules/core-java-9-new-features/src/main/java/com/baeldung/java9/streams.reactive/EndSubscriber.java similarity index 100% rename from core-java-modules/core-java-9/src/main/java/com/baeldung/java9/streams.reactive/EndSubscriber.java rename to core-java-modules/core-java-9-new-features/src/main/java/com/baeldung/java9/streams.reactive/EndSubscriber.java diff --git a/core-java-modules/core-java-9/src/main/java/com/baeldung/java9/streams.reactive/TransformProcessor.java b/core-java-modules/core-java-9-new-features/src/main/java/com/baeldung/java9/streams.reactive/TransformProcessor.java similarity index 100% rename from core-java-modules/core-java-9/src/main/java/com/baeldung/java9/streams.reactive/TransformProcessor.java rename to core-java-modules/core-java-9-new-features/src/main/java/com/baeldung/java9/streams.reactive/TransformProcessor.java diff --git a/core-java-modules/core-java-9/src/main/java/com/baeldung/multireleaseapp/App.java b/core-java-modules/core-java-9-new-features/src/main/java/com/baeldung/multireleaseapp/App.java similarity index 100% rename from core-java-modules/core-java-9/src/main/java/com/baeldung/multireleaseapp/App.java rename to core-java-modules/core-java-9-new-features/src/main/java/com/baeldung/multireleaseapp/App.java diff --git a/core-java-modules/core-java-9/src/main/java/com/baeldung/multireleaseapp/DateHelper.java b/core-java-modules/core-java-9-new-features/src/main/java/com/baeldung/multireleaseapp/DateHelper.java similarity index 100% rename from core-java-modules/core-java-9/src/main/java/com/baeldung/multireleaseapp/DateHelper.java rename to core-java-modules/core-java-9-new-features/src/main/java/com/baeldung/multireleaseapp/DateHelper.java diff --git a/core-java-modules/core-java-9/src/main/java9/com/baeldung/multireleaseapp/DateHelper.java b/core-java-modules/core-java-9-new-features/src/main/java9/com/baeldung/multireleaseapp/DateHelper.java similarity index 100% rename from core-java-modules/core-java-9/src/main/java9/com/baeldung/multireleaseapp/DateHelper.java rename to core-java-modules/core-java-9-new-features/src/main/java9/com/baeldung/multireleaseapp/DateHelper.java diff --git a/core-java-modules/core-java-9/src/modules/com.baeldung.httpclient/com/baeldung/httpclient/HttpClientExample.java b/core-java-modules/core-java-9-new-features/src/modules/com.baeldung.httpclient/com/baeldung/httpclient/HttpClientExample.java similarity index 100% rename from core-java-modules/core-java-9/src/modules/com.baeldung.httpclient/com/baeldung/httpclient/HttpClientExample.java rename to core-java-modules/core-java-9-new-features/src/modules/com.baeldung.httpclient/com/baeldung/httpclient/HttpClientExample.java diff --git a/core-java-modules/core-java-9/src/modules/com.baeldung.httpclient/module-info.java b/core-java-modules/core-java-9-new-features/src/modules/com.baeldung.httpclient/module-info.java similarity index 100% rename from core-java-modules/core-java-9/src/modules/com.baeldung.httpclient/module-info.java rename to core-java-modules/core-java-9-new-features/src/modules/com.baeldung.httpclient/module-info.java diff --git a/core-java-modules/core-java-9/src/modules/com.baeldung.logging.app/com/baeldung/logging/app/MainApp.java b/core-java-modules/core-java-9-new-features/src/modules/com.baeldung.logging.app/com/baeldung/logging/app/MainApp.java similarity index 100% rename from core-java-modules/core-java-9/src/modules/com.baeldung.logging.app/com/baeldung/logging/app/MainApp.java rename to core-java-modules/core-java-9-new-features/src/modules/com.baeldung.logging.app/com/baeldung/logging/app/MainApp.java diff --git a/core-java-modules/core-java-9/src/modules/com.baeldung.logging.app/module-info.java b/core-java-modules/core-java-9-new-features/src/modules/com.baeldung.logging.app/module-info.java similarity index 100% rename from core-java-modules/core-java-9/src/modules/com.baeldung.logging.app/module-info.java rename to core-java-modules/core-java-9-new-features/src/modules/com.baeldung.logging.app/module-info.java diff --git a/core-java-modules/core-java-9/src/modules/com.baeldung.logging.slf4j/com/baeldung/logging/slf4j/Slf4jLogger.java b/core-java-modules/core-java-9-new-features/src/modules/com.baeldung.logging.slf4j/com/baeldung/logging/slf4j/Slf4jLogger.java similarity index 100% rename from core-java-modules/core-java-9/src/modules/com.baeldung.logging.slf4j/com/baeldung/logging/slf4j/Slf4jLogger.java rename to core-java-modules/core-java-9-new-features/src/modules/com.baeldung.logging.slf4j/com/baeldung/logging/slf4j/Slf4jLogger.java diff --git a/core-java-modules/core-java-9/src/modules/com.baeldung.logging.slf4j/com/baeldung/logging/slf4j/Slf4jLoggerFinder.java b/core-java-modules/core-java-9-new-features/src/modules/com.baeldung.logging.slf4j/com/baeldung/logging/slf4j/Slf4jLoggerFinder.java similarity index 100% rename from core-java-modules/core-java-9/src/modules/com.baeldung.logging.slf4j/com/baeldung/logging/slf4j/Slf4jLoggerFinder.java rename to core-java-modules/core-java-9-new-features/src/modules/com.baeldung.logging.slf4j/com/baeldung/logging/slf4j/Slf4jLoggerFinder.java diff --git a/core-java-modules/core-java-9/src/modules/com.baeldung.logging.slf4j/module-info.java b/core-java-modules/core-java-9-new-features/src/modules/com.baeldung.logging.slf4j/module-info.java similarity index 100% rename from core-java-modules/core-java-9/src/modules/com.baeldung.logging.slf4j/module-info.java rename to core-java-modules/core-java-9-new-features/src/modules/com.baeldung.logging.slf4j/module-info.java diff --git a/core-java-modules/core-java-9/src/modules/com.baeldung.logging/com/baeldung/logging/ConsoleLogger.java b/core-java-modules/core-java-9-new-features/src/modules/com.baeldung.logging/com/baeldung/logging/ConsoleLogger.java similarity index 100% rename from core-java-modules/core-java-9/src/modules/com.baeldung.logging/com/baeldung/logging/ConsoleLogger.java rename to core-java-modules/core-java-9-new-features/src/modules/com.baeldung.logging/com/baeldung/logging/ConsoleLogger.java diff --git a/core-java-modules/core-java-9/src/modules/com.baeldung.logging/com/baeldung/logging/CustomLoggerFinder.java b/core-java-modules/core-java-9-new-features/src/modules/com.baeldung.logging/com/baeldung/logging/CustomLoggerFinder.java similarity index 100% rename from core-java-modules/core-java-9/src/modules/com.baeldung.logging/com/baeldung/logging/CustomLoggerFinder.java rename to core-java-modules/core-java-9-new-features/src/modules/com.baeldung.logging/com/baeldung/logging/CustomLoggerFinder.java diff --git a/core-java-modules/core-java-9/src/modules/com.baeldung.logging/module-info.java b/core-java-modules/core-java-9-new-features/src/modules/com.baeldung.logging/module-info.java similarity index 100% rename from core-java-modules/core-java-9/src/modules/com.baeldung.logging/module-info.java rename to core-java-modules/core-java-9-new-features/src/modules/com.baeldung.logging/module-info.java diff --git a/core-java-modules/core-java-9/src/test/java/com/baeldung/java9/MultiResultionImageUnitTest.java b/core-java-modules/core-java-9-new-features/src/test/java/com/baeldung/java9/MultiResultionImageUnitTest.java similarity index 100% rename from core-java-modules/core-java-9/src/test/java/com/baeldung/java9/MultiResultionImageUnitTest.java rename to core-java-modules/core-java-9-new-features/src/test/java/com/baeldung/java9/MultiResultionImageUnitTest.java diff --git a/core-java-modules/core-java-9/src/test/java/com/baeldung/java9/OptionalToStreamUnitTest.java b/core-java-modules/core-java-9-new-features/src/test/java/com/baeldung/java9/OptionalToStreamUnitTest.java similarity index 100% rename from core-java-modules/core-java-9/src/test/java/com/baeldung/java9/OptionalToStreamUnitTest.java rename to core-java-modules/core-java-9-new-features/src/test/java/com/baeldung/java9/OptionalToStreamUnitTest.java diff --git a/core-java-modules/core-java-9/src/test/java/com/baeldung/java9/httpclient/HttpClientTest.java b/core-java-modules/core-java-9-new-features/src/test/java/com/baeldung/java9/httpclient/HttpClientTest.java similarity index 100% rename from core-java-modules/core-java-9/src/test/java/com/baeldung/java9/httpclient/HttpClientTest.java rename to core-java-modules/core-java-9-new-features/src/test/java/com/baeldung/java9/httpclient/HttpClientTest.java diff --git a/core-java-modules/core-java-9/src/test/java/com/baeldung/java9/httpclient/HttpRequestTest.java b/core-java-modules/core-java-9-new-features/src/test/java/com/baeldung/java9/httpclient/HttpRequestTest.java similarity index 100% rename from core-java-modules/core-java-9/src/test/java/com/baeldung/java9/httpclient/HttpRequestTest.java rename to core-java-modules/core-java-9-new-features/src/test/java/com/baeldung/java9/httpclient/HttpRequestTest.java diff --git a/core-java-modules/core-java-9/src/test/java/com/baeldung/java9/httpclient/HttpResponseTest.java b/core-java-modules/core-java-9-new-features/src/test/java/com/baeldung/java9/httpclient/HttpResponseTest.java similarity index 100% rename from core-java-modules/core-java-9/src/test/java/com/baeldung/java9/httpclient/HttpResponseTest.java rename to core-java-modules/core-java-9-new-features/src/test/java/com/baeldung/java9/httpclient/HttpResponseTest.java diff --git a/core-java-modules/core-java-9/src/test/java/com/baeldung/java9/language/DiamondUnitTest.java b/core-java-modules/core-java-9-new-features/src/test/java/com/baeldung/java9/language/DiamondUnitTest.java similarity index 100% rename from core-java-modules/core-java-9/src/test/java/com/baeldung/java9/language/DiamondUnitTest.java rename to core-java-modules/core-java-9-new-features/src/test/java/com/baeldung/java9/language/DiamondUnitTest.java diff --git a/core-java-modules/core-java-9/src/test/java/com/baeldung/java9/language/PrivateInterfaceUnitTest.java b/core-java-modules/core-java-9-new-features/src/test/java/com/baeldung/java9/language/PrivateInterfaceUnitTest.java similarity index 100% rename from core-java-modules/core-java-9/src/test/java/com/baeldung/java9/language/PrivateInterfaceUnitTest.java rename to core-java-modules/core-java-9-new-features/src/test/java/com/baeldung/java9/language/PrivateInterfaceUnitTest.java diff --git a/core-java-modules/core-java-9/src/test/java/com/baeldung/java9/language/TryWithResourcesUnitTest.java b/core-java-modules/core-java-9-new-features/src/test/java/com/baeldung/java9/language/TryWithResourcesUnitTest.java similarity index 100% rename from core-java-modules/core-java-9/src/test/java/com/baeldung/java9/language/TryWithResourcesUnitTest.java rename to core-java-modules/core-java-9-new-features/src/test/java/com/baeldung/java9/language/TryWithResourcesUnitTest.java diff --git a/core-java-modules/core-java-9/src/test/java/com/baeldung/java9/reactive/BaeldungBatchSubscriberImplIntegrationTest.java b/core-java-modules/core-java-9-new-features/src/test/java/com/baeldung/java9/reactive/BaeldungBatchSubscriberImplIntegrationTest.java similarity index 100% rename from core-java-modules/core-java-9/src/test/java/com/baeldung/java9/reactive/BaeldungBatchSubscriberImplIntegrationTest.java rename to core-java-modules/core-java-9-new-features/src/test/java/com/baeldung/java9/reactive/BaeldungBatchSubscriberImplIntegrationTest.java diff --git a/core-java-modules/core-java-9/src/test/java/com/baeldung/java9/reactive/BaeldungSubscriberImplIntegrationTest.java b/core-java-modules/core-java-9-new-features/src/test/java/com/baeldung/java9/reactive/BaeldungSubscriberImplIntegrationTest.java similarity index 100% rename from core-java-modules/core-java-9/src/test/java/com/baeldung/java9/reactive/BaeldungSubscriberImplIntegrationTest.java rename to core-java-modules/core-java-9-new-features/src/test/java/com/baeldung/java9/reactive/BaeldungSubscriberImplIntegrationTest.java diff --git a/core-java-modules/core-java-9/src/test/java/com/baeldung/java9/stackwalker/StackWalkerDemoUnitTest.java b/core-java-modules/core-java-9-new-features/src/test/java/com/baeldung/java9/stackwalker/StackWalkerDemoUnitTest.java similarity index 100% rename from core-java-modules/core-java-9/src/test/java/com/baeldung/java9/stackwalker/StackWalkerDemoUnitTest.java rename to core-java-modules/core-java-9-new-features/src/test/java/com/baeldung/java9/stackwalker/StackWalkerDemoUnitTest.java diff --git a/core-java-modules/core-java-9/src/test/java/com/baeldung/java9/streams.reactive/ReactiveStreamsTest.java b/core-java-modules/core-java-9-new-features/src/test/java/com/baeldung/java9/streams.reactive/ReactiveStreamsTest.java similarity index 100% rename from core-java-modules/core-java-9/src/test/java/com/baeldung/java9/streams.reactive/ReactiveStreamsTest.java rename to core-java-modules/core-java-9-new-features/src/test/java/com/baeldung/java9/streams.reactive/ReactiveStreamsTest.java diff --git a/core-java-modules/core-java-9/src/test/java/com/baeldung/java9/varhandles/VariableHandlesTest.java b/core-java-modules/core-java-9-new-features/src/test/java/com/baeldung/java9/varhandles/VariableHandlesTest.java similarity index 100% rename from core-java-modules/core-java-9/src/test/java/com/baeldung/java9/varhandles/VariableHandlesTest.java rename to core-java-modules/core-java-9-new-features/src/test/java/com/baeldung/java9/varhandles/VariableHandlesTest.java diff --git a/core-java-modules/core-java-9/.gitignore b/core-java-modules/core-java-9/.gitignore deleted file mode 100644 index 83c05e60c8..0000000000 --- a/core-java-modules/core-java-9/.gitignore +++ /dev/null @@ -1,13 +0,0 @@ -*.class - -#folders# -/target -/neoDb* -/data -/src/main/webapp/WEB-INF/classes -*/META-INF/* - -# Packaged files # -*.jar -*.war -*.ear \ No newline at end of file diff --git a/core-java-modules/core-java-9/README.md b/core-java-modules/core-java-9/README.md index f4939ae1e1..94f480db67 100644 --- a/core-java-modules/core-java-9/README.md +++ b/core-java-modules/core-java-9/README.md @@ -4,28 +4,13 @@ This module contains articles about Java 9 core features ### Relevant Articles: -- [Java 9 New Features](https://www.baeldung.com/new-java-9) -- [New Stream Collectors in Java 9](http://www.baeldung.com/java9-stream-collectors) -- [Introduction to Project Jigsaw](http://www.baeldung.com/project-jigsaw-java-modularity) -- [Java 9 Variable Handles Demystified](http://www.baeldung.com/java-variable-handles) -- [Exploring the New HTTP Client in Java 9 and 11](http://www.baeldung.com/java-9-http-client) - [Method Handles in Java](http://www.baeldung.com/java-method-handles) - [Introduction to Chronicle Queue](http://www.baeldung.com/java-chronicle-queue) - [Optional orElse Optional](http://www.baeldung.com/java-optional-or-else-optional) - [Iterate Through a Range of Dates in Java](https://www.baeldung.com/java-iterate-date-range) - [Initialize a HashMap in Java](https://www.baeldung.com/java-initialize-hashmap) - [Immutable Set in Java](https://www.baeldung.com/java-immutable-set) -- [Multi-Release Jar Files](https://www.baeldung.com/java-multi-release-jar) -- [Ahead of Time Compilation (AoT)](https://www.baeldung.com/ahead-of-time-compilation) -- [Java 9 Process API Improvements](https://www.baeldung.com/java-9-process-api) -- [Java 9 java.util.Objects Additions](https://www.baeldung.com/java-9-objects-new) -- [Java 9 Reactive Streams](https://www.baeldung.com/java-9-reactive-streams) -- [Java 9 Optional API Additions](https://www.baeldung.com/java-9-optional) -- [Java 9 CompletableFuture API Improvements](https://www.baeldung.com/java-9-completablefuture) -- [Introduction to Java 9 StackWalking API](https://www.baeldung.com/java-9-stackwalking-api) -- [Java 9 Convenience Factory Methods for Collections](https://www.baeldung.com/java-9-collections-factory-methods) -- [Java 9 Stream API Improvements](https://www.baeldung.com/java-9-stream-api) -- [A Guide to Java 9 Modularity](https://www.baeldung.com/java-9-modularity) -- [Java 9 java.lang.Module API](https://www.baeldung.com/java-9-module-api) -- [Java 9 Platform Logging API](https://www.baeldung.com/java-9-logging-api) - [Filtering a Stream of Optionals in Java](https://www.baeldung.com/java-filter-stream-of-optional) + +Note: also contains part of the code for the article +[How to Filter a Collection in Java](https://www.baeldung.com/java-collection-filtering). diff --git a/core-java-modules/core-java-9/src/main/java/.gitignore b/core-java-modules/core-java-9/src/main/java/.gitignore deleted file mode 100644 index 83c05e60c8..0000000000 --- a/core-java-modules/core-java-9/src/main/java/.gitignore +++ /dev/null @@ -1,13 +0,0 @@ -*.class - -#folders# -/target -/neoDb* -/data -/src/main/webapp/WEB-INF/classes -*/META-INF/* - -# Packaged files # -*.jar -*.war -*.ear \ No newline at end of file diff --git a/core-java-modules/core-java-9/src/test/java/com/baeldung/java9/README.MD b/core-java-modules/core-java-9/src/test/java/com/baeldung/java9/README.MD deleted file mode 100644 index 2f44a2336b..0000000000 --- a/core-java-modules/core-java-9/src/test/java/com/baeldung/java9/README.MD +++ /dev/null @@ -1,2 +0,0 @@ -### Relevant Artiles: -- [Filtering a Stream of Optionals in Java](http://www.baeldung.com/java-filter-stream-of-optional) diff --git a/core-java-modules/core-java-arrays-2/README.md b/core-java-modules/core-java-arrays-2/README.md index 5fa2f2bf4c..a78b3327b6 100644 --- a/core-java-modules/core-java-arrays-2/README.md +++ b/core-java-modules/core-java-arrays-2/README.md @@ -12,4 +12,5 @@ This module contains articles about Java arrays - [Intersection Between two Integer Arrays](https://www.baeldung.com/java-array-intersection) - [Removing an Element from an Array in Java](https://www.baeldung.com/java-array-remove-element) - [Removing the First Element of an Array](https://www.baeldung.com/java-array-remove-first-element) +- [Adding an Element to a Java Array vs an ArrayList](https://www.baeldung.com/java-add-element-to-array-vs-list) - [[<-- Prev]](/core-java-modules/core-java-arrays) diff --git a/core-java-modules/core-java-collections-list-3/src/main/java/com/baeldung/list/DuplicatesCounter.java b/core-java-modules/core-java-collections-list-3/src/main/java/com/baeldung/list/duplicatescounter/DuplicatesCounter.java similarity index 96% rename from core-java-modules/core-java-collections-list-3/src/main/java/com/baeldung/list/DuplicatesCounter.java rename to core-java-modules/core-java-collections-list-3/src/main/java/com/baeldung/list/duplicatescounter/DuplicatesCounter.java index 04e24e5fa1..b5138eed7d 100644 --- a/core-java-modules/core-java-collections-list-3/src/main/java/com/baeldung/list/DuplicatesCounter.java +++ b/core-java-modules/core-java-collections-list-3/src/main/java/com/baeldung/list/duplicatescounter/DuplicatesCounter.java @@ -1,4 +1,4 @@ -package com.baeldung.list; +package com.baeldung.list.duplicatescounter; import java.util.HashMap; import java.util.List; diff --git a/core-java-modules/core-java-collections-list-3/src/test/java/com/baeldung/collection/filtering/CollectionFilteringUnitTest.java b/core-java-modules/core-java-collections-list-3/src/test/java/com/baeldung/collection/filtering/CollectionFilteringUnitTest.java index cbc7136192..d41c12cd23 100644 --- a/core-java-modules/core-java-collections-list-3/src/test/java/com/baeldung/collection/filtering/CollectionFilteringUnitTest.java +++ b/core-java-modules/core-java-collections-list-3/src/test/java/com/baeldung/collection/filtering/CollectionFilteringUnitTest.java @@ -33,9 +33,9 @@ public class CollectionFilteringUnitTest { for (Employee employee : originalList) { for (String name : nameFilter) { - if (employee.getName() - .equalsIgnoreCase(name)) { + if (employee.getName().equals(name)) { filteredList.add(employee); + //break; } } } diff --git a/core-java-modules/core-java-collections-list-3/src/test/java/com/baeldung/list/DuplicatesCounterUnitTest.java b/core-java-modules/core-java-collections-list-3/src/test/java/com/baeldung/list/duplicatescounter/DuplicatesCounterUnitTest.java similarity index 97% rename from core-java-modules/core-java-collections-list-3/src/test/java/com/baeldung/list/DuplicatesCounterUnitTest.java rename to core-java-modules/core-java-collections-list-3/src/test/java/com/baeldung/list/duplicatescounter/DuplicatesCounterUnitTest.java index 4b6a03aaef..be9ccded9b 100644 --- a/core-java-modules/core-java-collections-list-3/src/test/java/com/baeldung/list/DuplicatesCounterUnitTest.java +++ b/core-java-modules/core-java-collections-list-3/src/test/java/com/baeldung/list/duplicatescounter/DuplicatesCounterUnitTest.java @@ -1,4 +1,4 @@ -package com.baeldung.list; +package com.baeldung.list.duplicatescounter; import org.assertj.core.util.Lists; import org.junit.jupiter.api.Test; diff --git a/core-java-modules/core-java-date-operations/pom.xml b/core-java-modules/core-java-date-operations/pom.xml new file mode 100644 index 0000000000..f6e75ca518 --- /dev/null +++ b/core-java-modules/core-java-date-operations/pom.xml @@ -0,0 +1,17 @@ + + + 4.0.0 + core-java-date-operations + ${project.parent.version} + jar + + + com.baeldung + parent-java + 0.0.1-SNAPSHOT + ../../parent-java + + + \ No newline at end of file diff --git a/core-java-modules/core-java-date-operations/src/main/java/com/baeldung/datetime/CalendarUtils.java b/core-java-modules/core-java-date-operations/src/main/java/com/baeldung/datetime/CalendarUtils.java new file mode 100644 index 0000000000..ab1550fd90 --- /dev/null +++ b/core-java-modules/core-java-date-operations/src/main/java/com/baeldung/datetime/CalendarUtils.java @@ -0,0 +1,15 @@ +package com.baeldung.datetime; + +import java.text.ParseException; +import java.util.Calendar; +import java.util.Date; + +public class CalendarUtils { + + public static Calendar getPlusDays(Date date, int amount) throws ParseException { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + calendar.add(Calendar.DAY_OF_YEAR, amount); + return calendar; + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-date-operations/src/main/java/com/baeldung/datetime/DateUtils.java b/core-java-modules/core-java-date-operations/src/main/java/com/baeldung/datetime/DateUtils.java new file mode 100644 index 0000000000..34f799d3f4 --- /dev/null +++ b/core-java-modules/core-java-date-operations/src/main/java/com/baeldung/datetime/DateUtils.java @@ -0,0 +1,20 @@ +package com.baeldung.datetime; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; + +public class DateUtils { + + public static Date getNow() { + return new Date(); + } + + public static Date getDate(long millis) { + return new Date(millis); + } + + public static Date getDate(String dateAsString, String pattern) throws ParseException { + return new SimpleDateFormat(pattern).parse(dateAsString); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-date-operations/src/main/java/com/baeldung/datetime/sql/DateUtils.java b/core-java-modules/core-java-date-operations/src/main/java/com/baeldung/datetime/sql/DateUtils.java new file mode 100644 index 0000000000..1b4e825df8 --- /dev/null +++ b/core-java-modules/core-java-date-operations/src/main/java/com/baeldung/datetime/sql/DateUtils.java @@ -0,0 +1,21 @@ +package com.baeldung.datetime.sql; + +import java.sql.Date; +import java.text.ParseException; +import java.text.SimpleDateFormat; + +public class DateUtils { + + public static Date getNow() { + return new Date(System.currentTimeMillis()); + } + + public static Date getDate(String dateAsString) { + return Date.valueOf(dateAsString); + } + + public static Date getDate(String dateAsString, String pattern) throws ParseException { + java.util.Date customUtilDate = new SimpleDateFormat(pattern).parse(dateAsString); + return new Date(customUtilDate.getTime()); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-date-operations/src/main/java/com/baeldung/datetime/sql/TimeUtils.java b/core-java-modules/core-java-date-operations/src/main/java/com/baeldung/datetime/sql/TimeUtils.java new file mode 100644 index 0000000000..3fa1ffdef8 --- /dev/null +++ b/core-java-modules/core-java-date-operations/src/main/java/com/baeldung/datetime/sql/TimeUtils.java @@ -0,0 +1,21 @@ +package com.baeldung.datetime.sql; + +import java.sql.Time; +import java.text.ParseException; +import java.text.SimpleDateFormat; + +public class TimeUtils { + + public static Time getNow() { + return new Time(System.currentTimeMillis()); + } + + public static Time getTime(String timeAsString) { + return Time.valueOf(timeAsString); + } + + public static Time getTime(String dateAsString, String pattern) throws ParseException { + java.util.Date customUtilDate = new SimpleDateFormat(pattern).parse(dateAsString); + return new Time(customUtilDate.getTime()); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-date-operations/src/main/java/com/baeldung/datetime/sql/TimestampUtils.java b/core-java-modules/core-java-date-operations/src/main/java/com/baeldung/datetime/sql/TimestampUtils.java new file mode 100644 index 0000000000..02a928daa7 --- /dev/null +++ b/core-java-modules/core-java-date-operations/src/main/java/com/baeldung/datetime/sql/TimestampUtils.java @@ -0,0 +1,21 @@ +package com.baeldung.datetime.sql; + +import java.sql.Timestamp; +import java.text.ParseException; +import java.text.SimpleDateFormat; + +public class TimestampUtils { + + public static Timestamp getNow() { + return new Timestamp(System.currentTimeMillis()); + } + + public static Timestamp getTimestamp(String timestampAsString) { + return Timestamp.valueOf(timestampAsString); + } + + public static Timestamp getTimestamp(String dateAsString, String pattern) throws ParseException { + java.util.Date customUtilDate = new SimpleDateFormat(pattern).parse(dateAsString); + return new Timestamp(customUtilDate.getTime()); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-date-operations/src/test/java/com/baeldung/datetime/CalendarUtilsUnitTest.java b/core-java-modules/core-java-date-operations/src/test/java/com/baeldung/datetime/CalendarUtilsUnitTest.java new file mode 100644 index 0000000000..0060162ffb --- /dev/null +++ b/core-java-modules/core-java-date-operations/src/test/java/com/baeldung/datetime/CalendarUtilsUnitTest.java @@ -0,0 +1,21 @@ +package com.baeldung.datetime; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import com.baeldung.datetime.CalendarUtils; +import com.baeldung.datetime.DateUtils; + +import java.text.ParseException; +import java.util.Date; + +public class CalendarUtilsUnitTest { + + @Test + public void givenDateAndDaysToAdd_thenCalendarIsCorrectlyReturned() throws ParseException { + Date initialDate = DateUtils.getDate("2020/01/01", "yyyy/MM/dd"); + Date expectedDate= DateUtils.getDate("2020/01/11", "yyyy/MM/dd"); + assertEquals(expectedDate, CalendarUtils.getPlusDays(initialDate, 10).getTime()); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-date-operations/src/test/java/com/baeldung/datetime/DateUtilsUnitTest.java b/core-java-modules/core-java-date-operations/src/test/java/com/baeldung/datetime/DateUtilsUnitTest.java new file mode 100644 index 0000000000..62a0fc0b4b --- /dev/null +++ b/core-java-modules/core-java-date-operations/src/test/java/com/baeldung/datetime/DateUtilsUnitTest.java @@ -0,0 +1,25 @@ +package com.baeldung.datetime; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import com.baeldung.datetime.DateUtils; + +import java.text.ParseException; +import java.util.Date; + +public class DateUtilsUnitTest { + + @Test + public void givenTimeMillis_thenDateIsReturned() { + Date now = DateUtils.getNow(); + assertEquals(DateUtils.getDate(now.getTime()), now); + } + + @Test + public void givenDateAndPattern_thenDateIsCorrectlyReturned() throws ParseException { + long milliseconds = new Date(2020 - 1900, 0, 1).getTime(); + assertEquals(DateUtils.getDate(milliseconds), DateUtils.getDate("2020/01/01", "yyyy/MM/dd")); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-date-operations/src/test/java/com/baeldung/datetime/sql/DateUtilsUnitTest.java b/core-java-modules/core-java-date-operations/src/test/java/com/baeldung/datetime/sql/DateUtilsUnitTest.java new file mode 100644 index 0000000000..a04f64f6dd --- /dev/null +++ b/core-java-modules/core-java-date-operations/src/test/java/com/baeldung/datetime/sql/DateUtilsUnitTest.java @@ -0,0 +1,28 @@ +package com.baeldung.datetime.sql; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import com.baeldung.datetime.sql.DateUtils; + +import java.text.ParseException; +import java.util.Date; + +public class DateUtilsUnitTest { + + @Test + public void givenCurrentDate_thenTodayIsReturned() { + assertEquals(DateUtils.getNow(), new Date()); + } + + @Test(expected = IllegalArgumentException.class) + public void givenDateAsString_whenPatternIsNotRespected_thenExceptionIsThrown() { + DateUtils.getDate("2020 01 01"); + } + + @Test + public void givenDateAndPattern_thenDateIsCorrectlyReturned() throws ParseException { + assertEquals(DateUtils.getDate("2020-01-01"), DateUtils.getDate("2020/01/01", "yyyy/MM/dd")); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-date-operations/src/test/java/com/baeldung/datetime/sql/TimeUtilsUnitTest.java b/core-java-modules/core-java-date-operations/src/test/java/com/baeldung/datetime/sql/TimeUtilsUnitTest.java new file mode 100644 index 0000000000..6b49558f1b --- /dev/null +++ b/core-java-modules/core-java-date-operations/src/test/java/com/baeldung/datetime/sql/TimeUtilsUnitTest.java @@ -0,0 +1,28 @@ +package com.baeldung.datetime.sql; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import com.baeldung.datetime.sql.TimeUtils; + +import java.text.ParseException; +import java.util.Date; + +public class TimeUtilsUnitTest { + + @Test + public void givenCurrentTime_thenNowIsReturned() { + assertEquals(TimeUtils.getNow(), new Date()); + } + + @Test(expected = IllegalArgumentException.class) + public void givenTimeAsString_whenPatternIsNotRespected_thenExceptionIsThrown() { + TimeUtils.getTime("10 11 12"); + } + + @Test + public void givenTimeAndPattern_thenTimeIsCorrectlyReturned() throws ParseException { + assertEquals(TimeUtils.getTime("10:11:12"), TimeUtils.getTime("10 11 12", "hh mm ss")); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-date-operations/src/test/java/com/baeldung/datetime/sql/TimestampUtilsUnitTest.java b/core-java-modules/core-java-date-operations/src/test/java/com/baeldung/datetime/sql/TimestampUtilsUnitTest.java new file mode 100644 index 0000000000..2faf8fab0e --- /dev/null +++ b/core-java-modules/core-java-date-operations/src/test/java/com/baeldung/datetime/sql/TimestampUtilsUnitTest.java @@ -0,0 +1,29 @@ +package com.baeldung.datetime.sql; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import com.baeldung.datetime.sql.TimestampUtils; + +import java.text.ParseException; +import java.util.Date; + +public class TimestampUtilsUnitTest { + + @Test + public void givenCurrentTimestamp_thenNowIsReturned() { + assertEquals(TimestampUtils.getNow() + .getTime(), new Date().getTime()); + } + + @Test(expected = IllegalArgumentException.class) + public void givenTimestampAsString_whenPatternIsNotRespected_thenExceptionIsThrown() { + TimestampUtils.getTimestamp("2020/01/01 10:11-12"); + } + + @Test + public void givenTimestampAndPattern_thenTimestampIsCorrectlyReturned() throws ParseException { + assertEquals(TimestampUtils.getTimestamp("2020-01-01 10:11:12"), TimestampUtils.getTimestamp("2020/01/01 10:11-12", "yyyy/MM/dd hh:mm-ss")); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-exceptions/src/main/java/com/baeldung/trywithresource/AutoCloseableMain.java b/core-java-modules/core-java-exceptions/src/main/java/com/baeldung/trywithresource/AutoCloseableMain.java new file mode 100644 index 0000000000..fee52fe2bc --- /dev/null +++ b/core-java-modules/core-java-exceptions/src/main/java/com/baeldung/trywithresource/AutoCloseableMain.java @@ -0,0 +1,16 @@ +package com.baeldung.trywithresource; + +public class AutoCloseableMain { + + public static void main(String[] args) throws Exception { + orderOfClosingResources(); + } + + private static void orderOfClosingResources() throws Exception { + try (AutoCloseableResourcesFirst af = new AutoCloseableResourcesFirst(); + AutoCloseableResourcesSecond as = new AutoCloseableResourcesSecond()) { + af.doSomething(); + as.doSomething(); + } + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-exceptions/src/main/java/com/baeldung/trywithresource/AutoCloseableResourcesFirst.java b/core-java-modules/core-java-exceptions/src/main/java/com/baeldung/trywithresource/AutoCloseableResourcesFirst.java new file mode 100644 index 0000000000..b001244d93 --- /dev/null +++ b/core-java-modules/core-java-exceptions/src/main/java/com/baeldung/trywithresource/AutoCloseableResourcesFirst.java @@ -0,0 +1,17 @@ +package com.baeldung.trywithresource; + +public class AutoCloseableResourcesFirst implements AutoCloseable { + + public AutoCloseableResourcesFirst() { + System.out.println("Constructor -> AutoCloseableResources_First"); + } + + public void doSomething() { + System.out.println("Something -> AutoCloseableResources_First"); + } + + @Override + public void close() throws Exception { + System.out.println("Closed AutoCloseableResources_First"); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-exceptions/src/main/java/com/baeldung/trywithresource/AutoCloseableResourcesSecond.java b/core-java-modules/core-java-exceptions/src/main/java/com/baeldung/trywithresource/AutoCloseableResourcesSecond.java new file mode 100644 index 0000000000..ef8bcd7166 --- /dev/null +++ b/core-java-modules/core-java-exceptions/src/main/java/com/baeldung/trywithresource/AutoCloseableResourcesSecond.java @@ -0,0 +1,17 @@ +package com.baeldung.trywithresource; + +public class AutoCloseableResourcesSecond implements AutoCloseable { + + public AutoCloseableResourcesSecond() { + System.out.println("Constructor -> AutoCloseableResources_Second"); + } + + public void doSomething() { + System.out.println("Something -> AutoCloseableResources_Second"); + } + + @Override + public void close() throws Exception { + System.out.println("Closed AutoCloseableResources_Second"); + } +} diff --git a/core-java-modules/core-java-exceptions/src/main/java/com/baeldung/trywithresource/MyResource.java b/core-java-modules/core-java-exceptions/src/main/java/com/baeldung/trywithresource/MyResource.java new file mode 100644 index 0000000000..3ddf0f52e0 --- /dev/null +++ b/core-java-modules/core-java-exceptions/src/main/java/com/baeldung/trywithresource/MyResource.java @@ -0,0 +1,8 @@ +package com.baeldung.trywithresource; + +public class MyResource implements AutoCloseable { + @Override + public void close() throws Exception { + System.out.println("Closed MyResource"); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-io-2/src/test/java/com/baeldung/file/FileClassDemoUnitTest.java b/core-java-modules/core-java-io-2/src/test/java/com/baeldung/file/FileClassDemoUnitTest.java index b60a12d208..322060fed8 100644 --- a/core-java-modules/core-java-io-2/src/test/java/com/baeldung/file/FileClassDemoUnitTest.java +++ b/core-java-modules/core-java-io-2/src/test/java/com/baeldung/file/FileClassDemoUnitTest.java @@ -11,148 +11,171 @@ import static org.junit.Assert.*; public class FileClassDemoUnitTest { @Test - public void givenDirectoryCreated_whenMkdirIsInvoked_thenDirectoryIsDeleted() { - File directory = new File("testDirectory"); - if (!directory.isDirectory() || !directory.exists()) { - directory.mkdir(); - } - + public void givenDir_whenMkdir_thenDirIsDeleted() { + File directory = new File("dir"); + assertTrue(directory.mkdir()); assertTrue(directory.delete()); } @Test - public void givenFileCreated_whenCreateNewFileIsInvoked_thenFileIsDeleted() throws IOException { - File file = new File("testFile.txt"); - if (!file.isFile() || !file.exists()) { - file.createNewFile(); + public void givenFile_whenCreateNewFile_thenFileIsDeleted() { + File file = new File("file.txt"); + try { + assertTrue(file.createNewFile()); + } catch (IOException e) { + fail("Could not create " + "file.txt"); } - assertTrue(file.delete()); } + @Test + public void givenFile_whenCreateNewFile_thenMetadataIsCorrect() { + + String sep = File.separator; + + File parentDir = makeDir("filesDir"); + + File child = new File(parentDir, "file.txt"); + try { + child.createNewFile(); + } catch (IOException e) { + fail("Could not create " + "file.txt"); + } + + assertEquals("file.txt", child.getName()); + assertEquals(parentDir.getName(), child.getParentFile().getName()); + assertEquals(parentDir.getPath() + sep + "file.txt", child.getPath()); + + removeDir(parentDir); + } + @Test - public void givenFileCreated_whenCreateNewFileInvoked_thenMetadataIsAsExpected() throws IOException { + public void givenReadOnlyFile_whenCreateNewFile_thenCantModFile() { + File parentDir = makeDir("readDir"); - // different Operating systems have different separator characters - String separatorCharacter = System.getProperty("file.separator"); - - File parentDirectory = makeDirectory("filesDirectory"); - - File childFile = new File(parentDirectory, "file1.txt"); - childFile.createNewFile(); - - assertTrue(childFile.getName().equals("file1.txt")); - assertTrue(childFile.getParentFile().getName().equals(parentDirectory.getName())); - assertTrue(childFile.getPath().equals(parentDirectory.getPath() + separatorCharacter + "file1.txt")); - - removeDirectory(parentDirectory); - } - - - @Test(expected = FileNotFoundException.class) - public void givenReadOnlyFileCreated_whenCreateNewFileInvoked_thenFileCannotBeWrittenTo() throws IOException { - File parentDirectory = makeDirectory("filesDirectory"); - - File childFile = new File(parentDirectory, "file1.txt"); - childFile.createNewFile(); - - childFile.setWritable(false); - - FileOutputStream fos = new FileOutputStream(childFile); - fos.write("Hello World".getBytes()); // write operation - fos.flush(); - fos.close(); - - removeDirectory(parentDirectory); - } - - @Test(expected = FileNotFoundException.class) - public void givenWriteOnlyFileCreated_whenCreateNewFileInvoked_thenFileCannotBeReadFrom() throws IOException { - File parentDirectory = makeDirectory("filesDirectory"); - - File childFile = new File(parentDirectory, "file1.txt"); - childFile.createNewFile(); - - childFile.setReadable(false); - - FileInputStream fis = new FileInputStream(childFile); - fis.read(); // read operation - fis.close(); - - removeDirectory(parentDirectory); + File child = new File(parentDir, "file.txt"); + try { + child.createNewFile(); + } catch (IOException e) { + fail("Could not create " + "file.txt"); + } + child.setWritable(false); + boolean writable = true; + try (FileOutputStream fos = new FileOutputStream(child)) { + fos.write("Hello World".getBytes()); // write operation + fos.flush(); + } catch (IOException e) { + writable = false; + } finally { + removeDir(parentDir); + } + assertFalse(writable); } @Test - public void givenFilesCreatedInDirectory_whenCreateNewFileInvoked_thenTheyCanBeListedAsExpected() throws IOException { - File directory = makeDirectory("filtersDirectory"); + public void givenWriteOnlyFile_whenCreateNewFile_thenCantReadFile() { + File parentDir = makeDir("writeDir"); - File csvFile = new File(directory, "csvFile.csv"); - csvFile.createNewFile(); + File child = new File(parentDir, "file.txt"); + try { + child.createNewFile(); + } catch (IOException e) { + fail("Could not create " + "file.txt"); + } + child.setReadable(false); + boolean readable = true; + try (FileInputStream fis = new FileInputStream(child)) { + fis.read(); // read operation + } catch (IOException e) { + readable = false; + } finally { + removeDir(parentDir); + } + assertFalse(readable); + } - File txtFile = new File(directory, "txtFile.txt"); - txtFile.createNewFile(); + @Test + public void givenFilesInDir_whenCreateNewFile_thenCanListFiles() { + File parentDir = makeDir("filtersDir"); + + String[] files = {"file1.csv", "file2.txt"}; + for (String file : files) { + try { + new File(parentDir, file).createNewFile(); + } catch (IOException e) { + fail("Could not create " + file); + } + } //normal listing - assertEquals(2, directory.list().length); + assertEquals(2, parentDir.list().length); //filtered listing FilenameFilter csvFilter = (dir, ext) -> ext.endsWith(".csv"); - assertEquals(1, directory.list(csvFilter).length); + assertEquals(1, parentDir.list(csvFilter).length); - removeDirectory(directory); + removeDir(parentDir); } @Test - public void givenDirectoryIsCreated_whenMkdirInvoked_thenDirectoryCanBeRenamed() { + public void givenDir_whenMkdir_thenCanRenameDir() { - File source = makeDirectory("source"); - File destination = makeDirectory("destination"); - source.renameTo(destination); + File source = makeDir("source"); + File destination = makeDir("destination"); + boolean renamed = source.renameTo(destination); - assertFalse(source.isDirectory()); - assertTrue(destination.isDirectory()); + if (renamed) { + assertFalse(source.isDirectory()); + assertTrue(destination.isDirectory()); - removeDirectory(destination); + removeDir(destination); + } } @Test - public void givenDataIsWrittenToFile_whenWriteIsInvoked_thenFreeSpaceOnSystemDecreases() throws IOException { + public void givenDataWritten_whenWrite_thenFreeSpaceReduces() { - String name = System.getProperty("user.home") + System.getProperty("file.separator") + "test"; - File testDir = makeDirectory(name); + String home = System.getProperty("user.home"); + String sep = File.separator; + File testDir = makeDir(home + sep + "test"); File sample = new File(testDir, "sample.txt"); - long freeSpaceBeforeWrite = testDir.getFreeSpace(); - writeSampleDataToFile(sample); + long freeSpaceBefore = testDir.getFreeSpace(); + try { + writeSampleDataToFile(sample); + } catch (IOException e) { + fail("Could not write to " + "sample.txt"); + } - long freeSpaceAfterWrite = testDir.getFreeSpace(); - assertTrue(freeSpaceAfterWrite < freeSpaceBeforeWrite); + long freeSpaceAfter = testDir.getFreeSpace(); + assertTrue(freeSpaceAfter < freeSpaceBefore); - removeDirectory(testDir); + removeDir(testDir); } - private static File makeDirectory(String directoryName) { - File directory = new File(directoryName); + private static File makeDir(String name) { + File directory = new File(name); directory.mkdir(); if (directory.isDirectory()) { return directory; } - throw new RuntimeException("Directory not created for " + directoryName); + throw new RuntimeException("'" + name + "' not made!"); } - private static void removeDirectory(File directory) { + private static void removeDir(File directory) { // make sure you don't delete your home directory here - if (directory.getPath().equals(System.getProperty("user.home"))) { + String home = System.getProperty("user.home"); + if (directory.getPath().equals(home)) { return; } // remove directory and its files from system - if (directory != null && directory.exists()) { + if (directory.exists()) { // delete all files inside the directory - File[] filesInDirectory = directory.listFiles(); - if (filesInDirectory != null) { - List files = Arrays.asList(filesInDirectory); + File[] dirFiles = directory.listFiles(); + if (dirFiles != null) { + List files = Arrays.asList(dirFiles); files.forEach(f -> deleteFile(f)); } @@ -171,8 +194,8 @@ public class FileClassDemoUnitTest { //write sample text to file try (FileOutputStream out = new FileOutputStream(sample)) { for (int i = 1; i <= 100000; i++) { - String sampleText = "Sample line number " + i + "\n"; - out.write(sampleText.getBytes()); + String text = "Sample line number " + i + "\n"; + out.write(text.getBytes()); } } } diff --git a/core-java-modules/core-java-io/README.md b/core-java-modules/core-java-io/README.md index 34b2f371e1..2a68e861e8 100644 --- a/core-java-modules/core-java-io/README.md +++ b/core-java-modules/core-java-io/README.md @@ -13,22 +13,11 @@ This module contains articles about core Java input and output (IO) - [Differences Between the Java WatchService API and the Apache Commons IO Monitor Library](http://www.baeldung.com/java-watchservice-vs-apache-commons-io-monitor-library) - [File Size in Java](http://www.baeldung.com/java-file-size) - [Comparing getPath(), getAbsolutePath(), and getCanonicalPath() in Java](http://www.baeldung.com/java-path) -- [Using Java MappedByteBuffer](http://www.baeldung.com/java-mapped-byte-buffer) - [How to Copy a File with Java](http://www.baeldung.com/java-copy-file) - [Java – Append Data to a File](http://www.baeldung.com/java-append-to-file) - [FileNotFoundException in Java](http://www.baeldung.com/java-filenotfound-exception) - [How to Read a File in Java](http://www.baeldung.com/reading-file-in-java) -- [A Guide To NIO2 Asynchronous File Channel](http://www.baeldung.com/java-nio2-async-file-channel) -- [A Guide To NIO2 FileVisitor](http://www.baeldung.com/java-nio2-file-visitor) -- [A Guide To NIO2 File Attribute APIs](http://www.baeldung.com/java-nio2-file-attribute) -- [Introduction to the Java NIO2 File API](http://www.baeldung.com/java-nio-2-file-api) - [Zipping and Unzipping in Java](http://www.baeldung.com/java-compress-and-uncompress) -- [Java NIO2 Path API](http://www.baeldung.com/java-nio-2-path) -- [A Guide to WatchService in Java NIO2](http://www.baeldung.com/java-nio2-watchservice) -- [Guide to Java NIO2 Asynchronous Channel APIs](http://www.baeldung.com/java-nio-2-async-channels) -- [A Guide to NIO2 Asynchronous Socket Channel](http://www.baeldung.com/java-nio2-async-socket-channel) -- [Download a File From an URL in Java](http://www.baeldung.com/java-download-file) -- [Create a Symbolic Link with Java](http://www.baeldung.com/java-symlink) - [Quick Use of FilenameFilter](http://www.baeldung.com/java-filename-filter) - [Read a File into an ArrayList](https://www.baeldung.com/java-file-to-arraylist) - [Guide to Java OutputStream](https://www.baeldung.com/java-outputstream) @@ -40,6 +29,5 @@ This module contains articles about core Java input and output (IO) - [How to Write to a CSV File in Java](https://www.baeldung.com/java-csv) - [List Files in a Directory in Java](https://www.baeldung.com/java-list-directory-files) - [Java InputStream to Byte Array and ByteBuffer](https://www.baeldung.com/convert-input-stream-to-array-of-bytes) -- [Introduction to the Java NIO Selector](https://www.baeldung.com/java-nio-selector) - [How to Avoid the Java FileNotFoundException When Loading Resources](https://www.baeldung.com/java-classpath-resource-cannot-be-opened) - [[More -->]](/core-java-modules/core-java-io-2) diff --git a/core-java-modules/core-java-io/pom.xml b/core-java-modules/core-java-io/pom.xml index 3478f71286..393ab5e318 100644 --- a/core-java-modules/core-java-io/pom.xml +++ b/core-java-modules/core-java-io/pom.xml @@ -27,12 +27,6 @@ ${hsqldb.version} runtime - - - org.asynchttpclient - async-http-client - ${async-http-client.version} - com.opencsv opencsv @@ -155,7 +149,6 @@ 3.0.0-M1 2.4.0 - 2.4.5 1.18 0.1.5 diff --git a/core-java-modules/core-java-io/src/main/java/com/baeldung/java/nio/selector/README.md b/core-java-modules/core-java-io/src/main/java/com/baeldung/java/nio/selector/README.md deleted file mode 100644 index b28aae1397..0000000000 --- a/core-java-modules/core-java-io/src/main/java/com/baeldung/java/nio/selector/README.md +++ /dev/null @@ -1,2 +0,0 @@ -###Relevant Articles: -- [Introduction to the Java NIO Selector](http://www.baeldung.com/java-nio-selector) diff --git a/core-java-modules/core-java-io/src/test/java/com/baeldung/filechannel/FileChannelUnitTest.java b/core-java-modules/core-java-io/src/test/java/com/baeldung/filechannel/FileChannelUnitTest.java deleted file mode 100644 index 6964ba80e3..0000000000 --- a/core-java-modules/core-java-io/src/test/java/com/baeldung/filechannel/FileChannelUnitTest.java +++ /dev/null @@ -1,165 +0,0 @@ -package com.baeldung.filechannel; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -import java.io.ByteArrayOutputStream; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.RandomAccessFile; -import java.nio.ByteBuffer; -import java.nio.MappedByteBuffer; -import java.nio.channels.FileChannel; -import java.nio.channels.FileLock; -import java.nio.charset.StandardCharsets; - -import org.junit.Test; - -public class FileChannelUnitTest { - - @Test - public void givenFile_whenReadWithFileChannelUsingRandomAccessFile_thenCorrect() throws IOException { - - try (RandomAccessFile reader = new RandomAccessFile("src/test/resources/test_read.in", "r"); - FileChannel channel = reader.getChannel(); - ByteArrayOutputStream out = new ByteArrayOutputStream();) { - - int bufferSize = 1024; - if (bufferSize > channel.size()) { - bufferSize = (int) channel.size(); - } - ByteBuffer buff = ByteBuffer.allocate(bufferSize); - - while (channel.read(buff) > 0) { - out.write(buff.array(), 0, buff.position()); - buff.clear(); - } - - String fileContent = new String(out.toByteArray(), StandardCharsets.UTF_8); - - assertEquals("Hello world", fileContent); - } - } - - @Test - public void givenFile_whenReadWithFileChannelUsingFileInputStream_thenCorrect() throws IOException { - - try (ByteArrayOutputStream out = new ByteArrayOutputStream(); - FileInputStream fin = new FileInputStream("src/test/resources/test_read.in"); - FileChannel channel = fin.getChannel();) { - - int bufferSize = 1024; - if (bufferSize > channel.size()) { - bufferSize = (int) channel.size(); - } - ByteBuffer buff = ByteBuffer.allocate(bufferSize); - - while (channel.read(buff) > 0) { - out.write(buff.array(), 0, buff.position()); - buff.clear(); - } - String fileContent = new String(out.toByteArray(), StandardCharsets.UTF_8); - - assertEquals("Hello world", fileContent); - } - } - - @Test - public void givenFile_whenReadAFileSectionIntoMemoryWithFileChannel_thenCorrect() throws IOException { - - try (RandomAccessFile reader = new RandomAccessFile("src/test/resources/test_read.in", "r"); - FileChannel channel = reader.getChannel(); - ByteArrayOutputStream out = new ByteArrayOutputStream();) { - - MappedByteBuffer buff = channel.map(FileChannel.MapMode.READ_ONLY, 6, 5); - - if (buff.hasRemaining()) { - byte[] data = new byte[buff.remaining()]; - buff.get(data); - assertEquals("world", new String(data, StandardCharsets.UTF_8)); - } - } - } - - @Test - public void whenWriteWithFileChannelUsingRandomAccessFile_thenCorrect() throws IOException { - String file = "src/test/resources/test_write_using_filechannel.txt"; - try (RandomAccessFile writer = new RandomAccessFile(file, "rw"); - FileChannel channel = writer.getChannel();) { - ByteBuffer buff = ByteBuffer.wrap("Hello world".getBytes(StandardCharsets.UTF_8)); - - channel.write(buff); - - // now we verify whether the file was written correctly - RandomAccessFile reader = new RandomAccessFile(file, "r"); - assertEquals("Hello world", reader.readLine()); - reader.close(); - } - } - - @Test - public void givenFile_whenWriteAFileUsingLockAFileSectionWithFileChannel_thenCorrect() throws IOException { - try (RandomAccessFile reader = new RandomAccessFile("src/test/resources/test_read.in", "rw"); - FileChannel channel = reader.getChannel(); - FileLock fileLock = channel.tryLock(6, 5, Boolean.FALSE);) { - - assertNotNull(fileLock); - } - } - - @Test - public void givenFile_whenReadWithFileChannelGetPosition_thenCorrect() throws IOException { - - try (ByteArrayOutputStream out = new ByteArrayOutputStream(); - RandomAccessFile reader = new RandomAccessFile("src/test/resources/test_read.in", "r"); - FileChannel channel = reader.getChannel();) { - - int bufferSize = 1024; - if (bufferSize > channel.size()) { - bufferSize = (int) channel.size(); - } - ByteBuffer buff = ByteBuffer.allocate(bufferSize); - - while (channel.read(buff) > 0) { - out.write(buff.array(), 0, buff.position()); - buff.clear(); - } - - // the original file is 11 bytes long, so that's where the position pointer should be - assertEquals(11, channel.position()); - - channel.position(4); - assertEquals(4, channel.position()); - } - } - - @Test - public void whenGetFileSize_thenCorrect() throws IOException { - - try (RandomAccessFile reader = new RandomAccessFile("src/test/resources/test_read.in", "r"); - FileChannel channel = reader.getChannel();) { - - // the original file is 11 bytes long, so that's where the position pointer should be - assertEquals(11, channel.size()); - } - } - - @Test - public void whenTruncateFile_thenCorrect() throws IOException { - String input = "this is a test input"; - - FileOutputStream fout = new FileOutputStream("src/test/resources/test_truncate.txt"); - FileChannel channel = fout.getChannel(); - - ByteBuffer buff = ByteBuffer.wrap(input.getBytes()); - channel.write(buff); - buff.flip(); - - channel = channel.truncate(5); - assertEquals(5, channel.size()); - - fout.close(); - channel.close(); - } -} diff --git a/core-java-modules/core-java-io/src/test/java/com/baeldung/java/nio2/README.md b/core-java-modules/core-java-io/src/test/java/com/baeldung/java/nio2/README.md deleted file mode 100644 index 569be82d27..0000000000 --- a/core-java-modules/core-java-io/src/test/java/com/baeldung/java/nio2/README.md +++ /dev/null @@ -1,11 +0,0 @@ -### Relevant Articles: -- [Introduction to the Java NIO2 File API](http://www.baeldung.com/java-nio-2-file-api) -- [Java NIO2 Path API](http://www.baeldung.com/java-nio-2-path) -- [A Guide To NIO2 Asynchronous File Channel](http://www.baeldung.com/java-nio2-async-file-channel) -- [Guide to Selenium with JUnit / TestNG](http://www.baeldung.com/java-selenium-with-junit-and-testng) -- [A Guide to NIO2 Asynchronous Socket Channel](http://www.baeldung.com/java-nio2-async-socket-channel) -- [A Guide To NIO2 FileVisitor](http://www.baeldung.com/java-nio2-file-visitor) -- [A Guide To NIO2 File Attribute APIs](http://www.baeldung.com/java-nio2-file-attribute) -- [How to use the Spring FactoryBean?](http://www.baeldung.com/spring-factorybean) -- [A Guide to WatchService in Java NIO2](http://www.baeldung.com/java-nio2-watchservice) -- [Guide to Java NIO2 Asynchronous Channel APIs](http://www.baeldung.com/java-nio-2-async-channels) diff --git a/core-java-modules/core-java-io/src/test/resources/test_truncate.txt b/core-java-modules/core-java-io/src/test/resources/test_truncate.txt deleted file mode 100644 index 26d3b38cdd..0000000000 --- a/core-java-modules/core-java-io/src/test/resources/test_truncate.txt +++ /dev/null @@ -1 +0,0 @@ -this \ No newline at end of file diff --git a/core-java-modules/core-java-io/src/test/resources/test_write_using_filechannel.txt b/core-java-modules/core-java-io/src/test/resources/test_write_using_filechannel.txt deleted file mode 100644 index 70c379b63f..0000000000 --- a/core-java-modules/core-java-io/src/test/resources/test_write_using_filechannel.txt +++ /dev/null @@ -1 +0,0 @@ -Hello world \ No newline at end of file diff --git a/core-java-modules/core-java-lang-oop-3/README.md b/core-java-modules/core-java-lang-oop-3/README.md index f8efcb737f..69fb4f5d28 100644 --- a/core-java-modules/core-java-lang-oop-3/README.md +++ b/core-java-modules/core-java-lang-oop-3/README.md @@ -15,4 +15,4 @@ This module contains articles about Object-oriented programming (OOP) in Java - [Java Interfaces](https://www.baeldung.com/java-interfaces) - [Static and Dynamic Binding in Java](https://www.baeldung.com/java-static-dynamic-binding) - [Methods in Java](https://www.baeldung.com/java-methods) -- [[<-- Prev]](/core-java-modules/core-java-lang-oop-2) +- [[<-- Prev]](/core-java-modules/core-java-lang-oop-2) [[More -->]](/core-java-modules/core-java-lang-oop-4) diff --git a/core-java-modules/core-java-lang-oop-4/README.md b/core-java-modules/core-java-lang-oop-4/README.md new file mode 100644 index 0000000000..fae5b3091b --- /dev/null +++ b/core-java-modules/core-java-lang-oop-4/README.md @@ -0,0 +1,6 @@ +## Core Java Lang OOP (Part 4) + +This module contains articles about Object-oriented programming (OOP) in Java + +### Relevant Articles: +- [[<-- Prev]](/core-java-modules/core-java-lang-oop-3) diff --git a/core-java-modules/core-java-lang-oop-4/pom.xml b/core-java-modules/core-java-lang-oop-4/pom.xml new file mode 100644 index 0000000000..72662a8ea4 --- /dev/null +++ b/core-java-modules/core-java-lang-oop-4/pom.xml @@ -0,0 +1,57 @@ + + 4.0.0 + core-java-lang-oop-4 + 0.1.0-SNAPSHOT + core-java-lang-oop-4 + jar + + + com.baeldung + parent-java + 0.0.1-SNAPSHOT + ../../parent-java + + + + + + log4j + log4j + ${log4j.version} + + + org.slf4j + log4j-over-slf4j + ${org.slf4j.version} + + + + org.assertj + assertj-core + ${assertj-core.version} + test + + + com.h2database + h2 + ${h2.version} + test + + + + + core-java-lang-oop-4 + + + src/main/resources + true + + + + + + 3.10.0 + + + diff --git a/core-java-modules/core-java-lang-oop-4/src/main/java/com/baeldung/strictfpUsage/Circle.java b/core-java-modules/core-java-lang-oop-4/src/main/java/com/baeldung/strictfpUsage/Circle.java new file mode 100644 index 0000000000..a1f08d1bff --- /dev/null +++ b/core-java-modules/core-java-lang-oop-4/src/main/java/com/baeldung/strictfpUsage/Circle.java @@ -0,0 +1,5 @@ +package com.baeldung.strictfpUsage; + +public strictfp interface Circle { + double computeArea(double radius); +} diff --git a/core-java-modules/core-java-lang-oop-4/src/main/java/com/baeldung/strictfpUsage/ScientificCalculator.java b/core-java-modules/core-java-lang-oop-4/src/main/java/com/baeldung/strictfpUsage/ScientificCalculator.java new file mode 100644 index 0000000000..b898c3da3e --- /dev/null +++ b/core-java-modules/core-java-lang-oop-4/src/main/java/com/baeldung/strictfpUsage/ScientificCalculator.java @@ -0,0 +1,12 @@ +package com.baeldung.strictfpUsage; + +public strictfp class ScientificCalculator { + + public double sum(double value1, double value2) { + return value1 + value2; + } + + public double diff(double value1, double value2) { + return value1 - value2; + } +} diff --git a/core-java-modules/core-java-lang-oop-4/src/test/java/com/baeldung/strictfpUsage/ScientificCalculatorUnitTest.java b/core-java-modules/core-java-lang-oop-4/src/test/java/com/baeldung/strictfpUsage/ScientificCalculatorUnitTest.java new file mode 100644 index 0000000000..775c75ca9d --- /dev/null +++ b/core-java-modules/core-java-lang-oop-4/src/test/java/com/baeldung/strictfpUsage/ScientificCalculatorUnitTest.java @@ -0,0 +1,18 @@ +package com.baeldung.strictfpUsage; + +import org.junit.Test; + +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; + +public class ScientificCalculatorUnitTest { + + @Test + public void whenMethodOfstrictfpClassInvoked_thenIdenticalResultOnAllPlatforms() { + ScientificCalculator calculator = new ScientificCalculator(); + double result = calculator.sum(23e10, 98e17); + assertThat(result, is(9.800000230000001E18)); + result = calculator.diff(Double.MAX_VALUE, 1.56); + assertThat(result, is(1.7976931348623157E308)); + } +} diff --git a/core-java-modules/core-java-lang-syntax-2/README.md b/core-java-modules/core-java-lang-syntax-2/README.md index 4242e381c9..71ade494bd 100644 --- a/core-java-modules/core-java-lang-syntax-2/README.md +++ b/core-java-modules/core-java-lang-syntax-2/README.md @@ -12,4 +12,5 @@ This module contains articles about Java syntax - [The Java Native Keyword and Methods](https://www.baeldung.com/java-native) - [Variable Scope in Java](https://www.baeldung.com/java-variable-scope) - [Introduction to Basic Syntax in Java](https://www.baeldung.com/java-syntax) +- [Java ‘protected’ Access Modifier](https://www.baeldung.com/java-protected-access-modifier) - [[<-- Prev]](/core-java-modules/core-java-lang-syntax) diff --git a/core-java-modules/core-java-networking-2/README.md b/core-java-modules/core-java-networking-2/README.md index 7dc33b5e11..120b111ff5 100644 --- a/core-java-modules/core-java-networking-2/README.md +++ b/core-java-modules/core-java-networking-2/README.md @@ -4,10 +4,11 @@ This module contains articles about networking in Java ### Relevant Articles -- [Checking if a URL Exists in Java](https://www.baeldung.com/java-check-url-exists) -- [Making a JSON POST Request With HttpURLConnection](https://www.baeldung.com/httpurlconnection-post) +- [Checking If a URL Exists in Java](https://www.baeldung.com/java-check-url-exists) +- [Making a JSON POST Request with HttpURLConnection](https://www.baeldung.com/httpurlconnection-post) - [Using Curl in Java](https://www.baeldung.com/java-curl) -- [Do a Simple HTTP Request in Java](http://www.baeldung.com/java-http-request) -- [Sending Emails with Java](http://www.baeldung.com/java-email) +- [Do a Simple HTTP Request in Java](https://www.baeldung.com/java-http-request) +- [Sending Emails with Java](https://www.baeldung.com/java-email) - [Authentication with HttpUrlConnection](https://www.baeldung.com/java-http-url-connection) +- [Download a File from an URL in Java](https://www.baeldung.com/java-download-file) - [[<-- Prev]](/core-java-modules/core-java-networking) diff --git a/core-java-modules/core-java-networking-2/pom.xml b/core-java-modules/core-java-networking-2/pom.xml index 2d404a553b..c3a5891066 100644 --- a/core-java-modules/core-java-networking-2/pom.xml +++ b/core-java-modules/core-java-networking-2/pom.xml @@ -6,9 +6,10 @@ jar - com.baeldung.core-java-modules - core-java-modules - 1.0.0-SNAPSHOT + com.baeldung + parent-java + 0.0.1-SNAPSHOT + ../../parent-java @@ -27,6 +28,11 @@ mail ${javax.mail.version} + + org.asynchttpclient + async-http-client + ${async-http-client.version} + @@ -36,5 +42,6 @@ 4.5.9 1.5.0-b01 + 2.4.5 diff --git a/core-java-modules/core-java-io/src/main/java/com/baeldung/download/FileDownload.java b/core-java-modules/core-java-networking-2/src/main/java/com/baeldung/download/FileDownload.java similarity index 99% rename from core-java-modules/core-java-io/src/main/java/com/baeldung/download/FileDownload.java rename to core-java-modules/core-java-networking-2/src/main/java/com/baeldung/download/FileDownload.java index a099406d4c..ebcf7a70f7 100644 --- a/core-java-modules/core-java-io/src/main/java/com/baeldung/download/FileDownload.java +++ b/core-java-modules/core-java-networking-2/src/main/java/com/baeldung/download/FileDownload.java @@ -4,7 +4,7 @@ import org.apache.commons.io.FileUtils; import org.asynchttpclient.*; import java.io.*; -import java.net.*; +import java.net.URL; import java.nio.channels.Channels; import java.nio.channels.FileChannel; import java.nio.channels.ReadableByteChannel; diff --git a/core-java-modules/core-java-io/src/main/java/com/baeldung/download/ResumableDownload.java b/core-java-modules/core-java-networking-2/src/main/java/com/baeldung/download/ResumableDownload.java similarity index 100% rename from core-java-modules/core-java-io/src/main/java/com/baeldung/download/ResumableDownload.java rename to core-java-modules/core-java-networking-2/src/main/java/com/baeldung/download/ResumableDownload.java diff --git a/core-java-modules/core-java-io/src/test/java/com/baeldung/download/FileDownloadIntegrationTest.java b/core-java-modules/core-java-networking-2/src/test/java/com/baeldung/download/FileDownloadIntegrationTest.java similarity index 98% rename from core-java-modules/core-java-io/src/test/java/com/baeldung/download/FileDownloadIntegrationTest.java rename to core-java-modules/core-java-networking-2/src/test/java/com/baeldung/download/FileDownloadIntegrationTest.java index 81ac391958..16017ee482 100644 --- a/core-java-modules/core-java-io/src/test/java/com/baeldung/download/FileDownloadIntegrationTest.java +++ b/core-java-modules/core-java-networking-2/src/test/java/com/baeldung/download/FileDownloadIntegrationTest.java @@ -1,8 +1,10 @@ package com.baeldung.download; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.assertTrue; +import org.junit.After; +import org.junit.BeforeClass; +import org.junit.Test; +import javax.xml.bind.DatatypeConverter; import java.io.IOException; import java.net.URISyntaxException; import java.nio.file.Files; @@ -11,11 +13,7 @@ import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.concurrent.ExecutionException; -import javax.xml.bind.DatatypeConverter; - -import org.junit.After; -import org.junit.BeforeClass; -import org.junit.Test; +import static org.junit.Assert.assertTrue; public class FileDownloadIntegrationTest { diff --git a/core-java-modules/core-java-nio-2/README.md b/core-java-modules/core-java-nio-2/README.md new file mode 100644 index 0000000000..8b29c97385 --- /dev/null +++ b/core-java-modules/core-java-nio-2/README.md @@ -0,0 +1,11 @@ +## Core Java NIO + +This module contains articles about core Java non-blocking input and output (IO) + +## Relevant Articles: + +- [A Guide to WatchService in Java NIO2](https://www.baeldung.com/java-nio2-watchservice) +- [Create a Symbolic Link with Java](https://www.baeldung.com/java-symlink) +- [Introduction to the Java NIO Selector](https://www.baeldung.com/java-nio-selector) +- [Using Java MappedByteBuffer](https://www.baeldung.com/java-mapped-byte-buffer) +- [[<-- Prev]](/core-java-modules/core-java-nio) \ No newline at end of file diff --git a/core-java-modules/core-java-nio-2/pom.xml b/core-java-modules/core-java-nio-2/pom.xml new file mode 100644 index 0000000000..c1fa423b38 --- /dev/null +++ b/core-java-modules/core-java-nio-2/pom.xml @@ -0,0 +1,17 @@ + + 4.0.0 + core-java-nio-2 + 0.1.0-SNAPSHOT + core-java-nio-2 + jar + + + com.baeldung + parent-java + 0.0.1-SNAPSHOT + ../../parent-java + + + \ No newline at end of file diff --git a/core-java-modules/core-java-io/src/main/java/com/baeldung/java/nio/selector/EchoClient.java b/core-java-modules/core-java-nio-2/src/main/java/com/baeldung/selector/EchoClient.java similarity index 96% rename from core-java-modules/core-java-io/src/main/java/com/baeldung/java/nio/selector/EchoClient.java rename to core-java-modules/core-java-nio-2/src/main/java/com/baeldung/selector/EchoClient.java index 61f339db58..dd0a15ac7e 100644 --- a/core-java-modules/core-java-io/src/main/java/com/baeldung/java/nio/selector/EchoClient.java +++ b/core-java-modules/core-java-nio-2/src/main/java/com/baeldung/selector/EchoClient.java @@ -1,4 +1,4 @@ -package com.baeldung.java.nio.selector; +package com.baeldung.selector; import java.io.IOException; import java.net.InetSocketAddress; diff --git a/core-java-modules/core-java-io/src/main/java/com/baeldung/java/nio/selector/EchoServer.java b/core-java-modules/core-java-nio-2/src/main/java/com/baeldung/selector/EchoServer.java similarity index 98% rename from core-java-modules/core-java-io/src/main/java/com/baeldung/java/nio/selector/EchoServer.java rename to core-java-modules/core-java-nio-2/src/main/java/com/baeldung/selector/EchoServer.java index 7c1e291646..8cf2e941fe 100644 --- a/core-java-modules/core-java-io/src/main/java/com/baeldung/java/nio/selector/EchoServer.java +++ b/core-java-modules/core-java-nio-2/src/main/java/com/baeldung/selector/EchoServer.java @@ -1,4 +1,4 @@ -package com.baeldung.java.nio.selector; +package com.baeldung.selector; import java.io.File; import java.io.IOException; diff --git a/core-java-modules/core-java-io/src/main/java/com/baeldung/symlink/SymLinkExample.java b/core-java-modules/core-java-nio-2/src/main/java/com/baeldung/symlink/SymLinkExample.java similarity index 93% rename from core-java-modules/core-java-io/src/main/java/com/baeldung/symlink/SymLinkExample.java rename to core-java-modules/core-java-nio-2/src/main/java/com/baeldung/symlink/SymLinkExample.java index 63ee0f14b1..4c2c47e085 100644 --- a/core-java-modules/core-java-io/src/main/java/com/baeldung/symlink/SymLinkExample.java +++ b/core-java-modules/core-java-nio-2/src/main/java/com/baeldung/symlink/SymLinkExample.java @@ -6,9 +6,11 @@ import java.nio.file.DirectoryStream; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import static java.nio.file.StandardOpenOption.*; import java.util.stream.IntStream; +import static java.nio.file.StandardOpenOption.CREATE; +import static java.nio.file.StandardOpenOption.TRUNCATE_EXISTING; + public class SymLinkExample { public void createSymbolicLink(Path link, Path target) throws IOException { diff --git a/core-java-modules/core-java-io/src/main/java/com/baeldung/java/nio2/watcher/DirectoryWatcherExample.java b/core-java-modules/core-java-nio-2/src/main/java/com/baeldung/watcher/DirectoryWatcherExample.java similarity index 74% rename from core-java-modules/core-java-io/src/main/java/com/baeldung/java/nio2/watcher/DirectoryWatcherExample.java rename to core-java-modules/core-java-nio-2/src/main/java/com/baeldung/watcher/DirectoryWatcherExample.java index 4c35ffdb22..e8a2a401ab 100644 --- a/core-java-modules/core-java-io/src/main/java/com/baeldung/java/nio2/watcher/DirectoryWatcherExample.java +++ b/core-java-modules/core-java-nio-2/src/main/java/com/baeldung/watcher/DirectoryWatcherExample.java @@ -1,13 +1,7 @@ -package com.baeldung.java.nio2.watcher; +package com.baeldung.watcher; import java.io.IOException; -import java.nio.file.FileSystems; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.nio.file.StandardWatchEventKinds; -import java.nio.file.WatchEvent; -import java.nio.file.WatchKey; -import java.nio.file.WatchService; +import java.nio.file.*; public class DirectoryWatcherExample { diff --git a/core-java-modules/core-java-io/src/test/java/com/baeldung/mappedbytebuffer/MappedByteBufferUnitTest.java b/core-java-modules/core-java-nio-2/src/test/java/com/baeldung/mappedbytebuffer/MappedByteBufferUnitTest.java similarity index 100% rename from core-java-modules/core-java-io/src/test/java/com/baeldung/mappedbytebuffer/MappedByteBufferUnitTest.java rename to core-java-modules/core-java-nio-2/src/test/java/com/baeldung/mappedbytebuffer/MappedByteBufferUnitTest.java diff --git a/core-java-modules/core-java-io/src/test/java/com/baeldung/java/nio/selector/NioEchoLiveTest.java b/core-java-modules/core-java-nio-2/src/test/java/com/baeldung/selector/NioEchoLiveTest.java similarity index 87% rename from core-java-modules/core-java-io/src/test/java/com/baeldung/java/nio/selector/NioEchoLiveTest.java rename to core-java-modules/core-java-nio-2/src/test/java/com/baeldung/selector/NioEchoLiveTest.java index 0e1afa87a5..39deb798e5 100644 --- a/core-java-modules/core-java-io/src/test/java/com/baeldung/java/nio/selector/NioEchoLiveTest.java +++ b/core-java-modules/core-java-nio-2/src/test/java/com/baeldung/selector/NioEchoLiveTest.java @@ -1,13 +1,15 @@ -package com.baeldung.java.nio.selector; - -import static org.junit.Assert.assertEquals; - -import java.io.IOException; +package com.baeldung.selector; +import com.baeldung.selector.EchoClient; +import com.baeldung.selector.EchoServer; import org.junit.After; import org.junit.Before; import org.junit.Test; +import java.io.IOException; + +import static org.junit.Assert.assertEquals; + public class NioEchoLiveTest { private Process server; diff --git a/core-java-modules/core-java-io/src/test/java/com/baeldung/symlink/SymLinkExampleManualTest.java b/core-java-modules/core-java-nio-2/src/test/java/com/baeldung/symlink/SymLinkExampleManualTest.java similarity index 100% rename from core-java-modules/core-java-io/src/test/java/com/baeldung/symlink/SymLinkExampleManualTest.java rename to core-java-modules/core-java-nio-2/src/test/java/com/baeldung/symlink/SymLinkExampleManualTest.java index caa7049475..e6723e719c 100644 --- a/core-java-modules/core-java-io/src/test/java/com/baeldung/symlink/SymLinkExampleManualTest.java +++ b/core-java-modules/core-java-nio-2/src/test/java/com/baeldung/symlink/SymLinkExampleManualTest.java @@ -1,13 +1,13 @@ package com.baeldung.symlink; -import static org.junit.Assert.*; +import org.junit.Test; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import org.junit.Test; +import static org.junit.Assert.*; public class SymLinkExampleManualTest { diff --git a/core-java-modules/core-java-io/src/test/resources/fileToRead.txt b/core-java-modules/core-java-nio-2/src/test/resources/fileToRead.txt similarity index 100% rename from core-java-modules/core-java-io/src/test/resources/fileToRead.txt rename to core-java-modules/core-java-nio-2/src/test/resources/fileToRead.txt diff --git a/core-java-modules/core-java-io/src/test/resources/fileToWriteTo.txt b/core-java-modules/core-java-nio-2/src/test/resources/fileToWriteTo.txt similarity index 100% rename from core-java-modules/core-java-io/src/test/resources/fileToWriteTo.txt rename to core-java-modules/core-java-nio-2/src/test/resources/fileToWriteTo.txt diff --git a/core-java-modules/core-java-nio/README.md b/core-java-modules/core-java-nio/README.md index 727bd2546c..b64a436957 100644 --- a/core-java-modules/core-java-nio/README.md +++ b/core-java-modules/core-java-nio/README.md @@ -5,4 +5,13 @@ This module contains articles about core Java non-blocking input and output (IO) ## Relevant Articles: - [Determine File Creation Date in Java](https://www.baeldung.com/java-file-creation-date) -- [Find the Number of Lines in a File Using Jav](https://www.baeldung.com/java-file-number-of-lines) +- [Find the Number of Lines in a File Using Java](https://www.baeldung.com/java-file-number-of-lines) +- [A Guide to NIO2 Asynchronous File Channel](https://www.baeldung.com/java-nio2-async-file-channel) +- [A Guide to NIO2 FileVisitor](https://www.baeldung.com/java-nio2-file-visitor) +- [Guide to Java FileChannel](https://www.baeldung.com/java-filechannel) +- [A Guide to NIO2 File Attribute APIs](https://www.baeldung.com/java-nio2-file-attribute) +- [Introduction to the Java NIO2 File API](https://www.baeldung.com/java-nio-2-file-api) +- [Java NIO2 Path API](https://www.baeldung.com/java-nio-2-path) +- [Guide to Java NIO2 Asynchronous Channel APIs](https://www.baeldung.com/java-nio-2-async-channels) +- [A Guide to NIO2 Asynchronous Socket Channel](https://www.baeldung.com/java-nio2-async-socket-channel) +- [[More -->]](/core-java-modules/core-java-nio-2) diff --git a/core-java-modules/core-java-nio/pom.xml b/core-java-modules/core-java-nio/pom.xml index 31433e632f..da8759a956 100644 --- a/core-java-modules/core-java-nio/pom.xml +++ b/core-java-modules/core-java-nio/pom.xml @@ -13,4 +13,5 @@ 0.0.1-SNAPSHOT ../../parent-java + \ No newline at end of file diff --git a/core-java-modules/core-java-io/src/main/java/com/baeldung/java/nio2/visitor/FileSearchExample.java b/core-java-modules/core-java-nio/src/main/java/com/baeldung/filevisitor/FileSearchExample.java similarity index 97% rename from core-java-modules/core-java-io/src/main/java/com/baeldung/java/nio2/visitor/FileSearchExample.java rename to core-java-modules/core-java-nio/src/main/java/com/baeldung/filevisitor/FileSearchExample.java index b1b790f541..b49d6eb570 100644 --- a/core-java-modules/core-java-io/src/main/java/com/baeldung/java/nio2/visitor/FileSearchExample.java +++ b/core-java-modules/core-java-nio/src/main/java/com/baeldung/filevisitor/FileSearchExample.java @@ -1,4 +1,4 @@ -package com.baeldung.java.nio2.visitor; +package com.baeldung.filevisitor; import java.io.IOException; import java.nio.file.*; diff --git a/core-java-modules/core-java-io/src/main/java/com/baeldung/java/nio2/visitor/FileVisitorImpl.java b/core-java-modules/core-java-nio/src/main/java/com/baeldung/filevisitor/FileVisitorImpl.java similarity index 94% rename from core-java-modules/core-java-io/src/main/java/com/baeldung/java/nio2/visitor/FileVisitorImpl.java rename to core-java-modules/core-java-nio/src/main/java/com/baeldung/filevisitor/FileVisitorImpl.java index aa769b5091..d86264720f 100644 --- a/core-java-modules/core-java-io/src/main/java/com/baeldung/java/nio2/visitor/FileVisitorImpl.java +++ b/core-java-modules/core-java-nio/src/main/java/com/baeldung/filevisitor/FileVisitorImpl.java @@ -1,4 +1,4 @@ -package com.baeldung.java.nio2.visitor; +package com.baeldung.filevisitor; import java.io.IOException; import java.nio.file.FileVisitResult; diff --git a/core-java-modules/core-java-nio/src/main/java/com/baeldung/file/Main.java b/core-java-modules/core-java-nio/src/main/java/com/baeldung/lines/Main.java similarity index 62% rename from core-java-modules/core-java-nio/src/main/java/com/baeldung/file/Main.java rename to core-java-modules/core-java-nio/src/main/java/com/baeldung/lines/Main.java index d8800dd881..5aa0968ab9 100644 --- a/core-java-modules/core-java-nio/src/main/java/com/baeldung/file/Main.java +++ b/core-java-modules/core-java-nio/src/main/java/com/baeldung/lines/Main.java @@ -1,13 +1,13 @@ -package com.baeldung.file; +package com.baeldung.lines; -import static com.baeldung.file.NumberOfLineFinder.getTotalNumberOfLinesUsingApacheCommonsIO; -import static com.baeldung.file.NumberOfLineFinder.getTotalNumberOfLinesUsingBufferedReader; -import static com.baeldung.file.NumberOfLineFinder.getTotalNumberOfLinesUsingGoogleGuava; -import static com.baeldung.file.NumberOfLineFinder.getTotalNumberOfLinesUsingLineNumberReader; -import static com.baeldung.file.NumberOfLineFinder.getTotalNumberOfLinesUsingNIOFileChannel; -import static com.baeldung.file.NumberOfLineFinder.getTotalNumberOfLinesUsingNIOFiles; -import static com.baeldung.file.NumberOfLineFinder.getTotalNumberOfLinesUsingNIOFilesReadAllLines; -import static com.baeldung.file.NumberOfLineFinder.getTotalNumberOfLinesUsingScanner; +import static com.baeldung.lines.NumberOfLineFinder.getTotalNumberOfLinesUsingApacheCommonsIO; +import static com.baeldung.lines.NumberOfLineFinder.getTotalNumberOfLinesUsingBufferedReader; +import static com.baeldung.lines.NumberOfLineFinder.getTotalNumberOfLinesUsingGoogleGuava; +import static com.baeldung.lines.NumberOfLineFinder.getTotalNumberOfLinesUsingLineNumberReader; +import static com.baeldung.lines.NumberOfLineFinder.getTotalNumberOfLinesUsingNIOFileChannel; +import static com.baeldung.lines.NumberOfLineFinder.getTotalNumberOfLinesUsingNIOFiles; +import static com.baeldung.lines.NumberOfLineFinder.getTotalNumberOfLinesUsingNIOFilesReadAllLines; +import static com.baeldung.lines.NumberOfLineFinder.getTotalNumberOfLinesUsingScanner; public class Main { diff --git a/core-java-modules/core-java-nio/src/main/java/com/baeldung/file/NumberOfLineFinder.java b/core-java-modules/core-java-nio/src/main/java/com/baeldung/lines/NumberOfLineFinder.java similarity index 99% rename from core-java-modules/core-java-nio/src/main/java/com/baeldung/file/NumberOfLineFinder.java rename to core-java-modules/core-java-nio/src/main/java/com/baeldung/lines/NumberOfLineFinder.java index 3abf82f3fa..b355295dab 100644 --- a/core-java-modules/core-java-nio/src/main/java/com/baeldung/file/NumberOfLineFinder.java +++ b/core-java-modules/core-java-nio/src/main/java/com/baeldung/lines/NumberOfLineFinder.java @@ -1,4 +1,4 @@ -package com.baeldung.file; +package com.baeldung.lines; import java.io.BufferedReader; import java.io.File; diff --git a/core-java-modules/core-java-io/src/test/java/com/baeldung/java/nio2/async/AsyncEchoClient.java b/core-java-modules/core-java-nio/src/test/java/com/baeldung/async/AsyncEchoClient.java similarity index 98% rename from core-java-modules/core-java-io/src/test/java/com/baeldung/java/nio2/async/AsyncEchoClient.java rename to core-java-modules/core-java-nio/src/test/java/com/baeldung/async/AsyncEchoClient.java index ebab715306..f42f5cdeca 100644 --- a/core-java-modules/core-java-io/src/test/java/com/baeldung/java/nio2/async/AsyncEchoClient.java +++ b/core-java-modules/core-java-nio/src/test/java/com/baeldung/async/AsyncEchoClient.java @@ -1,4 +1,4 @@ -package com.baeldung.java.nio2.async; +package com.baeldung.async; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/core-java-modules/core-java-io/src/test/java/com/baeldung/java/nio2/async/AsyncEchoIntegrationTest.java b/core-java-modules/core-java-nio/src/test/java/com/baeldung/async/AsyncEchoIntegrationTest.java similarity index 95% rename from core-java-modules/core-java-io/src/test/java/com/baeldung/java/nio2/async/AsyncEchoIntegrationTest.java rename to core-java-modules/core-java-nio/src/test/java/com/baeldung/async/AsyncEchoIntegrationTest.java index 3cfac0e90f..42053cea96 100644 --- a/core-java-modules/core-java-io/src/test/java/com/baeldung/java/nio2/async/AsyncEchoIntegrationTest.java +++ b/core-java-modules/core-java-nio/src/test/java/com/baeldung/async/AsyncEchoIntegrationTest.java @@ -1,4 +1,4 @@ -package com.baeldung.java.nio2.async; +package com.baeldung.async; import org.junit.After; import org.junit.Before; diff --git a/core-java-modules/core-java-io/src/test/java/com/baeldung/java/nio2/async/AsyncEchoServer.java b/core-java-modules/core-java-nio/src/test/java/com/baeldung/async/AsyncEchoServer.java similarity index 98% rename from core-java-modules/core-java-io/src/test/java/com/baeldung/java/nio2/async/AsyncEchoServer.java rename to core-java-modules/core-java-nio/src/test/java/com/baeldung/async/AsyncEchoServer.java index 01873b344a..b3f8151b7e 100644 --- a/core-java-modules/core-java-io/src/test/java/com/baeldung/java/nio2/async/AsyncEchoServer.java +++ b/core-java-modules/core-java-nio/src/test/java/com/baeldung/async/AsyncEchoServer.java @@ -1,4 +1,4 @@ -package com.baeldung.java.nio2.async; +package com.baeldung.async; import java.io.File; import java.io.IOException; diff --git a/core-java-modules/core-java-io/src/test/java/com/baeldung/java/nio2/async/AsyncEchoServer2.java b/core-java-modules/core-java-nio/src/test/java/com/baeldung/async/AsyncEchoServer2.java similarity index 98% rename from core-java-modules/core-java-io/src/test/java/com/baeldung/java/nio2/async/AsyncEchoServer2.java rename to core-java-modules/core-java-nio/src/test/java/com/baeldung/async/AsyncEchoServer2.java index 663fc4f2ed..15b98cbf6e 100644 --- a/core-java-modules/core-java-io/src/test/java/com/baeldung/java/nio2/async/AsyncEchoServer2.java +++ b/core-java-modules/core-java-nio/src/test/java/com/baeldung/async/AsyncEchoServer2.java @@ -1,4 +1,4 @@ -package com.baeldung.java.nio2.async; +package com.baeldung.async; import java.io.File; import java.io.IOException; diff --git a/core-java-modules/core-java-io/src/test/java/com/baeldung/java/nio2/async/AsyncFileIntegrationTest.java b/core-java-modules/core-java-nio/src/test/java/com/baeldung/asyncfilechannel/AsyncFileChannelIntegrationTest.java similarity index 98% rename from core-java-modules/core-java-io/src/test/java/com/baeldung/java/nio2/async/AsyncFileIntegrationTest.java rename to core-java-modules/core-java-nio/src/test/java/com/baeldung/asyncfilechannel/AsyncFileChannelIntegrationTest.java index cf37b92565..68f0afec95 100644 --- a/core-java-modules/core-java-io/src/test/java/com/baeldung/java/nio2/async/AsyncFileIntegrationTest.java +++ b/core-java-modules/core-java-nio/src/test/java/com/baeldung/asyncfilechannel/AsyncFileChannelIntegrationTest.java @@ -1,4 +1,4 @@ -package com.baeldung.java.nio2.async; +package com.baeldung.asyncfilechannel; import org.junit.Test; @@ -16,7 +16,7 @@ import java.util.concurrent.Future; import static org.junit.Assert.assertEquals; -public class AsyncFileIntegrationTest { +public class AsyncFileChannelIntegrationTest { @Test public void givenPath_whenReadsContentWithFuture_thenCorrect() throws IOException, ExecutionException, InterruptedException { diff --git a/core-java-modules/core-java-io/src/test/java/com/baeldung/java/nio2/attributes/BasicAttribsIntegrationTest.java b/core-java-modules/core-java-nio/src/test/java/com/baeldung/attributes/BasicAttribsIntegrationTest.java similarity index 98% rename from core-java-modules/core-java-io/src/test/java/com/baeldung/java/nio2/attributes/BasicAttribsIntegrationTest.java rename to core-java-modules/core-java-nio/src/test/java/com/baeldung/attributes/BasicAttribsIntegrationTest.java index 4b6302e93c..a1f05d107f 100644 --- a/core-java-modules/core-java-io/src/test/java/com/baeldung/java/nio2/attributes/BasicAttribsIntegrationTest.java +++ b/core-java-modules/core-java-nio/src/test/java/com/baeldung/attributes/BasicAttribsIntegrationTest.java @@ -1,4 +1,4 @@ -package com.baeldung.java.nio2.attributes; +package com.baeldung.attributes; import org.junit.BeforeClass; import org.junit.Test; diff --git a/core-java-modules/core-java-io/src/test/java/com/baeldung/java/nio2/FileIntegrationTest.java b/core-java-modules/core-java-nio/src/test/java/com/baeldung/file/FileIntegrationTest.java similarity index 99% rename from core-java-modules/core-java-io/src/test/java/com/baeldung/java/nio2/FileIntegrationTest.java rename to core-java-modules/core-java-nio/src/test/java/com/baeldung/file/FileIntegrationTest.java index d1cf81e4ce..1ae84a4dcf 100644 --- a/core-java-modules/core-java-io/src/test/java/com/baeldung/java/nio2/FileIntegrationTest.java +++ b/core-java-modules/core-java-nio/src/test/java/com/baeldung/file/FileIntegrationTest.java @@ -1,4 +1,4 @@ -package com.baeldung.java.nio2; +package com.baeldung.file; import org.apache.commons.io.FileUtils; import org.junit.AfterClass; diff --git a/core-java-modules/core-java-nio/src/test/java/com/baeldung/file/NumberOfLineFinderUnitTest.java b/core-java-modules/core-java-nio/src/test/java/com/baeldung/lines/NumberOfLineFinderUnitTest.java similarity index 71% rename from core-java-modules/core-java-nio/src/test/java/com/baeldung/file/NumberOfLineFinderUnitTest.java rename to core-java-modules/core-java-nio/src/test/java/com/baeldung/lines/NumberOfLineFinderUnitTest.java index 40ed6d6bba..661b42accd 100644 --- a/core-java-modules/core-java-nio/src/test/java/com/baeldung/file/NumberOfLineFinderUnitTest.java +++ b/core-java-modules/core-java-nio/src/test/java/com/baeldung/lines/NumberOfLineFinderUnitTest.java @@ -1,13 +1,13 @@ -package com.baeldung.file; +package com.baeldung.lines; -import static com.baeldung.file.NumberOfLineFinder.getTotalNumberOfLinesUsingApacheCommonsIO; -import static com.baeldung.file.NumberOfLineFinder.getTotalNumberOfLinesUsingBufferedReader; -import static com.baeldung.file.NumberOfLineFinder.getTotalNumberOfLinesUsingGoogleGuava; -import static com.baeldung.file.NumberOfLineFinder.getTotalNumberOfLinesUsingLineNumberReader; -import static com.baeldung.file.NumberOfLineFinder.getTotalNumberOfLinesUsingNIOFileChannel; -import static com.baeldung.file.NumberOfLineFinder.getTotalNumberOfLinesUsingNIOFiles; -import static com.baeldung.file.NumberOfLineFinder.getTotalNumberOfLinesUsingNIOFilesReadAllLines; -import static com.baeldung.file.NumberOfLineFinder.getTotalNumberOfLinesUsingScanner; +import static com.baeldung.lines.NumberOfLineFinder.getTotalNumberOfLinesUsingApacheCommonsIO; +import static com.baeldung.lines.NumberOfLineFinder.getTotalNumberOfLinesUsingBufferedReader; +import static com.baeldung.lines.NumberOfLineFinder.getTotalNumberOfLinesUsingGoogleGuava; +import static com.baeldung.lines.NumberOfLineFinder.getTotalNumberOfLinesUsingLineNumberReader; +import static com.baeldung.lines.NumberOfLineFinder.getTotalNumberOfLinesUsingNIOFileChannel; +import static com.baeldung.lines.NumberOfLineFinder.getTotalNumberOfLinesUsingNIOFiles; +import static com.baeldung.lines.NumberOfLineFinder.getTotalNumberOfLinesUsingNIOFilesReadAllLines; +import static com.baeldung.lines.NumberOfLineFinder.getTotalNumberOfLinesUsingScanner; import static org.junit.Assert.assertEquals; import org.junit.Test; diff --git a/core-java-modules/core-java-io/src/test/java/com/baeldung/java/nio2/PathManualTest.java b/core-java-modules/core-java-nio/src/test/java/com/baeldung/path/PathManualTest.java similarity index 97% rename from core-java-modules/core-java-io/src/test/java/com/baeldung/java/nio2/PathManualTest.java rename to core-java-modules/core-java-nio/src/test/java/com/baeldung/path/PathManualTest.java index 969dff1da2..7017fd42e7 100644 --- a/core-java-modules/core-java-io/src/test/java/com/baeldung/java/nio2/PathManualTest.java +++ b/core-java-modules/core-java-nio/src/test/java/com/baeldung/path/PathManualTest.java @@ -1,8 +1,6 @@ -package com.baeldung.java.nio2; +package com.baeldung.path; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; +import org.junit.Test; import java.io.IOException; import java.net.URI; @@ -10,7 +8,7 @@ import java.nio.file.NoSuchFileException; import java.nio.file.Path; import java.nio.file.Paths; -import org.junit.Test; +import static org.junit.Assert.*; public class PathManualTest { diff --git a/core-java-modules/core-java-nio/src/test/resources/.gitignore b/core-java-modules/core-java-nio/src/test/resources/.gitignore deleted file mode 100644 index 83c05e60c8..0000000000 --- a/core-java-modules/core-java-nio/src/test/resources/.gitignore +++ /dev/null @@ -1,13 +0,0 @@ -*.class - -#folders# -/target -/neoDb* -/data -/src/main/webapp/WEB-INF/classes -*/META-INF/* - -# Packaged files # -*.jar -*.war -*.ear \ No newline at end of file diff --git a/core-java-modules/core-java-nio/src/test/resources/file.txt b/core-java-modules/core-java-nio/src/test/resources/file.txt new file mode 100644 index 0000000000..558d8bbf35 --- /dev/null +++ b/core-java-modules/core-java-nio/src/test/resources/file.txt @@ -0,0 +1 @@ +baeldung.com \ No newline at end of file diff --git a/core-java-modules/core-java-streams-3/src/main/java/com/baeldung/streams/debug/entity/Customer.java b/core-java-modules/core-java-streams-3/src/main/java/com/baeldung/streams/debug/entity/Customer.java new file mode 100644 index 0000000000..b8e1b6db5b --- /dev/null +++ b/core-java-modules/core-java-streams-3/src/main/java/com/baeldung/streams/debug/entity/Customer.java @@ -0,0 +1,19 @@ +package com.baeldung.streams.debug.entity; + +public class Customer { + private final String name; + private final int age; + + public Customer(String name, int age) { + this.name = name; + this.age = age; + } + + public String getName() { + return name; + } + + public int getAge() { + return age; + } +} diff --git a/core-java-modules/core-java-streams-3/src/test/java/com/baeldung/streams/debug/Example1.java b/core-java-modules/core-java-streams-3/src/test/java/com/baeldung/streams/debug/Example1.java new file mode 100644 index 0000000000..d8087bc98a --- /dev/null +++ b/core-java-modules/core-java-streams-3/src/test/java/com/baeldung/streams/debug/Example1.java @@ -0,0 +1,18 @@ +package com.baeldung.streams.debug; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.stream.IntStream; + +import org.junit.Test; + +public class Example1 { + @Test + public void whenDebugging_thenInformationIsShown() { + int[] listOutputSorted = IntStream.of(-3, 10, -4, 1, 3) + .sorted() + .toArray(); + + assertThat(listOutputSorted).isSorted(); + } +} diff --git a/core-java-modules/core-java-streams-3/src/test/java/com/baeldung/streams/debug/Example2.java b/core-java-modules/core-java-streams-3/src/test/java/com/baeldung/streams/debug/Example2.java new file mode 100644 index 0000000000..56cbddf0b4 --- /dev/null +++ b/core-java-modules/core-java-streams-3/src/test/java/com/baeldung/streams/debug/Example2.java @@ -0,0 +1,36 @@ +package com.baeldung.streams.debug; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.Arrays; +import java.util.List; +import java.util.Optional; +import java.util.stream.Stream; + +import org.junit.Test; + +import com.baeldung.streams.debug.entity.Customer; + +public class Example2 { + @Test + public void whenDebugging_thenInformationIsShown() { + List> customers = Arrays.asList( + Optional.of(new Customer("John P.", 15)), + Optional.of(new Customer("Sarah M.", 78)), + Optional.empty(), + Optional.of(new Customer("Mary T.", 20)), + Optional.empty(), + Optional.of(new Customer("Florian G.", 89)), + Optional.empty() + ); + + long numberOf65PlusCustomers = customers.stream() + .flatMap(c -> c.map(Stream::of) + .orElseGet(Stream::empty)) + .mapToInt(Customer::getAge) + .filter(c -> c > 65) + .count(); + + assertThat(numberOf65PlusCustomers).isEqualTo(2); + } +} diff --git a/core-java-modules/core-java-string-algorithms-2/README.md b/core-java-modules/core-java-string-algorithms-2/README.md index 2cd64e1920..94ace77d66 100644 --- a/core-java-modules/core-java-string-algorithms-2/README.md +++ b/core-java-modules/core-java-string-algorithms-2/README.md @@ -12,5 +12,5 @@ This module contains articles about string-related algorithms. - [Pad a String with Zeros or Spaces in Java](https://www.baeldung.com/java-pad-string) - [Remove Leading and Trailing Characters from a String](https://www.baeldung.com/java-remove-trailing-characters) - [Counting Words in a String](https://www.baeldung.com/java-word-counting) -- [Finding the Difference Between Two Strings](https://www.baeldung.com/java-difference-between-two-strings) +- [Finding the Difference Between Two Strings in Java](https://www.baeldung.com/java-difference-between-two-strings) - More articles: [[<-- prev]](../core-java-string-algorithms) diff --git a/java-strings/src/test/java/com/baeldung/string/StringUnitTest.java b/core-java-modules/core-java-string-apis/src/test/java/com/baeldung/stringapi/StringUnitTest.java similarity index 96% rename from java-strings/src/test/java/com/baeldung/string/StringUnitTest.java rename to core-java-modules/core-java-string-apis/src/test/java/com/baeldung/stringapi/StringUnitTest.java index 0d4fd6eff9..5c1fe2fbda 100644 --- a/java-strings/src/test/java/com/baeldung/string/StringUnitTest.java +++ b/core-java-modules/core-java-string-apis/src/test/java/com/baeldung/stringapi/StringUnitTest.java @@ -1,16 +1,13 @@ -package com.baeldung.string; +package com.baeldung.stringapi; -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; +import org.junit.Test; import java.io.UnsupportedEncodingException; import java.nio.charset.StandardCharsets; import java.util.IllegalFormatException; import java.util.regex.PatternSyntaxException; -import org.junit.Test; +import static org.junit.Assert.*; public class StringUnitTest { diff --git a/core-java-modules/core-java-strings/README.md b/core-java-modules/core-java-strings/README.md new file mode 100644 index 0000000000..4a418db29f --- /dev/null +++ b/core-java-modules/core-java-strings/README.md @@ -0,0 +1,14 @@ +## Java Strings + +This module contains articles about strings in Java. + +### Relevant Articles: +- [Use char[] Array over a String for Manipulating Passwords in Java?](https://www.baeldung.com/java-storing-passwords) +- [Compact Strings in Java 9](https://www.baeldung.com/java-9-compact-string) +- [String Not Empty Test Assertions in Java](https://www.baeldung.com/java-assert-string-not-empty) +- [String Performance Hints](https://www.baeldung.com/java-string-performance) +- [Java Localization – Formatting Messages](https://www.baeldung.com/java-localization-messages-formatting) +- [Java – Generate Random String](https://www.baeldung.com/java-random-string) +- [Java String Interview Questions and Answers](https://www.baeldung.com/java-string-interview-questions) +- [Java Multi-line String](https://www.baeldung.com/java-multiline-string) +- [Guide to Java String Pool](https://www.baeldung.com/java-string-pool) diff --git a/core-java-modules/core-java-strings/pom.xml b/core-java-modules/core-java-strings/pom.xml new file mode 100644 index 0000000000..6a80886549 --- /dev/null +++ b/core-java-modules/core-java-strings/pom.xml @@ -0,0 +1,60 @@ + + 4.0.0 + core-java-strings + 0.1.0-SNAPSHOT + jar + core-java-strings + + + com.baeldung + parent-java + 0.0.1-SNAPSHOT + ../../parent-java + + + + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + + + org.openjdk.jmh + jmh-core + ${jmh-core.version} + + + org.openjdk.jmh + jmh-generator-annprocess + ${jmh-generator.version} + + + com.ibm.icu + icu4j + ${icu4j.version} + + + org.assertj + assertj-core + ${assertj.version} + test + + + + + core-java-strings + + + src/main/resources + true + + + + + + 3.6.1 + 61.1 + + + diff --git a/java-strings/src/main/java/com/baeldung/java9/compactstring/CompactStringDemo.java b/core-java-modules/core-java-strings/src/main/java/com/baeldung/java9/compactstring/CompactStringDemo.java similarity index 97% rename from java-strings/src/main/java/com/baeldung/java9/compactstring/CompactStringDemo.java rename to core-java-modules/core-java-strings/src/main/java/com/baeldung/java9/compactstring/CompactStringDemo.java index cb24511f72..eae75eaa2b 100644 --- a/java-strings/src/main/java/com/baeldung/java9/compactstring/CompactStringDemo.java +++ b/core-java-modules/core-java-strings/src/main/java/com/baeldung/java9/compactstring/CompactStringDemo.java @@ -1,9 +1,10 @@ package com.baeldung.java9.compactstring; import java.util.List; -import static java.util.stream.Collectors.toList; import java.util.stream.IntStream; +import static java.util.stream.Collectors.toList; + public class CompactStringDemo { public static void main(String[] args) { @@ -11,14 +12,14 @@ public class CompactStringDemo { List strings = IntStream.rangeClosed(1, 10_000_000) .mapToObj(Integer::toString).collect(toList()); long totalTime = System.currentTimeMillis() - startTime; - System.out.println("Generated " + strings.size() + " strings in " + System.out.println("Generated " + strings.size() + " strings in " + totalTime + " ms."); startTime = System.currentTimeMillis(); String appended = (String) strings.stream().limit(100_000) .reduce("", (left, right) -> left.toString() + right.toString()); totalTime = System.currentTimeMillis() - startTime; - System.out.println("Created string of length " + appended.length() + System.out.println("Created string of length " + appended.length() + " in " + totalTime + " ms."); } } diff --git a/java-strings-2/src/main/java/com/baeldung/localization/App.java b/core-java-modules/core-java-strings/src/main/java/com/baeldung/localization/App.java similarity index 100% rename from java-strings-2/src/main/java/com/baeldung/localization/App.java rename to core-java-modules/core-java-strings/src/main/java/com/baeldung/localization/App.java diff --git a/java-strings-2/src/main/java/com/baeldung/localization/ICUFormat.java b/core-java-modules/core-java-strings/src/main/java/com/baeldung/localization/ICUFormat.java similarity index 100% rename from java-strings-2/src/main/java/com/baeldung/localization/ICUFormat.java rename to core-java-modules/core-java-strings/src/main/java/com/baeldung/localization/ICUFormat.java index f7bc357933..c82af30c87 100644 --- a/java-strings-2/src/main/java/com/baeldung/localization/ICUFormat.java +++ b/core-java-modules/core-java-strings/src/main/java/com/baeldung/localization/ICUFormat.java @@ -1,11 +1,11 @@ package com.baeldung.localization; +import com.ibm.icu.text.MessageFormat; + import java.util.List; import java.util.Locale; import java.util.ResourceBundle; -import com.ibm.icu.text.MessageFormat; - public class ICUFormat { public static String getLabel(Locale locale, Object[] data) { diff --git a/java-strings-2/src/main/java/com/baeldung/localization/JavaSEFormat.java b/core-java-modules/core-java-strings/src/main/java/com/baeldung/localization/JavaSEFormat.java similarity index 100% rename from java-strings-2/src/main/java/com/baeldung/localization/JavaSEFormat.java rename to core-java-modules/core-java-strings/src/main/java/com/baeldung/localization/JavaSEFormat.java diff --git a/java-strings-2/src/main/java/com/baeldung/localization/Localization.java b/core-java-modules/core-java-strings/src/main/java/com/baeldung/localization/Localization.java similarity index 100% rename from java-strings-2/src/main/java/com/baeldung/localization/Localization.java rename to core-java-modules/core-java-strings/src/main/java/com/baeldung/localization/Localization.java diff --git a/java-strings-2/src/main/java/com/baeldung/string/multiline/MultiLineString.java b/core-java-modules/core-java-strings/src/main/java/com/baeldung/multiline/MultiLineString.java similarity index 98% rename from java-strings-2/src/main/java/com/baeldung/string/multiline/MultiLineString.java rename to core-java-modules/core-java-strings/src/main/java/com/baeldung/multiline/MultiLineString.java index 1bde2dcb63..987bc751cd 100644 --- a/java-strings-2/src/main/java/com/baeldung/string/multiline/MultiLineString.java +++ b/core-java-modules/core-java-strings/src/main/java/com/baeldung/multiline/MultiLineString.java @@ -1,4 +1,7 @@ -package com.baeldung.string.multiline; +package com.baeldung.multiline; + +import com.google.common.base.Joiner; +import com.google.common.collect.ImmutableList; import java.io.IOException; import java.io.PrintWriter; @@ -6,9 +9,6 @@ import java.io.StringWriter; import java.nio.file.Files; import java.nio.file.Paths; -import com.google.common.base.Joiner; -import com.google.common.collect.ImmutableList; - public class MultiLineString { String newLine = System.getProperty("line.separator"); diff --git a/java-strings/src/main/java/com/baeldung/string/StringPerformance.java b/core-java-modules/core-java-strings/src/main/java/com/baeldung/stringperformance/StringPerformance.java similarity index 99% rename from java-strings/src/main/java/com/baeldung/string/StringPerformance.java rename to core-java-modules/core-java-strings/src/main/java/com/baeldung/stringperformance/StringPerformance.java index 3b0c32991c..8e9d3afdde 100644 --- a/java-strings/src/main/java/com/baeldung/string/StringPerformance.java +++ b/core-java-modules/core-java-strings/src/main/java/com/baeldung/stringperformance/StringPerformance.java @@ -1,4 +1,4 @@ -package com.baeldung.string; +package com.baeldung.stringperformance; import com.google.common.base.Splitter; import org.apache.commons.lang3.StringUtils; diff --git a/java-strings-2/src/main/resources/formats_en.properties b/core-java-modules/core-java-strings/src/main/resources/formats_en.properties similarity index 100% rename from java-strings-2/src/main/resources/formats_en.properties rename to core-java-modules/core-java-strings/src/main/resources/formats_en.properties diff --git a/java-strings-2/src/main/resources/formats_fr.properties b/core-java-modules/core-java-strings/src/main/resources/formats_fr.properties similarity index 100% rename from java-strings-2/src/main/resources/formats_fr.properties rename to core-java-modules/core-java-strings/src/main/resources/formats_fr.properties diff --git a/java-strings-2/src/main/resources/formats_it.properties b/core-java-modules/core-java-strings/src/main/resources/formats_it.properties similarity index 100% rename from java-strings-2/src/main/resources/formats_it.properties rename to core-java-modules/core-java-strings/src/main/resources/formats_it.properties diff --git a/java-strings-2/src/main/resources/formats_pl.properties b/core-java-modules/core-java-strings/src/main/resources/formats_pl.properties similarity index 100% rename from java-strings-2/src/main/resources/formats_pl.properties rename to core-java-modules/core-java-strings/src/main/resources/formats_pl.properties diff --git a/java-strings-2/src/main/resources/logback.xml b/core-java-modules/core-java-strings/src/main/resources/logback.xml similarity index 100% rename from java-strings-2/src/main/resources/logback.xml rename to core-java-modules/core-java-strings/src/main/resources/logback.xml diff --git a/java-strings-2/src/main/resources/messages_en.properties b/core-java-modules/core-java-strings/src/main/resources/messages_en.properties similarity index 100% rename from java-strings-2/src/main/resources/messages_en.properties rename to core-java-modules/core-java-strings/src/main/resources/messages_en.properties diff --git a/java-strings-2/src/main/resources/messages_fr.properties b/core-java-modules/core-java-strings/src/main/resources/messages_fr.properties similarity index 100% rename from java-strings-2/src/main/resources/messages_fr.properties rename to core-java-modules/core-java-strings/src/main/resources/messages_fr.properties diff --git a/java-strings-2/src/main/resources/messages_it.properties b/core-java-modules/core-java-strings/src/main/resources/messages_it.properties similarity index 100% rename from java-strings-2/src/main/resources/messages_it.properties rename to core-java-modules/core-java-strings/src/main/resources/messages_it.properties diff --git a/java-strings-2/src/main/resources/messages_pl.properties b/core-java-modules/core-java-strings/src/main/resources/messages_pl.properties similarity index 100% rename from java-strings-2/src/main/resources/messages_pl.properties rename to core-java-modules/core-java-strings/src/main/resources/messages_pl.properties diff --git a/java-strings-2/src/main/resources/stephenking.txt b/core-java-modules/core-java-strings/src/main/resources/stephenking.txt similarity index 100% rename from java-strings-2/src/main/resources/stephenking.txt rename to core-java-modules/core-java-strings/src/main/resources/stephenking.txt diff --git a/java-strings/src/test/java/com/baeldung/chararraypassword/PasswordStoreExamplesUnitTest.java b/core-java-modules/core-java-strings/src/test/java/com/baeldung/chararraypassword/PasswordStoreExamplesUnitTest.java similarity index 100% rename from java-strings/src/test/java/com/baeldung/chararraypassword/PasswordStoreExamplesUnitTest.java rename to core-java-modules/core-java-strings/src/test/java/com/baeldung/chararraypassword/PasswordStoreExamplesUnitTest.java diff --git a/java-strings-2/src/test/java/com/baeldung/string/interview/LocaleUnitTest.java b/core-java-modules/core-java-strings/src/test/java/com/baeldung/interview/LocaleUnitTest.java similarity index 93% rename from java-strings-2/src/test/java/com/baeldung/string/interview/LocaleUnitTest.java rename to core-java-modules/core-java-strings/src/test/java/com/baeldung/interview/LocaleUnitTest.java index 1d221056fd..5655d2536d 100644 --- a/java-strings-2/src/test/java/com/baeldung/string/interview/LocaleUnitTest.java +++ b/core-java-modules/core-java-strings/src/test/java/com/baeldung/interview/LocaleUnitTest.java @@ -1,11 +1,12 @@ -package com.baeldung.string.interview; +package com.baeldung.interview; + +import org.junit.Test; import java.math.BigDecimal; import java.text.NumberFormat; import java.util.Locale; -import static org.junit.Assert.assertEquals; -import org.junit.Test; +import static org.junit.Assert.assertEquals; public class LocaleUnitTest { @Test diff --git a/java-strings-2/src/test/java/com/baeldung/string/interview/StringAnagramUnitTest.java b/core-java-modules/core-java-strings/src/test/java/com/baeldung/interview/StringAnagramUnitTest.java similarity index 94% rename from java-strings-2/src/test/java/com/baeldung/string/interview/StringAnagramUnitTest.java rename to core-java-modules/core-java-strings/src/test/java/com/baeldung/interview/StringAnagramUnitTest.java index aadfade737..8f3bacc267 100644 --- a/java-strings-2/src/test/java/com/baeldung/string/interview/StringAnagramUnitTest.java +++ b/core-java-modules/core-java-strings/src/test/java/com/baeldung/interview/StringAnagramUnitTest.java @@ -1,10 +1,10 @@ -package com.baeldung.string.interview; +package com.baeldung.interview; -import static org.assertj.core.api.Assertions.assertThat; +import org.junit.Test; import java.util.Arrays; -import org.junit.Test; +import static org.assertj.core.api.Assertions.assertThat; public class StringAnagramUnitTest { public boolean isAnagram(String s1, String s2) { diff --git a/java-strings-2/src/test/java/com/baeldung/string/interview/StringChangeCaseUnitTest.java b/core-java-modules/core-java-strings/src/test/java/com/baeldung/interview/StringChangeCaseUnitTest.java similarity index 92% rename from java-strings-2/src/test/java/com/baeldung/string/interview/StringChangeCaseUnitTest.java rename to core-java-modules/core-java-strings/src/test/java/com/baeldung/interview/StringChangeCaseUnitTest.java index 2c7ec500fe..4c3815a2e4 100644 --- a/java-strings-2/src/test/java/com/baeldung/string/interview/StringChangeCaseUnitTest.java +++ b/core-java-modules/core-java-strings/src/test/java/com/baeldung/interview/StringChangeCaseUnitTest.java @@ -1,9 +1,9 @@ -package com.baeldung.string.interview; - -import static org.junit.Assert.assertEquals; +package com.baeldung.interview; import org.junit.Test; +import static org.junit.Assert.assertEquals; + public class StringChangeCaseUnitTest { @Test public void givenString_whenChangingToUppercase_thenCaseChanged() { diff --git a/java-strings-2/src/test/java/com/baeldung/string/interview/StringCountOccurrencesUnitTest.java b/core-java-modules/core-java-strings/src/test/java/com/baeldung/interview/StringCountOccurrencesUnitTest.java similarity index 94% rename from java-strings-2/src/test/java/com/baeldung/string/interview/StringCountOccurrencesUnitTest.java rename to core-java-modules/core-java-strings/src/test/java/com/baeldung/interview/StringCountOccurrencesUnitTest.java index 6c17643ac8..cb92c06d32 100644 --- a/java-strings-2/src/test/java/com/baeldung/string/interview/StringCountOccurrencesUnitTest.java +++ b/core-java-modules/core-java-strings/src/test/java/com/baeldung/interview/StringCountOccurrencesUnitTest.java @@ -1,9 +1,9 @@ -package com.baeldung.string.interview; - -import static org.junit.Assert.assertEquals; +package com.baeldung.interview; import org.junit.Test; +import static org.junit.Assert.assertEquals; + public class StringCountOccurrencesUnitTest { public int countOccurrences(String s, char c) { int count = 0; diff --git a/java-strings-2/src/test/java/com/baeldung/string/interview/StringFormatUnitTest.java b/core-java-modules/core-java-strings/src/test/java/com/baeldung/interview/StringFormatUnitTest.java similarity index 90% rename from java-strings-2/src/test/java/com/baeldung/string/interview/StringFormatUnitTest.java rename to core-java-modules/core-java-strings/src/test/java/com/baeldung/interview/StringFormatUnitTest.java index 787017791c..8492db0dc0 100644 --- a/java-strings-2/src/test/java/com/baeldung/string/interview/StringFormatUnitTest.java +++ b/core-java-modules/core-java-strings/src/test/java/com/baeldung/interview/StringFormatUnitTest.java @@ -1,9 +1,9 @@ -package com.baeldung.string.interview; - -import static org.junit.Assert.assertEquals; +package com.baeldung.interview; import org.junit.Test; +import static org.junit.Assert.assertEquals; + public class StringFormatUnitTest { @Test public void givenString_whenUsingStringFormat_thenStringFormatted() { diff --git a/java-strings-2/src/test/java/com/baeldung/string/interview/StringInternUnitTest.java b/core-java-modules/core-java-strings/src/test/java/com/baeldung/interview/StringInternUnitTest.java similarity index 91% rename from java-strings-2/src/test/java/com/baeldung/string/interview/StringInternUnitTest.java rename to core-java-modules/core-java-strings/src/test/java/com/baeldung/interview/StringInternUnitTest.java index c5bffb7573..3092a72399 100644 --- a/java-strings-2/src/test/java/com/baeldung/string/interview/StringInternUnitTest.java +++ b/core-java-modules/core-java-strings/src/test/java/com/baeldung/interview/StringInternUnitTest.java @@ -1,9 +1,9 @@ -package com.baeldung.string.interview; - -import static org.assertj.core.api.Assertions.assertThat; +package com.baeldung.interview; import org.junit.Test; +import static org.assertj.core.api.Assertions.assertThat; + public class StringInternUnitTest { @Test public void whenCallingStringIntern_thenStringsInterned() { diff --git a/java-strings-2/src/test/java/com/baeldung/string/interview/StringJoinerUnitTest.java b/core-java-modules/core-java-strings/src/test/java/com/baeldung/interview/StringJoinerUnitTest.java similarity index 91% rename from java-strings-2/src/test/java/com/baeldung/string/interview/StringJoinerUnitTest.java rename to core-java-modules/core-java-strings/src/test/java/com/baeldung/interview/StringJoinerUnitTest.java index d44c7478e4..b5556f588c 100644 --- a/java-strings-2/src/test/java/com/baeldung/string/interview/StringJoinerUnitTest.java +++ b/core-java-modules/core-java-strings/src/test/java/com/baeldung/interview/StringJoinerUnitTest.java @@ -1,10 +1,11 @@ -package com.baeldung.string.interview; - -import java.util.StringJoiner; -import static org.junit.Assert.assertEquals; +package com.baeldung.interview; import org.junit.Test; +import java.util.StringJoiner; + +import static org.junit.Assert.assertEquals; + public class StringJoinerUnitTest { @Test public void whenUsingStringJoiner_thenStringsJoined() { diff --git a/java-strings-2/src/test/java/com/baeldung/string/interview/StringPalindromeUnitTest.java b/core-java-modules/core-java-strings/src/test/java/com/baeldung/interview/StringPalindromeUnitTest.java similarity index 95% rename from java-strings-2/src/test/java/com/baeldung/string/interview/StringPalindromeUnitTest.java rename to core-java-modules/core-java-strings/src/test/java/com/baeldung/interview/StringPalindromeUnitTest.java index 79ed14cd99..760939932a 100644 --- a/java-strings-2/src/test/java/com/baeldung/string/interview/StringPalindromeUnitTest.java +++ b/core-java-modules/core-java-strings/src/test/java/com/baeldung/interview/StringPalindromeUnitTest.java @@ -1,9 +1,9 @@ -package com.baeldung.string.interview; - -import static org.assertj.core.api.Assertions.assertThat; +package com.baeldung.interview; import org.junit.Test; +import static org.assertj.core.api.Assertions.assertThat; + public class StringPalindromeUnitTest { public boolean isPalindrome(String text) { diff --git a/java-strings-2/src/test/java/com/baeldung/string/interview/StringReverseUnitTest.java b/core-java-modules/core-java-strings/src/test/java/com/baeldung/interview/StringReverseUnitTest.java similarity index 88% rename from java-strings-2/src/test/java/com/baeldung/string/interview/StringReverseUnitTest.java rename to core-java-modules/core-java-strings/src/test/java/com/baeldung/interview/StringReverseUnitTest.java index bb9b45dc97..484a6d0d68 100644 --- a/java-strings-2/src/test/java/com/baeldung/string/interview/StringReverseUnitTest.java +++ b/core-java-modules/core-java-strings/src/test/java/com/baeldung/interview/StringReverseUnitTest.java @@ -1,9 +1,9 @@ -package com.baeldung.string.interview; - -import static org.junit.Assert.assertEquals; +package com.baeldung.interview; import org.junit.Test; +import static org.junit.Assert.assertEquals; + public class StringReverseUnitTest { @Test public void whenUsingInbuildMethods_thenStringReversed() { diff --git a/java-strings-2/src/test/java/com/baeldung/string/interview/StringSplitUnitTest.java b/core-java-modules/core-java-strings/src/test/java/com/baeldung/interview/StringSplitUnitTest.java similarity index 95% rename from java-strings-2/src/test/java/com/baeldung/string/interview/StringSplitUnitTest.java rename to core-java-modules/core-java-strings/src/test/java/com/baeldung/interview/StringSplitUnitTest.java index e1cea62462..5aff593e3e 100644 --- a/java-strings-2/src/test/java/com/baeldung/string/interview/StringSplitUnitTest.java +++ b/core-java-modules/core-java-strings/src/test/java/com/baeldung/interview/StringSplitUnitTest.java @@ -1,7 +1,8 @@ -package com.baeldung.string.interview; +package com.baeldung.interview; import org.apache.commons.lang3.StringUtils; import org.junit.Test; + import static org.junit.Assert.assertArrayEquals; public class StringSplitUnitTest { diff --git a/java-strings-2/src/test/java/com/baeldung/string/interview/StringToByteArrayUnitTest.java b/core-java-modules/core-java-strings/src/test/java/com/baeldung/interview/StringToByteArrayUnitTest.java similarity index 95% rename from java-strings-2/src/test/java/com/baeldung/string/interview/StringToByteArrayUnitTest.java rename to core-java-modules/core-java-strings/src/test/java/com/baeldung/interview/StringToByteArrayUnitTest.java index aee4eedcd6..90c5ca25c2 100644 --- a/java-strings-2/src/test/java/com/baeldung/string/interview/StringToByteArrayUnitTest.java +++ b/core-java-modules/core-java-strings/src/test/java/com/baeldung/interview/StringToByteArrayUnitTest.java @@ -1,11 +1,11 @@ -package com.baeldung.string.interview; +package com.baeldung.interview; -import static org.junit.Assert.assertArrayEquals; +import org.junit.Test; import java.io.UnsupportedEncodingException; import java.nio.charset.StandardCharsets; -import org.junit.Test; +import static org.junit.Assert.assertArrayEquals; public class StringToByteArrayUnitTest { @Test diff --git a/java-strings-2/src/test/java/com/baeldung/string/interview/StringToCharArrayUnitTest.java b/core-java-modules/core-java-strings/src/test/java/com/baeldung/interview/StringToCharArrayUnitTest.java similarity index 91% rename from java-strings-2/src/test/java/com/baeldung/string/interview/StringToCharArrayUnitTest.java rename to core-java-modules/core-java-strings/src/test/java/com/baeldung/interview/StringToCharArrayUnitTest.java index 1322d0fa82..5ebd7448f1 100644 --- a/java-strings-2/src/test/java/com/baeldung/string/interview/StringToCharArrayUnitTest.java +++ b/core-java-modules/core-java-strings/src/test/java/com/baeldung/interview/StringToCharArrayUnitTest.java @@ -1,10 +1,10 @@ -package com.baeldung.string.interview; +package com.baeldung.interview; -import static org.junit.Assert.assertEquals; +import org.junit.Test; import java.util.Arrays; -import org.junit.Test; +import static org.junit.Assert.assertEquals; public class StringToCharArrayUnitTest { @Test diff --git a/java-strings-2/src/test/java/com/baeldung/string/interview/StringToIntegerUnitTest.java b/core-java-modules/core-java-strings/src/test/java/com/baeldung/interview/StringToIntegerUnitTest.java similarity index 89% rename from java-strings-2/src/test/java/com/baeldung/string/interview/StringToIntegerUnitTest.java rename to core-java-modules/core-java-strings/src/test/java/com/baeldung/interview/StringToIntegerUnitTest.java index a905438a84..24a715dc75 100644 --- a/java-strings-2/src/test/java/com/baeldung/string/interview/StringToIntegerUnitTest.java +++ b/core-java-modules/core-java-strings/src/test/java/com/baeldung/interview/StringToIntegerUnitTest.java @@ -1,6 +1,7 @@ -package com.baeldung.string.interview; +package com.baeldung.interview; import org.junit.Test; + import static org.assertj.core.api.Assertions.assertThat; public class StringToIntegerUnitTest { diff --git a/java-strings-2/src/test/java/com/baeldung/localization/ICUFormatUnitTest.java b/core-java-modules/core-java-strings/src/test/java/com/baeldung/localization/ICUFormatUnitTest.java similarity index 98% rename from java-strings-2/src/test/java/com/baeldung/localization/ICUFormatUnitTest.java rename to core-java-modules/core-java-strings/src/test/java/com/baeldung/localization/ICUFormatUnitTest.java index 2c8f9b47f3..3c5c5fcb55 100644 --- a/java-strings-2/src/test/java/com/baeldung/localization/ICUFormatUnitTest.java +++ b/core-java-modules/core-java-strings/src/test/java/com/baeldung/localization/ICUFormatUnitTest.java @@ -1,12 +1,10 @@ package com.baeldung.localization; -import static org.junit.Assert.assertEquals; - -import java.util.Locale; - import org.junit.Test; -import com.baeldung.localization.ICUFormat; +import java.util.Locale; + +import static org.junit.Assert.assertEquals; public class ICUFormatUnitTest { diff --git a/java-strings-2/src/test/java/com/baeldung/string/multiline/MultiLineStringUnitTest.java b/core-java-modules/core-java-strings/src/test/java/com/baeldung/multiline/MultiLineStringUnitTest.java similarity index 85% rename from java-strings-2/src/test/java/com/baeldung/string/multiline/MultiLineStringUnitTest.java rename to core-java-modules/core-java-strings/src/test/java/com/baeldung/multiline/MultiLineStringUnitTest.java index 3ebee9b5d1..04d318c71b 100644 --- a/java-strings-2/src/test/java/com/baeldung/string/multiline/MultiLineStringUnitTest.java +++ b/core-java-modules/core-java-strings/src/test/java/com/baeldung/multiline/MultiLineStringUnitTest.java @@ -1,11 +1,10 @@ -package com.baeldung.string.multiline; +package com.baeldung.multiline; import org.junit.Test; -import static org.junit.Assert.assertEquals; import java.io.IOException; -import com.baeldung.string.multiline.MultiLineString; +import static org.junit.Assert.assertEquals; public class MultiLineStringUnitTest { diff --git a/core-java-modules/core-java-strings/src/test/java/com/baeldung/randomstrings/RandomStringsUnitTest.java b/core-java-modules/core-java-strings/src/test/java/com/baeldung/randomstrings/RandomStringsUnitTest.java new file mode 100644 index 0000000000..2806635d03 --- /dev/null +++ b/core-java-modules/core-java-strings/src/test/java/com/baeldung/randomstrings/RandomStringsUnitTest.java @@ -0,0 +1,72 @@ +package com.baeldung.randomstrings; + +import org.apache.commons.lang3.RandomStringUtils; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.nio.charset.Charset; +import java.util.Random; + +public class RandomStringsUnitTest { + + private static final Logger LOG = LoggerFactory.getLogger(RandomStringsUnitTest.class); + + @Test + public void givenUsingPlainJava_whenGeneratingRandomStringUnbounded_thenCorrect() { + final byte[] array = new byte[7]; // length is bounded by 7 + new Random().nextBytes(array); + final String generatedString = new String(array, Charset.forName("UTF-8")); + + LOG.debug(generatedString); + } + + @Test + public void givenUsingPlainJava_whenGeneratingRandomStringBounded_thenCorrect() { + final int leftLimit = 97; // letter 'a' + final int rightLimit = 122; // letter 'z' + final int targetStringLength = 10; + final Random random = new Random(); + final StringBuilder buffer = new StringBuilder(targetStringLength); + + for (int i = 0; i < targetStringLength; i++) { + final int randomLimitedInt = leftLimit + (int) (random.nextFloat() * (rightLimit - leftLimit + 1)); + buffer.append((char) randomLimitedInt); + } + final String generatedString = buffer.toString(); + + LOG.debug(generatedString); + } + + @Test + public void givenUsingApache_whenGeneratingRandomString_thenCorrect() { + final String generatedString = RandomStringUtils.random(10); + + LOG.debug(generatedString); + } + + @Test + public void givenUsingApache_whenGeneratingRandomAlphabeticString_thenCorrect() { + final String generatedString = RandomStringUtils.randomAlphabetic(10); + + LOG.debug(generatedString); + } + + @Test + public void givenUsingApache_whenGeneratingRandomAlphanumericString_thenCorrect() { + final String generatedString = RandomStringUtils.randomAlphanumeric(10); + + LOG.debug(generatedString); + } + + @Test + public void givenUsingApache_whenGeneratingRandomStringBounded_thenCorrect() { + final int length = 10; + final boolean useLetters = true; + final boolean useNumbers = false; + final String generatedString = RandomStringUtils.random(length, useLetters, useNumbers); + + LOG.debug(generatedString); + } + +} diff --git a/java-strings/src/test/java/com/baeldung/string/StringEmptyUnitTest.java b/core-java-modules/core-java-strings/src/test/java/com/baeldung/stringnotempty/StringNotEmptyUnitTest.java similarity index 81% rename from java-strings/src/test/java/com/baeldung/string/StringEmptyUnitTest.java rename to core-java-modules/core-java-strings/src/test/java/com/baeldung/stringnotempty/StringNotEmptyUnitTest.java index 17b13f89de..482105cc40 100644 --- a/java-strings/src/test/java/com/baeldung/string/StringEmptyUnitTest.java +++ b/core-java-modules/core-java-strings/src/test/java/com/baeldung/stringnotempty/StringNotEmptyUnitTest.java @@ -1,21 +1,16 @@ -package com.baeldung.string; - -import static org.hamcrest.CoreMatchers.not; -import static org.hamcrest.text.IsEmptyString.isEmptyOrNullString; -import static org.hamcrest.text.IsEmptyString.isEmptyString; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertNotSame; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.assertTrue; +package com.baeldung.stringnotempty; +import com.google.common.base.Strings; import org.apache.commons.lang3.StringUtils; import org.assertj.core.api.Assertions; import org.junit.Test; -import com.google.common.base.Strings; +import static org.hamcrest.CoreMatchers.not; +import static org.hamcrest.text.IsEmptyString.isEmptyOrNullString; +import static org.hamcrest.text.IsEmptyString.isEmptyString; +import static org.junit.Assert.*; -public class StringEmptyUnitTest { +public class StringNotEmptyUnitTest { private String text = "baeldung"; diff --git a/java-strings-ops/src/test/java/com/baeldung/stringpool/StringPoolUnitTest.java b/core-java-modules/core-java-strings/src/test/java/com/baeldung/stringpool/StringPoolUnitTest.java similarity index 100% rename from java-strings-ops/src/test/java/com/baeldung/stringpool/StringPoolUnitTest.java rename to core-java-modules/core-java-strings/src/test/java/com/baeldung/stringpool/StringPoolUnitTest.java diff --git a/core-java-modules/pom.xml b/core-java-modules/pom.xml index 68ece1c473..16ec19835a 100644 --- a/core-java-modules/pom.xml +++ b/core-java-modules/pom.xml @@ -19,6 +19,7 @@ core-java-lang-operators core-java-networking-2 core-java-security-manager + core-java-date-operations diff --git a/httpclient/README.md b/httpclient/README.md index 678b195965..d88739e901 100644 --- a/httpclient/README.md +++ b/httpclient/README.md @@ -2,7 +2,7 @@ This module contains articles about HttpClient 4.x -###The Course +### The Course The "REST With Spring" Classes: http://bit.ly/restwithspring diff --git a/hystrix/src/test/java/com/baeldung/hystrix/SpringAndHystrixIntegrationTest.java b/hystrix/src/test/java/com/baeldung/hystrix/SpringAndHystrixIntegrationTest.java index 004314b0ed..c8910878a9 100644 --- a/hystrix/src/test/java/com/baeldung/hystrix/SpringAndHystrixIntegrationTest.java +++ b/hystrix/src/test/java/com/baeldung/hystrix/SpringAndHystrixIntegrationTest.java @@ -13,7 +13,7 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; @RunWith(SpringRunner.class) -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT, classes = AppConfig.class) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = AppConfig.class) public class SpringAndHystrixIntegrationTest { @Autowired diff --git a/jackson-simple/src/test/java/com/baeldung/jackson/annotation/MyBean.java b/jackson-simple/src/test/java/com/baeldung/jackson/annotation/MyBean.java index 5d4ce4202c..e4e78ce445 100644 --- a/jackson-simple/src/test/java/com/baeldung/jackson/annotation/MyBean.java +++ b/jackson-simple/src/test/java/com/baeldung/jackson/annotation/MyBean.java @@ -1,8 +1,10 @@ package com.baeldung.jackson.annotation; +import com.fasterxml.jackson.annotation.JsonGetter; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import com.fasterxml.jackson.annotation.JsonSetter; @JsonInclude(Include.NON_NULL) @JsonPropertyOrder({ "name", "id" }) @@ -18,4 +20,14 @@ public class MyBean { this.id = id; this.name = name; } + + @JsonGetter("name") + public String getTheName() { + return name; + } + + @JsonSetter("name") + public void setTheName(String name) { + this.name = name; + } } diff --git a/jackson/README.md b/jackson/README.md index f96a569617..a62a788c41 100644 --- a/jackson/README.md +++ b/jackson/README.md @@ -2,10 +2,12 @@ This module contains articles about Jackson. -###The Course +### The Course + The "REST With Spring" Classes: http://bit.ly/restwithspring ### Relevant Articles: + - [Jackson – Unmarshall to Collection/Array](https://www.baeldung.com/jackson-collection-array) - [Jackson – Custom Serializer](https://www.baeldung.com/jackson-custom-serialization) - [Getting Started with Custom Deserialization in Jackson](https://www.baeldung.com/jackson-deserialization) @@ -24,7 +26,7 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [Map Serialization and Deserialization with Jackson](https://www.baeldung.com/jackson-map) - [Jackson Streaming API](https://www.baeldung.com/jackson-streaming-api) - [Jackson – JsonMappingException (No serializer found for class)](https://www.baeldung.com/jackson-jsonmappingexception) -- [How To Serialize Enums as JSON Objects with Jackson](https://www.baeldung.com/jackson-serialize-enums) +- [How To Serialize and Deserialize Enums with Jackson](https://www.baeldung.com/jackson-serialize-enums) - [Jackson – Marshall String to JsonNode](https://www.baeldung.com/jackson-json-to-jsonnode) - [Jackson – Unmarshall to Collection/Array](https://www.baeldung.com/jackson-collection-array) - [Serialize Only Fields that meet a Custom Criteria with Jackson](https://www.baeldung.com/jackson-serialize-field-custom-criteria) diff --git a/java-jdi/README.md b/java-jdi/README.md index c8c2d3e9ab..110906e845 100644 --- a/java-jdi/README.md +++ b/java-jdi/README.md @@ -2,6 +2,6 @@ This module contains articles about JDI, the Java Debug Interface. -###Relevant articles +### Relevant articles - [An Intro to the Java Debug Interface (JDI)](https://www.baeldung.com/java-debug-interface) diff --git a/java-numbers/src/test/java/com/baeldung/random/JavaRandomUnitTest.java b/java-numbers/src/test/java/com/baeldung/random/JavaRandomUnitTest.java index 2273dfda13..de37b8d1e3 100644 --- a/java-numbers/src/test/java/com/baeldung/random/JavaRandomUnitTest.java +++ b/java-numbers/src/test/java/com/baeldung/random/JavaRandomUnitTest.java @@ -1,12 +1,10 @@ package com.baeldung.random; -import org.apache.commons.lang3.RandomStringUtils; import org.apache.commons.math3.random.RandomDataGenerator; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.nio.charset.Charset; import java.util.Random; public class JavaRandomUnitTest { @@ -155,63 +153,4 @@ public class JavaRandomUnitTest { LOG.debug("{}", generatedDouble); } - // tests - random String - - @Test - public void givenUsingPlainJava_whenGeneratingRandomStringUnbounded_thenCorrect() { - final byte[] array = new byte[7]; // length is bounded by 7 - new Random().nextBytes(array); - final String generatedString = new String(array, Charset.forName("UTF-8")); - - LOG.debug(generatedString); - } - - @Test - public void givenUsingPlainJava_whenGeneratingRandomStringBounded_thenCorrect() { - final int leftLimit = 97; // letter 'a' - final int rightLimit = 122; // letter 'z' - final int targetStringLength = 10; - final Random random = new Random(); - final StringBuilder buffer = new StringBuilder(targetStringLength); - - for (int i = 0; i < targetStringLength; i++) { - final int randomLimitedInt = leftLimit + (int) (random.nextFloat() * (rightLimit - leftLimit + 1)); - buffer.append((char) randomLimitedInt); - } - final String generatedString = buffer.toString(); - - LOG.debug(generatedString); - } - - @Test - public void givenUsingApache_whenGeneratingRandomString_thenCorrect() { - final String generatedString = RandomStringUtils.random(10); - - LOG.debug(generatedString); - } - - @Test - public void givenUsingApache_whenGeneratingRandomAlphabeticString_thenCorrect() { - final String generatedString = RandomStringUtils.randomAlphabetic(10); - - LOG.debug(generatedString); - } - - @Test - public void givenUsingApache_whenGeneratingRandomAlphanumericString_thenCorrect() { - final String generatedString = RandomStringUtils.randomAlphanumeric(10); - - LOG.debug(generatedString); - } - - @Test - public void givenUsingApache_whenGeneratingRandomStringBounded_thenCorrect() { - final int length = 10; - final boolean useLetters = true; - final boolean useNumbers = false; - final String generatedString = RandomStringUtils.random(length, useLetters, useNumbers); - - LOG.debug(generatedString); - } - } diff --git a/java-strings-2/README.md b/java-strings-2/README.md deleted file mode 100644 index ecbdb7def9..0000000000 --- a/java-strings-2/README.md +++ /dev/null @@ -1,11 +0,0 @@ -## Java Strings Cookbooks and Examples - -This module contains articles about strings in Java. - -### Relevant Articles: - -- [Java Localization – Formatting Messages](https://www.baeldung.com/java-localization-messages-formatting) -- [Java – Generate Random String](https://www.baeldung.com/java-random-string) -- [Java String Interview Questions and Answers](https://www.baeldung.com/java-string-interview-questions) -- [Java Multi-line String](https://www.baeldung.com/java-multiline-string) -- More articles: [[<-- prev>]](/java-strings) diff --git a/java-strings-2/pom.xml b/java-strings-2/pom.xml deleted file mode 100755 index be47b1ec89..0000000000 --- a/java-strings-2/pom.xml +++ /dev/null @@ -1,155 +0,0 @@ - - 4.0.0 - java-strings-2 - 0.1.0-SNAPSHOT - jar - java-strings-2 - - - com.baeldung - parent-java - 0.0.1-SNAPSHOT - ../parent-java - - - - - org.openjdk.jmh - jmh-core - ${jmh-core.version} - - - org.openjdk.jmh - jmh-generator-annprocess - ${jmh-core.version} - - - com.ibm.icu - icu4j - ${icu4j.version} - - - com.google.guava - guava - ${guava.version} - - - org.apache.commons - commons-lang3 - ${commons-lang3.version} - - - commons-io - commons-io - ${commons-io.version} - - - commons-codec - commons-codec - ${commons-codec.version} - - - junit - junit - ${junit.version} - test - - - org.hamcrest - hamcrest-library - ${org.hamcrest.version} - test - - - org.assertj - assertj-core - ${assertj.version} - test - - - - - org.passay - passay - ${passay.version} - - - org.apache.commons - commons-text - ${commons-text.version} - - - com.vdurmont - emoji-java - ${emoji-java.version} - - - org.ahocorasick - ahocorasick - ${ahocorasick.version} - - - javax.validation - validation-api - ${validation-api.version} - - - org.hibernate.validator - hibernate-validator - ${hibernate-validator.version} - - - javax.el - javax.el-api - ${javax.el-api.version} - - - org.glassfish.web - javax.el - ${javax.el.version} - - - - - java-strings-2 - - - src/main/resources - true - - - - - - org.apache.maven.plugins - maven-compiler-plugin - ${maven-compiler-plugin.version} - - ${java.version} - ${java.version} - -parameters - - - - - - - 3.8.1 - 1.10 - 1.3.1 - - 3.6.1 - 4.0.0 - 0.4.0 - 61.1 - 28.0-jre - 1.4 - 2.0.0.Final - 6.0.2.Final - 3.0.0 - 2.2.6 - - - \ No newline at end of file diff --git a/java-strings-2/src/test/resources/.gitignore b/java-strings-2/src/test/resources/.gitignore deleted file mode 100644 index 83c05e60c8..0000000000 --- a/java-strings-2/src/test/resources/.gitignore +++ /dev/null @@ -1,13 +0,0 @@ -*.class - -#folders# -/target -/neoDb* -/data -/src/main/webapp/WEB-INF/classes -*/META-INF/* - -# Packaged files # -*.jar -*.war -*.ear \ No newline at end of file diff --git a/java-strings-ops/README.md b/java-strings-ops/README.md deleted file mode 100644 index 4c618585f3..0000000000 --- a/java-strings-ops/README.md +++ /dev/null @@ -1,6 +0,0 @@ -## Java Strings Cookbooks and Examples - -This module contains articles about operations on strings in Java. - -### Relevant Articles: -- [Guide to Java String Pool](https://www.baeldung.com/java-string-pool) diff --git a/java-strings-ops/pom.xml b/java-strings-ops/pom.xml deleted file mode 100644 index ebed216c2b..0000000000 --- a/java-strings-ops/pom.xml +++ /dev/null @@ -1,99 +0,0 @@ - - 4.0.0 - com.baeldung - java-strings-ops - 0.1.0-SNAPSHOT - jar - java-strings-ops - - - com.baeldung - parent-java - 0.0.1-SNAPSHOT - ../parent-java - - - - - org.apache.commons - commons-lang3 - ${commons-lang3.version} - - - log4j - log4j - ${log4j.version} - - - - org.assertj - assertj-core - ${assertj.version} - test - - - org.openjdk.jmh - jmh-core - ${jmh-core.version} - - - org.openjdk.jmh - jmh-generator-annprocess - ${jmh-generator.version} - - - com.google.guava - guava - ${guava.version} - - - - org.junit.jupiter - junit-jupiter-api - ${junit-jupiter-api.version} - test - - - - org.hamcrest - hamcrest-library - ${org.hamcrest.version} - test - - - - - - java-strings-ops - - - src/main/resources - true - - - - - - org.apache.maven.plugins - maven-compiler-plugin - ${maven-compiler-plugin.version} - - ${java.version} - ${java.version} - -parameters - - - - - - - - 3.8.1 - 27.0.1-jre - - 3.6.1 - 5.3.1 - - - diff --git a/java-strings-ops/src/main/resources/log4j.properties b/java-strings-ops/src/main/resources/log4j.properties deleted file mode 100644 index 2ea9fa9209..0000000000 --- a/java-strings-ops/src/main/resources/log4j.properties +++ /dev/null @@ -1,8 +0,0 @@ -# Root logger option -log4j.rootLogger=DEBUG, stdout - -# Redirect log messages to console -log4j.appender.stdout=org.apache.log4j.ConsoleAppender -log4j.appender.stdout.Target=System.out -log4j.appender.stdout.layout=org.apache.log4j.PatternLayout -log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n \ No newline at end of file diff --git a/java-strings-ops/src/test/resources/.gitignore b/java-strings-ops/src/test/resources/.gitignore deleted file mode 100644 index 83c05e60c8..0000000000 --- a/java-strings-ops/src/test/resources/.gitignore +++ /dev/null @@ -1,13 +0,0 @@ -*.class - -#folders# -/target -/neoDb* -/data -/src/main/webapp/WEB-INF/classes -*/META-INF/* - -# Packaged files # -*.jar -*.war -*.ear \ No newline at end of file diff --git a/java-strings/README.md b/java-strings/README.md deleted file mode 100644 index 4668ad014e..0000000000 --- a/java-strings/README.md +++ /dev/null @@ -1,10 +0,0 @@ -## Java Strings Cookbooks and Examples - -This module contains articles about strings in Java. - -### Relevant Articles: -- [Use char[] Array Over a String for Manipulating Passwords in Java?](https://www.baeldung.com/java-storing-passwords) -- [Compact Strings in Java 9](https://www.baeldung.com/java-9-compact-string) -- [String Not Empty Test Assertions in Java](https://www.baeldung.com/java-assert-string-not-empty) -- [String Performance Hints](https://www.baeldung.com/java-string-performance) -- More articles: [[next -->]](/java-strings-2) diff --git a/java-strings/pom.xml b/java-strings/pom.xml deleted file mode 100755 index 42a57bfb42..0000000000 --- a/java-strings/pom.xml +++ /dev/null @@ -1,117 +0,0 @@ - - 4.0.0 - com.baeldung - java-strings - 0.1.0-SNAPSHOT - jar - java-strings - - - com.baeldung - parent-java - 0.0.1-SNAPSHOT - ../parent-java - - - - - commons-io - commons-io - ${commons-io.version} - - - org.apache.commons - commons-lang3 - ${commons-lang3.version} - - - log4j - log4j - ${log4j.version} - - - commons-codec - commons-codec - ${commons-codec.version} - - - - org.assertj - assertj-core - ${assertj.version} - test - - - org.openjdk.jmh - jmh-core - ${jmh-core.version} - - - org.openjdk.jmh - jmh-generator-annprocess - ${jmh-generator.version} - - - com.ibm.icu - icu4j - ${icu4j.version} - - - com.google.guava - guava - ${guava.version} - - - - org.junit.jupiter - junit-jupiter-api - ${junit-jupiter-api.version} - test - - - - org.hamcrest - hamcrest-library - ${org.hamcrest.version} - test - - - - - - java-strings - - - src/main/resources - true - - - - - - org.apache.maven.plugins - maven-compiler-plugin - ${maven-compiler-plugin.version} - - ${java.version} - ${java.version} - -parameters - - - - - - - - 3.8.1 - 1.10 - - 3.6.1 - 61.1 - 27.0.1-jre - 5.3.1 - 1.4 - - - diff --git a/java-strings/src/main/resources/data.csv b/java-strings/src/main/resources/data.csv deleted file mode 100644 index ec4ac10443..0000000000 --- a/java-strings/src/main/resources/data.csv +++ /dev/null @@ -1,3 +0,0 @@ -1|IND|India -2|MY|Malaysia -3|AU|Australia diff --git a/java-strings/src/main/resources/logback.xml b/java-strings/src/main/resources/logback.xml deleted file mode 100644 index 7d900d8ea8..0000000000 --- a/java-strings/src/main/resources/logback.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n - - - - - - - - \ No newline at end of file diff --git a/java-strings/src/test/java/com/baeldung/CharArrayToStringUnitTest.java b/java-strings/src/test/java/com/baeldung/CharArrayToStringUnitTest.java deleted file mode 100644 index 3488f8b390..0000000000 --- a/java-strings/src/test/java/com/baeldung/CharArrayToStringUnitTest.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.baeldung; - -import static org.junit.Assert.*; - -import org.junit.Test; - -public class CharArrayToStringUnitTest { - - @Test - public void givenCharArray_whenCallingStringConstructor_shouldConvertToString() { - char[] charArray = { 'c', 'h', 'a', 'r', 'a', 'c', 't', 'e', 'r' }; - String result = new String(charArray); - String expectedValue = "character"; - - assertEquals(expectedValue, result); - } - - @Test - public void givenCharArray_whenCallingStringConstructorWithOffsetAndLength_shouldConvertToString() { - char[] charArray = { 'c', 'h', 'a', 'r', 'a', 'c', 't', 'e', 'r' }; - String result = new String(charArray, 4, 3); - String expectedValue = "act"; - - assertEquals(expectedValue, result); - } - - @Test - public void givenCharArray_whenCallingStringCopyValueOf_shouldConvertToString() { - char[] charArray = { 'c', 'h', 'a', 'r', 'a', 'c', 't', 'e', 'r' }; - String result = String.copyValueOf(charArray); - String expectedValue = "character"; - - assertEquals(expectedValue, result); - } - - @Test - public void givenCharArray_whenCallingStringCopyValueOfWithOffsetAndLength_shouldConvertToString() { - char[] charArray = { 'c', 'h', 'a', 'r', 'a', 'c', 't', 'e', 'r' }; - String result = String.copyValueOf(charArray, 0, 4); - String expectedValue = "char"; - - assertEquals(expectedValue, result); - } - - @Test - public void givenCharArray_whenCallingStringValueOf_shouldConvertToString() { - char[] charArray = { 'c', 'h', 'a', 'r', 'a', 'c', 't', 'e', 'r' }; - String result = String.valueOf(charArray); - String expectedValue = "character"; - - assertEquals(expectedValue, result); - } - - @Test - public void givenCharArray_whenCallingStringValueOfWithOffsetAndLength_shouldConvertToString() { - char[] charArray = { 'c', 'h', 'a', 'r', 'a', 'c', 't', 'e', 'r' }; - String result = String.valueOf(charArray, 3, 4); - String expectedValue = "ract"; - - assertEquals(expectedValue, result); - } -} diff --git a/java-strings/src/test/java/com/baeldung/StringToCharArrayUnitTest.java b/java-strings/src/test/java/com/baeldung/StringToCharArrayUnitTest.java deleted file mode 100644 index cd996e58e2..0000000000 --- a/java-strings/src/test/java/com/baeldung/StringToCharArrayUnitTest.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.baeldung; - -import static org.junit.Assert.*; - -import org.junit.Test; - -public class StringToCharArrayUnitTest { - - @Test - public void givenString_whenCallingStringToCharArray_shouldConvertToCharArray() { - String givenString = "characters"; - - char[] result = givenString.toCharArray(); - - char[] expectedCharArray = { 'c', 'h', 'a', 'r', 'a', 'c', 't', 'e', 'r', 's' }; - - assertArrayEquals(expectedCharArray, result); - } - -} diff --git a/java-strings/src/test/resources/.gitignore b/java-strings/src/test/resources/.gitignore deleted file mode 100644 index 83c05e60c8..0000000000 --- a/java-strings/src/test/resources/.gitignore +++ /dev/null @@ -1,13 +0,0 @@ -*.class - -#folders# -/target -/neoDb* -/data -/src/main/webapp/WEB-INF/classes -*/META-INF/* - -# Packaged files # -*.jar -*.war -*.ear \ No newline at end of file diff --git a/javaxval/README.md b/javaxval/README.md index c2c392b276..33ce4eae5b 100644 --- a/javaxval/README.md +++ b/javaxval/README.md @@ -9,4 +9,4 @@ This module contains articles about Bean Validation. - [Difference Between @NotNull, @NotEmpty, and @NotBlank Constraints in Bean Validation](https://www.baeldung.com/java-bean-validation-not-null-empty-blank) - [Javax BigDecimal Validation](https://www.baeldung.com/javax-bigdecimal-validation) - [Grouping Javax Validation Constraints](https://www.baeldung.com/javax-validation-groups) -- [Javax Validations for Enums](https://www.baeldung.com/javax-validations-enums) +- [Validations for Enum Types](https://www.baeldung.com/javax-validations-enums) diff --git a/libraries-3/README.md b/libraries-3/README.md new file mode 100644 index 0000000000..a6c6b190ab --- /dev/null +++ b/libraries-3/README.md @@ -0,0 +1,9 @@ +## Libraries-3 + +This module contains articles about various Java libraries. +These are small libraries that are relatively easy to use and do not require any separate module of their own. + +The code examples related to different libraries are each in their own module. + +Remember, for advanced libraries like [Jackson](/jackson) and [JUnit](/testing-modules) we already have separate modules. Please make sure to have a look at the existing modules in such cases. + diff --git a/libraries-3/pom.xml b/libraries-3/pom.xml new file mode 100644 index 0000000000..214e87287d --- /dev/null +++ b/libraries-3/pom.xml @@ -0,0 +1,51 @@ + + + 4.0.0 + libraries-3 + libraries-3 + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + + + + + jboss-public-repository-group + JBoss Public Repository Group + http://repository.jboss.org/nexus/content/groups/public/ + + true + never + + + true + daily + + + + + + + com.beust + jcommander + ${jcommander.version} + + + org.projectlombok + lombok + ${lombok.version} + + + + + 1.78 + 1.18.6 + UTF-8 + 1.8 + 1.8 + + diff --git a/libraries-3/src/main/java/com/baeldung/jcommander/helloworld/HelloWorldApp.java b/libraries-3/src/main/java/com/baeldung/jcommander/helloworld/HelloWorldApp.java new file mode 100644 index 0000000000..56a74ecf21 --- /dev/null +++ b/libraries-3/src/main/java/com/baeldung/jcommander/helloworld/HelloWorldApp.java @@ -0,0 +1,37 @@ +package com.baeldung.jcommander.helloworld; + +import com.beust.jcommander.JCommander; +import com.beust.jcommander.Parameter; + +public class HelloWorldApp { + + /* + * Execute: + * mvn exec:java -Dexec.mainClass=com.baeldung.jcommander.helloworld.HelloWorldApp -q \ + * -Dexec.args="--name JavaWorld" + */ + public static void main(String[] args) { + HelloWorldArgs jArgs = new HelloWorldArgs(); + JCommander helloCmd = JCommander + .newBuilder() + .addObject(jArgs) + .build(); + + helloCmd.parse(args); + System.out.println("Hello " + jArgs.getName()); + } +} + +class HelloWorldArgs { + + @Parameter( + names = "--name", + description = "User name", + required = true + ) + private String name; + + public String getName() { + return name; + } +} diff --git a/libraries-3/src/main/java/com/baeldung/jcommander/usagebilling/UsageBasedBillingApp.java b/libraries-3/src/main/java/com/baeldung/jcommander/usagebilling/UsageBasedBillingApp.java new file mode 100644 index 0000000000..029e7eed01 --- /dev/null +++ b/libraries-3/src/main/java/com/baeldung/jcommander/usagebilling/UsageBasedBillingApp.java @@ -0,0 +1,23 @@ +package com.baeldung.jcommander.usagebilling; + +import com.baeldung.jcommander.usagebilling.cli.UsageBasedBilling; + +public class UsageBasedBillingApp { + + /* + * Entry-point: invokes the cli passing the command-line args + * + * Invoking "Submit" sub-command: + * mvn exec:java \ + -Dexec.mainClass=com.baeldung.jcommander.usagebilling.UsageBasedBillingApp -q \ + -Dexec.args="submit --customer cb898e7a-f2a0-46d2-9a09-531f1cee1839 --subscription subscriptionPQRMN001 --pricing-type PRE_RATED --timestamp 2019-10-03T10:58:00 --quantity 7 --price 24.56" + * + * Invoking "Fetch" sub-command: + * mvn exec:java \ + -Dexec.mainClass=com.baeldung.jcommander.usagebilling.UsageBasedBillingApp -q \ + -Dexec.args="fetch --customer cb898e7a-f2a0-46d2-9a09-531f1cee1839 --subscription subscriptionPQRMN001 subscriptionPQRMN002 subscriptionPQRMN003 --itemized" + */ + public static void main(String[] args) { + new UsageBasedBilling().run(args); + } +} diff --git a/libraries-3/src/main/java/com/baeldung/jcommander/usagebilling/cli/FetchCurrentChargesCommand.java b/libraries-3/src/main/java/com/baeldung/jcommander/usagebilling/cli/FetchCurrentChargesCommand.java new file mode 100644 index 0000000000..ea6b18af53 --- /dev/null +++ b/libraries-3/src/main/java/com/baeldung/jcommander/usagebilling/cli/FetchCurrentChargesCommand.java @@ -0,0 +1,67 @@ +package com.baeldung.jcommander.usagebilling.cli; + +import com.baeldung.jcommander.usagebilling.cli.splitter.ColonParameterSplitter; +import com.baeldung.jcommander.usagebilling.cli.validator.UUIDValidator; +import com.baeldung.jcommander.usagebilling.model.CurrentChargesRequest; +import com.baeldung.jcommander.usagebilling.model.CurrentChargesResponse; +import com.baeldung.jcommander.usagebilling.service.FetchCurrentChargesService; +import com.beust.jcommander.Parameter; +import com.beust.jcommander.Parameters; +import lombok.Getter; + +import java.util.List; + +import static com.baeldung.jcommander.usagebilling.cli.UsageBasedBilling.*; +import static com.baeldung.jcommander.usagebilling.service.FetchCurrentChargesService.getDefault; + +@Parameters( + commandNames = { FETCH_CMD }, + commandDescription = "Fetch charges for a customer in the current month, can be itemized or aggregated" +) +@Getter +class FetchCurrentChargesCommand { + + FetchCurrentChargesCommand() { + } + + private FetchCurrentChargesService service = getDefault(); + + @Parameter(names = "--help", help = true) + private boolean help; + + @Parameter( + names = { "--customer", "-C" }, + description = "Id of the Customer who's using the services", + validateWith = UUIDValidator.class, + order = 1, + required = true + ) + private String customerId; + + @Parameter( + names = { "--subscription", "-S" }, + description = "Filter charges for specific subscription Ids, includes all subscriptions if no value is specified", + variableArity = true, + splitter = ColonParameterSplitter.class, + order = 2 + ) + private List subscriptionIds; + + @Parameter( + names = { "--itemized" }, + description = "Whether the response should contain breakdown by subscription, only aggregate values are returned by default", + order = 3 + ) + private boolean itemized; + + void fetch() { + CurrentChargesRequest req = CurrentChargesRequest.builder() + .customerId(customerId) + .subscriptionIds(subscriptionIds) + .itemized(itemized) + .build(); + + CurrentChargesResponse response = service.fetch(req); + System.out.println(response); + } +} diff --git a/libraries-3/src/main/java/com/baeldung/jcommander/usagebilling/cli/SubmitUsageCommand.java b/libraries-3/src/main/java/com/baeldung/jcommander/usagebilling/cli/SubmitUsageCommand.java new file mode 100644 index 0000000000..d3516b19d3 --- /dev/null +++ b/libraries-3/src/main/java/com/baeldung/jcommander/usagebilling/cli/SubmitUsageCommand.java @@ -0,0 +1,96 @@ +package com.baeldung.jcommander.usagebilling.cli; + +import com.baeldung.jcommander.usagebilling.cli.converter.ISO8601TimestampConverter; +import com.baeldung.jcommander.usagebilling.cli.validator.UUIDValidator; +import com.baeldung.jcommander.usagebilling.model.UsageRequest; +import com.baeldung.jcommander.usagebilling.model.UsageRequest.PricingType; +import com.baeldung.jcommander.usagebilling.service.SubmitUsageService; +import com.beust.jcommander.Parameter; +import com.beust.jcommander.Parameters; +import lombok.Getter; + +import java.math.BigDecimal; +import java.time.Instant; + +import static com.baeldung.jcommander.usagebilling.cli.UsageBasedBilling.*; +import static com.baeldung.jcommander.usagebilling.service.SubmitUsageService.getDefault; + +@Parameters( + commandNames = { SUBMIT_CMD }, + commandDescription = "Submit usage for a given customer and subscription, accepts one usage item" +) +@Getter +class SubmitUsageCommand { + + SubmitUsageCommand() { + } + + private SubmitUsageService service = getDefault(); + + @Parameter(names = "--help", help = true) + private boolean help; + + @Parameter( + names = { "--customer", "-C" }, + description = "Id of the Customer who's using the services", + validateWith = UUIDValidator.class, + order = 1, + required = true + ) + private String customerId; + + @Parameter( + names = { "--subscription", "-S" }, + description = "Id of the Subscription that was purchased", + order = 2, + required = true + ) + private String subscriptionId; + + @Parameter( + names = { "--pricing-type", "-P" }, + description = "Pricing type of the usage reported", + order = 3, + required = true + ) + private PricingType pricingType; + + @Parameter( + names = { "--quantity" }, + description = "Used quantity; reported quantity is added over the billing period", + order = 3, + required = true + ) + private Integer quantity; + + @Parameter( + names = { "--timestamp" }, + description = "Timestamp of the usage event, must lie in the current billing period", + converter = ISO8601TimestampConverter.class, + order = 4, + required = true + ) + private Instant timestamp; + + @Parameter( + names = { "--price" }, + description = "If PRE_RATED, unit price to be applied per unit of usage quantity reported", + order = 5 + ) + private BigDecimal price; + + void submit() { + + UsageRequest req = UsageRequest.builder() + .customerId(customerId) + .subscriptionId(subscriptionId) + .pricingType(pricingType) + .quantity(quantity) + .timestamp(timestamp) + .price(price) + .build(); + + String reqId = service.submit(req); + System.out.println("Generated Request Id for reference: " + reqId); + } +} diff --git a/libraries-3/src/main/java/com/baeldung/jcommander/usagebilling/cli/UsageBasedBilling.java b/libraries-3/src/main/java/com/baeldung/jcommander/usagebilling/cli/UsageBasedBilling.java new file mode 100644 index 0000000000..a531a68644 --- /dev/null +++ b/libraries-3/src/main/java/com/baeldung/jcommander/usagebilling/cli/UsageBasedBilling.java @@ -0,0 +1,80 @@ +package com.baeldung.jcommander.usagebilling.cli; + +import com.beust.jcommander.JCommander; +import com.beust.jcommander.ParameterException; +import com.beust.jcommander.UnixStyleUsageFormatter; + +public class UsageBasedBilling { + + static final String SUBMIT_CMD = "submit"; + static final String FETCH_CMD = "fetch"; + + private JCommander jCommander; + private SubmitUsageCommand submitUsageCmd; + private FetchCurrentChargesCommand fetchChargesCmd; + + public UsageBasedBilling() { + this.submitUsageCmd = new SubmitUsageCommand(); + this.fetchChargesCmd = new FetchCurrentChargesCommand(); + jCommander = JCommander.newBuilder() + .addObject(this) + .addCommand(submitUsageCmd) + .addCommand(fetchChargesCmd) + .build(); + + setUsageFormatter(SUBMIT_CMD); + setUsageFormatter(FETCH_CMD); + } + + public void run(String[] args) { + String parsedCmdStr; + try { + jCommander.parse(args); + parsedCmdStr = jCommander.getParsedCommand(); + + switch (parsedCmdStr) { + case SUBMIT_CMD: + if (submitUsageCmd.isHelp()) { + getSubCommandHandle(SUBMIT_CMD).usage(); + } + System.out.println("Parsing usage request..."); + submitUsageCmd.submit(); + break; + + case FETCH_CMD: + if (fetchChargesCmd.isHelp()) { + getSubCommandHandle(SUBMIT_CMD).usage(); + } + System.out.println("Preparing fetch query..."); + fetchChargesCmd.fetch(); + + break; + + default: + System.err.println("Invalid command: " + parsedCmdStr); + } + } catch (ParameterException e) { + System.err.println(e.getLocalizedMessage()); + parsedCmdStr = jCommander.getParsedCommand(); + if (parsedCmdStr != null) { + getSubCommandHandle(parsedCmdStr).usage(); + } else { + jCommander.usage(); + } + } + } + + private JCommander getSubCommandHandle(String command) { + JCommander cmd = jCommander.getCommands().get(command); + + if (cmd == null) { + System.err.println("Invalid command: " + command); + } + return cmd; + } + + private void setUsageFormatter(String subCommand) { + JCommander cmd = getSubCommandHandle(subCommand); + cmd.setUsageFormatter(new UnixStyleUsageFormatter(cmd)); + } +} diff --git a/libraries-3/src/main/java/com/baeldung/jcommander/usagebilling/cli/converter/ISO8601TimestampConverter.java b/libraries-3/src/main/java/com/baeldung/jcommander/usagebilling/cli/converter/ISO8601TimestampConverter.java new file mode 100644 index 0000000000..e54865a811 --- /dev/null +++ b/libraries-3/src/main/java/com/baeldung/jcommander/usagebilling/cli/converter/ISO8601TimestampConverter.java @@ -0,0 +1,33 @@ +package com.baeldung.jcommander.usagebilling.cli.converter; + +import com.beust.jcommander.ParameterException; +import com.beust.jcommander.converters.BaseConverter; + +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneOffset; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; + +import static java.lang.String.format; + +public class ISO8601TimestampConverter extends BaseConverter { + + private static final DateTimeFormatter TS_FORMATTER = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss"); + + public ISO8601TimestampConverter(String optionName) { + super(optionName); + } + + @Override + public Instant convert(String value) { + try { + return LocalDateTime + .parse(value, TS_FORMATTER) + .atOffset(ZoneOffset.UTC) + .toInstant(); + } catch (DateTimeParseException e) { + throw new ParameterException(getErrorString(value, format("an ISO-8601 formatted timestamp (%s)", TS_FORMATTER.toString()))); + } + } +} diff --git a/libraries-3/src/main/java/com/baeldung/jcommander/usagebilling/cli/splitter/ColonParameterSplitter.java b/libraries-3/src/main/java/com/baeldung/jcommander/usagebilling/cli/splitter/ColonParameterSplitter.java new file mode 100644 index 0000000000..f24c028123 --- /dev/null +++ b/libraries-3/src/main/java/com/baeldung/jcommander/usagebilling/cli/splitter/ColonParameterSplitter.java @@ -0,0 +1,15 @@ +package com.baeldung.jcommander.usagebilling.cli.splitter; + +import com.beust.jcommander.converters.IParameterSplitter; + +import java.util.List; + +import static java.util.Arrays.asList; + +public class ColonParameterSplitter implements IParameterSplitter { + + @Override + public List split(String value) { + return asList(value.split(":")); + } +} diff --git a/libraries-3/src/main/java/com/baeldung/jcommander/usagebilling/cli/validator/UUIDValidator.java b/libraries-3/src/main/java/com/baeldung/jcommander/usagebilling/cli/validator/UUIDValidator.java new file mode 100644 index 0000000000..a72912f7d0 --- /dev/null +++ b/libraries-3/src/main/java/com/baeldung/jcommander/usagebilling/cli/validator/UUIDValidator.java @@ -0,0 +1,26 @@ +package com.baeldung.jcommander.usagebilling.cli.validator; + +import com.beust.jcommander.IParameterValidator; +import com.beust.jcommander.ParameterException; + +import java.util.regex.Pattern; + +public class UUIDValidator implements IParameterValidator { + + private static final String UUID_REGEX = + "[0-9a-fA-F]{8}(-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}"; + + @Override + public void validate(String name, String value) throws ParameterException { + if (!isValidUUID(value)) { + throw new ParameterException( + "String parameter " + value + " is not a valid UUID."); + } + } + + private boolean isValidUUID(String value) { + return Pattern + .compile(UUID_REGEX) + .matcher(value).matches(); + } +} diff --git a/libraries-3/src/main/java/com/baeldung/jcommander/usagebilling/model/CurrentChargesRequest.java b/libraries-3/src/main/java/com/baeldung/jcommander/usagebilling/model/CurrentChargesRequest.java new file mode 100644 index 0000000000..93dd7a5732 --- /dev/null +++ b/libraries-3/src/main/java/com/baeldung/jcommander/usagebilling/model/CurrentChargesRequest.java @@ -0,0 +1,16 @@ +package com.baeldung.jcommander.usagebilling.model; + +import lombok.*; + +import java.util.List; + +@NoArgsConstructor(access = AccessLevel.PACKAGE) +@AllArgsConstructor(access = AccessLevel.PACKAGE) +@Builder +@Getter +public class CurrentChargesRequest { + + private String customerId; + private List subscriptionIds; + private boolean itemized; +} diff --git a/libraries-3/src/main/java/com/baeldung/jcommander/usagebilling/model/CurrentChargesResponse.java b/libraries-3/src/main/java/com/baeldung/jcommander/usagebilling/model/CurrentChargesResponse.java new file mode 100644 index 0000000000..865a6e4a3d --- /dev/null +++ b/libraries-3/src/main/java/com/baeldung/jcommander/usagebilling/model/CurrentChargesResponse.java @@ -0,0 +1,56 @@ +package com.baeldung.jcommander.usagebilling.model; + +import lombok.*; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.List; + +@NoArgsConstructor(access = AccessLevel.PACKAGE) +@AllArgsConstructor(access = AccessLevel.PACKAGE) +@Builder +@Getter +public class CurrentChargesResponse { + + private String customerId; + private BigDecimal amountDue; + private List lineItems; + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb + .append("Current Month Charges: {") + .append("\n\tcustomer: ") + .append(this.customerId) + .append("\n\ttotalAmountDue: ") + .append(this.amountDue.setScale(2, RoundingMode.HALF_UP)) + .append("\n\tlineItems: ["); + + for (LineItem li : this.lineItems) { + sb + .append("\n\t\t{") + .append("\n\t\t\tsubscription: ") + .append(li.subscriptionId) + .append("\n\t\t\tamount: ") + .append(li.amount.setScale(2, RoundingMode.HALF_UP)) + .append("\n\t\t\tquantity: ") + .append(li.quantity) + .append("\n\t\t},"); + } + + sb.append("\n\t]\n}\n"); + return sb.toString(); + } + + @NoArgsConstructor(access = AccessLevel.PACKAGE) + @AllArgsConstructor(access = AccessLevel.PACKAGE) + @Builder + @Getter + public static class LineItem { + + private String subscriptionId; + private BigDecimal amount; + private Integer quantity; + } +} diff --git a/libraries-3/src/main/java/com/baeldung/jcommander/usagebilling/model/UsageRequest.java b/libraries-3/src/main/java/com/baeldung/jcommander/usagebilling/model/UsageRequest.java new file mode 100644 index 0000000000..2785474acf --- /dev/null +++ b/libraries-3/src/main/java/com/baeldung/jcommander/usagebilling/model/UsageRequest.java @@ -0,0 +1,50 @@ +package com.baeldung.jcommander.usagebilling.model; + +import lombok.*; + +import java.math.BigDecimal; +import java.time.Instant; + +@NoArgsConstructor(access = AccessLevel.PACKAGE) +@AllArgsConstructor(access = AccessLevel.PACKAGE) +@Builder +@Getter +public class UsageRequest { + + private String customerId; + private String subscriptionId; + private PricingType pricingType; + private Integer quantity; + private BigDecimal price; + private Instant timestamp; + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb + .append("\nUsage: {") + .append("\n\tcustomer: ") + .append(this.customerId) + .append("\n\tsubscription: ") + .append(this.subscriptionId) + .append("\n\tquantity: ") + .append(this.quantity) + .append("\n\ttimestamp: ") + .append(this.timestamp) + .append("\n\tpricingType: ") + .append(this.pricingType); + + if (PricingType.PRE_RATED == this.pricingType) { + sb + .append("\n\tpreRatedAt: ") + .append(this.price); + } + + sb.append("\n}\n"); + return sb.toString(); + } + + public enum PricingType { + PRE_RATED, UNRATED + } +} diff --git a/libraries-3/src/main/java/com/baeldung/jcommander/usagebilling/service/DefaultFetchCurrentChargesService.java b/libraries-3/src/main/java/com/baeldung/jcommander/usagebilling/service/DefaultFetchCurrentChargesService.java new file mode 100644 index 0000000000..6436d49875 --- /dev/null +++ b/libraries-3/src/main/java/com/baeldung/jcommander/usagebilling/service/DefaultFetchCurrentChargesService.java @@ -0,0 +1,68 @@ +package com.baeldung.jcommander.usagebilling.service; + +import com.baeldung.jcommander.usagebilling.model.CurrentChargesRequest; +import com.baeldung.jcommander.usagebilling.model.CurrentChargesResponse; +import com.baeldung.jcommander.usagebilling.model.CurrentChargesResponse.LineItem; + +import java.math.BigDecimal; +import java.util.List; +import java.util.UUID; + +import static java.lang.String.format; +import static java.util.Arrays.asList; +import static java.util.Arrays.fill; +import static java.util.Collections.emptyList; +import static java.util.concurrent.ThreadLocalRandom.current; +import static java.util.stream.Collectors.toList; + +class DefaultFetchCurrentChargesService implements FetchCurrentChargesService { + + @Override + public CurrentChargesResponse fetch(CurrentChargesRequest request) { + List subscriptions = request.getSubscriptionIds(); + + if (subscriptions == null || subscriptions.isEmpty()) { + System.out.println("Fetching ALL charges for customer: " + request.getCustomerId()); + subscriptions = mockSubscriptions(); + + } else { + System.out.println(format("Fetching charges for customer: %s and subscriptions: %s", request.getCustomerId(), subscriptions)); + } + + CurrentChargesResponse charges = mockCharges(request.getCustomerId(), subscriptions, request.isItemized()); + System.out.println("Fetched charges..."); + return charges; + } + + private CurrentChargesResponse mockCharges(String customerId, List subscriptions, boolean itemized) { + List lineItems = mockLineItems(subscriptions); + BigDecimal amountDue = lineItems + .stream() + .map(li -> li.getAmount()) + .reduce(new BigDecimal("0"), BigDecimal::add); + + return CurrentChargesResponse + .builder() + .customerId(customerId) + .lineItems(itemized ? lineItems : emptyList()) + .amountDue(amountDue) + .build(); + } + + private List mockLineItems(List subscriptions) { + return subscriptions + .stream() + .map(subscription -> LineItem.builder() + .subscriptionId(subscription) + .quantity(current().nextInt(20)) + .amount(new BigDecimal(current().nextDouble(1_000))) + .build()) + .collect(toList()); + } + + private List mockSubscriptions() { + String[] subscriptions = new String[5]; + fill(subscriptions, UUID.randomUUID().toString()); + return asList(subscriptions); + } +} diff --git a/libraries-3/src/main/java/com/baeldung/jcommander/usagebilling/service/DefaultSubmitUsageService.java b/libraries-3/src/main/java/com/baeldung/jcommander/usagebilling/service/DefaultSubmitUsageService.java new file mode 100644 index 0000000000..44ac9e9ed7 --- /dev/null +++ b/libraries-3/src/main/java/com/baeldung/jcommander/usagebilling/service/DefaultSubmitUsageService.java @@ -0,0 +1,16 @@ +package com.baeldung.jcommander.usagebilling.service; + +import com.baeldung.jcommander.usagebilling.model.UsageRequest; + +import java.util.UUID; + +class DefaultSubmitUsageService implements SubmitUsageService { + + @Override + public String submit(UsageRequest request) { + System.out.println("Submitting usage..." + request); + + System.out.println("Submitted usage successfully..."); + return UUID.randomUUID().toString(); + } +} diff --git a/libraries-3/src/main/java/com/baeldung/jcommander/usagebilling/service/FetchCurrentChargesService.java b/libraries-3/src/main/java/com/baeldung/jcommander/usagebilling/service/FetchCurrentChargesService.java new file mode 100644 index 0000000000..2cc56658ff --- /dev/null +++ b/libraries-3/src/main/java/com/baeldung/jcommander/usagebilling/service/FetchCurrentChargesService.java @@ -0,0 +1,13 @@ +package com.baeldung.jcommander.usagebilling.service; + +import com.baeldung.jcommander.usagebilling.model.CurrentChargesRequest; +import com.baeldung.jcommander.usagebilling.model.CurrentChargesResponse; + +public interface FetchCurrentChargesService { + + static FetchCurrentChargesService getDefault() { + return new DefaultFetchCurrentChargesService(); + } + + CurrentChargesResponse fetch(CurrentChargesRequest request); +} diff --git a/libraries-3/src/main/java/com/baeldung/jcommander/usagebilling/service/SubmitUsageService.java b/libraries-3/src/main/java/com/baeldung/jcommander/usagebilling/service/SubmitUsageService.java new file mode 100644 index 0000000000..2a29e6e474 --- /dev/null +++ b/libraries-3/src/main/java/com/baeldung/jcommander/usagebilling/service/SubmitUsageService.java @@ -0,0 +1,12 @@ +package com.baeldung.jcommander.usagebilling.service; + +import com.baeldung.jcommander.usagebilling.model.UsageRequest; + +public interface SubmitUsageService { + + static SubmitUsageService getDefault() { + return new DefaultSubmitUsageService(); + } + + String submit(UsageRequest request); +} diff --git a/libraries-3/src/test/java/com/baeldung/jcommander/helloworld/HelloWorldAppUnitTest.java b/libraries-3/src/test/java/com/baeldung/jcommander/helloworld/HelloWorldAppUnitTest.java new file mode 100644 index 0000000000..48b3ac2896 --- /dev/null +++ b/libraries-3/src/test/java/com/baeldung/jcommander/helloworld/HelloWorldAppUnitTest.java @@ -0,0 +1,28 @@ +package com.baeldung.jcommander.helloworld; + +import com.beust.jcommander.JCommander; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class HelloWorldAppUnitTest { + + @Test + public void whenJCommanderInvokedWithArgs_thenArgsParsed() { + + HelloWorldArgs jArgs = new HelloWorldArgs(); + JCommander helloCmd = JCommander + .newBuilder() + .addObject(jArgs) + .build(); + + // when + String[] argv = new String[] { + "--name", "JavaWorld" + }; + helloCmd.parse(argv); + + // then + assertEquals("JavaWorld", jArgs.getName()); + } +} diff --git a/libraries-3/src/test/java/com/baeldung/jcommander/usagebilling/cli/FetchCurrentChargesCommandUnitTest.java b/libraries-3/src/test/java/com/baeldung/jcommander/usagebilling/cli/FetchCurrentChargesCommandUnitTest.java new file mode 100644 index 0000000000..b639661c39 --- /dev/null +++ b/libraries-3/src/test/java/com/baeldung/jcommander/usagebilling/cli/FetchCurrentChargesCommandUnitTest.java @@ -0,0 +1,61 @@ +package com.baeldung.jcommander.usagebilling.cli; + +import com.beust.jcommander.JCommander; +import org.junit.Test; + +import static org.hamcrest.collection.IsIterableContainingInOrder.contains; +import static org.junit.Assert.assertThat; + +public class FetchCurrentChargesCommandUnitTest { + + private JCommander jc = JCommander.newBuilder() + .addObject(new FetchCurrentChargesCommand()) + .build(); + + @Test + public void whenParsedMultipleSubscriptionsParameter_thenParameterSubscriptionsIsPopulated() { + FetchCurrentChargesCommand cmd = (FetchCurrentChargesCommand) jc + .getObjects() + .get(0); + + jc.parse(new String[] { + "-C", "cb898e7a-f2a0-46d2-9a09-531f1cee1839", + "-S", "subscriptionA001", + "-S", "subscriptionA002", + "-S", "subscriptionA003", + }); + + assertThat(cmd.getSubscriptionIds(), + contains("subscriptionA001", "subscriptionA002", "subscriptionA003")); + } + + @Test + public void whenParsedSubscriptionsColonSeparatedParameter_thenParameterSubscriptionsIsPopulated() { + FetchCurrentChargesCommand cmd = (FetchCurrentChargesCommand) jc + .getObjects() + .get(0); + + jc.parse(new String[] { + "-C", "cb898e7a-f2a0-46d2-9a09-531f1cee1839", + "-S", "subscriptionA001:subscriptionA002:subscriptionA003", + }); + + assertThat(cmd.getSubscriptionIds(), + contains("subscriptionA001", "subscriptionA002", "subscriptionA003")); + } + + @Test + public void whenParsedSubscriptionsWithVariableArity_thenParameterSubscriptionsIsPopulated() { + FetchCurrentChargesCommand cmd = (FetchCurrentChargesCommand) jc + .getObjects() + .get(0); + + jc.parse(new String[] { + "-C", "cb898e7a-f2a0-46d2-9a09-531f1cee1839", + "-S", "subscriptionA001", "subscriptionA002", "subscriptionA003", + }); + + assertThat(cmd.getSubscriptionIds(), + contains("subscriptionA001", "subscriptionA002", "subscriptionA003")); + } +} diff --git a/libraries-3/src/test/java/com/baeldung/jcommander/usagebilling/cli/SubmitUsageCommandUnitTest.java b/libraries-3/src/test/java/com/baeldung/jcommander/usagebilling/cli/SubmitUsageCommandUnitTest.java new file mode 100644 index 0000000000..d6ce132053 --- /dev/null +++ b/libraries-3/src/test/java/com/baeldung/jcommander/usagebilling/cli/SubmitUsageCommandUnitTest.java @@ -0,0 +1,64 @@ +package com.baeldung.jcommander.usagebilling.cli; + +import com.beust.jcommander.JCommander; +import com.beust.jcommander.ParameterException; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class SubmitUsageCommandUnitTest { + + private JCommander jc = JCommander.newBuilder() + .addObject(new SubmitUsageCommand()) + .build(); + + @Test + public void whenParsedCustomerParameter_thenParameterOfTypeStringIsPopulated() { + jc.parse(new String[] { + "--customer", "cb898e7a-f2a0-46d2-9a09-531f1cee1839", + "--subscription", "subscriptionPQRMN001", + "--pricing-type", "PRE_RATED", + "--timestamp", "2019-10-03T10:58:00", + "--quantity", "7", + "--price", "24.56" + }); + + SubmitUsageCommand cmd = (SubmitUsageCommand) jc + .getObjects() + .get(0); + assertEquals("cb898e7a-f2a0-46d2-9a09-531f1cee1839", cmd.getCustomerId()); + } + + @Test + public void whenParsedTimestampParameter_thenParameterOfTypeInstantIsPopulated() { + jc.parse(new String[] { + "--customer", "cb898e7a-f2a0-46d2-9a09-531f1cee1839", + "--subscription", "subscriptionPQRMN001", + "--pricing-type", "PRE_RATED", + "--timestamp", "2019-10-03T10:58:00", + "--quantity", "7", + "--price", "24.56" + }); + + SubmitUsageCommand cmd = (SubmitUsageCommand) jc + .getObjects() + .get(0); + assertEquals("2019-10-03T10:58:00Z", cmd + .getTimestamp() + .toString()); + } + + @Test(expected = ParameterException.class) + public void whenParsedCustomerIdNotUUID_thenParameterException() { + jc.parse(new String[] { + "--customer", "customer001", + "--subscription", "subscriptionPQRMN001", + "--pricing-type", "PRE_RATED", + "--timestamp", "2019-10-03T10:58:00", + "--quantity", "7", + "--price", "24.56" + }); + } +} diff --git a/linux-bash/command-line-arguments/src/main/bash/userReg-flags.sh b/linux-bash/command-line-arguments/src/main/bash/userReg-flags.sh new file mode 100644 index 0000000000..b2b4589d03 --- /dev/null +++ b/linux-bash/command-line-arguments/src/main/bash/userReg-flags.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +while getopts u:a:f: flag +do +case "${flag}" +in +u) username=${OPTARG};; +a) age=${OPTARG};; +f) fullname=${OPTARG};; +esac +done +echo "Username: $username"; +echo "Age: $age"; +echo "Full Name: $fullname"; diff --git a/linux-bash/command-line-arguments/src/main/bash/userReg-positional-parameter.sh b/linux-bash/command-line-arguments/src/main/bash/userReg-positional-parameter.sh new file mode 100644 index 0000000000..7071ff56d4 --- /dev/null +++ b/linux-bash/command-line-arguments/src/main/bash/userReg-positional-parameter.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +echo "Username: $1"; +echo "Age: $2"; +echo "Full Name: $3"; diff --git a/linux-bash/command-line-arguments/src/main/bash/users-loop.sh b/linux-bash/command-line-arguments/src/main/bash/users-loop.sh new file mode 100644 index 0000000000..545416f3e0 --- /dev/null +++ b/linux-bash/command-line-arguments/src/main/bash/users-loop.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +i=1; +for user in "$@" +do +echo "Username - $i: $user"; +i=$((i + 1)); +done diff --git a/linux-bash/command-line-arguments/src/main/bash/users-shift-operator.sh b/linux-bash/command-line-arguments/src/main/bash/users-shift-operator.sh new file mode 100644 index 0000000000..a212b62317 --- /dev/null +++ b/linux-bash/command-line-arguments/src/main/bash/users-shift-operator.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +i=1; +j=$#; +while [ $i -le $j ] +do +echo "Username - $i: $1"; +i=$((i + 1)); +shift 1; +done diff --git a/linux-bash/json/src/main/bash/fruit.json b/linux-bash/json/src/main/bash/fruit.json new file mode 100644 index 0000000000..392d2290ae --- /dev/null +++ b/linux-bash/json/src/main/bash/fruit.json @@ -0,0 +1 @@ +{"fruit":{"name":"apple","color":"green","price":1.20}} diff --git a/linux-bash/json/src/main/bash/fruits.json b/linux-bash/json/src/main/bash/fruits.json new file mode 100644 index 0000000000..114a9a35cc --- /dev/null +++ b/linux-bash/json/src/main/bash/fruits.json @@ -0,0 +1,17 @@ +[ + { + "name": "apple", + "color": "green", + "price": 1.2 + }, + { + "name": "banana", + "color": "yellow", + "price": 0.5 + }, + { + "name": "kiwi", + "color": "green", + "price": 1.25 + } +] diff --git a/linux-bash/json/src/main/bash/jq.sh b/linux-bash/json/src/main/bash/jq.sh new file mode 100755 index 0000000000..786be304db --- /dev/null +++ b/linux-bash/json/src/main/bash/jq.sh @@ -0,0 +1,56 @@ +#!/bin/bash + +#3.1. Beautify JSON +echo '{"fruit":{"name":"apple","color":"green","price":1.20}}' | jq '.' +jq '.' fruit.json +curl http://api.open-notify.org/iss-now.json | jq '.' + +#3.2. Accessing Properties +jq '.fruit' fruit.json +jq '.fruit.color' fruit.json +jq '.fruit.color,.fruit.price' fruit.json +echo '{ "with space": "hello" }' | jq '."with space"' + +#4.1. Iteration +echo '["x","y","z"]' | jq '.[]' +jq '.[] | .name' fruits.json +jq '.[].name' fruits.json + +#4.2. Accessing By Index +jq '.[1].price' fruits.json + +#4.3. Slicing +echo '[1,2,3,4,5,6,7,8,9,10]' | jq '.[6:9]' +echo '[1,2,3,4,5,6,7,8,9,10]' | jq '.[:6]' | jq '.[-2:]' + +#5.1. Getting Keys +jq '.fruit | keys' fruit.json + +#5.2. Returning the Length +jq '.fruit | length' fruit.json +jq '.fruit.name | length' fruit.json + +#5.3. Mapping Values +jq 'map(has("name"))' fruits.json +jq 'map(.price+2)' fruits.json + +#5.4. Min and Max +jq '[.[].price] | min' fruits.json +jq '[.[].price] | max' fruits.json + +#5.5. Selecting Values +jq '.[] | select(.price>0.5)' fruits.json +jq '.[] | select(.color=="yellow")' fruits.json +jq '.[] | select(.color=="yellow" and .price>=0.5)' fruits.json + +#5.6. Support For RegEx +jq '.[] | select(.name|test("^a.")) | .price' fruits.json + +#5.7. Find Unique Values +jq 'map(.color) | unique' fruits.json + +#5.8. Deleting Keys From JSON +jq 'del(.fruit.name)' fruit.json + +# 6. Transforming +jq '.query.pages | [.[] | map(.) | .[] | {page_title: .title, page_description: .extract}]' wikipedia.json diff --git a/linux-bash/json/src/main/bash/wikipedia.json b/linux-bash/json/src/main/bash/wikipedia.json new file mode 100644 index 0000000000..180b160bcc --- /dev/null +++ b/linux-bash/json/src/main/bash/wikipedia.json @@ -0,0 +1,22 @@ +{ + "query": { + "pages": [ + { + "21721040": { + "pageid": 21721040, + "ns": 0, + "title": "Stack Overflow", + "extract": "Some interesting text about Stack Overflow" + } + }, + { + "21721041": { + "pageid": 21721041, + "ns": 0, + "title": "Baeldung", + "extract": "A great place to learn about Java" + } + } + ] + } +} diff --git a/lombok/pom.xml b/lombok/pom.xml index 2acf9e240d..5e2ad33f66 100644 --- a/lombok/pom.xml +++ b/lombok/pom.xml @@ -76,11 +76,12 @@ - 1.18.4 + 1.18.10 + 1.0.0.Final - 1.18.4.0 + 1.18.10.0 3.8.0 diff --git a/lombok/src/main/java/com/baeldung/lombok/accessors/model/BasicAccount.java b/lombok/src/main/java/com/baeldung/lombok/accessors/model/BasicAccount.java new file mode 100644 index 0000000000..a9332735c7 --- /dev/null +++ b/lombok/src/main/java/com/baeldung/lombok/accessors/model/BasicAccount.java @@ -0,0 +1,24 @@ +package com.baeldung.lombok.accessors.model; + +import java.math.BigDecimal; + +public class BasicAccount { + private String name; + private BigDecimal balance; + + public BigDecimal getBalance() { + return this.balance; + } + + public void setBalance(BigDecimal newBalance) { + this.balance = newBalance; + } + + public String getName() { + return this.name; + } + + public void setName(String accountName) { + this.name = accountName; + } +} diff --git a/lombok/src/main/java/com/baeldung/lombok/accessors/model/ChainedAccount.java b/lombok/src/main/java/com/baeldung/lombok/accessors/model/ChainedAccount.java new file mode 100644 index 0000000000..0437d8f60e --- /dev/null +++ b/lombok/src/main/java/com/baeldung/lombok/accessors/model/ChainedAccount.java @@ -0,0 +1,15 @@ +package com.baeldung.lombok.accessors.model; + +import lombok.Getter; +import lombok.Setter; +import lombok.experimental.Accessors; + +import java.math.BigDecimal; + +@Accessors(chain = true) +@Getter +@Setter +public class ChainedAccount { + private String name; + private BigDecimal balance; +} diff --git a/lombok/src/main/java/com/baeldung/lombok/accessors/model/ChainedFluentAccount.java b/lombok/src/main/java/com/baeldung/lombok/accessors/model/ChainedFluentAccount.java new file mode 100644 index 0000000000..6ebc080c94 --- /dev/null +++ b/lombok/src/main/java/com/baeldung/lombok/accessors/model/ChainedFluentAccount.java @@ -0,0 +1,15 @@ +package com.baeldung.lombok.accessors.model; + +import lombok.Getter; +import lombok.Setter; +import lombok.experimental.Accessors; + +import java.math.BigDecimal; + +@Accessors(fluent = true, chain = true) +@Getter +@Setter +public class ChainedFluentAccount { + private String name; + private BigDecimal balance; +} diff --git a/lombok/src/main/java/com/baeldung/lombok/accessors/model/FluentAccount.java b/lombok/src/main/java/com/baeldung/lombok/accessors/model/FluentAccount.java new file mode 100644 index 0000000000..4c2e1f7976 --- /dev/null +++ b/lombok/src/main/java/com/baeldung/lombok/accessors/model/FluentAccount.java @@ -0,0 +1,15 @@ +package com.baeldung.lombok.accessors.model; + +import lombok.Getter; +import lombok.Setter; +import lombok.experimental.Accessors; + +import java.math.BigDecimal; + +@Accessors(fluent = true, chain = false) +@Getter +@Setter +public class FluentAccount { + private String name; + private BigDecimal balance; +} diff --git a/lombok/src/main/java/com/baeldung/lombok/accessors/model/PrefixedAccount.java b/lombok/src/main/java/com/baeldung/lombok/accessors/model/PrefixedAccount.java new file mode 100644 index 0000000000..506d7adc75 --- /dev/null +++ b/lombok/src/main/java/com/baeldung/lombok/accessors/model/PrefixedAccount.java @@ -0,0 +1,20 @@ +package com.baeldung.lombok.accessors.model; + +import lombok.Getter; +import lombok.Setter; +import lombok.experimental.Accessors; + +import java.math.BigDecimal; + + +@Accessors(prefix = {"s", "bd"}) +@Getter +@Setter +public class PrefixedAccount { + private String sName; + private BigDecimal bdBalance; + + @Accessors(prefix = "s_") + private String s_notes; + +} diff --git a/lombok/src/main/java/com/baeldung/lombok/accessors/model/PrefixedFluentAccount.java b/lombok/src/main/java/com/baeldung/lombok/accessors/model/PrefixedFluentAccount.java new file mode 100644 index 0000000000..eb23bf58e2 --- /dev/null +++ b/lombok/src/main/java/com/baeldung/lombok/accessors/model/PrefixedFluentAccount.java @@ -0,0 +1,15 @@ +package com.baeldung.lombok.accessors.model; + +import lombok.Getter; +import lombok.Setter; +import lombok.experimental.Accessors; + +import java.math.BigDecimal; + +@Accessors(prefix = {"s", "bd"}, fluent = true) +@Getter +@Setter +public class PrefixedFluentAccount { + private String sName; + private BigDecimal bdBalance; +} diff --git a/lombok/src/main/java/com/baeldung/lombok/accessors/model/StandardAccount.java b/lombok/src/main/java/com/baeldung/lombok/accessors/model/StandardAccount.java new file mode 100644 index 0000000000..4d0d578a4d --- /dev/null +++ b/lombok/src/main/java/com/baeldung/lombok/accessors/model/StandardAccount.java @@ -0,0 +1,13 @@ +package com.baeldung.lombok.accessors.model; + +import lombok.Getter; +import lombok.Setter; + +import java.math.BigDecimal; + +@Getter +@Setter +public class StandardAccount { + private String name; + private BigDecimal balance; +} diff --git a/lombok/src/test/java/com/baeldung/lombok/accessors/AccessorsUnitTest.java b/lombok/src/test/java/com/baeldung/lombok/accessors/AccessorsUnitTest.java new file mode 100644 index 0000000000..04f38bfc32 --- /dev/null +++ b/lombok/src/test/java/com/baeldung/lombok/accessors/AccessorsUnitTest.java @@ -0,0 +1,74 @@ +package com.baeldung.lombok.accessors; + +import com.baeldung.lombok.accessors.model.*; +import org.junit.Test; + +import java.math.BigDecimal; + +import static org.junit.Assert.assertEquals; + +public class AccessorsUnitTest { + + @Test + public void givenBasicAccount_thenUseBasicAccessors() { + BasicAccount account = new BasicAccount(); + account.setName("Basic Accessors"); + account.setBalance(BigDecimal.TEN); + + assertEquals("Basic Accessors", account.getName()); + assertEquals(BigDecimal.TEN, account.getBalance()); + } + + @Test + public void givenFluentAccount_thenUseFluentAccessors() { + FluentAccount account = new FluentAccount(); + account.name("Fluent Account"); + account.balance(BigDecimal.TEN); + + assertEquals("Fluent Account", account.name()); + assertEquals(BigDecimal.TEN, account.balance()); + } + + @Test + public void givenChainedAccount_thenUseChainedAccessors() { + ChainedAccount account = new ChainedAccount(); + account.setName("Chained Account").setBalance(BigDecimal.TEN); + + assertEquals("Chained Account", account.getName()); + assertEquals(BigDecimal.TEN, account.getBalance()); + } + + @Test + public void givenChainedFluentAccount_thenUseChainedFluentAccessors() { + ChainedFluentAccount account = new ChainedFluentAccount() + .name("Fluent Account") + .balance(BigDecimal.TEN); + + assertEquals("Fluent Account", account.name()); + assertEquals(BigDecimal.TEN, account.balance()); + } + + @Test + public void givenPrefixedAccount_thenRemovePrefixFromAccessors() { + PrefixedAccount account = new PrefixedAccount(); + account.setName("Prefixed Fields"); + account.setBalance(BigDecimal.TEN); + account.setNotes("Notes"); + + assertEquals("Prefixed Fields", account.getName()); + assertEquals(BigDecimal.TEN, account.getBalance()); + assertEquals("Notes", account.getNotes()); + } + + @Test + public void givenPrefixedFluentAccount_thenRemovePrefixFromAccessors() { + PrefixedFluentAccount account = new PrefixedFluentAccount(); + account + .name("Prefixed Fluent Fields") + .balance(BigDecimal.TEN); + + assertEquals("Prefixed Fluent Fields", account.name()); + assertEquals(BigDecimal.TEN, account.balance()); + } + +} diff --git a/mapstruct/README.md b/mapstruct/README.md index f5a1e1a092..9887a7f43d 100644 --- a/mapstruct/README.md +++ b/mapstruct/README.md @@ -2,7 +2,8 @@ This module contains articles about MapStruct. -###Relevant Articles: +### Relevant Articles: + - [Quick Guide to MapStruct](https://www.baeldung.com/mapstruct) - [Custom Mapper with MapStruct](https://www.baeldung.com/mapstruct-custom-mapper) - [Using Multiple Source Objects with MapStruct](https://www.baeldung.com/mapstruct-multiple-source-objects) diff --git a/patterns/design-patterns-creational/README.md b/patterns/design-patterns-creational/README.md index 99b9b39787..026115a6d6 100644 --- a/patterns/design-patterns-creational/README.md +++ b/patterns/design-patterns-creational/README.md @@ -6,4 +6,5 @@ - [Double-Checked Locking with Singleton](https://www.baeldung.com/java-singleton-double-checked-locking) - [Java Constructors vs Static Factory Methods](https://www.baeldung.com/java-constructors-vs-static-factory-methods) - [Automatic Generation of the Builder Pattern with FreeBuilder](https://www.baeldung.com/java-builder-pattern-freebuilder) -- [How to Replace Many if Statements in Java](https://www.baeldung.com/java-replace-if-statements) \ No newline at end of file +- [How to Replace Many if Statements in Java](https://www.baeldung.com/java-replace-if-statements) +- [Prototype Pattern in Java](https://www.baeldung.com/java-pattern-prototype) diff --git a/persistence-modules/hibernate5-2/README.md b/persistence-modules/hibernate5-2/README.md new file mode 100644 index 0000000000..c61552f305 --- /dev/null +++ b/persistence-modules/hibernate5-2/README.md @@ -0,0 +1,3 @@ +### Relevant Articles: +- [Hibernate Error “Not all named parameters have been set”](https://www.baeldung.com/hibernate-error-named-parameters-not-set) + diff --git a/persistence-modules/hibernate5-2/src/main/java/com/baeldung/fetchMode/Customer.java b/persistence-modules/hibernate5-2/src/main/java/com/baeldung/fetchMode/Customer.java new file mode 100644 index 0000000000..5997602205 --- /dev/null +++ b/persistence-modules/hibernate5-2/src/main/java/com/baeldung/fetchMode/Customer.java @@ -0,0 +1,39 @@ +package com.baeldung.fetchMode; + +import org.hibernate.annotations.Fetch; +import org.hibernate.annotations.FetchMode; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.OneToMany; +import java.util.HashSet; +import java.util.Set; + +@Entity +public class Customer { + + @Id + @GeneratedValue + private Long id; + + @OneToMany(mappedBy = "customer") + @Fetch(value = FetchMode.SELECT) + private Set orders = new HashSet<>(); + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Set getOrders() { + return orders; + } + + public void setOrders(Set orders) { + this.orders = orders; + } +} diff --git a/persistence-modules/hibernate5-2/src/main/java/com/baeldung/fetchMode/Order.java b/persistence-modules/hibernate5-2/src/main/java/com/baeldung/fetchMode/Order.java new file mode 100644 index 0000000000..c031972830 --- /dev/null +++ b/persistence-modules/hibernate5-2/src/main/java/com/baeldung/fetchMode/Order.java @@ -0,0 +1,50 @@ +package com.baeldung.fetchMode; + +import javax.persistence.*; + +@Entity +public class Order { + + @Id + @GeneratedValue + private Long id; + + private String name; + + @ManyToOne + @JoinColumn(name = "customer_id") + private Customer customer; + + public Order() { + + } + + public Order(String name, Customer customer) { + this.name = name; + this.customer = customer; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Customer getCustomer() { + return customer; + } + + public void setCustomer(Customer customer) { + this.customer = customer; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/persistence-modules/spring-data-cassandra-reactive/README.md b/persistence-modules/spring-data-cassandra-reactive/README.md index 87a61d46b3..5352843850 100644 --- a/persistence-modules/spring-data-cassandra-reactive/README.md +++ b/persistence-modules/spring-data-cassandra-reactive/README.md @@ -1,3 +1,3 @@ -#Relevant Articles +### Relevant Articles - [Spring Data with Reactive Cassandra](https://www.baeldung.com/spring-data-cassandra-reactive) diff --git a/persistence-modules/spring-data-jpa-3/README.md b/persistence-modules/spring-data-jpa-3/README.md new file mode 100644 index 0000000000..28e62a9de1 --- /dev/null +++ b/persistence-modules/spring-data-jpa-3/README.md @@ -0,0 +1,3 @@ +### Relevant Articles: +- [Programmatic Transaction Management in Spring](https://www.baeldung.com/spring-programmatic-transaction-management) + diff --git a/persistence-modules/spring-data-jpa-3/pom.xml b/persistence-modules/spring-data-jpa-3/pom.xml index f743fce2a3..32f81d5745 100644 --- a/persistence-modules/spring-data-jpa-3/pom.xml +++ b/persistence-modules/spring-data-jpa-3/pom.xml @@ -18,29 +18,22 @@ + + org.springframework.boot + spring-boot-starter-web + org.springframework.boot spring-boot-starter-data-jpa - org.postgresql - postgresql - ${postgresql.version} + com.h2database + h2 + runtime + ${h2.version} - - org.testcontainers - junit-jupiter - ${testcontainers.version} - test - - - org.testcontainers - postgresql - ${testcontainers.version} - test - org.springframework.boot spring-boot-starter-test @@ -71,8 +64,7 @@ - 1.12.2 - 42.2.8 + 1.4.200 diff --git a/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/tx/Payment.java b/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/model/Payment.java similarity index 97% rename from persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/tx/Payment.java rename to persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/model/Payment.java index 37f3d09381..2c24e5777e 100644 --- a/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/tx/Payment.java +++ b/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/model/Payment.java @@ -1,4 +1,4 @@ -package com.baeldung.tx; +package com.baeldung.model; import javax.persistence.*; diff --git a/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/model/User.java b/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/model/User.java new file mode 100644 index 0000000000..94d0c023f2 --- /dev/null +++ b/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/model/User.java @@ -0,0 +1,42 @@ +package com.baeldung.model; + +import javax.persistence.*; +import java.util.Set; + +@Entity +@Table(name = "users") +public class User { + + @Id + @GeneratedValue + private Long id; + + private String username; + + @ElementCollection + private Set permissions; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public Set getPermissions() { + return permissions; + } + + public void setPermissions(Set permissions) { + this.permissions = permissions; + } +} diff --git a/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/repository/UserRepository.java b/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/repository/UserRepository.java new file mode 100644 index 0000000000..bb3ce781f6 --- /dev/null +++ b/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/repository/UserRepository.java @@ -0,0 +1,17 @@ +package com.baeldung.repository; + +import com.baeldung.model.User; +import org.springframework.data.jpa.repository.EntityGraph; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.Optional; + +public interface UserRepository extends JpaRepository { + + @EntityGraph(attributePaths = "permissions") + Optional findDetailedByUsername(String username); + + Optional findSummaryByUsername(String username); + + Optional findByUsername(String username); +} diff --git a/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/service/SimpleUserService.java b/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/service/SimpleUserService.java new file mode 100644 index 0000000000..6782254f61 --- /dev/null +++ b/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/service/SimpleUserService.java @@ -0,0 +1,24 @@ +package com.baeldung.service; + +import com.baeldung.model.User; +import com.baeldung.repository.UserRepository; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Optional; + +@Service +public class SimpleUserService implements UserService { + + private final UserRepository userRepository; + + public SimpleUserService(UserRepository userRepository) { + this.userRepository = userRepository; + } + + @Override + @Transactional(readOnly = true) + public Optional findOne(String username) { + return userRepository.findDetailedByUsername(username); + } +} diff --git a/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/service/UserService.java b/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/service/UserService.java new file mode 100644 index 0000000000..11b3dc82ce --- /dev/null +++ b/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/service/UserService.java @@ -0,0 +1,9 @@ +package com.baeldung.service; + +import com.baeldung.model.User; + +import java.util.Optional; + +public interface UserService { + Optional findOne(String username); +} diff --git a/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/web/DetailedUserDto.java b/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/web/DetailedUserDto.java new file mode 100644 index 0000000000..0d8fe02b91 --- /dev/null +++ b/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/web/DetailedUserDto.java @@ -0,0 +1,45 @@ +package com.baeldung.web; + +import com.baeldung.model.User; + +import java.util.Set; + +public class DetailedUserDto { + + private Long id; + private String username; + private Set permissions; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public Set getPermissions() { + return permissions; + } + + public void setPermissions(Set permissions) { + this.permissions = permissions; + } + + public static DetailedUserDto fromEntity(User user) { + DetailedUserDto detailed = new DetailedUserDto(); + detailed.setId(user.getId()); + detailed.setUsername(user.getUsername()); + detailed.setPermissions(user.getPermissions()); + + return detailed; + } +} diff --git a/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/web/UserController.java b/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/web/UserController.java new file mode 100644 index 0000000000..867d60cc2f --- /dev/null +++ b/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/web/UserController.java @@ -0,0 +1,27 @@ +package com.baeldung.web; + +import com.baeldung.service.UserService; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/users") +public class UserController { + + private final UserService userService; + + public UserController(UserService userService) { + this.userService = userService; + } + + @GetMapping("/{username}") + public ResponseEntity findOne(@PathVariable String username) { + return userService.findOne(username) + .map(DetailedUserDto::fromEntity) + .map(ResponseEntity::ok) + .orElse(ResponseEntity.notFound().build()); + } +} diff --git a/persistence-modules/spring-data-jpa-3/src/test/java/com/baeldung/osiv/UserControllerIntegrationTest.java b/persistence-modules/spring-data-jpa-3/src/test/java/com/baeldung/osiv/UserControllerIntegrationTest.java new file mode 100644 index 0000000000..ba94fc111b --- /dev/null +++ b/persistence-modules/spring-data-jpa-3/src/test/java/com/baeldung/osiv/UserControllerIntegrationTest.java @@ -0,0 +1,54 @@ +package com.baeldung.osiv; + +import com.baeldung.model.User; +import com.baeldung.repository.UserRepository; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +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.web.servlet.MockMvc; + +import java.util.Arrays; +import java.util.HashSet; + +import static org.hamcrest.Matchers.containsInAnyOrder; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@SpringBootTest +@AutoConfigureMockMvc +@ActiveProfiles("test") +class UserControllerIntegrationTest { + + @Autowired + private UserRepository userRepository; + + @Autowired + private MockMvc mockMvc; + + @BeforeEach + void setUp() { + User user = new User(); + user.setUsername("root"); + user.setPermissions(new HashSet<>(Arrays.asList("PERM_READ", "PERM_WRITE"))); + + userRepository.save(user); + } + + @Test + void givenTheUserExists_WhenOsivIsEnabled_ThenLazyInitWorkEverywhere() throws Exception { + mockMvc.perform(get("/users/root")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.username").value("root")) + .andExpect(jsonPath("$.permissions", containsInAnyOrder("PERM_READ", "PERM_WRITE"))); + } + + @AfterEach + void flushDb() { + userRepository.deleteAll(); + } +} diff --git a/persistence-modules/spring-data-jpa-3/src/test/java/com/baeldung/tx/ManualTransactionIntegrationTest.java b/persistence-modules/spring-data-jpa-3/src/test/java/com/baeldung/tx/ManualTransactionIntegrationTest.java index 62d64d4372..1ce8e91ec5 100644 --- a/persistence-modules/spring-data-jpa-3/src/test/java/com/baeldung/tx/ManualTransactionIntegrationTest.java +++ b/persistence-modules/spring-data-jpa-3/src/test/java/com/baeldung/tx/ManualTransactionIntegrationTest.java @@ -1,10 +1,10 @@ package com.baeldung.tx; +import com.baeldung.model.Payment; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; import org.springframework.test.context.ActiveProfiles; import org.springframework.transaction.PlatformTransactionManager; @@ -14,27 +14,17 @@ import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.support.DefaultTransactionDefinition; import org.springframework.transaction.support.TransactionCallbackWithoutResult; import org.springframework.transaction.support.TransactionTemplate; -import org.testcontainers.containers.PostgreSQLContainer; -import org.testcontainers.junit.jupiter.Container; -import org.testcontainers.junit.jupiter.Testcontainers; import javax.persistence.EntityManager; -import static java.util.Collections.singletonList; import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase.Replace.NONE; import static org.springframework.transaction.annotation.Propagation.NOT_SUPPORTED; @DataJpaTest -@Testcontainers @ActiveProfiles("test") -@AutoConfigureTestDatabase(replace = NONE) @Transactional(propagation = NOT_SUPPORTED) class ManualTransactionIntegrationTest { - @Container - private static PostgreSQLContainer pg = initPostgres(); - @Autowired private PlatformTransactionManager transactionManager; @@ -159,13 +149,4 @@ class ManualTransactionIntegrationTest { .getResultList()).hasSize(1); } - private static PostgreSQLContainer initPostgres() { - PostgreSQLContainer pg = new PostgreSQLContainer<>("postgres:11.1") - .withDatabaseName("baeldung") - .withUsername("test") - .withPassword("test"); - pg.setPortBindings(singletonList("54320:5432")); - - return pg; - } } diff --git a/persistence-modules/spring-data-jpa-3/src/test/resources/application-test.properties b/persistence-modules/spring-data-jpa-3/src/test/resources/application-test.properties index aa7093f751..f9497c8f37 100644 --- a/persistence-modules/spring-data-jpa-3/src/test/resources/application-test.properties +++ b/persistence-modules/spring-data-jpa-3/src/test/resources/application-test.properties @@ -1,4 +1,2 @@ spring.jpa.hibernate.ddl-auto=update -spring.datasource.url=jdbc:postgresql://localhost:54320/baeldung -spring.datasource.username=test -spring.datasource.password=test +spring.datasource.url=jdbc:h2:mem:jpa3 \ No newline at end of file diff --git a/persistence-modules/spring-persistence-simple/README.md b/persistence-modules/spring-persistence-simple/README.md index 8e55a59c7c..db0d0ce83c 100644 --- a/persistence-modules/spring-persistence-simple/README.md +++ b/persistence-modules/spring-persistence-simple/README.md @@ -12,6 +12,7 @@ - [Introduction to Spring Data JPA](http://www.baeldung.com/the-persistence-layer-with-spring-data-jpa) - [Spring Data JPA @Query](http://www.baeldung.com/spring-data-jpa-query) - [Spring JDBC](https://www.baeldung.com/spring-jdbc-jdbctemplate) +- [Transaction Propagation and Isolation in Spring @Transactional](https://www.baeldung.com/spring-transactional-propagation-isolation) ### Eclipse Config After importing the project into Eclipse, you may see the following error: diff --git a/pom.xml b/pom.xml index c91e77ef93..1759273b67 100644 --- a/pom.xml +++ b/pom.xml @@ -1,4 +1,3 @@ - @@ -406,7 +405,7 @@ --> core-java-modules/core-java-text core-java-modules/core-java-lambdas - + core-java-modules/core-java-arrays core-java-modules/core-java-arrays-2 @@ -424,6 +423,7 @@ core-java-modules/core-java-io core-java-modules/core-java-io-files core-java-modules/core-java-nio + core-java-modules/core-java-nio-2 core-java-modules/core-java-security core-java-modules/core-java-exceptions core-java-modules/core-java-lang-syntax @@ -445,6 +445,7 @@ core-java-modules/core-java-string-algorithms core-java-modules/core-java-string-algorithms-2 core-java-modules/core-java-string-apis + core-java-modules/core-java-strings core-java-modules/core-java core-java-modules/core-java-jar core-java-modules/core-java-jvm @@ -508,9 +509,6 @@ java-numbers-2 java-rmi java-spi - java-strings - java-strings-2 - java-strings-ops java-vavr-stream java-websocket javafx @@ -544,6 +542,7 @@ libraries libraries-2 + libraries-3 libraries-data libraries-data-2 libraries-data-db @@ -604,13 +603,15 @@ rule-engines rsocket - rxjava - rxjava-2 + rxjava-core + rxjava-observables + rxjava-operators + rxjava-libraries software-security/sql-injection-samples tensorflow-java spf4j - spring-boot-configuration + spring-boot-config-jpa-error spring-boot-flowable spring-boot-mvc-2 spring-boot-performance @@ -697,7 +698,7 @@ spring-boot-bootstrap spring-boot-camel - spring-boot-configuration + spring-boot-config-jpa-error spring-boot-client spring-boot-crud @@ -722,10 +723,11 @@ spring-boot-parent spring-boot-property-exp spring-boot-security + spring-boot-springdoc spring-boot-testing spring-boot-vue spring-caching - spring-boot-libraries + spring-boot-libraries spring-cloud @@ -922,6 +924,7 @@ spring-boot-keycloak spring-boot-mvc spring-boot-property-exp + spring-boot-springdoc spring-boot-vue spring-cloud spring-cloud/spring-cloud-archaius/basic-config @@ -1180,7 +1183,7 @@ core-java-modules/core-java-time-measurements --> core-java-modules/core-java-text - + core-java-modules/core-java-arrays core-java-modules/core-java-arrays-2 @@ -1198,6 +1201,7 @@ core-java-modules/core-java-io core-java-modules/core-java-io-files core-java-modules/core-java-nio + core-java-modules/core-java-nio-2 core-java-modules/core-java-security core-java-modules/core-java-exceptions core-java-modules/core-java-lang-syntax @@ -1218,6 +1222,7 @@ core-java-modules/core-java-string-algorithms core-java-modules/core-java-string-algorithms-2 core-java-modules/core-java-string-apis + core-java-modules/core-java-strings core-scala couchbase custom-pmd @@ -1278,9 +1283,6 @@ java-numbers-2 java-rmi java-spi - java-strings - java-strings-2 - java-strings-ops java-vavr-stream java-websocket javafx @@ -1312,6 +1314,7 @@ libraries + libraries-3 libraries-data libraries-data-2 libraries-data-db @@ -1370,8 +1373,10 @@ rule-engines rsocket - rxjava - rxjava-2 + rxjava-core + rxjava-observables + rxjava-operators + rxjava-libraries oauth2-framework-impl spf4j spring-boot-performance @@ -1466,8 +1471,9 @@ spring-boot-parent spring-boot-property-exp spring-boot-security + spring-boot-springdoc spring-boot-vue - spring-caching + spring-caching spring-cloud spring-cloud-bus diff --git a/rxjava-2/README.md b/rxjava-2/README.md deleted file mode 100644 index 87f606a323..0000000000 --- a/rxjava-2/README.md +++ /dev/null @@ -1,14 +0,0 @@ -## RxJava - -This module contains articles about RxJava. - -### Relevant articles: - -- [RxJava and Error Handling](https://www.baeldung.com/rxjava-error-handling) -- [RxJava 2 – Flowable](https://www.baeldung.com/rxjava-2-flowable) -- [RxJava Maybe](https://www.baeldung.com/rxjava-maybe) -- [Introduction to RxRelay for RxJava](https://www.baeldung.com/rx-relay) -- [Combining RxJava Completables](https://www.baeldung.com/rxjava-completable) -- [Converting Synchronous and Asynchronous APIs to Observables using RxJava2](https://www.baeldung.com/rxjava-apis-to-observables) -- [RxJava Hooks](https://www.baeldung.com/rxjava-hooks) -- More articles: [[<-- prev]](/rxjava) diff --git a/rxjava-2/pom.xml b/rxjava-2/pom.xml deleted file mode 100644 index 47d16ec8dd..0000000000 --- a/rxjava-2/pom.xml +++ /dev/null @@ -1,53 +0,0 @@ - - - 4.0.0 - rxjava-2 - rxjava-2 - 1.0-SNAPSHOT - - - com.baeldung - parent-java - 0.0.1-SNAPSHOT - ../parent-java - - - - - io.reactivex.rxjava2 - rxjava - ${rx.java2.version} - - - com.jayway.awaitility - awaitility - ${awaitility.version} - - - org.assertj - assertj-core - ${assertj.version} - - - com.jakewharton.rxrelay2 - rxrelay - ${rxrelay.version} - - - - com.github.akarnokd - rxjava2-extensions - ${rxjava2.ext.version} - - - - - 3.8.0 - 2.2.2 - 1.7.0 - 2.0.0 - 0.20.4 - - \ No newline at end of file diff --git a/rxjava-core/README.md b/rxjava-core/README.md new file mode 100644 index 0000000000..2773bd9423 --- /dev/null +++ b/rxjava-core/README.md @@ -0,0 +1,16 @@ +## RxJava + +This module contains articles about RxJava. + +### Relevant articles: + +- [Dealing with Backpressure with RxJava](https://www.baeldung.com/rxjava-backpressure) +- [How to Test RxJava?](https://www.baeldung.com/rxjava-testing) +- [Introduction to RxJava](https://www.baeldung.com/rx-java) +- [Schedulers in RxJava](https://www.baeldung.com/rxjava-schedulers) +- [Difference Between Flatmap and Switchmap in RxJava](https://www.baeldung.com/rxjava-flatmap-switchmap) +- [RxJava and Error Handling](https://www.baeldung.com/rxjava-error-handling) +- [RxJava Maybe](https://www.baeldung.com/rxjava-maybe) +- [Combining RxJava Completables](https://www.baeldung.com/rxjava-completable) +- [RxJava Hooks](https://www.baeldung.com/rxjava-hooks) +- More articles: [[next -->]](/rxjava-2) diff --git a/rxjava-core/pom.xml b/rxjava-core/pom.xml new file mode 100644 index 0000000000..401ad83808 --- /dev/null +++ b/rxjava-core/pom.xml @@ -0,0 +1,46 @@ + + + 4.0.0 + rxjava-core + 1.0-SNAPSHOT + rxjava-core + + + com.baeldung + parent-java + 0.0.1-SNAPSHOT + ../parent-java + + + + + io.reactivex + rxjava + ${rx.java.version} + + + io.reactivex.rxjava2 + rxjava + ${rx.java2.version} + + + com.jayway.awaitility + awaitility + ${awaitility.version} + + + org.assertj + assertj-core + ${assertj.version} + + + + + 3.8.0 + 1.2.5 + 1.7.0 + 2.2.2 + + + \ No newline at end of file diff --git a/rxjava/src/main/java/com/baeldung/rxjava/ComputeFunction.java b/rxjava-core/src/main/java/com/baeldung/rxjava/ComputeFunction.java similarity index 100% rename from rxjava/src/main/java/com/baeldung/rxjava/ComputeFunction.java rename to rxjava-core/src/main/java/com/baeldung/rxjava/ComputeFunction.java diff --git a/rxjava/src/main/java/com/baeldung/rxjava/ConnectableObservableImpl.java b/rxjava-core/src/main/java/com/baeldung/rxjava/ConnectableObservableImpl.java similarity index 100% rename from rxjava/src/main/java/com/baeldung/rxjava/ConnectableObservableImpl.java rename to rxjava-core/src/main/java/com/baeldung/rxjava/ConnectableObservableImpl.java diff --git a/rxjava/src/main/java/com/baeldung/rxjava/ObservableImpl.java b/rxjava-core/src/main/java/com/baeldung/rxjava/ObservableImpl.java similarity index 100% rename from rxjava/src/main/java/com/baeldung/rxjava/ObservableImpl.java rename to rxjava-core/src/main/java/com/baeldung/rxjava/ObservableImpl.java diff --git a/rxjava/src/main/java/com/baeldung/rxjava/ResourceManagement.java b/rxjava-core/src/main/java/com/baeldung/rxjava/ResourceManagement.java similarity index 100% rename from rxjava/src/main/java/com/baeldung/rxjava/ResourceManagement.java rename to rxjava-core/src/main/java/com/baeldung/rxjava/ResourceManagement.java diff --git a/rxjava/src/main/java/com/baeldung/rxjava/SingleImpl.java b/rxjava-core/src/main/java/com/baeldung/rxjava/SingleImpl.java similarity index 100% rename from rxjava/src/main/java/com/baeldung/rxjava/SingleImpl.java rename to rxjava-core/src/main/java/com/baeldung/rxjava/SingleImpl.java diff --git a/rxjava/src/main/java/com/baeldung/rxjava/SubjectImpl.java b/rxjava-core/src/main/java/com/baeldung/rxjava/SubjectImpl.java similarity index 100% rename from rxjava/src/main/java/com/baeldung/rxjava/SubjectImpl.java rename to rxjava-core/src/main/java/com/baeldung/rxjava/SubjectImpl.java diff --git a/java-strings-ops/src/main/resources/logback.xml b/rxjava-core/src/main/resources/logback.xml similarity index 100% rename from java-strings-ops/src/main/resources/logback.xml rename to rxjava-core/src/main/resources/logback.xml diff --git a/rxjava-2/src/test/java/com/baeldung/rxjava/CompletableUnitTest.java b/rxjava-core/src/test/java/com/baeldung/rxjava/CompletableUnitTest.java similarity index 100% rename from rxjava-2/src/test/java/com/baeldung/rxjava/CompletableUnitTest.java rename to rxjava-core/src/test/java/com/baeldung/rxjava/CompletableUnitTest.java diff --git a/rxjava/src/test/java/com/baeldung/rxjava/ConnectableObservableIntegrationTest.java b/rxjava-core/src/test/java/com/baeldung/rxjava/ConnectableObservableIntegrationTest.java similarity index 100% rename from rxjava/src/test/java/com/baeldung/rxjava/ConnectableObservableIntegrationTest.java rename to rxjava-core/src/test/java/com/baeldung/rxjava/ConnectableObservableIntegrationTest.java diff --git a/rxjava-2/src/test/java/com/baeldung/rxjava/MaybeUnitTest.java b/rxjava-core/src/test/java/com/baeldung/rxjava/MaybeUnitTest.java similarity index 100% rename from rxjava-2/src/test/java/com/baeldung/rxjava/MaybeUnitTest.java rename to rxjava-core/src/test/java/com/baeldung/rxjava/MaybeUnitTest.java diff --git a/rxjava/src/test/java/com/baeldung/rxjava/ObservableUnitTest.java b/rxjava-core/src/test/java/com/baeldung/rxjava/ObservableUnitTest.java similarity index 100% rename from rxjava/src/test/java/com/baeldung/rxjava/ObservableUnitTest.java rename to rxjava-core/src/test/java/com/baeldung/rxjava/ObservableUnitTest.java diff --git a/rxjava/src/test/java/com/baeldung/rxjava/ResourceManagementUnitTest.java b/rxjava-core/src/test/java/com/baeldung/rxjava/ResourceManagementUnitTest.java similarity index 100% rename from rxjava/src/test/java/com/baeldung/rxjava/ResourceManagementUnitTest.java rename to rxjava-core/src/test/java/com/baeldung/rxjava/ResourceManagementUnitTest.java diff --git a/rxjava/src/test/java/com/baeldung/rxjava/RxJavaBackpressureLongRunningUnitTest.java b/rxjava-core/src/test/java/com/baeldung/rxjava/RxJavaBackpressureLongRunningUnitTest.java similarity index 100% rename from rxjava/src/test/java/com/baeldung/rxjava/RxJavaBackpressureLongRunningUnitTest.java rename to rxjava-core/src/test/java/com/baeldung/rxjava/RxJavaBackpressureLongRunningUnitTest.java diff --git a/rxjava-2/src/test/java/com/baeldung/rxjava/RxJavaHooksManualTest.java b/rxjava-core/src/test/java/com/baeldung/rxjava/RxJavaHooksManualTest.java similarity index 96% rename from rxjava-2/src/test/java/com/baeldung/rxjava/RxJavaHooksManualTest.java rename to rxjava-core/src/test/java/com/baeldung/rxjava/RxJavaHooksManualTest.java index b79fa9af22..f71d9e8839 100644 --- a/rxjava-2/src/test/java/com/baeldung/rxjava/RxJavaHooksManualTest.java +++ b/rxjava-core/src/test/java/com/baeldung/rxjava/RxJavaHooksManualTest.java @@ -1,84 +1,84 @@ -package com.baeldung.rxjava; - -import static org.junit.Assert.assertTrue; - -import org.junit.After; -import org.junit.Test; - -import io.reactivex.Observable; -import io.reactivex.plugins.RxJavaPlugins; -import io.reactivex.schedulers.Schedulers; - -public class RxJavaHooksManualTest { - - private boolean initHookCalled = false; - private boolean hookCalled = false; - - @Test - public void givenIOScheduler_whenCalled_shouldExecuteTheHooks() { - - RxJavaPlugins.setInitIoSchedulerHandler((scheduler) -> { - initHookCalled = true; - return scheduler.call(); - }); - - RxJavaPlugins.setIoSchedulerHandler((scheduler) -> { - hookCalled = true; - return scheduler; - }); - - Observable.range(1, 10) - .map(v -> v * 2) - .subscribeOn(Schedulers.io()) - .test(); - assertTrue(hookCalled && initHookCalled); - } - - @Test - public void givenNewThreadScheduler_whenCalled_shouldExecuteTheHook() { - - RxJavaPlugins.setInitNewThreadSchedulerHandler((scheduler) -> { - initHookCalled = true; - return scheduler.call(); - }); - - RxJavaPlugins.setNewThreadSchedulerHandler((scheduler) -> { - hookCalled = true; - return scheduler; - }); - - Observable.range(1, 15) - .map(v -> v * 2) - .subscribeOn(Schedulers.newThread()) - .test(); - assertTrue(hookCalled && initHookCalled); - } - - @Test - public void givenSingleScheduler_whenCalled_shouldExecuteTheHooks() { - - RxJavaPlugins.setInitSingleSchedulerHandler((scheduler) -> { - initHookCalled = true; - return scheduler.call(); - }); - - RxJavaPlugins.setSingleSchedulerHandler((scheduler) -> { - hookCalled = true; - return scheduler; - }); - - Observable.range(1, 10) - .map(v -> v * 2) - .subscribeOn(Schedulers.single()) - .test(); - assertTrue(hookCalled && initHookCalled); - - } - - @After - public void reset() { - hookCalled = false; - initHookCalled = false; - RxJavaPlugins.reset(); - } -} +package com.baeldung.rxjava; + +import static org.junit.Assert.assertTrue; + +import org.junit.After; +import org.junit.Test; + +import io.reactivex.Observable; +import io.reactivex.plugins.RxJavaPlugins; +import io.reactivex.schedulers.Schedulers; + +public class RxJavaHooksManualTest { + + private boolean initHookCalled = false; + private boolean hookCalled = false; + + @Test + public void givenIOScheduler_whenCalled_shouldExecuteTheHooks() { + + RxJavaPlugins.setInitIoSchedulerHandler((scheduler) -> { + initHookCalled = true; + return scheduler.call(); + }); + + RxJavaPlugins.setIoSchedulerHandler((scheduler) -> { + hookCalled = true; + return scheduler; + }); + + Observable.range(1, 10) + .map(v -> v * 2) + .subscribeOn(Schedulers.io()) + .test(); + assertTrue(hookCalled && initHookCalled); + } + + @Test + public void givenNewThreadScheduler_whenCalled_shouldExecuteTheHook() { + + RxJavaPlugins.setInitNewThreadSchedulerHandler((scheduler) -> { + initHookCalled = true; + return scheduler.call(); + }); + + RxJavaPlugins.setNewThreadSchedulerHandler((scheduler) -> { + hookCalled = true; + return scheduler; + }); + + Observable.range(1, 15) + .map(v -> v * 2) + .subscribeOn(Schedulers.newThread()) + .test(); + assertTrue(hookCalled && initHookCalled); + } + + @Test + public void givenSingleScheduler_whenCalled_shouldExecuteTheHooks() { + + RxJavaPlugins.setInitSingleSchedulerHandler((scheduler) -> { + initHookCalled = true; + return scheduler.call(); + }); + + RxJavaPlugins.setSingleSchedulerHandler((scheduler) -> { + hookCalled = true; + return scheduler; + }); + + Observable.range(1, 10) + .map(v -> v * 2) + .subscribeOn(Schedulers.single()) + .test(); + assertTrue(hookCalled && initHookCalled); + + } + + @After + public void reset() { + hookCalled = false; + initHookCalled = false; + RxJavaPlugins.reset(); + } +} diff --git a/rxjava-2/src/test/java/com/baeldung/rxjava/RxJavaHooksUnitTest.java b/rxjava-core/src/test/java/com/baeldung/rxjava/RxJavaHooksUnitTest.java similarity index 96% rename from rxjava-2/src/test/java/com/baeldung/rxjava/RxJavaHooksUnitTest.java rename to rxjava-core/src/test/java/com/baeldung/rxjava/RxJavaHooksUnitTest.java index dd4287a4a9..cea6cc70f6 100644 --- a/rxjava-2/src/test/java/com/baeldung/rxjava/RxJavaHooksUnitTest.java +++ b/rxjava-core/src/test/java/com/baeldung/rxjava/RxJavaHooksUnitTest.java @@ -1,244 +1,244 @@ -package com.baeldung.rxjava; - -import static org.junit.Assert.assertTrue; - -import org.junit.After; -import org.junit.Test; - -import io.reactivex.Completable; -import io.reactivex.Flowable; -import io.reactivex.Maybe; -import io.reactivex.Observable; -import io.reactivex.Single; -import io.reactivex.flowables.ConnectableFlowable; -import io.reactivex.observables.ConnectableObservable; -import io.reactivex.plugins.RxJavaPlugins; -import io.reactivex.schedulers.Schedulers; - -public class RxJavaHooksUnitTest { - - private boolean initHookCalled = false; - private boolean hookCalled = false; - - @Test - public void givenObservable_whenError_shouldExecuteTheHook() { - RxJavaPlugins.setErrorHandler(throwable -> { - hookCalled = true; - }); - - Observable.error(new IllegalStateException()) - .subscribe(); - assertTrue(hookCalled); - } - - @Test - public void givenCompletable_whenAssembled_shouldExecuteTheHook() { - - RxJavaPlugins.setOnCompletableAssembly(completable -> { - hookCalled = true; - return completable; - }); - Completable.fromSingle(Single.just(1)); - assertTrue(hookCalled); - } - - @Test - public void givenCompletable_whenSubscribed_shouldExecuteTheHook() { - - RxJavaPlugins.setOnCompletableSubscribe((completable, observer) -> { - hookCalled = true; - return observer; - }); - - Completable.fromSingle(Single.just(1)) - .test(); - assertTrue(hookCalled); - } - - @Test - public void givenObservable_whenAssembled_shouldExecuteTheHook() { - - RxJavaPlugins.setOnObservableAssembly(observable -> { - hookCalled = true; - return observable; - }); - - Observable.range(1, 10); - assertTrue(hookCalled); - } - - @Test - public void givenObservable_whenSubscribed_shouldExecuteTheHook() { - - RxJavaPlugins.setOnObservableSubscribe((observable, observer) -> { - hookCalled = true; - return observer; - }); - - Observable.range(1, 10) - .test(); - assertTrue(hookCalled); - } - - @Test - public void givenConnectableObservable_whenAssembled_shouldExecuteTheHook() { - - RxJavaPlugins.setOnConnectableObservableAssembly(connectableObservable -> { - hookCalled = true; - return connectableObservable; - }); - - ConnectableObservable.range(1, 10) - .publish() - .connect(); - assertTrue(hookCalled); - } - - @Test - public void givenFlowable_whenAssembled_shouldExecuteTheHook() { - - RxJavaPlugins.setOnFlowableAssembly(flowable -> { - hookCalled = true; - return flowable; - }); - - Flowable.range(1, 10); - assertTrue(hookCalled); - } - - @Test - public void givenFlowable_whenSubscribed_shouldExecuteTheHook() { - - RxJavaPlugins.setOnFlowableSubscribe((flowable, observer) -> { - hookCalled = true; - return observer; - }); - - Flowable.range(1, 10) - .test(); - assertTrue(hookCalled); - } - - @Test - public void givenConnectableFlowable_whenAssembled_shouldExecuteTheHook() { - - RxJavaPlugins.setOnConnectableFlowableAssembly(connectableFlowable -> { - hookCalled = true; - return connectableFlowable; - }); - - ConnectableFlowable.range(1, 10) - .publish() - .connect(); - assertTrue(hookCalled); - } - - @Test - public void givenParallel_whenAssembled_shouldExecuteTheHook() { - - RxJavaPlugins.setOnParallelAssembly(parallelFlowable -> { - hookCalled = true; - return parallelFlowable; - }); - - Flowable.range(1, 10) - .parallel(); - assertTrue(hookCalled); - } - - @Test - public void givenMaybe_whenAssembled_shouldExecuteTheHook() { - - RxJavaPlugins.setOnMaybeAssembly(maybe -> { - hookCalled = true; - return maybe; - }); - - Maybe.just(1); - assertTrue(hookCalled); - } - - @Test - public void givenMaybe_whenSubscribed_shouldExecuteTheHook() { - - RxJavaPlugins.setOnMaybeSubscribe((maybe, observer) -> { - hookCalled = true; - return observer; - }); - - Maybe.just(1) - .test(); - assertTrue(hookCalled); - } - - @Test - public void givenSingle_whenAssembled_shouldExecuteTheHook() { - - RxJavaPlugins.setOnSingleAssembly(single -> { - hookCalled = true; - return single; - }); - - Single.just(1); - assertTrue(hookCalled); - } - - @Test - public void givenSingle_whenSubscribed_shouldExecuteTheHook() { - - RxJavaPlugins.setOnSingleSubscribe((single, observer) -> { - hookCalled = true; - return observer; - }); - - Single.just(1) - .test(); - assertTrue(hookCalled); - } - - @Test - public void givenAnyScheduler_whenCalled_shouldExecuteTheHook() { - - RxJavaPlugins.setScheduleHandler((runnable) -> { - hookCalled = true; - return runnable; - }); - - Observable.range(1, 10) - .map(v -> v * 2) - .subscribeOn(Schedulers.single()) - .test(); - hookCalled = false; - Observable.range(1, 10) - .map(v -> v * 2) - .subscribeOn(Schedulers.computation()) - .test(); - assertTrue(hookCalled); - } - - @Test - public void givenComputationScheduler_whenCalled_shouldExecuteTheHooks() { - - RxJavaPlugins.setInitComputationSchedulerHandler((scheduler) -> { - initHookCalled = true; - return scheduler.call(); - }); - RxJavaPlugins.setComputationSchedulerHandler((scheduler) -> { - hookCalled = true; - return scheduler; - }); - - Observable.range(1, 10) - .map(v -> v * 2) - .subscribeOn(Schedulers.computation()) - .test(); - assertTrue(hookCalled && initHookCalled); - } - - @After - public void reset() { - initHookCalled = false; - hookCalled = false; - RxJavaPlugins.reset(); - } -} +package com.baeldung.rxjava; + +import static org.junit.Assert.assertTrue; + +import org.junit.After; +import org.junit.Test; + +import io.reactivex.Completable; +import io.reactivex.Flowable; +import io.reactivex.Maybe; +import io.reactivex.Observable; +import io.reactivex.Single; +import io.reactivex.flowables.ConnectableFlowable; +import io.reactivex.observables.ConnectableObservable; +import io.reactivex.plugins.RxJavaPlugins; +import io.reactivex.schedulers.Schedulers; + +public class RxJavaHooksUnitTest { + + private boolean initHookCalled = false; + private boolean hookCalled = false; + + @Test + public void givenObservable_whenError_shouldExecuteTheHook() { + RxJavaPlugins.setErrorHandler(throwable -> { + hookCalled = true; + }); + + Observable.error(new IllegalStateException()) + .subscribe(); + assertTrue(hookCalled); + } + + @Test + public void givenCompletable_whenAssembled_shouldExecuteTheHook() { + + RxJavaPlugins.setOnCompletableAssembly(completable -> { + hookCalled = true; + return completable; + }); + Completable.fromSingle(Single.just(1)); + assertTrue(hookCalled); + } + + @Test + public void givenCompletable_whenSubscribed_shouldExecuteTheHook() { + + RxJavaPlugins.setOnCompletableSubscribe((completable, observer) -> { + hookCalled = true; + return observer; + }); + + Completable.fromSingle(Single.just(1)) + .test(); + assertTrue(hookCalled); + } + + @Test + public void givenObservable_whenAssembled_shouldExecuteTheHook() { + + RxJavaPlugins.setOnObservableAssembly(observable -> { + hookCalled = true; + return observable; + }); + + Observable.range(1, 10); + assertTrue(hookCalled); + } + + @Test + public void givenObservable_whenSubscribed_shouldExecuteTheHook() { + + RxJavaPlugins.setOnObservableSubscribe((observable, observer) -> { + hookCalled = true; + return observer; + }); + + Observable.range(1, 10) + .test(); + assertTrue(hookCalled); + } + + @Test + public void givenConnectableObservable_whenAssembled_shouldExecuteTheHook() { + + RxJavaPlugins.setOnConnectableObservableAssembly(connectableObservable -> { + hookCalled = true; + return connectableObservable; + }); + + ConnectableObservable.range(1, 10) + .publish() + .connect(); + assertTrue(hookCalled); + } + + @Test + public void givenFlowable_whenAssembled_shouldExecuteTheHook() { + + RxJavaPlugins.setOnFlowableAssembly(flowable -> { + hookCalled = true; + return flowable; + }); + + Flowable.range(1, 10); + assertTrue(hookCalled); + } + + @Test + public void givenFlowable_whenSubscribed_shouldExecuteTheHook() { + + RxJavaPlugins.setOnFlowableSubscribe((flowable, observer) -> { + hookCalled = true; + return observer; + }); + + Flowable.range(1, 10) + .test(); + assertTrue(hookCalled); + } + + @Test + public void givenConnectableFlowable_whenAssembled_shouldExecuteTheHook() { + + RxJavaPlugins.setOnConnectableFlowableAssembly(connectableFlowable -> { + hookCalled = true; + return connectableFlowable; + }); + + ConnectableFlowable.range(1, 10) + .publish() + .connect(); + assertTrue(hookCalled); + } + + @Test + public void givenParallel_whenAssembled_shouldExecuteTheHook() { + + RxJavaPlugins.setOnParallelAssembly(parallelFlowable -> { + hookCalled = true; + return parallelFlowable; + }); + + Flowable.range(1, 10) + .parallel(); + assertTrue(hookCalled); + } + + @Test + public void givenMaybe_whenAssembled_shouldExecuteTheHook() { + + RxJavaPlugins.setOnMaybeAssembly(maybe -> { + hookCalled = true; + return maybe; + }); + + Maybe.just(1); + assertTrue(hookCalled); + } + + @Test + public void givenMaybe_whenSubscribed_shouldExecuteTheHook() { + + RxJavaPlugins.setOnMaybeSubscribe((maybe, observer) -> { + hookCalled = true; + return observer; + }); + + Maybe.just(1) + .test(); + assertTrue(hookCalled); + } + + @Test + public void givenSingle_whenAssembled_shouldExecuteTheHook() { + + RxJavaPlugins.setOnSingleAssembly(single -> { + hookCalled = true; + return single; + }); + + Single.just(1); + assertTrue(hookCalled); + } + + @Test + public void givenSingle_whenSubscribed_shouldExecuteTheHook() { + + RxJavaPlugins.setOnSingleSubscribe((single, observer) -> { + hookCalled = true; + return observer; + }); + + Single.just(1) + .test(); + assertTrue(hookCalled); + } + + @Test + public void givenAnyScheduler_whenCalled_shouldExecuteTheHook() { + + RxJavaPlugins.setScheduleHandler((runnable) -> { + hookCalled = true; + return runnable; + }); + + Observable.range(1, 10) + .map(v -> v * 2) + .subscribeOn(Schedulers.single()) + .test(); + hookCalled = false; + Observable.range(1, 10) + .map(v -> v * 2) + .subscribeOn(Schedulers.computation()) + .test(); + assertTrue(hookCalled); + } + + @Test + public void givenComputationScheduler_whenCalled_shouldExecuteTheHooks() { + + RxJavaPlugins.setInitComputationSchedulerHandler((scheduler) -> { + initHookCalled = true; + return scheduler.call(); + }); + RxJavaPlugins.setComputationSchedulerHandler((scheduler) -> { + hookCalled = true; + return scheduler; + }); + + Observable.range(1, 10) + .map(v -> v * 2) + .subscribeOn(Schedulers.computation()) + .test(); + assertTrue(hookCalled && initHookCalled); + } + + @After + public void reset() { + initHookCalled = false; + hookCalled = false; + RxJavaPlugins.reset(); + } +} diff --git a/rxjava/src/test/java/com/baeldung/rxjava/RxJavaUnitTest.java b/rxjava-core/src/test/java/com/baeldung/rxjava/RxJavaUnitTest.java similarity index 100% rename from rxjava/src/test/java/com/baeldung/rxjava/RxJavaUnitTest.java rename to rxjava-core/src/test/java/com/baeldung/rxjava/RxJavaUnitTest.java diff --git a/rxjava/src/test/java/com/baeldung/rxjava/SchedulersLiveTest.java b/rxjava-core/src/test/java/com/baeldung/rxjava/SchedulersLiveTest.java similarity index 100% rename from rxjava/src/test/java/com/baeldung/rxjava/SchedulersLiveTest.java rename to rxjava-core/src/test/java/com/baeldung/rxjava/SchedulersLiveTest.java diff --git a/rxjava/src/test/java/com/baeldung/rxjava/SingleUnitTest.java b/rxjava-core/src/test/java/com/baeldung/rxjava/SingleUnitTest.java similarity index 100% rename from rxjava/src/test/java/com/baeldung/rxjava/SingleUnitTest.java rename to rxjava-core/src/test/java/com/baeldung/rxjava/SingleUnitTest.java diff --git a/rxjava/src/test/java/com/baeldung/rxjava/SubjectUnitTest.java b/rxjava-core/src/test/java/com/baeldung/rxjava/SubjectUnitTest.java similarity index 100% rename from rxjava/src/test/java/com/baeldung/rxjava/SubjectUnitTest.java rename to rxjava-core/src/test/java/com/baeldung/rxjava/SubjectUnitTest.java diff --git a/rxjava-2/src/test/java/com/baeldung/rxjava/onerror/ExceptionHandlingIntegrationTest.java b/rxjava-core/src/test/java/com/baeldung/rxjava/onerror/ExceptionHandlingIntegrationTest.java similarity index 100% rename from rxjava-2/src/test/java/com/baeldung/rxjava/onerror/ExceptionHandlingIntegrationTest.java rename to rxjava-core/src/test/java/com/baeldung/rxjava/onerror/ExceptionHandlingIntegrationTest.java diff --git a/rxjava-2/src/test/java/com/baeldung/rxjava/onerror/OnErrorRetryIntegrationTest.java b/rxjava-core/src/test/java/com/baeldung/rxjava/onerror/OnErrorRetryIntegrationTest.java similarity index 100% rename from rxjava-2/src/test/java/com/baeldung/rxjava/onerror/OnErrorRetryIntegrationTest.java rename to rxjava-core/src/test/java/com/baeldung/rxjava/onerror/OnErrorRetryIntegrationTest.java diff --git a/rxjava-libraries/README.md b/rxjava-libraries/README.md new file mode 100644 index 0000000000..ac8aac6908 --- /dev/null +++ b/rxjava-libraries/README.md @@ -0,0 +1,10 @@ +## RxJava Libraries + + This module contains articles about RxJava libraries + +### Related Articles: + +- [RxJava 2 – Flowable](https://www.baeldung.com/rxjava-2-flowable) +- [Introduction to RxRelay for RxJava](https://www.baeldung.com/rx-relay) +- [Introduction to rxjava-jdbc](https://www.baeldung.com/rxjava-jdbc) + diff --git a/rxjava-libraries/pom.xml b/rxjava-libraries/pom.xml new file mode 100644 index 0000000000..541d9116c8 --- /dev/null +++ b/rxjava-libraries/pom.xml @@ -0,0 +1,59 @@ + + + 4.0.0 + rxjava-libraries + 1.0-SNAPSHOT + rxjava-libraries + + + com.baeldung + parent-java + 0.0.1-SNAPSHOT + ../parent-java + + + + + io.reactivex + rxjava + ${rx.java.version} + + + io.reactivex.rxjava2 + rxjava + ${rx.java2.version} + + + com.jakewharton.rxrelay2 + rxrelay + ${rxrelay.version} + + + com.github.davidmoten + rxjava-jdbc + ${rx.java.jdbc.version} + + + com.h2database + h2 + ${h2.version} + runtime + + + org.assertj + assertj-core + ${assertj.version} + + + + + + 0.7.11 + 1.2.5 + 2.0.0 + 2.2.2 + 3.8.0 + + + \ No newline at end of file diff --git a/rxjava-2/src/main/java/com/baeldung/rxjava/RandomRelay.java b/rxjava-libraries/src/main/java/com/baeldung/rxjava/RandomRelay.java similarity index 100% rename from rxjava-2/src/main/java/com/baeldung/rxjava/RandomRelay.java rename to rxjava-libraries/src/main/java/com/baeldung/rxjava/RandomRelay.java diff --git a/rxjava/src/main/java/com/baeldung/rxjava/jdbc/Connector.java b/rxjava-libraries/src/main/java/com/baeldung/rxjava/jdbc/Connector.java similarity index 100% rename from rxjava/src/main/java/com/baeldung/rxjava/jdbc/Connector.java rename to rxjava-libraries/src/main/java/com/baeldung/rxjava/jdbc/Connector.java diff --git a/rxjava/src/main/java/com/baeldung/rxjava/jdbc/Employee.java b/rxjava-libraries/src/main/java/com/baeldung/rxjava/jdbc/Employee.java similarity index 100% rename from rxjava/src/main/java/com/baeldung/rxjava/jdbc/Employee.java rename to rxjava-libraries/src/main/java/com/baeldung/rxjava/jdbc/Employee.java diff --git a/rxjava/src/main/java/com/baeldung/rxjava/jdbc/Manager.java b/rxjava-libraries/src/main/java/com/baeldung/rxjava/jdbc/Manager.java similarity index 100% rename from rxjava/src/main/java/com/baeldung/rxjava/jdbc/Manager.java rename to rxjava-libraries/src/main/java/com/baeldung/rxjava/jdbc/Manager.java diff --git a/rxjava/src/main/java/com/baeldung/rxjava/jdbc/Utils.java b/rxjava-libraries/src/main/java/com/baeldung/rxjava/jdbc/Utils.java similarity index 100% rename from rxjava/src/main/java/com/baeldung/rxjava/jdbc/Utils.java rename to rxjava-libraries/src/main/java/com/baeldung/rxjava/jdbc/Utils.java diff --git a/rxjava-2/src/test/java/com/baeldung/rxjava/FlowableIntegrationTest.java b/rxjava-libraries/src/test/java/com/baeldung/rxjava/FlowableIntegrationTest.java similarity index 100% rename from rxjava-2/src/test/java/com/baeldung/rxjava/FlowableIntegrationTest.java rename to rxjava-libraries/src/test/java/com/baeldung/rxjava/FlowableIntegrationTest.java diff --git a/rxjava-2/src/test/java/com/baeldung/rxjava/RxRelayIntegrationTest.java b/rxjava-libraries/src/test/java/com/baeldung/rxjava/RxRelayIntegrationTest.java similarity index 100% rename from rxjava-2/src/test/java/com/baeldung/rxjava/RxRelayIntegrationTest.java rename to rxjava-libraries/src/test/java/com/baeldung/rxjava/RxRelayIntegrationTest.java diff --git a/rxjava/src/test/java/com/baeldung/rxjava/jdbc/AutomapClassIntegrationTest.java b/rxjava-libraries/src/test/java/com/baeldung/rxjava/jdbc/AutomapClassIntegrationTest.java similarity index 100% rename from rxjava/src/test/java/com/baeldung/rxjava/jdbc/AutomapClassIntegrationTest.java rename to rxjava-libraries/src/test/java/com/baeldung/rxjava/jdbc/AutomapClassIntegrationTest.java diff --git a/rxjava/src/test/java/com/baeldung/rxjava/jdbc/AutomapInterfaceIntegrationTest.java b/rxjava-libraries/src/test/java/com/baeldung/rxjava/jdbc/AutomapInterfaceIntegrationTest.java similarity index 100% rename from rxjava/src/test/java/com/baeldung/rxjava/jdbc/AutomapInterfaceIntegrationTest.java rename to rxjava-libraries/src/test/java/com/baeldung/rxjava/jdbc/AutomapInterfaceIntegrationTest.java diff --git a/rxjava/src/test/java/com/baeldung/rxjava/jdbc/BasicQueryTypesIntegrationTest.java b/rxjava-libraries/src/test/java/com/baeldung/rxjava/jdbc/BasicQueryTypesIntegrationTest.java similarity index 100% rename from rxjava/src/test/java/com/baeldung/rxjava/jdbc/BasicQueryTypesIntegrationTest.java rename to rxjava-libraries/src/test/java/com/baeldung/rxjava/jdbc/BasicQueryTypesIntegrationTest.java diff --git a/rxjava/src/test/java/com/baeldung/rxjava/jdbc/InsertBlobIntegrationTest.java b/rxjava-libraries/src/test/java/com/baeldung/rxjava/jdbc/InsertBlobIntegrationTest.java similarity index 100% rename from rxjava/src/test/java/com/baeldung/rxjava/jdbc/InsertBlobIntegrationTest.java rename to rxjava-libraries/src/test/java/com/baeldung/rxjava/jdbc/InsertBlobIntegrationTest.java diff --git a/rxjava/src/test/java/com/baeldung/rxjava/jdbc/InsertClobIntegrationTest.java b/rxjava-libraries/src/test/java/com/baeldung/rxjava/jdbc/InsertClobIntegrationTest.java similarity index 100% rename from rxjava/src/test/java/com/baeldung/rxjava/jdbc/InsertClobIntegrationTest.java rename to rxjava-libraries/src/test/java/com/baeldung/rxjava/jdbc/InsertClobIntegrationTest.java diff --git a/rxjava/src/test/java/com/baeldung/rxjava/jdbc/ReturnKeysIntegrationTest.java b/rxjava-libraries/src/test/java/com/baeldung/rxjava/jdbc/ReturnKeysIntegrationTest.java similarity index 100% rename from rxjava/src/test/java/com/baeldung/rxjava/jdbc/ReturnKeysIntegrationTest.java rename to rxjava-libraries/src/test/java/com/baeldung/rxjava/jdbc/ReturnKeysIntegrationTest.java diff --git a/rxjava/src/test/java/com/baeldung/rxjava/jdbc/TransactionIntegrationTest.java b/rxjava-libraries/src/test/java/com/baeldung/rxjava/jdbc/TransactionIntegrationTest.java similarity index 100% rename from rxjava/src/test/java/com/baeldung/rxjava/jdbc/TransactionIntegrationTest.java rename to rxjava-libraries/src/test/java/com/baeldung/rxjava/jdbc/TransactionIntegrationTest.java diff --git a/rxjava/src/test/resources/actual_clob b/rxjava-libraries/src/test/resources/actual_clob similarity index 100% rename from rxjava/src/test/resources/actual_clob rename to rxjava-libraries/src/test/resources/actual_clob diff --git a/rxjava/src/test/resources/expected_clob b/rxjava-libraries/src/test/resources/expected_clob similarity index 100% rename from rxjava/src/test/resources/expected_clob rename to rxjava-libraries/src/test/resources/expected_clob diff --git a/rxjava-observables/README.md b/rxjava-observables/README.md new file mode 100644 index 0000000000..3bec990012 --- /dev/null +++ b/rxjava-observables/README.md @@ -0,0 +1,11 @@ +## RxJava Observables + + This module contains articles about RxJava Observables + +### Related Articles: + +- [Combining Observables in RxJava](https://www.baeldung.com/rxjava-combine-observables) +- [RxJava One Observable, Multiple Subscribers](https://www.baeldung.com/rxjava-multiple-subscribers-observable) +- [RxJava StringObservable](https://www.baeldung.com/rxjava-string) +- [Filtering Observables in RxJava](https://www.baeldung.com/rxjava-filtering) + diff --git a/rxjava-observables/pom.xml b/rxjava-observables/pom.xml new file mode 100644 index 0000000000..c2bf0bcd88 --- /dev/null +++ b/rxjava-observables/pom.xml @@ -0,0 +1,41 @@ + + + 4.0.0 + rxjava-observables + 1.0-SNAPSHOT + rxjava-observables + + + com.baeldung + parent-java + 0.0.1-SNAPSHOT + ../parent-java + + + + + io.reactivex + rxjava + ${rx.java.version} + + + io.reactivex + rxjava-string + ${rx.java.string.version} + + + org.assertj + assertj-core + ${assertj.version} + + + + + + 1.1.1 + 1.2.5 + 3.8.0 + + + \ No newline at end of file diff --git a/rxjava/src/main/java/com/baeldung/rxjava/MultipleSubscribersColdObs.java b/rxjava-observables/src/main/java/com/baeldung/rxjava/MultipleSubscribersColdObs.java similarity index 100% rename from rxjava/src/main/java/com/baeldung/rxjava/MultipleSubscribersColdObs.java rename to rxjava-observables/src/main/java/com/baeldung/rxjava/MultipleSubscribersColdObs.java diff --git a/rxjava/src/main/java/com/baeldung/rxjava/MultipleSubscribersHotObs.java b/rxjava-observables/src/main/java/com/baeldung/rxjava/MultipleSubscribersHotObs.java similarity index 100% rename from rxjava/src/main/java/com/baeldung/rxjava/MultipleSubscribersHotObs.java rename to rxjava-observables/src/main/java/com/baeldung/rxjava/MultipleSubscribersHotObs.java diff --git a/rxjava/src/test/java/com/baeldung/rxjava/combine/ObservableCombineUnitTest.java b/rxjava-observables/src/test/java/com/baeldung/rxjava/combine/ObservableCombineUnitTest.java similarity index 100% rename from rxjava/src/test/java/com/baeldung/rxjava/combine/ObservableCombineUnitTest.java rename to rxjava-observables/src/test/java/com/baeldung/rxjava/combine/ObservableCombineUnitTest.java diff --git a/rxjava/src/test/java/com/baeldung/rxjava/filters/RxJavaFilterOperatorsIntegrationTest.java b/rxjava-observables/src/test/java/com/baeldung/rxjava/filters/RxJavaFilterOperatorsIntegrationTest.java similarity index 100% rename from rxjava/src/test/java/com/baeldung/rxjava/filters/RxJavaFilterOperatorsIntegrationTest.java rename to rxjava-observables/src/test/java/com/baeldung/rxjava/filters/RxJavaFilterOperatorsIntegrationTest.java diff --git a/rxjava/src/test/java/com/baeldung/rxjava/filters/RxJavaSkipOperatorsIntegrationTest.java b/rxjava-observables/src/test/java/com/baeldung/rxjava/filters/RxJavaSkipOperatorsIntegrationTest.java similarity index 100% rename from rxjava/src/test/java/com/baeldung/rxjava/filters/RxJavaSkipOperatorsIntegrationTest.java rename to rxjava-observables/src/test/java/com/baeldung/rxjava/filters/RxJavaSkipOperatorsIntegrationTest.java diff --git a/rxjava/src/test/java/com/baeldung/rxjava/filters/RxJavaTimeFilteringOperatorsIntegrationTest.java b/rxjava-observables/src/test/java/com/baeldung/rxjava/filters/RxJavaTimeFilteringOperatorsIntegrationTest.java similarity index 100% rename from rxjava/src/test/java/com/baeldung/rxjava/filters/RxJavaTimeFilteringOperatorsIntegrationTest.java rename to rxjava-observables/src/test/java/com/baeldung/rxjava/filters/RxJavaTimeFilteringOperatorsIntegrationTest.java diff --git a/rxjava/src/test/java/com/baeldung/rxjava/operators/RxStringOperatorsUnitTest.java b/rxjava-observables/src/test/java/com/baeldung/rxjava/operators/RxStringOperatorsUnitTest.java similarity index 100% rename from rxjava/src/test/java/com/baeldung/rxjava/operators/RxStringOperatorsUnitTest.java rename to rxjava-observables/src/test/java/com/baeldung/rxjava/operators/RxStringOperatorsUnitTest.java diff --git a/rxjava-operators/README.md b/rxjava-operators/README.md new file mode 100644 index 0000000000..293d310bbd --- /dev/null +++ b/rxjava-operators/README.md @@ -0,0 +1,12 @@ +## RxJava Operators + + This module contains articles about RxJava Operators + +### Related Articles: + +- [Mathematical and Aggregate Operators in RxJava](https://www.baeldung.com/rxjava-math) +- [Observable Utility Operators in RxJava](https://www.baeldung.com/rxjava-observable-operators) +- [Implementing Custom Operators in RxJava](https://www.baeldung.com/rxjava-custom-operators) +- [Converting Synchronous and Asynchronous APIs to Observables using RxJava2](https://www.baeldung.com/rxjava-apis-to-observables) + + diff --git a/rxjava/pom.xml b/rxjava-operators/pom.xml similarity index 66% rename from rxjava/pom.xml rename to rxjava-operators/pom.xml index 85106d1127..8064613f45 100644 --- a/rxjava/pom.xml +++ b/rxjava-operators/pom.xml @@ -1,11 +1,11 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - rxjava + rxjava-operators 1.0-SNAPSHOT - rxjava - + rxjava-operators + com.baeldung parent-java @@ -19,48 +19,40 @@ rxjava ${rx.java.version} - - io.reactivex - rxjava-math - ${rx.java.math.version} + io.reactivex.rxjava2 + rxjava + ${rx.java2.version} - + - io.reactivex - rxjava-string - ${rx.java.string.version} - - - - com.jayway.awaitility - awaitility - ${awaitility.version} - - - com.github.davidmoten - rxjava-jdbc - ${rx.java.jdbc.version} - - - com.h2database - h2 - ${h2.version} - runtime + com.github.akarnokd + rxjava2-extensions + ${rxjava2.ext.version} org.assertj assertj-core ${assertj.version} + + io.reactivex + rxjava-math + ${rx.java.math.version} + + + com.jayway.awaitility + awaitility + ${awaitility.version} + + 0.20.4 + 2.2.2 3.8.0 1.2.5 - 0.7.11 1.0.0 - 1.1.1 1.7.0 diff --git a/rxjava/src/main/java/com/baeldung/rxjava/operator/ToCleanString.java b/rxjava-operators/src/main/java/com/baeldung/rxjava/operator/ToCleanString.java similarity index 100% rename from rxjava/src/main/java/com/baeldung/rxjava/operator/ToCleanString.java rename to rxjava-operators/src/main/java/com/baeldung/rxjava/operator/ToCleanString.java diff --git a/rxjava/src/main/java/com/baeldung/rxjava/operator/ToLength.java b/rxjava-operators/src/main/java/com/baeldung/rxjava/operator/ToLength.java similarity index 100% rename from rxjava/src/main/java/com/baeldung/rxjava/operator/ToLength.java rename to rxjava-operators/src/main/java/com/baeldung/rxjava/operator/ToLength.java diff --git a/rxjava-2/src/test/java/com/baeldung/rxjava/AsyncAndSyncToObservableIntegrationTest.java b/rxjava-operators/src/test/java/com/baeldung/rxjava/AsyncAndSyncToObservableIntegrationTest.java similarity index 96% rename from rxjava-2/src/test/java/com/baeldung/rxjava/AsyncAndSyncToObservableIntegrationTest.java rename to rxjava-operators/src/test/java/com/baeldung/rxjava/AsyncAndSyncToObservableIntegrationTest.java index 90f4fe94ae..2842fab80e 100644 --- a/rxjava-2/src/test/java/com/baeldung/rxjava/AsyncAndSyncToObservableIntegrationTest.java +++ b/rxjava-operators/src/test/java/com/baeldung/rxjava/AsyncAndSyncToObservableIntegrationTest.java @@ -1,107 +1,107 @@ -package com.baeldung.rxjava; - -import static org.junit.Assert.assertEquals; - -import java.util.Arrays; -import java.util.List; -import java.util.concurrent.Callable; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; - -import org.junit.Test; - -import hu.akarnokd.rxjava2.async.AsyncObservable; -import io.reactivex.Observable; - -public class AsyncAndSyncToObservableIntegrationTest { - - AtomicInteger counter = new AtomicInteger(); - Callable callable = () -> counter.incrementAndGet(); - - /* Method will execute every time it gets subscribed*/ - @Test - public void givenSyncMethod_whenConvertedWithFromCallable_thenReturnObservable() { - - Observable source = Observable.fromCallable(callable); - - for (int i = 1; i < 5; i++) { - source.test() - .awaitDone(5, TimeUnit.SECONDS) - .assertResult(i); - - assertEquals(i, counter.get()); - } - } - - /* Method will execute only once and cache its result.*/ - @Test - public void givenSyncMethod_whenConvertedWithStart_thenReturnObservable() { - - Observable source = AsyncObservable.start(callable); - - for (int i = 1; i < 5; i++) { - source.test() - .awaitDone(5, TimeUnit.SECONDS) - .assertResult(1); - - assertEquals(1, counter.get()); - } - } - - /* Method will execute only once and cache its result.*/ - @Test - public void givenAsyncMethod_whenConvertedWithFromFuture_thenRetrunObservble() { - - ExecutorService executor = Executors.newSingleThreadExecutor(); - Future future = executor.submit(callable); - Observable source = Observable.fromFuture(future); - - for (int i = 1; i < 5; i++) { - source.test() - .awaitDone(5, TimeUnit.SECONDS) - .assertResult(1); - - assertEquals(1, counter.get()); - } - - executor.shutdown(); - } - - /* Method will execute every time it gets subscribed*/ - @Test - public void givenAsyncMethod_whenConvertedWithStartFuture_thenRetrunObservble() { - - ExecutorService executor = Executors.newSingleThreadExecutor(); - Observable source = AsyncObservable.startFuture(() -> executor.submit(callable)); - - for (int i = 1; i < 5; i++) { - source.test() - .awaitDone(5, TimeUnit.SECONDS) - .assertResult(i); - - assertEquals(i, counter.get()); - } - - executor.shutdown(); - } - - /*Method will execute only once and cache its result.*/ - @Test - public void givenAsyncMethod_whenConvertedWithDeferFuture_thenRetrunObservble() { - List list = Arrays.asList(new Integer[] { counter.incrementAndGet(), counter.incrementAndGet(), counter.incrementAndGet() }); - ExecutorService exec = Executors.newSingleThreadExecutor(); - Callable> callable = () -> Observable.fromIterable(list); - Observable source = AsyncObservable.deferFuture(() -> exec.submit(callable)); - for (int i = 1; i < 4; i++) { - source.test() - .awaitDone(5, TimeUnit.SECONDS) - .assertResult(1, 2, 3); - } - - exec.shutdown(); - } - -} +package com.baeldung.rxjava; + +import static org.junit.Assert.assertEquals; + +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; + +import org.junit.Test; + +import hu.akarnokd.rxjava2.async.AsyncObservable; +import io.reactivex.Observable; + +public class AsyncAndSyncToObservableIntegrationTest { + + AtomicInteger counter = new AtomicInteger(); + Callable callable = () -> counter.incrementAndGet(); + + /* Method will execute every time it gets subscribed*/ + @Test + public void givenSyncMethod_whenConvertedWithFromCallable_thenReturnObservable() { + + Observable source = Observable.fromCallable(callable); + + for (int i = 1; i < 5; i++) { + source.test() + .awaitDone(5, TimeUnit.SECONDS) + .assertResult(i); + + assertEquals(i, counter.get()); + } + } + + /* Method will execute only once and cache its result.*/ + @Test + public void givenSyncMethod_whenConvertedWithStart_thenReturnObservable() { + + Observable source = AsyncObservable.start(callable); + + for (int i = 1; i < 5; i++) { + source.test() + .awaitDone(5, TimeUnit.SECONDS) + .assertResult(1); + + assertEquals(1, counter.get()); + } + } + + /* Method will execute only once and cache its result.*/ + @Test + public void givenAsyncMethod_whenConvertedWithFromFuture_thenRetrunObservble() { + + ExecutorService executor = Executors.newSingleThreadExecutor(); + Future future = executor.submit(callable); + Observable source = Observable.fromFuture(future); + + for (int i = 1; i < 5; i++) { + source.test() + .awaitDone(5, TimeUnit.SECONDS) + .assertResult(1); + + assertEquals(1, counter.get()); + } + + executor.shutdown(); + } + + /* Method will execute every time it gets subscribed*/ + @Test + public void givenAsyncMethod_whenConvertedWithStartFuture_thenRetrunObservble() { + + ExecutorService executor = Executors.newSingleThreadExecutor(); + Observable source = AsyncObservable.startFuture(() -> executor.submit(callable)); + + for (int i = 1; i < 5; i++) { + source.test() + .awaitDone(5, TimeUnit.SECONDS) + .assertResult(i); + + assertEquals(i, counter.get()); + } + + executor.shutdown(); + } + + /*Method will execute only once and cache its result.*/ + @Test + public void givenAsyncMethod_whenConvertedWithDeferFuture_thenRetrunObservble() { + List list = Arrays.asList(new Integer[] { counter.incrementAndGet(), counter.incrementAndGet(), counter.incrementAndGet() }); + ExecutorService exec = Executors.newSingleThreadExecutor(); + Callable> callable = () -> Observable.fromIterable(list); + Observable source = AsyncObservable.deferFuture(() -> exec.submit(callable)); + for (int i = 1; i < 4; i++) { + source.test() + .awaitDone(5, TimeUnit.SECONDS) + .assertResult(1, 2, 3); + } + + exec.shutdown(); + } + +} diff --git a/rxjava/src/test/java/com/baeldung/rxjava/RxJavaCustomOperatorUnitTest.java b/rxjava-operators/src/test/java/com/baeldung/rxjava/RxJavaCustomOperatorUnitTest.java similarity index 100% rename from rxjava/src/test/java/com/baeldung/rxjava/RxJavaCustomOperatorUnitTest.java rename to rxjava-operators/src/test/java/com/baeldung/rxjava/RxJavaCustomOperatorUnitTest.java diff --git a/rxjava/src/test/java/com/baeldung/rxjava/UtilityOperatorsIntegrationTest.java b/rxjava-operators/src/test/java/com/baeldung/rxjava/UtilityOperatorsIntegrationTest.java similarity index 100% rename from rxjava/src/test/java/com/baeldung/rxjava/UtilityOperatorsIntegrationTest.java rename to rxjava-operators/src/test/java/com/baeldung/rxjava/UtilityOperatorsIntegrationTest.java diff --git a/rxjava/src/test/java/com/baeldung/rxjava/operators/RxAggregateOperatorsUnitTest.java b/rxjava-operators/src/test/java/com/baeldung/rxjava/operators/RxAggregateOperatorsUnitTest.java similarity index 100% rename from rxjava/src/test/java/com/baeldung/rxjava/operators/RxAggregateOperatorsUnitTest.java rename to rxjava-operators/src/test/java/com/baeldung/rxjava/operators/RxAggregateOperatorsUnitTest.java diff --git a/rxjava-2/src/test/java/com/baeldung/rxjava/operators/RxFlatmapAndSwitchmapUnitTest.java b/rxjava-operators/src/test/java/com/baeldung/rxjava/operators/RxFlatmapAndSwitchmapUnitTest.java similarity index 100% rename from rxjava-2/src/test/java/com/baeldung/rxjava/operators/RxFlatmapAndSwitchmapUnitTest.java rename to rxjava-operators/src/test/java/com/baeldung/rxjava/operators/RxFlatmapAndSwitchmapUnitTest.java diff --git a/rxjava/src/test/java/com/baeldung/rxjava/operators/RxMathematicalOperatorsUnitTest.java b/rxjava-operators/src/test/java/com/baeldung/rxjava/operators/RxMathematicalOperatorsUnitTest.java similarity index 100% rename from rxjava/src/test/java/com/baeldung/rxjava/operators/RxMathematicalOperatorsUnitTest.java rename to rxjava-operators/src/test/java/com/baeldung/rxjava/operators/RxMathematicalOperatorsUnitTest.java diff --git a/rxjava/README.md b/rxjava/README.md deleted file mode 100644 index c9308ddcc6..0000000000 --- a/rxjava/README.md +++ /dev/null @@ -1,20 +0,0 @@ -## RxJava - -This module contains articles about RxJava. - -### Relevant articles: - -- [Dealing with Backpressure with RxJava](https://www.baeldung.com/rxjava-backpressure) -- [How to Test RxJava?](https://www.baeldung.com/rxjava-testing) -- [Implementing Custom Operators in RxJava](https://www.baeldung.com/rxjava-custom-operators) -- [Introduction to RxJava](https://www.baeldung.com/rx-java) -- [Observable Utility Operators in RxJava](https://www.baeldung.com/rxjava-observable-operators) -- [Introduction to rxjava-jdbc](https://www.baeldung.com/rxjava-jdbc) -- [Schedulers in RxJava](https://www.baeldung.com/rxjava-schedulers) -- [Mathematical and Aggregate Operators in RxJava](https://www.baeldung.com/rxjava-math) -- [Combining Observables in RxJava](https://www.baeldung.com/rxjava-combine-observables) -- [RxJava StringObservable](https://www.baeldung.com/rxjava-string) -- [Filtering Observables in RxJava](https://www.baeldung.com/rxjava-filtering) -- [RxJava One Observable, Multiple Subscribers](https://www.baeldung.com/rxjava-multiple-subscribers-observable) -- [Difference Between Flatmap and Switchmap in RxJava](https://www.baeldung.com/rxjava-flatmap-switchmap) -- More articles: [[next -->]](/rxjava-2) diff --git a/rxjava/src/main/resources/logback.xml b/rxjava/src/main/resources/logback.xml deleted file mode 100644 index 7d900d8ea8..0000000000 --- a/rxjava/src/main/resources/logback.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n - - - - - - - - \ No newline at end of file diff --git a/spring-5-security-oauth/src/main/java/com/baeldung/oauth2/LoginController.java b/spring-5-security-oauth/src/main/java/com/baeldung/oauth2/LoginController.java index 5d6c13bb0e..e2629053f1 100644 --- a/spring-5-security-oauth/src/main/java/com/baeldung/oauth2/LoginController.java +++ b/spring-5-security-oauth/src/main/java/com/baeldung/oauth2/LoginController.java @@ -71,5 +71,4 @@ public class LoginController { return "loginSuccess"; } - } diff --git a/spring-5/README.md b/spring-5/README.md index 8a0cbe807e..857b199562 100644 --- a/spring-5/README.md +++ b/spring-5/README.md @@ -15,4 +15,4 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [Spring ResponseStatusException](https://www.baeldung.com/spring-response-status-exception) - [Spring Assert Statements](https://www.baeldung.com/spring-assert) - [Configuring a Hikari Connection Pool with Spring Boot](https://www.baeldung.com/spring-boot-hikari) -- [Difference between vs ](https://www.baeldung.com/spring-contextannotation-contextcomponentscan) +- [Difference between \ vs \](https://www.baeldung.com/spring-contextannotation-contextcomponentscan) diff --git a/spring-amqp/src/main/java/com/baeldung/springamqp/errorhandling/ErrorHandlingApp.java b/spring-amqp/src/main/java/com/baeldung/springamqp/errorhandling/ErrorHandlingApp.java new file mode 100644 index 0000000000..72a9ec8ad7 --- /dev/null +++ b/spring-amqp/src/main/java/com/baeldung/springamqp/errorhandling/ErrorHandlingApp.java @@ -0,0 +1,26 @@ +package com.baeldung.springamqp.errorhandling; + +import com.baeldung.springamqp.errorhandling.producer.MessageProducer; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.context.event.ApplicationReadyEvent; +import org.springframework.context.event.EventListener; +import org.springframework.scheduling.annotation.EnableScheduling; + +@SpringBootApplication +@EnableScheduling +public class ErrorHandlingApp { + + @Autowired + MessageProducer messageProducer; + + public static void main(String[] args) { + SpringApplication.run(ErrorHandlingApp.class, args); + } + + @EventListener(ApplicationReadyEvent.class) + public void doSomethingAfterStartup() { + messageProducer.sendMessage(); + } +} diff --git a/spring-amqp/src/main/java/com/baeldung/springamqp/errorhandling/configuration/DLXCustomAmqpConfiguration.java b/spring-amqp/src/main/java/com/baeldung/springamqp/errorhandling/configuration/DLXCustomAmqpConfiguration.java new file mode 100644 index 0000000000..708b08476d --- /dev/null +++ b/spring-amqp/src/main/java/com/baeldung/springamqp/errorhandling/configuration/DLXCustomAmqpConfiguration.java @@ -0,0 +1,55 @@ +package com.baeldung.springamqp.errorhandling.configuration; + +import org.springframework.amqp.core.Binding; +import org.springframework.amqp.core.BindingBuilder; +import org.springframework.amqp.core.DirectExchange; +import org.springframework.amqp.core.FanoutExchange; +import org.springframework.amqp.core.Queue; +import org.springframework.amqp.core.QueueBuilder; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import static com.baeldung.springamqp.errorhandling.configuration.SimpleDLQAmqpConfiguration.EXCHANGE_MESSAGES; +import static com.baeldung.springamqp.errorhandling.configuration.SimpleDLQAmqpConfiguration.QUEUE_MESSAGES; +import static com.baeldung.springamqp.errorhandling.configuration.SimpleDLQAmqpConfiguration.QUEUE_MESSAGES_DLQ; + +@Configuration +@ConditionalOnProperty( + value = "amqp.configuration.current", + havingValue = "dlx-custom") +public class DLXCustomAmqpConfiguration { + public static final String DLX_EXCHANGE_MESSAGES = QUEUE_MESSAGES + ".dlx"; + + @Bean + Queue messagesQueue() { + return QueueBuilder.durable(QUEUE_MESSAGES) + .withArgument("x-dead-letter-exchange", DLX_EXCHANGE_MESSAGES) + .build(); + } + + @Bean + FanoutExchange deadLetterExchange() { + return new FanoutExchange(DLX_EXCHANGE_MESSAGES); + } + + @Bean + Queue deadLetterQueue() { + return QueueBuilder.durable(QUEUE_MESSAGES_DLQ).build(); + } + + @Bean + Binding deadLetterBinding() { + return BindingBuilder.bind(deadLetterQueue()).to(deadLetterExchange()); + } + + @Bean + DirectExchange messagesExchange() { + return new DirectExchange(EXCHANGE_MESSAGES); + } + + @Bean + Binding bindingMessages() { + return BindingBuilder.bind(messagesQueue()).to(messagesExchange()).with(QUEUE_MESSAGES); + } +} diff --git a/spring-amqp/src/main/java/com/baeldung/springamqp/errorhandling/configuration/DLXParkingLotAmqpConfiguration.java b/spring-amqp/src/main/java/com/baeldung/springamqp/errorhandling/configuration/DLXParkingLotAmqpConfiguration.java new file mode 100644 index 0000000000..bff325e657 --- /dev/null +++ b/spring-amqp/src/main/java/com/baeldung/springamqp/errorhandling/configuration/DLXParkingLotAmqpConfiguration.java @@ -0,0 +1,72 @@ +package com.baeldung.springamqp.errorhandling.configuration; + +import org.springframework.amqp.core.Binding; +import org.springframework.amqp.core.BindingBuilder; +import org.springframework.amqp.core.DirectExchange; +import org.springframework.amqp.core.FanoutExchange; +import org.springframework.amqp.core.Queue; +import org.springframework.amqp.core.QueueBuilder; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import static com.baeldung.springamqp.errorhandling.configuration.SimpleDLQAmqpConfiguration.EXCHANGE_MESSAGES; +import static com.baeldung.springamqp.errorhandling.configuration.SimpleDLQAmqpConfiguration.QUEUE_MESSAGES; +import static com.baeldung.springamqp.errorhandling.configuration.SimpleDLQAmqpConfiguration.QUEUE_MESSAGES_DLQ; + +@Configuration +@ConditionalOnProperty( + value = "amqp.configuration.current", + havingValue = "parking-lot-dlx") +public class DLXParkingLotAmqpConfiguration { + public static final String DLX_EXCHANGE_MESSAGES = QUEUE_MESSAGES + ".dlx"; + public static final String QUEUE_PARKING_LOT = QUEUE_MESSAGES + ".parking-lot"; + public static final String EXCHANGE_PARKING_LOT = QUEUE_MESSAGES + "exchange.parking-lot"; + + @Bean + FanoutExchange parkingLotExchange() { + return new FanoutExchange(EXCHANGE_PARKING_LOT); + } + + @Bean + Queue parkingLotQueue() { + return QueueBuilder.durable(QUEUE_PARKING_LOT).build(); + } + + @Bean + Binding parkingLotBinding() { + return BindingBuilder.bind(parkingLotQueue()).to(parkingLotExchange()); + } + + @Bean + Queue messagesQueue() { + return QueueBuilder.durable(QUEUE_MESSAGES) + .withArgument("x-dead-letter-exchange", DLX_EXCHANGE_MESSAGES) + .build(); + } + + @Bean + FanoutExchange deadLetterExchange() { + return new FanoutExchange(DLX_EXCHANGE_MESSAGES); + } + + @Bean + Queue deadLetterQueue() { + return QueueBuilder.durable(QUEUE_MESSAGES_DLQ).build(); + } + + @Bean + Binding deadLetterBinding() { + return BindingBuilder.bind(deadLetterQueue()).to(deadLetterExchange()); + } + + @Bean + DirectExchange messagesExchange() { + return new DirectExchange(EXCHANGE_MESSAGES); + } + + @Bean + Binding bindingMessages() { + return BindingBuilder.bind(messagesQueue()).to(messagesExchange()).with(QUEUE_MESSAGES); + } +} diff --git a/spring-amqp/src/main/java/com/baeldung/springamqp/errorhandling/configuration/FatalExceptionStrategyAmqpConfiguration.java b/spring-amqp/src/main/java/com/baeldung/springamqp/errorhandling/configuration/FatalExceptionStrategyAmqpConfiguration.java new file mode 100644 index 0000000000..dcd76d7f72 --- /dev/null +++ b/spring-amqp/src/main/java/com/baeldung/springamqp/errorhandling/configuration/FatalExceptionStrategyAmqpConfiguration.java @@ -0,0 +1,63 @@ +package com.baeldung.springamqp.errorhandling.configuration; + +import com.baeldung.springamqp.errorhandling.errorhandler.CustomFatalExceptionStrategy; +import org.springframework.amqp.core.Binding; +import org.springframework.amqp.core.BindingBuilder; +import org.springframework.amqp.core.DirectExchange; +import org.springframework.amqp.core.Queue; +import org.springframework.amqp.core.QueueBuilder; +import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory; +import org.springframework.amqp.rabbit.connection.ConnectionFactory; +import org.springframework.amqp.rabbit.listener.ConditionalRejectingErrorHandler; +import org.springframework.amqp.rabbit.listener.FatalExceptionStrategy; +import org.springframework.boot.autoconfigure.amqp.SimpleRabbitListenerContainerFactoryConfigurer; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.util.ErrorHandler; + +import static com.baeldung.springamqp.errorhandling.configuration.SimpleDLQAmqpConfiguration.EXCHANGE_MESSAGES; +import static com.baeldung.springamqp.errorhandling.configuration.SimpleDLQAmqpConfiguration.QUEUE_MESSAGES; + +@Configuration +@ConditionalOnProperty( + value = "amqp.configuration.current", + havingValue = "fatal-error-strategy") +public class FatalExceptionStrategyAmqpConfiguration { + + @Bean + public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory( + ConnectionFactory connectionFactory, + SimpleRabbitListenerContainerFactoryConfigurer configurer) { + SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory(); + configurer.configure(factory, connectionFactory); + factory.setErrorHandler(errorHandler()); + return factory; + } + + @Bean + public ErrorHandler errorHandler() { + return new ConditionalRejectingErrorHandler(customExceptionStrategy()); + } + + @Bean + FatalExceptionStrategy customExceptionStrategy() { + return new CustomFatalExceptionStrategy(); + } + + @Bean + Queue messagesQueue() { + return QueueBuilder.durable(QUEUE_MESSAGES) + .build(); + } + + @Bean + DirectExchange messagesExchange() { + return new DirectExchange(EXCHANGE_MESSAGES); + } + + @Bean + Binding bindingMessages() { + return BindingBuilder.bind(messagesQueue()).to(messagesExchange()).with(QUEUE_MESSAGES); + } +} diff --git a/spring-amqp/src/main/java/com/baeldung/springamqp/errorhandling/configuration/ListenerErrorHandlerAmqpConfiguration.java b/spring-amqp/src/main/java/com/baeldung/springamqp/errorhandling/configuration/ListenerErrorHandlerAmqpConfiguration.java new file mode 100644 index 0000000000..8990381da2 --- /dev/null +++ b/spring-amqp/src/main/java/com/baeldung/springamqp/errorhandling/configuration/ListenerErrorHandlerAmqpConfiguration.java @@ -0,0 +1,55 @@ +package com.baeldung.springamqp.errorhandling.configuration; + +import com.baeldung.springamqp.errorhandling.errorhandler.CustomErrorHandler; +import org.springframework.amqp.core.Binding; +import org.springframework.amqp.core.BindingBuilder; +import org.springframework.amqp.core.DirectExchange; +import org.springframework.amqp.core.Queue; +import org.springframework.amqp.core.QueueBuilder; +import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory; +import org.springframework.amqp.rabbit.connection.ConnectionFactory; +import org.springframework.boot.autoconfigure.amqp.SimpleRabbitListenerContainerFactoryConfigurer; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.util.ErrorHandler; + +import static com.baeldung.springamqp.errorhandling.configuration.SimpleDLQAmqpConfiguration.EXCHANGE_MESSAGES; +import static com.baeldung.springamqp.errorhandling.configuration.SimpleDLQAmqpConfiguration.QUEUE_MESSAGES; + +@Configuration +@ConditionalOnProperty( + value = "amqp.configuration.current", + havingValue = "listener-error") +public class ListenerErrorHandlerAmqpConfiguration { + + @Bean + public ErrorHandler errorHandler() { + return new CustomErrorHandler(); + } + + @Bean + public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory(ConnectionFactory connectionFactory, + SimpleRabbitListenerContainerFactoryConfigurer configurer) { + SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory(); + configurer.configure(factory, connectionFactory); + factory.setErrorHandler(errorHandler()); + return factory; + } + + @Bean + Queue messagesQueue() { + return QueueBuilder.durable(QUEUE_MESSAGES) + .build(); + } + + @Bean + DirectExchange messagesExchange() { + return new DirectExchange(EXCHANGE_MESSAGES); + } + + @Bean + Binding bindingMessages() { + return BindingBuilder.bind(messagesQueue()).to(messagesExchange()).with(QUEUE_MESSAGES); + } +} diff --git a/spring-amqp/src/main/java/com/baeldung/springamqp/errorhandling/configuration/RoutingKeyDLQAmqpConfiguration.java b/spring-amqp/src/main/java/com/baeldung/springamqp/errorhandling/configuration/RoutingKeyDLQAmqpConfiguration.java new file mode 100644 index 0000000000..defabed306 --- /dev/null +++ b/spring-amqp/src/main/java/com/baeldung/springamqp/errorhandling/configuration/RoutingKeyDLQAmqpConfiguration.java @@ -0,0 +1,55 @@ +package com.baeldung.springamqp.errorhandling.configuration; + +import org.springframework.amqp.core.Binding; +import org.springframework.amqp.core.BindingBuilder; +import org.springframework.amqp.core.DirectExchange; +import org.springframework.amqp.core.FanoutExchange; +import org.springframework.amqp.core.Queue; +import org.springframework.amqp.core.QueueBuilder; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import static com.baeldung.springamqp.errorhandling.configuration.SimpleDLQAmqpConfiguration.EXCHANGE_MESSAGES; +import static com.baeldung.springamqp.errorhandling.configuration.SimpleDLQAmqpConfiguration.QUEUE_MESSAGES; +import static com.baeldung.springamqp.errorhandling.configuration.SimpleDLQAmqpConfiguration.QUEUE_MESSAGES_DLQ; + +@Configuration +@ConditionalOnProperty( + value = "amqp.configuration.current", + havingValue = "routing-dlq") +public class RoutingKeyDLQAmqpConfiguration { + public static final String DLX_EXCHANGE_MESSAGES = QUEUE_MESSAGES + ".dlx"; + + @Bean + Queue messagesQueue() { + return QueueBuilder.durable(QUEUE_MESSAGES) + .withArgument("x-dead-letter-exchange", DLX_EXCHANGE_MESSAGES) + .build(); + } + + @Bean + FanoutExchange deadLetterExchange() { + return new FanoutExchange(DLX_EXCHANGE_MESSAGES); + } + + @Bean + Queue deadLetterQueue() { + return QueueBuilder.durable(QUEUE_MESSAGES_DLQ).build(); + } + + @Bean + Binding deadLetterBinding() { + return BindingBuilder.bind(deadLetterQueue()).to(deadLetterExchange()); + } + + @Bean + DirectExchange messagesExchange() { + return new DirectExchange(EXCHANGE_MESSAGES); + } + + @Bean + Binding bindingMessages() { + return BindingBuilder.bind(messagesQueue()).to(messagesExchange()).with(QUEUE_MESSAGES); + } +} diff --git a/spring-amqp/src/main/java/com/baeldung/springamqp/errorhandling/configuration/SimpleDLQAmqpConfiguration.java b/spring-amqp/src/main/java/com/baeldung/springamqp/errorhandling/configuration/SimpleDLQAmqpConfiguration.java new file mode 100644 index 0000000000..ea129986ca --- /dev/null +++ b/spring-amqp/src/main/java/com/baeldung/springamqp/errorhandling/configuration/SimpleDLQAmqpConfiguration.java @@ -0,0 +1,43 @@ +package com.baeldung.springamqp.errorhandling.configuration; + +import org.springframework.amqp.core.Binding; +import org.springframework.amqp.core.BindingBuilder; +import org.springframework.amqp.core.DirectExchange; +import org.springframework.amqp.core.Queue; +import org.springframework.amqp.core.QueueBuilder; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +@ConditionalOnProperty( + value = "amqp.configuration.current", + havingValue = "simple-dlq") +public class SimpleDLQAmqpConfiguration { + public static final String QUEUE_MESSAGES = "baeldung-messages-queue"; + public static final String QUEUE_MESSAGES_DLQ = QUEUE_MESSAGES + ".dlq"; + public static final String EXCHANGE_MESSAGES = "baeldung-messages-exchange"; + + @Bean + Queue messagesQueue() { + return QueueBuilder.durable(QUEUE_MESSAGES) + .withArgument("x-dead-letter-exchange", "") + .withArgument("x-dead-letter-routing-key", QUEUE_MESSAGES_DLQ) + .build(); + } + + @Bean + Queue deadLetterQueue() { + return QueueBuilder.durable(QUEUE_MESSAGES_DLQ).build(); + } + + @Bean + DirectExchange messagesExchange() { + return new DirectExchange(EXCHANGE_MESSAGES); + } + + @Bean + Binding bindingMessages() { + return BindingBuilder.bind(messagesQueue()).to(messagesExchange()).with(QUEUE_MESSAGES); + } +} diff --git a/spring-amqp/src/main/java/com/baeldung/springamqp/errorhandling/consumer/DLQCustomAmqpContainer.java b/spring-amqp/src/main/java/com/baeldung/springamqp/errorhandling/consumer/DLQCustomAmqpContainer.java new file mode 100644 index 0000000000..62907abee9 --- /dev/null +++ b/spring-amqp/src/main/java/com/baeldung/springamqp/errorhandling/consumer/DLQCustomAmqpContainer.java @@ -0,0 +1,35 @@ +package com.baeldung.springamqp.errorhandling.consumer; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.amqp.core.Message; +import org.springframework.amqp.rabbit.annotation.RabbitListener; +import org.springframework.amqp.rabbit.core.RabbitTemplate; + +import static com.baeldung.springamqp.errorhandling.configuration.SimpleDLQAmqpConfiguration.EXCHANGE_MESSAGES; +import static com.baeldung.springamqp.errorhandling.configuration.SimpleDLQAmqpConfiguration.QUEUE_MESSAGES_DLQ; +import static com.baeldung.springamqp.errorhandling.consumer.MessagesConsumer.HEADER_X_RETRIES_COUNT; + +public class DLQCustomAmqpContainer { + private static final Logger log = LoggerFactory.getLogger(DLQCustomAmqpContainer.class); + private final RabbitTemplate rabbitTemplate; + public static final int MAX_RETRIES_COUNT = 2; + + public DLQCustomAmqpContainer(RabbitTemplate rabbitTemplate) { + this.rabbitTemplate = rabbitTemplate; + } + + @RabbitListener(queues = QUEUE_MESSAGES_DLQ) + public void processFailedMessagesRetryHeaders(Message failedMessage) { + Integer retriesCnt = (Integer) failedMessage.getMessageProperties().getHeaders().get(HEADER_X_RETRIES_COUNT); + if (retriesCnt == null) + retriesCnt = 1; + if (retriesCnt > MAX_RETRIES_COUNT) { + log.info("Discarding message"); + return; + } + log.info("Retrying message for the {} time", retriesCnt); + failedMessage.getMessageProperties().getHeaders().put(HEADER_X_RETRIES_COUNT, ++retriesCnt); + rabbitTemplate.send(EXCHANGE_MESSAGES, failedMessage.getMessageProperties().getReceivedRoutingKey(), failedMessage); + } +} diff --git a/spring-amqp/src/main/java/com/baeldung/springamqp/errorhandling/consumer/MessagesConsumer.java b/spring-amqp/src/main/java/com/baeldung/springamqp/errorhandling/consumer/MessagesConsumer.java new file mode 100644 index 0000000000..17b65c58da --- /dev/null +++ b/spring-amqp/src/main/java/com/baeldung/springamqp/errorhandling/consumer/MessagesConsumer.java @@ -0,0 +1,63 @@ +package com.baeldung.springamqp.errorhandling.consumer; + +import com.baeldung.springamqp.errorhandling.configuration.SimpleDLQAmqpConfiguration; +import com.baeldung.springamqp.errorhandling.errorhandler.BusinessException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.amqp.core.Message; +import org.springframework.amqp.rabbit.annotation.RabbitListener; +import org.springframework.amqp.rabbit.core.RabbitTemplate; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class MessagesConsumer { + public static final String HEADER_X_RETRIES_COUNT = "x-retries-count"; + + + private static final Logger log = LoggerFactory.getLogger(MessagesConsumer.class); + private final RabbitTemplate rabbitTemplate; + + public MessagesConsumer(RabbitTemplate rabbitTemplate) { + this.rabbitTemplate = rabbitTemplate; + } + + @RabbitListener(queues = SimpleDLQAmqpConfiguration.QUEUE_MESSAGES) + public void receiveMessage(Message message) throws BusinessException { + log.info("Received message: {}", message.toString()); + throw new BusinessException(); + } + + @Bean + @ConditionalOnProperty( + value = "amqp.configuration.current", + havingValue = "simple-dlq") + public SimpleDLQAmqpContainer simpleAmqpContainer() { + return new SimpleDLQAmqpContainer(rabbitTemplate); + } + + @Bean + @ConditionalOnProperty( + value = "amqp.configuration.current", + havingValue = "routing-dlq") + public RoutingDLQAmqpContainer routingDLQAmqpContainer() { + return new RoutingDLQAmqpContainer(rabbitTemplate); + } + + @Bean + @ConditionalOnProperty( + value = "amqp.configuration.current", + havingValue = "dlx-custom") + public DLQCustomAmqpContainer dlqAmqpContainer() { + return new DLQCustomAmqpContainer(rabbitTemplate); + } + + @Bean + @ConditionalOnProperty( + value = "amqp.configuration.current", + havingValue = "parking-lot-dlx") + public ParkingLotDLQAmqpContainer parkingLotDLQAmqpContainer() { + return new ParkingLotDLQAmqpContainer(rabbitTemplate); + } +} \ No newline at end of file diff --git a/spring-amqp/src/main/java/com/baeldung/springamqp/errorhandling/consumer/ParkingLotDLQAmqpContainer.java b/spring-amqp/src/main/java/com/baeldung/springamqp/errorhandling/consumer/ParkingLotDLQAmqpContainer.java new file mode 100644 index 0000000000..34dccd408a --- /dev/null +++ b/spring-amqp/src/main/java/com/baeldung/springamqp/errorhandling/consumer/ParkingLotDLQAmqpContainer.java @@ -0,0 +1,43 @@ +package com.baeldung.springamqp.errorhandling.consumer; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.amqp.core.Message; +import org.springframework.amqp.rabbit.annotation.RabbitListener; +import org.springframework.amqp.rabbit.core.RabbitTemplate; + +import static com.baeldung.springamqp.errorhandling.configuration.DLXParkingLotAmqpConfiguration.EXCHANGE_PARKING_LOT; +import static com.baeldung.springamqp.errorhandling.configuration.DLXParkingLotAmqpConfiguration.QUEUE_PARKING_LOT; +import static com.baeldung.springamqp.errorhandling.configuration.SimpleDLQAmqpConfiguration.EXCHANGE_MESSAGES; +import static com.baeldung.springamqp.errorhandling.configuration.SimpleDLQAmqpConfiguration.QUEUE_MESSAGES_DLQ; +import static com.baeldung.springamqp.errorhandling.consumer.MessagesConsumer.HEADER_X_RETRIES_COUNT; + +public class ParkingLotDLQAmqpContainer { + private static final Logger log = LoggerFactory.getLogger(ParkingLotDLQAmqpContainer.class); + private final RabbitTemplate rabbitTemplate; + public static final int MAX_RETRIES_COUNT = 2; + + public ParkingLotDLQAmqpContainer(RabbitTemplate rabbitTemplate) { + this.rabbitTemplate = rabbitTemplate; + } + + @RabbitListener(queues = QUEUE_MESSAGES_DLQ) + public void processFailedMessagesRetryWithParkingLot(Message failedMessage) { + Integer retriesCnt = (Integer) failedMessage.getMessageProperties().getHeaders().get(HEADER_X_RETRIES_COUNT); + if (retriesCnt == null) + retriesCnt = 1; + if (retriesCnt > MAX_RETRIES_COUNT) { + log.info("Sending message to the parking lot queue"); + rabbitTemplate.send(EXCHANGE_PARKING_LOT, failedMessage.getMessageProperties().getReceivedRoutingKey(), failedMessage); + return; + } + log.info("Retrying message for the {} time", retriesCnt); + failedMessage.getMessageProperties().getHeaders().put(HEADER_X_RETRIES_COUNT, ++retriesCnt); + rabbitTemplate.send(EXCHANGE_MESSAGES, failedMessage.getMessageProperties().getReceivedRoutingKey(), failedMessage); + } + + @RabbitListener(queues = QUEUE_PARKING_LOT) + public void processParkingLotQueue(Message failedMessage) { + log.info("Received message in parking lot queue {}", failedMessage.toString()); + } +} diff --git a/spring-amqp/src/main/java/com/baeldung/springamqp/errorhandling/consumer/RoutingDLQAmqpContainer.java b/spring-amqp/src/main/java/com/baeldung/springamqp/errorhandling/consumer/RoutingDLQAmqpContainer.java new file mode 100644 index 0000000000..fedce76880 --- /dev/null +++ b/spring-amqp/src/main/java/com/baeldung/springamqp/errorhandling/consumer/RoutingDLQAmqpContainer.java @@ -0,0 +1,33 @@ +package com.baeldung.springamqp.errorhandling.consumer; + +import com.baeldung.springamqp.errorhandling.configuration.SimpleDLQAmqpConfiguration; +import com.baeldung.springamqp.errorhandling.errorhandler.BusinessException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.amqp.core.Message; +import org.springframework.amqp.rabbit.annotation.RabbitListener; +import org.springframework.amqp.rabbit.core.RabbitTemplate; + +import static com.baeldung.springamqp.errorhandling.configuration.SimpleDLQAmqpConfiguration.EXCHANGE_MESSAGES; +import static com.baeldung.springamqp.errorhandling.configuration.SimpleDLQAmqpConfiguration.QUEUE_MESSAGES_DLQ; + +public class RoutingDLQAmqpContainer { + private static final Logger log = LoggerFactory.getLogger(RoutingDLQAmqpContainer.class); + private final RabbitTemplate rabbitTemplate; + + public RoutingDLQAmqpContainer(RabbitTemplate rabbitTemplate) { + this.rabbitTemplate = rabbitTemplate; + } + + @RabbitListener(queues = SimpleDLQAmqpConfiguration.QUEUE_MESSAGES) + public void receiveMessage(Message message) throws BusinessException { + log.info("Received message: {}", message.toString()); + throw new BusinessException(); + } + + @RabbitListener(queues = QUEUE_MESSAGES_DLQ) + public void processFailedMessagesRequeue(Message failedMessage) { + log.info("Received failed message, requeueing: {}", failedMessage.toString()); + rabbitTemplate.send(EXCHANGE_MESSAGES, failedMessage.getMessageProperties().getReceivedRoutingKey(), failedMessage); + } +} diff --git a/spring-amqp/src/main/java/com/baeldung/springamqp/errorhandling/consumer/SimpleDLQAmqpContainer.java b/spring-amqp/src/main/java/com/baeldung/springamqp/errorhandling/consumer/SimpleDLQAmqpContainer.java new file mode 100644 index 0000000000..6f9da7b587 --- /dev/null +++ b/spring-amqp/src/main/java/com/baeldung/springamqp/errorhandling/consumer/SimpleDLQAmqpContainer.java @@ -0,0 +1,31 @@ +package com.baeldung.springamqp.errorhandling.consumer; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.amqp.core.Message; +import org.springframework.amqp.rabbit.annotation.RabbitListener; +import org.springframework.amqp.rabbit.core.RabbitTemplate; + +import static com.baeldung.springamqp.errorhandling.configuration.SimpleDLQAmqpConfiguration.EXCHANGE_MESSAGES; +import static com.baeldung.springamqp.errorhandling.configuration.SimpleDLQAmqpConfiguration.QUEUE_MESSAGES_DLQ; + +public class SimpleDLQAmqpContainer { + private static final Logger log = LoggerFactory.getLogger(SimpleDLQAmqpContainer.class); + private final RabbitTemplate rabbitTemplate; + + public SimpleDLQAmqpContainer(RabbitTemplate rabbitTemplate) { + this.rabbitTemplate = rabbitTemplate; + } + + @RabbitListener(queues = QUEUE_MESSAGES_DLQ) + public void processFailedMessages(Message message) { + log.info("Received failed message: {}", message.toString()); + } + + @RabbitListener(queues = QUEUE_MESSAGES_DLQ) + public void processFailedMessagesRequeue(Message failedMessage) { + log.info("Received failed message, requeueing: {}", failedMessage.toString()); + log.info("Received failed message, requeueing: {}", failedMessage.getMessageProperties().getReceivedRoutingKey()); + rabbitTemplate.send(EXCHANGE_MESSAGES, failedMessage.getMessageProperties().getReceivedRoutingKey(), failedMessage); + } +} diff --git a/spring-amqp/src/main/java/com/baeldung/springamqp/errorhandling/errorhandler/BusinessException.java b/spring-amqp/src/main/java/com/baeldung/springamqp/errorhandling/errorhandler/BusinessException.java new file mode 100644 index 0000000000..faec96e2aa --- /dev/null +++ b/spring-amqp/src/main/java/com/baeldung/springamqp/errorhandling/errorhandler/BusinessException.java @@ -0,0 +1,4 @@ +package com.baeldung.springamqp.errorhandling.errorhandler; + +public class BusinessException extends Exception { +} diff --git a/spring-amqp/src/main/java/com/baeldung/springamqp/errorhandling/errorhandler/CustomErrorHandler.java b/spring-amqp/src/main/java/com/baeldung/springamqp/errorhandling/errorhandler/CustomErrorHandler.java new file mode 100644 index 0000000000..5c5e9cdf13 --- /dev/null +++ b/spring-amqp/src/main/java/com/baeldung/springamqp/errorhandling/errorhandler/CustomErrorHandler.java @@ -0,0 +1,14 @@ +package com.baeldung.springamqp.errorhandling.errorhandler; + +import org.springframework.amqp.AmqpRejectAndDontRequeueException; +import org.springframework.util.ErrorHandler; + +public class CustomErrorHandler implements ErrorHandler { + + @Override + public void handleError(Throwable t) { + if (!(t.getCause() instanceof BusinessException)) { + throw new AmqpRejectAndDontRequeueException("Error Handler converted exception to fatal", t); + } + } +} diff --git a/spring-amqp/src/main/java/com/baeldung/springamqp/errorhandling/errorhandler/CustomFatalExceptionStrategy.java b/spring-amqp/src/main/java/com/baeldung/springamqp/errorhandling/errorhandler/CustomFatalExceptionStrategy.java new file mode 100644 index 0000000000..e14be4e73c --- /dev/null +++ b/spring-amqp/src/main/java/com/baeldung/springamqp/errorhandling/errorhandler/CustomFatalExceptionStrategy.java @@ -0,0 +1,10 @@ +package com.baeldung.springamqp.errorhandling.errorhandler; + +import org.springframework.amqp.rabbit.listener.ConditionalRejectingErrorHandler; + +public class CustomFatalExceptionStrategy extends ConditionalRejectingErrorHandler.DefaultExceptionStrategy { + @Override + public boolean isFatal(Throwable t) { + return !(t.getCause() instanceof BusinessException); + } +} \ No newline at end of file diff --git a/spring-amqp/src/main/java/com/baeldung/springamqp/errorhandling/producer/MessageProducer.java b/spring-amqp/src/main/java/com/baeldung/springamqp/errorhandling/producer/MessageProducer.java new file mode 100644 index 0000000000..c14fd5bf3b --- /dev/null +++ b/spring-amqp/src/main/java/com/baeldung/springamqp/errorhandling/producer/MessageProducer.java @@ -0,0 +1,24 @@ +package com.baeldung.springamqp.errorhandling.producer; + +import com.baeldung.springamqp.errorhandling.configuration.SimpleDLQAmqpConfiguration; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.amqp.rabbit.core.RabbitTemplate; +import org.springframework.stereotype.Service; + +@Service +public class MessageProducer { + + private static final Logger log = LoggerFactory.getLogger(MessageProducer.class); + private int messageNumber = 0; + private final RabbitTemplate rabbitTemplate; + + public MessageProducer(final RabbitTemplate rabbitTemplate) { + this.rabbitTemplate = rabbitTemplate; + } + + public void sendMessage() { + log.info("Sending message..."); + rabbitTemplate.convertAndSend(SimpleDLQAmqpConfiguration.EXCHANGE_MESSAGES, SimpleDLQAmqpConfiguration.QUEUE_MESSAGES, "Some message id:" + messageNumber++); + } +} \ No newline at end of file diff --git a/spring-amqp/src/main/resources/application.properties b/spring-amqp/src/main/resources/application.properties new file mode 100644 index 0000000000..c0c1cf1b47 --- /dev/null +++ b/spring-amqp/src/main/resources/application.properties @@ -0,0 +1,3 @@ +spring.rabbitmq.listener.simple.default-requeue-rejected=false +spring.main.allow-bean-definition-overriding=true +amqp.configuration.current=parking-lot-dlx \ No newline at end of file diff --git a/spring-boot-config-jpa-error/README.md b/spring-boot-config-jpa-error/README.md new file mode 100644 index 0000000000..39047a4207 --- /dev/null +++ b/spring-boot-config-jpa-error/README.md @@ -0,0 +1,6 @@ +# Spring Boot - DataJpaTest Error + +This module contains examples about a corner case using @DataJpaTest with a multi module project. + +### Relevant Articles: +- [Unable to Find @SpringBootConfiguration with @DataJpaTest](https://www.baeldung.com/spring-boot-unable-to-find-springbootconfiguration-with-datajpatest) diff --git a/spring-boot-configuration/data-jpa-application/pom.xml b/spring-boot-config-jpa-error/data-jpa-application/pom.xml similarity index 76% rename from spring-boot-configuration/data-jpa-application/pom.xml rename to spring-boot-config-jpa-error/data-jpa-application/pom.xml index b1bf6fda43..2952ff4c4c 100644 --- a/spring-boot-configuration/data-jpa-application/pom.xml +++ b/spring-boot-config-jpa-error/data-jpa-application/pom.xml @@ -5,8 +5,8 @@ 0.0.1-SNAPSHOT - com.baeldung.spring-boot-configuration - spring-boot-configuration + com.baeldung.spring-boot-config-jpa-error + spring-boot-config-jpa-error 0.0.1-SNAPSHOT \ No newline at end of file diff --git a/spring-boot-configuration/data-jpa-application/src/main/java/com/baeldung/data/jpa/ApplicationFound.java b/spring-boot-config-jpa-error/data-jpa-application/src/main/java/com/baeldung/data/jpa/ApplicationFound.java similarity index 100% rename from spring-boot-configuration/data-jpa-application/src/main/java/com/baeldung/data/jpa/ApplicationFound.java rename to spring-boot-config-jpa-error/data-jpa-application/src/main/java/com/baeldung/data/jpa/ApplicationFound.java diff --git a/spring-boot-configuration/data-jpa-application/src/main/java/com/baeldung/data/jpa/application/ApplicationNotFound.java b/spring-boot-config-jpa-error/data-jpa-application/src/main/java/com/baeldung/data/jpa/application/ApplicationNotFound.java similarity index 100% rename from spring-boot-configuration/data-jpa-application/src/main/java/com/baeldung/data/jpa/application/ApplicationNotFound.java rename to spring-boot-config-jpa-error/data-jpa-application/src/main/java/com/baeldung/data/jpa/application/ApplicationNotFound.java diff --git a/spring-boot-configuration/data-jpa-application/src/test/java/com/baeldung/data/jpa/DataJpaUnitTest.java b/spring-boot-config-jpa-error/data-jpa-application/src/test/java/com/baeldung/data/jpa/DataJpaUnitTest.java similarity index 100% rename from spring-boot-configuration/data-jpa-application/src/test/java/com/baeldung/data/jpa/DataJpaUnitTest.java rename to spring-boot-config-jpa-error/data-jpa-application/src/test/java/com/baeldung/data/jpa/DataJpaUnitTest.java diff --git a/spring-boot-configuration/data-jpa-library/pom.xml b/spring-boot-config-jpa-error/data-jpa-library/pom.xml similarity index 76% rename from spring-boot-configuration/data-jpa-library/pom.xml rename to spring-boot-config-jpa-error/data-jpa-library/pom.xml index 1534e7ed23..f8b876b65b 100644 --- a/spring-boot-configuration/data-jpa-library/pom.xml +++ b/spring-boot-config-jpa-error/data-jpa-library/pom.xml @@ -5,8 +5,8 @@ 0.0.1-SNAPSHOT - com.baeldung.spring-boot-configuration - spring-boot-configuration + com.baeldung.spring-boot-config-jpa-error + spring-boot-config-jpa-error 0.0.1-SNAPSHOT \ No newline at end of file diff --git a/spring-boot-configuration/data-jpa-library/src/main/java/com/baeldung/data/jpa/libarary/model/Example.java b/spring-boot-config-jpa-error/data-jpa-library/src/main/java/com/baeldung/data/jpa/libarary/model/Example.java similarity index 100% rename from spring-boot-configuration/data-jpa-library/src/main/java/com/baeldung/data/jpa/libarary/model/Example.java rename to spring-boot-config-jpa-error/data-jpa-library/src/main/java/com/baeldung/data/jpa/libarary/model/Example.java diff --git a/spring-boot-configuration/data-jpa-library/src/test/java/com/baeldung/data/jpa/TestApplication.java b/spring-boot-config-jpa-error/data-jpa-library/src/test/java/com/baeldung/data/jpa/TestApplication.java similarity index 100% rename from spring-boot-configuration/data-jpa-library/src/test/java/com/baeldung/data/jpa/TestApplication.java rename to spring-boot-config-jpa-error/data-jpa-library/src/test/java/com/baeldung/data/jpa/TestApplication.java diff --git a/spring-boot-configuration/data-jpa-library/src/test/java/com/baeldung/data/jpa/libarary/DataJpaUnitTest.java b/spring-boot-config-jpa-error/data-jpa-library/src/test/java/com/baeldung/data/jpa/libarary/DataJpaUnitTest.java similarity index 100% rename from spring-boot-configuration/data-jpa-library/src/test/java/com/baeldung/data/jpa/libarary/DataJpaUnitTest.java rename to spring-boot-config-jpa-error/data-jpa-library/src/test/java/com/baeldung/data/jpa/libarary/DataJpaUnitTest.java diff --git a/spring-boot-configuration/pom.xml b/spring-boot-config-jpa-error/pom.xml similarity index 94% rename from spring-boot-configuration/pom.xml rename to spring-boot-config-jpa-error/pom.xml index e4473c3f2d..12087aa610 100644 --- a/spring-boot-configuration/pom.xml +++ b/spring-boot-config-jpa-error/pom.xml @@ -1,8 +1,8 @@ 4.0.0 - com.baeldung.spring-boot-configuration - spring-boot-configuration + com.baeldung.spring-boot-config-jpa-error + spring-boot-config-jpa-error 0.0.1-SNAPSHOT pom diff --git a/spring-boot-configuration/README.md b/spring-boot-configuration/README.md deleted file mode 100644 index c449538a9d..0000000000 --- a/spring-boot-configuration/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# Spring Boot Configuration - -This module contains articles about Spring Boot Configuration. - -### Relevant Articles: diff --git a/spring-boot-di/README.MD b/spring-boot-di/README.MD index 6e2c495b88..cbd42c5609 100644 --- a/spring-boot-di/README.MD +++ b/spring-boot-di/README.MD @@ -8,3 +8,4 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring ### Relevant Articles: - [Spring Component Scanning](https://www.baeldung.com/spring-component-scanning) +- [Spring @ComponentScan – Filter Types](https://www.baeldung.com/spring-componentscan-filter-type) diff --git a/spring-boot-properties/src/test/java/com/baeldung/properties/parentchild/config/ChildConfig2.java b/spring-boot-properties/src/test/java/com/baeldung/properties/parentchild/config/ChildConfig2.java index c15fcbd352..a506060d1c 100644 --- a/spring-boot-properties/src/test/java/com/baeldung/properties/parentchild/config/ChildConfig2.java +++ b/spring-boot-properties/src/test/java/com/baeldung/properties/parentchild/config/ChildConfig2.java @@ -16,7 +16,7 @@ public class ChildConfig2 { } @Bean - public static PropertyPlaceholderConfigurer configurer() { + public static PropertyPlaceholderConfigurer properties() { final PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer(); ppc.setLocations(new ClassPathResource("child.properties")); return ppc; diff --git a/spring-boot-properties/src/test/java/com/baeldung/properties/parentchild/config/ParentConfig2.java b/spring-boot-properties/src/test/java/com/baeldung/properties/parentchild/config/ParentConfig2.java index ddb59a5309..f5376e0c8e 100644 --- a/spring-boot-properties/src/test/java/com/baeldung/properties/parentchild/config/ParentConfig2.java +++ b/spring-boot-properties/src/test/java/com/baeldung/properties/parentchild/config/ParentConfig2.java @@ -16,7 +16,7 @@ public class ParentConfig2 { } @Bean - public static PropertyPlaceholderConfigurer configurer() { + public static PropertyPlaceholderConfigurer properties() { final PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer(); ppc.setLocations(new ClassPathResource("parent.properties")); return ppc; diff --git a/spring-boot-springdoc/README.md b/spring-boot-springdoc/README.md new file mode 100644 index 0000000000..e54f4e926f --- /dev/null +++ b/spring-boot-springdoc/README.md @@ -0,0 +1,3 @@ +### Relevant Articles: +- [Documenting a Spring REST API Using OpenAPI 3.0](https://www.baeldung.com/spring-rest-openapi-documentation) + diff --git a/spring-boot-springdoc/pom.xml b/spring-boot-springdoc/pom.xml new file mode 100644 index 0000000000..a818db6e53 --- /dev/null +++ b/spring-boot-springdoc/pom.xml @@ -0,0 +1,106 @@ + + + 4.0.0 + com.baeldung + spring-boot-springdoc + 0.0.1-SNAPSHOT + spring-boot-springdoc + Project for Springdoc integration + jar + + + parent-boot-2 + com.baeldung + 0.0.1-SNAPSHOT + ../parent-boot-2 + + + + 1.8 + + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + org.springdoc + springdoc-openapi-core + 1.1.45 + + + org.springdoc + springdoc-openapi-ui + 1.1.45 + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + + + integration + + + + org.springframework.boot + spring-boot-maven-plugin + 2.1.8.RELEASE + + + pre-integration-test + + start + + + + post-integration-test + + stop + + + + + + org.springdoc + springdoc-openapi-maven-plugin + 0.2 + + + integration-test + + generate + + + + + http://localhost:8080/api-docs + openapi.json + ${project.build.directory} + + + + + + + + + \ No newline at end of file diff --git a/spring-boot-springdoc/src/main/java/com/baeldung/springdoc/SpringdocApplication.java b/spring-boot-springdoc/src/main/java/com/baeldung/springdoc/SpringdocApplication.java new file mode 100644 index 0000000000..45c7c23621 --- /dev/null +++ b/spring-boot-springdoc/src/main/java/com/baeldung/springdoc/SpringdocApplication.java @@ -0,0 +1,13 @@ +package com.baeldung.springdoc; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class SpringdocApplication { + + public static void main(String[] args) { + SpringApplication.run(SpringdocApplication.class, args); + } + +} diff --git a/spring-boot-springdoc/src/main/java/com/baeldung/springdoc/controller/BookController.java b/spring-boot-springdoc/src/main/java/com/baeldung/springdoc/controller/BookController.java new file mode 100644 index 0000000000..4d7d9e3d85 --- /dev/null +++ b/spring-boot-springdoc/src/main/java/com/baeldung/springdoc/controller/BookController.java @@ -0,0 +1,73 @@ +package com.baeldung.springdoc.controller; + +import java.util.Collection; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PatchMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; + +import com.baeldung.springdoc.exception.BookNotFoundException; +import com.baeldung.springdoc.model.Book; +import com.baeldung.springdoc.repository.BookRepository; + +@RestController +@RequestMapping("/api/book") +public class BookController { + + @Autowired + private BookRepository repository; + + @GetMapping("/{id}") + public Book findById(@PathVariable long id) { + return repository.findById(id) + .orElseThrow(() -> new BookNotFoundException()); + } + + @GetMapping("/") + public Collection findBooks() { + return repository.getBooks(); + } + + @PutMapping("/{id}") + @ResponseStatus(HttpStatus.OK) + public Book updateBook(@PathVariable("id") final String id, @RequestBody final Book book) { + return book; + } + + @PatchMapping("/{id}") + @ResponseStatus(HttpStatus.OK) + public Book patchBook(@PathVariable("id") final String id, @RequestBody final Book book) { + return book; + } + + @PostMapping("/") + @ResponseStatus(HttpStatus.CREATED) + public Book postBook(@NotNull @Valid @RequestBody final Book book) { + return book; + } + + @RequestMapping(method = RequestMethod.HEAD, value = "/") + @ResponseStatus(HttpStatus.OK) + public Book headBook() { + return new Book(); + } + + @DeleteMapping("/{id}") + @ResponseStatus(HttpStatus.OK) + public long deleteBook(@PathVariable final long id) { + return id; + } +} diff --git a/spring-boot-springdoc/src/main/java/com/baeldung/springdoc/exception/BookNotFoundException.java b/spring-boot-springdoc/src/main/java/com/baeldung/springdoc/exception/BookNotFoundException.java new file mode 100644 index 0000000000..632cb683bc --- /dev/null +++ b/spring-boot-springdoc/src/main/java/com/baeldung/springdoc/exception/BookNotFoundException.java @@ -0,0 +1,10 @@ +package com.baeldung.springdoc.exception; + +@SuppressWarnings("serial") +public class BookNotFoundException extends RuntimeException { + + public BookNotFoundException() { + + } + +} \ No newline at end of file diff --git a/spring-boot-springdoc/src/main/java/com/baeldung/springdoc/exception/GlobalControllerExceptionHandler.java b/spring-boot-springdoc/src/main/java/com/baeldung/springdoc/exception/GlobalControllerExceptionHandler.java new file mode 100644 index 0000000000..c829072236 --- /dev/null +++ b/spring-boot-springdoc/src/main/java/com/baeldung/springdoc/exception/GlobalControllerExceptionHandler.java @@ -0,0 +1,24 @@ +package com.baeldung.springdoc.exception; + +import org.springframework.core.convert.ConversionFailedException; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +@RestControllerAdvice +public class GlobalControllerExceptionHandler { + + @ExceptionHandler(ConversionFailedException.class) + @ResponseStatus(HttpStatus.BAD_REQUEST) + public ResponseEntity handleConnversion(RuntimeException ex) { + return new ResponseEntity<>(ex.getMessage(), HttpStatus.BAD_REQUEST); + } + + @ExceptionHandler(BookNotFoundException.class) + @ResponseStatus(HttpStatus.NOT_FOUND) + public ResponseEntity handleBookNotFound(RuntimeException ex) { + return new ResponseEntity<>(ex.getMessage(), HttpStatus.NOT_FOUND); + } +} diff --git a/spring-boot-springdoc/src/main/java/com/baeldung/springdoc/model/Book.java b/spring-boot-springdoc/src/main/java/com/baeldung/springdoc/model/Book.java new file mode 100644 index 0000000000..8f678a7ec2 --- /dev/null +++ b/spring-boot-springdoc/src/main/java/com/baeldung/springdoc/model/Book.java @@ -0,0 +1,41 @@ +package com.baeldung.springdoc.model; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Size; + +public class Book { + + private long id; + + @NotBlank + @Size(min = 0, max = 20) + private String title; + + @NotBlank + @Size(min = 0, max = 30) + private String author; + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getAuthor() { + return author; + } + + public void setAuthor(String author) { + this.author = author; + } +} diff --git a/spring-boot-springdoc/src/main/java/com/baeldung/springdoc/repository/BookRepository.java b/spring-boot-springdoc/src/main/java/com/baeldung/springdoc/repository/BookRepository.java new file mode 100644 index 0000000000..4040ba28c2 --- /dev/null +++ b/spring-boot-springdoc/src/main/java/com/baeldung/springdoc/repository/BookRepository.java @@ -0,0 +1,28 @@ +package com.baeldung.springdoc.repository; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +import org.springframework.stereotype.Repository; + +import com.baeldung.springdoc.model.Book; + +@Repository +public class BookRepository { + + private Map books = new HashMap<>(); + + public Optional findById(long id) { + return Optional.ofNullable(books.get(id)); + } + + public void add(Book book) { + books.put(book.getId(), book); + } + + public Collection getBooks() { + return books.values(); + } +} diff --git a/spring-boot-springdoc/src/main/resources/application.properties b/spring-boot-springdoc/src/main/resources/application.properties new file mode 100644 index 0000000000..f03e90feb6 --- /dev/null +++ b/spring-boot-springdoc/src/main/resources/application.properties @@ -0,0 +1,5 @@ +# custom path for swagger-ui +springdoc.swagger-ui.path=/swagger-ui-custom.html + +# custom path for api docs +springdoc.api-docs.path=/api-docs diff --git a/rxjava-2/src/main/resources/logback.xml b/spring-boot-springdoc/src/main/resources/logback.xml similarity index 74% rename from rxjava-2/src/main/resources/logback.xml rename to spring-boot-springdoc/src/main/resources/logback.xml index 7d900d8ea8..6a07b178e9 100644 --- a/rxjava-2/src/main/resources/logback.xml +++ b/spring-boot-springdoc/src/main/resources/logback.xml @@ -7,6 +7,9 @@ + + + diff --git a/spring-boot-springdoc/src/test/java/com/baeldung/springdoc/SpringContextIntegrationTest.java b/spring-boot-springdoc/src/test/java/com/baeldung/springdoc/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..58c12dc3bc --- /dev/null +++ b/spring-boot-springdoc/src/test/java/com/baeldung/springdoc/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package com.baeldung.springdoc; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + + } + +} diff --git a/spring-cloud/spring-cloud-stream-starters/README.md b/spring-cloud/spring-cloud-stream-starters/README.md index 761d54abbd..5b9b70e4f1 100644 --- a/spring-cloud/spring-cloud-stream-starters/README.md +++ b/spring-cloud/spring-cloud-stream-starters/README.md @@ -1,3 +1,3 @@ -#Revelant Articles: +# Relevant Articles: - [Using a Spring Cloud App Starter](http://www.baeldung.com/spring-cloud-app-starter) diff --git a/spring-cloud/spring-cloud-zuul-fallback/README.md b/spring-cloud/spring-cloud-zuul-fallback/README.md index 2f13c1923b..de5cfcef4b 100644 --- a/spring-cloud/spring-cloud-zuul-fallback/README.md +++ b/spring-cloud/spring-cloud-zuul-fallback/README.md @@ -1,2 +1,2 @@ ### Relevant Articles: -- [Fallback for Zuul Route](TODO) +- [Fallback for Zuul Route](https://www.baeldung.com/spring-zuul-fallback-route) diff --git a/spring-core-3/README.md b/spring-core-3/README.md index 7ca95ae78e..1c5d911402 100644 --- a/spring-core-3/README.md +++ b/spring-core-3/README.md @@ -1,7 +1,7 @@ ## Relevant Articles: - [Understanding getBean() in Spring](https://www.baeldung.com/spring-getbean) -- [Exploring the Spring BeanFactory API](https://www.baeldung.com/spring-beanfactory) +- [Guide to the Spring BeanFactory](https://www.baeldung.com/spring-beanfactory) - [How to use the Spring FactoryBean?](https://www.baeldung.com/spring-factorybean) - [Spring – Injecting Collections](https://www.baeldung.com/spring-injecting-collections) -- More articles: [[<-- prev]](/spring-core-2) \ No newline at end of file +- More articles: [[<-- prev]](/spring-core-2) diff --git a/spring-integration/README.md b/spring-integration/README.md index 2e719a8674..ad46082a04 100644 --- a/spring-integration/README.md +++ b/spring-integration/README.md @@ -7,6 +7,7 @@ This module contains articles about Spring Integration - [Security In Spring Integration](https://www.baeldung.com/spring-integration-security) - [Spring Integration Java DSL](https://www.baeldung.com/spring-integration-java-dsl) - [Using Subflows in Spring Integration](https://www.baeldung.com/spring-integration-subflows) +- [Transaction Support in Spring Integration](https://www.baeldung.com/spring-integration-transaction) ### Running the Sample Executing the `mvn exec:java` maven command (either from the command line or from an IDE) will start up the application. Follow the command prompt for further instructions. diff --git a/spring-mockito/src/test/java/com/baeldung/UserServiceIntegrationUnitTest.java b/spring-mockito/src/test/java/com/baeldung/UserServiceUnitTest.java similarity index 95% rename from spring-mockito/src/test/java/com/baeldung/UserServiceIntegrationUnitTest.java rename to spring-mockito/src/test/java/com/baeldung/UserServiceUnitTest.java index 573a37a9a4..11c7b4d8a8 100644 --- a/spring-mockito/src/test/java/com/baeldung/UserServiceIntegrationUnitTest.java +++ b/spring-mockito/src/test/java/com/baeldung/UserServiceUnitTest.java @@ -12,7 +12,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @ActiveProfiles("test") @RunWith(SpringJUnit4ClassRunner.class) @SpringBootTest(classes = MocksApplication.class) -public class UserServiceIntegrationUnitTest { +public class UserServiceUnitTest { @Autowired private UserService userService; diff --git a/spring-mvc-simple-2/src/main/java/com/baeldung/flash_attributes/Application.java b/spring-mvc-simple-2/src/main/java/com/baeldung/flash_attributes/Application.java new file mode 100644 index 0000000000..0472ba4e7b --- /dev/null +++ b/spring-mvc-simple-2/src/main/java/com/baeldung/flash_attributes/Application.java @@ -0,0 +1,14 @@ +package com.baeldung.flash_attributes; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; + +@SpringBootApplication +public class Application extends SpringBootServletInitializer { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + +} diff --git a/spring-mvc-simple-2/src/main/java/com/baeldung/flash_attributes/controllers/PoemSubmission.java b/spring-mvc-simple-2/src/main/java/com/baeldung/flash_attributes/controllers/PoemSubmission.java new file mode 100644 index 0000000000..6264ea0531 --- /dev/null +++ b/spring-mvc-simple-2/src/main/java/com/baeldung/flash_attributes/controllers/PoemSubmission.java @@ -0,0 +1,49 @@ +package com.baeldung.flash_attributes.controllers; + +import com.baeldung.flash_attributes.model.Poem; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.servlet.mvc.support.RedirectAttributes; +import org.springframework.web.servlet.support.RequestContextUtils; +import org.springframework.web.servlet.view.RedirectView; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; + +@Controller +public class PoemSubmission { + + @GetMapping("/poem/success") + public String getSuccess(HttpServletRequest request) { + Map inputFlashMap = RequestContextUtils.getInputFlashMap(request); + if (inputFlashMap != null) { + Poem poem = (Poem) inputFlashMap.get("poem"); + return "success"; + } else { + return "redirect:/poem/submit"; + } + } + + @PostMapping("/poem/submit") + public RedirectView submitPost( + HttpServletRequest request, + @ModelAttribute Poem poem, + RedirectAttributes redirectAttributes) { + if (Poem.isValidPoem(poem)) { + redirectAttributes.addFlashAttribute("poem", poem); + return new RedirectView("/poem/success", true); + } else { + return new RedirectView("/poem/submit", true); + } + } + + @GetMapping("/poem/submit") + public String submitGet(Model model) { + model.addAttribute("poem", new Poem()); + return "submit"; + } + +} \ No newline at end of file diff --git a/spring-mvc-simple-2/src/main/java/com/baeldung/flash_attributes/model/Poem.java b/spring-mvc-simple-2/src/main/java/com/baeldung/flash_attributes/model/Poem.java new file mode 100644 index 0000000000..bff65456c1 --- /dev/null +++ b/spring-mvc-simple-2/src/main/java/com/baeldung/flash_attributes/model/Poem.java @@ -0,0 +1,39 @@ +package com.baeldung.flash_attributes.model; + +import org.apache.logging.log4j.util.Strings; + +public class Poem { + private String title; + private String author; + private String body; + + public static boolean isValidPoem(Poem poem) { + return poem != null && Strings.isNotBlank(poem.getAuthor()) && Strings.isNotBlank(poem.getBody()) + && Strings.isNotBlank(poem.getTitle()); + } + + public String getTitle() { + return this.title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getBody() { + return this.body; + } + + public void setBody(String body) { + this.body = body; + } + + public String getAuthor() { + return this.author; + } + + public void setAuthor(String author) { + this.author = author; + } + +} diff --git a/spring-mvc-simple-2/src/main/resources/application.properties b/spring-mvc-simple-2/src/main/resources/application.properties index d29338d3d3..aca20f4e3c 100644 --- a/spring-mvc-simple-2/src/main/resources/application.properties +++ b/spring-mvc-simple-2/src/main/resources/application.properties @@ -1,3 +1,9 @@ spring.main.allow-bean-definition-overriding=true + spring.mail.host=localhost -spring.mail.port=8025 \ No newline at end of file +spring.mail.port=8025 + +spring.thymeleaf.cache=false +spring.thymeleaf.enabled=true +spring.thymeleaf.prefix=classpath:/templates/ +spring.thymeleaf.suffix=.html diff --git a/spring-mvc-simple-2/src/main/resources/templates/submit.html b/spring-mvc-simple-2/src/main/resources/templates/submit.html new file mode 100644 index 0000000000..0ed0107c20 --- /dev/null +++ b/spring-mvc-simple-2/src/main/resources/templates/submit.html @@ -0,0 +1,50 @@ + + + + Poetry Contest: Submission + + + +
+ + + + + + + + + + + + + + + +
+ + + +
+ + + +
+ + +