Merge branch 'eugenp:master' into master
This commit is contained in:
		
						commit
						c5777c892c
					
				| @ -8,6 +8,9 @@ import java.util.PriorityQueue; | ||||
| import java.util.Queue; | ||||
| import java.util.stream.Collectors; | ||||
| 
 | ||||
| import lombok.extern.slf4j.Slf4j; | ||||
| 
 | ||||
| @Slf4j | ||||
| public class RouteFinder<T extends GraphNode> { | ||||
|     private final Graph<T> graph; | ||||
|     private final Scorer<T> nextNodeScorer; | ||||
| @ -28,11 +31,11 @@ public class RouteFinder<T extends GraphNode> { | ||||
|         openSet.add(start); | ||||
| 
 | ||||
|         while (!openSet.isEmpty()) { | ||||
|             System.out.println("Open Set contains: " + openSet.stream().map(RouteNode::getCurrent).collect(Collectors.toSet())); | ||||
|             log.debug("Open Set contains: " + openSet.stream().map(RouteNode::getCurrent).collect(Collectors.toSet())); | ||||
|             RouteNode<T> next = openSet.poll(); | ||||
|             System.out.println("Looking at node: " + next); | ||||
|             log.debug("Looking at node: " + next); | ||||
|             if (next.getCurrent().equals(to)) { | ||||
|                 System.out.println("Found our destination!"); | ||||
|                 log.debug("Found our destination!"); | ||||
| 
 | ||||
|                 List<T> route = new ArrayList<>(); | ||||
|                 RouteNode<T> current = next; | ||||
| @ -41,7 +44,7 @@ public class RouteFinder<T extends GraphNode> { | ||||
|                     current = allNodes.get(current.getPrevious()); | ||||
|                 } while (current != null); | ||||
| 
 | ||||
|                 System.out.println("Route: " + route); | ||||
|                 log.debug("Route: " + route); | ||||
|                 return route; | ||||
|             } | ||||
| 
 | ||||
| @ -55,7 +58,7 @@ public class RouteFinder<T extends GraphNode> { | ||||
|                     nextNode.setRouteScore(newScore); | ||||
|                     nextNode.setEstimatedScore(newScore + targetScorer.computeCost(connection, to)); | ||||
|                     openSet.add(nextNode); | ||||
|                     System.out.println("Found a better route to node: " + nextNode); | ||||
|                     log.debug("Found a better route to node: " + nextNode); | ||||
|                 } | ||||
|             }); | ||||
|         } | ||||
|  | ||||
| @ -1,5 +1,7 @@ | ||||
| package com.baeldung.algorithms.astar.underground; | ||||
| 
 | ||||
| import static org.assertj.core.api.Assertions.assertThat; | ||||
| 
 | ||||
| import java.util.HashMap; | ||||
| import java.util.HashSet; | ||||
| import java.util.List; | ||||
| @ -10,9 +12,13 @@ import java.util.stream.Stream; | ||||
| 
 | ||||
| import com.baeldung.algorithms.astar.Graph; | ||||
| import com.baeldung.algorithms.astar.RouteFinder; | ||||
| 
 | ||||
| import lombok.extern.slf4j.Slf4j; | ||||
| 
 | ||||
| import org.junit.Before; | ||||
| import org.junit.Test; | ||||
| 
 | ||||
| @Slf4j | ||||
| public class RouteFinderIntegrationTest { | ||||
| 
 | ||||
|     private Graph<Station> underground; | ||||
| @ -637,7 +643,8 @@ public class RouteFinderIntegrationTest { | ||||
|     @Test | ||||
|     public void findRoute() { | ||||
|         List<Station> route = routeFinder.findRoute(underground.getNode("74"), underground.getNode("7")); | ||||
|         assertThat(route).size().isPositive(); | ||||
| 
 | ||||
|         System.out.println(route.stream().map(Station::getName).collect(Collectors.toList())); | ||||
|         route.stream().map(Station::getName).collect(Collectors.toList()).forEach(station -> log.debug(station)); | ||||
|     } | ||||
| } | ||||
|  | ||||
							
								
								
									
										18
									
								
								apache-kafka/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								apache-kafka/README.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,18 @@ | ||||
| ## Apache Kafka | ||||
| 
 | ||||
| This module contains articles about Apache Kafka. | ||||
| 
 | ||||
| ### Relevant articles | ||||
| - [Kafka Streams vs Kafka Consumer](https://www.baeldung.com/java-kafka-streams-vs-kafka-consumer) | ||||
| - [Kafka Topic Creation Using Java](https://www.baeldung.com/kafka-topic-creation) | ||||
| - [Using Kafka MockConsumer](https://www.baeldung.com/kafka-mockconsumer) | ||||
| - [Using Kafka MockProducer](https://www.baeldung.com/kafka-mockproducer) | ||||
| - [Introduction to KafkaStreams in Java](https://www.baeldung.com/java-kafka-streams) | ||||
| - [Introduction to Kafka Connectors](https://www.baeldung.com/kafka-connectors-guide) | ||||
| - [Kafka Connect Example with MQTT and MongoDB](https://www.baeldung.com/kafka-connect-mqtt-mongodb) | ||||
| - [Building a Data Pipeline with Flink and Kafka](https://www.baeldung.com/kafka-flink-data-pipeline) | ||||
| - [Exactly Once Processing in Kafka with Java](https://www.baeldung.com/kafka-exactly-once) | ||||
| 
 | ||||
| 
 | ||||
| ##### Building the project | ||||
| You can build the project from the command line using: *mvn clean install*, or in an IDE. | ||||
							
								
								
									
										180
									
								
								apache-kafka/pom.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										180
									
								
								apache-kafka/pom.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,180 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <project xmlns="http://maven.apache.org/POM/4.0.0" | ||||
|     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||||
|     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||||
|     <modelVersion>4.0.0</modelVersion> | ||||
|     <artifactId>apache-kafka</artifactId> | ||||
|     <name>apache-kafka</name> | ||||
| 
 | ||||
|     <parent> | ||||
|         <groupId>com.baeldung</groupId> | ||||
|         <artifactId>parent-modules</artifactId> | ||||
|         <version>1.0.0-SNAPSHOT</version> | ||||
|     </parent> | ||||
| 
 | ||||
|     <dependencies> | ||||
|         <dependency> | ||||
|             <groupId>org.apache.kafka</groupId> | ||||
|             <artifactId>kafka-clients</artifactId> | ||||
|             <version>${kafka.version}</version> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.apache.kafka</groupId> | ||||
|             <artifactId>kafka-streams</artifactId> | ||||
|             <version>${kafka.version}</version> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.slf4j</groupId> | ||||
|             <artifactId>slf4j-api</artifactId> | ||||
|             <version>${org.slf4j.version}</version> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.slf4j</groupId> | ||||
|             <artifactId>slf4j-log4j12</artifactId> | ||||
|             <version>${org.slf4j.version}</version> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.apache.flink</groupId> | ||||
|             <artifactId>flink-connector-kafka-0.11_2.11</artifactId> | ||||
|             <version>${flink.version}</version> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.apache.flink</groupId> | ||||
|             <artifactId>flink-streaming-java_2.11</artifactId> | ||||
|             <version>${flink.version}</version> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.apache.flink</groupId> | ||||
|             <artifactId>flink-core</artifactId> | ||||
|             <version>${flink.version}</version> | ||||
|             <exclusions> | ||||
|                 <exclusion> | ||||
|                     <artifactId>commons-logging</artifactId> | ||||
|                     <groupId>commons-logging</groupId> | ||||
|                 </exclusion> | ||||
|             </exclusions> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.apache.flink</groupId> | ||||
|             <artifactId>flink-java</artifactId> | ||||
|             <version>${flink.version}</version> | ||||
|             <exclusions> | ||||
|                 <exclusion> | ||||
|                     <artifactId>commons-logging</artifactId> | ||||
|                     <groupId>commons-logging</groupId> | ||||
|                 </exclusion> | ||||
|             </exclusions> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.apache.flink</groupId> | ||||
|             <artifactId>flink-test-utils_2.11</artifactId> | ||||
|             <version>${flink.version}</version> | ||||
|             <scope>test</scope> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>com.google.guava</groupId> | ||||
|             <artifactId>guava</artifactId> | ||||
|             <version>${guava.version}</version> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.awaitility</groupId> | ||||
|             <artifactId>awaitility</artifactId> | ||||
|             <version>${awaitility.version}</version> | ||||
|             <scope>test</scope> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.awaitility</groupId> | ||||
|             <artifactId>awaitility-proxy</artifactId> | ||||
|             <version>${awaitility.version}</version> | ||||
|             <scope>test</scope> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>com.fasterxml.jackson.datatype</groupId> | ||||
|             <artifactId>jackson-datatype-jsr310</artifactId> | ||||
|             <version>${jackson.version}</version> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>com.fasterxml.jackson.core</groupId> | ||||
|             <artifactId>jackson-databind</artifactId> | ||||
|             <version>${jackson.version}</version> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.assertj</groupId> | ||||
|             <artifactId>assertj-core</artifactId> | ||||
|             <version>${assertj.version}</version> | ||||
|             <scope>test</scope> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.testcontainers</groupId> | ||||
|             <artifactId>kafka</artifactId> | ||||
|             <version>${testcontainers-kafka.version}</version> | ||||
|             <scope>test</scope> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.testcontainers</groupId> | ||||
|             <artifactId>junit-jupiter</artifactId> | ||||
|             <version>${testcontainers-jupiter.version}</version> | ||||
|             <scope>test</scope> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.apache.spark</groupId> | ||||
|             <artifactId>spark-core_2.11</artifactId> | ||||
|             <version>${org.apache.spark.spark-core.version}</version> | ||||
|             <scope>provided</scope> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.apache.spark</groupId> | ||||
|             <artifactId>spark-sql_2.11</artifactId> | ||||
|             <version>${org.apache.spark.spark-core.version}</version> | ||||
|             <scope>provided</scope> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.apache.spark</groupId> | ||||
|             <artifactId>spark-graphx_2.11</artifactId> | ||||
|             <version>${org.apache.spark.spark-core.version}</version> | ||||
|             <scope>provided</scope> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.apache.spark</groupId> | ||||
|             <artifactId>spark-streaming_2.11</artifactId> | ||||
|             <version>${org.apache.spark.spark-core.version}</version> | ||||
|             <scope>provided</scope> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.apache.spark</groupId> | ||||
|             <artifactId>spark-mllib_2.11</artifactId> | ||||
|             <version>${org.apache.spark.spark-core.version}</version> | ||||
|             <scope>provided</scope> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.apache.spark</groupId> | ||||
|             <artifactId>spark-streaming-kafka-0-10_2.11</artifactId> | ||||
|             <version>${org.apache.spark.spark-core.version}</version> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>com.datastax.spark</groupId> | ||||
|             <artifactId>spark-cassandra-connector_2.11</artifactId> | ||||
|             <version>${com.datastax.spark.spark-cassandra-connector.version}</version> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>com.datastax.spark</groupId> | ||||
|             <artifactId>spark-cassandra-connector-java_2.11</artifactId> | ||||
|             <version>${com.datastax.spark.spark-cassandra-connector-java.version}</version> | ||||
|         </dependency> | ||||
|     </dependencies> | ||||
| 
 | ||||
|     <properties> | ||||
|         <assertj.version>3.6.2</assertj.version> | ||||
|         <kafka.version>2.8.0</kafka.version> | ||||
|         <testcontainers-kafka.version>1.15.3</testcontainers-kafka.version> | ||||
|         <testcontainers-jupiter.version>1.15.3</testcontainers-jupiter.version> | ||||
|         <flink.version>1.5.0</flink.version> | ||||
|         <awaitility.version>3.0.0</awaitility.version> | ||||
|         <guava.version>29.0-jre</guava.version> | ||||
|         <org.apache.spark.spark-core.version>2.4.8</org.apache.spark.spark-core.version> | ||||
|         <graphframes.version>0.8.1-spark3.0-s_2.12</graphframes.version> | ||||
|         <com.datastax.spark.spark-cassandra-connector.version>2.5.2</com.datastax.spark.spark-cassandra-connector.version> | ||||
|         <com.datastax.spark.spark-cassandra-connector-java.version>1.6.0-M1</com.datastax.spark.spark-cassandra-connector-java.version> | ||||
|     </properties> | ||||
| 
 | ||||
| </project> | ||||
| @ -0,0 +1,70 @@ | ||||
| package com.baeldung.flink; | ||||
| 
 | ||||
| import com.baeldung.flink.model.Backup; | ||||
| import com.baeldung.flink.model.InputMessage; | ||||
| import com.baeldung.flink.operator.BackupAggregator; | ||||
| import com.baeldung.flink.operator.InputMessageTimestampAssigner; | ||||
| import com.baeldung.flink.operator.WordsCapitalizer; | ||||
| import org.apache.flink.streaming.api.TimeCharacteristic; | ||||
| import org.apache.flink.streaming.api.datastream.DataStream; | ||||
| import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment; | ||||
| import org.apache.flink.streaming.api.windowing.time.Time; | ||||
| import org.apache.flink.streaming.connectors.kafka.FlinkKafkaConsumer011; | ||||
| import org.apache.flink.streaming.connectors.kafka.FlinkKafkaProducer011; | ||||
| 
 | ||||
| import static com.baeldung.flink.connector.Consumers.*; | ||||
| import static com.baeldung.flink.connector.Producers.*; | ||||
| 
 | ||||
| public class FlinkDataPipeline { | ||||
| 
 | ||||
|     public static void capitalize() throws Exception { | ||||
|         String inputTopic = "flink_input"; | ||||
|         String outputTopic = "flink_output"; | ||||
|         String consumerGroup = "baeldung"; | ||||
|         String address = "localhost:9092"; | ||||
| 
 | ||||
|         StreamExecutionEnvironment environment = StreamExecutionEnvironment.getExecutionEnvironment(); | ||||
| 
 | ||||
|         FlinkKafkaConsumer011<String> flinkKafkaConsumer = createStringConsumerForTopic(inputTopic, address, consumerGroup); | ||||
|         flinkKafkaConsumer.setStartFromEarliest(); | ||||
| 
 | ||||
|         DataStream<String> stringInputStream = environment.addSource(flinkKafkaConsumer); | ||||
| 
 | ||||
|         FlinkKafkaProducer011<String> flinkKafkaProducer = createStringProducer(outputTopic, address); | ||||
| 
 | ||||
|         stringInputStream.map(new WordsCapitalizer()) | ||||
|             .addSink(flinkKafkaProducer); | ||||
| 
 | ||||
|         environment.execute(); | ||||
|     } | ||||
| 
 | ||||
|     public static void createBackup() throws Exception { | ||||
|         String inputTopic = "flink_input"; | ||||
|         String outputTopic = "flink_output"; | ||||
|         String consumerGroup = "baeldung"; | ||||
|         String kafkaAddress = "localhost:9092"; | ||||
| 
 | ||||
|         StreamExecutionEnvironment environment = StreamExecutionEnvironment.getExecutionEnvironment(); | ||||
| 
 | ||||
|         environment.setStreamTimeCharacteristic(TimeCharacteristic.EventTime); | ||||
| 
 | ||||
|         FlinkKafkaConsumer011<InputMessage> flinkKafkaConsumer = createInputMessageConsumer(inputTopic, kafkaAddress, consumerGroup); | ||||
|         flinkKafkaConsumer.setStartFromEarliest(); | ||||
| 
 | ||||
|         flinkKafkaConsumer.assignTimestampsAndWatermarks(new InputMessageTimestampAssigner()); | ||||
|         FlinkKafkaProducer011<Backup> flinkKafkaProducer = createBackupProducer(outputTopic, kafkaAddress); | ||||
| 
 | ||||
|         DataStream<InputMessage> inputMessagesStream = environment.addSource(flinkKafkaConsumer); | ||||
| 
 | ||||
|         inputMessagesStream.timeWindowAll(Time.hours(24)) | ||||
|             .aggregate(new BackupAggregator()) | ||||
|             .addSink(flinkKafkaProducer); | ||||
| 
 | ||||
|         environment.execute(); | ||||
|     } | ||||
| 
 | ||||
|     public static void main(String[] args) throws Exception { | ||||
|         createBackup(); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -9,23 +9,20 @@ import java.util.Properties; | ||||
| 
 | ||||
| public class Consumers { | ||||
| 
 | ||||
| public static FlinkKafkaConsumer011<String> createStringConsumerForTopic( | ||||
|   String topic, String kafkaAddress, String kafkaGroup ) { | ||||
|     Properties props = new Properties(); | ||||
|     props.setProperty("bootstrap.servers", kafkaAddress); | ||||
|     props.setProperty("group.id",kafkaGroup); | ||||
|     FlinkKafkaConsumer011<String> consumer = | ||||
|       new FlinkKafkaConsumer011<>(topic, new SimpleStringSchema(),props); | ||||
|     public static FlinkKafkaConsumer011<String> createStringConsumerForTopic(String topic, String kafkaAddress, String kafkaGroup) { | ||||
|         Properties props = new Properties(); | ||||
|         props.setProperty("bootstrap.servers", kafkaAddress); | ||||
|         props.setProperty("group.id", kafkaGroup); | ||||
|         FlinkKafkaConsumer011<String> consumer = new FlinkKafkaConsumer011<>(topic, new SimpleStringSchema(), props); | ||||
| 
 | ||||
|     return consumer; | ||||
| } | ||||
|         return consumer; | ||||
|     } | ||||
| 
 | ||||
|     public static FlinkKafkaConsumer011<InputMessage> createInputMessageConsumer(String topic, String kafkaAddress, String kafkaGroup ) { | ||||
|     public static FlinkKafkaConsumer011<InputMessage> createInputMessageConsumer(String topic, String kafkaAddress, String kafkaGroup) { | ||||
|         Properties properties = new Properties(); | ||||
|         properties.setProperty("bootstrap.servers", kafkaAddress); | ||||
|         properties.setProperty("group.id",kafkaGroup); | ||||
|         FlinkKafkaConsumer011<InputMessage> consumer = new FlinkKafkaConsumer011<InputMessage>( | ||||
|                 topic, new InputMessageDeserializationSchema(),properties); | ||||
|         properties.setProperty("group.id", kafkaGroup); | ||||
|         FlinkKafkaConsumer011<InputMessage> consumer = new FlinkKafkaConsumer011<InputMessage>(topic, new InputMessageDeserializationSchema(), properties); | ||||
| 
 | ||||
|         return consumer; | ||||
|     } | ||||
| @ -18,6 +18,7 @@ public class InputMessage { | ||||
|     public String getSender() { | ||||
|         return sender; | ||||
|     } | ||||
| 
 | ||||
|     public void setSender(String sender) { | ||||
|         this.sender = sender; | ||||
|     } | ||||
| @ -55,12 +56,14 @@ public class InputMessage { | ||||
| 
 | ||||
|     @Override | ||||
|     public boolean equals(Object o) { | ||||
|         if (this == o) return true; | ||||
|         if (o == null || getClass() != o.getClass()) return false; | ||||
|         if (this == o) | ||||
|             return true; | ||||
|         if (o == null || getClass() != o.getClass()) | ||||
|             return false; | ||||
|         InputMessage message1 = (InputMessage) o; | ||||
|         return Objects.equal(sender, message1.sender) && | ||||
|                 Objects.equal(recipient, message1.recipient) && | ||||
|                 Objects.equal(sentAt, message1.sentAt) && | ||||
|         return Objects.equal(sender, message1.sender) &&  | ||||
|                 Objects.equal(recipient, message1.recipient) &&  | ||||
|                 Objects.equal(sentAt, message1.sentAt) &&  | ||||
|                 Objects.equal(message, message1.message); | ||||
|     } | ||||
| 
 | ||||
| @ -0,0 +1,34 @@ | ||||
| package com.baeldung.flink.operator; | ||||
| 
 | ||||
| import com.baeldung.flink.model.Backup; | ||||
| import com.baeldung.flink.model.InputMessage; | ||||
| import org.apache.flink.api.common.functions.AggregateFunction; | ||||
| 
 | ||||
| import java.time.LocalDateTime; | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
| 
 | ||||
| public class BackupAggregator implements AggregateFunction<InputMessage, List<InputMessage>, Backup> { | ||||
|     @Override | ||||
|     public List<InputMessage> createAccumulator() { | ||||
|         return new ArrayList<>(); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public List<InputMessage> add(InputMessage inputMessage, List<InputMessage> inputMessages) { | ||||
|         inputMessages.add(inputMessage); | ||||
|         return inputMessages; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public Backup getResult(List<InputMessage> inputMessages) { | ||||
|         Backup backup = new Backup(inputMessages, LocalDateTime.now()); | ||||
|         return backup; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public List<InputMessage> merge(List<InputMessage> inputMessages, List<InputMessage> acc1) { | ||||
|         inputMessages.addAll(acc1); | ||||
|         return inputMessages; | ||||
|     } | ||||
| } | ||||
| @ -12,7 +12,9 @@ public class InputMessageTimestampAssigner implements AssignerWithPunctuatedWate | ||||
|     @Override | ||||
|     public long extractTimestamp(InputMessage element, long previousElementTimestamp) { | ||||
|         ZoneId zoneId = ZoneId.systemDefault(); | ||||
|         return element.getSentAt().atZone(zoneId).toEpochSecond() * 1000; | ||||
|         return element.getSentAt() | ||||
|             .atZone(zoneId) | ||||
|             .toEpochSecond() * 1000; | ||||
|     } | ||||
| 
 | ||||
|     @Nullable | ||||
| @ -9,8 +9,7 @@ import org.apache.flink.api.common.serialization.SerializationSchema; | ||||
| import org.slf4j.Logger; | ||||
| import org.slf4j.LoggerFactory; | ||||
| 
 | ||||
| public class BackupSerializationSchema | ||||
|   implements SerializationSchema<Backup> { | ||||
| public class BackupSerializationSchema implements SerializationSchema<Backup> { | ||||
| 
 | ||||
|     static ObjectMapper objectMapper = new ObjectMapper().registerModule(new JavaTimeModule()); | ||||
| 
 | ||||
| @ -18,7 +17,7 @@ public class BackupSerializationSchema | ||||
| 
 | ||||
|     @Override | ||||
|     public byte[] serialize(Backup backupMessage) { | ||||
|         if(objectMapper == null) { | ||||
|         if (objectMapper == null) { | ||||
|             objectMapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY); | ||||
|             objectMapper = new ObjectMapper().registerModule(new JavaTimeModule()); | ||||
|         } | ||||
| @ -8,12 +8,10 @@ import org.apache.flink.api.common.typeinfo.TypeInformation; | ||||
| 
 | ||||
| import java.io.IOException; | ||||
| 
 | ||||
| public class InputMessageDeserializationSchema implements | ||||
|       DeserializationSchema<InputMessage> { | ||||
| public class InputMessageDeserializationSchema implements DeserializationSchema<InputMessage> { | ||||
| 
 | ||||
|     static ObjectMapper objectMapper = new ObjectMapper().registerModule(new JavaTimeModule()); | ||||
| 
 | ||||
| 
 | ||||
|     @Override | ||||
|     public InputMessage deserialize(byte[] bytes) throws IOException { | ||||
| 
 | ||||
| @ -27,11 +27,11 @@ public class KafkaTopicApplication { | ||||
|             short replicationFactor = 1; | ||||
|             NewTopic newTopic = new NewTopic(topicName, partitions, replicationFactor); | ||||
| 
 | ||||
|             CreateTopicsResult result = admin.createTopics( | ||||
|               Collections.singleton(newTopic)); | ||||
|             CreateTopicsResult result = admin.createTopics(Collections.singleton(newTopic)); | ||||
| 
 | ||||
|             // get the async result for the new topic creation | ||||
|             KafkaFuture<Void> future = result.values().get(topicName); | ||||
|             KafkaFuture<Void> future = result.values() | ||||
|                 .get(topicName); | ||||
| 
 | ||||
|             // call get() to block until topic creation has completed or failed | ||||
|             future.get(); | ||||
| @ -47,15 +47,13 @@ public class KafkaTopicApplication { | ||||
|             short replicationFactor = 1; | ||||
|             NewTopic newTopic = new NewTopic(topicName, partitions, replicationFactor); | ||||
| 
 | ||||
|             CreateTopicsOptions topicOptions = new CreateTopicsOptions() | ||||
|               .validateOnly(true) | ||||
|               .retryOnQuotaViolation(true); | ||||
|             CreateTopicsOptions topicOptions = new CreateTopicsOptions().validateOnly(true) | ||||
|                 .retryOnQuotaViolation(true); | ||||
| 
 | ||||
|             CreateTopicsResult result = admin.createTopics( | ||||
|               Collections.singleton(newTopic), topicOptions | ||||
|             ); | ||||
|             CreateTopicsResult result = admin.createTopics(Collections.singleton(newTopic), topicOptions); | ||||
| 
 | ||||
|             KafkaFuture<Void> future = result.values().get(topicName); | ||||
|             KafkaFuture<Void> future = result.values() | ||||
|                 .get(topicName); | ||||
|             future.get(); | ||||
|         } | ||||
|     } | ||||
| @ -72,14 +70,12 @@ public class KafkaTopicApplication { | ||||
|             Map<String, String> newTopicConfig = new HashMap<>(); | ||||
|             newTopicConfig.put(TopicConfig.CLEANUP_POLICY_CONFIG, TopicConfig.CLEANUP_POLICY_COMPACT); | ||||
|             newTopicConfig.put(TopicConfig.COMPRESSION_TYPE_CONFIG, "lz4"); | ||||
|             NewTopic newTopic = new NewTopic(topicName, partitions, replicationFactor) | ||||
|               .configs(newTopicConfig); | ||||
|             NewTopic newTopic = new NewTopic(topicName, partitions, replicationFactor).configs(newTopicConfig); | ||||
| 
 | ||||
|             CreateTopicsResult result = admin.createTopics( | ||||
|               Collections.singleton(newTopic) | ||||
|             ); | ||||
|             CreateTopicsResult result = admin.createTopics(Collections.singleton(newTopic)); | ||||
| 
 | ||||
|             KafkaFuture<Void> future = result.values().get(topicName); | ||||
|             KafkaFuture<Void> future = result.values() | ||||
|                 .get(topicName); | ||||
|             future.get(); | ||||
|         } | ||||
|     } | ||||
| @ -19,9 +19,7 @@ public class CountryPopulationConsumer { | ||||
|     private java.util.function.Consumer<Throwable> exceptionConsumer; | ||||
|     private java.util.function.Consumer<CountryPopulation> countryPopulationConsumer; | ||||
| 
 | ||||
|     public CountryPopulationConsumer( | ||||
|             Consumer<String, Integer> consumer, java.util.function.Consumer<Throwable> exceptionConsumer, | ||||
|             java.util.function.Consumer<CountryPopulation> countryPopulationConsumer) { | ||||
|     public CountryPopulationConsumer(Consumer<String, Integer> consumer, java.util.function.Consumer<Throwable> exceptionConsumer, java.util.function.Consumer<CountryPopulation> countryPopulationConsumer) { | ||||
|         this.consumer = consumer; | ||||
|         this.exceptionConsumer = exceptionConsumer; | ||||
|         this.countryPopulationConsumer = countryPopulationConsumer; | ||||
| @ -1,4 +1,4 @@ | ||||
| package com.baeldung.kafka; | ||||
| package com.baeldung.kafka.exactlyonce; | ||||
| 
 | ||||
| import org.apache.kafka.clients.producer.KafkaProducer; | ||||
| import org.apache.kafka.clients.producer.ProducerRecord; | ||||
| @ -24,16 +24,16 @@ public class TransactionalMessageProducer { | ||||
| 
 | ||||
|         producer.initTransactions(); | ||||
| 
 | ||||
|         try{ | ||||
|         try { | ||||
| 
 | ||||
|             producer.beginTransaction(); | ||||
| 
 | ||||
|             Stream.of(DATA_MESSAGE_1, DATA_MESSAGE_2).forEach(s -> producer.send( | ||||
|                     new ProducerRecord<String, String>("input", null, s))); | ||||
|             Stream.of(DATA_MESSAGE_1, DATA_MESSAGE_2) | ||||
|                 .forEach(s -> producer.send(new ProducerRecord<String, String>("input", null, s))); | ||||
| 
 | ||||
|             producer.commitTransaction(); | ||||
| 
 | ||||
|         }catch (KafkaException e){ | ||||
|         } catch (KafkaException e) { | ||||
| 
 | ||||
|             producer.abortTransaction(); | ||||
| 
 | ||||
| @ -1,4 +1,4 @@ | ||||
| package com.baeldung.kafka; | ||||
| package com.baeldung.kafka.exactlyonce; | ||||
| 
 | ||||
| import org.apache.kafka.clients.consumer.ConsumerRecord; | ||||
| import org.apache.kafka.clients.consumer.ConsumerRecords; | ||||
| @ -43,10 +43,11 @@ public class TransactionalWordCount { | ||||
|                 ConsumerRecords<String, String> records = consumer.poll(ofSeconds(60)); | ||||
| 
 | ||||
|                 Map<String, Integer> wordCountMap = records.records(new TopicPartition(INPUT_TOPIC, 0)) | ||||
|                         .stream() | ||||
|                         .flatMap(record -> Stream.of(record.value().split(" "))) | ||||
|                         .map(word -> Tuple.of(word, 1)) | ||||
|                         .collect(Collectors.toMap(tuple -> tuple.getKey(), t1 -> t1.getValue(), (v1, v2) -> v1 + v2)); | ||||
|                     .stream() | ||||
|                     .flatMap(record -> Stream.of(record.value() | ||||
|                         .split(" "))) | ||||
|                     .map(word -> Tuple.of(word, 1)) | ||||
|                     .collect(Collectors.toMap(tuple -> tuple.getKey(), t1 -> t1.getValue(), (v1, v2) -> v1 + v2)); | ||||
| 
 | ||||
|                 producer.beginTransaction(); | ||||
| 
 | ||||
| @ -56,7 +57,8 @@ public class TransactionalWordCount { | ||||
| 
 | ||||
|                 for (TopicPartition partition : records.partitions()) { | ||||
|                     List<ConsumerRecord<String, String>> partitionedRecords = records.records(partition); | ||||
|                     long offset = partitionedRecords.get(partitionedRecords.size() - 1).offset(); | ||||
|                     long offset = partitionedRecords.get(partitionedRecords.size() - 1) | ||||
|                         .offset(); | ||||
| 
 | ||||
|                     offsetsToCommit.put(partition, new OffsetAndMetadata(offset + 1)); | ||||
|                 } | ||||
| @ -72,7 +74,6 @@ public class TransactionalWordCount { | ||||
| 
 | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     private static KafkaConsumer<String, String> createKafkaConsumer() { | ||||
| @ -1,4 +1,4 @@ | ||||
| package com.baeldung.kafka; | ||||
| package com.baeldung.kafka.exactlyonce; | ||||
| 
 | ||||
| public class Tuple { | ||||
| 
 | ||||
| @ -10,8 +10,8 @@ public class Tuple { | ||||
|         this.value = value; | ||||
|     } | ||||
| 
 | ||||
|     public static Tuple of(String key, Integer value){ | ||||
|         return new Tuple(key,value); | ||||
|     public static Tuple of(String key, Integer value) { | ||||
|         return new Tuple(key, value); | ||||
|     } | ||||
| 
 | ||||
|     public String getKey() { | ||||
| @ -15,8 +15,7 @@ public class KafkaProducer { | ||||
|     } | ||||
| 
 | ||||
|     public Future<RecordMetadata> send(String key, String value) { | ||||
|         ProducerRecord record = new ProducerRecord("topic_sports_news", | ||||
|                 key, value); | ||||
|         ProducerRecord record = new ProducerRecord("topic_sports_news", key, value); | ||||
|         return producer.send(record); | ||||
|     } | ||||
| 
 | ||||
| @ -36,5 +35,4 @@ public class KafkaProducer { | ||||
|         producer.commitTransaction(); | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
| } | ||||
| @ -1,4 +1,4 @@ | ||||
| package com.baeldung.kafka.streams; | ||||
| package com.baeldung.kafka.streamsvsconsumer; | ||||
| 
 | ||||
| import org.apache.kafka.clients.consumer.ConsumerConfig; | ||||
| import org.apache.kafka.clients.producer.KafkaProducer; | ||||
| @ -1,61 +1,78 @@ | ||||
| package com.baeldung.kafkastreams; | ||||
| 
 | ||||
| import org.apache.kafka.clients.consumer.ConsumerConfig; | ||||
| import org.apache.kafka.common.serialization.Serde; | ||||
| import org.apache.kafka.common.serialization.Serdes; | ||||
| import org.apache.kafka.streams.KafkaStreams; | ||||
| import org.apache.kafka.streams.StreamsConfig; | ||||
| import org.apache.kafka.streams.kstream.KStream; | ||||
| import org.apache.kafka.streams.kstream.KStreamBuilder; | ||||
| import org.apache.kafka.streams.kstream.KTable; | ||||
| import org.apache.kafka.test.TestUtils; | ||||
| import org.junit.Ignore; | ||||
| import org.junit.Test; | ||||
| 
 | ||||
| import java.io.IOException; | ||||
| import java.io.UncheckedIOException; | ||||
| import java.nio.file.Files; | ||||
| import java.nio.file.Path; | ||||
| import java.util.Arrays; | ||||
| import java.util.Properties; | ||||
| import java.util.regex.Pattern; | ||||
| 
 | ||||
| import org.apache.kafka.clients.consumer.ConsumerConfig; | ||||
| import org.apache.kafka.common.serialization.Serdes; | ||||
| import org.apache.kafka.streams.KafkaStreams; | ||||
| import org.apache.kafka.streams.StreamsBuilder; | ||||
| import org.apache.kafka.streams.StreamsConfig; | ||||
| import org.apache.kafka.streams.Topology; | ||||
| import org.apache.kafka.streams.kstream.KStream; | ||||
| import org.apache.kafka.streams.kstream.KTable; | ||||
| import org.apache.kafka.streams.kstream.Produced; | ||||
| import org.junit.Ignore; | ||||
| import org.junit.Test; | ||||
| 
 | ||||
| public class KafkaStreamsLiveTest { | ||||
|     private String bootstrapServers = "localhost:9092"; | ||||
|     private Path stateDirectory; | ||||
| 
 | ||||
|     @Test | ||||
|     @Ignore("it needs to have kafka broker running on local") | ||||
|     public void shouldTestKafkaStreams() throws InterruptedException { | ||||
|         //given | ||||
|         // given | ||||
|         String inputTopic = "inputTopic"; | ||||
| 
 | ||||
|         Properties streamsConfiguration = new Properties(); | ||||
|         streamsConfiguration.put(StreamsConfig.APPLICATION_ID_CONFIG, "wordcount-live-test"); | ||||
|         streamsConfiguration.put(StreamsConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers); | ||||
|         streamsConfiguration.put(StreamsConfig.DEFAULT_KEY_SERDE_CLASS_CONFIG, Serdes.String().getClass().getName()); | ||||
|         streamsConfiguration.put(StreamsConfig.DEFAULT_VALUE_SERDE_CLASS_CONFIG, Serdes.String().getClass().getName()); | ||||
|         streamsConfiguration.put(StreamsConfig.DEFAULT_KEY_SERDE_CLASS_CONFIG, Serdes.String() | ||||
|             .getClass() | ||||
|             .getName()); | ||||
|         streamsConfiguration.put(StreamsConfig.DEFAULT_VALUE_SERDE_CLASS_CONFIG, Serdes.String() | ||||
|             .getClass() | ||||
|             .getName()); | ||||
|         streamsConfiguration.put(StreamsConfig.COMMIT_INTERVAL_MS_CONFIG, 1000); | ||||
|         streamsConfiguration.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest"); | ||||
|          | ||||
|         // Use a temporary directory for storing state, which will be automatically removed after the test. | ||||
|         streamsConfiguration.put(StreamsConfig.STATE_DIR_CONFIG, TestUtils.tempDirectory().getAbsolutePath()); | ||||
|         try { | ||||
|             this.stateDirectory = Files.createTempDirectory("kafka-streams"); | ||||
|             streamsConfiguration.put(StreamsConfig.STATE_DIR_CONFIG, this.stateDirectory.toAbsolutePath() | ||||
|                 .toString()); | ||||
|         } catch (final IOException e) { | ||||
|             throw new UncheckedIOException("Cannot create temporary directory", e); | ||||
|         } | ||||
| 
 | ||||
|         //when | ||||
|         KStreamBuilder builder = new KStreamBuilder(); | ||||
|         // when | ||||
|         final StreamsBuilder builder = new StreamsBuilder(); | ||||
|         KStream<String, String> textLines = builder.stream(inputTopic); | ||||
|         Pattern pattern = Pattern.compile("\\W+", Pattern.UNICODE_CHARACTER_CLASS); | ||||
| 
 | ||||
|         KTable<String, Long> wordCounts = textLines | ||||
|                 .flatMapValues(value -> Arrays.asList(pattern.split(value.toLowerCase()))) | ||||
|                 .groupBy((key, word) -> word) | ||||
|                 .count(); | ||||
|         KTable<String, Long> wordCounts = textLines.flatMapValues(value -> Arrays.asList(pattern.split(value.toLowerCase()))) | ||||
|             .groupBy((key, word) -> word) | ||||
|             .count(); | ||||
| 
 | ||||
|         wordCounts.foreach((word, count) -> System.out.println("word: " + word + " -> " + count)); | ||||
|         wordCounts.toStream() | ||||
|             .foreach((word, count) -> System.out.println("word: " + word + " -> " + count)); | ||||
| 
 | ||||
|         String outputTopic = "outputTopic"; | ||||
|         final Serde<String> stringSerde = Serdes.String(); | ||||
|         final Serde<Long> longSerde = Serdes.Long(); | ||||
|         wordCounts.to(stringSerde, longSerde, outputTopic); | ||||
| 
 | ||||
|         KafkaStreams streams = new KafkaStreams(builder, streamsConfiguration); | ||||
|         wordCounts.toStream() | ||||
|             .to(outputTopic, Produced.with(Serdes.String(), Serdes.Long())); | ||||
| 
 | ||||
|         final Topology topology = builder.build(); | ||||
|         KafkaStreams streams = new KafkaStreams(topology, streamsConfiguration); | ||||
|         streams.start(); | ||||
| 
 | ||||
|         //then | ||||
|         // then | ||||
|         Thread.sleep(30000); | ||||
|         streams.close(); | ||||
|     } | ||||
							
								
								
									
										3181
									
								
								apache-libraries/src/main/resources/models/en-lemmatizer.dict
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3181
									
								
								apache-libraries/src/main/resources/models/en-lemmatizer.dict
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -2,3 +2,4 @@ | ||||
| 
 | ||||
| - [String API Updates in Java 12](https://www.baeldung.com/java12-string-api) | ||||
| - [New Features in Java 12](https://www.baeldung.com/java-12-new-features) | ||||
| - [Compare the Content of Two Files in Java](https://www.baeldung.com/java-compare-files) | ||||
|  | ||||
| @ -1,48 +1,53 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <project xmlns="http://maven.apache.org/POM/4.0.0" | ||||
|     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||||
|     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||||
|     <modelVersion>4.0.0</modelVersion> | ||||
|     <artifactId>core-java-16</artifactId> | ||||
|     <version>0.1.0-SNAPSHOT</version> | ||||
|     <name>core-java-16</name> | ||||
|     <packaging>jar</packaging> | ||||
|     <url>http://maven.apache.org</url> | ||||
| 	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||||
| 	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||||
| 	<modelVersion>4.0.0</modelVersion> | ||||
| 	<artifactId>core-java-16</artifactId> | ||||
| 	<version>0.1.0-SNAPSHOT</version> | ||||
| 	<name>core-java-16</name> | ||||
| 	<packaging>jar</packaging> | ||||
| 	<url>http://maven.apache.org</url> | ||||
| 
 | ||||
|     <parent> | ||||
|         <groupId>com.baeldung</groupId> | ||||
|         <artifactId>parent-modules</artifactId> | ||||
|         <version>1.0.0-SNAPSHOT</version> | ||||
|         <relativePath>../../</relativePath> | ||||
|     </parent> | ||||
| 	<parent> | ||||
| 		<groupId>com.baeldung</groupId> | ||||
| 		<artifactId>parent-modules</artifactId> | ||||
| 		<version>1.0.0-SNAPSHOT</version> | ||||
| 		<relativePath>../../</relativePath> | ||||
| 	</parent> | ||||
| 
 | ||||
|     <dependencies> | ||||
|         <dependency> | ||||
|             <groupId>org.assertj</groupId> | ||||
|             <artifactId>assertj-core</artifactId> | ||||
|             <version>${assertj.version}</version> | ||||
|             <scope>test</scope> | ||||
|         </dependency> | ||||
|     </dependencies> | ||||
| 	<dependencies> | ||||
| 		<dependency> | ||||
| 			<groupId>org.assertj</groupId> | ||||
| 			<artifactId>assertj-core</artifactId> | ||||
| 			<version>${assertj.version}</version> | ||||
| 			<scope>test</scope> | ||||
| 		</dependency> | ||||
| 		<dependency> | ||||
| 			<groupId>org.apache.commons</groupId> | ||||
| 			<artifactId>commons-lang3</artifactId> | ||||
| 			<version>3.12.0</version> | ||||
| 		</dependency> | ||||
| 	</dependencies> | ||||
| 
 | ||||
|     <build> | ||||
|         <plugins> | ||||
|             <plugin> | ||||
|                 <groupId>org.apache.maven.plugins</groupId> | ||||
|                 <artifactId>maven-compiler-plugin</artifactId> | ||||
|                 <version>${maven-compiler-plugin.version}</version> | ||||
|                 <configuration> | ||||
|                     <source>${maven.compiler.source.version}</source> | ||||
|                     <target>${maven.compiler.target.version}</target> | ||||
|                 </configuration> | ||||
|             </plugin> | ||||
|         </plugins> | ||||
|     </build> | ||||
| 	<build> | ||||
| 		<plugins> | ||||
| 			<plugin> | ||||
| 				<groupId>org.apache.maven.plugins</groupId> | ||||
| 				<artifactId>maven-compiler-plugin</artifactId> | ||||
| 				<version>${maven-compiler-plugin.version}</version> | ||||
| 				<configuration> | ||||
| 					<source>${maven.compiler.source.version}</source> | ||||
| 					<target>${maven.compiler.target.version}</target> | ||||
| 				</configuration> | ||||
| 			</plugin> | ||||
| 		</plugins> | ||||
| 	</build> | ||||
| 
 | ||||
|     <properties> | ||||
|         <maven.compiler.source.version>16</maven.compiler.source.version> | ||||
|         <maven.compiler.target.version>16</maven.compiler.target.version> | ||||
|         <assertj.version>3.6.1</assertj.version> | ||||
|     </properties> | ||||
| 	<properties> | ||||
| 		<maven.compiler.source.version>16</maven.compiler.source.version> | ||||
| 		<maven.compiler.target.version>16</maven.compiler.target.version> | ||||
| 		<assertj.version>3.6.1</assertj.version> | ||||
| 	</properties> | ||||
| 
 | ||||
| </project> | ||||
| @ -0,0 +1,43 @@ | ||||
| package com.baeldung.java_16_features.groupingby; | ||||
| 
 | ||||
| import java.util.IntSummaryStatistics; | ||||
| 
 | ||||
| 
 | ||||
| public class BlogPost { | ||||
|      | ||||
|     private String title; | ||||
|     private String author; | ||||
|     private BlogPostType type; | ||||
|     private int likes; | ||||
|     record AuthPostTypesLikes(String author, BlogPostType type, int likes) {}; | ||||
|     record PostcountTitlesLikesStats(long postCount, String titles, IntSummaryStatistics likesStats){}; | ||||
|     record TitlesBoundedSumOfLikes(String titles, int boundedSumOfLikes) {}; | ||||
|      | ||||
|     public BlogPost(String title, String author, BlogPostType type, int likes) { | ||||
|         this.title = title; | ||||
|         this.author = author; | ||||
|         this.type = type; | ||||
|         this.likes = likes; | ||||
|     } | ||||
| 
 | ||||
|     public String getTitle() { | ||||
|         return title; | ||||
|     } | ||||
| 
 | ||||
|     public String getAuthor() { | ||||
|         return author; | ||||
|     } | ||||
| 
 | ||||
|     public BlogPostType getType() { | ||||
|         return type; | ||||
|     } | ||||
| 
 | ||||
|     public int getLikes() { | ||||
|         return likes; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public String toString() { | ||||
|         return "BlogPost{" + "title='" + title + '\'' + ", type=" + type + ", likes=" + likes + '}'; | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,5 @@ | ||||
| package com.baeldung.java_16_features.groupingby; | ||||
| 
 | ||||
| public enum BlogPostType { | ||||
|     NEWS, REVIEW, GUIDE | ||||
| } | ||||
| @ -0,0 +1,41 @@ | ||||
| package com.baeldung.java_16_features.groupingby; | ||||
| 
 | ||||
| import java.util.Objects; | ||||
| 
 | ||||
| public class Tuple { | ||||
|     private final BlogPostType type; | ||||
|     private final String author; | ||||
| 
 | ||||
|     public Tuple(BlogPostType type, String author) { | ||||
|         this.type = type; | ||||
|         this.author = author; | ||||
|     } | ||||
| 
 | ||||
|     public BlogPostType getType() { | ||||
|         return type; | ||||
|     } | ||||
| 
 | ||||
|     public String getAuthor() { | ||||
|         return author; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public boolean equals(Object o) { | ||||
|         if (this == o) | ||||
|             return true; | ||||
|         if (o == null || getClass() != o.getClass()) | ||||
|             return false; | ||||
|         Tuple tuple = (Tuple) o; | ||||
|         return type == tuple.type && author.equals(tuple.author); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public int hashCode() { | ||||
|         return Objects.hash(type, author); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public String toString() { | ||||
|         return "Tuple{" + "type=" + type + ", author='" + author + '\'' + '}'; | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,302 @@ | ||||
| package com.baeldung.java_16_features.groupingby; | ||||
| 
 | ||||
| import static java.util.Comparator.comparingInt; | ||||
| import static java.util.stream.Collectors.averagingInt; | ||||
| import static java.util.stream.Collectors.counting; | ||||
| import static java.util.stream.Collectors.groupingBy; | ||||
| import static java.util.stream.Collectors.groupingByConcurrent; | ||||
| import static java.util.stream.Collectors.collectingAndThen; | ||||
| import static java.util.stream.Collectors.toMap; | ||||
| import static java.util.stream.Collectors.joining; | ||||
| import static java.util.stream.Collectors.mapping; | ||||
| import static java.util.stream.Collectors.maxBy; | ||||
| import static java.util.stream.Collectors.summarizingInt; | ||||
| import static java.util.stream.Collectors.summingInt; | ||||
| import static java.util.stream.Collectors.toList; | ||||
| import static java.util.stream.Collectors.toSet; | ||||
| import static org.assertj.core.api.Assertions.assertThat; | ||||
| import static org.assertj.core.api.Assertions.offset; | ||||
| import static org.junit.jupiter.api.Assertions.assertEquals; | ||||
| import static org.junit.jupiter.api.Assertions.assertNull; | ||||
| import static org.junit.jupiter.api.Assertions.assertTrue; | ||||
| 
 | ||||
| import java.util.Arrays; | ||||
| import java.util.EnumMap; | ||||
| import java.util.IntSummaryStatistics; | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
| import java.util.Optional; | ||||
| import java.util.Set; | ||||
| import java.util.concurrent.ConcurrentMap; | ||||
| 
 | ||||
| import org.apache.commons.lang3.tuple.ImmutablePair; | ||||
| import org.apache.commons.lang3.tuple.Pair; | ||||
| import org.junit.jupiter.api.Test; | ||||
| 
 | ||||
| public class JavaGroupingByCollectorUnitTest { | ||||
| 
 | ||||
|     private static final List<BlogPost> posts = Arrays.asList(new BlogPost("News item 1", "Author 1", BlogPostType.NEWS, 15), new BlogPost("Tech review 1", "Author 2", BlogPostType.REVIEW, 5), | ||||
|         new BlogPost("Programming guide", "Author 1", BlogPostType.GUIDE, 20), new BlogPost("News item 2", "Author 2", BlogPostType.NEWS, 35), new BlogPost("Tech review 2", "Author 1", BlogPostType.REVIEW, 15)); | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenAListOfPosts_whenGroupedByType_thenGetAMapBetweenTypeAndPosts() { | ||||
|         Map<BlogPostType, List<BlogPost>> postsPerType = posts.stream() | ||||
|             .collect(groupingBy(BlogPost::getType)); | ||||
| 
 | ||||
|         assertEquals(2, postsPerType.get(BlogPostType.NEWS) | ||||
|             .size()); | ||||
|         assertEquals(1, postsPerType.get(BlogPostType.GUIDE) | ||||
|             .size()); | ||||
|         assertEquals(2, postsPerType.get(BlogPostType.REVIEW) | ||||
|             .size()); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenAListOfPosts_whenGroupedByTypeAndTheirTitlesAreJoinedInAString_thenGetAMapBetweenTypeAndCsvTitles() { | ||||
|         Map<BlogPostType, String> postsPerType = posts.stream() | ||||
|             .collect(groupingBy(BlogPost::getType, mapping(BlogPost::getTitle, joining(", ", "Post titles: [", "]")))); | ||||
| 
 | ||||
|         assertEquals("Post titles: [News item 1, News item 2]", postsPerType.get(BlogPostType.NEWS)); | ||||
|         assertEquals("Post titles: [Programming guide]", postsPerType.get(BlogPostType.GUIDE)); | ||||
|         assertEquals("Post titles: [Tech review 1, Tech review 2]", postsPerType.get(BlogPostType.REVIEW)); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenAListOfPosts_whenGroupedByTypeAndSumTheLikes_thenGetAMapBetweenTypeAndPostLikes() { | ||||
|         Map<BlogPostType, Integer> likesPerType = posts.stream() | ||||
|             .collect(groupingBy(BlogPost::getType, summingInt(BlogPost::getLikes))); | ||||
| 
 | ||||
|         assertEquals(50, likesPerType.get(BlogPostType.NEWS) | ||||
|             .intValue()); | ||||
|         assertEquals(20, likesPerType.get(BlogPostType.REVIEW) | ||||
|             .intValue()); | ||||
|         assertEquals(20, likesPerType.get(BlogPostType.GUIDE) | ||||
|             .intValue()); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenAListOfPosts_whenGroupedByTypeInAnEnumMap_thenGetAnEnumMapBetweenTypeAndPosts() { | ||||
|         EnumMap<BlogPostType, List<BlogPost>> postsPerType = posts.stream() | ||||
|             .collect(groupingBy(BlogPost::getType, () -> new EnumMap<>(BlogPostType.class), toList())); | ||||
| 
 | ||||
|         assertEquals(2, postsPerType.get(BlogPostType.NEWS) | ||||
|             .size()); | ||||
|         assertEquals(1, postsPerType.get(BlogPostType.GUIDE) | ||||
|             .size()); | ||||
|         assertEquals(2, postsPerType.get(BlogPostType.REVIEW) | ||||
|             .size()); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenAListOfPosts_whenGroupedByTypeInSets_thenGetAMapBetweenTypesAndSetsOfPosts() { | ||||
|         Map<BlogPostType, Set<BlogPost>> postsPerType = posts.stream() | ||||
|             .collect(groupingBy(BlogPost::getType, toSet())); | ||||
| 
 | ||||
|         assertEquals(2, postsPerType.get(BlogPostType.NEWS) | ||||
|             .size()); | ||||
|         assertEquals(1, postsPerType.get(BlogPostType.GUIDE) | ||||
|             .size()); | ||||
|         assertEquals(2, postsPerType.get(BlogPostType.REVIEW) | ||||
|             .size()); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenAListOfPosts_whenGroupedByTypeConcurrently_thenGetAMapBetweenTypeAndPosts() { | ||||
|         ConcurrentMap<BlogPostType, List<BlogPost>> postsPerType = posts.parallelStream() | ||||
|             .collect(groupingByConcurrent(BlogPost::getType)); | ||||
| 
 | ||||
|         assertEquals(2, postsPerType.get(BlogPostType.NEWS) | ||||
|             .size()); | ||||
|         assertEquals(1, postsPerType.get(BlogPostType.GUIDE) | ||||
|             .size()); | ||||
|         assertEquals(2, postsPerType.get(BlogPostType.REVIEW) | ||||
|             .size()); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenAListOfPosts_whenGroupedByTypeAndAveragingLikes_thenGetAMapBetweenTypeAndAverageNumberOfLikes() { | ||||
|         Map<BlogPostType, Double> averageLikesPerType = posts.stream() | ||||
|             .collect(groupingBy(BlogPost::getType, averagingInt(BlogPost::getLikes))); | ||||
| 
 | ||||
|         assertEquals(25, averageLikesPerType.get(BlogPostType.NEWS) | ||||
|             .intValue()); | ||||
|         assertEquals(20, averageLikesPerType.get(BlogPostType.GUIDE) | ||||
|             .intValue()); | ||||
|         assertEquals(10, averageLikesPerType.get(BlogPostType.REVIEW) | ||||
|             .intValue()); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenAListOfPosts_whenGroupedByTypeAndCounted_thenGetAMapBetweenTypeAndNumberOfPosts() { | ||||
|         Map<BlogPostType, Long> numberOfPostsPerType = posts.stream() | ||||
|             .collect(groupingBy(BlogPost::getType, counting())); | ||||
| 
 | ||||
|         assertEquals(2, numberOfPostsPerType.get(BlogPostType.NEWS) | ||||
|             .intValue()); | ||||
|         assertEquals(1, numberOfPostsPerType.get(BlogPostType.GUIDE) | ||||
|             .intValue()); | ||||
|         assertEquals(2, numberOfPostsPerType.get(BlogPostType.REVIEW) | ||||
|             .intValue()); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenAListOfPosts_whenGroupedByTypeAndMaxingLikes_thenGetAMapBetweenTypeAndMaximumNumberOfLikes() { | ||||
|         Map<BlogPostType, Optional<BlogPost>> maxLikesPerPostType = posts.stream() | ||||
|             .collect(groupingBy(BlogPost::getType, maxBy(comparingInt(BlogPost::getLikes)))); | ||||
| 
 | ||||
|         assertTrue(maxLikesPerPostType.get(BlogPostType.NEWS) | ||||
|             .isPresent()); | ||||
|         assertEquals(35, maxLikesPerPostType.get(BlogPostType.NEWS) | ||||
|             .get() | ||||
|             .getLikes()); | ||||
| 
 | ||||
|         assertTrue(maxLikesPerPostType.get(BlogPostType.GUIDE) | ||||
|             .isPresent()); | ||||
|         assertEquals(20, maxLikesPerPostType.get(BlogPostType.GUIDE) | ||||
|             .get() | ||||
|             .getLikes()); | ||||
| 
 | ||||
|         assertTrue(maxLikesPerPostType.get(BlogPostType.REVIEW) | ||||
|             .isPresent()); | ||||
|         assertEquals(15, maxLikesPerPostType.get(BlogPostType.REVIEW) | ||||
|             .get() | ||||
|             .getLikes()); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenAListOfPosts_whenGroupedByAuthorAndThenByType_thenGetAMapBetweenAuthorAndMapsBetweenTypeAndBlogPosts() { | ||||
|         Map<String, Map<BlogPostType, List<BlogPost>>> map = posts.stream() | ||||
|             .collect(groupingBy(BlogPost::getAuthor, groupingBy(BlogPost::getType))); | ||||
| 
 | ||||
|         assertEquals(1, map.get("Author 1") | ||||
|             .get(BlogPostType.NEWS) | ||||
|             .size()); | ||||
|         assertEquals(1, map.get("Author 1") | ||||
|             .get(BlogPostType.GUIDE) | ||||
|             .size()); | ||||
|         assertEquals(1, map.get("Author 1") | ||||
|             .get(BlogPostType.REVIEW) | ||||
|             .size()); | ||||
| 
 | ||||
|         assertEquals(1, map.get("Author 2") | ||||
|             .get(BlogPostType.NEWS) | ||||
|             .size()); | ||||
|         assertEquals(1, map.get("Author 2") | ||||
|             .get(BlogPostType.REVIEW) | ||||
|             .size()); | ||||
|         assertNull(map.get("Author 2") | ||||
|             .get(BlogPostType.GUIDE)); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenAListOfPosts_whenGroupedByTypeAndSummarizingLikes_thenGetAMapBetweenTypeAndSummary() { | ||||
|         Map<BlogPostType, IntSummaryStatistics> likeStatisticsPerType = posts.stream() | ||||
|             .collect(groupingBy(BlogPost::getType, summarizingInt(BlogPost::getLikes))); | ||||
| 
 | ||||
|         IntSummaryStatistics newsLikeStatistics = likeStatisticsPerType.get(BlogPostType.NEWS); | ||||
| 
 | ||||
|         assertEquals(2, newsLikeStatistics.getCount()); | ||||
|         assertEquals(50, newsLikeStatistics.getSum()); | ||||
|         assertEquals(25.0, newsLikeStatistics.getAverage(), 0.001); | ||||
|         assertEquals(35, newsLikeStatistics.getMax()); | ||||
|         assertEquals(15, newsLikeStatistics.getMin()); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenAListOfPosts_whenGroupedByComplexMapPairKeyType_thenGetAMapBetweenPairAndList() { | ||||
| 
 | ||||
|         Map<Pair<BlogPostType, String>, List<BlogPost>> postsPerTypeAndAuthor = posts.stream() | ||||
|             .collect(groupingBy(post -> new ImmutablePair<>(post.getType(), post.getAuthor()))); | ||||
| 
 | ||||
|         List<BlogPost> result = postsPerTypeAndAuthor.get(new ImmutablePair<>(BlogPostType.GUIDE, "Author 1")); | ||||
| 
 | ||||
|         assertThat(result.size()).isEqualTo(1); | ||||
| 
 | ||||
|         BlogPost blogPost = result.get(0); | ||||
| 
 | ||||
|         assertThat(blogPost.getTitle()).isEqualTo("Programming guide"); | ||||
|         assertThat(blogPost.getType()).isEqualTo(BlogPostType.GUIDE); | ||||
|         assertThat(blogPost.getAuthor()).isEqualTo("Author 1"); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenAListOfPosts_whenGroupedByComplexMapKeyType_thenGetAMapBetweenTupleAndList() { | ||||
| 
 | ||||
|         Map<Tuple, List<BlogPost>> postsPerTypeAndAuthor = posts.stream() | ||||
|             .collect(groupingBy(post -> new Tuple(post.getType(), post.getAuthor()))); | ||||
| 
 | ||||
|         List<BlogPost> result = postsPerTypeAndAuthor.get(new Tuple(BlogPostType.GUIDE, "Author 1")); | ||||
| 
 | ||||
|         assertThat(result.size()).isEqualTo(1); | ||||
| 
 | ||||
|         BlogPost blogPost = result.get(0); | ||||
| 
 | ||||
|         assertThat(blogPost.getTitle()).isEqualTo("Programming guide"); | ||||
|         assertThat(blogPost.getType()).isEqualTo(BlogPostType.GUIDE); | ||||
|         assertThat(blogPost.getAuthor()).isEqualTo("Author 1"); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenAListOfPosts_whenGroupedByRecord_thenGetAMapBetweenRecordAndList() { | ||||
| 
 | ||||
|         Map<BlogPost.AuthPostTypesLikes, List<BlogPost>> postsPerTypeAndAuthor = posts.stream() | ||||
|             .collect(groupingBy(post -> new BlogPost.AuthPostTypesLikes(post.getAuthor(), post.getType(), post.getLikes()))); | ||||
| 
 | ||||
|         List<BlogPost> result = postsPerTypeAndAuthor.get(new BlogPost.AuthPostTypesLikes("Author 1", BlogPostType.GUIDE, 20)); | ||||
| 
 | ||||
|         assertThat(result.size()).isEqualTo(1); | ||||
| 
 | ||||
|         BlogPost blogPost = result.get(0); | ||||
| 
 | ||||
|         assertThat(blogPost.getTitle()).isEqualTo("Programming guide"); | ||||
|         assertThat(blogPost.getType()).isEqualTo(BlogPostType.GUIDE); | ||||
|         assertThat(blogPost.getAuthor()).isEqualTo("Author 1"); | ||||
|         assertThat(blogPost.getLikes()).isEqualTo(20); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenListOfPosts_whenGroupedByAuthor_thenGetAMapUsingCollectingAndThen() { | ||||
| 
 | ||||
|         Map<String, BlogPost.PostcountTitlesLikesStats> postsPerAuthor = posts.stream() | ||||
|             .collect(groupingBy(BlogPost::getAuthor, collectingAndThen(toList(), list -> { | ||||
|                 long count = list.stream() | ||||
|                     .map(BlogPost::getTitle) | ||||
|                     .collect(counting()); | ||||
|                 String titles = list.stream() | ||||
|                     .map(BlogPost::getTitle) | ||||
|                     .collect(joining(" : ")); | ||||
|                 IntSummaryStatistics summary = list.stream() | ||||
|                     .collect(summarizingInt(BlogPost::getLikes)); | ||||
|                 return new BlogPost.PostcountTitlesLikesStats(count, titles, summary); | ||||
|             }))); | ||||
| 
 | ||||
|         BlogPost.PostcountTitlesLikesStats result = postsPerAuthor.get("Author 1"); | ||||
|         assertThat(result.postCount()).isEqualTo(3L); | ||||
|         assertThat(result.titles()).isEqualTo("News item 1 : Programming guide : Tech review 2"); | ||||
|         assertThat(result.likesStats().getMax()).isEqualTo(20); | ||||
|         assertThat(result.likesStats().getMin()).isEqualTo(15); | ||||
|         assertThat(result.likesStats().getAverage()).isEqualTo(16.666d, offset(0.001d)); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenListOfPosts_whenGroupedByAuthor_thenGetAMapUsingToMap() { | ||||
| 
 | ||||
|         int maxValLikes = 17; | ||||
|         Map<String, BlogPost.TitlesBoundedSumOfLikes> postsPerAuthor = posts.stream() | ||||
|             .collect(toMap(BlogPost::getAuthor, post -> { | ||||
|                 int likes = (post.getLikes() > maxValLikes) ? maxValLikes : post.getLikes(); | ||||
|                 return new BlogPost.TitlesBoundedSumOfLikes(post.getTitle(), likes); | ||||
|             }, (u1, u2) -> { | ||||
|                 int likes = (u2.boundedSumOfLikes() > maxValLikes) ? maxValLikes : u2.boundedSumOfLikes(); | ||||
|                 return new BlogPost.TitlesBoundedSumOfLikes(u1.titles() | ||||
|                     .toUpperCase() + " : " | ||||
|                     + u2.titles() | ||||
|                         .toUpperCase(), | ||||
|                     u1.boundedSumOfLikes() + likes); | ||||
|             })); | ||||
|          | ||||
|         BlogPost.TitlesBoundedSumOfLikes result = postsPerAuthor.get("Author 1"); | ||||
|         assertThat(result.titles()).isEqualTo("NEWS ITEM 1 : PROGRAMMING GUIDE : TECH REVIEW 2"); | ||||
|         assertThat(result.boundedSumOfLikes()).isEqualTo(47); | ||||
|     } | ||||
| } | ||||
| @ -189,21 +189,8 @@ public class StopExecution { | ||||
|             longRunningSort(); | ||||
|         } | ||||
| 
 | ||||
|         private void longRunningOperation() { | ||||
|             LOG.info("long Running operation started"); | ||||
| 
 | ||||
|             try { | ||||
|                 //Thread.sleep(500); | ||||
|                 longFileRead(); | ||||
|                 LOG.info("long running operation finished"); | ||||
|             } catch (InterruptedException e) { | ||||
|                 LOG.info("long Running operation interrupted"); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         private void longRunningSort() { | ||||
|             LOG.info("long Running task started"); | ||||
|             // Do you long running calculation here | ||||
|             LOG.info("Long running task started"); | ||||
|             int len = 100000; | ||||
|             List<Integer> numbers = new ArrayList<>(); | ||||
|             try { | ||||
| @ -229,25 +216,7 @@ public class StopExecution { | ||||
|                 LOG.info("Index position: " + i); | ||||
|                 LOG.info("Long running task finished"); | ||||
|             } catch (InterruptedException e) { | ||||
|                 LOG.info("long Running operation interrupted"); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         private void longFileRead() throws InterruptedException { | ||||
|             String file = "input.txt"; | ||||
|             ClassLoader classloader = getClass().getClassLoader(); | ||||
| 
 | ||||
|             try (InputStream inputStream = classloader.getResourceAsStream(file)) { | ||||
|                 Reader inputStreamReader = new InputStreamReader(inputStream); | ||||
| 
 | ||||
|                 int data = inputStreamReader.read(); | ||||
|                 while (data != -1) { | ||||
|                     char theChar = (char) data; | ||||
|                     data = inputStreamReader.read(); | ||||
|                     throwExceptionOnThreadInterrupt(); | ||||
|                 } | ||||
|             } catch (IOException e) { | ||||
|                 LOG.error("Exception: ", e); | ||||
|                 LOG.info("Long running operation interrupted"); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|  | ||||
| @ -13,12 +13,9 @@ import java.util.stream.IntStream; | ||||
| public class TimeApi { | ||||
| 
 | ||||
|     public static List<Date> getDatesBetweenUsingJava7(Date startDate, Date endDate) { | ||||
|         List<Date> datesInRange = new ArrayList<Date>(); | ||||
|         Calendar calendar = new GregorianCalendar(); | ||||
|         calendar.setTime(startDate); | ||||
| 
 | ||||
|         Calendar endCalendar = new GregorianCalendar(); | ||||
|         endCalendar.setTime(endDate); | ||||
|         List<Date> datesInRange = new ArrayList<>(); | ||||
|         Calendar calendar = getCalendarWithoutTime(startDate); | ||||
|         Calendar endCalendar = getCalendarWithoutTime(endDate); | ||||
| 
 | ||||
|         while (calendar.before(endCalendar)) { | ||||
|             Date result = calendar.getTime(); | ||||
| @ -40,4 +37,15 @@ public class TimeApi { | ||||
|         return startDate.datesUntil(endDate).collect(Collectors.toList()); | ||||
|     } | ||||
| 
 | ||||
|     private static Calendar getCalendarWithoutTime(Date date) { | ||||
|         Calendar calendar = new GregorianCalendar(); | ||||
|         calendar.setTime(date); | ||||
|         calendar.set(Calendar.HOUR, 0); | ||||
|         calendar.set(Calendar.HOUR_OF_DAY, 0); | ||||
|         calendar.set(Calendar.MINUTE, 0); | ||||
|         calendar.set(Calendar.SECOND, 0); | ||||
|         calendar.set(Calendar.MILLISECOND, 0); | ||||
|         return calendar; | ||||
|     } | ||||
| 
 | ||||
| } | ||||
|  | ||||
| @ -1,12 +1,13 @@ | ||||
| package com.baeldung.java9.time; | ||||
| 
 | ||||
| import org.junit.Test; | ||||
| 
 | ||||
| import java.time.LocalDate; | ||||
| import java.util.Calendar; | ||||
| import java.util.Date; | ||||
| import java.util.List; | ||||
| 
 | ||||
| import static org.junit.Assert.assertEquals; | ||||
| import org.junit.Test; | ||||
| import static org.assertj.core.api.Assertions.assertThat; | ||||
| 
 | ||||
| public class TimeApiUnitTest { | ||||
| 
 | ||||
| @ -18,19 +19,18 @@ public class TimeApiUnitTest { | ||||
|         Date endDate = endCalendar.getTime(); | ||||
| 
 | ||||
|         List<Date> dates = TimeApi.getDatesBetweenUsingJava7(startDate, endDate); | ||||
|         assertEquals(dates.size(), 2); | ||||
| 
 | ||||
|         assertThat(dates).hasSize(2); | ||||
| 
 | ||||
|         Calendar calendar = Calendar.getInstance(); | ||||
|         Date date1 = calendar.getTime(); | ||||
|         assertEquals(dates.get(0).getDay(), date1.getDay()); | ||||
|         assertEquals(dates.get(0).getMonth(), date1.getMonth()); | ||||
|         assertEquals(dates.get(0).getYear(), date1.getYear()); | ||||
|         Date expectedDate1 = calendar.getTime(); | ||||
|         assertThat(dates.get(0)).isInSameDayAs(expectedDate1); | ||||
|         assertThatTimeFieldsAreZero(dates.get(0)); | ||||
| 
 | ||||
|         calendar.add(Calendar.DATE, 1); | ||||
|         Date date2 = calendar.getTime(); | ||||
|         assertEquals(dates.get(1).getDay(), date2.getDay()); | ||||
|         assertEquals(dates.get(1).getMonth(), date2.getMonth()); | ||||
|         assertEquals(dates.get(1).getYear(), date2.getYear()); | ||||
|         Date expectedDate2 = calendar.getTime(); | ||||
|         assertThat(dates.get(1)).isInSameDayAs(expectedDate2); | ||||
|         assertThatTimeFieldsAreZero(dates.get(1)); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
| @ -39,9 +39,8 @@ public class TimeApiUnitTest { | ||||
|         LocalDate endDate = LocalDate.now().plusDays(2); | ||||
| 
 | ||||
|         List<LocalDate> dates = TimeApi.getDatesBetweenUsingJava8(startDate, endDate); | ||||
|         assertEquals(dates.size(), 2); | ||||
|         assertEquals(dates.get(0), LocalDate.now()); | ||||
|         assertEquals(dates.get(1), LocalDate.now().plusDays(1)); | ||||
| 
 | ||||
|         assertThat(dates).containsExactly(LocalDate.now(), LocalDate.now().plusDays(1)); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
| @ -50,9 +49,15 @@ public class TimeApiUnitTest { | ||||
|         LocalDate endDate = LocalDate.now().plusDays(2); | ||||
| 
 | ||||
|         List<LocalDate> dates = TimeApi.getDatesBetweenUsingJava9(startDate, endDate); | ||||
|         assertEquals(dates.size(), 2); | ||||
|         assertEquals(dates.get(0), LocalDate.now()); | ||||
|         assertEquals(dates.get(1), LocalDate.now().plusDays(1)); | ||||
| 
 | ||||
|         assertThat(dates).containsExactly(LocalDate.now(), LocalDate.now().plusDays(1)); | ||||
|     } | ||||
| 
 | ||||
|     private static void assertThatTimeFieldsAreZero(Date date) { | ||||
|         assertThat(date).hasHourOfDay(0); | ||||
|         assertThat(date).hasMinute(0); | ||||
|         assertThat(date).hasSecond(0); | ||||
|         assertThat(date).hasMillisecond(0); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
|  | ||||
| @ -75,7 +75,7 @@ | ||||
| 
 | ||||
|     <properties> | ||||
|         <commons-validator.version>1.6</commons-validator.version> | ||||
|         <joda-time.version>2.10</joda-time.version> | ||||
|         <joda-time.version>2.10.10</joda-time.version> | ||||
|         <!-- testing --> | ||||
|         <assertj.version>3.6.1</assertj.version> | ||||
|         <maven.compiler.source>1.9</maven.compiler.source> | ||||
|  | ||||
| @ -0,0 +1,54 @@ | ||||
| package com.baeldung.formatduration; | ||||
| 
 | ||||
| import org.apache.commons.lang3.time.DurationFormatUtils; | ||||
| import org.joda.time.Period; | ||||
| import org.junit.Test; | ||||
| 
 | ||||
| import java.time.Duration; | ||||
| import java.util.concurrent.TimeUnit; | ||||
| 
 | ||||
| import static org.assertj.core.api.Assertions.assertThat; | ||||
| 
 | ||||
| public class FormatDurationUnitTest { | ||||
| 
 | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenInterval_WhenFormatInterval_formatDuration() { | ||||
|         long HH = TimeUnit.MILLISECONDS.toHours(38114000); | ||||
|         long MM = TimeUnit.MILLISECONDS.toMinutes(38114000) % 60; | ||||
|         long SS = TimeUnit.MILLISECONDS.toSeconds(38114000) % 60; | ||||
|         String timeInHHMMSS = String.format("%02d:%02d:%02d", HH, MM, SS); | ||||
| 
 | ||||
|         assertThat(timeInHHMMSS).isEqualTo("10:35:14"); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenInterval_WhenFormatUsingDuration_formatDuration() { | ||||
|         Duration duration = Duration.ofMillis(38114000); | ||||
|         long seconds = duration.getSeconds(); | ||||
|         long HH = seconds / 3600; | ||||
|         long MM = (seconds % 3600) / 60; | ||||
|         long SS = seconds % 60; | ||||
|         String timeInHHMMSS =  String.format("%02d:%02d:%02d", HH, MM, SS); | ||||
|         assertThat(timeInHHMMSS).isEqualTo("10:35:14"); | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenInterval_WhenFormatDurationUsingApacheCommons_formatDuration() { | ||||
|         assertThat(DurationFormatUtils.formatDuration(38114000, "HH:mm:ss")) | ||||
|           .isEqualTo("10:35:14"); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenInterval_WhenFormatDurationUsingJodaTime_formatDuration() { | ||||
|         org.joda.time.Duration duration = new org.joda.time.Duration(38114000); | ||||
|         Period period = duration.toPeriod(); | ||||
|         long HH = period.getHours(); | ||||
|         long MM = period.getMinutes(); | ||||
|         long SS = period.getSeconds(); | ||||
| 
 | ||||
|         String timeInHHMMSS = String.format("%02d:%02d:%02d", HH, MM, SS); | ||||
|         assertThat(timeInHHMMSS).isEqualTo("10:35:14"); | ||||
|     } | ||||
| } | ||||
| @ -7,3 +7,4 @@ This module contains article about constructors in Java | ||||
| - [Java Copy Constructor](https://www.baeldung.com/java-copy-constructor) | ||||
| - [Cannot Reference “X” Before Supertype Constructor Has Been Called](https://www.baeldung.com/java-cannot-reference-x-before-supertype-constructor-error) | ||||
| - [Private Constructors in Java](https://www.baeldung.com/java-private-constructors) | ||||
| - [Throwing Exceptions in Constructors](https://www.baeldung.com/java-constructors-exceptions) | ||||
|  | ||||
| @ -0,0 +1,32 @@ | ||||
| package com.baeldung.constructors.exception; | ||||
| 
 | ||||
| import java.io.File; | ||||
| import java.io.IOException; | ||||
| 
 | ||||
| public class Animal { | ||||
| 
 | ||||
|     public Animal() throws InstantiationException { | ||||
|         throw new InstantiationException("Cannot be instantiated"); | ||||
|     } | ||||
| 
 | ||||
|     public Animal(String id, int age) { | ||||
|         if (id == null) | ||||
|             throw new NullPointerException("Id cannot be null"); | ||||
|         if (age < 0) | ||||
|             throw new IllegalArgumentException("Age cannot be negative"); | ||||
|     } | ||||
| 
 | ||||
|     public Animal(File file) throws SecurityException, IOException { | ||||
|         // Avoiding Path traversal attacks | ||||
|         if (file.isAbsolute()) { | ||||
|             throw new SecurityException("Traversal attack - absolute path not allowed"); | ||||
|         } | ||||
|         // Avoiding directory traversal | ||||
|         // a/../..b/ | ||||
|         if (!file.getCanonicalPath() | ||||
|             .equals(file.getAbsolutePath())) { | ||||
|             throw new SecurityException("Directory traversal attempt?"); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,13 @@ | ||||
| package com.baeldung.constructors.exception; | ||||
| 
 | ||||
| public class Bird extends Animal { | ||||
| 
 | ||||
|     // Note that we are throwing parent exception | ||||
|     public Bird() throws ReflectiveOperationException { | ||||
|         super(); | ||||
|     } | ||||
| 
 | ||||
|     public Bird(String id, int age) { | ||||
|         super(id, age); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,47 @@ | ||||
| package com.baeldung.constructors.exception; | ||||
| 
 | ||||
| import java.io.File; | ||||
| 
 | ||||
| import org.assertj.core.api.Assertions; | ||||
| import org.junit.Test; | ||||
| 
 | ||||
| public class AnimalUnitTest { | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenNoArgument_thenFails() { | ||||
|         Assertions.assertThatThrownBy(() -> { | ||||
|             new Animal(); | ||||
|         }) | ||||
|             .isInstanceOf(Exception.class); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenInvalidArg_thenFails() { | ||||
|         Assertions.assertThatThrownBy(() -> { | ||||
|             new Animal(null, 30); | ||||
|         }) | ||||
|             .isInstanceOf(NullPointerException.class); | ||||
|     } | ||||
| 
 | ||||
|     @Test(expected = Test.None.class) | ||||
|     public void givenValidArg_thenSuccess() { | ||||
|         new Animal("1234", 30); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenAbsolutePath_thenFails() { | ||||
|         Assertions.assertThatThrownBy(() -> { | ||||
|             new Animal(new File("temp.txt").getAbsoluteFile()); | ||||
|         }) | ||||
|             .isInstanceOf(SecurityException.class); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenDirectoryTraversalPath_thenFails() { | ||||
|         Assertions.assertThatThrownBy(() -> { | ||||
|             new Animal(new File(File.separator + ".." + File.separator + "temp.txt")); | ||||
|         }) | ||||
|             .isInstanceOf(SecurityException.class); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -5,3 +5,4 @@ This module contains articles about Java operators | ||||
| ## Relevant Articles: | ||||
| 
 | ||||
| - [Logical vs Bitwise OR Operator](https://www.baeldung.com/java-logical-vs-bitwise-or-operator) | ||||
| - [Bitmasking in Java with Bitwise Operators](https://www.baeldung.com/java-bitmasking) | ||||
|  | ||||
| @ -25,9 +25,9 @@ public class GrepWithUnix4JIntegrationTest { | ||||
| 
 | ||||
|     @Test | ||||
|     public void whenGrepWithSimpleString_thenCorrect() { | ||||
|         int expectedLineCount = 4; | ||||
|         int expectedLineCount = 5; | ||||
| 
 | ||||
|         // grep "NINETEEN" dictionary.txt | ||||
|         // grep "NINETEEN" dictionary.in | ||||
|         List<Line> lines = Unix4j.grep("NINETEEN", fileToGrep).toLineList(); | ||||
| 
 | ||||
|         assertEquals(expectedLineCount, lines.size()); | ||||
| @ -35,9 +35,9 @@ public class GrepWithUnix4JIntegrationTest { | ||||
| 
 | ||||
|     @Test | ||||
|     public void whenInverseGrepWithSimpleString_thenCorrect() { | ||||
|         int expectedLineCount = 178687; | ||||
|         int expectedLineCount = 8; | ||||
| 
 | ||||
|         // grep -v "NINETEEN" dictionary.txt | ||||
|         // grep -v "NINETEEN" dictionary.in | ||||
|         List<Line> lines = grep(Options.v, "NINETEEN", fileToGrep).toLineList(); | ||||
| 
 | ||||
|         assertEquals(expectedLineCount, lines.size()); | ||||
| @ -45,9 +45,9 @@ public class GrepWithUnix4JIntegrationTest { | ||||
| 
 | ||||
|     @Test | ||||
|     public void whenGrepWithRegex_thenCorrect() { | ||||
|         int expectedLineCount = 151; | ||||
|         int expectedLineCount = 5; | ||||
| 
 | ||||
|         // grep -c ".*?NINE.*?" dictionary.txt | ||||
|         // grep -c ".*?NINE.*?" dictionary.in | ||||
|         String patternCount = grep(Options.c, ".*?NINE.*?", fileToGrep).cut(fields, ":", 1).toStringResult(); | ||||
| 
 | ||||
|         assertEquals(expectedLineCount, Integer.parseInt(patternCount)); | ||||
|  | ||||
| @ -0,0 +1,13 @@ | ||||
| EIGHTTEEN | ||||
| EIGHTTEENS | ||||
| EIGHTTEENTH | ||||
| EIGHTTEENTHS | ||||
| NINETEEN | ||||
| NINETEENS | ||||
| NINETEENTH | ||||
| NINETEENTHS | ||||
| TWENTY | ||||
| TWENTHIES | ||||
| TWENTHIETH | ||||
| TWENTHIETHS | ||||
| TWENTYNINETEEN | ||||
| @ -4,3 +4,4 @@ | ||||
| - [Java (String) or .toString()?](https://www.baeldung.com/java-string-casting-vs-tostring) | ||||
| - [Split Java String by Newline](https://www.baeldung.com/java-string-split-by-newline) | ||||
| - [Split a String in Java and Keep the Delimiters](https://www.baeldung.com/java-split-string-keep-delimiters) | ||||
| - [Validate String as Filename in Java](https://www.baeldung.com/java-validate-filename) | ||||
|  | ||||
| @ -0,0 +1,61 @@ | ||||
| package com.baeldung.stringfilenamevalidaiton; | ||||
| 
 | ||||
| import java.io.File; | ||||
| import java.io.IOException; | ||||
| import java.nio.file.Paths; | ||||
| import java.util.Arrays; | ||||
| 
 | ||||
| public class StringFilenameValidationUtils { | ||||
| 
 | ||||
|     public static final Character[] INVALID_WINDOWS_SPECIFIC_CHARS = {'"', '*', ':', '<', '>', '?', '\\', '|', 0x7F}; | ||||
|     public static final Character[] INVALID_UNIX_SPECIFIC_CHARS = {'\000'}; | ||||
| 
 | ||||
|     public static final String REGEX_PATTERN = "^[A-za-z0-9.]{1,255}$"; | ||||
| 
 | ||||
|     private StringFilenameValidationUtils() { | ||||
|     } | ||||
| 
 | ||||
|     public static boolean validateStringFilenameUsingIO(String filename) throws IOException { | ||||
|         File file = new File(filename); | ||||
|         boolean created = false; | ||||
|         try { | ||||
|             created = file.createNewFile(); | ||||
|             return created; | ||||
|         } finally { | ||||
|             if (created) { | ||||
|                 file.delete(); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public static boolean validateStringFilenameUsingNIO2(String filename) { | ||||
|         Paths.get(filename); | ||||
|         return true; | ||||
|     } | ||||
| 
 | ||||
|     public static boolean validateStringFilenameUsingContains(String filename) { | ||||
|         if (filename == null || filename.isEmpty() || filename.length() > 255) { | ||||
|             return false; | ||||
|         } | ||||
|         return Arrays.stream(getInvalidCharsByOS()) | ||||
|             .noneMatch(ch -> filename.contains(ch.toString())); | ||||
|     } | ||||
| 
 | ||||
|     public static boolean validateStringFilenameUsingRegex(String filename) { | ||||
|         if (filename == null) { | ||||
|             return false; | ||||
|         } | ||||
|         return filename.matches(REGEX_PATTERN); | ||||
|     } | ||||
| 
 | ||||
|     private static Character[] getInvalidCharsByOS() { | ||||
|         String os = System.getProperty("os.name").toLowerCase(); | ||||
|         if (os.contains("win")) { | ||||
|             return INVALID_WINDOWS_SPECIFIC_CHARS; | ||||
|         } else if (os.contains("nix") || os.contains("nux") || os.contains("mac")) { | ||||
|             return INVALID_UNIX_SPECIFIC_CHARS; | ||||
|         } else { | ||||
|             return new Character[]{}; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,130 @@ | ||||
| package com.baeldung.stringfilenamevalidaiton; | ||||
| 
 | ||||
| import org.apache.commons.lang3.RandomStringUtils; | ||||
| import org.apache.commons.lang3.RandomUtils; | ||||
| import org.junit.jupiter.api.Test; | ||||
| import org.junit.jupiter.api.condition.EnabledOnOs; | ||||
| import org.junit.jupiter.api.condition.OS; | ||||
| import org.junit.jupiter.params.ParameterizedTest; | ||||
| import org.junit.jupiter.params.provider.EmptySource; | ||||
| import org.junit.jupiter.params.provider.MethodSource; | ||||
| import org.junit.jupiter.params.provider.NullSource; | ||||
| 
 | ||||
| import java.io.IOException; | ||||
| import java.nio.file.InvalidPathException; | ||||
| import java.util.Arrays; | ||||
| import java.util.stream.Stream; | ||||
| 
 | ||||
| import static com.baeldung.stringfilenamevalidaiton.StringFilenameValidationUtils.validateStringFilenameUsingContains; | ||||
| import static com.baeldung.stringfilenamevalidaiton.StringFilenameValidationUtils.validateStringFilenameUsingIO; | ||||
| import static com.baeldung.stringfilenamevalidaiton.StringFilenameValidationUtils.validateStringFilenameUsingNIO2; | ||||
| import static com.baeldung.stringfilenamevalidaiton.StringFilenameValidationUtils.validateStringFilenameUsingRegex; | ||||
| import static org.assertj.core.api.Assertions.assertThat; | ||||
| import static org.assertj.core.api.Assertions.assertThatThrownBy; | ||||
| 
 | ||||
| public class StringFilenameValidationUnitTest { | ||||
| 
 | ||||
|     private static final String CORRECT_FILENAME_PATTERN = "baeldung.txt"; | ||||
| 
 | ||||
|     @ParameterizedTest | ||||
|     @MethodSource("correctAlphanumericFilenamesProvider") | ||||
|     public void givenCorrectAlphanumericRandomFilenameString_whenValidateUsingIO_thenReturnTrue(String filename) throws IOException { | ||||
|         assertThat(validateStringFilenameUsingIO(filename)).isTrue(); | ||||
|         assertThat(validateStringFilenameUsingNIO2(filename)).isTrue(); | ||||
|         assertThat(validateStringFilenameUsingContains(filename)).isTrue(); | ||||
|         assertThat(validateStringFilenameUsingRegex(filename)).isTrue(); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenTooLongFileNameString_whenValidate_thenIOAndCustomFailsNIO2Succeed() { | ||||
|         String filename = RandomStringUtils.randomAlphabetic(500); | ||||
|         assertThatThrownBy(() -> validateStringFilenameUsingIO(filename)) | ||||
|             .isInstanceOf(IOException.class) | ||||
|             .hasMessageContaining("File name too long"); | ||||
|         assertThat(validateStringFilenameUsingNIO2(filename)).isTrue(); | ||||
|         assertThat(validateStringFilenameUsingContains(filename)).isFalse(); | ||||
|         assertThat(validateStringFilenameUsingRegex(filename)).isFalse(); | ||||
|     } | ||||
| 
 | ||||
|     @ParameterizedTest | ||||
|     @NullSource | ||||
|     public void givenNullString_whenValidate_thenFails(String filename) { | ||||
|         assertThatThrownBy(() -> validateStringFilenameUsingIO(filename)) | ||||
|             .isInstanceOf(NullPointerException.class); | ||||
|         assertThatThrownBy(() -> validateStringFilenameUsingNIO2(filename)) | ||||
|             .isInstanceOf(NullPointerException.class); | ||||
|         assertThat(validateStringFilenameUsingContains(filename)).isFalse(); | ||||
|         assertThat(validateStringFilenameUsingRegex(filename)).isFalse(); | ||||
|     } | ||||
| 
 | ||||
|     @ParameterizedTest | ||||
|     @EmptySource | ||||
|     public void givenEmptyString_whenValidate_thenIOAndCustomFailsNIO2Succeed(String filename) { | ||||
|         assertThatThrownBy(() -> validateStringFilenameUsingIO(filename)) | ||||
|             .isInstanceOf(IOException.class); | ||||
|         assertThat(validateStringFilenameUsingNIO2(filename)).isTrue(); | ||||
|         assertThat(validateStringFilenameUsingContains(filename)).isFalse(); | ||||
|         assertThat(validateStringFilenameUsingRegex(filename)).isFalse(); | ||||
|     } | ||||
| 
 | ||||
|     @ParameterizedTest | ||||
|     @EnabledOnOs({OS.LINUX, OS.MAC}) | ||||
|     @MethodSource("filenamesWithInvalidWindowsChars") | ||||
|     public void givenFilenameStringWithInvalidWindowsCharAndIsUnix_whenValidateUsingIO_thenReturnTrue(String filename) throws IOException { | ||||
|         assertThat(validateStringFilenameUsingIO(filename)).isTrue(); | ||||
|         assertThat(validateStringFilenameUsingNIO2(filename)).isTrue(); | ||||
|         assertThat(validateStringFilenameUsingContains(filename)).isTrue(); | ||||
|     } | ||||
| 
 | ||||
|     @ParameterizedTest | ||||
|     @EnabledOnOs(OS.WINDOWS) | ||||
|     @MethodSource("filenamesWithInvalidWindowsChars") | ||||
|     public void givenFilenameStringWithInvalidWindowsCharAndIsWindows_whenValidateUsingIO_thenRaiseException(String filename) { | ||||
|         assertThatThrownBy(() -> validateStringFilenameUsingIO(filename)) | ||||
|             .isInstanceOf(IOException.class) | ||||
|             .hasMessageContaining("Invalid file path"); | ||||
| 
 | ||||
|         assertThatThrownBy(() -> validateStringFilenameUsingNIO2(filename)) | ||||
|             .isInstanceOf(InvalidPathException.class) | ||||
|             .hasMessage("character not allowed"); | ||||
| 
 | ||||
|         assertThat(validateStringFilenameUsingContains(filename)).isFalse(); | ||||
|     } | ||||
| 
 | ||||
|     @ParameterizedTest | ||||
|     @EnabledOnOs({OS.LINUX, OS.MAC}) | ||||
|     @MethodSource("filenamesWithInvalidUnixChars") | ||||
|     public void givenFilenameStringWithInvalidUnixCharAndIsUnix_whenValidate_thenRaiseException(String filename) { | ||||
|         assertThatThrownBy(() -> validateStringFilenameUsingIO(filename)) | ||||
|             .isInstanceOf(IOException.class) | ||||
|             .hasMessageContaining("Invalid file path"); | ||||
| 
 | ||||
|         assertThatThrownBy(() -> validateStringFilenameUsingNIO2(filename)) | ||||
|             .isInstanceOf(InvalidPathException.class) | ||||
|             .hasMessageContaining("character not allowed"); | ||||
| 
 | ||||
|         assertThat(validateStringFilenameUsingContains(filename)).isFalse(); | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     private static Stream<String> correctAlphanumericFilenamesProvider() { | ||||
|         return Stream.generate(() -> RandomStringUtils.randomAlphanumeric(1, 10) + "." + RandomStringUtils.randomAlphabetic(3, 5)).limit(10); | ||||
|     } | ||||
| 
 | ||||
|     private static Stream<String> filenamesWithInvalidWindowsChars() { | ||||
|         return Arrays.stream(StringFilenameValidationUtils.INVALID_WINDOWS_SPECIFIC_CHARS) | ||||
|             .map(character -> { | ||||
|                 int idx = RandomUtils.nextInt(0, CORRECT_FILENAME_PATTERN.length()); | ||||
|                 return CORRECT_FILENAME_PATTERN.substring(0, idx) + character + CORRECT_FILENAME_PATTERN.substring(idx); | ||||
|             }); | ||||
|     } | ||||
| 
 | ||||
|     private static Stream<String> filenamesWithInvalidUnixChars() { | ||||
|         return Arrays.stream(StringFilenameValidationUtils.INVALID_UNIX_SPECIFIC_CHARS) | ||||
|             .map(character -> { | ||||
|                 int idx = RandomUtils.nextInt(0, CORRECT_FILENAME_PATTERN.length()); | ||||
|                 return CORRECT_FILENAME_PATTERN.substring(0, idx) + character + CORRECT_FILENAME_PATTERN.substring(idx); | ||||
|             }); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -1,21 +1,21 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||||
|          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||||
| <project xmlns="http://maven.apache.org/POM/4.0.0" | ||||
|     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||||
|     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||||
|     <modelVersion>4.0.0</modelVersion> | ||||
|     <parent> | ||||
|         <groupId>org.springframework.boot</groupId> | ||||
|         <artifactId>spring-boot-starter-parent</artifactId> | ||||
|         <version>2.4.2</version> | ||||
|         <relativePath/> <!-- lookup parent from repository --> | ||||
|     </parent> | ||||
|     <groupId>com.baeldung.docker</groupId> | ||||
|     <artifactId>heap-sizing</artifactId> | ||||
|     <version>0.0.1-SNAPSHOT</version> | ||||
|     <name>heap-sizing</name> | ||||
|     <description>Demo project for Spring Boot</description> | ||||
|     <properties> | ||||
|         <java.version>11</java.version> | ||||
|     </properties> | ||||
| 
 | ||||
|     <parent> | ||||
|         <groupId>com.baeldung</groupId> | ||||
|         <artifactId>parent-boot-2</artifactId> | ||||
|         <version>0.0.1-SNAPSHOT</version> | ||||
|         <relativePath>../../parent-boot-2</relativePath> | ||||
|     </parent> | ||||
| 
 | ||||
|     <dependencies> | ||||
|         <dependency> | ||||
|             <groupId>org.springframework.boot</groupId> | ||||
| @ -58,4 +58,8 @@ | ||||
|         </plugins> | ||||
|     </build> | ||||
| 
 | ||||
|     <properties> | ||||
|         <java.version>11</java.version> | ||||
|     </properties> | ||||
| 
 | ||||
| </project> | ||||
|  | ||||
| @ -6,7 +6,8 @@ | ||||
|             </pattern> | ||||
|         </encoder> | ||||
|     </appender> | ||||
| 
 | ||||
| 	<logger name="org.kie.api.internal.utils" level="WARN"/> | ||||
| 	<logger name="org.drools.compiler" level="WARN"/> | ||||
|     <root level="INFO"> | ||||
|         <appender-ref ref="STDOUT" /> | ||||
|     </root> | ||||
|  | ||||
| @ -3,6 +3,11 @@ plugins { | ||||
|     id 'org.springframework.boot' version '2.3.4.RELEASE' | ||||
| } | ||||
| 
 | ||||
| ext { | ||||
|     springBootVersion = '2.3.4.RELEASE' | ||||
|     lombokVersion = '1.18.14' | ||||
| } | ||||
| 
 | ||||
| group = 'com.gradle' | ||||
| version = '1.0.0' | ||||
| sourceCompatibility = '14' | ||||
| @ -12,19 +17,16 @@ repositories { | ||||
| } | ||||
| 
 | ||||
| dependencies { | ||||
|     implementation 'org.springframework.boot:spring-boot-starter:2.3.4.RELEASE' | ||||
|     implementation "org.springframework.boot:spring-boot-starter:${springBootVersion}" | ||||
| 
 | ||||
|     testImplementation 'org.springframework.boot:spring-boot-starter-test:2.3.4.RELEASE' | ||||
| 
 | ||||
|     compileOnly 'org.projectlombok:lombok:1.18.14' | ||||
| 
 | ||||
|     testCompileOnly 'org.projectlombok:lombok:1.18.14' | ||||
|     compileOnly "org.projectlombok:lombok:${lombokVersion}" | ||||
| 
 | ||||
|     runtimeOnly files('libs/sampleOne.jar', 'libs/sampleTwo.jar') | ||||
|      | ||||
|     runtimeOnly fileTree('libs') { include '*.jar' } | ||||
|     runtimeOnly fileTree("libs") { include "*.jar" } | ||||
| 
 | ||||
| //    implementation gradleApi() | ||||
|     testImplementation "org.springframework.boot:spring-boot-starter-test:${springBootVersion}" | ||||
| 
 | ||||
|     testCompileOnly "org.projectlombok:lombok:${lombokVersion}" | ||||
| } | ||||
| 
 | ||||
| test { | ||||
|  | ||||
							
								
								
									
										
											BIN
										
									
								
								gradle/gradle-dependency-management/gradle/wrapper/gradle-wrapper.jar
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								gradle/gradle-dependency-management/gradle/wrapper/gradle-wrapper.jar
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										234
									
								
								gradle/gradle-dependency-management/gradlew
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										234
									
								
								gradle/gradle-dependency-management/gradlew
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @ -0,0 +1,234 @@ | ||||
| #!/bin/sh | ||||
| 
 | ||||
| # | ||||
| # Copyright © 2015-2021 the original authors. | ||||
| # | ||||
| # Licensed under the Apache License, Version 2.0 (the "License"); | ||||
| # you may not use this file except in compliance with the License. | ||||
| # You may obtain a copy of the License at | ||||
| # | ||||
| #      https://www.apache.org/licenses/LICENSE-2.0 | ||||
| # | ||||
| # Unless required by applicable law or agreed to in writing, software | ||||
| # distributed under the License is distributed on an "AS IS" BASIS, | ||||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| # See the License for the specific language governing permissions and | ||||
| # limitations under the License. | ||||
| # | ||||
| 
 | ||||
| ############################################################################## | ||||
| # | ||||
| #   Gradle start up script for POSIX generated by Gradle. | ||||
| # | ||||
| #   Important for running: | ||||
| # | ||||
| #   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is | ||||
| #       noncompliant, but you have some other compliant shell such as ksh or | ||||
| #       bash, then to run this script, type that shell name before the whole | ||||
| #       command line, like: | ||||
| # | ||||
| #           ksh Gradle | ||||
| # | ||||
| #       Busybox and similar reduced shells will NOT work, because this script | ||||
| #       requires all of these POSIX shell features: | ||||
| #         * functions; | ||||
| #         * expansions «$var», «${var}», «${var:-default}», «${var+SET}», | ||||
| #           «${var#prefix}», «${var%suffix}», and «$( cmd )»; | ||||
| #         * compound commands having a testable exit status, especially «case»; | ||||
| #         * various built-in commands including «command», «set», and «ulimit». | ||||
| # | ||||
| #   Important for patching: | ||||
| # | ||||
| #   (2) This script targets any POSIX shell, so it avoids extensions provided | ||||
| #       by Bash, Ksh, etc; in particular arrays are avoided. | ||||
| # | ||||
| #       The "traditional" practice of packing multiple parameters into a | ||||
| #       space-separated string is a well documented source of bugs and security | ||||
| #       problems, so this is (mostly) avoided, by progressively accumulating | ||||
| #       options in "$@", and eventually passing that to Java. | ||||
| # | ||||
| #       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, | ||||
| #       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; | ||||
| #       see the in-line comments for details. | ||||
| # | ||||
| #       There are tweaks for specific operating systems such as AIX, CygWin, | ||||
| #       Darwin, MinGW, and NonStop. | ||||
| # | ||||
| #   (3) This script is generated from the Groovy template | ||||
| #       https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt | ||||
| #       within the Gradle project. | ||||
| # | ||||
| #       You can find Gradle at https://github.com/gradle/gradle/. | ||||
| # | ||||
| ############################################################################## | ||||
| 
 | ||||
| # Attempt to set APP_HOME | ||||
| 
 | ||||
| # Resolve links: $0 may be a link | ||||
| app_path=$0 | ||||
| 
 | ||||
| # Need this for daisy-chained symlinks. | ||||
| while | ||||
|     APP_HOME=${app_path%"${app_path##*/}"}  # leaves a trailing /; empty if no leading path | ||||
|     [ -h "$app_path" ] | ||||
| do | ||||
|     ls=$( ls -ld "$app_path" ) | ||||
|     link=${ls#*' -> '} | ||||
|     case $link in             #( | ||||
|       /*)   app_path=$link ;; #( | ||||
|       *)    app_path=$APP_HOME$link ;; | ||||
|     esac | ||||
| done | ||||
| 
 | ||||
| APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit | ||||
| 
 | ||||
| APP_NAME="Gradle" | ||||
| APP_BASE_NAME=${0##*/} | ||||
| 
 | ||||
| # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. | ||||
| DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' | ||||
| 
 | ||||
| # Use the maximum available, or set MAX_FD != -1 to use that value. | ||||
| MAX_FD=maximum | ||||
| 
 | ||||
| warn () { | ||||
|     echo "$*" | ||||
| } >&2 | ||||
| 
 | ||||
| die () { | ||||
|     echo | ||||
|     echo "$*" | ||||
|     echo | ||||
|     exit 1 | ||||
| } >&2 | ||||
| 
 | ||||
| # OS specific support (must be 'true' or 'false'). | ||||
| cygwin=false | ||||
| msys=false | ||||
| darwin=false | ||||
| nonstop=false | ||||
| case "$( uname )" in                #( | ||||
|   CYGWIN* )         cygwin=true  ;; #( | ||||
|   Darwin* )         darwin=true  ;; #( | ||||
|   MSYS* | MINGW* )  msys=true    ;; #( | ||||
|   NONSTOP* )        nonstop=true ;; | ||||
| esac | ||||
| 
 | ||||
| CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar | ||||
| 
 | ||||
| 
 | ||||
| # Determine the Java command to use to start the JVM. | ||||
| if [ -n "$JAVA_HOME" ] ; then | ||||
|     if [ -x "$JAVA_HOME/jre/sh/java" ] ; then | ||||
|         # IBM's JDK on AIX uses strange locations for the executables | ||||
|         JAVACMD=$JAVA_HOME/jre/sh/java | ||||
|     else | ||||
|         JAVACMD=$JAVA_HOME/bin/java | ||||
|     fi | ||||
|     if [ ! -x "$JAVACMD" ] ; then | ||||
|         die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME | ||||
| 
 | ||||
| Please set the JAVA_HOME variable in your environment to match the | ||||
| location of your Java installation." | ||||
|     fi | ||||
| else | ||||
|     JAVACMD=java | ||||
|     which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. | ||||
| 
 | ||||
| Please set the JAVA_HOME variable in your environment to match the | ||||
| location of your Java installation." | ||||
| fi | ||||
| 
 | ||||
| # Increase the maximum file descriptors if we can. | ||||
| if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then | ||||
|     case $MAX_FD in #( | ||||
|       max*) | ||||
|         MAX_FD=$( ulimit -H -n ) || | ||||
|             warn "Could not query maximum file descriptor limit" | ||||
|     esac | ||||
|     case $MAX_FD in  #( | ||||
|       '' | soft) :;; #( | ||||
|       *) | ||||
|         ulimit -n "$MAX_FD" || | ||||
|             warn "Could not set maximum file descriptor limit to $MAX_FD" | ||||
|     esac | ||||
| fi | ||||
| 
 | ||||
| # Collect all arguments for the java command, stacking in reverse order: | ||||
| #   * args from the command line | ||||
| #   * the main class name | ||||
| #   * -classpath | ||||
| #   * -D...appname settings | ||||
| #   * --module-path (only if needed) | ||||
| #   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. | ||||
| 
 | ||||
| # For Cygwin or MSYS, switch paths to Windows format before running java | ||||
| if "$cygwin" || "$msys" ; then | ||||
|     APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) | ||||
|     CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) | ||||
| 
 | ||||
|     JAVACMD=$( cygpath --unix "$JAVACMD" ) | ||||
| 
 | ||||
|     # Now convert the arguments - kludge to limit ourselves to /bin/sh | ||||
|     for arg do | ||||
|         if | ||||
|             case $arg in                                #( | ||||
|               -*)   false ;;                            # don't mess with options #( | ||||
|               /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath | ||||
|                     [ -e "$t" ] ;;                      #( | ||||
|               *)    false ;; | ||||
|             esac | ||||
|         then | ||||
|             arg=$( cygpath --path --ignore --mixed "$arg" ) | ||||
|         fi | ||||
|         # Roll the args list around exactly as many times as the number of | ||||
|         # args, so each arg winds up back in the position where it started, but | ||||
|         # possibly modified. | ||||
|         # | ||||
|         # NB: a `for` loop captures its iteration list before it begins, so | ||||
|         # changing the positional parameters here affects neither the number of | ||||
|         # iterations, nor the values presented in `arg`. | ||||
|         shift                   # remove old arg | ||||
|         set -- "$@" "$arg"      # push replacement arg | ||||
|     done | ||||
| fi | ||||
| 
 | ||||
| # Collect all arguments for the java command; | ||||
| #   * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of | ||||
| #     shell script including quotes and variable substitutions, so put them in | ||||
| #     double quotes to make sure that they get re-expanded; and | ||||
| #   * put everything else in single quotes, so that it's not re-expanded. | ||||
| 
 | ||||
| set -- \ | ||||
|         "-Dorg.gradle.appname=$APP_BASE_NAME" \ | ||||
|         -classpath "$CLASSPATH" \ | ||||
|         org.gradle.wrapper.GradleWrapperMain \ | ||||
|         "$@" | ||||
| 
 | ||||
| # Use "xargs" to parse quoted args. | ||||
| # | ||||
| # With -n1 it outputs one arg per line, with the quotes and backslashes removed. | ||||
| # | ||||
| # In Bash we could simply go: | ||||
| # | ||||
| #   readarray ARGS < <( xargs -n1 <<<"$var" ) && | ||||
| #   set -- "${ARGS[@]}" "$@" | ||||
| # | ||||
| # but POSIX shell has neither arrays nor command substitution, so instead we | ||||
| # post-process each arg (as a line of input to sed) to backslash-escape any | ||||
| # character that might be a shell metacharacter, then use eval to reverse | ||||
| # that process (while maintaining the separation between arguments), and wrap | ||||
| # the whole thing up as a single "set" statement. | ||||
| # | ||||
| # This will of course break if any of these variables contains a newline or | ||||
| # an unmatched quote. | ||||
| # | ||||
| 
 | ||||
| eval "set -- $( | ||||
|         printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | | ||||
|         xargs -n1 | | ||||
|         sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | | ||||
|         tr '\n' ' ' | ||||
|     )" '"$@"' | ||||
| 
 | ||||
| exec "$JAVACMD" "$@" | ||||
							
								
								
									
										89
									
								
								gradle/gradle-dependency-management/gradlew.bat
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								gradle/gradle-dependency-management/gradlew.bat
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,89 @@ | ||||
| @rem | ||||
| @rem Copyright 2015 the original author or authors. | ||||
| @rem | ||||
| @rem Licensed under the Apache License, Version 2.0 (the "License"); | ||||
| @rem you may not use this file except in compliance with the License. | ||||
| @rem You may obtain a copy of the License at | ||||
| @rem | ||||
| @rem      https://www.apache.org/licenses/LICENSE-2.0 | ||||
| @rem | ||||
| @rem Unless required by applicable law or agreed to in writing, software | ||||
| @rem distributed under the License is distributed on an "AS IS" BASIS, | ||||
| @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| @rem See the License for the specific language governing permissions and | ||||
| @rem limitations under the License. | ||||
| @rem | ||||
| 
 | ||||
| @if "%DEBUG%" == "" @echo off | ||||
| @rem ########################################################################## | ||||
| @rem | ||||
| @rem  Gradle startup script for Windows | ||||
| @rem | ||||
| @rem ########################################################################## | ||||
| 
 | ||||
| @rem Set local scope for the variables with windows NT shell | ||||
| if "%OS%"=="Windows_NT" setlocal | ||||
| 
 | ||||
| set DIRNAME=%~dp0 | ||||
| if "%DIRNAME%" == "" set DIRNAME=. | ||||
| set APP_BASE_NAME=%~n0 | ||||
| set APP_HOME=%DIRNAME% | ||||
| 
 | ||||
| @rem Resolve any "." and ".." in APP_HOME to make it shorter. | ||||
| for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi | ||||
| 
 | ||||
| @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. | ||||
| set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" | ||||
| 
 | ||||
| @rem Find java.exe | ||||
| if defined JAVA_HOME goto findJavaFromJavaHome | ||||
| 
 | ||||
| set JAVA_EXE=java.exe | ||||
| %JAVA_EXE% -version >NUL 2>&1 | ||||
| if "%ERRORLEVEL%" == "0" goto execute | ||||
| 
 | ||||
| echo. | ||||
| echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. | ||||
| echo. | ||||
| echo Please set the JAVA_HOME variable in your environment to match the | ||||
| echo location of your Java installation. | ||||
| 
 | ||||
| goto fail | ||||
| 
 | ||||
| :findJavaFromJavaHome | ||||
| set JAVA_HOME=%JAVA_HOME:"=% | ||||
| set JAVA_EXE=%JAVA_HOME%/bin/java.exe | ||||
| 
 | ||||
| if exist "%JAVA_EXE%" goto execute | ||||
| 
 | ||||
| echo. | ||||
| echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% | ||||
| echo. | ||||
| echo Please set the JAVA_HOME variable in your environment to match the | ||||
| echo location of your Java installation. | ||||
| 
 | ||||
| goto fail | ||||
| 
 | ||||
| :execute | ||||
| @rem Setup the command line | ||||
| 
 | ||||
| set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar | ||||
| 
 | ||||
| 
 | ||||
| @rem Execute Gradle | ||||
| "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* | ||||
| 
 | ||||
| :end | ||||
| @rem End local scope for the variables with windows NT shell | ||||
| if "%ERRORLEVEL%"=="0" goto mainEnd | ||||
| 
 | ||||
| :fail | ||||
| rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of | ||||
| rem the _cmd.exe /c_ return code! | ||||
| if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 | ||||
| exit /b 1 | ||||
| 
 | ||||
| :mainEnd | ||||
| if "%OS%"=="Windows_NT" endlocal | ||||
| 
 | ||||
| :omega | ||||
							
								
								
									
										
											BIN
										
									
								
								gradle/gradle-dependency-management/libs/sampleOne.jar
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								gradle/gradle-dependency-management/libs/sampleOne.jar
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								gradle/gradle-dependency-management/libs/sampleTwo.jar
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								gradle/gradle-dependency-management/libs/sampleTwo.jar
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| @ -3,5 +3,6 @@ | ||||
| This module contains articles about JavaFX. | ||||
| 
 | ||||
| ### Relevant Articles: | ||||
| -[Introduction to JavaFX](https://www.baeldung.com/javafx) | ||||
| - [Introduction to JavaFX](https://www.baeldung.com/javafx) | ||||
| - [Display Custom Items in JavaFX ListView](https://www.baeldung.com/javafx-listview-display-custom-items) | ||||
| 
 | ||||
|  | ||||
| @ -0,0 +1,38 @@ | ||||
| package com.baeldung.listview; | ||||
| 
 | ||||
| import com.baeldung.listview.cellfactory.CheckboxCellFactory; | ||||
| import com.baeldung.listview.cellfactory.PersonCellFactory; | ||||
| import javafx.collections.FXCollections; | ||||
| import javafx.collections.ObservableList; | ||||
| import javafx.fxml.FXML; | ||||
| import javafx.fxml.Initializable; | ||||
| import javafx.scene.control.ListView; | ||||
| 
 | ||||
| import java.net.URL; | ||||
| import java.util.ResourceBundle; | ||||
| 
 | ||||
| public class ExampleController implements Initializable { | ||||
|     @FXML | ||||
|     private ListView<Person> listView; | ||||
| 
 | ||||
|     @Override | ||||
|     public void initialize(URL location, ResourceBundle resources) { | ||||
|         ObservableList<Person> wordsList = FXCollections.observableArrayList(); | ||||
|         wordsList.add(new Person("Isaac", "Newton")); | ||||
|         wordsList.add(new Person("Albert", "Einstein")); | ||||
|         wordsList.add(new Person("Ludwig", "Boltzmann")); | ||||
|         listView.setItems(wordsList); | ||||
|     } | ||||
| 
 | ||||
|     public void defaultButtonClick() { | ||||
|         listView.setCellFactory(null); | ||||
|     } | ||||
| 
 | ||||
|     public void cellFactoryButtonClick() { | ||||
|         listView.setCellFactory(new PersonCellFactory()); | ||||
|     } | ||||
| 
 | ||||
|     public void checkboxCellFactoryButtonClick() { | ||||
|         listView.setCellFactory(new CheckboxCellFactory()); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										28
									
								
								javafx/src/main/java/com/baeldung/listview/Main.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								javafx/src/main/java/com/baeldung/listview/Main.java
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,28 @@ | ||||
| package com.baeldung.javafx.listview; | ||||
| 
 | ||||
| import javafx.application.Application; | ||||
| import javafx.fxml.FXMLLoader; | ||||
| import javafx.scene.Parent; | ||||
| import javafx.scene.Scene; | ||||
| import javafx.stage.Stage; | ||||
| 
 | ||||
| import java.net.URL; | ||||
| 
 | ||||
| public class Main extends Application { | ||||
| 
 | ||||
|     public static void main(String args[]) { | ||||
|         launch(args); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void start(Stage primaryStage) throws Exception { | ||||
|         FXMLLoader loader = new FXMLLoader(); | ||||
|         URL xmlUrl = getClass().getResource("/example.fxml"); | ||||
|         loader.setLocation(xmlUrl); | ||||
|         Parent root = loader.load(); | ||||
| 
 | ||||
|         primaryStage.setTitle("List View Demo"); | ||||
|         primaryStage.setScene(new Scene(root)); | ||||
|         primaryStage.show(); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										25
									
								
								javafx/src/main/java/com/baeldung/listview/Person.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								javafx/src/main/java/com/baeldung/listview/Person.java
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,25 @@ | ||||
| package com.baeldung.listview; | ||||
| 
 | ||||
| public class Person { | ||||
| 
 | ||||
|     private final String firstName; | ||||
|     private final String lastName; | ||||
| 
 | ||||
|     public Person(String firstName, String lastName) { | ||||
|         this.firstName = firstName; | ||||
|         this.lastName = lastName; | ||||
|     } | ||||
| 
 | ||||
|     public String getFirstName() { | ||||
|         return firstName; | ||||
|     } | ||||
| 
 | ||||
|     public String getLastName() { | ||||
|         return lastName; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public String toString() { | ||||
|         return firstName + " " + lastName; | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,29 @@ | ||||
| package com.baeldung.listview.cellfactory; | ||||
| 
 | ||||
| import com.baeldung.listview.Person; | ||||
| import javafx.scene.control.CheckBox; | ||||
| import javafx.scene.control.ListCell; | ||||
| import javafx.scene.control.ListView; | ||||
| import javafx.util.Callback; | ||||
| 
 | ||||
| public class CheckboxCellFactory implements Callback<ListView<Person>, ListCell<Person>> { | ||||
|     @Override | ||||
|     public ListCell<Person> call(ListView<Person> param) { | ||||
|         return new ListCell<Person>(){ | ||||
|             @Override | ||||
|             public void updateItem(Person person, boolean empty) { | ||||
|                 super.updateItem(person, empty); | ||||
|                 if (empty) { | ||||
|                     setText(null); | ||||
|                     setGraphic(null); | ||||
|                 } else if (person != null) { | ||||
|                     setText(null); | ||||
|                     setGraphic(new CheckBox(person.getFirstName() + " " + person.getLastName())); | ||||
|                 } else { | ||||
|                     setText("null"); | ||||
|                     setGraphic(null); | ||||
|                 } | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,23 @@ | ||||
| package com.baeldung.listview.cellfactory; | ||||
| 
 | ||||
| import com.baeldung.listview.Person; | ||||
| import javafx.scene.control.ListCell; | ||||
| import javafx.scene.control.ListView; | ||||
| import javafx.util.Callback; | ||||
| 
 | ||||
| public class PersonCellFactory implements Callback<ListView<Person>, ListCell<Person>> { | ||||
|     @Override | ||||
|     public ListCell<Person> call(ListView<Person> param) { | ||||
|         return new ListCell<Person>(){ | ||||
|             @Override | ||||
|             public void updateItem(Person person, boolean empty) { | ||||
|                 super.updateItem(person, empty); | ||||
|                 if (empty || person == null) { | ||||
|                     setText(null); | ||||
|                 } else { | ||||
|                     setText(person.getFirstName() + " " + person.getLastName()); | ||||
|                 } | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										14
									
								
								javafx/src/main/resources/example.fxml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								javafx/src/main/resources/example.fxml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,14 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| 
 | ||||
| <?import javafx.scene.control.Button?> | ||||
| <?import javafx.scene.control.ListView?> | ||||
| <?import javafx.scene.layout.AnchorPane?> | ||||
| 
 | ||||
| <AnchorPane prefHeight="188.0" prefWidth="457.0" xmlns="http://javafx.com/javafx/8.0.172-ea" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.baeldung.listview.ExampleController"> | ||||
|    <children> | ||||
|       <ListView id="listView" fx:id="listView" layoutX="14.0" layoutY="25.0" prefHeight="138.0" prefWidth="256.0" /> | ||||
|       <Button layoutX="283.0" layoutY="25.0" mnemonicParsing="false" onAction="#defaultButtonClick" prefHeight="25.0" prefWidth="139.0" text="Default" /> | ||||
|       <Button layoutX="283.0" layoutY="63.0" mnemonicParsing="false" onAction="#cellFactoryButtonClick" prefHeight="25.0" prefWidth="139.0" text="Cell Factory" /> | ||||
|       <Button layoutX="283.0" layoutY="104.0" mnemonicParsing="false" onAction="#checkboxCellFactoryButtonClick" prefHeight="25.0" prefWidth="139.0" text="Checkbox Cell Factory" /> | ||||
|    </children> | ||||
| </AnchorPane> | ||||
| @ -5,20 +5,14 @@ import javax.ws.rs.container.ResourceInfo; | ||||
| import javax.ws.rs.core.FeatureContext; | ||||
| import javax.ws.rs.ext.Provider; | ||||
| 
 | ||||
| import org.slf4j.Logger; | ||||
| import org.slf4j.LoggerFactory; | ||||
| 
 | ||||
| import com.baeldung.jersey.server.Greetings; | ||||
| import com.baeldung.jersey.server.filter.ResponseServerFilter; | ||||
| 
 | ||||
| @Provider | ||||
| public class HelloDynamicBinding implements DynamicFeature { | ||||
| 
 | ||||
|     private static final Logger LOG = LoggerFactory.getLogger(HelloDynamicBinding.class); | ||||
| 
 | ||||
|     @Override | ||||
|     public void configure(ResourceInfo resourceInfo, FeatureContext context) { | ||||
|         LOG.info("Hello dynamic binding"); | ||||
| 
 | ||||
|         if (Greetings.class.equals(resourceInfo.getResourceClass()) && resourceInfo.getResourceMethod() | ||||
|             .getName() | ||||
|  | ||||
| @ -17,7 +17,6 @@ | ||||
|     </prerequisites> | ||||
| 
 | ||||
|     <properties> | ||||
|         <lifecycle.mapping.version>1.0.0</lifecycle.mapping.version> | ||||
|         <argLine>-Djava.security.egd=file:/dev/./urandom -Xmx256m</argLine> | ||||
|         <assertj.version>3.6.2</assertj.version> | ||||
|         <awaitility.version>2.0.0</awaitility.version> | ||||
| @ -31,6 +30,7 @@ | ||||
|         <jcache.version>1.0.0</jcache.version> | ||||
|         <jhipster.server.version>1.1.0</jhipster.server.version> | ||||
|         <jjwt.version>0.7.0</jjwt.version> | ||||
|         <lifecycle.mapping.version>1.0.0</lifecycle.mapping.version> | ||||
|         <liquibase-hibernate5.version>3.6</liquibase-hibernate5.version> | ||||
|         <liquibase-slf4j.version>2.0.0</liquibase-slf4j.version> | ||||
|         <liquibase.version>3.6.2</liquibase.version> | ||||
| @ -59,14 +59,14 @@ | ||||
| 
 | ||||
|         <sonar.issue.ignore.multicriteria>S3437,UndocumentedApi,BoldAndItalicTagsCheck</sonar.issue.ignore.multicriteria> | ||||
| 
 | ||||
|         <!-- Rule https://sonarqube.com/coding_rules#rule_key=Web%3ABoldAndItalicTagsCheck is ignored. Even if we agree that using the "i" tag is an awful practice, this is what is  | ||||
|         <!-- Rule https://sonarqube.com/coding_rules#rule_key=Web%3ABoldAndItalicTagsCheck is ignored. Even if we agree that using the "i" tag is an awful practice, this is what is | ||||
|             recommended by http://fontawesome.io/examples/ --> | ||||
|         <sonar.issue.ignore.multicriteria.BoldAndItalicTagsCheck.resourceKey>src/main/webapp/app/**/*.*</sonar.issue.ignore.multicriteria.BoldAndItalicTagsCheck.resourceKey> | ||||
|         <sonar.issue.ignore.multicriteria.BoldAndItalicTagsCheck.ruleKey>Web:BoldAndItalicTagsCheck</sonar.issue.ignore.multicriteria.BoldAndItalicTagsCheck.ruleKey> | ||||
|         <!-- Rule https://sonarqube.com/coding_rules#rule_key=squid%3AS3437 is ignored, as a JPA-managed field cannot be transient --> | ||||
|         <sonar.issue.ignore.multicriteria.S3437.resourceKey>src/main/java/**/*</sonar.issue.ignore.multicriteria.S3437.resourceKey> | ||||
|         <sonar.issue.ignore.multicriteria.S3437.ruleKey>squid:S3437</sonar.issue.ignore.multicriteria.S3437.ruleKey> | ||||
|         <!-- Rule http://sonarqube.com/coding_rules#rule_key=squid%3AUndocumentedApi is ignored, as we want to follow "clean code" guidelines and classes, methods and arguments names  | ||||
|         <!-- Rule http://sonarqube.com/coding_rules#rule_key=squid%3AUndocumentedApi is ignored, as we want to follow "clean code" guidelines and classes, methods and arguments names | ||||
|             should be self-explanatory --> | ||||
|         <sonar.issue.ignore.multicriteria.UndocumentedApi.resourceKey>src/main/java/**/*</sonar.issue.ignore.multicriteria.UndocumentedApi.resourceKey> | ||||
|         <sonar.issue.ignore.multicriteria.UndocumentedApi.ruleKey>squid:UndocumentedApi</sonar.issue.ignore.multicriteria.UndocumentedApi.ruleKey> | ||||
| @ -349,7 +349,6 @@ | ||||
|         <dependency> | ||||
|             <groupId>org.springframework.boot</groupId> | ||||
|             <artifactId>spring-boot-starter-test</artifactId> | ||||
|             <scope>test</scope> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.springframework.boot</groupId> | ||||
| @ -365,11 +364,6 @@ | ||||
|                 </exclusion> | ||||
|             </exclusions> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.springframework.boot</groupId> | ||||
|             <artifactId>spring-boot-test</artifactId> | ||||
|             <scope>test</scope> | ||||
|         </dependency> | ||||
|         <!-- Spring Cloud --> | ||||
|         <dependency> | ||||
|             <groupId>org.springframework.cloud</groupId> | ||||
| @ -427,7 +421,7 @@ | ||||
|         <defaultGoal>spring-boot:run</defaultGoal> | ||||
|         <pluginManagement> | ||||
|             <plugins> | ||||
|                 <!-- This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself. Remove when the m2e plugin can correctly  | ||||
|                 <!-- This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself. Remove when the m2e plugin can correctly | ||||
|                     bind to Maven lifecycle --> | ||||
|                 <plugin> | ||||
|                     <groupId>org.eclipse.m2e</groupId> | ||||
| @ -580,14 +574,6 @@ | ||||
|                     </execution> | ||||
|                 </executions> | ||||
|             </plugin> | ||||
|             <plugin> | ||||
|                 <groupId>org.apache.maven.plugins</groupId> | ||||
|                 <artifactId>maven-surefire-plugin</artifactId> | ||||
|                 <configuration> | ||||
|                     <!-- Force alphabetical order to have a reproducible build --> | ||||
|                     <runOrder>alphabetical</runOrder> | ||||
|                 </configuration> | ||||
|             </plugin> | ||||
|             <plugin> | ||||
|                 <groupId>org.jacoco</groupId> | ||||
|                 <artifactId>jacoco-maven-plugin</artifactId> | ||||
| @ -768,8 +754,8 @@ | ||||
|             </dependencies> | ||||
|         </profile> | ||||
|         <profile> | ||||
|             <!-- Profile for doing "continuous compilation" with the Scala Maven plugin. It allows automatic compilation of Java classes as soon as they are saved. To use it, run in  | ||||
|                 3 terminals: - './mvnw -Pcc scala:cc' for continous compilation of your classes - './mvnw -Pcc' for hot reload of Spring boot - 'gulp' for hot reload of the HTML/JavaScript assets Everything  | ||||
|             <!-- Profile for doing "continuous compilation" with the Scala Maven plugin. It allows automatic compilation of Java classes as soon as they are saved. To use it, run in | ||||
|                 3 terminals: - './mvnw -Pcc scala:cc' for continous compilation of your classes - './mvnw -Pcc' for hot reload of Spring boot - 'gulp' for hot reload of the HTML/JavaScript assets Everything | ||||
|                 should hot reload automatically! --> | ||||
|             <id>cc</id> | ||||
|             <build> | ||||
|  | ||||
| @ -21,6 +21,8 @@ eureka: | ||||
|         instanceId: carapp:${spring.application.instance_id:${random.value}} | ||||
| 
 | ||||
| spring: | ||||
|     main: | ||||
|         banner-mode: "off" | ||||
|     application: | ||||
|         name: carapp | ||||
|     jackson: | ||||
| @ -37,7 +39,7 @@ spring: | ||||
|         database-platform: io.github.jhipster.domain.util.FixedH2Dialect | ||||
|         database: H2 | ||||
|         open-in-view: false | ||||
|         show-sql: true | ||||
|         show-sql: false | ||||
|         hibernate: | ||||
|             ddl-auto: none | ||||
|             naming: | ||||
|  | ||||
| @ -3,7 +3,7 @@ | ||||
| <configuration scan="true"> | ||||
|     <include resource="org/springframework/boot/logging/logback/base.xml"/> | ||||
| 
 | ||||
|     <logger name="com.car.app" level="DEBUG"/> | ||||
|     <logger name="com.car.app" level="INFO"/> | ||||
|     <logger name="org.hibernate" level="WARN"/> | ||||
|     <logger name="org.hibernate.ejb.HibernatePersistence" level="OFF"/> | ||||
|     <logger name="org.apache.catalina.startup.DigesterFactory" level="OFF"/> | ||||
|  | ||||
| @ -29,6 +29,7 @@ | ||||
|         <jcache.version>1.0.0</jcache.version> | ||||
|         <jhipster.server.version>1.1.0</jhipster.server.version> | ||||
|         <jjwt.version>0.7.0</jjwt.version> | ||||
|         <lifecycle.mapping.version>1.0.0</lifecycle.mapping.version> | ||||
|         <liquibase-hibernate5.version>3.6</liquibase-hibernate5.version> | ||||
|         <liquibase-slf4j.version>2.0.0</liquibase-slf4j.version> | ||||
|         <liquibase.version>3.6.2</liquibase.version> | ||||
| @ -57,14 +58,14 @@ | ||||
| 
 | ||||
|         <sonar.issue.ignore.multicriteria>S3437,UndocumentedApi,BoldAndItalicTagsCheck</sonar.issue.ignore.multicriteria> | ||||
| 
 | ||||
|         <!-- Rule https://sonarqube.com/coding_rules#rule_key=Web%3ABoldAndItalicTagsCheck is ignored. Even if we agree that using the "i" tag is an awful practice, this is what is  | ||||
|         <!-- Rule https://sonarqube.com/coding_rules#rule_key=Web%3ABoldAndItalicTagsCheck is ignored. Even if we agree that using the "i" tag is an awful practice, this is what is | ||||
|             recommended by http://fontawesome.io/examples/ --> | ||||
|         <sonar.issue.ignore.multicriteria.BoldAndItalicTagsCheck.resourceKey>src/main/webapp/app/**/*.*</sonar.issue.ignore.multicriteria.BoldAndItalicTagsCheck.resourceKey> | ||||
|         <sonar.issue.ignore.multicriteria.BoldAndItalicTagsCheck.ruleKey>Web:BoldAndItalicTagsCheck</sonar.issue.ignore.multicriteria.BoldAndItalicTagsCheck.ruleKey> | ||||
|         <!-- Rule https://sonarqube.com/coding_rules#rule_key=squid%3AS3437 is ignored, as a JPA-managed field cannot be transient --> | ||||
|         <sonar.issue.ignore.multicriteria.S3437.resourceKey>src/main/java/**/*</sonar.issue.ignore.multicriteria.S3437.resourceKey> | ||||
|         <sonar.issue.ignore.multicriteria.S3437.ruleKey>squid:S3437</sonar.issue.ignore.multicriteria.S3437.ruleKey> | ||||
|         <!-- Rule http://sonarqube.com/coding_rules#rule_key=squid%3AUndocumentedApi is ignored, as we want to follow "clean code" guidelines and classes, methods and arguments names  | ||||
|         <!-- Rule http://sonarqube.com/coding_rules#rule_key=squid%3AUndocumentedApi is ignored, as we want to follow "clean code" guidelines and classes, methods and arguments names | ||||
|             should be self-explanatory --> | ||||
|         <sonar.issue.ignore.multicriteria.UndocumentedApi.resourceKey>src/main/java/**/*</sonar.issue.ignore.multicriteria.UndocumentedApi.resourceKey> | ||||
|         <sonar.issue.ignore.multicriteria.UndocumentedApi.ruleKey>squid:UndocumentedApi</sonar.issue.ignore.multicriteria.UndocumentedApi.ruleKey> | ||||
| @ -90,7 +91,6 @@ | ||||
|         <undertow.version>1.4.10.Final</undertow.version> | ||||
|         <validation-api.version>1.1.0.Final</validation-api.version> | ||||
|         <yarn.version>v0.21.3</yarn.version> | ||||
|         <lifecycle.mapping.version>1.0.0</lifecycle.mapping.version> | ||||
|     </properties> | ||||
| 
 | ||||
|     <dependencyManagement> | ||||
| @ -345,6 +345,10 @@ | ||||
|             <groupId>org.springframework.boot</groupId> | ||||
|             <artifactId>spring-boot-starter-security</artifactId> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.springframework.boot</groupId> | ||||
|             <artifactId>spring-boot-starter-test</artifactId> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.springframework.boot</groupId> | ||||
|             <artifactId>spring-boot-starter-thymeleaf</artifactId> | ||||
| @ -359,11 +363,6 @@ | ||||
|                 </exclusion> | ||||
|             </exclusions> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.springframework.boot</groupId> | ||||
|             <artifactId>spring-boot-test</artifactId> | ||||
|             <scope>test</scope> | ||||
|         </dependency> | ||||
|         <!-- Spring Cloud --> | ||||
|         <dependency> | ||||
|             <groupId>org.springframework.cloud</groupId> | ||||
| @ -421,7 +420,7 @@ | ||||
|         <defaultGoal>spring-boot:run</defaultGoal> | ||||
|         <pluginManagement> | ||||
|             <plugins> | ||||
|                 <!-- This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself. Remove when the m2e plugin can correctly  | ||||
|                 <!-- This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself. Remove when the m2e plugin can correctly | ||||
|                     bind to Maven lifecycle --> | ||||
|                 <plugin> | ||||
|                     <groupId>org.eclipse.m2e</groupId> | ||||
| @ -574,14 +573,6 @@ | ||||
|                     </execution> | ||||
|                 </executions> | ||||
|             </plugin> | ||||
|             <plugin> | ||||
|                 <groupId>org.apache.maven.plugins</groupId> | ||||
|                 <artifactId>maven-surefire-plugin</artifactId> | ||||
|                 <configuration> | ||||
|                     <!-- Force alphabetical order to have a reproducible build --> | ||||
|                     <runOrder>alphabetical</runOrder> | ||||
|                 </configuration> | ||||
|             </plugin> | ||||
|             <plugin> | ||||
|                 <groupId>org.jacoco</groupId> | ||||
|                 <artifactId>jacoco-maven-plugin</artifactId> | ||||
| @ -762,8 +753,8 @@ | ||||
|             </dependencies> | ||||
|         </profile> | ||||
|         <profile> | ||||
|             <!-- Profile for doing "continuous compilation" with the Scala Maven plugin. It allows automatic compilation of Java classes as soon as they are saved. To use it, run in  | ||||
|                 3 terminals: - './mvnw -Pcc scala:cc' for continous compilation of your classes - './mvnw -Pcc' for hot reload of Spring boot - 'gulp' for hot reload of the HTML/JavaScript assets Everything  | ||||
|             <!-- Profile for doing "continuous compilation" with the Scala Maven plugin. It allows automatic compilation of Java classes as soon as they are saved. To use it, run in | ||||
|                 3 terminals: - './mvnw -Pcc scala:cc' for continous compilation of your classes - './mvnw -Pcc' for hot reload of Spring boot - 'gulp' for hot reload of the HTML/JavaScript assets Everything | ||||
|                 should hot reload automatically! --> | ||||
|             <id>cc</id> | ||||
|             <build> | ||||
|  | ||||
| @ -21,6 +21,8 @@ eureka: | ||||
|         instanceId: dealerapp:${spring.application.instance_id:${random.value}} | ||||
| 
 | ||||
| spring: | ||||
|     main: | ||||
|         banner-mode: "off" | ||||
|     application: | ||||
|         name: dealerapp | ||||
|     jackson: | ||||
| @ -37,7 +39,7 @@ spring: | ||||
|         database-platform: io.github.jhipster.domain.util.FixedH2Dialect | ||||
|         database: H2 | ||||
|         open-in-view: false | ||||
|         show-sql: true | ||||
|         show-sql: false | ||||
|         hibernate: | ||||
|             ddl-auto: none | ||||
|             naming: | ||||
|  | ||||
| @ -3,7 +3,7 @@ | ||||
| <configuration scan="true"> | ||||
|     <include resource="org/springframework/boot/logging/logback/base.xml"/> | ||||
| 
 | ||||
|     <logger name="com.dealer.app" level="DEBUG"/> | ||||
|     <logger name="com.dealer.app" level="INFO"/> | ||||
|     <logger name="org.hibernate" level="WARN"/> | ||||
|     <logger name="org.hibernate.ejb.HibernatePersistence" level="OFF"/> | ||||
|     <logger name="org.apache.catalina.startup.DigesterFactory" level="OFF"/> | ||||
|  | ||||
| @ -32,6 +32,7 @@ | ||||
|         <jcache.version>1.0.0</jcache.version> | ||||
|         <jhipster.server.version>1.1.0</jhipster.server.version> | ||||
|         <jjwt.version>0.7.0</jjwt.version> | ||||
|         <lifecycle.mapping.version>1.0.0</lifecycle.mapping.version> | ||||
|         <liquibase-hibernate5.version>3.6</liquibase-hibernate5.version> | ||||
|         <liquibase-slf4j.version>2.0.0</liquibase-slf4j.version> | ||||
|         <liquibase.version>3.6.2</liquibase.version> | ||||
| @ -61,14 +62,14 @@ | ||||
| 
 | ||||
|         <sonar.issue.ignore.multicriteria>S3437,UndocumentedApi,BoldAndItalicTagsCheck</sonar.issue.ignore.multicriteria> | ||||
| 
 | ||||
|         <!-- Rule https://sonarqube.com/coding_rules#rule_key=Web%3ABoldAndItalicTagsCheck is ignored. Even if we agree that using the "i" tag is an awful practice, this is what is  | ||||
|         <!-- Rule https://sonarqube.com/coding_rules#rule_key=Web%3ABoldAndItalicTagsCheck is ignored. Even if we agree that using the "i" tag is an awful practice, this is what is | ||||
|             recommended by http://fontawesome.io/examples/ --> | ||||
|         <sonar.issue.ignore.multicriteria.BoldAndItalicTagsCheck.resourceKey>src/main/webapp/app/**/*.*</sonar.issue.ignore.multicriteria.BoldAndItalicTagsCheck.resourceKey> | ||||
|         <sonar.issue.ignore.multicriteria.BoldAndItalicTagsCheck.ruleKey>Web:BoldAndItalicTagsCheck</sonar.issue.ignore.multicriteria.BoldAndItalicTagsCheck.ruleKey> | ||||
|         <!-- Rule https://sonarqube.com/coding_rules#rule_key=squid%3AS3437 is ignored, as a JPA-managed field cannot be transient --> | ||||
|         <sonar.issue.ignore.multicriteria.S3437.resourceKey>src/main/java/**/*</sonar.issue.ignore.multicriteria.S3437.resourceKey> | ||||
|         <sonar.issue.ignore.multicriteria.S3437.ruleKey>squid:S3437</sonar.issue.ignore.multicriteria.S3437.ruleKey> | ||||
|         <!-- Rule http://sonarqube.com/coding_rules#rule_key=squid%3AUndocumentedApi is ignored, as we want to follow "clean code" guidelines and classes, methods and arguments names  | ||||
|         <!-- Rule http://sonarqube.com/coding_rules#rule_key=squid%3AUndocumentedApi is ignored, as we want to follow "clean code" guidelines and classes, methods and arguments names | ||||
|             should be self-explanatory --> | ||||
|         <sonar.issue.ignore.multicriteria.UndocumentedApi.resourceKey>src/main/java/**/*</sonar.issue.ignore.multicriteria.UndocumentedApi.resourceKey> | ||||
|         <sonar.issue.ignore.multicriteria.UndocumentedApi.ruleKey>squid:UndocumentedApi</sonar.issue.ignore.multicriteria.UndocumentedApi.ruleKey> | ||||
| @ -94,7 +95,6 @@ | ||||
|         <undertow.version>1.4.10.Final</undertow.version> | ||||
|         <validation-api.version>1.1.0.Final</validation-api.version> | ||||
|         <yarn.version>v0.21.3</yarn.version> | ||||
|         <lifecycle.mapping.version>1.0.0</lifecycle.mapping.version> | ||||
|     </properties> | ||||
| 
 | ||||
|     <dependencyManagement> | ||||
| @ -383,6 +383,10 @@ | ||||
|             <artifactId>spring-boot-starter-test</artifactId> | ||||
|             <scope>test</scope> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.springframework.boot</groupId> | ||||
|             <artifactId>spring-boot-starter-test</artifactId> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.springframework.boot</groupId> | ||||
|             <artifactId>spring-boot-starter-thymeleaf</artifactId> | ||||
| @ -397,11 +401,6 @@ | ||||
|                 </exclusion> | ||||
|             </exclusions> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.springframework.boot</groupId> | ||||
|             <artifactId>spring-boot-test</artifactId> | ||||
|             <scope>test</scope> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.springframework.cloud</groupId> | ||||
|             <artifactId>spring-cloud-starter</artifactId> | ||||
| @ -463,7 +462,7 @@ | ||||
|         <defaultGoal>spring-boot:run</defaultGoal> | ||||
|         <pluginManagement> | ||||
|             <plugins> | ||||
|                 <!-- This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself. Remove when the m2e plugin can correctly  | ||||
|                 <!-- This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself. Remove when the m2e plugin can correctly | ||||
|                     bind to Maven lifecycle --> | ||||
|                 <plugin> | ||||
|                     <groupId>org.eclipse.m2e</groupId> | ||||
| @ -632,14 +631,6 @@ | ||||
|                     </execution> | ||||
|                 </executions> | ||||
|             </plugin> | ||||
|             <plugin> | ||||
|                 <groupId>org.apache.maven.plugins</groupId> | ||||
|                 <artifactId>maven-surefire-plugin</artifactId> | ||||
|                 <configuration> | ||||
|                     <!-- Force alphabetical order to have a reproducible build --> | ||||
|                     <runOrder>alphabetical</runOrder> | ||||
|                 </configuration> | ||||
|             </plugin> | ||||
|             <plugin> | ||||
|                 <groupId>org.jacoco</groupId> | ||||
|                 <artifactId>jacoco-maven-plugin</artifactId> | ||||
| @ -878,8 +869,8 @@ | ||||
|             </dependencies> | ||||
|         </profile> | ||||
|         <profile> | ||||
|             <!-- Profile for doing "continuous compilation" with the Scala Maven plugin. It allows automatic compilation of Java classes as soon as they are saved. To use it, run in  | ||||
|                 3 terminals: - './mvnw -Pcc scala:cc' for continous compilation of your classes - './mvnw -Pcc' for hot reload of Spring boot - 'gulp' for hot reload of the HTML/JavaScript assets Everything  | ||||
|             <!-- Profile for doing "continuous compilation" with the Scala Maven plugin. It allows automatic compilation of Java classes as soon as they are saved. To use it, run in | ||||
|                 3 terminals: - './mvnw -Pcc scala:cc' for continous compilation of your classes - './mvnw -Pcc' for hot reload of Spring boot - 'gulp' for hot reload of the HTML/JavaScript assets Everything | ||||
|                 should hot reload automatically! --> | ||||
|             <id>cc</id> | ||||
|             <build> | ||||
|  | ||||
| @ -49,7 +49,7 @@ public class LogsResourceIntegrationTest { | ||||
|     public void changeLogs()throws Exception { | ||||
|         LoggerVM logger = new LoggerVM(); | ||||
|         logger.setLevel("INFO"); | ||||
|         logger.setName("ROOT"); | ||||
|         logger.setName("some.test.logger"); | ||||
| 
 | ||||
|         restLogsMockMvc.perform(put("/management/logs") | ||||
|             .contentType(TestUtil.APPLICATION_JSON_UTF8) | ||||
|  | ||||
| @ -21,6 +21,8 @@ eureka: | ||||
|         instanceId: gateway:${spring.application.instance_id:${random.value}} | ||||
| 
 | ||||
| spring: | ||||
|     main: | ||||
|         banner-mode: "off" | ||||
|     application: | ||||
|         name: gateway | ||||
|     autoconfigure: | ||||
| @ -39,7 +41,7 @@ spring: | ||||
|         database-platform: io.github.jhipster.domain.util.FixedH2Dialect | ||||
|         database: H2 | ||||
|         open-in-view: false | ||||
|         show-sql: true | ||||
|         show-sql: false | ||||
|         hibernate: | ||||
|             ddl-auto: none | ||||
|             naming: | ||||
|  | ||||
| @ -3,7 +3,7 @@ | ||||
| <configuration scan="true"> | ||||
|     <include resource="org/springframework/boot/logging/logback/base.xml"/> | ||||
| 
 | ||||
|     <logger name="com.gateway" level="DEBUG"/> | ||||
|     <logger name="com.gateway" level="INFO"/> | ||||
|     <logger name="org.hibernate" level="WARN"/> | ||||
|     <logger name="org.hibernate.ejb.HibernatePersistence" level="OFF"/> | ||||
|     <logger name="org.apache.catalina.startup.DigesterFactory" level="OFF"/> | ||||
|  | ||||
| @ -11,7 +11,7 @@ | ||||
|         <groupId>com.baeldung.jhipster</groupId> | ||||
|         <version>1.0.0-SNAPSHOT</version> | ||||
|     </parent> | ||||
|      | ||||
| 
 | ||||
|     <modules> | ||||
|         <module>car-app</module> | ||||
|         <module>dealer-app</module> | ||||
|  | ||||
| @ -277,8 +277,7 @@ | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.springframework.boot</groupId> | ||||
|             <artifactId>spring-boot-test</artifactId> | ||||
|             <scope>test</scope> | ||||
|             <artifactId>spring-boot-starter-test</artifactId> | ||||
|         </dependency> | ||||
|         <!-- security --> | ||||
|         <dependency> | ||||
| @ -297,7 +296,7 @@ | ||||
|         <defaultGoal>spring-boot:run</defaultGoal> | ||||
|         <pluginManagement> | ||||
|             <plugins> | ||||
|                 <!-- This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself. Remove when the m2e plugin can correctly  | ||||
|                 <!-- This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself. Remove when the m2e plugin can correctly | ||||
|                     bind to Maven lifecycle --> | ||||
|                 <plugin> | ||||
|                     <groupId>org.eclipse.m2e</groupId> | ||||
| @ -751,8 +750,8 @@ | ||||
|             </dependencies> | ||||
|         </profile> | ||||
|         <profile> | ||||
|             <!-- Profile for doing "continuous compilation" with the Scala Maven plugin. It allows automatic compilation of Java classes as soon as they are saved. To use it, run in  | ||||
|                 3 terminals: - './mvnw -Pcc scala:cc' for continous compilation of your classes - './mvnw -Pcc' for hot reload of Spring boot - 'gulp' for hot reload of the HTML/JavaScript assets Everything  | ||||
|             <!-- Profile for doing "continuous compilation" with the Scala Maven plugin. It allows automatic compilation of Java classes as soon as they are saved. To use it, run in | ||||
|                 3 terminals: - './mvnw -Pcc scala:cc' for continous compilation of your classes - './mvnw -Pcc' for hot reload of Spring boot - 'gulp' for hot reload of the HTML/JavaScript assets Everything | ||||
|                 should hot reload automatically! --> | ||||
|             <id>cc</id> | ||||
|             <build> | ||||
| @ -931,14 +930,14 @@ | ||||
| 
 | ||||
|         <sonar.issue.ignore.multicriteria>S3437,UndocumentedApi,BoldAndItalicTagsCheck</sonar.issue.ignore.multicriteria> | ||||
| 
 | ||||
|         <!-- Rule https://sonarqube.com/coding_rules#rule_key=Web%3ABoldAndItalicTagsCheck is ignored. Even if we agree that using the "i" tag is an awful practice, this is what is  | ||||
|         <!-- Rule https://sonarqube.com/coding_rules#rule_key=Web%3ABoldAndItalicTagsCheck is ignored. Even if we agree that using the "i" tag is an awful practice, this is what is | ||||
|             recommended by http://fontawesome.io/examples/ --> | ||||
|         <sonar.issue.ignore.multicriteria.BoldAndItalicTagsCheck.resourceKey>src/main/webapp/app/**/*.*</sonar.issue.ignore.multicriteria.BoldAndItalicTagsCheck.resourceKey> | ||||
|         <sonar.issue.ignore.multicriteria.BoldAndItalicTagsCheck.ruleKey>Web:BoldAndItalicTagsCheck</sonar.issue.ignore.multicriteria.BoldAndItalicTagsCheck.ruleKey> | ||||
|         <!-- Rule https://sonarqube.com/coding_rules#rule_key=squid%3AS3437 is ignored, as a JPA-managed field cannot be transient --> | ||||
|         <sonar.issue.ignore.multicriteria.S3437.resourceKey>src/main/java/**/*</sonar.issue.ignore.multicriteria.S3437.resourceKey> | ||||
|         <sonar.issue.ignore.multicriteria.S3437.ruleKey>squid:S3437</sonar.issue.ignore.multicriteria.S3437.ruleKey> | ||||
|         <!-- Rule http://sonarqube.com/coding_rules#rule_key=squid%3AUndocumentedApi is ignored, as we want to follow "clean code" guidelines and classes, methods and arguments names  | ||||
|         <!-- Rule http://sonarqube.com/coding_rules#rule_key=squid%3AUndocumentedApi is ignored, as we want to follow "clean code" guidelines and classes, methods and arguments names | ||||
|             should be self-explanatory --> | ||||
|         <sonar.issue.ignore.multicriteria.UndocumentedApi.resourceKey>src/main/java/**/*</sonar.issue.ignore.multicriteria.UndocumentedApi.resourceKey> | ||||
|         <sonar.issue.ignore.multicriteria.UndocumentedApi.ruleKey>squid:UndocumentedApi</sonar.issue.ignore.multicriteria.UndocumentedApi.ruleKey> | ||||
|  | ||||
| @ -49,7 +49,7 @@ public class LogsResourceIntegrationTest { | ||||
|     public void changeLogs()throws Exception { | ||||
|         LoggerVM logger = new LoggerVM(); | ||||
|         logger.setLevel("INFO"); | ||||
|         logger.setName("ROOT"); | ||||
|         logger.setName("some.test.logger"); | ||||
| 
 | ||||
|         restLogsMockMvc.perform(put("/management/logs") | ||||
|             .contentType(TestUtil.APPLICATION_JSON_UTF8) | ||||
|  | ||||
| @ -15,6 +15,8 @@ | ||||
| 
 | ||||
| 
 | ||||
| spring: | ||||
|     main: | ||||
|         banner-mode: "off" | ||||
|     application: | ||||
|         name: baeldung | ||||
|     jackson: | ||||
| @ -31,7 +33,7 @@ spring: | ||||
|         database-platform: io.github.jhipster.domain.util.FixedH2Dialect | ||||
|         database: H2 | ||||
|         open-in-view: false | ||||
|         show-sql: true | ||||
|         show-sql: false | ||||
|         hibernate: | ||||
|             ddl-auto: none | ||||
|             naming: | ||||
|  | ||||
| @ -3,7 +3,7 @@ | ||||
| <configuration scan="true"> | ||||
|     <include resource="org/springframework/boot/logging/logback/base.xml"/> | ||||
| 
 | ||||
|     <logger name="com.baeldung" level="DEBUG"/> | ||||
|     <logger name="com.baeldung" level="INFO"/> | ||||
|     <logger name="org.hibernate" level="WARN"/> | ||||
|     <logger name="org.hibernate.ejb.HibernatePersistence" level="OFF"/> | ||||
|     <logger name="org.apache.catalina.startup.DigesterFactory" level="OFF"/> | ||||
|  | ||||
| @ -1,6 +1,13 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> | ||||
|     <modelVersion>4.0.0</modelVersion> | ||||
| 
 | ||||
|     <parent> | ||||
|         <artifactId>jhipster-uaa</artifactId> | ||||
|         <groupId>com.baeldung.jhipster</groupId> | ||||
|         <version>1.0.0-SNAPSHOT</version> | ||||
|     </parent> | ||||
| 
 | ||||
|     <groupId>com.baeldung.jhipster.gateway</groupId> | ||||
|     <artifactId>gateway</artifactId> | ||||
|     <version>0.0.1-SNAPSHOT</version> | ||||
| @ -415,15 +422,6 @@ | ||||
|                     </execution> | ||||
|                 </executions> | ||||
|             </plugin> | ||||
|             <plugin> | ||||
|                 <groupId>org.apache.maven.plugins</groupId> | ||||
|                 <artifactId>maven-surefire-plugin</artifactId> | ||||
|                 <version>${maven-surefire-plugin.version}</version> | ||||
|                 <configuration> | ||||
|                     <!-- Force alphabetical order to have a reproducible build --> | ||||
|                     <runOrder>alphabetical</runOrder> | ||||
|                 </configuration> | ||||
|             </plugin> | ||||
|             <plugin> | ||||
|                 <groupId>org.jacoco</groupId> | ||||
|                 <artifactId>jacoco-maven-plugin</artifactId> | ||||
| @ -1010,7 +1008,7 @@ | ||||
|         </profile> | ||||
|         <!-- jhipster-needle-maven-add-profile --> | ||||
|     </profiles> | ||||
| 	 | ||||
| 
 | ||||
|     <properties> | ||||
|         <lifecycle.mapping.version>1.0.0</lifecycle.mapping.version> | ||||
|         <spring.web.version>0.24.0</spring.web.version> | ||||
| @ -1090,5 +1088,5 @@ | ||||
|         <sonar.tests>${project.basedir}/src/test/</sonar.tests> | ||||
| 
 | ||||
|         <!-- jhipster-needle-maven-property --> | ||||
|     </properties>	 | ||||
|     </properties> | ||||
| </project> | ||||
|  | ||||
| @ -40,7 +40,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. | ||||
|  * | ||||
|  * @see WebConfigurer | ||||
|  */ | ||||
| public class WebConfigurerTest { | ||||
| public class WebConfigurerUnitTest { | ||||
| 
 | ||||
|     private WebConfigurer webConfigurer; | ||||
| 
 | ||||
| @ -18,7 +18,7 @@ import static springfox.documentation.swagger2.web.Swagger2Controller.DEFAULT_UR | ||||
| /** | ||||
|  * Tests SwaggerBasePathRewritingFilter class. | ||||
|  */ | ||||
| public class SwaggerBasePathRewritingFilterTest { | ||||
| public class SwaggerBasePathRewritingFilterUnitTest { | ||||
| 
 | ||||
|     private SwaggerBasePathRewritingFilter filter = new SwaggerBasePathRewritingFilter(); | ||||
| 
 | ||||
| @ -16,7 +16,7 @@ import java.util.List; | ||||
|  * | ||||
|  * @see CookieCollection | ||||
|  */ | ||||
| public class CookieCollectionTest { | ||||
| public class CookieCollectionUnitTest { | ||||
|     public static final String COOKIE_NAME = "chocolate"; | ||||
|     public static final String COOKIE_VALUE = "yummy"; | ||||
|     public static final String BROWNIE_NAME = "brownie"; | ||||
| @ -12,7 +12,7 @@ import org.springframework.security.oauth2.common.OAuth2AccessToken; | ||||
|  * Test whether the CookieTokenExtractor can properly extract access tokens from | ||||
|  * Cookies and Headers. | ||||
|  */ | ||||
| public class CookieTokenExtractorTest { | ||||
| public class CookieTokenExtractorUnitTest { | ||||
|     private CookieTokenExtractor cookieTokenExtractor; | ||||
| 
 | ||||
|     @Before | ||||
| @ -22,24 +22,24 @@ public class CookieTokenExtractorTest { | ||||
| 
 | ||||
|     @Test | ||||
|     public void testExtractTokenCookie() { | ||||
|         MockHttpServletRequest request = OAuth2AuthenticationServiceTest.createMockHttpServletRequest(); | ||||
|         MockHttpServletRequest request = OAuth2AuthenticationServiceUnitTest.createMockHttpServletRequest(); | ||||
|         Authentication authentication = cookieTokenExtractor.extract(request); | ||||
|         Assert.assertEquals(OAuth2AuthenticationServiceTest.ACCESS_TOKEN_VALUE, authentication.getPrincipal().toString()); | ||||
|         Assert.assertEquals(OAuth2AuthenticationServiceUnitTest.ACCESS_TOKEN_VALUE, authentication.getPrincipal().toString()); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void testExtractTokenHeader() { | ||||
|         MockHttpServletRequest request = new MockHttpServletRequest(HttpMethod.GET.name(), "http://www.test.com"); | ||||
|         request.addHeader("Authorization", OAuth2AccessToken.BEARER_TYPE + " " + OAuth2AuthenticationServiceTest.ACCESS_TOKEN_VALUE); | ||||
|         request.addHeader("Authorization", OAuth2AccessToken.BEARER_TYPE + " " + OAuth2AuthenticationServiceUnitTest.ACCESS_TOKEN_VALUE); | ||||
|         Authentication authentication = cookieTokenExtractor.extract(request); | ||||
|         Assert.assertEquals(OAuth2AuthenticationServiceTest.ACCESS_TOKEN_VALUE, authentication.getPrincipal().toString()); | ||||
|         Assert.assertEquals(OAuth2AuthenticationServiceUnitTest.ACCESS_TOKEN_VALUE, authentication.getPrincipal().toString()); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void testExtractTokenParam() { | ||||
|         MockHttpServletRequest request = new MockHttpServletRequest(HttpMethod.GET.name(), "http://www.test.com"); | ||||
|         request.addParameter(OAuth2AccessToken.ACCESS_TOKEN, OAuth2AuthenticationServiceTest.ACCESS_TOKEN_VALUE); | ||||
|         request.addParameter(OAuth2AccessToken.ACCESS_TOKEN, OAuth2AuthenticationServiceUnitTest.ACCESS_TOKEN_VALUE); | ||||
|         Authentication authentication = cookieTokenExtractor.extract(request); | ||||
|         Assert.assertEquals(OAuth2AuthenticationServiceTest.ACCESS_TOKEN_VALUE, authentication.getPrincipal().toString()); | ||||
|         Assert.assertEquals(OAuth2AuthenticationServiceUnitTest.ACCESS_TOKEN_VALUE, authentication.getPrincipal().toString()); | ||||
|     } | ||||
| } | ||||
| @ -39,7 +39,7 @@ import static org.mockito.Mockito.when; | ||||
|  * @see OAuth2AuthenticationService | ||||
|  */ | ||||
| @RunWith(MockitoJUnitRunner.class) | ||||
| public class OAuth2AuthenticationServiceTest { | ||||
| public class OAuth2AuthenticationServiceUnitTest { | ||||
|     public static final String CLIENT_AUTHORIZATION = "Basic d2ViX2FwcDpjaGFuZ2VpdA=="; | ||||
|     public static final String ACCESS_TOKEN_VALUE = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE0OTQyNzI4NDQsInVzZXJfbmFtZSI6InVzZXIiLCJhdXRob3JpdGllcyI6WyJST0xFX1VTRVIiXSwianRpIjoiNzc1ZTJkYWUtYWYzZi00YTdhLWExOTktNzNiZTU1MmIxZDVkIiwiY2xpZW50X2lkIjoid2ViX2FwcCIsInNjb3BlIjpbIm9wZW5pZCJdfQ.gEK0YcX2IpkpxnkxXXHQ4I0xzTjcy7edqb89ukYE0LPe7xUcZVwkkCJF_nBxsGJh2jtA6NzNLfY5zuL6nP7uoAq3fmvsyrcyR2qPk8JuuNzGtSkICx3kPDRjAT4ST8SZdeh7XCbPVbySJ7ZmPlRWHyedzLA1wXN0NUf8yZYS4ELdUwVBYIXSjkNoKqfWm88cwuNr0g0teypjPtjDqCnXFt1pibwdfIXn479Y1neNAdvSpHcI4Ost-c7APCNxW2gqX-0BItZQearxRgKDdBQ7CGPAIky7dA0gPuKUpp_VCoqowKCXqkE9yKtRQGIISewtj2UkDRZePmzmYrUBXRzfYw"; | ||||
|     public static final String REFRESH_TOKEN_VALUE = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX25hbWUiOiJ1c2VyIiwic2NvcGUiOlsib3BlbmlkIl0sImF0aSI6Ijc3NWUyZGFlLWFmM2YtNGE3YS1hMTk5LTczYmU1NTJiMWQ1ZCIsImV4cCI6MTQ5Njg2NDc0MywiYXV0aG9yaXRpZXMiOlsiUk9MRV9VU0VSIl0sImp0aSI6IjhmYjI2YTllLTdjYzQtNDFlMi1hNzBjLTk4MDc0N2U2YWFiOSIsImNsaWVudF9pZCI6IndlYl9hcHAifQ.q1-Df9_AFO6TJNiLKV2YwTjRbnd7qcXv52skXYnog5siHYRoR6cPtm6TNQ04iDAoIHljTSTNnD6DS3bHk41mV55gsSVxGReL8VCb_R8ZmhVL4-5yr90sfms0wFp6lgD2bPmZ-TXiS2Oe9wcbNWagy5RsEplZ-sbXu3tjmDao4FN35ojPsXmUs84XnNQH3Y_-PY9GjZG0JEfLQIvE0J5BkXS18Z015GKyA6GBIoLhAGBQQYyG9m10ld_a9fD5SmCyCF72Jad_pfP1u8Z_WyvO-wrlBvm2x-zBthreVrXU5mOb9795wJEP-xaw3dXYGjht_grcW4vKUFtj61JgZk98CQ"; | ||||
Some files were not shown because too many files have changed in this diff Show More
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user