-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' of https://github.com/kiblykat/SmartInventorySystem
- Loading branch information
Showing
16 changed files
with
613 additions
and
38 deletions.
There are no files selected for viewing
105 changes: 105 additions & 0 deletions
105
src/main/java/sg/com/smartinventory/utility/Utility.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
package sg.com.smartinventory.utility; | ||
|
||
public class Utility { | ||
/** | ||
* Get the method name of the caller. | ||
* <p> | ||
* Java 9 introduced the Stack-Walking API to traverse the JVM stack frames in a | ||
* lazy and efficient manner. | ||
* First, we get a StackWalker instance using the getInstance() factory method. | ||
* Then we use the walk() method to traverse the stack frames from the top to | ||
* the bottom: | ||
* <p> | ||
* <ul> | ||
* <li>The walk() method can convert a stream of stack frames — | ||
* Stream<StackFrame> — to anything. | ||
* <li>The first element in the given stream is the top frame on the stack. | ||
* <li>The top frame on the stack always represents the currently executing | ||
* method. | ||
* </ul> | ||
* <p> | ||
* Therefore, if we get the first element from the stream, we’ll know the | ||
* currently executing method details. More specifically, we can use | ||
* StackFrame.getMethodName() to find the method name. | ||
* <p> | ||
* Compared to other approaches (more on them later), the Stack-Walking API has | ||
* a few advantages: | ||
* <p> | ||
* <ul> | ||
* <ul> | ||
* No need to create a dummy anonymous inner class instance — new | ||
* Object().getClass() {} | ||
* <ul> | ||
* No need to create a dummy exception — new Throwable() | ||
* <ul> | ||
* No need to eagerly capture the whole stacktrace, which can be costly | ||
* <p> | ||
* <ul> | ||
* On the contrary, the StackWalker only walks the stack one by one in a lazy | ||
* fashion. In this case, it only fetches the top frame, as opposed to the | ||
* stacktrace approach which captures all the frames eagerly. | ||
* | ||
* @param levelsUp The number of levels up the stack trace. | ||
* | ||
* @return The method name of the caller. | ||
*/ | ||
public static String getMethodName(int levelsUp) { | ||
// Check if the levelsUp is less than 0. If it is, throw an exception. | ||
if (levelsUp < 0) { | ||
throw new IllegalArgumentException("levelsUp must be greater than or equal to 0. "); | ||
} | ||
|
||
// Get the method name of the caller. The top is this function name itself, so | ||
// it should be skipped. | ||
return StackWalker.getInstance() | ||
.walk(s -> s.skip(1 + levelsUp).findFirst()) | ||
.get() | ||
.getMethodName(); | ||
} | ||
|
||
/** | ||
* Get the current method name. | ||
* | ||
* @return The current method name. | ||
* | ||
* @see #getMethodName() | ||
*/ | ||
public static String getCurrentMethodName() { | ||
// Get the method name of the caller. You need to skip 1 level up to get the | ||
// current method name as you are calling a base function below it. | ||
return getMethodName(1); | ||
} | ||
|
||
/** | ||
* Get the caller method name. | ||
* | ||
* @return The caller method name. | ||
* | ||
* @see #getMethodName() | ||
*/ | ||
public static String getCallerMethodName() { | ||
// Get the method name of the caller. You need to skip 2 level up to get the | ||
// current method name as you are calling a base function below it. | ||
return getMethodName(2); | ||
} | ||
|
||
/** | ||
* Get the caller method name. | ||
* | ||
* @param levelsUp The number of levels up the stack trace. | ||
* | ||
* @return The caller method name. | ||
* | ||
* @see #getCallerMethodName() | ||
*/ | ||
public static String getCallerMethodName(int levelsUp) { | ||
// Check if the levelsUp is less than 0. If it is, throw an exception. | ||
if (levelsUp < 0) { | ||
throw new IllegalArgumentException("levelsUp must be greater than or equal to 0. "); | ||
} | ||
|
||
// Get the method name of the caller. You need to skip 1 level up to get the | ||
// current method name as you are calling a base function below it. | ||
return getMethodName(2 + levelsUp); | ||
} | ||
} |
15 changes: 15 additions & 0 deletions
15
src/test/java/sg/com/smartinventory/SmartInventoryApplicationTests.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,28 @@ | ||
package sg.com.smartinventory; | ||
|
||
import static sg.com.smartinventory.utility.Utility.*; | ||
|
||
import static org.junit.jupiter.api.Assertions.*; | ||
|
||
import org.junit.jupiter.api.Test; | ||
|
||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
import org.springframework.boot.test.context.SpringBootTest; | ||
|
||
@SpringBootTest | ||
class SmartInventoryApplicationTests { | ||
/// Name this according to your class name. | ||
// The Logback library defines 5 log levels in order of priority: TRACE, DEBUG, | ||
// INFO, WARN, ERROR, with each of these having a corresponding logging method: | ||
// trace(), debug(), info(), warn(), error(). | ||
private static final Logger test_logger = LoggerFactory.getLogger(SmartInventoryApplicationTests.class); | ||
|
||
@Test | ||
void contextLoads() { | ||
test_logger.info("Starting test: " + getCurrentMethodName() + ". "); | ||
|
||
test_logger.info("Ending test: " + getCurrentMethodName() + ". "); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.