This commit is contained in:
Ahmed Tawila 2017-11-15 12:18:39 +02:00
commit f6bced487a
748 changed files with 8149 additions and 583 deletions

View File

@ -0,0 +1,59 @@
package com.baeldung.algorithms.prime;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class PrimeGenerator {
public static List<Integer> sieveOfEratosthenes(int n) {
final boolean prime[] = new boolean[n + 1];
Arrays.fill(prime, true);
for (int p = 2; p * p <= n; p++) {
if (prime[p]) {
for (int i = p * 2; i <= n; i += p)
prime[i] = false;
}
}
final List<Integer> primes = new LinkedList<>();
for (int i = 2; i <= n; i++) {
if (prime[i])
primes.add(i);
}
return primes;
}
public static List<Integer> primeNumbersBruteForce(int max) {
final List<Integer> primeNumbers = new LinkedList<Integer>();
for (int i = 2; i <= max; i++) {
if (isPrimeBruteForce(i)) {
primeNumbers.add(i);
}
}
return primeNumbers;
}
private static boolean isPrimeBruteForce(int x) {
for (int i = 2; i < x; i++) {
if (x % i == 0) {
return false;
}
}
return true;
}
public static List<Integer> primeNumbersTill(int max) {
return IntStream.rangeClosed(2, max)
.filter(x -> isPrime(x))
.boxed()
.collect(Collectors.toList());
}
private static boolean isPrime(int x) {
return IntStream.rangeClosed(2, (int) (Math.sqrt(x)))
.allMatch(n -> x % n != 0);
}
}

View File

@ -0,0 +1,28 @@
package com.baeldung.algorithms.prime;
import static com.baeldung.algorithms.prime.PrimeGenerator.*;
import java.util.Arrays;
import java.util.List;
import org.junit.Test;
import static org.junit.Assert.*;
public class PrimeGeneratorTest {
@Test
public void whenBruteForced_returnsSuccessfully() {
final List<Integer> primeNumbers = primeNumbersBruteForce(20);
assertEquals(Arrays.asList(new Integer[] { 2, 3, 5, 7, 11, 13, 17, 19 }), primeNumbers);
}
@Test
public void whenOptimized_returnsSuccessfully() {
final List<Integer> primeNumbers = primeNumbersTill(20);
assertEquals(Arrays.asList(new Integer[] { 2, 3, 5, 7, 11, 13, 17, 19 }), primeNumbers);
}
@Test
public void whenSieveOfEratosthenes_returnsSuccessfully() {
final List<Integer> primeNumbers = sieveOfEratosthenes(20);
assertEquals(Arrays.asList(new Integer[] { 2, 3, 5, 7, 11, 13, 17, 19 }), primeNumbers);
}
}

View File

@ -40,14 +40,14 @@ public class CasSecuredAppApplication {
@Primary
public AuthenticationEntryPoint authenticationEntryPoint(ServiceProperties sP) {
CasAuthenticationEntryPoint entryPoint = new CasAuthenticationEntryPoint();
entryPoint.setLoginUrl("https://localhost:8443/cas/login");
entryPoint.setLoginUrl("https://localhost:6443/cas/login");
entryPoint.setServiceProperties(sP);
return entryPoint;
}
@Bean
public TicketValidator ticketValidator() {
return new Cas30ServiceTicketValidator("https://localhost:8443/cas");
return new Cas30ServiceTicketValidator("https://localhost:6443/cas");
}
@Bean
@ -71,7 +71,7 @@ public class CasSecuredAppApplication {
@Bean
public LogoutFilter logoutFilter() {
LogoutFilter logoutFilter = new LogoutFilter(
"https://localhost:8443/cas/logout", securityContextLogoutHandler());
"https://localhost:6443/cas/logout", securityContextLogoutHandler());
logoutFilter.setFilterProcessesUrl("/logout/cas");
return logoutFilter;
}
@ -79,7 +79,7 @@ public class CasSecuredAppApplication {
@Bean
public SingleSignOutFilter singleSignOutFilter() {
SingleSignOutFilter singleSignOutFilter = new SingleSignOutFilter();
singleSignOutFilter.setCasServerUrlPrefix("https://localhost:8443/cas");
singleSignOutFilter.setCasServerUrlPrefix("https://localhost:6443/cas");
singleSignOutFilter.setIgnoreInitConfiguration(true);
return singleSignOutFilter;
}

Binary file not shown.

View File

@ -2,9 +2,9 @@
# CAS Server Context Configuration
#
server.context-path=/cas
server.port=8443
server.port=6443
server.ssl.key-store=file:/etc/cas/thekeystore
server.ssl.key-store=classpath:/etc/cas/thekeystore
server.ssl.key-store-password=changeit
server.ssl.key-password=changeit
# server.ssl.ciphers=
@ -40,6 +40,12 @@ spring.http.encoding.charset=UTF-8
spring.http.encoding.enabled=true
spring.http.encoding.force=true
##
#CAS CONFIG LOCATION
#
cas.standalone.config=classpath:/etc/cas/config
##
# CAS Cloud Bus Configuration
#
@ -82,6 +88,7 @@ spring.thymeleaf.mode=HTML
# CAS Log4j Configuration
#
# logging.config=file:/etc/cas/log4j2.xml
server.context-parameters.isLog4jAutoInitializationDisabled=true
##
@ -104,9 +111,10 @@ cas.authn.jdbc.query[0].dialect=org.hibernate.dialect.MySQLDialect
cas.authn.jdbc.query[0].user=root
cas.authn.jdbc.query[0].password=
cas.authn.jdbc.query[0].ddlAuto=none
cas.authn.jdbc.query[0].driverClass=com.mysql.jdbc.Driver
#cas.authn.jdbc.query[0].driverClass=com.mysql.jdbc.Driver
cas.authn.jdbc.query[0].driverClass=com.mysql.cj.jdbc.Driver
cas.authn.jdbc.query[0].fieldPassword=password
cas.authn.jdbc.query[0].passwordEncoder.type=BCRYPT
cas.authn.jdbc.query[0].passwordEncoder.type=NONE
##

View File

@ -1,16 +1,15 @@
cas.server.name: https://localhost:8443
cas.server.prefix: https://localhost:8443/cas
cas.server.name: https://localhost:6443
cas.server.prefix: https://localhost:643/cas
cas.adminPagesSecurity.ip=127\.0\.0\.1
logging.config: file:/etc/cas/config/log4j2.xml
cas.serviceRegistry.initFromJson=true
cas.serviceRegistry.config.location=classpath:/services
cas.authn.accept.users=
cas.authn.accept.name=
#CAS Database Authentication Property
# cas.authn.jdbc.query[0].healthQuery=

View File

@ -0,0 +1,2 @@
info:
description: CAS Configuration

View File

@ -0,0 +1,7 @@
cas.server.name: https://cas.example.org:8443
cas.server.prefix: https://cas.example.org:8443/cas
cas.adminPagesSecurity.ip=127\.0\.0\.1
logging.config: file:/etc/cas/config/log4j2.xml
# cas.serviceRegistry.config.location: classpath:/services

View File

@ -0,0 +1,117 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!-- Specify the refresh internal in seconds. -->
<Configuration monitorInterval="5" packages="org.apereo.cas.logging">
<Properties>
<!--
Default log directory is the current directory but that can be overridden with -Dcas.log.dir=<logdir>
Or you can change this property to a new default
-->
<Property name="cas.log.dir" >.</Property>
<!-- To see more CAS specific logging, adjust this property to info or debug or run server with -Dcas.log.leve=debug -->
<Property name="cas.log.level" >warn</Property>
</Properties>
<Appenders>
<Console name="console" target="SYSTEM_OUT">
<PatternLayout pattern="%d %p [%c] - &lt;%m&gt;%n"/>
</Console>
<RollingFile name="file" fileName="${sys:cas.log.dir}/cas.log" append="true"
filePattern="${sys:cas.log.dir}/cas-%d{yyyy-MM-dd-HH}-%i.log">
<PatternLayout pattern="%d %p [%c] - &lt;%m&gt;%n"/>
<Policies>
<OnStartupTriggeringPolicy />
<SizeBasedTriggeringPolicy size="10 MB"/>
<TimeBasedTriggeringPolicy />
</Policies>
</RollingFile>
<RollingFile name="auditlogfile" fileName="${sys:cas.log.dir}/cas_audit.log" append="true"
filePattern="${sys:cas.log.dir}/cas_audit-%d{yyyy-MM-dd-HH}-%i.log">
<PatternLayout pattern="%d %p [%c] - %m%n"/>
<Policies>
<OnStartupTriggeringPolicy />
<SizeBasedTriggeringPolicy size="10 MB"/>
<TimeBasedTriggeringPolicy />
</Policies>
</RollingFile>
<RollingFile name="perfFileAppender" fileName="${sys:cas.log.dir}/perfStats.log" append="true"
filePattern="${sys:cas.log.dir}/perfStats-%d{yyyy-MM-dd-HH}-%i.log">
<PatternLayout pattern="%m%n"/>
<Policies>
<OnStartupTriggeringPolicy />
<SizeBasedTriggeringPolicy size="10 MB"/>
<TimeBasedTriggeringPolicy />
</Policies>
</RollingFile>
<CasAppender name="casAudit">
<AppenderRef ref="auditlogfile" />
</CasAppender>
<CasAppender name="casFile">
<AppenderRef ref="file" />
</CasAppender>
<CasAppender name="casConsole">
<AppenderRef ref="console" />
</CasAppender>
<CasAppender name="casPerf">
<AppenderRef ref="perfFileAppender" />
</CasAppender>
</Appenders>
<Loggers>
<!-- If adding a Logger with level set higher than warn, make category as selective as possible -->
<!-- Loggers inherit appenders from Root Logger unless additivity is false -->
<AsyncLogger name="org.apereo" level="${sys:cas.log.level}" includeLocation="true"/>
<AsyncLogger name="org.apereo.services.persondir" level="${sys:cas.log.level}" includeLocation="true"/>
<AsyncLogger name="org.apereo.cas.web.flow" level="info" includeLocation="true"/>
<AsyncLogger name="org.apache" level="warn" />
<AsyncLogger name="org.apache.http" level="error" />
<AsyncLogger name="org.springframework" level="warn" />
<AsyncLogger name="org.springframework.cloud.server" level="warn" />
<AsyncLogger name="org.springframework.cloud.client" level="warn" />
<AsyncLogger name="org.springframework.cloud.bus" level="warn" />
<AsyncLogger name="org.springframework.aop" level="warn" />
<AsyncLogger name="org.springframework.boot" level="warn" />
<AsyncLogger name="org.springframework.boot.actuate.autoconfigure" level="warn" />
<AsyncLogger name="org.springframework.webflow" level="warn" />
<AsyncLogger name="org.springframework.session" level="warn" />
<AsyncLogger name="org.springframework.amqp" level="error" />
<AsyncLogger name="org.springframework.integration" level="warn" />
<AsyncLogger name="org.springframework.messaging" level="warn" />
<AsyncLogger name="org.springframework.web" level="warn" />
<AsyncLogger name="org.springframework.orm.jpa" level="warn" />
<AsyncLogger name="org.springframework.scheduling" level="warn" />
<AsyncLogger name="org.springframework.context.annotation" level="error" />
<AsyncLogger name="org.springframework.boot.devtools" level="error" />
<AsyncLogger name="org.springframework.web.socket" level="warn" />
<AsyncLogger name="org.thymeleaf" level="warn" />
<AsyncLogger name="org.pac4j" level="warn" />
<AsyncLogger name="org.opensaml" level="warn"/>
<AsyncLogger name="net.sf.ehcache" level="warn" />
<AsyncLogger name="com.couchbase" level="warn" includeLocation="true"/>
<AsyncLogger name="com.ryantenney.metrics" level="warn" />
<AsyncLogger name="net.jradius" level="warn" />
<AsyncLogger name="org.openid4java" level="warn" />
<AsyncLogger name="org.ldaptive" level="warn" />
<AsyncLogger name="com.hazelcast" level="warn" />
<AsyncLogger name="org.jasig.spring" level="warn" />
<!-- Log perf stats only to perfStats.log -->
<AsyncLogger name="perfStatsLogger" level="info" additivity="false" includeLocation="true">
<AppenderRef ref="casPerf"/>
</AsyncLogger>
<!-- Log audit to all root appenders, and also to audit log (additivity is not false) -->
<AsyncLogger name="org.apereo.inspektr.audit.support" level="info" includeLocation="true" >
<AppenderRef ref="casAudit"/>
</AsyncLogger>
<!-- All Loggers inherit appenders specified here, unless additivity="false" on the Logger -->
<AsyncRoot level="warn">
<AppenderRef ref="casFile"/>
<!--
For deployment to an application server running as service,
delete the casConsole appender below
-->
<AppenderRef ref="casConsole"/>
</AsyncRoot>
</Loggers>
</Configuration>

Binary file not shown.

View File

@ -0,0 +1,59 @@
package com.baeldung.prime;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class PrimeGenerator {
public static List<Integer> sieveOfEratosthenes(int n) {
final boolean prime[] = new boolean[n + 1];
Arrays.fill(prime, true);
for (int p = 2; p * p <= n; p++) {
if (prime[p]) {
for (int i = p * 2; i <= n; i += p)
prime[i] = false;
}
}
final List<Integer> primes = new LinkedList<>();
for (int i = 2; i <= n; i++) {
if (prime[i])
primes.add(i);
}
return primes;
}
public static List<Integer> primeNumbersBruteForce(int max) {
final List<Integer> primeNumbers = new LinkedList<Integer>();
for (int i = 2; i <= max; i++) {
if (isPrimeBruteForce(i)) {
primeNumbers.add(i);
}
}
return primeNumbers;
}
private static boolean isPrimeBruteForce(int x) {
for (int i = 2; i < x; i++) {
if (x % i == 0) {
return false;
}
}
return true;
}
public static List<Integer> primeNumbersTill(int max) {
return IntStream.rangeClosed(2, max)
.filter(x -> isPrime(x))
.boxed()
.collect(Collectors.toList());
}
private static boolean isPrime(int x) {
return IntStream.rangeClosed(2, (int) (Math.sqrt(x)))
.allMatch(n -> x % n != 0);
}
}

View File

@ -0,0 +1,28 @@
package com.baeldung.prime;
import static com.baeldung.prime.PrimeGenerator.*;
import java.util.Arrays;
import java.util.List;
import org.junit.Test;
import static org.junit.Assert.*;
public class PrimeGeneratorTest {
@Test
public void whenBruteForced_returnsSuccessfully() {
final List<Integer> primeNumbers = primeNumbersBruteForce(20);
assertEquals(Arrays.asList(new Integer[] { 2, 3, 5, 7, 11, 13, 17, 19 }), primeNumbers);
}
@Test
public void whenOptimized_returnsSuccessfully() {
final List<Integer> primeNumbers = primeNumbersTill(20);
assertEquals(Arrays.asList(new Integer[] { 2, 3, 5, 7, 11, 13, 17, 19 }), primeNumbers);
}
@Test
public void whenSieveOfEratosthenes_returnsSuccessfully() {
final List<Integer> primeNumbers = sieveOfEratosthenes(20);
assertEquals(Arrays.asList(new Integer[] { 2, 3, 5, 7, 11, 13, 17, 19 }), primeNumbers);
}
}

View File

@ -3,8 +3,18 @@ package com.baeldung.concurrent.daemon;
public class NewThread extends Thread {
public void run() {
while (true)
for (int i = 0; i < 10; i++)
System.out.println("New Thread is running...");
long startTime = System.currentTimeMillis();
while (true) {
for (int i = 0; i < 10; i++) {
System.out.println("New Thread is running..." + i);
}
// prevent the Thread to run forever. It will finish it's execution after 2 seconds
if (System.currentTimeMillis() - startTime > 2000) {
Thread.currentThread().interrupt();
break;
}
}
}
}

View File

@ -0,0 +1,39 @@
package com.baeldung.concurrent.executorservice;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
public class DelayedCallable implements Callable<String> {
private String name;
private long period;
private CountDownLatch latch;
public DelayedCallable(String name, long period, CountDownLatch latch) {
this(name, period);
this.latch = latch;
}
public DelayedCallable(String name, long period) {
this.name = name;
this.period = period;
}
public String call() {
try {
Thread.sleep(period);
if (latch != null) {
latch.countDown();
}
} catch (InterruptedException ex) {
// handle exception
ex.printStackTrace();
Thread.currentThread().interrupt();
}
return name;
}
}

View File

@ -3,11 +3,13 @@ package com.baeldung.concurrent.daemon;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import org.junit.Ignore;
import org.junit.Test;
public class DaemonThreadTest {
@Test
@Ignore
public void whenCallIsDaemon_thenCorrect() {
NewThread daemonThread = new NewThread();
NewThread userThread = new NewThread();
@ -20,6 +22,7 @@ public class DaemonThreadTest {
}
@Test(expected = IllegalThreadStateException.class)
@Ignore
public void givenUserThread_whenSetDaemonWhileRunning_thenIllegalThreadStateException() {
NewThread daemonThread = new NewThread();
daemonThread.start();

View File

@ -0,0 +1,215 @@
package com.baeldung.concurrent.executorservice;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.*;
import static junit.framework.TestCase.assertTrue;
import static org.junit.Assert.fail;
public class WaitingForThreadsToFinishTest {
private static final Logger LOG = LoggerFactory.getLogger(WaitingForThreadsToFinishTest.class);
private final static ExecutorService WORKER_THREAD_POOL = Executors.newFixedThreadPool(10);
public void awaitTerminationAfterShutdown(ExecutorService threadPool) {
threadPool.shutdown();
try {
if (!threadPool.awaitTermination(60, TimeUnit.SECONDS)) {
threadPool.shutdownNow();
}
} catch (InterruptedException ex) {
threadPool.shutdownNow();
Thread.currentThread().interrupt();
}
}
@Test
public void givenMultipleThreads_whenUsingCountDownLatch_thenMainShoudWaitForAllToFinish() {
ExecutorService WORKER_THREAD_POOL = Executors.newFixedThreadPool(10);
try {
long startTime = System.currentTimeMillis();
// create a CountDownLatch that waits for the 2 threads to finish
CountDownLatch latch = new CountDownLatch(2);
for (int i = 0; i < 2; i++) {
WORKER_THREAD_POOL.submit(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
latch.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
Thread.currentThread().interrupt();
}
}
});
}
// wait for the latch to be decremented by the two threads
latch.await();
long processingTime = System.currentTimeMillis() - startTime;
assertTrue(processingTime >= 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
awaitTerminationAfterShutdown(WORKER_THREAD_POOL);
}
@Test
public void givenMultipleThreads_whenInvokeAll_thenMainThreadShouldWaitForAllToFinish() {
ExecutorService WORKER_THREAD_POOL = Executors.newFixedThreadPool(10);
List<Callable<String>> callables = Arrays.asList(
new DelayedCallable("fast thread", 100),
new DelayedCallable("slow thread", 3000));
try {
long startProcessingTime = System.currentTimeMillis();
List<Future<String>> futures = WORKER_THREAD_POOL.invokeAll(callables);
awaitTerminationAfterShutdown(WORKER_THREAD_POOL);
try {
WORKER_THREAD_POOL.submit(new Callable<String>() {
@Override
public String call() throws Exception {
fail("This thread should have been rejected !");
Thread.sleep(1000000);
return null;
}
});
} catch (RejectedExecutionException ex) {
//
}
long totalProcessingTime = System.currentTimeMillis() - startProcessingTime;
assertTrue(totalProcessingTime >= 3000);
String firstThreadResponse = futures.get(0)
.get();
assertTrue("First response should be from the fast thread", "fast thread".equals(firstThreadResponse));
String secondThreadResponse = futures.get(1)
.get();
assertTrue("Last response should be from the slow thread", "slow thread".equals(secondThreadResponse));
} catch (ExecutionException | InterruptedException ex) {
ex.printStackTrace();
}
}
@Test
public void givenMultipleThreads_whenUsingCompletionService_thenMainThreadShouldWaitForAllToFinish() {
CompletionService<String> service = new ExecutorCompletionService<>(WORKER_THREAD_POOL);
List<Callable<String>> callables = Arrays.asList(
new DelayedCallable("fast thread", 100),
new DelayedCallable("slow thread", 3000));
for (Callable<String> callable : callables) {
service.submit(callable);
}
try {
long startProcessingTime = System.currentTimeMillis();
Future<String> future = service.take();
String firstThreadResponse = future.get();
long totalProcessingTime = System.currentTimeMillis() - startProcessingTime;
assertTrue("First response should be from the fast thread", "fast thread".equals(firstThreadResponse));
assertTrue(totalProcessingTime >= 100 && totalProcessingTime < 1000);
LOG.debug("Thread finished after: " + totalProcessingTime + " milliseconds");
future = service.take();
String secondThreadResponse = future.get();
totalProcessingTime = System.currentTimeMillis() - startProcessingTime;
assertTrue("Last response should be from the slow thread", "slow thread".equals(secondThreadResponse));
assertTrue(totalProcessingTime >= 3000 && totalProcessingTime < 4000);
LOG.debug("Thread finished after: " + totalProcessingTime + " milliseconds");
} catch (ExecutionException | InterruptedException ex) {
ex.printStackTrace();
} finally {
awaitTerminationAfterShutdown(WORKER_THREAD_POOL);
}
}
@Test
public void givenMultipleThreads_whenUsingCompletableFutures_thenMainThreadShouldWaitForAllToFinish() {
CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "Hello";
});
CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "Beautiful";
});
CompletableFuture<String> future3 = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "World";
});
long startProcessingTime = System.currentTimeMillis();
CompletableFuture<Void> combinedFuture = CompletableFuture.allOf(future1, future2, future3);
combinedFuture.join();
long totalProcessingTime = System.currentTimeMillis() - startProcessingTime;
assertTrue(totalProcessingTime >= 5000 && totalProcessingTime < 6000);
LOG.debug("Responses from all threads are available after " + totalProcessingTime + " milliseconds");
try {
String thread1Response = future1.get();
assertTrue(thread1Response.equals("Hello"));
String thread2Response = future2.get();
assertTrue(thread2Response.equals("Beautiful"));
String thread3Response = future3.get();
assertTrue(thread3Response.equals("World"));
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
awaitTerminationAfterShutdown(WORKER_THREAD_POOL);
}
}

View File

@ -1,24 +1,21 @@
package com.baeldung.concurrent.runnable;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import org.apache.commons.lang3.RandomUtils;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class RunnableVsThreadTest {
public class RunnableVsThreadLiveTest {
private static Logger log =
LoggerFactory.getLogger(RunnableVsThreadTest.class);
LoggerFactory.getLogger(RunnableVsThreadLiveTest.class);
private static ExecutorService executorService;
@ -77,9 +74,7 @@ public class RunnableVsThreadTest {
public void givenACallableAsLambda_whenSubmitToES_thenResult()
throws Exception {
Future<Integer> future = executorService.submit(() -> {
return RandomUtils.nextInt(0, 100);
});
Future<Integer> future = executorService.submit(() -> RandomUtils.nextInt(0, 100));
log.info("Result from callable: {}", future.get());
}
@ -99,7 +94,7 @@ class SimpleThread extends Thread{
private String message;
public SimpleThread(String message) {
SimpleThread(String message) {
this.message = message;
}
@ -116,7 +111,7 @@ class SimpleRunnable implements Runnable {
private String message;
public SimpleRunnable(String message) {
SimpleRunnable(String message) {
this.message = message;
}

View File

@ -114,4 +114,5 @@
- [StringBuilder and StringBuffer in Java](http://www.baeldung.com/java-string-builder-string-buffer)
- [Number of Digits in an Integer in Java](http://www.baeldung.com/java-number-of-digits-in-int)
- [Proxy, Decorator, Adapter and Bridge Patterns](http://www.baeldung.com/java-structural-design-patterns)
- [Creating a Java Compiler Plugin](http://www.baeldung.com/java-build-compiler-plugin)

View File

@ -216,6 +216,13 @@
<artifactId>spring-web</artifactId>
<version>4.3.4.RELEASE</version>
</dependency>
<dependency>
<groupId>com.sun</groupId>
<artifactId>tools</artifactId>
<version>1.8.0</version>
<scope>system</scope>
<systemPath>${java.home}/../lib/tools.jar</systemPath>
</dependency>
</dependencies>
<build>
@ -249,7 +256,7 @@
<exclude>**/*LongRunningUnitTest.java</exclude>
<exclude>**/*ManualTest.java</exclude>
</excludes>
<testFailureIgnore>true</testFailureIgnore>
</configuration>
</plugin>

View File

@ -0,0 +1,138 @@
package com.baeldung.breakcontinue;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
/**
* @author Santosh
*
*/
public class BreakContinue {
public static int unlabeledBreak() {
String searchName = "Wilson";
int counter = 0;
List<String> names = Arrays.asList("John", "Peter", "Robert", "Wilson", "Anthony", "Donald", "Richard");
for (String name : names) {
counter++;
if (name.equalsIgnoreCase(searchName)) {
break;
}
}
return counter;
}
public static int unlabeledBreakNestedLoops() {
String searchName = "Wilson";
int counter = 0;
Map<String, List<String>> nameMap = new HashMap<>();
nameMap.put("Grade1", Arrays.asList("John", "Peter", "Robert", "Wilson"));
nameMap.put("Grade2", Arrays.asList("Anthony", "Donald", "Richard", "Arnold"));
nameMap.put("Grade3", Arrays.asList("Wilson", "Michael", "Stephen", "Ryan"));
Iterator<Entry<String, List<String>>> iterator = nameMap.entrySet()
.iterator();
Entry<String, List<String>> entry = null;
List<String> names = null;
while (iterator.hasNext()) {
entry = iterator.next();
names = entry.getValue();
for (String name : names) {
if (name.equalsIgnoreCase(searchName)) {
counter++;
break;
}
}
}
return counter;
}
public static int labeledBreak() {
String searchName = "Wilson";
int counter = 0;
Map<String, List<String>> nameMap = new HashMap<>();
nameMap.put("Grade1", Arrays.asList("John", "Peter", "Robert", "Wilson"));
nameMap.put("Grade2", Arrays.asList("Anthony", "Donald", "Richard", "Arnold"));
nameMap.put("Grade3", Arrays.asList("Wilson", "Michael", "Stephen", "Ryan"));
Iterator<Entry<String, List<String>>> iterator = nameMap.entrySet()
.iterator();
Entry<String, List<String>> entry = null;
List<String> names = null;
compare:
while (iterator.hasNext()) {
entry = iterator.next();
names = entry.getValue();
for (String name : names) {
if (name.equalsIgnoreCase(searchName)) {
counter++;
break compare;
}
}
}
return counter;
}
public static int unlabeledContinue() {
String searchName = "Wilson";
int counter = 0;
Map<String, List<String>> nameMap = new HashMap<>();
nameMap.put("Grade1", Arrays.asList("John", "Wilson", "Robert", "Wilson"));
nameMap.put("Grade2", Arrays.asList("Anthony", "Donald", "Wilson", "Arnold"));
nameMap.put("Grade3", Arrays.asList("Wilson", "Michael", "Wilson", "Ryan"));
Iterator<Entry<String, List<String>>> iterator = nameMap.entrySet()
.iterator();
Entry<String, List<String>> entry = null;
List<String> names = null;
while (iterator.hasNext()) {
entry = iterator.next();
names = entry.getValue();
for (String name : names) {
if (!name.equalsIgnoreCase(searchName)) {
continue;
}
counter++;
}
}
return counter;
}
public static int labeledContinue() {
String searchName = "Wilson";
int counter = 0;
Map<String, List<String>> nameMap = new HashMap<>();
nameMap.put("Grade1", Arrays.asList("John", "Wilson", "Robert", "Wilson"));
nameMap.put("Grade2", Arrays.asList("Anthony", "Donald", "Wilson", "Arnold"));
nameMap.put("Grade3", Arrays.asList("Wilson", "Michael", "Wilson", "Ryan"));
Iterator<Entry<String, List<String>>> iterator = nameMap.entrySet()
.iterator();
Entry<String, List<String>> entry = null;
List<String> names = null;
compare:
while (iterator.hasNext()) {
entry = iterator.next();
names = entry.getValue();
for (String name : names) {
if (name.equalsIgnoreCase(searchName)) {
counter++;
continue compare;
}
}
}
return counter;
}
}

View File

@ -13,6 +13,8 @@ import java.util.Set;
public class EchoServer {
private static final String POISON_PILL = "POISON_PILL";
public static void main(String[] args) throws IOException {
Selector selector = Selector.open();
ServerSocketChannel serverSocket = ServerSocketChannel.open();
@ -30,23 +32,36 @@ public class EchoServer {
SelectionKey key = iter.next();
if (key.isAcceptable()) {
SocketChannel client = serverSocket.accept();
client.configureBlocking(false);
client.register(selector, SelectionKey.OP_READ);
register(selector, serverSocket);
}
if (key.isReadable()) {
SocketChannel client = (SocketChannel) key.channel();
client.read(buffer);
buffer.flip();
client.write(buffer);
buffer.clear();
answerWithEcho(buffer, key);
}
iter.remove();
}
}
}
private static void answerWithEcho(ByteBuffer buffer, SelectionKey key) throws IOException {
SocketChannel client = (SocketChannel) key.channel();
client.read(buffer);
if (new String(buffer.array()).trim().equals(POISON_PILL)) {
client.close();
System.out.println("Not accepting client messages anymore");
}
buffer.flip();
client.write(buffer);
buffer.clear();
}
private static void register(Selector selector, ServerSocketChannel serverSocket) throws IOException {
SocketChannel client = serverSocket.accept();
client.configureBlocking(false);
client.register(selector, SelectionKey.OP_READ);
}
public static Process start() throws IOException, InterruptedException {
String javaHome = System.getProperty("java.home");
String javaBin = javaHome + File.separator + "bin" + File.separator + "java";

View File

@ -0,0 +1,9 @@
package com.baeldung.javac;
import java.lang.annotation.*;
@Documented
@Retention(RetentionPolicy.CLASS)
@Target({ElementType.PARAMETER})
public @interface Positive {
}

View File

@ -0,0 +1,123 @@
package com.baeldung.javac;
import com.sun.source.tree.MethodTree;
import com.sun.source.tree.VariableTree;
import com.sun.source.util.*;
import com.sun.tools.javac.api.BasicJavacTask;
import com.sun.tools.javac.code.TypeTag;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.TreeMaker;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.Name;
import com.sun.tools.javac.util.Names;
import javax.tools.JavaCompiler;
import java.util.*;
import java.util.stream.Collectors;
import static com.sun.tools.javac.util.List.nil;
/**
* A {@link JavaCompiler javac} plugin which inserts {@code >= 0} checks into resulting {@code *.class} files
* for numeric method parameters marked by {@link Positive}
*/
public class SampleJavacPlugin implements Plugin {
public static final String NAME = "MyPlugin";
private static Set<String> TARGET_TYPES = new HashSet<>(Arrays.asList(
// Use only primitive types for simplicity
byte.class.getName(), short.class.getName(), char.class.getName(),
int.class.getName(), long.class.getName(), float.class.getName(), double.class.getName()));
@Override
public String getName() {
return NAME;
}
@Override
public void init(JavacTask task, String... args) {
Context context = ((BasicJavacTask) task).getContext();
task.addTaskListener(new TaskListener() {
@Override
public void started(TaskEvent e) {
}
@Override
public void finished(TaskEvent e) {
if (e.getKind() != TaskEvent.Kind.PARSE) {
return;
}
e.getCompilationUnit()
.accept(new TreeScanner<Void, Void>() {
@Override
public Void visitMethod(MethodTree method, Void v) {
List<VariableTree> parametersToInstrument = method.getParameters()
.stream()
.filter(SampleJavacPlugin.this::shouldInstrument)
.collect(Collectors.toList());
if (!parametersToInstrument.isEmpty()) {
// There is a possible case that more than one argument is marked by @Positive,
// as the checks are added to the method's body beginning, we process parameters RTL
// to ensure correct order.
Collections.reverse(parametersToInstrument);
parametersToInstrument.forEach(p -> addCheck(method, p, context));
}
// There is a possible case that there is a nested class declared in a method's body,
// hence, we want to proceed with method body AST as well.
return super.visitMethod(method, v);
}
}, null);
}
});
}
private boolean shouldInstrument(VariableTree parameter) {
return TARGET_TYPES.contains(parameter.getType().toString())
&& parameter.getModifiers().getAnnotations()
.stream()
.anyMatch(a -> Positive.class.getSimpleName().equals(a.getAnnotationType().toString()));
}
private void addCheck(MethodTree method, VariableTree parameter, Context context) {
JCTree.JCIf check = createCheck(parameter, context);
JCTree.JCBlock body = (JCTree.JCBlock) method.getBody();
body.stats = body.stats.prepend(check);
}
private static JCTree.JCIf createCheck(VariableTree parameter, Context context) {
TreeMaker factory = TreeMaker.instance(context);
Names symbolsTable = Names.instance(context);
return factory.at(((JCTree) parameter).pos)
.If(factory.Parens(createIfCondition(factory, symbolsTable, parameter)),
createIfBlock(factory, symbolsTable, parameter),
null);
}
private static JCTree.JCBinary createIfCondition(TreeMaker factory, Names symbolsTable, VariableTree parameter) {
Name parameterId = symbolsTable.fromString(parameter.getName().toString());
return factory.Binary(JCTree.Tag.LE,
factory.Ident(parameterId),
factory.Literal(TypeTag.INT, 0));
}
private static JCTree.JCBlock createIfBlock(TreeMaker factory, Names symbolsTable, VariableTree parameter) {
String parameterName = parameter.getName().toString();
Name parameterId = symbolsTable.fromString(parameterName);
String errorMessagePrefix = String.format("Argument '%s' of type %s is marked by @%s but got '",
parameterName, parameter.getType(), Positive.class.getSimpleName());
String errorMessageSuffix = "' for it";
return factory.Block(0, com.sun.tools.javac.util.List.of(
factory.Throw(
factory.NewClass(null, nil(),
factory.Ident(symbolsTable.fromString(IllegalArgumentException.class.getSimpleName())),
com.sun.tools.javac.util.List.of(factory.Binary(JCTree.Tag.PLUS,
factory.Binary(JCTree.Tag.PLUS, factory.Literal(TypeTag.CLASS, errorMessagePrefix),
factory.Ident(parameterId)),
factory.Literal(TypeTag.CLASS, errorMessageSuffix))), null))));
}
}

View File

@ -0,0 +1 @@
com.baeldung.javac.SampleJavacPlugin

View File

@ -0,0 +1,39 @@
package com.baeldung.breakcontinue;
import static com.baeldung.breakcontinue.BreakContinue.labeledBreak;
import static com.baeldung.breakcontinue.BreakContinue.labeledContinue;
import static com.baeldung.breakcontinue.BreakContinue.unlabeledBreak;
import static com.baeldung.breakcontinue.BreakContinue.unlabeledBreakNestedLoops;
import static com.baeldung.breakcontinue.BreakContinue.unlabeledContinue;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
public class BreakContinueTest {
@Test
public void whenUnlabeledBreak_ThenEqual() {
assertEquals(4, unlabeledBreak());
}
@Test
public void whenUnlabeledBreakNestedLoops_ThenEqual() {
assertEquals(2, unlabeledBreakNestedLoops());
}
@Test
public void whenLabeledBreak_ThenEqual() {
assertEquals(1, labeledBreak());
}
@Test
public void whenUnlabeledContinue_ThenEqual() {
assertEquals(5, unlabeledContinue());
}
@Test
public void whenLabeledContinue_ThenEqual() {
assertEquals(3, labeledContinue());
}
}

View File

@ -0,0 +1,42 @@
package com.baeldung.javac;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class SampleJavacPluginIntegrationTest {
private static final String CLASS_TEMPLATE =
"package com.baeldung.javac;\n" +
"\n" +
"public class Test {\n" +
" public static %1$s service(@Positive %1$s i) {\n" +
" return i;\n" +
" }\n" +
"}\n" +
"";
private TestCompiler compiler = new TestCompiler();
private TestRunner runner = new TestRunner();
@Test(expected = IllegalArgumentException.class)
public void givenInt_whenNegative_thenThrowsException() throws Throwable {
compileAndRun(double.class,-1);
}
@Test(expected = IllegalArgumentException.class)
public void givenInt_whenZero_thenThrowsException() throws Throwable {
compileAndRun(int.class,0);
}
@Test
public void givenInt_whenPositive_thenSuccess() throws Throwable {
assertEquals(1, compileAndRun(int.class, 1));
}
private Object compileAndRun(Class<?> argumentType, Object argument) throws Throwable {
String qualifiedClassName = "com.baeldung.javac.Test";
byte[] byteCode = compiler.compile(qualifiedClassName, String.format(CLASS_TEMPLATE, argumentType.getName()));
return runner.run(byteCode, qualifiedClassName, "service", new Class[] {argumentType}, argument);
}
}

View File

@ -0,0 +1,26 @@
package com.baeldung.javac;
import javax.tools.SimpleJavaFileObject;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URI;
/** Holds compiled byte code in a byte array */
public class SimpleClassFile extends SimpleJavaFileObject {
private ByteArrayOutputStream out;
public SimpleClassFile(URI uri) {
super(uri, Kind.CLASS);
}
@Override
public OutputStream openOutputStream() throws IOException {
return out = new ByteArrayOutputStream();
}
public byte[] getCompiledBinaries() {
return out.toByteArray();
}
}

View File

@ -0,0 +1,34 @@
package com.baeldung.javac;
import javax.tools.*;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
/** Adapts {@link SimpleClassFile} to the {@link JavaCompiler} */
public class SimpleFileManager extends ForwardingJavaFileManager<StandardJavaFileManager> {
private final List<SimpleClassFile> compiled = new ArrayList<>();
public SimpleFileManager(StandardJavaFileManager delegate) {
super(delegate);
}
@Override
public JavaFileObject getJavaFileForOutput(Location location,
String className,
JavaFileObject.Kind kind,
FileObject sibling)
{
SimpleClassFile result = new SimpleClassFile(URI.create("string://" + className));
compiled.add(result);
return result;
}
/**
* @return compiled binaries processed by the current class
*/
public List<SimpleClassFile> getCompiled() {
return compiled;
}
}

View File

@ -0,0 +1,23 @@
package com.baeldung.javac;
import javax.tools.SimpleJavaFileObject;
import java.net.URI;
/** Exposes given test source to the compiler. */
public class SimpleSourceFile extends SimpleJavaFileObject {
private final String content;
public SimpleSourceFile(String qualifiedClassName, String testSource) {
super(URI.create(String.format("file://%s%s",
qualifiedClassName.replaceAll("\\.", "/"),
Kind.SOURCE.extension)),
Kind.SOURCE);
content = testSource;
}
@Override
public CharSequence getCharContent(boolean ignoreEncodingErrors) {
return content;
}
}

View File

@ -0,0 +1,35 @@
package com.baeldung.javac;
import javax.tools.JavaCompiler;
import javax.tools.ToolProvider;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
import static java.util.Arrays.asList;
import static java.util.Collections.singletonList;
public class TestCompiler {
public byte[] compile(String qualifiedClassName, String testSource) {
StringWriter output = new StringWriter();
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
SimpleFileManager fileManager = new SimpleFileManager(compiler.getStandardFileManager(
null,
null,
null
));
List<SimpleSourceFile> compilationUnits = singletonList(new SimpleSourceFile(qualifiedClassName, testSource));
List<String> arguments = new ArrayList<>();
arguments.addAll(asList("-classpath", System.getProperty("java.class.path"),
"-Xplugin:" + SampleJavacPlugin.NAME));
JavaCompiler.CompilationTask task = compiler.getTask(output,
fileManager,
null,
arguments,
null,
compilationUnits);
task.call();
return fileManager.getCompiled().iterator().next().getCompiledBinaries();
}
}

View File

@ -0,0 +1,41 @@
package com.baeldung.javac;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class TestRunner {
public Object run(byte[] byteCode,
String qualifiedClassName,
String methodName,
Class<?>[] argumentTypes,
Object... args)
throws Throwable
{
ClassLoader classLoader = new ClassLoader() {
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
return defineClass(name, byteCode, 0, byteCode.length);
}
};
Class<?> clazz;
try {
clazz = classLoader.loadClass(qualifiedClassName);
} catch (ClassNotFoundException e) {
throw new RuntimeException("Can't load compiled test class", e);
}
Method method;
try {
method = clazz.getMethod(methodName, argumentTypes);
} catch (NoSuchMethodException e) {
throw new RuntimeException("Can't find the 'main()' method in the compiled test class", e);
}
try {
return method.invoke(null, args);
} catch (InvocationTargetException e) {
throw e.getCause();
}
}
}

View File

@ -0,0 +1,137 @@
package com.baeldung.stack;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.junit.Assert.*;
import java.util.Arrays;
import java.util.List;
import java.util.ListIterator;
import java.util.Stack;
import org.junit.Test;
public class StackUnitTest {
@Test
public void whenStackIsCreated_thenItHasSize0() {
Stack intStack = new Stack();
assertEquals(0, intStack.size());
}
@Test
public void givenEmptyStack_whenElementIsPushed_thenStackSizeisIncreased() {
Stack intStack = new Stack();
intStack.push(1);
assertEquals(1, intStack.size());
}
@Test
public void givenEmptyStack_whenMultipleElementsArePushed_thenStackSizeisIncreased() {
Stack intStack = new Stack();
List<Integer> intList = Arrays.asList(1, 2, 3, 4, 5, 6, 7);
boolean result = intStack.addAll(intList);
assertTrue(result);
assertEquals(7, intList.size());
}
@Test
public void whenElementIsPoppedFromStack_thenElementIsRemovedAndSizeChanges() {
Stack<Integer> intStack = new Stack();
intStack.push(5);
intStack.pop();
assertTrue(intStack.isEmpty());
}
@Test
public void whenElementIsPeeked_thenElementIsNotRemovedAndSizeDoesNotChange() {
Stack<Integer> intStack = new Stack();
intStack.push(5);
intStack.peek();
assertEquals(1, intStack.search(5));
assertEquals(1, intStack.size());
}
@Test
public void whenElementIsOnStack_thenSearchReturnsItsDistanceFromTheTop() {
Stack<Integer> intStack = new Stack();
intStack.push(5);
assertEquals(1, intStack.search(5));
}
@Test
public void whenElementIsOnStack_thenIndexOfReturnsItsIndex() {
Stack<Integer> intStack = new Stack();
intStack.push(5);
int indexOf = intStack.indexOf(5);
assertEquals(0, indexOf);
}
@Test
public void whenMultipleElementsAreOnStack_thenIndexOfReturnsLastElementIndex() {
Stack<Integer> intStack = new Stack();
intStack.push(5);
intStack.push(5);
intStack.push(5);
int lastIndexOf = intStack.lastIndexOf(5);
assertEquals(2, lastIndexOf);
}
@Test
public void givenElementOnStack_whenRemoveElementIsInvoked_thenElementIsRemoved() {
Stack<Integer> intStack = new Stack();
intStack.push(5);
intStack.push(5);
intStack.removeElement(5);
assertEquals(1, intStack.size());
}
@Test
public void givenElementOnStack_whenRemoveElementAtIsInvoked_thenElementIsRemoved() {
Stack<Integer> intStack = new Stack();
intStack.push(5);
intStack.push(7);
intStack.removeElementAt(1);
assertEquals(-1, intStack.search(7));
}
@Test
public void givenElementsOnStack_whenRemoveAllElementsIsInvoked_thenAllElementsAreRemoved() {
Stack<Integer> intStack = new Stack();
intStack.push(5);
intStack.push(7);
intStack.removeAllElements();
assertTrue(intStack.isEmpty());
}
@Test
public void givenElementsOnStack_whenRemoveAllIsInvoked_thenAllElementsFromCollectionAreRemoved() {
Stack<Integer> intStack = new Stack();
List<Integer> intList = Arrays.asList(1, 2, 3, 4, 5, 6, 7);
intStack.addAll(intList);
intStack.add(500);
intStack.removeAll(intList);
assertEquals(1, intStack.size());
}
@Test
public void givenElementsOnStack_whenRemoveIfIsInvoked_thenAllElementsSatysfyingConditionAreRemoved() {
Stack<Integer> intStack = new Stack();
List<Integer> intList = Arrays.asList(1, 2, 3, 4, 5, 6, 7);
intStack.addAll(intList);
intStack.removeIf(element -> element < 6);
assertEquals(2, intStack.size());
}
@Test
public void whenAnotherStackCreatedWhileTraversingStack_thenStacksAreEqual() {
Stack<Integer> intStack = new Stack<>();
List<Integer> intList = Arrays.asList(1, 2, 3, 4, 5, 6, 7);
intStack.addAll(intList);
ListIterator<Integer> it = intStack.listIterator();
Stack<Integer> result = new Stack();
while(it.hasNext()) {
result.push(it.next());
}
assertThat(result, equalTo(intStack));
}
}

View File

@ -0,0 +1,141 @@
package com.baeldung.string.formatter;
import java.util.Calendar;
import java.util.Formatter;
import java.util.GregorianCalendar;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
public class StringFormatterExampleTests {
@Test
public void givenString_whenFormatSpecifierForCalendar_thenGotExpected() {
//Syntax of Format Specifiers for Date/Time Representation
Calendar c = new GregorianCalendar(2017, 11, 10);
String s = String.format("The date is: %1$tm %1$te,%1$tY", c);
assertEquals("The date is: 12 10,2017", s);
}
@Test
public void givenString_whenGeneralConversion_thenConvertedString() {
//General Conversions
String s = String.format("The correct answer is %s", false);
assertEquals("The correct answer is false", s);
s = String.format("The correct answer is %b", null);
assertEquals("The correct answer is false", s);
s = String.format("The correct answer is %B", true);
assertEquals("The correct answer is TRUE", s);
}
@Test
public void givenString_whenCharConversion_thenConvertedString() {
//Character Conversions
String s = String.format("The correct answer is %c", 'a');
assertEquals("The correct answer is a", s);
s = String.format("The correct answer is %c", null);
assertEquals("The correct answer is null", s);
s = String.format("The correct answer is %C", 'b');
assertEquals("The correct answer is B", s);
s = String.format("The valid unicode character: %c", 0x0400);
assertTrue(Character.isValidCodePoint(0x0400));
assertEquals("The valid unicode character: Ѐ", s);
}
@Test(expected = java.util.IllegalFormatCodePointException.class)
public void givenString_whenIllegalCodePointForConversion_thenError() {
String s = String.format("The valid unicode character: %c", 0x11FFFF);
assertFalse(Character.isValidCodePoint(0x11FFFF));
assertEquals("The valid unicode character: Ā", s);
}
@Test
public void givenString_whenNumericIntegralConversion_thenConvertedString() {
//Numeric Integral Conversions
String s = String.format("The number 25 in decimal = %d", 25);
assertEquals("The number 25 in decimal = 25", s);
s = String.format("The number 25 in octal = %o", 25);
assertEquals("The number 25 in octal = 31", s);
s = String.format("The number 25 in hexadecimal = %x", 25);
assertEquals("The number 25 in hexadecimal = 19", s);
}
@Test
public void givenString_whenNumericFloatingConversion_thenConvertedString() {
//Numeric Floating-point Conversions
String s = String.format("The computerized scientific format of 10000.00 "
+ "= %e", 10000.00);
assertEquals("The computerized scientific format of 10000.00 = 1.000000e+04", s);
s = String.format("The decimal format of 10.019 = %f", 10.019);
assertEquals("The decimal format of 10.019 = 10.019000", s);
}
@Test
public void givenString_whenLineSeparatorConversion_thenConvertedString() {
//Line Separator Conversion
String s = String.format("First Line %nSecond Line");
assertEquals("First Line \n"
+ "Second Line", s);
}
@Test
public void givenString_whenSpecifyFlag_thenGotFormattedString() {
//Without left-justified flag
String s = String.format("Without left justified flag: %5d", 25);
assertEquals("Without left justified flag: 25", s);
//Using left-justified flag
s = String.format("With left justified flag: %-5d", 25);
assertEquals("With left justified flag: 25 ", s);
}
@Test
public void givenString_whenSpecifyPrecision_thenGotExpected() {
//Precision
String s = String.format("Output of 25.09878 with Precision 2: %.2f", 25.09878);
assertEquals("Output of 25.09878 with Precision 2: 25.10", s);
s = String.format("Output of general conversion type with Precision 2: %.2b", true);
assertEquals("Output of general conversion type with Precision 2: tr", s);
}
@Test
public void givenString_whenSpecifyArgumentIndex_thenGotExpected() {
Calendar c = new GregorianCalendar(2017, 11, 10);
//Argument_Index
String s = String.format("The date is: %1$tm %1$te,%1$tY", c);
assertEquals("The date is: 12 10,2017", s);
s = String.format("The date is: %1$tm %<te,%<tY", c);
assertEquals("The date is: 12 10,2017", s);
}
@Test
public void givenAppendable_whenCreateFormatter_thenFormatterWorksOnAppendable() {
//Using String Formatter with Appendable
StringBuilder sb = new StringBuilder();
Formatter formatter = new Formatter(sb);
formatter.format("I am writting to a %1$s Instance.", sb.getClass());
assertEquals("I am writting to a class java.lang.StringBuilder Instance.", sb.toString());
}
@Test
public void givenString_whenNoArguments_thenExpected() {
//Using String Formatter without arguments
String s = String.format("John scored 90%% in Fall semester");
assertEquals("John scored 90% in Fall semester", s);
}
}

View File

@ -0,0 +1,43 @@
package com.baeldung.stringpool;
import org.junit.Test;
import static org.assertj.core.api.Assertions.*;
public class StringPoolUnitTest {
@Test
public void whenCreatingConstantStrings_thenTheirAddressesAreEqual() {
String constantString1 = "Baeldung";
String constantString2 = "Baeldung";
assertThat(constantString1).isSameAs(constantString2);
}
@Test
public void whenCreatingStringsWithTheNewOperator_thenTheirAddressesAreDifferent() {
String newString1 = new String("Baeldung");
String newString2 = new String("Baeldung");
assertThat(newString1).isNotSameAs(newString2);
}
@Test
public void whenComparingConstantAndNewStrings_thenTheirAddressesAreDifferent() {
String constantString = "Baeldung";
String newString = new String("Baeldung");
assertThat(constantString).isNotSameAs(newString);
}
@Test
public void whenInterningAStringWithIdenticalValueToAnother_thenTheirAddressesAreEqual() {
String constantString = "interned Baeldung";
String newString = new String("interned Baeldung");
assertThat(constantString).isNotSameAs(newString);
String internedString = newString.intern();
assertThat(constantString).isSameAs(internedString);
}
}

View File

@ -15,5 +15,6 @@
- [Data Classes in Kotlin](http://www.baeldung.com/kotlin-data-classes)
- [Delegated Properties in Kotlin](http://www.baeldung.com/kotlin-delegated-properties)
- [Sealed Classes in Kotlin](http://www.baeldung.com/kotlin-sealed-classes)
- [JUnit 5 for Kotlin Developers](http://www.baeldung.com/junit-5-kotlin)

View File

@ -1,4 +1,3 @@
### Relevant Articles:
- [Introduction to Drools](http://www.baeldung.com/drools)
- [Drools Using Rules from Excel Files](http://www.baeldung.com/drools-excel)
- [Drools Using Rules from Excel Files](http://www.baeldung.com/drools-excel)

View File

@ -1,38 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>drools-backward-chaining</artifactId>
<version>1.0</version>
<name>drools-backward-chaining</name>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-modules</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<properties>
<runtime.version>6.4.0.Final</runtime.version>
</properties>
<dependencies>
<dependency>
<groupId>org.kie</groupId>
<artifactId>kie-api</artifactId>
<version>${runtime.version}</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-core</artifactId>
<version>${runtime.version}</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-decisiontables</artifactId>
<version>${runtime.version}</version>
</dependency>
</dependencies>
</project>

View File

@ -1,28 +0,0 @@
package com.baeldung;
import org.kie.api.KieServices;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
import com.baeldung.model.Beatle;
public class BackwardChainingBeatles {
public static void main(String[] args) {
KieServices ks = KieServices.Factory.get();
KieContainer kContainer = ks.getKieClasspathContainer();
KieSession kSession = kContainer.newKieSession("ksession-backward-chaining");
// drools session base on the xml configuration (<strong>kmodule.xml</strong>)
// graph population
kSession.insert(new Beatle("Starr", "drums"));
kSession.insert(new Beatle("McCartney", "bass"));
kSession.insert(new Beatle("Lennon", "guitar"));
kSession.insert(new Beatle("Harrison", "guitar"));
kSession.insert("Ringo"); // invoke the rule that calls the query implentation of backward chaining
kSession.fireAllRules(); // invoke all the rules
}
}

View File

@ -1,33 +0,0 @@
package com.baeldung.model;
import org.kie.api.definition.type.Position;
public class Beatle {
@Position(0)
private String lastName;
@Position(1)
private String instrument;
public Beatle(String lastName, String instrument) {
this.lastName = lastName;
this.instrument = instrument;
}
public String getInstrument() {
return instrument;
}
public void setInstrument(String instrument) {
this.instrument = instrument;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}

View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<kmodule xmlns="http://jboss.org/kie/6.0.0/kmodule">
<kbase name="backward_chaining" packages="backward_chaining">
<ksession name="ksession-backward-chaining"/>
</kbase>
</kmodule>

View File

@ -1,44 +0,0 @@
package com.baeldung
import com.baeldung.model.Beatle;
query whichBeatle(String lastName, String instrument)
Beatle(lastName, instrument;)
or
(Beatle(lastName, null;)
and
whichBeatle(null, instrument;)) //recursive call to the function that allows to search in a derivation tree structure
end
rule "Ringo"
when
String(this == "Ringo")
whichBeatle("Starr", "drums";)
then
System.out.println("The beatle is Ringo Starr");
end
rule "Paul"
when
String(this == "Paul")
whichBeatle("McCartney", "bass";)
then
System.out.println("The beatle is Paul McCartney");
end
rule "John"
when
String(this == "John")
whichBeatle("Lennon", "guitar";)
then
System.out.println("The beatle is John Lennon");
end
rule "George"
when
String(this == "George")
whichBeatle("Harrison", "guitar";)
then
System.out.println("The beatle is George Harrison");
end

View File

@ -1,71 +1,68 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.baeldung</groupId>
<artifactId>drools</artifactId>
<version>1.0.0-SNAPSHOT</version>
<artifactId>drools</artifactId>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-modules</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-modules</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<properties>
<http-component-version>4.4.6</http-component-version>
<drools-version>7.4.1.Final</drools-version>
<apache-poi-version>3.13</apache-poi-version>
</properties>
<properties>
<http-component-version>4.4.6</http-component-version>
<drools-version>7.1.0.Beta2</drools-version>
<apache-poi-version>3.13</apache-poi-version>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
<version>${http-component-version}</version>
</dependency>
<!-- ... -->
<dependency>
<groupId>org.kie</groupId>
<artifactId>kie-ci</artifactId>
<version>${drools-version}</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-decisiontables</artifactId>
<version>${drools-version}</version>
</dependency>
<dependencies>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
<version>${http-component-version}</version>
</dependency>
<!-- ... -->
<dependency>
<groupId>org.kie</groupId>
<artifactId>kie-ci</artifactId>
<version>${drools-version}</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-decisiontables</artifactId>
<version>${drools-version}</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-core</artifactId>
<version>${drools-version}</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-compiler</artifactId>
<version>${drools-version}</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>${apache-poi-version}</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-core</artifactId>
<version>${drools-version}</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-compiler</artifactId>
<version>${drools-version}</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>${apache-poi-version}</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>${apache-poi-version}</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>${apache-poi-version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.6.RELEASE</version>
</dependency>
</dependencies>
</dependencies>
</project>
</project>

View File

@ -0,0 +1,30 @@
package com.baeldung.drools.backward_chaining;
import org.kie.api.runtime.KieSession;
import com.baeldung.drools.config.DroolsBeanFactory;
import com.baeldung.drools.model.Fact;
import com.baeldung.drools.model.Result;
public class BackwardChaining {
public static void main(String[] args) {
Result result = new BackwardChaining().backwardChaining();
System.out.println(result.getValue());
result.getFacts()
.stream()
.forEach(System.out::println);
}
public Result backwardChaining() {
Result result = new Result();
KieSession ksession = new DroolsBeanFactory().getKieSession();
ksession.setGlobal("result", result);
ksession.insert(new Fact("Asia", "Planet Earth"));
ksession.insert(new Fact("China", "Asia"));
ksession.insert(new Fact("Great Wall of China", "China"));
ksession.fireAllRules();
return result;
}
}

View File

@ -3,7 +3,6 @@ package com.baeldung.drools.config;
import org.drools.decisiontable.DecisionTableProviderImpl;
import org.kie.api.KieServices;
import org.kie.api.builder.*;
import org.kie.api.io.KieResources;
import org.kie.api.io.Resource;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
@ -22,7 +21,7 @@ public class DroolsBeanFactory {
private KieFileSystem getKieFileSystem() throws IOException{
KieFileSystem kieFileSystem = kieServices.newKieFileSystem();
List<String> rules=Arrays.asList("SuggestApplicant.drl","Product_rules.xls");
List<String> rules=Arrays.asList("BackwardChaining.drl","SuggestApplicant.drl","Product_rules.xls");
for(String rule:rules){
kieFileSystem.write(ResourceFactory.newClassPathResource(rule));
}
@ -56,9 +55,11 @@ public class DroolsBeanFactory {
getKieRepository();
KieFileSystem kieFileSystem = kieServices.newKieFileSystem();
kieFileSystem.write(ResourceFactory.newClassPathResource("com/baeldung/drools/rules/BackwardChaining.drl"));
kieFileSystem.write(ResourceFactory.newClassPathResource("com/baeldung/drools/rules/SuggestApplicant.drl"));
kieFileSystem.write(ResourceFactory.newClassPathResource("com/baeldung/drools/rules/Product_rules.xls"));
KieBuilder kb = kieServices.newKieBuilder(kieFileSystem);
kb.buildAll();
KieModule kieModule = kb.getKieModule();

View File

@ -0,0 +1,69 @@
package com.baeldung.drools.model;
import org.kie.api.definition.type.Position;
public class Fact {
@Position(0)
private String element;
@Position(1)
private String place;
public Fact(String element, String place) {
this.element = element;
this.place = place;
}
public String getElement() {
return element;
}
public void setElement(String element) {
this.element = element;
}
public String getPlace() {
return place;
}
public void setPlace(String place) {
this.place = place;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((element == null) ? 0 : element.hashCode());
result = prime * result + ((place == null) ? 0 : place.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Fact other = (Fact) obj;
if (element == null) {
if (other.element != null)
return false;
} else if (!element.equals(other.element))
return false;
if (place == null) {
if (other.place != null)
return false;
} else if (!place.equals(other.place))
return false;
return true;
}
@Override
public String toString() {
return "Fact{" + "element='" + element + '\'' + ", place='" + place + '\'' + '}';
}
}

View File

@ -0,0 +1,31 @@
package com.baeldung.drools.model;
import java.util.ArrayList;
import java.util.List;
public class Result {
private String value;
private List<String> facts = new ArrayList<>();
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public List<String> getFacts() {
return facts;
}
public void setFacts(List<String> facts) {
this.facts = facts;
}
public void addFact(String fact) {
this.facts.add(fact);
}
}

View File

@ -0,0 +1,27 @@
package com.baeldung.drools.rules
import com.baeldung.drools.model.Fact;
global com.baeldung.drools.model.Result result;
dialect "mvel"
query belongsTo(String x, String y)
Fact(x, y;)
or
(Fact(z, y;) and belongsTo(x, z;))
end
rule "Great Wall of China BELONGS TO Planet Earth"
when
belongsTo("Great Wall of China", "Planet Earth";)
then
result.setValue("Decision one taken: Great Wall of China BELONGS TO Planet Earth");
end
rule "print all facts"
when
belongsTo(element, place;)
then
result.addFact(element + " IS ELEMENT OF " + place);
end

View File

@ -0,0 +1,36 @@
package com.baeldung.drools.backward_chaining;
import org.junit.Before;
import org.junit.Test;
import org.kie.api.runtime.KieSession;
import com.baeldung.drools.config.DroolsBeanFactory;
import com.baeldung.drools.model.Fact;
import com.baeldung.drools.model.Result;
import static junit.framework.TestCase.assertEquals;
public class BackwardChainingTest {
private Result result;
private KieSession ksession;
@Before
public void before() {
result = new Result();
ksession = new DroolsBeanFactory().getKieSession();
}
@Test
public void whenWallOfChinaIsGiven_ThenItBelongsToPlanetEarth() {
ksession.setGlobal("result", result);
ksession.insert(new Fact("Asia", "Planet Earth"));
ksession.insert(new Fact("China", "Asia"));
ksession.insert(new Fact("Great Wall of China", "China"));
ksession.fireAllRules();
// Assert Decision one
assertEquals(result.getValue(), "Decision one taken: Great Wall of China BELONGS TO Planet Earth");
}
}

View File

@ -1,5 +1,6 @@
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import javax.ejb.EJB;
@ -15,7 +16,6 @@ import wildfly.beans.UserBeanLocal;
* Servlet implementation class TestEJBServlet
*/
public class TestEJBServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@EJB
private UserBeanLocal userBean;
@ -23,8 +23,19 @@ public class TestEJBServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
List<User> users = userBean.getUsers();
response.getWriter()
.append("The number of users is: " + users.size());
PrintWriter out = response.getWriter();
out.println("<html>");
out.println("<head><title>Users</title></head>");
out.println("<body>");
out.println("<center><h1>List of users:</h1>");
out.println("<table border=\"1\" align=\"center\" style=\"width:50%\">");
for (User user : users) {
out.println("<tr>");
out.print("<td>" + user.getUsername() + "</td>");
out.print("<td>" + user.getEmail() + "</td>");
out.println("</tr>");
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

3
guava-modules/README.md Normal file
View File

@ -0,0 +1,3 @@
## Guava Modules

View File

@ -4,13 +4,14 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.baeldung</groupId>
<artifactId>guava18</artifactId>
<artifactId>guava-18</artifactId>
<version>0.1.0-SNAPSHOT</version>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-modules</artifactId>
<version>1.0.0-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<dependencies>

View File

@ -4,13 +4,14 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.baeldung</groupId>
<artifactId>guava19</artifactId>
<artifactId>guava-19</artifactId>
<version>0.1.0-SNAPSHOT</version>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-modules</artifactId>
<version>1.0.0-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<dependencies>

View File

@ -4,13 +4,14 @@
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>guava21</artifactId>
<artifactId>guava-21</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-modules</artifactId>
<version>1.0.0-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<dependencies>

View File

@ -0,0 +1,17 @@
## Building
To build the module, use Maven's `package` goal:
```
mvn clean package
```
## Running
To run the application, use Spring Boot's `run` goal:
```
mvn spring-boot:run
```
The application will be accessible at [http://localhost:8080/](http://localhost:8080/)

View File

@ -3,7 +3,7 @@
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>
<groupId>com.forketyfork.guest</groupId>
<groupId>com.stackify.guest</groupId>
<artifactId>spring-mvc</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>

View File

@ -1,11 +1,11 @@
package com.forketyfork.guest.springmvc;
package com.stackify.guest.springmvc;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.boot.SpringApplication;
@SpringBootApplication
@ComponentScan(basePackages = {"com.forketyfork.guest.springmvc"})
@ComponentScan(basePackages = {"com.stackify.guest.springmvc"})
public class Spring5Application {
public static void main(String[] args) {

View File

@ -1,4 +1,4 @@
package com.forketyfork.guest.springmvc.model;
package com.stackify.guest.springmvc.model;
public class LoginData {

View File

@ -1,6 +1,5 @@
package com.forketyfork.guest.springmvc.web;
package com.stackify.guest.springmvc.web;
import com.forketyfork.guest.springmvc.model.LoginData;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
@ -8,6 +7,8 @@ import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import com.stackify.guest.springmvc.model.LoginData;
import java.util.Collections;
@Controller

View File

@ -1,4 +1,4 @@
package com.forketyfork.guest.springmvc.web;
package com.stackify.guest.springmvc.web;
public class MyInputResource {

View File

@ -1,4 +1,4 @@
package com.forketyfork.guest.springmvc.web;
package com.stackify.guest.springmvc.web;
public class MyOutputResource {

View File

@ -1,4 +1,4 @@
package com.forketyfork.guest.springmvc.web;
package com.stackify.guest.springmvc.web;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

View File

@ -0,0 +1,17 @@
## Building
To build the module, use Maven's `package` goal:
```
mvn clean package
```
## Running
To run the application, use Spring Boot's `run` goal:
```
mvn spring-boot:run
```
The application will be accessible at [http://localhost:8080/](http://localhost:8080/)

View File

@ -0,0 +1,77 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.stackify.guest</groupId>
<artifactId>spring-security</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.M6</version>
<relativePath/>
</parent>
<name>spring-security</name>
<description>Spring Security Sample Project</description>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring5</artifactId>
<version>3.0.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
</project>

View File

@ -0,0 +1,15 @@
package com.stackify.guest.springsecurity;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
@SpringBootApplication
@ComponentScan(basePackages = {"com.stackify.guest.springsecurity"})
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}

View File

@ -0,0 +1,16 @@
package com.stackify.guest.springsecurity.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebMvcConfiguration implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/customLogin").setViewName("customLogin");
registry.addViewController("/loginSuccess").setViewName("index");
}
}

View File

@ -0,0 +1,40 @@
package com.stackify.guest.springsecurity.config;
import org.springframework.context.annotation.Bean;
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.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.JdbcUserDetailsManager;
import javax.sql.DataSource;
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
public UserDetailsService jdbcUserDetailsService(DataSource dataSource) {
JdbcUserDetailsManager manager = new JdbcUserDetailsManager();
manager.setDataSource(dataSource);
return manager;
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/css/**").permitAll()
.anyRequest().authenticated()
.and().formLogin()
.loginPage("/customLogin")
.defaultSuccessUrl("/loginSuccess", true)
.permitAll();
}
}

View File

@ -0,0 +1,2 @@
INSERT INTO users VALUES ('jill', '$2a$04$qUlqAEEYF1YvrpJMosodoewgL6aO.qgHytl2k5L7kdXEWnJsFdxvq', TRUE);
INSERT INTO authorities VALUES ('jill', 'USERS');

View File

@ -0,0 +1,10 @@
CREATE TABLE users (
username VARCHAR(256) PRIMARY KEY,
password VARCHAR(256),
enabled BOOLEAN
);
CREATE TABLE authorities (
username VARCHAR(256) REFERENCES users (username),
authority VARCHAR(256)
);

Some files were not shown because too many files have changed in this diff Show More