+ * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + *
+ * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.iluwatar.balking; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +/** + * In Balking Design Pattern if an object’s method is invoked when it is in an inappropriate state, + * then the method will return without doing anything. Objects that use this pattern are generally only in a + * state that is prone to balking temporarily but for an unknown amount of time + * + * In this example implementation WashingMachine is an object that has two states + * in which it can be: ENABLED and WASHING. If the machine is ENABLED + * the state is changed into WASHING that any other thread can't invoke this action on this and then do the job. + * On the other hand if it have been already washing and any other thread execute wash() + * it can't do that once again and returns doing nothing. + */ + +public class App { + + private static final Logger LOGGER = LoggerFactory.getLogger(App.class); + + /** + * @param args the command line arguments - not used + */ + public static void main(String... args) { + final WashingMachine washingMachine = new WashingMachine(); + ExecutorService executorService = Executors.newFixedThreadPool(3); + for (int i = 0; i < 3; i++) { + executorService.execute(washingMachine::wash); + } + executorService.shutdown(); + try { + executorService.awaitTermination(10, TimeUnit.SECONDS); + } catch (InterruptedException ie) { + LOGGER.error("ERROR: Waiting on executor service shutdown!"); + } + } + +} diff --git a/balking/src/main/java/com/iluwatar/balking/WashingMachine.java b/balking/src/main/java/com/iluwatar/balking/WashingMachine.java new file mode 100644 index 000000000..e4f1259ad --- /dev/null +++ b/balking/src/main/java/com/iluwatar/balking/WashingMachine.java @@ -0,0 +1,76 @@ +/** + * The MIT License + * Copyright (c) 2014 Ilkka Seppälä + *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + *
+ * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.iluwatar.balking; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Washing machine class + */ +public class WashingMachine { + + private static final Logger LOGGER = LoggerFactory.getLogger(WashingMachine.class); + + private WashingMachineState washingMachineState; + + public WashingMachine() { + washingMachineState = WashingMachineState.ENABLED; + } + + public WashingMachineState getWashingMachineState() { + return washingMachineState; + } + + /** + * Method responsible for washing + * if the object is in appropriate state + */ + public void wash() { + synchronized (this) { + LOGGER.info("{}: Actual machine state: {}", Thread.currentThread().getName(), getWashingMachineState()); + if (washingMachineState == WashingMachineState.WASHING) { + LOGGER.error("ERROR: Cannot wash if the machine has been already washing!"); + return; + } + washingMachineState = WashingMachineState.WASHING; + } + LOGGER.info("{}: Doing the washing", Thread.currentThread().getName()); + try { + Thread.sleep(50); + } catch (InterruptedException ie) { + ie.printStackTrace(); + } + endOfWashing(); + } + + /** + * Method responsible of ending the washing + * by changing machine state + */ + public synchronized void endOfWashing() { + washingMachineState = WashingMachineState.ENABLED; + LOGGER.info("{}: Washing completed.", Thread.currentThread().getId()); + } + +} diff --git a/balking/src/main/java/com/iluwatar/balking/WashingMachineState.java b/balking/src/main/java/com/iluwatar/balking/WashingMachineState.java new file mode 100644 index 000000000..40a5b2f38 --- /dev/null +++ b/balking/src/main/java/com/iluwatar/balking/WashingMachineState.java @@ -0,0 +1,32 @@ +/** + * The MIT License + * Copyright (c) 2014 Ilkka Seppälä + *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + *
+ * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.iluwatar.balking; + +/** + * WashingMachineState enum describes in which state machine is, + * it can be enabled and ready to work as well as during washing + */ + +public enum WashingMachineState { + ENABLED, WASHING +} diff --git a/balking/src/test/java/com/iluwatar/balking/AppTest.java b/balking/src/test/java/com/iluwatar/balking/AppTest.java new file mode 100644 index 000000000..df104b901 --- /dev/null +++ b/balking/src/test/java/com/iluwatar/balking/AppTest.java @@ -0,0 +1,39 @@ +/** + * The MIT License + * Copyright (c) 2014 Ilkka Seppälä + *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + *
+ * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package com.iluwatar.balking; + +import org.junit.Test; + +/** + * Application test + */ +public class AppTest { + + @Test + public void main() throws Exception { + String[] args = {}; + App.main(args); + } + +} \ No newline at end of file diff --git a/balking/src/test/java/com/iluwatar/balking/WashingMachineTest.java b/balking/src/test/java/com/iluwatar/balking/WashingMachineTest.java new file mode 100644 index 000000000..ecf81f409 --- /dev/null +++ b/balking/src/test/java/com/iluwatar/balking/WashingMachineTest.java @@ -0,0 +1,65 @@ +/** + * The MIT License + * Copyright (c) 2014 Ilkka Seppälä + *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + *
+ * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package com.iluwatar.balking;
+
+import org.junit.Test;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+import static org.junit.Assert.*;
+
+/**
+ * Tests for {@link WashingMachine}
+ */
+public class WashingMachineTest {
+
+ private volatile WashingMachineState machineStateGlobal;
+
+ @Test
+ public void wash() throws Exception {
+ WashingMachine washingMachine = new WashingMachine();
+ ExecutorService executorService = Executors.newFixedThreadPool(2);
+ executorService.execute(washingMachine::wash);
+ executorService.execute(() -> {
+ washingMachine.wash();
+ machineStateGlobal = washingMachine.getWashingMachineState();
+ });
+ executorService.shutdown();
+ try {
+ executorService.awaitTermination(10, TimeUnit.SECONDS);
+ } catch (InterruptedException ie) {
+ ie.printStackTrace();
+ }
+ assertEquals(WashingMachineState.WASHING, machineStateGlobal);
+ }
+
+ @Test
+ public void endOfWashing() throws Exception {
+ WashingMachine washingMachine = new WashingMachine();
+ washingMachine.wash();
+ assertEquals(WashingMachineState.ENABLED, washingMachine.getWashingMachineState());
+ }
+
+}
\ No newline at end of file
diff --git a/bridge/pom.xml b/bridge/pom.xml
index ec04ff395..7c60f8ef8 100644
--- a/bridge/pom.xml
+++ b/bridge/pom.xml
@@ -29,7 +29,7 @@
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package com.iluwatar.converter;
+
+
+import com.google.common.collect.Lists;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * The Converter pattern is a behavioral design pattern which allows a common way of bidirectional
+ * conversion between corresponding types (e.g. DTO and domain representations of the logically
+ * isomorphic types). Moreover, the pattern introduces a common way of converting a collection of
+ * objects between types.
+ */
+public class App {
+ /**
+ * Program entry point
+ *
+ * @param args command line args
+ */
+ public static void main(String[] args) {
+ Converter
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.iluwatar.converter;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+/**
+ * Generic converter, thanks to Java8 features not only provides a way of generic bidirectional
+ * conversion between coresponding types, but also a common way of converting a collection of objects
+ * of the same type, reducing boilerplate code to the absolute minimum.
+ * @param
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.iluwatar.converter;
+
+import java.util.Objects;
+
+/**
+ * User class
+ */
+public class User {
+ private String firstName;
+ private String lastName;
+ private boolean isActive;
+ private String userId;
+
+ /**
+ * @param firstName user's first name
+ * @param lastName user's last name
+ * @param isActive flag indicating whether the user is active
+ * @param userId user's identificator
+ */
+ public User(String firstName, String lastName, boolean isActive, String userId) {
+ this.firstName = firstName;
+ this.lastName = lastName;
+ this.isActive = isActive;
+ this.userId = userId;
+ }
+
+ public String getFirstName() {
+ return firstName;
+ }
+
+ public String getLastName() {
+ return lastName;
+ }
+
+ public boolean isActive() {
+ return isActive;
+ }
+
+ public String getUserId() {
+ return userId;
+ }
+
+ @Override public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ User user = (User) o;
+ return isActive == user.isActive && Objects.equals(firstName, user.firstName) && Objects
+ .equals(lastName, user.lastName) && Objects.equals(userId, user.userId);
+ }
+
+ @Override public int hashCode() {
+ return Objects.hash(firstName, lastName, isActive, userId);
+ }
+
+ @Override public String toString() {
+ return "User{" + "firstName='" + firstName + '\'' + ", lastName='" + lastName + '\''
+ + ", isActive=" + isActive + ", userId='" + userId + '\'' + '}';
+ }
+}
diff --git a/converter/src/main/java/com/iluwatar/converter/UserConverter.java b/converter/src/main/java/com/iluwatar/converter/UserConverter.java
new file mode 100644
index 000000000..9ef1d03c2
--- /dev/null
+++ b/converter/src/main/java/com/iluwatar/converter/UserConverter.java
@@ -0,0 +1,40 @@
+/**
+ * The MIT License
+ * Copyright (c) 2014-2016 Ilkka Seppälä
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.iluwatar.converter;
+
+/**
+ * Example implementation of the simple User converter.
+ */
+public class UserConverter extends Converter
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.iluwatar.converter;
+
+
+import java.util.Objects;
+
+/**
+ * User DTO class
+ */
+public class UserDto {
+
+ private String firstName;
+ private String lastName;
+ private boolean isActive;
+ private String email;
+
+ /**
+ * @param firstName user's first name
+ * @param lastName user's last name
+ * @param isActive flag indicating whether the user is active
+ * @param email user's email address
+ */
+ public UserDto(String firstName, String lastName, boolean isActive, String email) {
+ this.firstName = firstName;
+ this.lastName = lastName;
+ this.isActive = isActive;
+ this.email = email;
+ }
+
+ public String getFirstName() {
+ return firstName;
+ }
+
+ public String getLastName() {
+ return lastName;
+ }
+
+ public boolean isActive() {
+ return isActive;
+ }
+
+ public String getEmail() {
+ return email;
+ }
+
+ @Override public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ UserDto userDto = (UserDto) o;
+ return isActive == userDto.isActive && Objects.equals(firstName, userDto.firstName) && Objects
+ .equals(lastName, userDto.lastName) && Objects.equals(email, userDto.email);
+ }
+
+ @Override public int hashCode() {
+ return Objects.hash(firstName, lastName, isActive, email);
+ }
+
+ @Override public String toString() {
+ return "UserDto{" + "firstName='" + firstName + '\'' + ", lastName='" + lastName + '\''
+ + ", isActive=" + isActive + ", email='" + email + '\'' + '}';
+ }
+}
diff --git a/converter/src/test/java/com/iluwatar/converter/AppTest.java b/converter/src/test/java/com/iluwatar/converter/AppTest.java
new file mode 100644
index 000000000..091fbe2ca
--- /dev/null
+++ b/converter/src/test/java/com/iluwatar/converter/AppTest.java
@@ -0,0 +1,38 @@
+/**
+ * The MIT License
+ * Copyright (c) 2014-2016 Ilkka Seppälä
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package com.iluwatar.converter;
+
+import org.junit.Test;
+
+/**
+ * App running test
+ */
+public class AppTest {
+
+ @Test
+ public void testMain() {
+ String[] args = {};
+ App.main(args);
+ }
+
+}
diff --git a/converter/src/test/java/com/iluwatar/converter/ConverterTest.java b/converter/src/test/java/com/iluwatar/converter/ConverterTest.java
new file mode 100644
index 000000000..9fc2e2a0c
--- /dev/null
+++ b/converter/src/test/java/com/iluwatar/converter/ConverterTest.java
@@ -0,0 +1,84 @@
+/**
+ * The MIT License
+ * Copyright (c) 2014 Ilkka Seppälä
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package com.iluwatar.converter;
+
+import com.google.common.collect.Lists;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+
+import static junit.framework.TestCase.assertEquals;
+
+/**
+ * Tests for {@link Converter}
+ */
+public class ConverterTest {
+
+ private UserConverter userConverter = new UserConverter();
+
+ /**
+ * Tests whether a converter created of opposite functions holds equality as a bijection.
+ */
+ @Test public void testConversionsStartingFromDomain() {
+ User u1 = new User("Tom", "Hanks", true, "tom@hanks.com");
+ User u2 = userConverter.convertFromDto(userConverter.convertFromEntity(u1));
+ assertEquals(u1, u2);
+ }
+
+ /**
+ * Tests whether a converter created of opposite functions holds equality as a bijection.
+ */
+ @Test public void testConversionsStartingFromDto() {
+ UserDto u1 = new UserDto("Tom", "Hanks", true, "tom@hanks.com");
+ UserDto u2 = userConverter.convertFromEntity(userConverter.convertFromDto(u1));
+ assertEquals(u1, u2);
+ }
+
+ /**
+ * Tests the custom users converter. Thanks to Java8 lambdas, converter can be easily and
+ * cleanly instantiated allowing various different conversion strategies to be implemented.
+ */
+ @Test public void testCustomConverter() {
+ Converter
+ * Implementation is based on GuardedQueue, which has two methods: get and put,
+ * the condition is that we cannot get from empty queue so when thread attempt
+ * to break the condition we invoke Object's wait method on him and when other thread put an element
+ * to the queue he notify the waiting one that now he can get from queue.
+ */
+package com.iluwatar.guarded.suspension;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Created by robertt240 on 1/26/17.
+ */
+public class App {
+ /**
+ * Example pattern execution
+ *
+ * @param args - command line args
+ */
+ public static void main(String[] args) {
+ GuardedQueue guardedQueue = new GuardedQueue();
+ ExecutorService executorService = Executors.newFixedThreadPool(3);
+
+ //here we create first thread which is supposed to get from guardedQueue
+ executorService.execute(() -> {
+ guardedQueue.get();
+ }
+ );
+
+ //here we wait two seconds to show that the thread which is trying to get from guardedQueue will be waiting
+ try {
+ Thread.sleep(2000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ //now we execute second thread which will put number to guardedQueue and notify first thread that it could get
+ executorService.execute(() -> {
+ guardedQueue.put(20);
+ }
+ );
+ executorService.shutdown();
+ try {
+ executorService.awaitTermination(30, TimeUnit.SECONDS);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+
+}
diff --git a/guarded-suspension/src/main/java/com/iluwatar/guarded/suspension/GuardedQueue.java b/guarded-suspension/src/main/java/com/iluwatar/guarded/suspension/GuardedQueue.java
new file mode 100644
index 000000000..bf6142dd9
--- /dev/null
+++ b/guarded-suspension/src/main/java/com/iluwatar/guarded/suspension/GuardedQueue.java
@@ -0,0 +1,70 @@
+/**
+ * The MIT License
+ * Copyright (c) 2014 Ilkka Seppälä
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package com.iluwatar.guarded.suspension;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.LinkedList;
+import java.util.Queue;
+
+/**
+ * Guarded Queue is an implementation for Guarded Suspension Pattern
+ * Guarded suspension pattern is used to handle a situation when you want to execute a method
+ * on an object which is not in a proper state.
+ * @see http://java-design-patterns.com/patterns/guarded-suspension/
+ */
+public class GuardedQueue {
+ private static final Logger LOGGER = LoggerFactory.getLogger(GuardedQueue.class);
+ private final Queue
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package com.iluwatar.guarded.suspension;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Test for Guarded Queue
+ */
+public class GuardedQueueTest {
+ private volatile Integer value;
+
+ @Test
+ public void testGet() {
+ GuardedQueue g = new GuardedQueue();
+ ExecutorService executorService = Executors.newFixedThreadPool(2);
+ executorService.submit(() -> value = g.get());
+ executorService.submit(() -> g.put(Integer.valueOf(10)));
+ executorService.shutdown();
+ try {
+ executorService.awaitTermination(30, TimeUnit.SECONDS);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ Assert.assertEquals(Integer.valueOf(10), value);
+ }
+
+ @Test
+ public void testPut() {
+ GuardedQueue g = new GuardedQueue();
+ g.put(12);
+ Assert.assertEquals(Integer.valueOf(12), g.get());
+
+ }
+
+}
diff --git a/half-sync-half-async/pom.xml b/half-sync-half-async/pom.xml
index 4b3285ff1..2952f8d54 100644
--- a/half-sync-half-async/pom.xml
+++ b/half-sync-half-async/pom.xml
@@ -29,7 +29,7 @@
Prototype
* @author Jeroen Meulemeester
*/
@RunWith(Parameterized.class)
diff --git a/proxy/pom.xml b/proxy/pom.xml
index f12db724c..293f3098d 100644
--- a/proxy/pom.xml
+++ b/proxy/pom.xml
@@ -29,7 +29,7 @@
+ * This App shows how to create an isolated space per each thread. In this
+ * example the usage of SimpleDateFormat is made to be thread-safe. This is an
+ * example of the ThreadLocal pattern.
+ *
+ * By applying the ThreadLocal pattern you can keep track of application
+ * instances or locale settings throughout the handling of a request. The
+ * ThreadLocal class works like a static variable, with the exception that it is
+ * only bound to the current thread! This allows us to use static variables in a
+ * thread-safe way.
+ *
+ * In Java, thread-local variables are implemented by the ThreadLocal class
+ * object. ThreadLocal holds a variable of type T, which is accessible via get/set
+ * methods.
+ *
+ * SimpleDateFormat is one of the basic Java classes and is not thread-safe. If
+ * you do not isolate the instance of SimpleDateFormat per each thread then
+ * problems arise.
+ *
+ * App converts the String date value 15/12/2015 to the Date format using the
+ * Java class SimpleDateFormat. It does this 20 times using 4 threads, each doing
+ * it 5 times. With the usage of as ThreadLocal in DateFormatCallable everything
+ * runs well. But if you comment out the ThreadLocal variant (marked with "//TLTL")
+ * and comment in the non ThreadLocal variant (marked with "//NTLNTL") you can
+ * see what will happen without the ThreadLocal. Most likely you will get incorrect
+ * date values and / or exceptions.
+ *
+ * This example clearly show what will happen when using non thread-safe classes
+ * in a thread. In real life this may happen one in of 1.000 or 10.000 conversions
+ * and those are really hard to find errors.
+ *
+ * @author Thomas Bauer, 2017
+ */
+public class App {
+ /**
+ * Program entry point
+ *
+ * @param args
+ * command line args
+ */
+ public static void main(String[] args) {
+ int counterDateValues = 0;
+ int counterExceptions = 0;
+
+ // Create a callable
+ DateFormatCallable callableDf = new DateFormatCallable("dd/MM/yyyy", "15/12/2015");
+ // start 4 threads, each using the same Callable instance
+ ExecutorService executor = Executors.newCachedThreadPool();
+
+ Future
+ * After a successful run 5 date values should be in the result object. All dates should have
+ * the same value (15.11.2015). To avoid problems with time zone not the date instances themselves
+ * are compared by the test. For the test the dates are converted into string format DD.MM.YYY
+ *
+ * Additionally the number of list entries are tested for both the list with the date values
+ * and the list with the exceptions
+ *
+ * @author Thomas Bauer, January 2017
+ *
+ */
+public class DateFormatCallableTest {
+
+ // Class variables used in setup() have to be static because setup() has to be static
+ /**
+ * Result object given back by DateFormatCallable
+ * -- Array with converted date values
+ * -- Array with thrown exceptions
+ */
+ static Result result;
+
+ /**
+ * The date values created by the run of of DateFormatRunnalbe. List will be filled in the setup() method
+ */
+ static List
+ * An incorrect formatted date is passed to the Callable
+ * After a successful run 0 date values and 5 exceptions should be in the result object.
+ *
+ * @author Thomas Bauer, January 2017
+ *
+ */
+public class DateFormatCallableTestIncorrectDateFormat {
+
+ // Class variables used in setup() have to be static because setup() has to be static
+ /**
+ * Result object given back by DateFormatCallable
+ * -- Array with converted date values
+ * -- Array with thrown exceptions
+ */
+ static Result result;
+
+ /**
+ * The date values created by the run of DateFormatRunnalbe. List will be filled in the setup() method
+ */
+ static List
+ * After a successful run 5 date values should be in the result object of each thread. All dates
+ * should have the same value (15.11.2015). To avoid problems with time zone not the date instances
+ * themselves are compared by the test. For the test the dates are converted into string format DD.MM.YYY
+ *
+ * Additionally the number of list entries are tested for both the list with the date values
+ * and the list with the exceptions
+ *
+ * @author Thomas Bauer, January 2017
+ *
+ */
+public class DateFormatCallableTestMultiThread {
+
+ // Class variables used in setup() have to be static because setup() has to be static
+ /**
+ * Result object given back by DateFormatCallable, one for each thread
+ * -- Array with converted date values
+ * -- Array with thrown exceptions
+ */
+ static Result[] result = new Result[4];
+
+ /**
+ * The date values created by the run of of DateFormatRunnalbe. List will be filled in the setup() method
+ */
+ @SuppressWarnings("serial")
+ static class StringArrayList extends ArrayList Observable
+ * @param , O extends Observer, A> {
diff --git a/observer/src/test/java/com/iluwatar/observer/WeatherObserverTest.java b/observer/src/test/java/com/iluwatar/observer/WeatherObserverTest.java
index 7120a31e0..70a7922c5 100644
--- a/observer/src/test/java/com/iluwatar/observer/WeatherObserverTest.java
+++ b/observer/src/test/java/com/iluwatar/observer/WeatherObserverTest.java
@@ -22,18 +22,18 @@
*/
package com.iluwatar.observer;
+import static org.junit.Assert.assertEquals;
+
import com.iluwatar.observer.utils.InMemoryAppender;
+import java.util.function.Supplier;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
-import java.util.function.Supplier;
-
-import static org.junit.Assert.assertEquals;
-
/**
* Date: 12/27/15 - 11:44 AM
- *
+ * Weather Observer Tests
+ * @param Supplier method generating singletons
* @author Jeroen Meulemeester
* @author Richard Jones
*/
diff --git a/specification/pom.xml b/specification/pom.xml
index 40584b7ca..33cc0f1e5 100644
--- a/specification/pom.xml
+++ b/specification/pom.xml
@@ -29,7 +29,7 @@