Merge branch 'master' of github.com:eugenp/tutorials
This commit is contained in:
		
						commit
						32bdaa1d49
					
				| @ -13,6 +13,5 @@ This module contains articles about algorithms. Some classes of algorithms, e.g. | ||||
| - [Checking if a Java Graph has a Cycle](https://www.baeldung.com/java-graph-has-a-cycle) | ||||
| - [A Guide to the Folding Technique in Java](https://www.baeldung.com/folding-hashing-technique) | ||||
| - [Creating a Triangle with for Loops in Java](https://www.baeldung.com/java-print-triangle) | ||||
| - [Efficient Word Frequency Calculator in Java](https://www.baeldung.com/java-word-frequency) | ||||
| - [The K-Means Clustering Algorithm in Java](https://www.baeldung.com/java-k-means-clustering-algorithm) | ||||
| - More articles: [[<-- prev]](/algorithms-miscellaneous-2) [[next -->]](/algorithms-miscellaneous-4) | ||||
|  | ||||
| @ -15,9 +15,5 @@ This module contains articles about algorithms. Some classes of algorithms, e.g. | ||||
| - [Maximum Subarray Problem](https://www.baeldung.com/java-maximum-subarray) | ||||
| - [How to Merge Two Sorted Arrays](https://www.baeldung.com/java-merge-sorted-arrays) | ||||
| - [Median of Stream of Integers using Heap](https://www.baeldung.com/java-stream-integers-median-using-heap) | ||||
| - [Kruskal’s Algorithm for Spanning Trees](https://www.baeldung.com/java-spanning-trees-kruskal) | ||||
| - [Balanced Brackets Algorithm in Java](https://www.baeldung.com/java-balanced-brackets-algorithm) | ||||
| - [Efficiently Merge Sorted Java Sequences](https://www.baeldung.com/java-merge-sorted-sequences) | ||||
| - [Introduction to Greedy Algorithms with Java](https://www.baeldung.com/java-greedy-algorithms) | ||||
| - [The Caesar Cipher in Java](https://www.baeldung.com/java-caesar-cipher) | ||||
| - More articles: [[<-- prev]](/../algorithms-miscellaneous-4) | ||||
| - More articles: [[<-- prev]](/../algorithms-miscellaneous-4) [[next -->]](/../algorithms-miscellaneous-6) | ||||
| 
 | ||||
|  | ||||
| @ -25,12 +25,6 @@ | ||||
|             <artifactId>commons-math3</artifactId> | ||||
|             <version>${commons-math3.version}</version> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.projectlombok</groupId> | ||||
|             <artifactId>lombok</artifactId> | ||||
|             <version>${lombok.version}</version> | ||||
|             <scope>provided</scope> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>pl.allegro.finance</groupId> | ||||
|             <artifactId>tradukisto</artifactId> | ||||
|  | ||||
							
								
								
									
										10
									
								
								algorithms-miscellaneous-6/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								algorithms-miscellaneous-6/README.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,10 @@ | ||||
| ### Relevant Articles: | ||||
| 
 | ||||
| - [Boruvka’s Algorithm for Minimum Spanning Trees](https://www.baeldung.com/java-boruvka-algorithm) | ||||
| - [Gradient Descent in Java](https://www.baeldung.com/java-gradient-descent) | ||||
| - [Kruskal’s Algorithm for Spanning Trees](https://www.baeldung.com/java-spanning-trees-kruskal) | ||||
| - [Balanced Brackets Algorithm in Java](https://www.baeldung.com/java-balanced-brackets-algorithm) | ||||
| - [Efficiently Merge Sorted Java Sequences](https://www.baeldung.com/java-merge-sorted-sequences) | ||||
| - [Introduction to Greedy Algorithms with Java](https://www.baeldung.com/java-greedy-algorithms) | ||||
| - [The Caesar Cipher in Java](https://www.baeldung.com/java-caesar-cipher) | ||||
| - More articles: [[<-- prev]](/../algorithms-miscellaneous-5) | ||||
| @ -18,10 +18,35 @@ | ||||
|             <artifactId>guava</artifactId> | ||||
|             <version>${guava.version}</version> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.junit.platform</groupId> | ||||
|             <artifactId>junit-platform-commons</artifactId> | ||||
|             <version>${junit.platform.version}</version> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.assertj</groupId> | ||||
|             <artifactId>assertj-core</artifactId> | ||||
|             <version>${org.assertj.core.version}</version> | ||||
|             <scope>test</scope> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.projectlombok</groupId> | ||||
|             <artifactId>lombok</artifactId> | ||||
|             <version>${lombok.version}</version> | ||||
|             <scope>provided</scope> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.apache.commons</groupId> | ||||
|             <artifactId>commons-math3</artifactId> | ||||
|             <version>${commons-math3.version}</version> | ||||
|         </dependency> | ||||
|     </dependencies> | ||||
|      | ||||
|     <properties> | ||||
|         <guava.version>28.1-jre</guava.version> | ||||
|         <org.assertj.core.version>3.9.0</org.assertj.core.version> | ||||
|         <junit.platform.version>1.6.0</junit.platform.version> | ||||
|         <commons-math3.version>3.6.1</commons-math3.version> | ||||
|     </properties> | ||||
| 
 | ||||
| </project> | ||||
|  | ||||
| @ -1,3 +1,7 @@ | ||||
| ### Relevant Articles: | ||||
| 
 | ||||
| - [Sorting a String Alphabetically in Java](https://www.baeldung.com/java-sort-string-alphabetically) | ||||
| - [Sorting Strings by Contained Numbers in Java](https://www.baeldung.com/java-sort-strings-contained-numbers) | ||||
| - [How an In-Place Sorting Algorithm Works](https://www.baeldung.com/java-in-place-sorting) | ||||
| - [Partitioning and Sorting Arrays with Many Repeated Entries](https://www.baeldung.com/java-sorting-arrays-with-repeated-entries) | ||||
| - More articles: [[<-- prev]](/algorithms-sorting) | ||||
|  | ||||
| @ -1,4 +1,4 @@ | ||||
| package com.baeldung.algorithms.sort.bynumber; | ||||
| package com.baeldung.algorithms.bynumber; | ||||
| 
 | ||||
| import java.util.Comparator; | ||||
| 
 | ||||
| @ -1,6 +1,5 @@ | ||||
| package com.baeldung.algorithms.sort.bynumber; | ||||
| package com.baeldung.algorithms.bynumber; | ||||
| 
 | ||||
| import com.baeldung.algorithms.sort.bynumber.NaturalOrderComparators; | ||||
| import org.junit.Test; | ||||
| 
 | ||||
| import java.util.ArrayList; | ||||
| @ -11,10 +11,7 @@ This module contains articles about sorting algorithms. | ||||
| - [Heap Sort in Java](https://www.baeldung.com/java-heap-sort) | ||||
| - [Shell Sort in Java](https://www.baeldung.com/java-shell-sort) | ||||
| - [Counting Sort in Java](https://www.baeldung.com/java-counting-sort) | ||||
| - [Sorting Strings by Contained Numbers in Java](https://www.baeldung.com/java-sort-strings-contained-numbers) | ||||
| - [How an In-Place Sorting Algorithm Works](https://www.baeldung.com/java-in-place-sorting) | ||||
| - [Selection Sort in Java](https://www.baeldung.com/java-selection-sort) | ||||
| - [Sorting Strings by Contained Numbers in Java](https://www.baeldung.com/java-sort-strings-contained-numbers) | ||||
| - [Radix Sort in Java](https://www.baeldung.com/java-radix-sort) | ||||
| - [Sorting a String Alphabetically in Java](https://www.baeldung.com/java-sort-string-alphabetically) | ||||
| - [Bucket Sort in Java](https://www.baeldung.com/java-bucket-sort) | ||||
| - More articles: [[next -->]](/algorithms-sorintg-2) | ||||
|  | ||||
| @ -1,3 +0,0 @@ | ||||
| ### Relevant Articles: | ||||
| 
 | ||||
| - [Intro to OData with Olingo](https://www.baeldung.com/olingo) | ||||
| @ -10,9 +10,9 @@ | ||||
| 
 | ||||
|     <parent> | ||||
|         <groupId>com.baeldung</groupId> | ||||
|         <artifactId>parent-boot-1</artifactId> | ||||
|         <artifactId>parent-boot-2</artifactId> | ||||
|         <version>0.0.1-SNAPSHOT</version> | ||||
|         <relativePath>../parent-boot-1</relativePath> | ||||
|         <relativePath>../parent-boot-2</relativePath> | ||||
|     </parent> | ||||
| 
 | ||||
|     <dependencies> | ||||
|  | ||||
| @ -1,11 +1,14 @@ | ||||
| package com.baeldung; | ||||
| 
 | ||||
| import org.apache.shiro.SecurityUtils; | ||||
| import org.apache.shiro.authc.*; | ||||
| import org.apache.shiro.authc.AuthenticationException; | ||||
| import org.apache.shiro.authc.IncorrectCredentialsException; | ||||
| import org.apache.shiro.authc.LockedAccountException; | ||||
| import org.apache.shiro.authc.UnknownAccountException; | ||||
| import org.apache.shiro.authc.UsernamePasswordToken; | ||||
| import org.apache.shiro.mgt.DefaultSecurityManager; | ||||
| import org.apache.shiro.mgt.SecurityManager; | ||||
| import org.apache.shiro.realm.Realm; | ||||
| import org.apache.shiro.realm.text.IniRealm; | ||||
| import org.apache.shiro.session.Session; | ||||
| import org.apache.shiro.subject.Subject; | ||||
| import org.slf4j.Logger; | ||||
|  | ||||
| @ -1,16 +1,24 @@ | ||||
| package com.baeldung; | ||||
| 
 | ||||
| import org.apache.shiro.authc.*; | ||||
| import java.sql.Connection; | ||||
| import java.sql.SQLException; | ||||
| import java.util.Arrays; | ||||
| import java.util.Collection; | ||||
| import java.util.HashMap; | ||||
| import java.util.HashSet; | ||||
| import java.util.Map; | ||||
| import java.util.Set; | ||||
| 
 | ||||
| import org.apache.shiro.authc.AuthenticationException; | ||||
| import org.apache.shiro.authc.AuthenticationInfo; | ||||
| import org.apache.shiro.authc.AuthenticationToken; | ||||
| import org.apache.shiro.authc.SimpleAuthenticationInfo; | ||||
| import org.apache.shiro.authc.UnknownAccountException; | ||||
| import org.apache.shiro.authc.UsernamePasswordToken; | ||||
| import org.apache.shiro.authz.AuthorizationInfo; | ||||
| import org.apache.shiro.authz.SimpleAuthorizationInfo; | ||||
| import org.apache.shiro.realm.jdbc.JdbcRealm; | ||||
| import org.apache.shiro.subject.PrincipalCollection; | ||||
| import org.slf4j.Logger; | ||||
| import org.slf4j.LoggerFactory; | ||||
| 
 | ||||
| import java.sql.Connection; | ||||
| import java.sql.SQLException; | ||||
| import java.util.*; | ||||
| 
 | ||||
| public class MyCustomRealm extends JdbcRealm { | ||||
| 
 | ||||
|  | ||||
| @ -1,14 +1,15 @@ | ||||
| package com.baeldung.shiro.permissions.custom; | ||||
| 
 | ||||
| import com.baeldung.MyCustomRealm; | ||||
| import org.apache.shiro.SecurityUtils; | ||||
| import org.apache.shiro.authc.*; | ||||
| import org.apache.shiro.authc.AuthenticationException; | ||||
| import org.apache.shiro.authc.IncorrectCredentialsException; | ||||
| import org.apache.shiro.authc.LockedAccountException; | ||||
| import org.apache.shiro.authc.UnknownAccountException; | ||||
| import org.apache.shiro.authc.UsernamePasswordToken; | ||||
| import org.apache.shiro.config.Ini; | ||||
| import org.apache.shiro.mgt.DefaultSecurityManager; | ||||
| import org.apache.shiro.mgt.SecurityManager; | ||||
| import org.apache.shiro.realm.Realm; | ||||
| import org.apache.shiro.realm.text.IniRealm; | ||||
| import org.apache.shiro.session.Session; | ||||
| import org.apache.shiro.subject.Subject; | ||||
| import org.slf4j.Logger; | ||||
| import org.slf4j.LoggerFactory; | ||||
|  | ||||
							
								
								
									
										6
									
								
								atomikos/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								atomikos/README.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,6 @@ | ||||
| ## Atomikos | ||||
| This module contains articles about Atomikos | ||||
| 
 | ||||
| ### Relevant Articles:  | ||||
| 
 | ||||
| - [A Guide to Atomikos](https://www.baeldung.com/java-atomikos) | ||||
							
								
								
									
										119
									
								
								atomikos/pom.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										119
									
								
								atomikos/pom.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,119 @@ | ||||
| <?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> | ||||
| 	<artifactId>atomikos</artifactId> | ||||
| 	<name>atomikos</name> | ||||
| 
 | ||||
| 	<parent> | ||||
| 		<groupId>com.baeldung</groupId> | ||||
| 		<artifactId>parent-modules</artifactId> | ||||
| 		<version>1.0.0-SNAPSHOT</version> | ||||
| 	</parent> | ||||
| 
 | ||||
| 	<dependencies> | ||||
| 		<dependency> | ||||
| 			<groupId>com.atomikos</groupId> | ||||
| 			<artifactId>transactions-jdbc</artifactId> | ||||
| 			<version>${atomikos-version}</version> | ||||
| 		</dependency> | ||||
| 		<dependency> | ||||
| 			<groupId>com.atomikos</groupId> | ||||
| 			<artifactId>transactions-jms</artifactId> | ||||
| 			<version>${atomikos-version}</version> | ||||
| 		</dependency> | ||||
| 		<dependency> | ||||
| 			<groupId>com.atomikos</groupId> | ||||
| 			<artifactId>transactions-hibernate4</artifactId> | ||||
| 			<version>${atomikos-version}</version> | ||||
| 		</dependency> | ||||
| 		<dependency> | ||||
| 			<groupId>org.springframework</groupId> | ||||
| 			<artifactId>spring-context</artifactId> | ||||
| 			<version>${spring-version}</version> | ||||
| 		</dependency> | ||||
| 		<dependency> | ||||
| 			<groupId>org.springframework</groupId> | ||||
| 			<artifactId>spring-tx</artifactId> | ||||
| 			<version>${spring-version}</version> | ||||
| 		</dependency> | ||||
| 		<dependency> | ||||
| 			<groupId>org.springframework.data</groupId> | ||||
| 			<artifactId>spring-data-jpa</artifactId> | ||||
| 			<version>1.11.23.RELEASE</version> | ||||
| 		</dependency> | ||||
| 		<dependency> | ||||
| 			<groupId>org.springframework</groupId> | ||||
| 			<artifactId>spring-test</artifactId> | ||||
| 			<version>${spring-version}</version> | ||||
| 			<scope>test</scope> | ||||
| 		</dependency> | ||||
| 		<dependency> | ||||
| 			<groupId>org.hibernate</groupId> | ||||
| 			<artifactId>hibernate-entitymanager</artifactId> | ||||
| 			<version>${hibernate.version}</version> | ||||
| 			<scope>provided</scope> | ||||
| 			<exclusions> | ||||
| 				<exclusion> | ||||
| 					<groupId>javax.transaction</groupId> | ||||
| 					<artifactId>jta</artifactId> | ||||
| 				</exclusion> | ||||
| 			</exclusions> | ||||
| 		</dependency> | ||||
| 		<dependency> | ||||
| 			<groupId>org.apache.activemq</groupId> | ||||
| 			<artifactId>activemq-core</artifactId> | ||||
| 			<version>5.7.0</version> | ||||
| 		</dependency> | ||||
| 		<dependency> | ||||
| 			<groupId>org.apache.derby</groupId> | ||||
| 			<artifactId>derby</artifactId> | ||||
| 			<version>10.8.1.2</version> | ||||
| 		</dependency> | ||||
| 		<dependency> | ||||
| 			<groupId>junit</groupId> | ||||
| 			<artifactId>junit</artifactId> | ||||
| 			<version>4.12</version> | ||||
| 			<scope>test</scope> | ||||
| 		</dependency> | ||||
| 		<!-- the JTA API --> | ||||
| 		<dependency> | ||||
| 			<groupId>javax.transaction</groupId> | ||||
| 			<artifactId>jta</artifactId> | ||||
| 			<version>1.1</version> | ||||
| 		</dependency> | ||||
| 		<dependency> | ||||
| 			<groupId>org.apache.geronimo.specs</groupId> | ||||
| 			<artifactId>geronimo-jta_1.0.1B_spec</artifactId> | ||||
| 			<version>1.0</version> | ||||
| 		</dependency> | ||||
| 		<dependency> | ||||
| 			<groupId>javax.validation</groupId> | ||||
| 			<artifactId>validation-api</artifactId> | ||||
| 			<version>2.0.1.Final</version> | ||||
| 		</dependency> | ||||
| 		<dependency> | ||||
| 			<groupId>org.hibernate.validator</groupId> | ||||
| 			<artifactId>hibernate-validator</artifactId> | ||||
| 			<version>6.1.2.Final</version> | ||||
| 		</dependency> | ||||
| 		<dependency> | ||||
| 			<groupId>javax.el</groupId> | ||||
| 			<artifactId>javax.el-api</artifactId> | ||||
| 			<version>3.0.0</version> | ||||
| 		</dependency> | ||||
| 		<dependency> | ||||
| 			<groupId>org.glassfish.web</groupId> | ||||
| 			<artifactId>javax.el</artifactId> | ||||
| 			<version>2.2.4</version> | ||||
| 		</dependency> | ||||
| 	</dependencies> | ||||
| 
 | ||||
| 	<properties> | ||||
| 		<atomikos-version>5.0.6</atomikos-version> | ||||
| 		<spring-version>5.1.6.RELEASE</spring-version> | ||||
| 		<hibernate.version>5.4.3.Final</hibernate.version> | ||||
| 	</properties> | ||||
| 
 | ||||
| </project> | ||||
| @ -0,0 +1,53 @@ | ||||
| package com.baeldung.atomikos.direct; | ||||
| 
 | ||||
| import java.sql.Connection; | ||||
| import java.sql.Statement; | ||||
| import java.util.UUID; | ||||
| 
 | ||||
| import javax.sql.DataSource; | ||||
| 
 | ||||
| import com.atomikos.icatch.jta.UserTransactionImp; | ||||
| 
 | ||||
| public class Application { | ||||
| 
 | ||||
|     private DataSource inventoryDataSource; | ||||
|     private DataSource orderDataSource; | ||||
| 
 | ||||
|     public Application(DataSource inventoryDataSource, DataSource orderDataSource) { | ||||
|         this.inventoryDataSource = inventoryDataSource; | ||||
|         this.orderDataSource = orderDataSource; | ||||
|     } | ||||
| 
 | ||||
|     public void placeOrder(String productId, int amount) throws Exception { | ||||
| 
 | ||||
|         UserTransactionImp utx = new UserTransactionImp(); | ||||
|         String orderId = UUID.randomUUID() | ||||
|             .toString(); | ||||
|         boolean rollback = false; | ||||
|         try { | ||||
|             utx.begin(); | ||||
|             Connection inventoryConnection = inventoryDataSource.getConnection(); | ||||
|             Connection orderConnection = orderDataSource.getConnection(); | ||||
|             Statement s1 = inventoryConnection.createStatement(); | ||||
|             String q1 = "update Inventory set balance = balance - " + amount + " where productId ='" + productId + "'"; | ||||
|             s1.executeUpdate(q1); | ||||
|             s1.close(); | ||||
|             Statement s2 = orderConnection.createStatement(); | ||||
|             String q2 = "insert into Orders values ( '" + orderId + "', '" + productId + "', " + amount + " )"; | ||||
|             s2.executeUpdate(q2); | ||||
|             s2.close(); | ||||
|             inventoryConnection.close(); | ||||
|             orderConnection.close(); | ||||
|         } catch (Exception e) { | ||||
|             System.out.println(e.getMessage()); | ||||
|             rollback = true; | ||||
|         } finally { | ||||
|             if (!rollback) | ||||
|                 utx.commit(); | ||||
|             else | ||||
|                 utx.rollback(); | ||||
|         } | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,41 @@ | ||||
| package com.baeldung.atomikos.spring; | ||||
| 
 | ||||
| import java.sql.Connection; | ||||
| import java.sql.Statement; | ||||
| import java.util.UUID; | ||||
| 
 | ||||
| import javax.sql.DataSource; | ||||
| 
 | ||||
| import org.springframework.transaction.annotation.Transactional; | ||||
| 
 | ||||
| public class Application { | ||||
| 
 | ||||
|     private DataSource inventoryDataSource; | ||||
|     private DataSource orderDataSource; | ||||
| 
 | ||||
|     public Application(DataSource inventoryDataSource, DataSource orderDataSource) { | ||||
|         this.inventoryDataSource = inventoryDataSource; | ||||
|         this.orderDataSource = orderDataSource; | ||||
|     } | ||||
| 
 | ||||
|     @Transactional(rollbackFor = Exception.class) | ||||
|     public void placeOrder(String productId, int amount) throws Exception { | ||||
| 
 | ||||
|         String orderId = UUID.randomUUID() | ||||
|             .toString(); | ||||
|         Connection inventoryConnection = inventoryDataSource.getConnection(); | ||||
|         Connection orderConnection = orderDataSource.getConnection(); | ||||
|         Statement s1 = inventoryConnection.createStatement(); | ||||
|         String q1 = "update Inventory set balance = balance - " + amount + " where productId ='" + productId + "'"; | ||||
|         s1.executeUpdate(q1); | ||||
|         s1.close(); | ||||
|         Statement s2 = orderConnection.createStatement(); | ||||
|         String q2 = "insert into Orders values ( '" + orderId + "', '" + productId + "', " + amount + " )"; | ||||
|         s2.executeUpdate(q2); | ||||
|         s2.close(); | ||||
|         inventoryConnection.close(); | ||||
|         orderConnection.close(); | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,68 @@ | ||||
| package com.baeldung.atomikos.spring.config; | ||||
| 
 | ||||
| import java.util.Properties; | ||||
| 
 | ||||
| import javax.transaction.SystemException; | ||||
| 
 | ||||
| import org.springframework.context.annotation.Bean; | ||||
| import org.springframework.context.annotation.Configuration; | ||||
| import org.springframework.transaction.annotation.EnableTransactionManagement; | ||||
| import org.springframework.transaction.jta.JtaTransactionManager; | ||||
| 
 | ||||
| import com.atomikos.icatch.jta.UserTransactionManager; | ||||
| import com.atomikos.jdbc.AtomikosDataSourceBean; | ||||
| import com.baeldung.atomikos.spring.Application; | ||||
| 
 | ||||
| @Configuration | ||||
| @EnableTransactionManagement | ||||
| public class Config { | ||||
| 
 | ||||
|     @Bean(initMethod = "init", destroyMethod = "close") | ||||
|     public AtomikosDataSourceBean inventoryDataSource() { | ||||
|         AtomikosDataSourceBean dataSource = new AtomikosDataSourceBean(); | ||||
|         dataSource.setLocalTransactionMode(true); | ||||
|         dataSource.setUniqueResourceName("db1"); | ||||
|         dataSource.setXaDataSourceClassName("org.apache.derby.jdbc.EmbeddedXADataSource"); | ||||
|         Properties xaProperties = new Properties(); | ||||
|         xaProperties.put("databaseName", "db1"); | ||||
|         xaProperties.put("createDatabase", "create"); | ||||
|         dataSource.setXaProperties(xaProperties); | ||||
|         dataSource.setPoolSize(10); | ||||
|         return dataSource; | ||||
|     } | ||||
| 
 | ||||
|     @Bean(initMethod = "init", destroyMethod = "close") | ||||
|     public AtomikosDataSourceBean orderDataSource() { | ||||
|         AtomikosDataSourceBean dataSource = new AtomikosDataSourceBean(); | ||||
|         dataSource.setLocalTransactionMode(true); | ||||
|         dataSource.setUniqueResourceName("db2"); | ||||
|         dataSource.setXaDataSourceClassName("org.apache.derby.jdbc.EmbeddedXADataSource"); | ||||
|         Properties xaProperties = new Properties(); | ||||
|         xaProperties.put("databaseName", "db2"); | ||||
|         xaProperties.put("createDatabase", "create"); | ||||
|         dataSource.setXaProperties(xaProperties); | ||||
|         dataSource.setPoolSize(10); | ||||
|         return dataSource; | ||||
|     } | ||||
| 
 | ||||
|     @Bean(initMethod = "init", destroyMethod = "close") | ||||
|     public UserTransactionManager userTransactionManager() throws SystemException { | ||||
|         UserTransactionManager userTransactionManager = new UserTransactionManager(); | ||||
|         userTransactionManager.setTransactionTimeout(300); | ||||
|         userTransactionManager.setForceShutdown(true); | ||||
|         return userTransactionManager; | ||||
|     } | ||||
| 
 | ||||
|     @Bean | ||||
|     public JtaTransactionManager jtaTransactionManager() throws SystemException { | ||||
|         JtaTransactionManager jtaTransactionManager = new JtaTransactionManager(); | ||||
|         jtaTransactionManager.setTransactionManager(userTransactionManager()); | ||||
|         jtaTransactionManager.setUserTransaction(userTransactionManager()); | ||||
|         return jtaTransactionManager; | ||||
|     } | ||||
| 
 | ||||
|     @Bean | ||||
|     public Application application() { | ||||
|         return new Application(inventoryDataSource(), orderDataSource()); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,48 @@ | ||||
| package com.baeldung.atomikos.spring.jpa; | ||||
| 
 | ||||
| import java.util.Set; | ||||
| import java.util.UUID; | ||||
| 
 | ||||
| import javax.validation.ConstraintViolation; | ||||
| import javax.validation.Validation; | ||||
| import javax.validation.Validator; | ||||
| import javax.validation.ValidatorFactory; | ||||
| 
 | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.transaction.annotation.Transactional; | ||||
| 
 | ||||
| import com.baeldung.atomikos.spring.jpa.inventory.Inventory; | ||||
| import com.baeldung.atomikos.spring.jpa.inventory.InventoryRepository; | ||||
| import com.baeldung.atomikos.spring.jpa.order.Order; | ||||
| import com.baeldung.atomikos.spring.jpa.order.OrderRepository; | ||||
| 
 | ||||
| public class Application { | ||||
| 
 | ||||
|     @Autowired | ||||
|     private InventoryRepository inventoryRepository; | ||||
| 
 | ||||
|     @Autowired | ||||
|     private OrderRepository orderRepository; | ||||
| 
 | ||||
|     @Transactional(rollbackFor = Exception.class) | ||||
|     public void placeOrder(String productId, int amount) throws Exception { | ||||
| 
 | ||||
|         String orderId = UUID.randomUUID() | ||||
|             .toString(); | ||||
|         Inventory inventory = inventoryRepository.findOne(productId); | ||||
|         inventory.setBalance(inventory.getBalance() - amount); | ||||
|         inventoryRepository.save(inventory); | ||||
|         Order order = new Order(); | ||||
|         order.setOrderId(orderId); | ||||
|         order.setProductId(productId); | ||||
|         order.setAmount(new Long(amount)); | ||||
|         ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); | ||||
|         Validator validator = factory.getValidator(); | ||||
|         Set<ConstraintViolation<Order>> violations = validator.validate(order); | ||||
|         if (violations.size() > 0) | ||||
|             throw new Exception("Invalid instance of an order."); | ||||
|         orderRepository.save(order); | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,38 @@ | ||||
| package com.baeldung.atomikos.spring.jpa.config; | ||||
| 
 | ||||
| import javax.transaction.SystemException; | ||||
| 
 | ||||
| import org.springframework.context.annotation.Bean; | ||||
| import org.springframework.context.annotation.Configuration; | ||||
| import org.springframework.transaction.annotation.EnableTransactionManagement; | ||||
| import org.springframework.transaction.jta.JtaTransactionManager; | ||||
| 
 | ||||
| import com.atomikos.icatch.jta.UserTransactionManager; | ||||
| import com.baeldung.atomikos.spring.jpa.Application; | ||||
| 
 | ||||
| @Configuration | ||||
| @EnableTransactionManagement | ||||
| public class Config { | ||||
| 
 | ||||
|     @Bean(initMethod = "init", destroyMethod = "close") | ||||
|     public UserTransactionManager userTransactionManager() throws SystemException { | ||||
|         UserTransactionManager userTransactionManager = new UserTransactionManager(); | ||||
|         userTransactionManager.setTransactionTimeout(300); | ||||
|         userTransactionManager.setForceShutdown(true); | ||||
|         return userTransactionManager; | ||||
|     } | ||||
| 
 | ||||
|     @Bean | ||||
|     public JtaTransactionManager transactionManager() throws SystemException { | ||||
|         JtaTransactionManager jtaTransactionManager = new JtaTransactionManager(); | ||||
|         jtaTransactionManager.setTransactionManager(userTransactionManager()); | ||||
|         jtaTransactionManager.setUserTransaction(userTransactionManager()); | ||||
|         return jtaTransactionManager; | ||||
|     } | ||||
| 
 | ||||
|     @Bean | ||||
|     public Application application() { | ||||
|         return new Application(); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,31 @@ | ||||
| package com.baeldung.atomikos.spring.jpa.inventory; | ||||
| 
 | ||||
| import javax.persistence.Entity; | ||||
| import javax.persistence.Id; | ||||
| import javax.persistence.Table; | ||||
| 
 | ||||
| @Entity | ||||
| @Table(name = "INVENTORY") | ||||
| public class Inventory { | ||||
| 
 | ||||
|     @Id | ||||
|     private String productId; | ||||
|     private Long balance; | ||||
| 
 | ||||
|     public String getProductId() { | ||||
|         return productId; | ||||
|     } | ||||
| 
 | ||||
|     public void setProductId(String productId) { | ||||
|         this.productId = productId; | ||||
|     } | ||||
| 
 | ||||
|     public Long getBalance() { | ||||
|         return balance; | ||||
|     } | ||||
| 
 | ||||
|     public void setBalance(Long balance) { | ||||
|         this.balance = balance; | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,53 @@ | ||||
| package com.baeldung.atomikos.spring.jpa.inventory; | ||||
| 
 | ||||
| import java.util.Properties; | ||||
| 
 | ||||
| import javax.persistence.EntityManagerFactory; | ||||
| 
 | ||||
| import org.springframework.context.annotation.Bean; | ||||
| import org.springframework.context.annotation.Configuration; | ||||
| import org.springframework.data.jpa.repository.config.EnableJpaRepositories; | ||||
| import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; | ||||
| import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; | ||||
| 
 | ||||
| import com.atomikos.jdbc.AtomikosDataSourceBean; | ||||
| 
 | ||||
| @Configuration | ||||
| @EnableJpaRepositories(basePackages = "com.baeldung.atomikos.spring.jpa.inventory", entityManagerFactoryRef = "inventoryEntityManager", transactionManagerRef = "transactionManager") | ||||
| public class InventoryConfig { | ||||
| 
 | ||||
|     @Bean(initMethod = "init", destroyMethod = "close") | ||||
|     public AtomikosDataSourceBean inventoryDataSource() { | ||||
|         AtomikosDataSourceBean dataSource = new AtomikosDataSourceBean(); | ||||
|         dataSource.setLocalTransactionMode(true); | ||||
|         dataSource.setUniqueResourceName("db1"); | ||||
|         dataSource.setXaDataSourceClassName("org.apache.derby.jdbc.EmbeddedXADataSource"); | ||||
|         Properties xaProperties = new Properties(); | ||||
|         xaProperties.put("databaseName", "db1"); | ||||
|         xaProperties.put("createDatabase", "create"); | ||||
|         dataSource.setXaProperties(xaProperties); | ||||
|         dataSource.setPoolSize(10); | ||||
|         return dataSource; | ||||
|     } | ||||
| 
 | ||||
|     @Bean | ||||
|     public EntityManagerFactory inventoryEntityManager() { | ||||
|         HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); | ||||
|         LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean(); | ||||
|         factory.setJpaVendorAdapter(vendorAdapter); | ||||
|         factory.setPackagesToScan("com.baeldung.atomikos.spring.jpa.inventory"); | ||||
|         factory.setDataSource(inventoryDataSource()); | ||||
|         Properties jpaProperties = new Properties(); | ||||
|         //jpaProperties.put("hibernate.show_sql", "true"); | ||||
|         //jpaProperties.put("hibernate.format_sql", "true"); | ||||
|         jpaProperties.put("hibernate.dialect", "org.hibernate.dialect.DerbyDialect"); | ||||
|         jpaProperties.put("hibernate.current_session_context_class", "jta"); | ||||
|         jpaProperties.put("javax.persistence.transactionType", "jta"); | ||||
|         jpaProperties.put("hibernate.transaction.manager_lookup_class", "com.atomikos.icatch.jta.hibernate3.TransactionManagerLookup"); | ||||
|         jpaProperties.put("hibernate.hbm2ddl.auto", "create-drop"); | ||||
|         factory.setJpaProperties(jpaProperties); | ||||
|         factory.afterPropertiesSet(); | ||||
|         return factory.getObject(); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,9 @@ | ||||
| package com.baeldung.atomikos.spring.jpa.inventory; | ||||
| 
 | ||||
| import org.springframework.data.jpa.repository.JpaRepository; | ||||
| import org.springframework.stereotype.Repository; | ||||
| 
 | ||||
| @Repository | ||||
| public interface InventoryRepository extends JpaRepository<Inventory, String> { | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,42 @@ | ||||
| package com.baeldung.atomikos.spring.jpa.order; | ||||
| 
 | ||||
| import javax.persistence.Entity; | ||||
| import javax.persistence.Id; | ||||
| import javax.persistence.Table; | ||||
| import javax.validation.constraints.Max; | ||||
| 
 | ||||
| @Entity | ||||
| @Table(name = "ORDERS") | ||||
| public class Order { | ||||
| 
 | ||||
|     @Id | ||||
|     private String orderId; | ||||
|     private String productId; | ||||
|     @Max(5) | ||||
|     private Long amount; | ||||
| 
 | ||||
|     public String getOrderId() { | ||||
|         return orderId; | ||||
|     } | ||||
| 
 | ||||
|     public void setOrderId(String orderId) { | ||||
|         this.orderId = orderId; | ||||
|     } | ||||
| 
 | ||||
|     public String getProductId() { | ||||
|         return productId; | ||||
|     } | ||||
| 
 | ||||
|     public void setProductId(String productId) { | ||||
|         this.productId = productId; | ||||
|     } | ||||
| 
 | ||||
|     public Long getAmount() { | ||||
|         return amount; | ||||
|     } | ||||
| 
 | ||||
|     public void setAmount(Long amount) { | ||||
|         this.amount = amount; | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,53 @@ | ||||
| package com.baeldung.atomikos.spring.jpa.order; | ||||
| 
 | ||||
| import java.util.Properties; | ||||
| 
 | ||||
| import javax.persistence.EntityManagerFactory; | ||||
| 
 | ||||
| import org.springframework.context.annotation.Bean; | ||||
| import org.springframework.context.annotation.Configuration; | ||||
| import org.springframework.data.jpa.repository.config.EnableJpaRepositories; | ||||
| import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; | ||||
| import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; | ||||
| 
 | ||||
| import com.atomikos.jdbc.AtomikosDataSourceBean; | ||||
| 
 | ||||
| @Configuration | ||||
| @EnableJpaRepositories(basePackages = "com.baeldung.atomikos.spring.jpa.order", entityManagerFactoryRef = "orderEntityManager", transactionManagerRef = "transactionManager") | ||||
| public class OrderConfig { | ||||
| 
 | ||||
|     @Bean(initMethod = "init", destroyMethod = "close") | ||||
|     public AtomikosDataSourceBean orderDataSource() { | ||||
|         AtomikosDataSourceBean dataSource = new AtomikosDataSourceBean(); | ||||
|         dataSource.setLocalTransactionMode(true); | ||||
|         dataSource.setUniqueResourceName("db2"); | ||||
|         dataSource.setXaDataSourceClassName("org.apache.derby.jdbc.EmbeddedXADataSource"); | ||||
|         Properties xaProperties = new Properties(); | ||||
|         xaProperties.put("databaseName", "db2"); | ||||
|         xaProperties.put("createDatabase", "create"); | ||||
|         dataSource.setXaProperties(xaProperties); | ||||
|         dataSource.setPoolSize(10); | ||||
|         return dataSource; | ||||
|     } | ||||
| 
 | ||||
|     @Bean | ||||
|     public EntityManagerFactory orderEntityManager() { | ||||
|         HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); | ||||
|         LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean(); | ||||
|         factory.setJpaVendorAdapter(vendorAdapter); | ||||
|         factory.setPackagesToScan("com.baeldung.atomikos.spring.jpa.order"); | ||||
|         factory.setDataSource(orderDataSource()); | ||||
|         Properties jpaProperties = new Properties(); | ||||
|         //jpaProperties.put("hibernate.show_sql", "true"); | ||||
|         //jpaProperties.put("hibernate.format_sql", "true"); | ||||
|         jpaProperties.put("hibernate.dialect", "org.hibernate.dialect.DerbyDialect"); | ||||
|         jpaProperties.put("hibernate.current_session_context_class", "jta"); | ||||
|         jpaProperties.put("javax.persistence.transactionType", "jta"); | ||||
|         jpaProperties.put("hibernate.transaction.manager_lookup_class", "com.atomikos.icatch.jta.hibernate3.TransactionManagerLookup"); | ||||
|         jpaProperties.put("hibernate.hbm2ddl.auto", "create-drop"); | ||||
|         factory.setJpaProperties(jpaProperties); | ||||
|         factory.afterPropertiesSet(); | ||||
|         return factory.getObject(); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,9 @@ | ||||
| package com.baeldung.atomikos.spring.jpa.order; | ||||
| 
 | ||||
| import org.springframework.data.jpa.repository.JpaRepository; | ||||
| import org.springframework.stereotype.Repository; | ||||
| 
 | ||||
| @Repository | ||||
| public interface OrderRepository extends JpaRepository<Order, String> { | ||||
| 
 | ||||
| } | ||||
							
								
								
									
										10
									
								
								atomikos/src/main/resources/schema.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								atomikos/src/main/resources/schema.sql
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,10 @@ | ||||
| CREATE TABLE INVENTORY ( | ||||
|     productId VARCHAR PRIMARY KEY, | ||||
|     balance INT | ||||
| ); | ||||
| 
 | ||||
| CREATE TABLE ORDERS ( | ||||
|     orderId VARCHAR PRIMARY KEY, | ||||
|     productId VARCHAR, | ||||
|     amount INT NOT NULL CHECK (amount <= 5) | ||||
| ); | ||||
							
								
								
									
										1
									
								
								atomikos/src/main/resources/transactions.properties
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								atomikos/src/main/resources/transactions.properties
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1 @@ | ||||
| com.atomikos.icatch.file=logs | ||||
| @ -0,0 +1,118 @@ | ||||
| package com.baeldung.atomikos.direct; | ||||
| 
 | ||||
| import static org.junit.jupiter.api.Assertions.assertEquals; | ||||
| 
 | ||||
| import java.sql.Connection; | ||||
| import java.sql.ResultSet; | ||||
| import java.sql.SQLException; | ||||
| import java.sql.Statement; | ||||
| import java.util.Properties; | ||||
| import java.util.UUID; | ||||
| 
 | ||||
| import javax.sql.DataSource; | ||||
| 
 | ||||
| import org.junit.BeforeClass; | ||||
| import org.junit.Ignore; | ||||
| import org.junit.Test; | ||||
| 
 | ||||
| import com.atomikos.icatch.jta.UserTransactionImp; | ||||
| import com.atomikos.jdbc.AtomikosDataSourceBean; | ||||
| 
 | ||||
| public class ApplicationUnitTest { | ||||
| 
 | ||||
|     private static DataSource inventoryDataSource; | ||||
|     private static DataSource orderDataSource; | ||||
| 
 | ||||
|     private static String productId = UUID.randomUUID() | ||||
|         .toString(); | ||||
| 
 | ||||
|     @Test | ||||
|     @Ignore | ||||
|     public void testPlaceOrderSuccess() throws Exception { | ||||
|         int amount = 1; | ||||
|         long initialBalance = getBalance(inventoryDataSource, productId); | ||||
|         Application application = new Application(inventoryDataSource, orderDataSource); | ||||
|         application.placeOrder(productId, amount); | ||||
|         long finalBalance = getBalance(inventoryDataSource, productId); | ||||
|         assertEquals(initialBalance - amount, finalBalance); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     @Ignore | ||||
|     public void testPlaceOrderFailure() throws Exception { | ||||
|         int amount = 10; | ||||
|         long initialBalance = getBalance(inventoryDataSource, productId); | ||||
|         Application application = new Application(inventoryDataSource, orderDataSource); | ||||
|         application.placeOrder(productId, amount); | ||||
|         long finalBalance = getBalance(inventoryDataSource, productId); | ||||
|         assertEquals(initialBalance, finalBalance); | ||||
|     } | ||||
| 
 | ||||
|     @BeforeClass | ||||
|     public static void setUp() throws SQLException { | ||||
| 
 | ||||
|         inventoryDataSource = getDataSource("db1"); | ||||
|         orderDataSource = getDataSource("db2"); | ||||
|         Connection inventoryConnection = inventoryDataSource.getConnection(); | ||||
|         Connection orderConnection = orderDataSource.getConnection(); | ||||
|         String createInventoryTable = "create table Inventory ( " + " productId VARCHAR ( 100 ) PRIMARY KEY, balance INT )"; | ||||
|         String createInventoryRow = "insert into Inventory values ( '" + productId + "', 10000 )"; | ||||
|         Statement s1 = inventoryConnection.createStatement(); | ||||
|         try { | ||||
|             s1.executeUpdate(createInventoryTable); | ||||
|         } catch (Exception e) { | ||||
|             System.out.println("Inventory table exists"); | ||||
|         } | ||||
|         try { | ||||
|             s1.executeUpdate(createInventoryRow); | ||||
|         } catch (Exception e) { | ||||
|             System.out.println("Product row exists"); | ||||
|         } | ||||
|         s1.close(); | ||||
|         String createOrderTable = "create table Orders ( orderId VARCHAR ( 100 ) PRIMARY KEY, productId VARCHAR ( 100 ), amount INT NOT NULL CHECK (amount <= 5) )"; | ||||
|         Statement s2 = orderConnection.createStatement(); | ||||
|         try { | ||||
|             s2.executeUpdate(createOrderTable); | ||||
|         } catch (Exception e) { | ||||
|             System.out.println("Orders table exists"); | ||||
|         } | ||||
|         s2.close(); | ||||
|         inventoryConnection.close(); | ||||
|         orderConnection.close(); | ||||
|     } | ||||
| 
 | ||||
|     private static DataSource getDataSource(String db) { | ||||
| 
 | ||||
|         DataSource ds; | ||||
|         AtomikosDataSourceBean ads = new AtomikosDataSourceBean(); | ||||
|         ads.setXaDataSourceClassName("org.apache.derby.jdbc.EmbeddedXADataSource"); | ||||
|         Properties properties = new Properties(); | ||||
|         properties.put("databaseName", db); | ||||
|         properties.put("createDatabase", "create"); | ||||
|         ads.setXaProperties(properties); | ||||
|         ads.setUniqueResourceName(db); | ||||
|         ads.setPoolSize(10); // optional | ||||
|         ads.setBorrowConnectionTimeout(10); // optional | ||||
|         ds = ads; | ||||
|         return ds; | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     private static long getBalance(DataSource inventoryDataSource, String productId) throws Exception { | ||||
| 
 | ||||
|         UserTransactionImp utx = new UserTransactionImp(); | ||||
|         utx.begin(); | ||||
|         Connection inventoryConnection = inventoryDataSource.getConnection(); | ||||
|         Statement s1 = inventoryConnection.createStatement(); | ||||
|         String q1 = "select balance from Inventory where productId='" + productId + "'"; | ||||
|         ResultSet rs1 = s1.executeQuery(q1); | ||||
|         if (rs1 == null || !rs1.next()) | ||||
|             throw new Exception("Product not found: " + productId); | ||||
|         long balance = rs1.getLong(1); | ||||
|         inventoryConnection.close(); | ||||
|         utx.commit(); | ||||
|         return balance; | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,108 @@ | ||||
| package com.baeldung.atomikos.spring; | ||||
| 
 | ||||
| import static org.junit.jupiter.api.Assertions.assertEquals; | ||||
| 
 | ||||
| import java.sql.Connection; | ||||
| import java.sql.ResultSet; | ||||
| import java.sql.SQLException; | ||||
| import java.sql.Statement; | ||||
| import java.util.UUID; | ||||
| 
 | ||||
| import javax.sql.DataSource; | ||||
| 
 | ||||
| import org.junit.Before; | ||||
| import org.junit.Ignore; | ||||
| import org.junit.Test; | ||||
| import org.junit.runner.RunWith; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.test.context.ContextConfiguration; | ||||
| import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; | ||||
| 
 | ||||
| import com.baeldung.atomikos.spring.config.Config; | ||||
| 
 | ||||
| @RunWith(SpringJUnit4ClassRunner.class) | ||||
| @ContextConfiguration(classes = { Config.class }) | ||||
| public class ApplicationUnitTest { | ||||
| 
 | ||||
|     private static String productId = UUID.randomUUID() | ||||
|         .toString(); | ||||
| 
 | ||||
|     @Autowired | ||||
|     Application application; | ||||
| 
 | ||||
|     @Autowired | ||||
|     DataSource inventoryDataSource; | ||||
| 
 | ||||
|     @Autowired | ||||
|     DataSource orderDataSource; | ||||
| 
 | ||||
|     @Test | ||||
|     @Ignore | ||||
|     public void testPlaceOrderSuccess() throws Exception { | ||||
|         int amount = 1; | ||||
|         long initialBalance = getBalance(inventoryDataSource, productId); | ||||
|         application.placeOrder(productId, amount); | ||||
|         long finalBalance = getBalance(inventoryDataSource, productId); | ||||
|         assertEquals(initialBalance - amount, finalBalance); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     @Ignore | ||||
|     public void testPlaceOrderFailure() throws Exception { | ||||
|         int amount = 10; | ||||
|         long initialBalance = getBalance(inventoryDataSource, productId); | ||||
|         try { | ||||
|             application.placeOrder(productId, amount); | ||||
|         } catch (Exception e) { | ||||
|             System.out.println(e.getMessage()); | ||||
|         } | ||||
|         long finalBalance = getBalance(inventoryDataSource, productId); | ||||
|         assertEquals(initialBalance, finalBalance); | ||||
|     } | ||||
| 
 | ||||
|     @Before | ||||
|     public void setUp() throws SQLException { | ||||
| 
 | ||||
|         Connection inventoryConnection = inventoryDataSource.getConnection(); | ||||
|         Connection orderConnection = orderDataSource.getConnection(); | ||||
|         String createInventoryTable = "create table Inventory ( " + " productId VARCHAR ( 100 ) PRIMARY KEY, balance INT )"; | ||||
|         String createInventoryRow = "insert into Inventory values ( '" + productId + "', 10000 )"; | ||||
|         Statement s1 = inventoryConnection.createStatement(); | ||||
|         try { | ||||
|             s1.executeUpdate(createInventoryTable); | ||||
|         } catch (Exception e) { | ||||
|             System.out.println("Inventory table exists"); | ||||
|         } | ||||
|         try { | ||||
|             s1.executeUpdate(createInventoryRow); | ||||
|         } catch (Exception e) { | ||||
|             System.out.println("Product row exists"); | ||||
|         } | ||||
|         s1.close(); | ||||
|         String createOrderTable = "create table Orders ( orderId VARCHAR ( 100 ) PRIMARY KEY, productId VARCHAR ( 100 ), amount INT NOT NULL CHECK (amount <= 5) )"; | ||||
|         Statement s2 = orderConnection.createStatement(); | ||||
|         try { | ||||
|             s2.executeUpdate(createOrderTable); | ||||
|         } catch (Exception e) { | ||||
|             System.out.println("Orders table exists"); | ||||
|         } | ||||
|         s2.close(); | ||||
|         inventoryConnection.close(); | ||||
|         orderConnection.close(); | ||||
|     } | ||||
| 
 | ||||
|     private static long getBalance(DataSource inventoryDataSource, String productId) throws Exception { | ||||
| 
 | ||||
|         Connection inventoryConnection = inventoryDataSource.getConnection(); | ||||
|         Statement s1 = inventoryConnection.createStatement(); | ||||
|         String q1 = "select balance from Inventory where productId='" + productId + "'"; | ||||
|         ResultSet rs1 = s1.executeQuery(q1); | ||||
|         if (rs1 == null || !rs1.next()) | ||||
|             throw new Exception("Product not found: " + productId); | ||||
|         long balance = rs1.getLong(1); | ||||
|         inventoryConnection.close(); | ||||
|         return balance; | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,80 @@ | ||||
| package com.baeldung.atomikos.spring.jpa; | ||||
| 
 | ||||
| import static org.junit.jupiter.api.Assertions.assertEquals; | ||||
| 
 | ||||
| import java.sql.SQLException; | ||||
| import java.util.UUID; | ||||
| 
 | ||||
| import org.junit.Before; | ||||
| import org.junit.Ignore; | ||||
| import org.junit.Test; | ||||
| import org.junit.runner.RunWith; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.test.context.ContextConfiguration; | ||||
| import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; | ||||
| 
 | ||||
| import com.baeldung.atomikos.spring.jpa.config.Config; | ||||
| import com.baeldung.atomikos.spring.jpa.inventory.Inventory; | ||||
| import com.baeldung.atomikos.spring.jpa.inventory.InventoryConfig; | ||||
| import com.baeldung.atomikos.spring.jpa.inventory.InventoryRepository; | ||||
| import com.baeldung.atomikos.spring.jpa.order.OrderConfig; | ||||
| import com.baeldung.atomikos.spring.jpa.order.OrderRepository; | ||||
| 
 | ||||
| @RunWith(SpringJUnit4ClassRunner.class) | ||||
| @ContextConfiguration(classes = { Config.class, InventoryConfig.class, OrderConfig.class }) | ||||
| public class ApplicationUnitTest { | ||||
| 
 | ||||
|     private static String productId = UUID.randomUUID() | ||||
|         .toString(); | ||||
| 
 | ||||
|     @Autowired | ||||
|     Application application; | ||||
| 
 | ||||
|     @Autowired | ||||
|     InventoryRepository inventoryRepository; | ||||
| 
 | ||||
|     @Autowired | ||||
|     OrderRepository orderRepository; | ||||
| 
 | ||||
|     @Test | ||||
|     @Ignore | ||||
|     public void testPlaceOrderSuccess() throws Exception { | ||||
|         int amount = 1; | ||||
|         long initialBalance = getBalance(inventoryRepository, productId); | ||||
|         application.placeOrder(productId, amount); | ||||
|         long finalBalance = getBalance(inventoryRepository, productId); | ||||
|         assertEquals(initialBalance - amount, finalBalance); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     @Ignore | ||||
|     public void testPlaceOrderFailure() throws Exception { | ||||
|         int amount = 10; | ||||
|         long initialBalance = getBalance(inventoryRepository, productId); | ||||
|         try { | ||||
|             application.placeOrder(productId, amount); | ||||
|         } catch (Exception e) { | ||||
|             System.out.println(e.getMessage()); | ||||
|         } | ||||
|         long finalBalance = getBalance(inventoryRepository, productId); | ||||
|         assertEquals(initialBalance, finalBalance); | ||||
|     } | ||||
| 
 | ||||
|     @Before | ||||
|     public void setUp() throws SQLException { | ||||
| 
 | ||||
|         Inventory inventory = new Inventory(); | ||||
|         inventory.setProductId(productId); | ||||
|         inventory.setBalance(new Long(10000)); | ||||
|         inventoryRepository.save(inventory); | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     private static long getBalance(InventoryRepository inventoryRepository, String productId) throws Exception { | ||||
| 
 | ||||
|         return inventoryRepository.findOne(productId) | ||||
|             .getBalance(); | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -7,12 +7,6 @@ | ||||
|         </encoder> | ||||
|     </appender> | ||||
| 
 | ||||
|     <logger name="org.springframework" level="WARN" /> | ||||
|     <logger name="org.springframework.transaction" level="WARN" /> | ||||
| 
 | ||||
|     <!-- in order to debug some marshalling issues, this needs to be TRACE --> | ||||
|     <logger name="org.springframework.web.servlet.mvc" level="WARN" /> | ||||
| 
 | ||||
|     <root level="INFO"> | ||||
|         <appender-ref ref="STDOUT" /> | ||||
|     </root> | ||||
							
								
								
									
										1
									
								
								atomikos/src/test/resources/transactions.properties
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								atomikos/src/test/resources/transactions.properties
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1 @@ | ||||
| com.atomikos.icatch.file=logs | ||||
							
								
								
									
										56
									
								
								aws-app-sync/pom.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								aws-app-sync/pom.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,56 @@ | ||||
| <?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"> | ||||
|     <modelVersion>4.0.0</modelVersion> | ||||
|     <parent> | ||||
|         <groupId>org.springframework.boot</groupId> | ||||
|         <artifactId>spring-boot-starter-parent</artifactId> | ||||
|         <version>2.2.6.RELEASE</version> | ||||
|         <relativePath/> <!-- lookup parent from repository --> | ||||
|     </parent> | ||||
| 
 | ||||
|     <groupId>com.baeldung</groupId> | ||||
|     <artifactId>aws-app-sync</artifactId> | ||||
|     <version>0.0.1-SNAPSHOT</version> | ||||
|     <name>aws-app-sync</name> | ||||
| 
 | ||||
|     <description>Spring Boot using AWS App Sync</description> | ||||
| 
 | ||||
|     <properties> | ||||
|         <java.version>1.8</java.version> | ||||
|     </properties> | ||||
| 
 | ||||
|     <dependencies> | ||||
| 
 | ||||
|         <dependency> | ||||
|             <groupId>org.springframework.boot</groupId> | ||||
|             <artifactId>spring-boot-starter-web</artifactId> | ||||
|         </dependency> | ||||
| 
 | ||||
|         <dependency> | ||||
|             <groupId>org.springframework.boot</groupId> | ||||
|             <artifactId>spring-boot-starter-test</artifactId> | ||||
|             <scope>test</scope> | ||||
|             <exclusions> | ||||
|                 <exclusion> | ||||
|                     <groupId>org.junit.vintage</groupId> | ||||
|                     <artifactId>junit-vintage-engine</artifactId> | ||||
|                 </exclusion> | ||||
|             </exclusions> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.springframework.boot</groupId> | ||||
|             <artifactId>spring-boot-starter-webflux</artifactId> | ||||
|         </dependency> | ||||
|     </dependencies> | ||||
| 
 | ||||
|     <build> | ||||
|         <plugins> | ||||
|             <plugin> | ||||
|                 <groupId>org.springframework.boot</groupId> | ||||
|                 <artifactId>spring-boot-maven-plugin</artifactId> | ||||
|             </plugin> | ||||
|         </plugins> | ||||
|     </build> | ||||
| 
 | ||||
| </project> | ||||
| @ -0,0 +1,32 @@ | ||||
| package com.baeldung.awsappsync; | ||||
| 
 | ||||
| import org.springframework.http.HttpMethod; | ||||
| import org.springframework.http.MediaType; | ||||
| import org.springframework.web.reactive.function.BodyInserters; | ||||
| import org.springframework.web.reactive.function.client.WebClient; | ||||
| 
 | ||||
| import java.nio.charset.StandardCharsets; | ||||
| import java.util.Map; | ||||
| 
 | ||||
| public class AppSyncClientHelper { | ||||
| 
 | ||||
|     static String apiUrl = "https://m4i3b6icrrb7livfbypfspiifi.appsync-api.us-east-2.amazonaws.com"; | ||||
|     static String apiKey = "da2-bm4rpatkkrc5jfyhvvq7itjeke"; | ||||
|     static String API_KEY_HEADER = "x-api-key"; | ||||
| 
 | ||||
|     public static WebClient.ResponseSpec getResponseBodySpec(Map<String, Object> requestBody) { | ||||
|         return WebClient | ||||
|                 .builder() | ||||
|                 .baseUrl(apiUrl) | ||||
|                 .defaultHeader(API_KEY_HEADER, apiKey) | ||||
|                 .defaultHeader("Content-Type", "application/json") | ||||
|                 .build() | ||||
|                 .method(HttpMethod.POST) | ||||
|                 .uri("/graphql") | ||||
|                 .body(BodyInserters.fromValue(requestBody)) | ||||
|                 .accept(MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML) | ||||
|                 .acceptCharset(StandardCharsets.UTF_8) | ||||
|                 .retrieve(); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,13 @@ | ||||
| package com.baeldung.awsappsync; | ||||
| 
 | ||||
| import org.springframework.boot.SpringApplication; | ||||
| import org.springframework.boot.autoconfigure.SpringBootApplication; | ||||
| 
 | ||||
| @SpringBootApplication | ||||
| public class AwsAppSyncApplication { | ||||
| 
 | ||||
|     public static void main(String[] args) { | ||||
|         SpringApplication.run(AwsAppSyncApplication.class, args); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,72 @@ | ||||
| package com.baeldung.awsappsync; | ||||
| 
 | ||||
| import org.junit.jupiter.api.Test; | ||||
| import org.springframework.boot.test.context.SpringBootTest; | ||||
| import org.springframework.web.reactive.function.client.WebClient; | ||||
| 
 | ||||
| import java.util.HashMap; | ||||
| import java.util.Map; | ||||
| 
 | ||||
| import static org.junit.jupiter.api.Assertions.*; | ||||
| 
 | ||||
| @SpringBootTest | ||||
| class AwsAppSyncApplicationTests { | ||||
| 
 | ||||
|     @Test | ||||
|     void givenGraphQuery_whenListEvents_thenReturnAllEvents() { | ||||
| 
 | ||||
|         Map<String, Object> requestBody = new HashMap<>(); | ||||
|         requestBody.put("query", "query ListEvents {" | ||||
|                 + "  listEvents {" | ||||
|                 + "    items {" | ||||
|                 + "      id" | ||||
|                 + "      name" | ||||
|                 + "      where" | ||||
|                 + "      when" | ||||
|                 + "      description" | ||||
|                 + "    }" | ||||
|                 + "  }" | ||||
|                 + "}"); | ||||
|         requestBody.put("variables", ""); | ||||
|         requestBody.put("operationName", "ListEvents"); | ||||
| 
 | ||||
|         String bodyString = AppSyncClientHelper.getResponseBodySpec(requestBody) | ||||
|                 .bodyToMono(String.class).block(); | ||||
| 
 | ||||
|         assertNotNull(bodyString); | ||||
|         assertTrue(bodyString.contains("My First Event")); | ||||
|         assertTrue(bodyString.contains("where")); | ||||
|         assertTrue(bodyString.contains("when")); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     void givenGraphAdd_whenMutation_thenReturnIdNameDesc() { | ||||
| 
 | ||||
|         String queryString = "mutation add {" | ||||
|                 + "    createEvent(" | ||||
|                 + "        name:\"My added GraphQL event\"" | ||||
|                 + "        where:\"Day 2\"" | ||||
|                 + "        when:\"Saturday night\"" | ||||
|                 + "        description:\"Studying GraphQL\"" | ||||
|                 + "    ){" | ||||
|                 + "        id" | ||||
|                 + "        name" | ||||
|                 + "        description" | ||||
|                 + "    }" | ||||
|                 + "}"; | ||||
| 
 | ||||
|         Map<String, Object> requestBody = new HashMap<>(); | ||||
|         requestBody.put("query", queryString); | ||||
|         requestBody.put("variables", ""); | ||||
|         requestBody.put("operationName", "add"); | ||||
| 
 | ||||
|         WebClient.ResponseSpec response = AppSyncClientHelper.getResponseBodySpec(requestBody); | ||||
| 
 | ||||
|         String bodyString = response.bodyToMono(String.class).block(); | ||||
| 
 | ||||
|         assertNotNull(bodyString); | ||||
|         assertTrue(bodyString.contains("My added GraphQL event")); | ||||
|         assertFalse(bodyString.contains("where")); | ||||
|         assertFalse(bodyString.contains("when")); | ||||
|     } | ||||
| } | ||||
| @ -1,3 +0,0 @@ | ||||
| ### Relevant Articles: | ||||
| 
 | ||||
| - [Building Java Applications with Bazel](https://www.baeldung.com/bazel-build-tool) | ||||
| @ -1,7 +1,18 @@ | ||||
| ## CAS | ||||
| 
 | ||||
| This module contains articles about the Central Authentication Service (CAS) | ||||
| This module contains articles about the Central Authentication Service (CAS). | ||||
| 
 | ||||
| The module consists of 2 submodules: | ||||
| 1. `cas-server` - it requires JDK11 and uses the Gradle War Overlay style to ease setup and deployment. To  start the server, simply run: | ||||
| 
 | ||||
| `./gradlew run | ||||
|   -Dorg.gradle.java.home=$JAVA11_HOME | ||||
|   -Pargs="-Dcas.standalone.configurationDirectory=/cas-server/src/main/resources/etc/cas/config"` | ||||
| 
 | ||||
| The server starts at https://localhost:8443. `casuser`/`Mellon` are the username and password for logging in. | ||||
| 
 | ||||
| 2. `cas-secured-app` - A Maven based Springboot Application | ||||
| 
 | ||||
| ### Relevant Articles:  | ||||
| 
 | ||||
| - [CAS SSO With Spring Security](baeldung.com/spring-security-cas-sso) | ||||
| - [CAS SSO With Spring Security](https://www.baeldung.com/spring-security-cas-sso) | ||||
| @ -1,146 +0,0 @@ | ||||
| CAS Overlay Template [](https://travis-ci.org/apereo/cas-overlay-template) | ||||
| ======================= | ||||
| 
 | ||||
| Generic CAS WAR overlay to exercise the latest versions of CAS. This overlay could be freely used as a starting template for local CAS war overlays. | ||||
| 
 | ||||
| # Versions | ||||
| 
 | ||||
| - CAS `6.1.x` | ||||
| - JDK `11` | ||||
| 
 | ||||
| # Overview | ||||
| 
 | ||||
| To build the project, use: | ||||
| 
 | ||||
| ```bash | ||||
| # Use --refresh-dependencies to force-update SNAPSHOT versions | ||||
| ./gradlew[.bat] clean build | ||||
| ``` | ||||
| 
 | ||||
| To see what commands are available to the build script, run: | ||||
| 
 | ||||
| ```bash | ||||
| ./gradlew[.bat] tasks | ||||
| ``` | ||||
| 
 | ||||
| To launch into the CAS command-line shell: | ||||
| 
 | ||||
| ```bash | ||||
| ./gradlew[.bat] downloadShell runShell | ||||
| ``` | ||||
| 
 | ||||
| To fetch and overlay a CAS resource or view, use: | ||||
| 
 | ||||
| ```bash | ||||
| ./gradlew[.bat] getResource -PresourceName=[resource-name] | ||||
| ``` | ||||
| 
 | ||||
| To list all available CAS views and templates: | ||||
| 
 | ||||
| ```bash | ||||
| ./gradlew[.bat] listTemplateViews | ||||
| ``` | ||||
| 
 | ||||
| To unzip and explode the CAS web application file and the internal resources jar: | ||||
| 
 | ||||
| ```bash | ||||
| ./gradlew[.bat] explodeWar | ||||
| ``` | ||||
| 
 | ||||
| # Configuration | ||||
| 
 | ||||
| - The `etc` directory contains the configuration files and directories that need to be copied to `/etc/cas/config`. | ||||
| 
 | ||||
| ```bash | ||||
| ./gradlew[.bat] copyCasConfiguration | ||||
| ``` | ||||
| 
 | ||||
| - The specifics of the build are controlled using the `gradle.properties` file. | ||||
| 
 | ||||
| ## Adding Modules | ||||
| 
 | ||||
| CAS modules may be specified under the `dependencies` block of the [Gradle build script](build.gradle): | ||||
| 
 | ||||
| ```gradle | ||||
| dependencies { | ||||
|     compile "org.apereo.cas:cas-server-some-module:${project.casVersion}" | ||||
|     ... | ||||
| } | ||||
| ``` | ||||
| 
 | ||||
| To collect the list of all project modules and dependencies: | ||||
| 
 | ||||
| ```bash | ||||
| ./gradlew[.bat] allDependencies | ||||
| ``` | ||||
| 
 | ||||
| ### Clear Gradle Cache | ||||
| 
 | ||||
| If you need to, on Linux/Unix systems, you can delete all the existing artifacts (artifacts and metadata) Gradle has downloaded using: | ||||
| 
 | ||||
| ```bash | ||||
| # Only do this when absolutely necessary | ||||
| rm -rf $HOME/.gradle/caches/ | ||||
| ``` | ||||
| 
 | ||||
| Same strategy applies to Windows too, provided you switch `$HOME` to its equivalent in the above command. | ||||
| 
 | ||||
| # Deployment | ||||
| 
 | ||||
| - Create a keystore file `thekeystore` under `/etc/cas`. Use the password `changeit` for both the keystore and the key/certificate entries. This can either be done using the JDK's `keytool` utility or via the following command: | ||||
| 
 | ||||
| ```bash | ||||
| ./gradlew[.bat] createKeystore | ||||
| ``` | ||||
| 
 | ||||
| - Ensure the keystore is loaded up with keys and certificates of the server. | ||||
| 
 | ||||
| On a successful deployment via the following methods, CAS will be available at: | ||||
| 
 | ||||
| * `https://cas.server.name:8443/cas` | ||||
| 
 | ||||
| ## Executable WAR | ||||
| 
 | ||||
| Run the CAS web application as an executable WAR: | ||||
| 
 | ||||
| ```bash | ||||
| ./gradlew[.bat] run | ||||
| ``` | ||||
| 
 | ||||
| Debug the CAS web application as an executable WAR: | ||||
| 
 | ||||
| ```bash | ||||
| ./gradlew[.bat] debug | ||||
| ``` | ||||
| 
 | ||||
| Run the CAS web application as a *standalone* executable WAR: | ||||
| 
 | ||||
| ```bash | ||||
| ./gradlew[.bat] clean executable | ||||
| ``` | ||||
| 
 | ||||
| ## External | ||||
| 
 | ||||
| Deploy the binary web application file `cas.war` after a successful build to a servlet container of choice. | ||||
| 
 | ||||
| ## Docker | ||||
| 
 | ||||
| The following strategies outline how to build and deploy CAS Docker images. | ||||
| 
 | ||||
| ### Jib | ||||
| 
 | ||||
| The overlay embraces the [Jib Gradle Plugin](https://github.com/GoogleContainerTools/jib) to provide easy-to-use out-of-the-box tooling for building CAS docker images. Jib is an open-source Java containerizer from Google that lets Java developers build containers using the tools they know. It is a container image builder that handles all the steps of packaging your application into a container image. It does not require you to write a Dockerfile or have Docker installed, and it is directly integrated into the overlay. | ||||
| 
 | ||||
| ```bash | ||||
| ./gradlew build jibDockerBuild | ||||
| ``` | ||||
| 
 | ||||
| ### Dockerfile | ||||
| 
 | ||||
| You can also use the native Docker tooling and the provided `Dockerfile` to build and run CAS. | ||||
| 
 | ||||
| ```bash | ||||
| chmod +x *.sh | ||||
| ./docker-build.sh | ||||
| ./docker-run.sh | ||||
| ``` | ||||
							
								
								
									
										40
									
								
								core-groovy-2/determine-datatype/pom.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								core-groovy-2/determine-datatype/pom.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,40 @@ | ||||
| <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> | ||||
|     <groupId>com.baeldung.groovy</groupId> | ||||
|     <artifactId>determine-datatype</artifactId> | ||||
|     <version>0.0.1-SNAPSHOT</version> | ||||
|     <build> | ||||
|         <sourceDirectory>src</sourceDirectory> | ||||
|         <plugins> | ||||
|             <plugin> | ||||
|                 <artifactId>maven-compiler-plugin</artifactId> | ||||
|                 <version>3.8.0</version> | ||||
|                 <configuration> | ||||
|                     <source>1.8</source> | ||||
|                     <target>1.8</target> | ||||
|                 </configuration> | ||||
|             </plugin> | ||||
|             <plugin> | ||||
|                 <groupId>org.codehaus.gmaven</groupId> | ||||
|                 <artifactId>groovy-maven-plugin</artifactId> | ||||
|                 <dependencies> | ||||
|                     <dependency> | ||||
|                         <groupId>org.codehaus.groovy</groupId> | ||||
|                         <artifactId>groovy-all</artifactId> | ||||
|                         <version>2.0.6</version> | ||||
|                     </dependency> | ||||
|                 </dependencies> | ||||
|             </plugin> | ||||
|         </plugins> | ||||
|     </build> | ||||
|     <dependencies> | ||||
|         <!-- https://mvnrepository.com/artifact/org.junit/junit5-engine --> | ||||
|         <dependency> | ||||
|             <groupId>org.junit</groupId> | ||||
|             <artifactId>junit5-engine</artifactId> | ||||
|             <version>5.0.0-ALPHA</version> | ||||
|         </dependency> | ||||
|     </dependencies> | ||||
| </project> | ||||
| @ -0,0 +1,14 @@ | ||||
| package com.baeldung.groovy.determine.datatype | ||||
| 
 | ||||
| class Person { | ||||
|      | ||||
|     private int ageAsInt | ||||
|     private Double ageAsDouble | ||||
|     private String ageAsString | ||||
|      | ||||
|     Person() {} | ||||
|     Person(int ageAsInt) { this.ageAsInt =  ageAsInt} | ||||
|     Person(Double ageAsDouble) { this.ageAsDouble =  ageAsDouble} | ||||
|     Person(String ageAsString) { this.ageAsString =  ageAsString}     | ||||
| } | ||||
| class Student extends Person {} | ||||
| @ -0,0 +1,55 @@ | ||||
| package com.baeldung.groovy.determine.datatype; | ||||
| 
 | ||||
| import org.junit.Assert | ||||
| import org.junit.Test; | ||||
| 
 | ||||
| public class PersonTest { | ||||
|      | ||||
|     @Test | ||||
|     public void givenWhenParameterTypeIsInteger_thenReturnTrue() { | ||||
|         Person personObj = new Person(10) | ||||
|         Assert.assertTrue(personObj.ageAsInt instanceof Integer); | ||||
|     } | ||||
|      | ||||
|     @Test | ||||
|     public void givenWhenParameterTypeIsDouble_thenReturnTrue() { | ||||
|         Person personObj = new Person(10.0) | ||||
|         Assert.assertTrue((personObj.ageAsDouble).getClass() == Double) | ||||
|     } | ||||
|      | ||||
|     @Test | ||||
|     public void givenWhenParameterTypeIsString_thenReturnTrue() { | ||||
|         Person personObj = new Person("10 years") | ||||
|         Assert.assertTrue(personObj.ageAsString.class == String) | ||||
|     } | ||||
|      | ||||
|     @Test | ||||
|     public void givenClassName_WhenParameterIsInteger_thenReturnTrue() { | ||||
|         Assert.assertTrue(Person.class.getDeclaredField('ageAsInt').type == int.class) | ||||
|     } | ||||
|      | ||||
|     @Test | ||||
|     public void givenWhenObjectIsInstanceOfType_thenReturnTrue() { | ||||
|         Person personObj = new Person() | ||||
|         Assert.assertTrue(personObj instanceof Person) | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenWhenInstanceIsOfSubtype_thenReturnTrue() { | ||||
|         Student studentObj = new Student() | ||||
|         Assert.assertTrue(studentObj in Person) | ||||
|     } | ||||
|      | ||||
|     @Test | ||||
|     public void givenGroovyList_WhenFindClassName_thenReturnTrue() { | ||||
|       def ageList = ['ageAsString','ageAsDouble', 10]    | ||||
|       Assert.assertTrue(ageList.class == ArrayList)      | ||||
|       Assert.assertTrue(ageList.getClass() == ArrayList) | ||||
|     } | ||||
|      | ||||
|     @Test | ||||
|     public void givenGrooyMap_WhenFindClassName_thenReturnTrue() { | ||||
|       def ageMap = [ageAsString: '10 years', ageAsDouble: 10.0] | ||||
|       Assert.assertFalse(ageMap.class == LinkedHashMap) | ||||
|     } | ||||
| } | ||||
| @ -12,4 +12,5 @@ This module contains articles about core Groovy concepts | ||||
| - [Closures in Groovy](https://www.baeldung.com/groovy-closures) | ||||
| - [Converting a String to a Date in Groovy](https://www.baeldung.com/groovy-string-to-date) | ||||
| - [Guide to I/O in Groovy](https://www.baeldung.com/groovy-io) | ||||
| - [Convert String to Integer in Groovy](https://www.baeldung.com/groovy-convert-string-to-integer) | ||||
| - [[More -->]](/core-groovy-2) | ||||
| @ -0,0 +1,110 @@ | ||||
| package com.baeldung.stringtoint | ||||
| 
 | ||||
| import org.junit.Test | ||||
| 
 | ||||
| import java.text.DecimalFormat | ||||
| 
 | ||||
| import static org.junit.Assert.assertEquals | ||||
| import static org.junit.Assert.assertNull | ||||
| 
 | ||||
| class ConvertStringToInt { | ||||
| 
 | ||||
|     @Test | ||||
|     void givenString_whenUsingAsInteger_thenConvertToInteger() { | ||||
|         def stringNum = "123" | ||||
|         def invalidString = "123a" | ||||
|         Integer expectedInteger = 123 | ||||
|         Integer integerNum = stringNum as Integer | ||||
|         def intNum = invalidString?.isInteger() ? invalidString as Integer : null | ||||
| 
 | ||||
|         assertNull(null, intNum) | ||||
|         assertEquals(integerNum, expectedInteger) | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     void givenString_whenUsingAsInt_thenConvertToInt() { | ||||
|         def stringNum = "123" | ||||
|         int expectedInt = 123 | ||||
|         int intNum = stringNum as int | ||||
| 
 | ||||
|         assertEquals(intNum, expectedInt) | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     void givenString_whenUsingToInteger_thenConvertToInteger() { | ||||
|         def stringNum = "123" | ||||
|         int expectedInt = 123 | ||||
|         int intNum = stringNum.toInteger() | ||||
| 
 | ||||
|         assertEquals(intNum, expectedInt) | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     void givenString_whenUsingParseInt_thenConvertToInteger() { | ||||
|         def stringNum = "123" | ||||
|         int expectedInt = 123 | ||||
|         int intNum = Integer.parseInt(stringNum) | ||||
| 
 | ||||
|         assertEquals(intNum, expectedInt) | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     void givenString_whenUsingValueOf_thenConvertToInteger() { | ||||
|         def stringNum = "123" | ||||
|         int expectedInt = 123 | ||||
|         int intNum = Integer.valueOf(stringNum) | ||||
| 
 | ||||
|         assertEquals(intNum, expectedInt) | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     void givenString_whenUsingIntValue_thenConvertToInteger() { | ||||
|         def stringNum = "123" | ||||
|         int expectedInt = 123 | ||||
|         int intNum = new Integer(stringNum).intValue() | ||||
| 
 | ||||
|         assertEquals(intNum, expectedInt) | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     void givenString_whenUsingNewInteger_thenConvertToInteger() { | ||||
|         def stringNum = "123" | ||||
|         int expectedInt = 123 | ||||
|         int intNum = new Integer(stringNum) | ||||
| 
 | ||||
|         assertEquals(intNum, expectedInt) | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     void givenString_whenUsingDecimalFormat_thenConvertToInteger() { | ||||
|         def stringNum = "123" | ||||
|         int expectedInt = 123 | ||||
|         DecimalFormat decimalFormat = new DecimalFormat("#") | ||||
|         int intNum = decimalFormat.parse(stringNum).intValue() | ||||
| 
 | ||||
|         assertEquals(intNum, expectedInt) | ||||
|     } | ||||
| 
 | ||||
|     @Test(expected = NumberFormatException.class) | ||||
|     void givenInvalidString_whenUsingAs_thenThrowNumberFormatException() { | ||||
|         def invalidString = "123a" | ||||
|         invalidString as Integer | ||||
|     } | ||||
| 
 | ||||
|     @Test(expected = NullPointerException.class) | ||||
|     void givenNullString_whenUsingToInteger_thenThrowNullPointerException() { | ||||
|         def invalidString = null | ||||
|         invalidString.toInteger() | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     void givenString_whenUsingIsInteger_thenCheckIfCorrectValue() { | ||||
|         def invalidString = "123a" | ||||
|         def validString = "123" | ||||
|         def invalidNum = invalidString?.isInteger() ? invalidString as Integer : false | ||||
|         def correctNum = validString?.isInteger() ? validString as Integer : false | ||||
| 
 | ||||
|         assertEquals(false, invalidNum) | ||||
|         assertEquals(123, correctNum) | ||||
|     } | ||||
| } | ||||
| @ -7,3 +7,4 @@ This module contains articles about Java 14. | ||||
| - [Guide to the @Serial Annotation in Java 14](https://www.baeldung.com/java-14-serial-annotation) | ||||
| - [Java Text Blocks](https://www.baeldung.com/java-text-blocks) | ||||
| - [Pattern Matching for instanceof in Java 14](https://www.baeldung.com/java-pattern-matching-instanceof) | ||||
| - [Helpful NullPointerExceptions in Java 14](https://www.baeldung.com/java-14-nullpointerexception) | ||||
|  | ||||
| @ -0,0 +1,56 @@ | ||||
| package com.baeldung.java14.npe; | ||||
| 
 | ||||
| public class HelpfulNullPointerException { | ||||
| 
 | ||||
|     public static void main(String[] args) { | ||||
|         Employee employee = null; | ||||
|         employee.getName(); | ||||
|     } | ||||
| 
 | ||||
|     public String getEmployeeEmailAddress(Employee employee) { | ||||
|         String emailAddress = employee.getPersonalDetails().getEmailAddress().toLowerCase(); | ||||
|         return emailAddress; | ||||
|     } | ||||
| 
 | ||||
|     static class Employee { | ||||
|         String name; | ||||
|         PersonalDetails personalDetails; | ||||
| 
 | ||||
|         public String getName() { | ||||
|             return name; | ||||
|         } | ||||
| 
 | ||||
|         public void setName(String name) { | ||||
|             this.name = name; | ||||
|         } | ||||
| 
 | ||||
|         public PersonalDetails getPersonalDetails() { | ||||
|             return personalDetails; | ||||
|         } | ||||
| 
 | ||||
|         public void setPersonalDetails(PersonalDetails personalDetails) { | ||||
|             this.personalDetails = personalDetails; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     static class PersonalDetails { | ||||
|         String emailAddress; | ||||
|         String phone; | ||||
| 
 | ||||
|         public String getEmailAddress() { | ||||
|             return emailAddress; | ||||
|         } | ||||
| 
 | ||||
|         public void setEmailAddress(String emailAddress) { | ||||
|             this.emailAddress = emailAddress; | ||||
|         } | ||||
| 
 | ||||
|         public String getPhone() { | ||||
|             return phone; | ||||
|         } | ||||
| 
 | ||||
|         public void setPhone(String phone) { | ||||
|             this.phone = phone; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,22 @@ | ||||
| package com.baeldung.java14.record; | ||||
| 
 | ||||
| import java.util.Objects; | ||||
| 
 | ||||
| public record Person (String name, String address) { | ||||
| 	 | ||||
| 	public static String UNKWOWN_ADDRESS = "Unknown"; | ||||
| 	public static String UNNAMED = "Unnamed"; | ||||
| 
 | ||||
| 	public Person { | ||||
| 		Objects.requireNonNull(name); | ||||
| 		Objects.requireNonNull(address); | ||||
| 	} | ||||
| 	 | ||||
| 	public Person(String name) { | ||||
| 		this(name, UNKWOWN_ADDRESS); | ||||
| 	} | ||||
| 	 | ||||
| 	public static Person unnamed(String address) { | ||||
| 		return new Person(UNNAMED, address); | ||||
| 	} | ||||
| } | ||||
| @ -0,0 +1,84 @@ | ||||
| package com.baeldung.java14.foreign.api; | ||||
| 
 | ||||
| import jdk.incubator.foreign.*; | ||||
| import org.junit.Test; | ||||
| 
 | ||||
| import static org.hamcrest.core.Is.is; | ||||
| import static org.junit.Assert.assertThat; | ||||
| 
 | ||||
| import java.lang.invoke.VarHandle; | ||||
| import java.nio.ByteOrder; | ||||
| 
 | ||||
| public class ForeignMemoryUnitTest { | ||||
| 
 | ||||
|     @Test | ||||
|     public void whenAValueIsSet_thenAccessTheValue() { | ||||
|         long value = 10; | ||||
|         MemoryAddress memoryAddress = | ||||
|           MemorySegment.allocateNative(8).baseAddress(); | ||||
|         VarHandle varHandle = MemoryHandles.varHandle(long.class, | ||||
|           ByteOrder.nativeOrder()); | ||||
|         varHandle.set(memoryAddress, value); | ||||
|         assertThat(varHandle.get(memoryAddress), is(value)); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void whenMultipleValuesAreSet_thenAccessAll() { | ||||
|         VarHandle varHandle = MemoryHandles.varHandle(int.class, | ||||
|           ByteOrder.nativeOrder()); | ||||
| 
 | ||||
|         try(MemorySegment memorySegment = | ||||
|           MemorySegment.allocateNative(100)) { | ||||
|             MemoryAddress base = memorySegment.baseAddress(); | ||||
|             for(int i=0; i<25; i++) { | ||||
|                 varHandle.set(base.addOffset((i*4)), i); | ||||
|             } | ||||
|             for(int i=0; i<25; i++) { | ||||
|                 assertThat(varHandle.get(base.addOffset((i*4))), is(i)); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void whenSetValuesWithMemoryLayout_thenTheyCanBeRetrieved() { | ||||
|         SequenceLayout sequenceLayout = | ||||
|           MemoryLayout.ofSequence(25, | ||||
|             MemoryLayout.ofValueBits(64, ByteOrder.nativeOrder())); | ||||
|         VarHandle varHandle = | ||||
|           sequenceLayout.varHandle(long.class, | ||||
|             MemoryLayout.PathElement.sequenceElement()); | ||||
| 
 | ||||
|         try(MemorySegment memorySegment = | ||||
|           MemorySegment.allocateNative(sequenceLayout)) { | ||||
|             MemoryAddress base = memorySegment.baseAddress(); | ||||
|             for(long i=0; i<sequenceLayout.elementCount().getAsLong(); i++) { | ||||
|                 varHandle.set(base, i, i); | ||||
|             } | ||||
|             for(long i=0; i<sequenceLayout.elementCount().getAsLong(); i++) { | ||||
|                 assertThat(varHandle.get(base, i), is(i)); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void whenSlicingMemorySegment_thenTheyCanBeAccessedIndividually() { | ||||
|         MemoryAddress memoryAddress = | ||||
|           MemorySegment.allocateNative(12).baseAddress(); | ||||
|         MemoryAddress memoryAddress1 = | ||||
|           memoryAddress.segment().asSlice(0,4).baseAddress(); | ||||
|         MemoryAddress memoryAddress2 = | ||||
|           memoryAddress.segment().asSlice(4,4).baseAddress(); | ||||
|         MemoryAddress memoryAddress3 = | ||||
|           memoryAddress.segment().asSlice(8,4).baseAddress(); | ||||
| 
 | ||||
|         VarHandle intHandle = | ||||
|           MemoryHandles.varHandle(int.class, ByteOrder.nativeOrder()); | ||||
|         intHandle.set(memoryAddress1, Integer.MIN_VALUE); | ||||
|         intHandle.set(memoryAddress2, 0); | ||||
|         intHandle.set(memoryAddress3, Integer.MAX_VALUE); | ||||
| 
 | ||||
|         assertThat(intHandle.get(memoryAddress1), is(Integer.MIN_VALUE)); | ||||
|         assertThat(intHandle.get(memoryAddress2), is(0)); | ||||
|         assertThat(intHandle.get(memoryAddress3), is(Integer.MAX_VALUE)); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,37 @@ | ||||
| package com.baeldung.java14.npe; | ||||
| 
 | ||||
| import org.junit.Test; | ||||
| 
 | ||||
| import static com.baeldung.java14.helpfulnullpointerexceptions.HelpfulNullPointerException.Employee; | ||||
| import static com.baeldung.java14.helpfulnullpointerexceptions.HelpfulNullPointerException.PersonalDetails; | ||||
| import static org.assertj.core.api.Assertions.assertThat; | ||||
| 
 | ||||
| public class HelpfulNullPointerExceptionUnitTest { | ||||
| 
 | ||||
|     @Test (expected = NullPointerException.class) | ||||
|     public void givenAnEmptyPersonalDetails_whenEmailAddressIsAccessed_thenThrowNPE() { | ||||
|         var helpfulNPE = new HelpfulNullPointerException(); | ||||
| 
 | ||||
|         var employee = new Employee(); | ||||
|         employee.setName("Eduard"); | ||||
|         employee.setPersonalDetails(new PersonalDetails()); | ||||
|         helpfulNPE.getEmployeeEmailAddress(employee); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenCompletePersonalDetails_whenEmailAddressIsAccessed_thenSuccess() { | ||||
|         var helpfulNPE = new HelpfulNullPointerException(); | ||||
|         var emailAddress = "eduard@gmx.com"; | ||||
| 
 | ||||
|         var employee = new Employee(); | ||||
|         employee.setName("Eduard"); | ||||
| 
 | ||||
|         var personalDetails = new PersonalDetails(); | ||||
|         personalDetails.setEmailAddress(emailAddress.toUpperCase()); | ||||
|         personalDetails.setPhone("1234"); | ||||
|         employee.setPersonalDetails(personalDetails); | ||||
| 
 | ||||
|         assertThat(helpfulNPE.getEmployeeEmailAddress(employee)).isEqualTo(emailAddress); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,150 @@ | ||||
| package com.baeldung.java14.record; | ||||
| 
 | ||||
| import static org.junit.Assert.assertEquals; | ||||
| import static org.junit.Assert.assertFalse; | ||||
| import static org.junit.Assert.assertNotEquals; | ||||
| import static org.junit.Assert.assertTrue; | ||||
| 
 | ||||
| import org.junit.Test; | ||||
| 
 | ||||
| public class PersonTest { | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenSameNameAndAddress_whenEquals_thenPersonsEqual() { | ||||
| 
 | ||||
|         String name = "John Doe"; | ||||
|         String address = "100 Linda Ln."; | ||||
| 
 | ||||
|         Person person1 = new Person(name, address); | ||||
|         Person person2 = new Person(name, address); | ||||
| 
 | ||||
|         assertTrue(person1.equals(person2)); | ||||
|     } | ||||
|      | ||||
|     @Test | ||||
|     public void givenDifferentObject_whenEquals_thenNotEqual() { | ||||
| 
 | ||||
|         Person person = new Person("John Doe", "100 Linda Ln."); | ||||
| 
 | ||||
|         assertFalse(person.equals(new Object())); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenDifferentName_whenEquals_thenPersonsNotEqual() { | ||||
|      | ||||
|         String address = "100 Linda Ln."; | ||||
|      | ||||
|         Person person1 = new Person("Jane Doe", address); | ||||
|         Person person2 = new Person("John Doe", address); | ||||
|      | ||||
|         assertFalse(person1.equals(person2)); | ||||
|     } | ||||
|      | ||||
|     @Test | ||||
|     public void givenDifferentAddress_whenEquals_thenPersonsNotEqual() { | ||||
|      | ||||
|         String name = "John Doe"; | ||||
|      | ||||
|         Person person1 = new Person(name, "100 Linda Ln."); | ||||
|         Person person2 = new Person(name, "200 London Ave."); | ||||
|      | ||||
|         assertFalse(person1.equals(person2)); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenSameNameAndAddress_whenHashCode_thenPersonsEqual() { | ||||
| 
 | ||||
|         String name = "John Doe"; | ||||
|         String address = "100 Linda Ln."; | ||||
| 
 | ||||
|         Person person1 = new Person(name, address); | ||||
|         Person person2 = new Person(name, address); | ||||
| 
 | ||||
|         assertEquals(person1.hashCode(), person2.hashCode()); | ||||
|     } | ||||
|      | ||||
|     @Test | ||||
|     public void givenDifferentObject_whenHashCode_thenNotEqual() { | ||||
| 
 | ||||
|         Person person = new Person("John Doe", "100 Linda Ln."); | ||||
| 
 | ||||
|         assertNotEquals(person.hashCode(), new Object().hashCode()); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenDifferentName_whenHashCode_thenPersonsNotEqual() { | ||||
| 
 | ||||
|         String address = "100 Linda Ln."; | ||||
| 
 | ||||
|         Person person1 = new Person("Jane Doe", address); | ||||
|         Person person2 = new Person("John Doe", address); | ||||
| 
 | ||||
|         assertNotEquals(person1.hashCode(), person2.hashCode()); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenDifferentAddress_whenHashCode_thenPersonsNotEqual() { | ||||
| 
 | ||||
|         String name = "John Doe"; | ||||
| 
 | ||||
|         Person person1 = new Person(name, "100 Linda Ln."); | ||||
|         Person person2 = new Person(name, "200 London Ave."); | ||||
| 
 | ||||
|         assertNotEquals(person1.hashCode(), person2.hashCode()); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenValidNameAndAddress_whenGetNameAndAddress_thenExpectedValuesReturned() { | ||||
| 
 | ||||
|         String name = "John Doe"; | ||||
|         String address = "100 Linda Ln."; | ||||
| 
 | ||||
|         Person person = new Person(name, address); | ||||
| 
 | ||||
|         assertEquals(name, person.name()); | ||||
|         assertEquals(address, person.address()); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenValidNameAndAddress_whenToString_thenCorrectStringReturned() { | ||||
| 
 | ||||
|         String name = "John Doe"; | ||||
|         String address = "100 Linda Ln."; | ||||
| 
 | ||||
|         Person person = new Person(name, address); | ||||
| 
 | ||||
|         assertEquals("Person[name=" + name + ", address=" + address + "]", person.toString()); | ||||
|     } | ||||
| 
 | ||||
|     @Test(expected = NullPointerException.class) | ||||
|     public void givenNullName_whenConstruct_thenErrorThrown() { | ||||
|         new Person(null, "100 Linda Ln."); | ||||
|     } | ||||
| 
 | ||||
|     @Test(expected = NullPointerException.class) | ||||
|     public void givenNullAddress_whenConstruct_thenErrorThrown() { | ||||
|         new Person("John Doe", null); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenUnknownAddress_whenConstructing_thenAddressPopulated() { | ||||
| 
 | ||||
|         String name = "John Doe"; | ||||
| 
 | ||||
|         Person person = new Person(name); | ||||
| 
 | ||||
|         assertEquals(name, person.name()); | ||||
|         assertEquals(Person.UNKWOWN_ADDRESS, person.address()); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenUnnamed_whenConstructingThroughFactory_thenNamePopulated() { | ||||
| 
 | ||||
|         String address = "100 Linda Ln."; | ||||
| 
 | ||||
|         Person person = Person.unnamed(address); | ||||
| 
 | ||||
|         assertEquals(Person.UNNAMED, person.name()); | ||||
|         assertEquals(address, person.address()); | ||||
|     } | ||||
| } | ||||
| @ -4,7 +4,6 @@ This module contains articles about Java 8 core features | ||||
| 
 | ||||
| ### Relevant Articles:  | ||||
| 
 | ||||
| - [How to Delay Code Execution in Java](https://www.baeldung.com/java-delay-code-execution) | ||||
| - [Run a Java Application from the Command Line](https://www.baeldung.com/java-run-jar-with-arguments) | ||||
| - [Java 8 Stream skip() vs limit()](https://www.baeldung.com/java-stream-skip-vs-limit) | ||||
| - [Guide to Java BiFunction Interface](https://www.baeldung.com/java-bifunction-interface) | ||||
|  | ||||
							
								
								
									
										5
									
								
								core-java-modules/core-java-8-datetime-2/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								core-java-modules/core-java-8-datetime-2/README.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,5 @@ | ||||
| ### Relevant Articles: | ||||
| 
 | ||||
| - [Generating Random Dates in Java](https://www.baeldung.com/java-random-dates) | ||||
| - [Creating a LocalDate with Values in Java](https://www.baeldung.com/java-creating-localdate-with-values) | ||||
| - [[<-- Prev]](/core-java-modules/core-java-datetime-java8-1) | ||||
| @ -4,9 +4,9 @@ | ||||
|     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-datetime-java8</artifactId> | ||||
|     <artifactId>core-java-8-datetime</artifactId> | ||||
|     <version>${project.parent.version}</version> | ||||
|     <name>core-java-datetime-java8</name> | ||||
|     <name>core-java-8-datetime</name> | ||||
|     <packaging>jar</packaging> | ||||
| 
 | ||||
|     <parent> | ||||
| @ -64,8 +64,8 @@ | ||||
|     </build> | ||||
| 
 | ||||
|     <properties> | ||||
|         <maven.compiler.source>1.9</maven.compiler.source> | ||||
|         <maven.compiler.target>1.9</maven.compiler.target> | ||||
|         <maven.compiler.source>1.8</maven.compiler.source> | ||||
|         <maven.compiler.target>1.8</maven.compiler.target> | ||||
|         <joda-time.version>2.10</joda-time.version> | ||||
|         <!-- testing --> | ||||
|         <assertj.version>3.6.1</assertj.version> | ||||
| @ -11,31 +11,31 @@ public class LocalDateExampleUnitTest { | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenValues_whenUsingOfMethod_thenLocalDate() { | ||||
|         assertEquals("2020-01-08", date.getCustomDateOne(2020, 1, 8)); | ||||
|         assertEquals("2020-01-08", date.getCustomDateOne(2020, 1, 8).toString()); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenValuesWithMonthEnum_whenUsingOfMethod_thenLocalDate() { | ||||
|         assertEquals("2020-01-08", date.getCustomDateTwo(2020, Month.JANUARY, 8)); | ||||
|         assertEquals("2020-01-08", date.getCustomDateTwo(2020, Month.JANUARY, 8).toString()); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenValues_whenUsingEpochDay_thenLocalDate() { | ||||
|         assertEquals("2020-01-08", date.getDateFromEpochDay(18269)); | ||||
|         assertEquals("2020-01-08", date.getDateFromEpochDay(18269).toString()); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenValues_whenUsingYearDay_thenLocalDate() { | ||||
|         assertEquals("2020-01-08", date.getDateFromYearAndDayOfYear(2020, 8)); | ||||
|         assertEquals("2020-01-08", date.getDateFromYearAndDayOfYear(2020, 8).toString()); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenValues_whenUsingParse_thenLocalDate() { | ||||
|         assertEquals("2020-01-08", date.getDateFromString("2020-01-08")); | ||||
|         assertEquals("2020-01-08", date.getDateFromString("2020-01-08").toString()); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenValuesWithFormatter_whenUsingParse_thenLocalDate() { | ||||
|         assertEquals("2020-01-08", date.getDateFromStringAndFormatter("8-Jan-2020", "d-MMM-yyyy")); | ||||
|         assertEquals("2020-01-08", date.getDateFromStringAndFormatter("8-Jan-2020", "d-MMM-yyyy").toString()); | ||||
|     } | ||||
| } | ||||
| @ -13,4 +13,4 @@ This module contains articles about the Date and Time API introduced with Java 8 | ||||
| - [How to Get the Start and the End of a Day using Java](http://www.baeldung.com/java-day-start-end) | ||||
| - [Set the Time Zone of a Date in Java](https://www.baeldung.com/java-set-date-time-zone) | ||||
| - [Comparing Dates in Java](https://www.baeldung.com/java-comparing-dates) | ||||
| - [Generating Random Dates in Java](https://www.baeldung.com/java-random-dates) | ||||
| - [[Next -->]](/core-java-modules/core-java-datetime-java8-2) | ||||
| @ -4,9 +4,9 @@ | ||||
|     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-datetime-java8</artifactId> | ||||
|     <artifactId>core-java-8-datetime</artifactId> | ||||
|     <version>${project.parent.version}</version> | ||||
|     <name>core-java-datetime-java8</name> | ||||
|     <name>core-java-8-datetime</name> | ||||
|     <packaging>jar</packaging> | ||||
| 
 | ||||
|     <parent> | ||||
| @ -64,8 +64,8 @@ | ||||
|     </build> | ||||
| 
 | ||||
|     <properties> | ||||
|         <maven.compiler.source>1.9</maven.compiler.source> | ||||
|         <maven.compiler.target>1.9</maven.compiler.target> | ||||
|         <maven.compiler.source>1.8</maven.compiler.source> | ||||
|         <maven.compiler.target>1.8</maven.compiler.target> | ||||
|         <joda-time.version>2.10</joda-time.version> | ||||
|         <!-- testing --> | ||||
|         <assertj.version>3.6.1</assertj.version> | ||||
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