mirror of
https://github.com/tiennm99/java-design-patterns.git
synced 2026-05-14 10:58:42 +00:00
* #2449 bump maven-checkstyle-plugin from 3.1.0 to 3.2.0 + resolve checkstyle issues * remove FileSelectorJFrame.java to resolve checkstyle issue * remove FileSelectorJFrame.java to resolve checkstyle issue * remove FileSelectorJFrame.java to resolve checkstyle issue * add refactored file with correct filename to resolve checkstyle issue * add the test data * change filenames from JFrame to Jframe for checkstyle * fix code smell from sonar report * add new testcases to improve the test coverage * remove code smell
This commit is contained in:
@@ -53,7 +53,7 @@ import lombok.extern.slf4j.Slf4j;
|
||||
* Communicate with pending asynchronous operations using the familiar events-and-delegates model.
|
||||
*
|
||||
* @see EventManager
|
||||
* @see Event
|
||||
* @see AsyncEvent
|
||||
*/
|
||||
@Slf4j
|
||||
public class App {
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
|
||||
*
|
||||
* The MIT License
|
||||
* Copyright © 2014-2022 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.event.asynchronous;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* Each Event runs as a separate/individual thread.
|
||||
*/
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
public class AsyncEvent implements Event, Runnable {
|
||||
|
||||
private final int eventId;
|
||||
private final int eventTime;
|
||||
@Getter
|
||||
private final boolean synchronous;
|
||||
private Thread thread;
|
||||
private boolean isComplete = false;
|
||||
private ThreadCompleteListener eventListener;
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
thread = new Thread(this);
|
||||
thread.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
if (null == thread) {
|
||||
return;
|
||||
}
|
||||
thread.interrupt();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void status() {
|
||||
if (!isComplete) {
|
||||
LOGGER.info("[{}] is not done.", eventId);
|
||||
} else {
|
||||
LOGGER.info("[{}] is done.", eventId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
var currentTime = System.currentTimeMillis();
|
||||
var endTime = currentTime + (eventTime * 1000);
|
||||
while (System.currentTimeMillis() < endTime) {
|
||||
try {
|
||||
Thread.sleep(1000); // Sleep for 1 second.
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
return;
|
||||
}
|
||||
}
|
||||
isComplete = true;
|
||||
completed();
|
||||
}
|
||||
|
||||
public final void addListener(final ThreadCompleteListener listener) {
|
||||
this.eventListener = listener;
|
||||
}
|
||||
|
||||
public final void removeListener() {
|
||||
this.eventListener = null;
|
||||
}
|
||||
|
||||
private void completed() {
|
||||
if (eventListener != null) {
|
||||
eventListener.completedEventHandler(eventId);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -24,76 +24,15 @@
|
||||
*/
|
||||
package com.iluwatar.event.asynchronous;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* Each Event runs as a separate/individual thread.
|
||||
* Events that fulfill the start stop and list out current status behaviour follow this interface.
|
||||
*/
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
public class Event implements IEvent, Runnable {
|
||||
public interface Event {
|
||||
|
||||
private final int eventId;
|
||||
private final int eventTime;
|
||||
@Getter
|
||||
private final boolean synchronous;
|
||||
private Thread thread;
|
||||
private boolean isComplete = false;
|
||||
private ThreadCompleteListener eventListener;
|
||||
void start();
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
thread = new Thread(this);
|
||||
thread.start();
|
||||
}
|
||||
void stop();
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
if (null == thread) {
|
||||
return;
|
||||
}
|
||||
thread.interrupt();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void status() {
|
||||
if (!isComplete) {
|
||||
LOGGER.info("[{}] is not done.", eventId);
|
||||
} else {
|
||||
LOGGER.info("[{}] is done.", eventId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
var currentTime = System.currentTimeMillis();
|
||||
var endTime = currentTime + (eventTime * 1000);
|
||||
while (System.currentTimeMillis() < endTime) {
|
||||
try {
|
||||
Thread.sleep(1000); // Sleep for 1 second.
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
return;
|
||||
}
|
||||
}
|
||||
isComplete = true;
|
||||
completed();
|
||||
}
|
||||
|
||||
public final void addListener(final ThreadCompleteListener listener) {
|
||||
this.eventListener = listener;
|
||||
}
|
||||
|
||||
public final void removeListener(final ThreadCompleteListener listener) {
|
||||
this.eventListener = null;
|
||||
}
|
||||
|
||||
private void completed() {
|
||||
if (eventListener != null) {
|
||||
eventListener.completedEventHandler(eventId);
|
||||
}
|
||||
}
|
||||
void status();
|
||||
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* EventManager handles and maintains a pool of event threads. {@link Event} threads are created
|
||||
* EventManager handles and maintains a pool of event threads. {@link AsyncEvent} threads are created
|
||||
* upon user request. Thre are two types of events; Asynchronous and Synchronous. There can be
|
||||
* multiple Asynchronous events running at once but only one Synchronous event running at a time.
|
||||
* Currently supported event operations are: start, stop, and getStatus. Once an event is complete,
|
||||
@@ -45,7 +45,7 @@ public class EventManager implements ThreadCompleteListener {
|
||||
public static final int MAX_EVENT_TIME = 1800; // in seconds / 30 minutes.
|
||||
private int currentlyRunningSyncEvent = -1;
|
||||
private final SecureRandom rand;
|
||||
private final Map<Integer, Event> eventPool;
|
||||
private final Map<Integer, AsyncEvent> eventPool;
|
||||
|
||||
private static final String DOES_NOT_EXIST = " does not exist.";
|
||||
|
||||
@@ -108,7 +108,7 @@ public class EventManager implements ThreadCompleteListener {
|
||||
|
||||
var newEventId = generateId();
|
||||
|
||||
var newEvent = new Event(newEventId, eventTime, isSynchronous);
|
||||
var newEvent = new AsyncEvent(newEventId, eventTime, isSynchronous);
|
||||
newEvent.addListener(this);
|
||||
eventPool.put(newEventId, newEvent);
|
||||
|
||||
@@ -167,7 +167,7 @@ public class EventManager implements ThreadCompleteListener {
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
public void statusOfAllEvents() {
|
||||
eventPool.entrySet().forEach(entry -> ((Event) ((Map.Entry) entry).getValue()).status());
|
||||
eventPool.entrySet().forEach(entry -> ((AsyncEvent) ((Map.Entry) entry).getValue()).status());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -175,7 +175,7 @@ public class EventManager implements ThreadCompleteListener {
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
public void shutdown() {
|
||||
eventPool.entrySet().forEach(entry -> ((Event) ((Map.Entry) entry).getValue()).stop());
|
||||
eventPool.entrySet().forEach(entry -> ((AsyncEvent) ((Map.Entry) entry).getValue()).stop());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -195,7 +195,7 @@ public class EventManager implements ThreadCompleteListener {
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback from an {@link Event} (once it is complete). The Event is then removed from the pool.
|
||||
* Callback from an {@link AsyncEvent} (once it is complete). The Event is then removed from the pool.
|
||||
*/
|
||||
@Override
|
||||
public void completedEventHandler(int eventId) {
|
||||
@@ -209,7 +209,7 @@ public class EventManager implements ThreadCompleteListener {
|
||||
/**
|
||||
* Getter method for event pool.
|
||||
*/
|
||||
public Map<Integer, Event> getEventPool() {
|
||||
public Map<Integer, AsyncEvent> getEventPool() {
|
||||
return eventPool;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
|
||||
*
|
||||
* The MIT License
|
||||
* Copyright © 2014-2022 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.event.asynchronous;
|
||||
|
||||
/**
|
||||
* Events that fulfill the start stop and list out current status behaviour follow this interface.
|
||||
*/
|
||||
public interface IEvent {
|
||||
|
||||
void start();
|
||||
|
||||
void stop();
|
||||
|
||||
void status();
|
||||
|
||||
}
|
||||
+23
-1
@@ -136,4 +136,26 @@ class EventAsynchronousTest {
|
||||
LOGGER.error(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLongRunningEventException(){
|
||||
assertThrows(LongRunningEventException.class, () -> {
|
||||
var eventManager = new EventManager();
|
||||
eventManager.createAsync(2000);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void testMaxNumOfEventsAllowedException(){
|
||||
assertThrows(MaxNumOfEventsAllowedException.class, () -> {
|
||||
final var eventManager = new EventManager();
|
||||
for(int i=0;i<1100;i++){
|
||||
eventManager.createAsync(i);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user