Merge remote-tracking branch 'origin/master'
This commit is contained in:
		
						commit
						77d4da5cd0
					
				| @ -1,2 +1,3 @@ | |||||||
| ### Relevant Articles: | ### Relevant Articles: | ||||||
| - [Microsoft Word Processing in Java with Apache POI](http://www.baeldung.com/java-microsoft-word-with-apache-poi) | - [Microsoft Word Processing in Java with Apache POI](http://www.baeldung.com/java-microsoft-word-with-apache-poi) | ||||||
|  | - [Working with Microsoft Excel in Java](http://www.baeldung.com/java-microsoft-excel) | ||||||
|  | |||||||
| @ -1,5 +1,5 @@ | |||||||
| <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||||||
|     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |          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> |     <modelVersion>4.0.0</modelVersion> | ||||||
|     <groupId>com.baeldung</groupId> |     <groupId>com.baeldung</groupId> | ||||||
|     <artifactId>core-java</artifactId> |     <artifactId>core-java</artifactId> | ||||||
| @ -10,6 +10,44 @@ | |||||||
| 
 | 
 | ||||||
|     <dependencies> |     <dependencies> | ||||||
| 
 | 
 | ||||||
|  |         <dependency> | ||||||
|  |             <groupId>org.neo4j</groupId> | ||||||
|  |             <artifactId>neo4j</artifactId> | ||||||
|  |             <version>3.1.0</version> | ||||||
|  |         </dependency> | ||||||
|  | 
 | ||||||
|  |         <dependency> | ||||||
|  |             <groupId>org.neo4j.driver</groupId> | ||||||
|  |             <artifactId>neo4j-java-driver</artifactId> | ||||||
|  |             <version>1.1.1</version> | ||||||
|  |         </dependency> | ||||||
|  | 
 | ||||||
|  |         <dependency> | ||||||
|  |             <groupId>org.neo4j</groupId> | ||||||
|  |             <artifactId>neo4j-jdbc-driver</artifactId> | ||||||
|  |             <version>3.0.1</version> | ||||||
|  |         </dependency> | ||||||
|  | 
 | ||||||
|  |         <dependency> | ||||||
|  |             <groupId>org.neo4j</groupId> | ||||||
|  |             <artifactId>neo4j-ogm-core</artifactId> | ||||||
|  |             <version>2.1.1</version> | ||||||
|  |         </dependency> | ||||||
|  | 
 | ||||||
|  |         <dependency> | ||||||
|  |             <groupId>org.neo4j</groupId> | ||||||
|  |             <artifactId>neo4j-ogm-embedded-driver</artifactId> | ||||||
|  |             <version>2.1.1</version> | ||||||
|  |         </dependency> | ||||||
|  | 
 | ||||||
|  |         <dependency> | ||||||
|  |             <groupId>com.google.inject</groupId> | ||||||
|  |             <artifactId>guice</artifactId> | ||||||
|  |             <version>4.1.0</version> | ||||||
|  |             <classifier>no_aop</classifier> | ||||||
|  |             <scope>test</scope> | ||||||
|  |         </dependency> | ||||||
|  | 
 | ||||||
|         <!-- utils --> |         <!-- utils --> | ||||||
|         <dependency> |         <dependency> | ||||||
|             <groupId>net.sourceforge.collections</groupId> |             <groupId>net.sourceforge.collections</groupId> | ||||||
| @ -63,7 +101,6 @@ | |||||||
|             <artifactId>grep4j</artifactId> |             <artifactId>grep4j</artifactId> | ||||||
|             <version>${grep4j.version}</version> |             <version>${grep4j.version}</version> | ||||||
|         </dependency> |         </dependency> | ||||||
|          |  | ||||||
|         <!-- web --> |         <!-- web --> | ||||||
| 
 | 
 | ||||||
|         <!-- marshalling --> |         <!-- marshalling --> | ||||||
| @ -269,7 +306,8 @@ | |||||||
|                         <configuration> |                         <configuration> | ||||||
|                             <shadedArtifactAttached>true</shadedArtifactAttached> |                             <shadedArtifactAttached>true</shadedArtifactAttached> | ||||||
|                             <transformers> |                             <transformers> | ||||||
|                                 <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> |                                 <transformer | ||||||
|  |                                         implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> | ||||||
|                                     <mainClass>org.baeldung.executable.ExecutableMavenJar</mainClass> |                                     <mainClass>org.baeldung.executable.ExecutableMavenJar</mainClass> | ||||||
|                                 </transformer> |                                 </transformer> | ||||||
|                             </transformers> |                             </transformers> | ||||||
|  | |||||||
							
								
								
									
										50
									
								
								core-java/src/main/java/com/baeldung/graph/Car.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								core-java/src/main/java/com/baeldung/graph/Car.java
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,50 @@ | |||||||
|  | package com.baeldung.graph; | ||||||
|  | 
 | ||||||
|  | import org.neo4j.ogm.annotation.GraphId; | ||||||
|  | import org.neo4j.ogm.annotation.NodeEntity; | ||||||
|  | import org.neo4j.ogm.annotation.Relationship; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * @author Danil Kornishev (danil.kornishev@mastercard.com) | ||||||
|  |  */ | ||||||
|  | @NodeEntity | ||||||
|  | public class Car { | ||||||
|  |     @GraphId | ||||||
|  |     private Long id; | ||||||
|  | 
 | ||||||
|  |     private String make; | ||||||
|  | 
 | ||||||
|  |     @Relationship(direction = "INCOMING") | ||||||
|  |     private Company company; | ||||||
|  | 
 | ||||||
|  |     public Car(String make, String model) { | ||||||
|  |         this.make = make; | ||||||
|  |         this.model = model; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public Long getId() { | ||||||
|  |         return id; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setId(Long id) { | ||||||
|  |         this.id = id; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public String getMake() { | ||||||
|  |         return make; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setMake(String make) { | ||||||
|  |         this.make = make; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public String getModel() { | ||||||
|  |         return model; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setModel(String model) { | ||||||
|  |         this.model = model; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private String model; | ||||||
|  | } | ||||||
							
								
								
									
										45
									
								
								core-java/src/main/java/com/baeldung/graph/Company.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								core-java/src/main/java/com/baeldung/graph/Company.java
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,45 @@ | |||||||
|  | package com.baeldung.graph; | ||||||
|  | 
 | ||||||
|  | import org.neo4j.ogm.annotation.NodeEntity; | ||||||
|  | import org.neo4j.ogm.annotation.Relationship; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * @author Danil Kornishev (danil.kornishev@mastercard.com) | ||||||
|  |  */ | ||||||
|  | @NodeEntity | ||||||
|  | public class Company { | ||||||
|  |     private Long id; | ||||||
|  | 
 | ||||||
|  |     private String name; | ||||||
|  | 
 | ||||||
|  |     @Relationship(type="owns") | ||||||
|  |     private Car car; | ||||||
|  | 
 | ||||||
|  |     public Company(String name) { | ||||||
|  |         this.name = name; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public Long getId() { | ||||||
|  |         return id; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setId(Long id) { | ||||||
|  |         this.id = id; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public String getName() { | ||||||
|  |         return name; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setName(String name) { | ||||||
|  |         this.name = name; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public Car getCar() { | ||||||
|  |         return car; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setCar(Car car) { | ||||||
|  |         this.car = car; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,36 @@ | |||||||
|  | package com.baeldung.java_8_features.groupingby; | ||||||
|  | 
 | ||||||
|  | public class BlogPost { | ||||||
|  |     private String title; | ||||||
|  |     private String author; | ||||||
|  |     private BlogPostType type; | ||||||
|  |     private int likes; | ||||||
|  | 
 | ||||||
|  |     public BlogPost(String title, String author, BlogPostType type, int likes) { | ||||||
|  |         this.title = title; | ||||||
|  |         this.author = author; | ||||||
|  |         this.type = type; | ||||||
|  |         this.likes = likes; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public String getTitle() { | ||||||
|  |         return title; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public String getAuthor() { | ||||||
|  |         return author; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public BlogPostType getType() { | ||||||
|  |         return type; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public int getLikes() { | ||||||
|  |         return likes; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public String toString() { | ||||||
|  |         return "BlogPost{" + "title='" + title + '\'' + ", type=" + type + ", likes=" + likes + '}'; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,5 @@ | |||||||
|  | package com.baeldung.java_8_features.groupingby; | ||||||
|  | 
 | ||||||
|  | public enum BlogPostType { | ||||||
|  |     NEWS, REVIEW, GUIDE | ||||||
|  | } | ||||||
| @ -0,0 +1,60 @@ | |||||||
|  | package com.baeldung.graph; | ||||||
|  | 
 | ||||||
|  | import java.sql.Connection; | ||||||
|  | import java.sql.DriverManager; | ||||||
|  | import java.sql.ResultSet; | ||||||
|  | import java.sql.Statement; | ||||||
|  | 
 | ||||||
|  | import org.junit.Ignore; | ||||||
|  | import org.junit.Test; | ||||||
|  | import org.neo4j.driver.v1.AuthTokens; | ||||||
|  | import org.neo4j.driver.v1.Driver; | ||||||
|  | import org.neo4j.driver.v1.GraphDatabase; | ||||||
|  | import org.neo4j.driver.v1.Session; | ||||||
|  | import org.neo4j.driver.v1.StatementResult; | ||||||
|  | import org.testng.Assert; | ||||||
|  | 
 | ||||||
|  | @Ignore | ||||||
|  | public class Neo4JServerTest { | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void standAloneDriver() { | ||||||
|  |         Driver driver = GraphDatabase.driver("bolt://localhost:7687", AuthTokens.basic("neo4j", "12345")); | ||||||
|  |         Session session = driver.session(); | ||||||
|  | 
 | ||||||
|  |         session.run("CREATE (baeldung:Company {name:\"Baeldung\"}) " + | ||||||
|  |                 "-[:owns]-> (tesla:Car {make: 'tesla', model: 'modelX'})" + | ||||||
|  |                 "RETURN baeldung, tesla"); | ||||||
|  | 
 | ||||||
|  |         StatementResult result = session.run("MATCH (company:Company)-[:owns]-> (car:Car)" + | ||||||
|  |                 "WHERE car.make='tesla' and car.model='modelX'" + | ||||||
|  |                 "RETURN company.name"); | ||||||
|  | 
 | ||||||
|  |         Assert.assertTrue(result.hasNext()); | ||||||
|  |         Assert.assertEquals(result.next().get("company.name").asString(), "Baeldung"); | ||||||
|  | 
 | ||||||
|  |         session.close(); | ||||||
|  |         driver.close(); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     @Test | ||||||
|  |     public void standAloneJdbc() throws Exception { | ||||||
|  |         Connection con = DriverManager.getConnection("jdbc:neo4j:bolt://localhost/?user=neo4j,password=12345,scheme=basic"); | ||||||
|  | 
 | ||||||
|  |         // Querying | ||||||
|  |         try (Statement stmt = con.createStatement()) { | ||||||
|  |             stmt.execute("CREATE (baeldung:Company {name:\"Baeldung\"}) " + | ||||||
|  |                     "-[:owns]-> (tesla:Car {make: 'tesla', model: 'modelX'})" + | ||||||
|  |                     "RETURN baeldung, tesla"); | ||||||
|  | 
 | ||||||
|  |             ResultSet rs = stmt.executeQuery("MATCH (company:Company)-[:owns]-> (car:Car)" + | ||||||
|  |                     "WHERE car.make='tesla' and car.model='modelX'" + | ||||||
|  |                     "RETURN company.name"); | ||||||
|  | 
 | ||||||
|  |             while (rs.next()) { | ||||||
|  |                 Assert.assertEquals(rs.getString("company.name"), "Baeldung"); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         con.close(); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										46
									
								
								core-java/src/test/java/com/baeldung/graph/Neo4jOgmTest.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								core-java/src/test/java/com/baeldung/graph/Neo4jOgmTest.java
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,46 @@ | |||||||
|  | package com.baeldung.graph; | ||||||
|  | 
 | ||||||
|  | import org.junit.Test; | ||||||
|  | import org.neo4j.ogm.config.Configuration; | ||||||
|  | import org.neo4j.ogm.model.Result; | ||||||
|  | import org.neo4j.ogm.session.Session; | ||||||
|  | import org.neo4j.ogm.session.SessionFactory; | ||||||
|  | import org.testng.Assert; | ||||||
|  | 
 | ||||||
|  | import java.util.HashMap; | ||||||
|  | import java.util.Map; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * @author Danil Kornishev (danil.kornishev@mastercard.com) | ||||||
|  |  */ | ||||||
|  | public class Neo4jOgmTest { | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void testOgm() { | ||||||
|  |         Configuration conf = new Configuration(); | ||||||
|  |         conf.driverConfiguration().setDriverClassName("org.neo4j.ogm.drivers.embedded.driver.EmbeddedDriver"); | ||||||
|  | 
 | ||||||
|  |         SessionFactory factory = new SessionFactory(conf, "com.baeldung.graph"); | ||||||
|  |         Session session = factory.openSession(); | ||||||
|  | 
 | ||||||
|  |         Car tesla = new Car("tesla", "modelS"); | ||||||
|  |         Company baeldung = new Company("baeldung"); | ||||||
|  | 
 | ||||||
|  |         baeldung.setCar(tesla); | ||||||
|  | 
 | ||||||
|  |         session.save(baeldung); | ||||||
|  | 
 | ||||||
|  |         Map<String, String> params = new HashMap<>(); | ||||||
|  |         params.put("make", "tesla"); | ||||||
|  |         Result result = session.query("MATCH (car:Car) <-[:owns]- (company:Company)" + | ||||||
|  |                 " WHERE car.make=$make" + | ||||||
|  |                 " RETURN company", params); | ||||||
|  | 
 | ||||||
|  |         Map<String, Object> firstResult = result.iterator().next(); | ||||||
|  | 
 | ||||||
|  |         Assert.assertEquals(firstResult.size(), 1); | ||||||
|  | 
 | ||||||
|  |         Company actual = (Company) firstResult.get("company"); | ||||||
|  |         Assert.assertEquals(actual.getName(), baeldung.getName()); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										167
									
								
								core-java/src/test/java/com/baeldung/graph/Neo4jTest.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										167
									
								
								core-java/src/test/java/com/baeldung/graph/Neo4jTest.java
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,167 @@ | |||||||
|  | package com.baeldung.graph; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | import java.io.File; | ||||||
|  | import java.util.Arrays; | ||||||
|  | import java.util.HashMap; | ||||||
|  | import java.util.Map; | ||||||
|  | 
 | ||||||
|  | import org.junit.After; | ||||||
|  | import org.junit.Before; | ||||||
|  | import org.junit.Test; | ||||||
|  | import org.neo4j.graphdb.GraphDatabaseService; | ||||||
|  | import org.neo4j.graphdb.Label; | ||||||
|  | import org.neo4j.graphdb.Node; | ||||||
|  | import org.neo4j.graphdb.NotFoundException; | ||||||
|  | import org.neo4j.graphdb.RelationshipType; | ||||||
|  | import org.neo4j.graphdb.Result; | ||||||
|  | import org.neo4j.graphdb.factory.GraphDatabaseFactory; | ||||||
|  | import org.testng.Assert; | ||||||
|  | 
 | ||||||
|  | public class Neo4jTest { | ||||||
|  | 
 | ||||||
|  |     private static GraphDatabaseService graphDb; | ||||||
|  | 
 | ||||||
|  |     @Before | ||||||
|  |     public void setUp() { | ||||||
|  |         GraphDatabaseFactory graphDbFactory = new GraphDatabaseFactory(); | ||||||
|  |         graphDb = graphDbFactory.newEmbeddedDatabase(new File("data/cars")); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @After | ||||||
|  |     public void tearDown() { | ||||||
|  |         graphDb.shutdown(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void testPersonCar() { | ||||||
|  |         graphDb.beginTx(); | ||||||
|  |         Node car = graphDb.createNode(Label.label("Car")); | ||||||
|  |         car.setProperty("make", "tesla"); | ||||||
|  |         car.setProperty("model", "model3"); | ||||||
|  | 
 | ||||||
|  |         Node owner = graphDb.createNode(Label.label("Person")); | ||||||
|  |         owner.setProperty("firstName", "baeldung"); | ||||||
|  |         owner.setProperty("lastName", "baeldung"); | ||||||
|  | 
 | ||||||
|  |         owner.createRelationshipTo(car, RelationshipType.withName("owner")); | ||||||
|  | 
 | ||||||
|  |         Result result = graphDb.execute("MATCH (c:Car) <-[owner]- (p:Person) " + | ||||||
|  |                 "WHERE c.make = 'tesla'" + | ||||||
|  |                 "RETURN p.firstName, p.lastName"); | ||||||
|  | 
 | ||||||
|  |         Map<String, Object> firstResult = result.next(); | ||||||
|  |         Assert.assertEquals("baeldung", firstResult.get("p.firstName")); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void testCreateNode() { | ||||||
|  | 
 | ||||||
|  |         graphDb.beginTx(); | ||||||
|  | 
 | ||||||
|  |         Result result = graphDb.execute("CREATE (baeldung:Company {name:\"Baeldung\"})" + | ||||||
|  |                 "RETURN baeldung"); | ||||||
|  | 
 | ||||||
|  |         Map<String, Object> firstResult = result.next(); | ||||||
|  |         Node firstNode = (Node) firstResult.get("baeldung"); | ||||||
|  |         Assert.assertEquals(firstNode.getProperty("name"), "Baeldung"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void testCreateNodeAndLink() { | ||||||
|  |         graphDb.beginTx(); | ||||||
|  | 
 | ||||||
|  |         Result result = graphDb.execute("CREATE (baeldung:Company {name:\"Baeldung\"}) " + | ||||||
|  |                 "-[:owns]-> (tesla:Car {make: 'tesla', model: 'modelX'})" + | ||||||
|  |                 "RETURN baeldung, tesla"); | ||||||
|  | 
 | ||||||
|  |         Map<String, Object> firstResult = result.next(); | ||||||
|  |         Assert.assertTrue(firstResult.containsKey("baeldung")); | ||||||
|  |         Assert.assertTrue(firstResult.containsKey("tesla")); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void testFindAndReturn() { | ||||||
|  |         graphDb.beginTx(); | ||||||
|  | 
 | ||||||
|  |         graphDb.execute("CREATE (baeldung:Company {name:\"Baeldung\"}) " + | ||||||
|  |                 "-[:owns]-> (tesla:Car {make: 'tesla', model: 'modelX'})" + | ||||||
|  |                 "RETURN baeldung, tesla"); | ||||||
|  | 
 | ||||||
|  |         Result result = graphDb.execute("MATCH (company:Company)-[:owns]-> (car:Car)" + | ||||||
|  |                 "WHERE car.make='tesla' and car.model='modelX'" + | ||||||
|  |                 "RETURN company.name"); | ||||||
|  | 
 | ||||||
|  |         Map<String, Object> firstResult = result.next(); | ||||||
|  |         Assert.assertEquals(firstResult.get("company.name"), "Baeldung"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void testUpdate() { | ||||||
|  |         graphDb.beginTx(); | ||||||
|  | 
 | ||||||
|  |         graphDb.execute("CREATE (baeldung:Company {name:\"Baeldung\"}) " + | ||||||
|  |                 "-[:owns]-> (tesla:Car {make: 'tesla', model: 'modelX'})" + | ||||||
|  |                 "RETURN baeldung, tesla"); | ||||||
|  | 
 | ||||||
|  |         Result result = graphDb.execute("MATCH (car:Car)" + | ||||||
|  |                 "WHERE car.make='tesla'" + | ||||||
|  |                 " SET car.milage=120" + | ||||||
|  |                 " SET car :Car:Electro" + | ||||||
|  |                 " SET car.model=NULL" + | ||||||
|  |                 " RETURN car"); | ||||||
|  | 
 | ||||||
|  |         Map<String, Object> firstResult = result.next(); | ||||||
|  |         Node car = (Node) firstResult.get("car"); | ||||||
|  | 
 | ||||||
|  |         Assert.assertEquals(car.getProperty("milage"), 120L); | ||||||
|  |         Assert.assertEquals(car.getLabels(), Arrays.asList(Label.label("Car"), Label.label("Electro"))); | ||||||
|  | 
 | ||||||
|  |         try { | ||||||
|  |             car.getProperty("model"); | ||||||
|  |             Assert.fail(); | ||||||
|  |         } catch (NotFoundException e) { | ||||||
|  |             // expected | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void testDelete() { | ||||||
|  |         graphDb.beginTx(); | ||||||
|  | 
 | ||||||
|  |         graphDb.execute("CREATE (baeldung:Company {name:\"Baeldung\"}) " + | ||||||
|  |                 "-[:owns]-> (tesla:Car {make: 'tesla', model: 'modelX'})" + | ||||||
|  |                 "RETURN baeldung, tesla"); | ||||||
|  | 
 | ||||||
|  |         graphDb.execute("MATCH (company:Company)" + | ||||||
|  |                 " WHERE company.name='Baeldung'" + | ||||||
|  |                 " DELETE company"); | ||||||
|  | 
 | ||||||
|  |         Result result = graphDb.execute("MATCH (company:Company)" + | ||||||
|  |                 " WHERE company.name='Baeldung'" + | ||||||
|  |                 " RETURN company"); | ||||||
|  | 
 | ||||||
|  |         Assert.assertFalse(result.hasNext()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void testBindings() { | ||||||
|  |         graphDb.beginTx(); | ||||||
|  | 
 | ||||||
|  |         Map<String, Object> params = new HashMap<>(); | ||||||
|  |         params.put("name", "baeldung"); | ||||||
|  |         params.put("make", "tesla"); | ||||||
|  |         params.put("model", "modelS"); | ||||||
|  | 
 | ||||||
|  |         Result result = graphDb.execute("CREATE (baeldung:Company {name:$name}) " + | ||||||
|  |                 "-[:owns]-> (tesla:Car {make: $make, model: $model})" + | ||||||
|  |                 "RETURN baeldung, tesla", params); | ||||||
|  | 
 | ||||||
|  |         Map<String, Object> firstResult = result.next(); | ||||||
|  |         Assert.assertTrue(firstResult.containsKey("baeldung")); | ||||||
|  |         Assert.assertTrue(firstResult.containsKey("tesla")); | ||||||
|  | 
 | ||||||
|  |         Node car = (Node) firstResult.get("tesla"); | ||||||
|  |         Assert.assertEquals(car.getProperty("model"), "modelS"); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,80 @@ | |||||||
|  | package com.baeldung.java.concurrentmodification; | ||||||
|  | 
 | ||||||
|  | import org.junit.Test; | ||||||
|  | 
 | ||||||
|  | import java.util.ArrayList; | ||||||
|  | import java.util.Collection; | ||||||
|  | import java.util.ConcurrentModificationException; | ||||||
|  | import java.util.Iterator; | ||||||
|  | import java.util.List; | ||||||
|  | 
 | ||||||
|  | import static java.util.stream.Collectors.toList; | ||||||
|  | import static org.assertj.core.api.Assertions.assertThat; | ||||||
|  | import static org.assertj.core.util.Lists.newArrayList; | ||||||
|  | 
 | ||||||
|  | public class ConcurrentModificationUnitTest { | ||||||
|  |     @Test(expected = ConcurrentModificationException.class) | ||||||
|  |     public void givenIterating_whenRemoving_thenThrowException() throws InterruptedException { | ||||||
|  | 
 | ||||||
|  |         List<Integer> integers = newArrayList(1, 2, 3); | ||||||
|  | 
 | ||||||
|  |         for (Integer integer : integers) { | ||||||
|  |             integers.remove(1); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void givenIterating_whenUsingIteratorRemove_thenNoError() throws InterruptedException { | ||||||
|  | 
 | ||||||
|  |         List<Integer> integers = newArrayList(1, 2, 3); | ||||||
|  | 
 | ||||||
|  |         for (Iterator<Integer> iterator = integers.iterator(); iterator.hasNext();) { | ||||||
|  |             Integer integer = iterator.next(); | ||||||
|  |             if(integer == 2) { | ||||||
|  |                 iterator.remove(); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         assertThat(integers).containsExactly(1, 3); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void givenIterating_whenUsingRemovalList_thenNoError() throws InterruptedException { | ||||||
|  | 
 | ||||||
|  |         List<Integer> integers = newArrayList(1, 2, 3); | ||||||
|  |         List<Integer> toRemove = newArrayList(); | ||||||
|  | 
 | ||||||
|  |         for (Integer integer : integers) { | ||||||
|  |             if(integer == 2) { | ||||||
|  |                 toRemove.add(integer); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         integers.removeAll(toRemove); | ||||||
|  | 
 | ||||||
|  |         assertThat(integers).containsExactly(1, 3); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void whenUsingRemoveIf_thenRemoveElements() throws InterruptedException { | ||||||
|  | 
 | ||||||
|  |         Collection<Integer> integers = newArrayList(1, 2, 3); | ||||||
|  | 
 | ||||||
|  |         integers.removeIf(i -> i == 2); | ||||||
|  | 
 | ||||||
|  |         assertThat(integers).containsExactly(1, 3); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void whenUsingStream_thenRemoveElements() { | ||||||
|  |         Collection<Integer> integers = newArrayList(1, 2, 3); | ||||||
|  | 
 | ||||||
|  |         List<String> collected = integers | ||||||
|  |                 .stream() | ||||||
|  |                 .filter(i -> i != 2) | ||||||
|  |                 .map(Object::toString) | ||||||
|  |                 .collect(toList()); | ||||||
|  | 
 | ||||||
|  |         assertThat(collected).containsExactly("1", "3"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -0,0 +1,231 @@ | |||||||
|  | package com.baeldung.java8; | ||||||
|  | 
 | ||||||
|  | import com.baeldung.java_8_features.groupingby.BlogPost; | ||||||
|  | import com.baeldung.java_8_features.groupingby.BlogPostType; | ||||||
|  | import org.junit.Test; | ||||||
|  | 
 | ||||||
|  | import java.util.*; | ||||||
|  | import java.util.concurrent.ConcurrentMap; | ||||||
|  | 
 | ||||||
|  | import static java.util.Comparator.comparingInt; | ||||||
|  | import static java.util.stream.Collectors.*; | ||||||
|  | import static org.junit.Assert.*; | ||||||
|  | 
 | ||||||
|  | public class Java8GroupingByCollectorUnitTest { | ||||||
|  | 
 | ||||||
|  |     private static final List<BlogPost> posts = Arrays.asList( | ||||||
|  |       new BlogPost("News item 1", "Author 1", BlogPostType.NEWS, 15), | ||||||
|  |       new BlogPost("Tech review 1", "Author 2", BlogPostType.REVIEW, 5), | ||||||
|  |       new BlogPost("Programming guide", "Author 1", BlogPostType.GUIDE, 20), | ||||||
|  |       new BlogPost("News item 2", "Author 2", BlogPostType.NEWS, 35), | ||||||
|  |       new BlogPost("Tech review 2", "Author 1", BlogPostType.REVIEW, 15)); | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void givenAListOfPosts_whenGroupedByType_thenGetAMapBetweenTypeAndPosts() { | ||||||
|  |         Map<BlogPostType, List<BlogPost>> postsPerType = posts | ||||||
|  |           .stream() | ||||||
|  |           .collect(groupingBy(BlogPost::getType)); | ||||||
|  | 
 | ||||||
|  |         assertEquals(2, postsPerType | ||||||
|  |           .get(BlogPostType.NEWS) | ||||||
|  |           .size()); | ||||||
|  |         assertEquals(1, postsPerType | ||||||
|  |           .get(BlogPostType.GUIDE) | ||||||
|  |           .size()); | ||||||
|  |         assertEquals(2, postsPerType | ||||||
|  |           .get(BlogPostType.REVIEW) | ||||||
|  |           .size()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void givenAListOfPosts_whenGroupedByTypeAndTheirTitlesAreJoinedInAString_thenGetAMapBetweenTypeAndCsvTitles() { | ||||||
|  |         Map<BlogPostType, String> postsPerType = posts | ||||||
|  |           .stream() | ||||||
|  |           .collect(groupingBy(BlogPost::getType, mapping(BlogPost::getTitle, joining(", ", "Post titles: [", "]")))); | ||||||
|  | 
 | ||||||
|  |         assertEquals("Post titles: [News item 1, News item 2]", postsPerType.get(BlogPostType.NEWS)); | ||||||
|  |         assertEquals("Post titles: [Programming guide]", postsPerType.get(BlogPostType.GUIDE)); | ||||||
|  |         assertEquals("Post titles: [Tech review 1, Tech review 2]", postsPerType.get(BlogPostType.REVIEW)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void givenAListOfPosts_whenGroupedByTypeAndSumTheLikes_thenGetAMapBetweenTypeAndPostLikes() { | ||||||
|  |         Map<BlogPostType, Integer> likesPerType = posts | ||||||
|  |           .stream() | ||||||
|  |           .collect(groupingBy(BlogPost::getType, summingInt(BlogPost::getLikes))); | ||||||
|  | 
 | ||||||
|  |         assertEquals(50, likesPerType | ||||||
|  |           .get(BlogPostType.NEWS) | ||||||
|  |           .intValue()); | ||||||
|  |         assertEquals(20, likesPerType | ||||||
|  |           .get(BlogPostType.REVIEW) | ||||||
|  |           .intValue()); | ||||||
|  |         assertEquals(20, likesPerType | ||||||
|  |           .get(BlogPostType.GUIDE) | ||||||
|  |           .intValue()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void givenAListOfPosts_whenGroupedByTypeInAnEnumMap_thenGetAnEnumMapBetweenTypeAndPosts() { | ||||||
|  |         EnumMap<BlogPostType, List<BlogPost>> postsPerType = posts | ||||||
|  |           .stream() | ||||||
|  |           .collect(groupingBy(BlogPost::getType, () -> new EnumMap<>(BlogPostType.class), toList())); | ||||||
|  | 
 | ||||||
|  |         assertEquals(2, postsPerType | ||||||
|  |           .get(BlogPostType.NEWS) | ||||||
|  |           .size()); | ||||||
|  |         assertEquals(1, postsPerType | ||||||
|  |           .get(BlogPostType.GUIDE) | ||||||
|  |           .size()); | ||||||
|  |         assertEquals(2, postsPerType | ||||||
|  |           .get(BlogPostType.REVIEW) | ||||||
|  |           .size()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void givenAListOfPosts_whenGroupedByTypeInSets_thenGetAMapBetweenTypesAndSetsOfPosts() { | ||||||
|  |         Map<BlogPostType, Set<BlogPost>> postsPerType = posts | ||||||
|  |           .stream() | ||||||
|  |           .collect(groupingBy(BlogPost::getType, toSet())); | ||||||
|  | 
 | ||||||
|  |         assertEquals(2, postsPerType | ||||||
|  |           .get(BlogPostType.NEWS) | ||||||
|  |           .size()); | ||||||
|  |         assertEquals(1, postsPerType | ||||||
|  |           .get(BlogPostType.GUIDE) | ||||||
|  |           .size()); | ||||||
|  |         assertEquals(2, postsPerType | ||||||
|  |           .get(BlogPostType.REVIEW) | ||||||
|  |           .size()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void givenAListOfPosts_whenGroupedByTypeConcurrently_thenGetAMapBetweenTypeAndPosts() { | ||||||
|  |         ConcurrentMap<BlogPostType, List<BlogPost>> postsPerType = posts | ||||||
|  |           .parallelStream() | ||||||
|  |           .collect(groupingByConcurrent(BlogPost::getType)); | ||||||
|  | 
 | ||||||
|  |         assertEquals(2, postsPerType | ||||||
|  |           .get(BlogPostType.NEWS) | ||||||
|  |           .size()); | ||||||
|  |         assertEquals(1, postsPerType | ||||||
|  |           .get(BlogPostType.GUIDE) | ||||||
|  |           .size()); | ||||||
|  |         assertEquals(2, postsPerType | ||||||
|  |           .get(BlogPostType.REVIEW) | ||||||
|  |           .size()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void givenAListOfPosts_whenGroupedByTypeAndAveragingLikes_thenGetAMapBetweenTypeAndAverageNumberOfLikes() { | ||||||
|  |         Map<BlogPostType, Double> averageLikesPerType = posts | ||||||
|  |           .stream() | ||||||
|  |           .collect(groupingBy(BlogPost::getType, averagingInt(BlogPost::getLikes))); | ||||||
|  | 
 | ||||||
|  |         assertEquals(25, averageLikesPerType | ||||||
|  |           .get(BlogPostType.NEWS) | ||||||
|  |           .intValue()); | ||||||
|  |         assertEquals(20, averageLikesPerType | ||||||
|  |           .get(BlogPostType.GUIDE) | ||||||
|  |           .intValue()); | ||||||
|  |         assertEquals(10, averageLikesPerType | ||||||
|  |           .get(BlogPostType.REVIEW) | ||||||
|  |           .intValue()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void givenAListOfPosts_whenGroupedByTypeAndCounted_thenGetAMapBetweenTypeAndNumberOfPosts() { | ||||||
|  |         Map<BlogPostType, Long> numberOfPostsPerType = posts | ||||||
|  |           .stream() | ||||||
|  |           .collect(groupingBy(BlogPost::getType, counting())); | ||||||
|  | 
 | ||||||
|  |         assertEquals(2, numberOfPostsPerType | ||||||
|  |           .get(BlogPostType.NEWS) | ||||||
|  |           .intValue()); | ||||||
|  |         assertEquals(1, numberOfPostsPerType | ||||||
|  |           .get(BlogPostType.GUIDE) | ||||||
|  |           .intValue()); | ||||||
|  |         assertEquals(2, numberOfPostsPerType | ||||||
|  |           .get(BlogPostType.REVIEW) | ||||||
|  |           .intValue()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void givenAListOfPosts_whenGroupedByTypeAndMaxingLikes_thenGetAMapBetweenTypeAndMaximumNumberOfLikes() { | ||||||
|  |         Map<BlogPostType, Optional<BlogPost>> maxLikesPerPostType = posts | ||||||
|  |           .stream() | ||||||
|  |           .collect(groupingBy(BlogPost::getType, maxBy(comparingInt(BlogPost::getLikes)))); | ||||||
|  | 
 | ||||||
|  |         assertTrue(maxLikesPerPostType | ||||||
|  |           .get(BlogPostType.NEWS) | ||||||
|  |           .isPresent()); | ||||||
|  |         assertEquals(35, maxLikesPerPostType | ||||||
|  |           .get(BlogPostType.NEWS) | ||||||
|  |           .get() | ||||||
|  |           .getLikes()); | ||||||
|  | 
 | ||||||
|  |         assertTrue(maxLikesPerPostType | ||||||
|  |           .get(BlogPostType.GUIDE) | ||||||
|  |           .isPresent()); | ||||||
|  |         assertEquals(20, maxLikesPerPostType | ||||||
|  |           .get(BlogPostType.GUIDE) | ||||||
|  |           .get() | ||||||
|  |           .getLikes()); | ||||||
|  | 
 | ||||||
|  |         assertTrue(maxLikesPerPostType | ||||||
|  |           .get(BlogPostType.REVIEW) | ||||||
|  |           .isPresent()); | ||||||
|  |         assertEquals(15, maxLikesPerPostType | ||||||
|  |           .get(BlogPostType.REVIEW) | ||||||
|  |           .get() | ||||||
|  |           .getLikes()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void givenAListOfPosts_whenGroupedByAuthorAndThenByType_thenGetAMapBetweenAuthorAndMapsBetweenTypeAndBlogPosts() { | ||||||
|  |         Map<String, Map<BlogPostType, List<BlogPost>>> map = posts | ||||||
|  |           .stream() | ||||||
|  |           .collect(groupingBy(BlogPost::getAuthor, groupingBy(BlogPost::getType))); | ||||||
|  | 
 | ||||||
|  |         assertEquals(1, map | ||||||
|  |           .get("Author 1") | ||||||
|  |           .get(BlogPostType.NEWS) | ||||||
|  |           .size()); | ||||||
|  |         assertEquals(1, map | ||||||
|  |           .get("Author 1") | ||||||
|  |           .get(BlogPostType.GUIDE) | ||||||
|  |           .size()); | ||||||
|  |         assertEquals(1, map | ||||||
|  |           .get("Author 1") | ||||||
|  |           .get(BlogPostType.REVIEW) | ||||||
|  |           .size()); | ||||||
|  | 
 | ||||||
|  |         assertEquals(1, map | ||||||
|  |           .get("Author 2") | ||||||
|  |           .get(BlogPostType.NEWS) | ||||||
|  |           .size()); | ||||||
|  |         assertEquals(1, map | ||||||
|  |           .get("Author 2") | ||||||
|  |           .get(BlogPostType.REVIEW) | ||||||
|  |           .size()); | ||||||
|  |         assertNull(map | ||||||
|  |           .get("Author 2") | ||||||
|  |           .get(BlogPostType.GUIDE)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void givenAListOfPosts_whenGroupedByTypeAndSummarizingLikes_thenGetAMapBetweenTypeAndSummary() { | ||||||
|  |         Map<BlogPostType, IntSummaryStatistics> likeStatisticsPerType = posts | ||||||
|  |           .stream() | ||||||
|  |           .collect(groupingBy(BlogPost::getType, summarizingInt(BlogPost::getLikes))); | ||||||
|  | 
 | ||||||
|  |         IntSummaryStatistics newsLikeStatistics = likeStatisticsPerType.get(BlogPostType.NEWS); | ||||||
|  | 
 | ||||||
|  |         assertEquals(2, newsLikeStatistics.getCount()); | ||||||
|  |         assertEquals(50, newsLikeStatistics.getSum()); | ||||||
|  |         assertEquals(25.0, newsLikeStatistics.getAverage(), 0.001); | ||||||
|  |         assertEquals(35, newsLikeStatistics.getMax()); | ||||||
|  |         assertEquals(15, newsLikeStatistics.getMin()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -9,7 +9,7 @@ | |||||||
|     <packaging>war</packaging> |     <packaging>war</packaging> | ||||||
| 
 | 
 | ||||||
|     <properties> |     <properties> | ||||||
|         <jersey.version>2.25</jersey.version> |         <jersey.version>2.25.1</jersey.version> | ||||||
|         <jcl.slf4j.version>1.7.22</jcl.slf4j.version> |         <jcl.slf4j.version>1.7.22</jcl.slf4j.version> | ||||||
|         <logback.version>1.1.8</logback.version> |         <logback.version>1.1.8</logback.version> | ||||||
|         <junit.version>4.12</junit.version> |         <junit.version>4.12</junit.version> | ||||||
|  | |||||||
| @ -18,7 +18,7 @@ public class RestClient { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public Employee getJsonEmployee(int id) { |     public Employee getJsonEmployee(int id) { | ||||||
|         return client.target(REST_URI).path(new Integer(id).toString()).request(MediaType.APPLICATION_JSON).get(Employee.class); |         return client.target(REST_URI).path(String.valueOf(id)).request(MediaType.APPLICATION_JSON).get(Employee.class); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public Response createXmlEmployee(Employee emp) { |     public Response createXmlEmployee(Employee emp) { | ||||||
| @ -26,6 +26,6 @@ public class RestClient { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public Employee getXmlEmployee(int id) { |     public Employee getXmlEmployee(int id) { | ||||||
|         return client.target(REST_URI).path(new Integer(id).toString()).request(MediaType.APPLICATION_XML).get(Employee.class); |         return client.target(REST_URI).path(String.valueOf(id)).request(MediaType.APPLICATION_XML).get(Employee.class); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -46,6 +46,23 @@ | |||||||
|         	<artifactId>commons-fileupload</artifactId> |         	<artifactId>commons-fileupload</artifactId> | ||||||
|         	<version>${fileupload.version}</version> |         	<version>${fileupload.version}</version> | ||||||
|         </dependency> |         </dependency> | ||||||
|  |          | ||||||
|  |          <dependency> | ||||||
|  |             <groupId>org.springframework.security</groupId> | ||||||
|  |             <artifactId>spring-security-web</artifactId> | ||||||
|  |             <version>${org.springframework.security.version}</version> | ||||||
|  |         </dependency> | ||||||
|  |         <dependency> | ||||||
|  |             <groupId>org.springframework.security</groupId> | ||||||
|  |             <artifactId>spring-security-config</artifactId> | ||||||
|  |             <version>${org.springframework.security.version}</version> | ||||||
|  |         </dependency> | ||||||
|  |         <dependency> | ||||||
|  |             <groupId>org.springframework.security</groupId> | ||||||
|  |             <artifactId>spring-security-taglibs</artifactId> | ||||||
|  |             <version>${org.springframework.security.version}</version> | ||||||
|  |         </dependency> | ||||||
|  |          | ||||||
|     </dependencies> |     </dependencies> | ||||||
|     <profiles> |     <profiles> | ||||||
|         <!-- Local --> |         <!-- Local --> | ||||||
| @ -98,6 +115,7 @@ | |||||||
|         <hibernate-validator.version>5.3.3.Final</hibernate-validator.version> |         <hibernate-validator.version>5.3.3.Final</hibernate-validator.version> | ||||||
|         <deploy-path>enter-location-of-server</deploy-path> |         <deploy-path>enter-location-of-server</deploy-path> | ||||||
| 		<fileupload.version>1.3.2</fileupload.version> | 		<fileupload.version>1.3.2</fileupload.version> | ||||||
|  | 		<org.springframework.security.version>4.2.1.RELEASE</org.springframework.security.version> | ||||||
|     </properties> |     </properties> | ||||||
| 
 | 
 | ||||||
| </project> | </project> | ||||||
|  | |||||||
| @ -0,0 +1,122 @@ | |||||||
|  | package com.baeldung.springmvcforms.configuration; | ||||||
|  | 
 | ||||||
|  | import org.springframework.beans.factory.annotation.Autowired; | ||||||
|  | import org.springframework.context.annotation.Bean; | ||||||
|  | import org.springframework.context.annotation.Configuration; | ||||||
|  | import org.springframework.core.annotation.Order; | ||||||
|  | import org.springframework.security.authentication.AuthenticationProvider; | ||||||
|  | import org.springframework.security.authentication.TestingAuthenticationProvider; | ||||||
|  | import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; | ||||||
|  | import org.springframework.security.config.annotation.web.builders.HttpSecurity; | ||||||
|  | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; | ||||||
|  | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; | ||||||
|  | import org.springframework.security.core.userdetails.User; | ||||||
|  | import org.springframework.security.core.userdetails.UserDetailsService; | ||||||
|  | import org.springframework.security.provisioning.InMemoryUserDetailsManager; | ||||||
|  | 
 | ||||||
|  | @Configuration | ||||||
|  | @EnableWebSecurity | ||||||
|  | public class SecurityConfig { | ||||||
|  | 
 | ||||||
|  |     @Bean | ||||||
|  |     public UserDetailsService userDetailsService() throws Exception { | ||||||
|  |         InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager(); | ||||||
|  |         manager.createUser(User.withUsername("user") | ||||||
|  |             .password("userPass") | ||||||
|  |             .roles("USER") | ||||||
|  |             .build()); | ||||||
|  |         manager.createUser(User.withUsername("admin") | ||||||
|  |             .password("adminPass") | ||||||
|  |             .roles("ADMIN") | ||||||
|  |             .build()); | ||||||
|  |         return manager; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Configuration | ||||||
|  |     @Order(1) | ||||||
|  |     public static class App1ConfigurationAdapter extends WebSecurityConfigurerAdapter { | ||||||
|  | 
 | ||||||
|  |         public App1ConfigurationAdapter() { | ||||||
|  |             super(); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         @Override | ||||||
|  |         protected void configure(AuthenticationManagerBuilder auth) throws Exception { | ||||||
|  |             auth.inMemoryAuthentication() | ||||||
|  |                 .withUser("admin") | ||||||
|  |                 .password("admin") | ||||||
|  |                 .roles("ADMIN"); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         @Override | ||||||
|  |         protected void configure(HttpSecurity http) throws Exception { | ||||||
|  |             http.antMatcher("/admin*") | ||||||
|  |                 .authorizeRequests() | ||||||
|  |                 .anyRequest() | ||||||
|  |                 .hasRole("ADMIN") | ||||||
|  |                 // log in | ||||||
|  |                 .and() | ||||||
|  |                 .formLogin() | ||||||
|  |                 .loginPage("/loginAdmin") | ||||||
|  |                 .loginProcessingUrl("/admin_login") | ||||||
|  |                 .failureUrl("/loginAdmin?error=loginError") | ||||||
|  |                 .defaultSuccessUrl("/adminPage") | ||||||
|  |                 // logout | ||||||
|  |                 .and() | ||||||
|  |                 .logout() | ||||||
|  |                 .logoutUrl("/admin_logout") | ||||||
|  |                 .logoutSuccessUrl("/protectedLinks") | ||||||
|  |                 .deleteCookies("JSESSIONID") | ||||||
|  |                 .and() | ||||||
|  |                 .exceptionHandling() | ||||||
|  |                 .accessDeniedPage("/403") | ||||||
|  |                 .and() | ||||||
|  |                 .csrf() | ||||||
|  |                 .disable(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Configuration | ||||||
|  |     @Order(2) | ||||||
|  |     public static class App2ConfigurationAdapter extends WebSecurityConfigurerAdapter { | ||||||
|  | 
 | ||||||
|  |         public App2ConfigurationAdapter() { | ||||||
|  |             super(); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         @Override | ||||||
|  |         protected void configure(AuthenticationManagerBuilder auth) throws Exception { | ||||||
|  |             auth.inMemoryAuthentication() | ||||||
|  |                 .withUser("user") | ||||||
|  |                 .password("user") | ||||||
|  |                 .roles("USER"); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         protected void configure(HttpSecurity http) throws Exception { | ||||||
|  |             http.antMatcher("/user*") | ||||||
|  |                 .authorizeRequests() | ||||||
|  |                 .anyRequest() | ||||||
|  |                 .hasRole("USER") | ||||||
|  |                 // log in | ||||||
|  |                 .and() | ||||||
|  |                 .formLogin() | ||||||
|  |                 .loginPage("/loginUser") | ||||||
|  |                 .loginProcessingUrl("/user_login") | ||||||
|  |                 .failureUrl("/loginUser?error=loginError") | ||||||
|  |                 .defaultSuccessUrl("/userPage") | ||||||
|  |                 // logout | ||||||
|  |                 .and() | ||||||
|  |                 .logout() | ||||||
|  |                 .logoutUrl("/user_logout") | ||||||
|  |                 .logoutSuccessUrl("/protectedLinks") | ||||||
|  |                 .deleteCookies("JSESSIONID") | ||||||
|  |                 .and() | ||||||
|  |                 .exceptionHandling() | ||||||
|  |                 .accessDeniedPage("/403") | ||||||
|  |                 .and() | ||||||
|  |                 .csrf() | ||||||
|  |                 .disable(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -3,6 +3,7 @@ package com.baeldung.springmvcforms.configuration; | |||||||
| import org.springframework.web.WebApplicationInitializer; | import org.springframework.web.WebApplicationInitializer; | ||||||
| import org.springframework.web.context.ContextLoaderListener; | import org.springframework.web.context.ContextLoaderListener; | ||||||
| import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; | import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; | ||||||
|  | import org.springframework.web.filter.DelegatingFilterProxy; | ||||||
| import org.springframework.web.servlet.DispatcherServlet; | import org.springframework.web.servlet.DispatcherServlet; | ||||||
| 
 | 
 | ||||||
| import javax.servlet.ServletContext; | import javax.servlet.ServletContext; | ||||||
| @ -24,6 +25,9 @@ public class WebInitializer implements WebApplicationInitializer { | |||||||
| 
 | 
 | ||||||
| 		servlet.setLoadOnStartup(1); | 		servlet.setLoadOnStartup(1); | ||||||
| 		servlet.addMapping("/"); | 		servlet.addMapping("/"); | ||||||
|  | 		 | ||||||
|  | 		container.addFilter("springSecurityFilterChain", new DelegatingFilterProxy("springSecurityFilterChain")) | ||||||
|  |         .addMappingForUrlPatterns(null, false, "/*"); | ||||||
| 	} | 	} | ||||||
| //	@Override | //	@Override | ||||||
| //	public void onStartup(ServletContext container) { | //	public void onStartup(ServletContext container) { | ||||||
|  | |||||||
| @ -0,0 +1,38 @@ | |||||||
|  | package com.baeldung.springmvcforms.controller; | ||||||
|  | 
 | ||||||
|  | import org.springframework.stereotype.Controller; | ||||||
|  | import org.springframework.web.bind.annotation.RequestMapping; | ||||||
|  | 
 | ||||||
|  | @Controller | ||||||
|  | public class UsersController { | ||||||
|  | 
 | ||||||
|  |     @RequestMapping("/protectedLinks") | ||||||
|  |     public String getAnonymousPage() { | ||||||
|  |         return "protectedLinks"; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @RequestMapping("/userPage") | ||||||
|  |     public String getUserPage() { | ||||||
|  |         return "userPage"; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @RequestMapping("/adminPage") | ||||||
|  |     public String getAdminPage() { | ||||||
|  |         return "adminPage"; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @RequestMapping("/loginAdmin") | ||||||
|  |     public String getAdminLoginPage() { | ||||||
|  |         return "loginAdmin"; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @RequestMapping("/loginUser") | ||||||
|  |     public String getUserLoginPage() { | ||||||
|  |         return "loginUser"; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @RequestMapping("/403") | ||||||
|  |     public String getAccessDeniedPage() { | ||||||
|  |         return "403"; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										12
									
								
								spring-mvc-forms/src/main/webapp/WEB-INF/views/403.jsp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								spring-mvc-forms/src/main/webapp/WEB-INF/views/403.jsp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,12 @@ | |||||||
|  | <%@ page language="java" contentType="text/html; charset=ISO-8859-1" | ||||||
|  |     pageEncoding="ISO-8859-1"%> | ||||||
|  | <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> | ||||||
|  | <html> | ||||||
|  | <head> | ||||||
|  | <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> | ||||||
|  | <title></title> | ||||||
|  | </head> | ||||||
|  | <body> | ||||||
|  | Your do not have permission to view this page. | ||||||
|  | </body> | ||||||
|  | </html> | ||||||
							
								
								
									
										16
									
								
								spring-mvc-forms/src/main/webapp/WEB-INF/views/adminPage.jsp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								spring-mvc-forms/src/main/webapp/WEB-INF/views/adminPage.jsp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,16 @@ | |||||||
|  | <%@ page language="java" contentType="text/html; charset=ISO-8859-1" | ||||||
|  |     pageEncoding="ISO-8859-1"%> | ||||||
|  | <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> | ||||||
|  | <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> | ||||||
|  | <html> | ||||||
|  | <head> | ||||||
|  | <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> | ||||||
|  | <title>Insert title here</title> | ||||||
|  | </head> | ||||||
|  | <body> | ||||||
|  | Welcome admin! <a href="<c:url value='/admin_logout' /> " >Logout</a> | ||||||
|  | 
 | ||||||
|  | <br /><br /> | ||||||
|  | <a href="<c:url value='/protectedLinks' /> " >Back to links</a> | ||||||
|  | </body> | ||||||
|  | </html> | ||||||
| @ -0,0 +1,38 @@ | |||||||
|  | <%@ page language="java" contentType="text/html; charset=ISO-8859-1" | ||||||
|  | 	pageEncoding="ISO-8859-1"%> | ||||||
|  | <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> | ||||||
|  | <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> | ||||||
|  | <html> | ||||||
|  | <head> | ||||||
|  | <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> | ||||||
|  | <title>Insert title here</title> | ||||||
|  | </head> | ||||||
|  | <body> | ||||||
|  | 
 | ||||||
|  |     <p>Admin login page</p> | ||||||
|  |     <form name="f" action="admin_login" method="POST"> | ||||||
|  | 
 | ||||||
|  |         <table> | ||||||
|  |             <tr> | ||||||
|  |                 <td>User:</td> | ||||||
|  |                 <td><input type="text" name="username" value=""></td> | ||||||
|  |             </tr> | ||||||
|  |             <tr> | ||||||
|  |                 <td>Password:</td> | ||||||
|  |                 <td><input type="password" name="password" /></td> | ||||||
|  |             </tr> | ||||||
|  |             <tr> | ||||||
|  |                 <td><input name="submit" type="submit" value="submit" /></td> | ||||||
|  |             </tr> | ||||||
|  |         </table> | ||||||
|  | 
 | ||||||
|  |     </form> | ||||||
|  | 
 | ||||||
|  |     <% | ||||||
|  |         if (request.getParameter("error") != null) { | ||||||
|  |             out.println("Login failed!"); | ||||||
|  |         } | ||||||
|  |     %> | ||||||
|  | 
 | ||||||
|  | </body> | ||||||
|  | </html> | ||||||
							
								
								
									
										37
									
								
								spring-mvc-forms/src/main/webapp/WEB-INF/views/loginUser.jsp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								spring-mvc-forms/src/main/webapp/WEB-INF/views/loginUser.jsp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,37 @@ | |||||||
|  | <%@ page language="java" contentType="text/html; charset=ISO-8859-1" | ||||||
|  | 	pageEncoding="ISO-8859-1"%> | ||||||
|  | <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> | ||||||
|  | <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> | ||||||
|  | <html> | ||||||
|  | <head> | ||||||
|  | <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> | ||||||
|  | <title>Login</title> | ||||||
|  | </head> | ||||||
|  | <body> | ||||||
|  | 
 | ||||||
|  |     <p>User login page</p> | ||||||
|  | 	 | ||||||
|  |     <form name="f" action="user_login" method="POST">	 | ||||||
|  |         <table> | ||||||
|  |             <tr> | ||||||
|  |                 <td>User:</td> | ||||||
|  |                 <td><input type="text" name="username" value=""></td> | ||||||
|  |             </tr> | ||||||
|  |             <tr> | ||||||
|  |                 <td>Password:</td> | ||||||
|  |                 <td><input type="password" name="password" /></td> | ||||||
|  |             </tr> | ||||||
|  |             <tr> | ||||||
|  |                 <td><input name="submit" type="submit" value="submit" /></td> | ||||||
|  |             </tr> | ||||||
|  |         </table> | ||||||
|  | 
 | ||||||
|  |     </form> | ||||||
|  |     <% | ||||||
|  |         if (request.getParameter("error") != null) { | ||||||
|  |             out.println("Login failed!"); | ||||||
|  |         } | ||||||
|  |     %> | ||||||
|  | 
 | ||||||
|  | </body> | ||||||
|  | </html> | ||||||
| @ -0,0 +1,16 @@ | |||||||
|  | <%@ page language="java" contentType="text/html; charset=ISO-8859-1" | ||||||
|  |     pageEncoding="ISO-8859-1"%> | ||||||
|  | <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> | ||||||
|  | <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> | ||||||
|  | <html> | ||||||
|  | <head> | ||||||
|  | <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> | ||||||
|  | <title>Insert title here</title> | ||||||
|  | </head> | ||||||
|  | <body> | ||||||
|  | 
 | ||||||
|  | <a href="<c:url value="/userPage" />">User page</a> | ||||||
|  | <br /> | ||||||
|  | <a href="<c:url value="/adminPage" />">Admin page</a> | ||||||
|  | </body> | ||||||
|  | </html> | ||||||
							
								
								
									
										15
									
								
								spring-mvc-forms/src/main/webapp/WEB-INF/views/userPage.jsp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								spring-mvc-forms/src/main/webapp/WEB-INF/views/userPage.jsp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,15 @@ | |||||||
|  | <%@ page language="java" contentType="text/html; charset=ISO-8859-1" | ||||||
|  |     pageEncoding="ISO-8859-1"%> | ||||||
|  | <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> | ||||||
|  | <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> | ||||||
|  | <html> | ||||||
|  | <head> | ||||||
|  | <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> | ||||||
|  | <title>Insert title here</title> | ||||||
|  | </head> | ||||||
|  | <body> | ||||||
|  | Welcome user! <a href="<c:url value='/user_logout' /> " >Logout</a> | ||||||
|  | <br /><br /> | ||||||
|  | <a href="<c:url value='/protectedLinks' /> " >Back to links</a> | ||||||
|  | </body> | ||||||
|  | </html> | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user