Merge pull request #78 from onixbyte/feature/change-license-to-mit-and-code-reformat

refactor: change to MIT license and reformat codes
This commit is contained in:
Zihlu Wang
2025-06-17 23:15:02 +08:00
committed by GitHub
73 changed files with 1521 additions and 2522 deletions
+25 -8
View File
@@ -2,7 +2,10 @@
## Our Pledge ## Our Pledge
We as members, contributors, and leaders pledge to make participation in our project a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. We as members, contributors, and leaders pledge to make participation in our project
a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity,
gender identity and expression, level of experience, nationality, personal appearance, race,
religion, or sexual identity and orientation.
## Our Standards ## Our Standards
@@ -20,26 +23,40 @@ Examples of unacceptable behaviour by participants include:
- Trolling, insulting, or derogatory comments - Trolling, insulting, or derogatory comments
- Personal or political attacks - Personal or political attacks
- Public or private harassment - Public or private harassment
- Publishing others private information, such as a physical or electronic address, without explicit permission - Publishing others private information, such as a physical or electronic address, without
explicit permission
- Other conduct which could reasonably be considered inappropriate in a professional setting - Other conduct which could reasonably be considered inappropriate in a professional setting
## Enforcement Responsibilities ## Enforcement Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable behaviour and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behaviour. Project maintainers are responsible for clarifying the standards of acceptable behaviour and are
expected to take appropriate and fair corrective action in response to any instances of
unacceptable behaviour.
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that do not align with this Code of Conduct, and will communicate reasons for moderation decisions when appropriate. Project maintainers have the right and responsibility to remove, edit, or reject comments, commits,
code, wiki edits, issues, and other contributions that do not align with this Code of Conduct, and
will communicate reasons for moderation decisions when appropriate.
## Scope ## Scope
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project email address, posting via an official social media account, or acting as an appointed representative at an online or offline event. This Code of Conduct applies both within project spaces and in public spaces when an individual is
representing the project or its community. Examples of representing a project or community include
using an official project email address, posting via an official social media account, or acting as
an appointed representative at an online or offline event.
## Enforcement ## Enforcement
Instances of abusive, harassing, or unacceptable behaviour may be reported by contacting the project team at [your-email@example.com]. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Instances of abusive, harassing, or unacceptable behaviour may be reported by contacting the
project team at [opensource@onixbyte.com](mailto:opensource@onixbyte.com). All complaints will be
reviewed and investigated and will result in a response that is deemed necessary and appropriate to
the circumstances. The project team is obligated to maintain confidentiality with regard to the
reporter of an incident.
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. Project maintainers who do not follow or enforce the Code of Conduct in good faith may face
temporary or permanent repercussions as determined by other members of the project's leadership.
## Attribution ## Attribution
This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org/), version 1.4, available at https://www.contributor-covenant.org/version/1/4/ This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org/),
version 1.4, available at https://www.contributor-covenant.org/version/1/4/
+16 -14
View File
@@ -1,18 +1,18 @@
# Contributing to Java Dev Kit # Contributing to OnixByte Toolbox
We appreciate your interest in contributing to our Java Enterprise Utility Library. Contributions are welcome in various We appreciate your interest in contributing to our Java Enterprise Utility Library. Contributions
forms such as code, documentation, bug reports, and test cases. To ensure a smooth collaboration, please follow the are welcome in various forms such as code, documentation, bug reports, and test cases. To ensure a
guidelines outlined below. smooth collaboration, please follow the guidelines outlined below.
## Getting Started ## Getting Started
The Java Dev Kit is an open-source Java library designed to ease Java enterprise application development. It is built The OnixByte Toolbox is an open-source Java library designed to ease Java enterprise
with Java 17, and we require contributors to use OpenJDK 17. application development. It is built with Java 17, and we require contributors to use OpenJDK 17.
## Development Setup ## Development Setup
There is no need for manual setup beyond ensuring you have JDK 17 and a stable internet connection. Our project uses There is no need for manual setup beyond ensuring you have JDK 17 and a stable internet connection.
Gradle Wrapper for building, simplifying the setup process. Our project uses Gradle Wrapper for building, simplifying the setup process.
```shell ```shell
./gradlew build ./gradlew build
@@ -20,13 +20,13 @@ Gradle Wrapper for building, simplifying the setup process.
## Branching Strategy ## Branching Strategy
We follow the `git-flow` branching model. Contributors should fork this repository and create their work on separate We follow the `git-flow` branching model. Contributors should fork this repository and create their
branches prefixed with `feature/` or `hotfix/` as appropriate. work on separate branches prefixed with `feature/` or `hotfix/` as appropriate.
## Code Style ## Code Style
Please adhere to the coding standards specified in our `.editorconfig` file in the root of the repository. Consistent Please adhere to the coding standards specified in our `.editorconfig` file in the root of
style helps in maintaining readability and uniformity across the codebase. the repository. Consistent style helps in maintaining readability and uniformity across the codebase.
## Commit Messages ## Commit Messages
@@ -52,8 +52,10 @@ This format helps in auto-generating changelogs and understanding the purpose be
## Testing ## Testing
We encourage using JUnit Jupiter for unit and integration tests. Pull Requests with accompanying test reports are prioritised for review and merging. We encourage using JUnit Jupiter for unit and integration tests. Pull Requests with accompanying
test reports are prioritised for review and merging.
## License ## License
By contributing to the Java Dev Kit, you agree that your contributions will be licensed under the Apache 2.0 license. If you do not agree to this, please refrain from contributing. By contributing to the OnixByte Toolbox, you agree that your contributions will be licensed under the
MIT license. If you do not agree to this, please refrain from contributing.
+17 -198
View File
@@ -1,202 +1,21 @@
MIT License
Apache License Copyright (c) 2024-2025 OnixByte
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 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:
1. Definitions. The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
"License" shall mean the terms and conditions for use, reproduction, THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
and distribution as defined by Sections 1 through 9 of this document. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
"Licensor" shall mean the copyright owner or entity authorized by AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
the copyright owner that is granting the License. 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
"Legal Entity" shall mean the union of the acting entity and all SOFTWARE.
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2024-2025 OnixByte
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
+17 -12
View File
@@ -1,16 +1,21 @@
/* /*
* Copyright (C) 2024-2025 OnixByte. * Copyright (c) 2024-2025 OnixByte
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Permission is hereby granted, free of charge, to any person obtaining a copy
* you may not use this file except in compliance with the License. * of this software and associated documentation files (the "Software"), to deal
* You may obtain a copy of the License at * 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:
* *
* http://www.apache.org/licenses/LICENSE-2.0 * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* *
* Unless required by applicable law or agreed to in writing, software * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* distributed under the License is distributed on an "AS IS" BASIS, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* See the License for the specific language governing permissions and * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* limitations under the License. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
*/ * SOFTWARE.
*/
+20 -14
View File
@@ -1,19 +1,25 @@
/* /*
* Copyright (C) 2024-2025 OnixByte. * Copyright (c) 2024-2025 OnixByte
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Permission is hereby granted, free of charge, to any person obtaining a copy
* you may not use this file except in compliance with the License. * of this software and associated documentation files (the "Software"), to deal
* You may obtain a copy of the License at * 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:
* *
* http://www.apache.org/licenses/LICENSE-2.0 * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* *
* Unless required by applicable law or agreed to in writing, software * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* distributed under the License is distributed on an "AS IS" BASIS, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* See the License for the specific language governing permissions and * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* limitations under the License. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/ */
import java.net.URI import java.net.URI
plugins { plugins {
@@ -82,8 +88,8 @@ publishing {
} }
scm { scm {
connection = "scm:git:git://github.com:OnixByte/JDevKit.git" connection = "scm:git:git://github.com:onixbyte/onixbyte-toolbox.git"
developerConnection = "scm:git:git://github.com:OnixByte/JDevKit.git" developerConnection = "scm:git:git://github.com:onixbyte/onixbyte-toolbox.git"
url = projectGithubUrl url = projectGithubUrl
} }
@@ -122,4 +128,4 @@ publishing {
} }
} }
} }
} }
@@ -1,18 +1,23 @@
/* /*
* Copyright (C) 2024-2025 OnixByte. * Copyright (c) 2024-2025 OnixByte
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Permission is hereby granted, free of charge, to any person obtaining a copy
* you may not use this file except in compliance with the License. * of this software and associated documentation files (the "Software"), to deal
* You may obtain a copy of the License at * 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:
* *
* http://www.apache.org/licenses/LICENSE-2.0 * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* *
* Unless required by applicable law or agreed to in writing, software * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* distributed under the License is distributed on an "AS IS" BASIS, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* See the License for the specific language governing permissions and * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* limitations under the License. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/ */
package com.onixbyte.common.util; package com.onixbyte.common.util;
@@ -54,12 +59,27 @@ import java.util.UUID;
* System.out.println(randomSecret); // Output: A randomly generated 16-character long secret * System.out.println(randomSecret); // Output: A randomly generated 16-character long secret
* }</pre> * }</pre>
* *
* @author hubin@baomidou * @author hubin
* @version 1.1.0 * @version 3.0.0
* @since 1.1.0
*/ */
public final class AesUtil { public final class AesUtil {
/**
* The algorithm AES.
*/
private static final String AES = "AES";
/**
* The algorithm AES/CBC/PKCS5Padding.
*/
private static final String AES_CBC_CIPHER = "AES/CBC/PKCS5Padding";
/**
* Private constructor to prevent instantiation of this utility class.
*/
private AesUtil() {
}
/** /**
* Encrypts the specified data using the AES algorithm with the provided secret key. * Encrypts the specified data using the AES algorithm with the provided secret key.
* *
@@ -125,21 +145,4 @@ public final class AesUtil {
public static String generateRandomSecret() { public static String generateRandomSecret() {
return UUID.randomUUID().toString().replaceAll("-", "").substring(0, 16); return UUID.randomUUID().toString().replaceAll("-", "").substring(0, 16);
} }
/**
* Private constructor to prevent instantiation of this utility class.
*/
private AesUtil() {
}
/**
* The algorithm AES.
*/
private static final String AES = "AES";
/**
* The algorithm AES/CBC/PKCS5Padding.
*/
private static final String AES_CBC_CIPHER = "AES/CBC/PKCS5Padding";
} }
@@ -1,18 +1,23 @@
/* /*
* Copyright (C) 2024-2025 OnixByte. * Copyright (c) 2024-2025 OnixByte
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Permission is hereby granted, free of charge, to any person obtaining a copy
* you may not use this file except in compliance with the License. * of this software and associated documentation files (the "Software"), to deal
* You may obtain a copy of the License at * 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:
* *
* http://www.apache.org/licenses/LICENSE-2.0 * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* *
* Unless required by applicable law or agreed to in writing, software * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* distributed under the License is distributed on an "AS IS" BASIS, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* See the License for the specific language governing permissions and * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* limitations under the License. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/ */
package com.onixbyte.common.util; package com.onixbyte.common.util;
@@ -50,11 +55,21 @@ import java.util.Objects;
* encoding and decoding. * encoding and decoding.
* *
* @author zihluwang * @author zihluwang
* @version 1.1.0 * @version 3.0.0
* @since 1.0.0
*/ */
public final class Base64Util { public final class Base64Util {
/**
* Private constructor to prevent instantiation of this utility class.
*/
private Base64Util() {
}
private static Base64.Encoder encoder;
private static Base64.Decoder decoder;
private static Base64.Encoder urlEncoder;
private static Base64.Decoder urlDecoder;
/** /**
* Ensure that there is only one Base64 Encoder. * Ensure that there is only one Base64 Encoder.
* *
@@ -103,12 +118,6 @@ public final class Base64Util {
return urlDecoder; return urlDecoder;
} }
/**
* Private constructor to prevent instantiation of this utility class.
*/
private Base64Util() {
}
/** /**
* Encodes the given string using the specified charset. * Encodes the given string using the specified charset.
* *
@@ -200,13 +209,4 @@ public final class Base64Util {
public static String decodeUrlComponents(String value) { public static String decodeUrlComponents(String value) {
return decodeUrlComponents(value, StandardCharsets.UTF_8); return decodeUrlComponents(value, StandardCharsets.UTF_8);
} }
private static Base64.Encoder encoder;
private static Base64.Decoder decoder;
private static Base64.Encoder urlEncoder;
private static Base64.Decoder urlDecoder;
} }
@@ -1,18 +1,23 @@
/* /*
* Copyright (C) 2024-2025 OnixByte. * Copyright (c) 2024-2025 OnixByte
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Permission is hereby granted, free of charge, to any person obtaining a copy
* you may not use this file except in compliance with the License. * of this software and associated documentation files (the "Software"), to deal
* You may obtain a copy of the License at * 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:
* *
* http://www.apache.org/licenses/LICENSE-2.0 * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* *
* Unless required by applicable law or agreed to in writing, software * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* distributed under the License is distributed on an "AS IS" BASIS, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* See the License for the specific language governing permissions and * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* limitations under the License. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/ */
package com.onixbyte.common.util; package com.onixbyte.common.util;
@@ -30,20 +35,23 @@ import java.util.function.BooleanSupplier;
* </p> * </p>
* *
* <p><b>Example usage:</b></p> * <p><b>Example usage:</b></p>
* <pre> * <pre>{@code
* {@code
* boolean result1 = BoolUtil.and(true, true, false); // false * boolean result1 = BoolUtil.and(true, true, false); // false
* boolean result2 = BoolUtil.or(true, false, false); // true * boolean result2 = BoolUtil.or(true, false, false); // true
* boolean result3 = BoolUtil.not(false); // true * boolean result3 = BoolUtil.not(false); // true
* } * }</pre>
* </pre>
* *
* @author zihluwang * @author zihluwang
* @version 1.6.2 * @version 3.0.0
* @since 1.6.2
*/ */
public final class BoolUtil { public final class BoolUtil {
/**
* Private constructor to prevent instantiation of this utility class.
*/
private BoolUtil() {
}
/** /**
* Logical and calculation. * Logical and calculation.
* *
@@ -91,10 +99,4 @@ public final class BoolUtil {
.filter(Objects::nonNull) .filter(Objects::nonNull)
.anyMatch(BooleanSupplier::getAsBoolean); .anyMatch(BooleanSupplier::getAsBoolean);
} }
/**
* Private constructor to prevent instantiation of this utility class.
*/
private BoolUtil() {}
} }
@@ -1,18 +1,23 @@
/* /*
* Copyright (C) 2024-2025 OnixByte. * Copyright (c) 2024-2025 OnixByte
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Permission is hereby granted, free of charge, to any person obtaining a copy
* you may not use this file except in compliance with the License. * of this software and associated documentation files (the "Software"), to deal
* You may obtain a copy of the License at * 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:
* *
* http://www.apache.org/licenses/LICENSE-2.0 * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* *
* Unless required by applicable law or agreed to in writing, software * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* distributed under the License is distributed on an "AS IS" BASIS, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* See the License for the specific language governing permissions and * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* limitations under the License. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/ */
package com.onixbyte.common.util; package com.onixbyte.common.util;
@@ -64,11 +69,10 @@ import java.util.function.Supplier;
* expressions. * expressions.
* *
* @author zihluwang * @author zihluwang
* @version 2.1.3 * @version 3.0.0
* @see java.util.function.Supplier * @see java.util.function.Supplier
* @see java.util.function.BooleanSupplier * @see java.util.function.BooleanSupplier
* @see java.lang.Runnable * @see java.lang.Runnable
* @since 1.0.0
*/ */
public final class BranchUtil { public final class BranchUtil {
@@ -167,7 +171,8 @@ public final class BranchUtil {
* *
* @param <T> the type of the result to be handled by the methods * @param <T> the type of the result to be handled by the methods
* @param trueSupplier the supplier to be executed if the result is {@code true} * @param trueSupplier the supplier to be executed if the result is {@code true}
* @return the result of the executed handler, or {@code null} if result of evaluation is {@code false} * @return the result of the executed handler, or {@code null} if result of evaluation
* is {@code false}
*/ */
public <T> T thenSupply(Supplier<T> trueSupplier) { public <T> T thenSupply(Supplier<T> trueSupplier) {
return thenSupply(trueSupplier, null); return thenSupply(trueSupplier, null);
@@ -205,5 +210,4 @@ public final class BranchUtil {
public void then(Runnable trueHandler) { public void then(Runnable trueHandler) {
then(trueHandler, null); then(trueHandler, null);
} }
} }
@@ -1,18 +1,23 @@
/* /*
* Copyright (C) 2024-2025 OnixByte. * Copyright (c) 2024-2025 OnixByte
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Permission is hereby granted, free of charge, to any person obtaining a copy
* you may not use this file except in compliance with the License. * of this software and associated documentation files (the "Software"), to deal
* You may obtain a copy of the License at * 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:
* *
* http://www.apache.org/licenses/LICENSE-2.0 * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* *
* Unless required by applicable law or agreed to in writing, software * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* distributed under the License is distributed on an "AS IS" BASIS, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* See the License for the specific language governing permissions and * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* limitations under the License. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/ */
package com.onixbyte.common.util; package com.onixbyte.common.util;
@@ -27,6 +32,7 @@ import java.util.function.Supplier;
* A utility class providing static methods for manipulating collections. * A utility class providing static methods for manipulating collections.
* *
* @author zihluwang * @author zihluwang
* @version 3.0.0
*/ */
public final class CollectionUtil { public final class CollectionUtil {
@@ -1,18 +1,23 @@
/* /*
* Copyright (C) 2024-2025 OnixByte. * Copyright (c) 2024-2025 OnixByte
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Permission is hereby granted, free of charge, to any person obtaining a copy
* you may not use this file except in compliance with the License. * of this software and associated documentation files (the "Software"), to deal
* You may obtain a copy of the License at * 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:
* *
* http://www.apache.org/licenses/LICENSE-2.0 * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* *
* Unless required by applicable law or agreed to in writing, software * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* distributed under the License is distributed on an "AS IS" BASIS, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* See the License for the specific language governing permissions and * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* limitations under the License. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/ */
package com.onixbyte.common.util; package com.onixbyte.common.util;
@@ -60,12 +65,17 @@ import java.util.Optional;
* encryption purposes. * encryption purposes.
* *
* @author zihluwang * @author zihluwang
* @version 1.1.0 * @version 3.0.0
* @see java.security.MessageDigest * @see java.security.MessageDigest
* @since 1.0.0
*/ */
public final class HashUtil { public final class HashUtil {
/**
* Private constructor to prevent instantiation of this utility class.
*/
private HashUtil() {
}
/** /**
* Calculates the MD2 hash value of the specified string using the given charset. * Calculates the MD2 hash value of the specified string using the given charset.
* *
@@ -222,12 +232,6 @@ public final class HashUtil {
return hash("SHA-512", value, StandardCharsets.UTF_8); return hash("SHA-512", value, StandardCharsets.UTF_8);
} }
/**
* Private constructor to prevent instantiation of this utility class.
*/
private HashUtil() {
}
/** /**
* Calculates the hash value of the specified string using the specified * Calculates the hash value of the specified string using the specified
* algorithm and charset. * algorithm and charset.
@@ -1,18 +1,23 @@
/* /*
* Copyright (C) 2024-2025 OnixByte. * Copyright (c) 2024-2025 OnixByte
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Permission is hereby granted, free of charge, to any person obtaining a copy
* you may not use this file except in compliance with the License. * of this software and associated documentation files (the "Software"), to deal
* You may obtain a copy of the License at * 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:
* *
* http://www.apache.org/licenses/LICENSE-2.0 * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* *
* Unless required by applicable law or agreed to in writing, software * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* distributed under the License is distributed on an "AS IS" BASIS, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* See the License for the specific language governing permissions and * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* limitations under the License. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/ */
package com.onixbyte.common.util; package com.onixbyte.common.util;
@@ -28,15 +33,16 @@ import java.util.Map;
* </p> * </p>
* *
* <p><b>Example usage:</b></p> * <p><b>Example usage:</b></p>
* <pre> * <pre>{@code
* {@code * // User.java
* public class User { * public class User {
* private String name; * private String name;
* private int age; * private int age;
* *
* // getters and setters * // getters and setters
* } * }
* *
* // UserMapAdapter.java
* public class UserMapAdapter implements ObjectMapAdapter<User> { * public class UserMapAdapter implements ObjectMapAdapter<User> {
* @Override * @Override
* public Map<String, Object> toMap(User user) { * public Map<String, Object> toMap(User user) {
@@ -73,15 +79,19 @@ import java.util.Map;
* System.out.println(newUser.getAge()); // Output: 30 * System.out.println(newUser.getAge()); // Output: 30
* } * }
* } * }
* } * }</pre>
* </pre>
* *
* @author zihluwang * @author zihluwang
* @version 1.7.0 * @version 3.0.0
* @since 1.0.0
*/ */
public final class MapUtil { public final class MapUtil {
/**
* Private constructor to prevent instantiation of this utility class.
*/
private MapUtil() {
}
/** /**
* Converts an object to a map by mapping the field names to their corresponding values. * Converts an object to a map by mapping the field names to their corresponding values.
* *
@@ -106,10 +116,4 @@ public final class MapUtil {
public static <T> T mapToObject(Map<String, Object> objectMap, ObjectMapAdapter<T> adapter) { public static <T> T mapToObject(Map<String, Object> objectMap, ObjectMapAdapter<T> adapter) {
return adapter.toObject(objectMap); return adapter.toObject(objectMap);
} }
/**
* Private constructor to prevent instantiation of this utility class.
*/
private MapUtil() {
}
} }
@@ -1,18 +1,23 @@
/* /*
* Copyright (C) 2024-2025 OnixByte. * Copyright (c) 2024-2025 OnixByte
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Permission is hereby granted, free of charge, to any person obtaining a copy
* you may not use this file except in compliance with the License. * of this software and associated documentation files (the "Software"), to deal
* You may obtain a copy of the License at * 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:
* *
* http://www.apache.org/licenses/LICENSE-2.0 * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* *
* Unless required by applicable law or agreed to in writing, software * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* distributed under the License is distributed on an "AS IS" BASIS, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* See the License for the specific language governing permissions and * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* limitations under the License. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/ */
package com.onixbyte.common.util; package com.onixbyte.common.util;
@@ -28,8 +33,7 @@ import java.util.Map;
* {@code T} to a {@link Map} and vice versa.</p> * {@code T} to a {@link Map} and vice versa.</p>
* *
* <p><b>Example usage:</b></p> * <p><b>Example usage:</b></p>
* <pre> * <pre>{@code
* {@code
* public class User { * public class User {
* private String name; * private String name;
* private int age; * private int age;
@@ -54,13 +58,11 @@ import java.util.Map;
* return user; * return user;
* } * }
* } * }
* } * }</pre>
* </pre>
* *
* @param <T> the type of the object to be converted * @param <T> the type of the object to be converted
* @author zihluwang * @author zihluwang
* @version 1.7.0 * @version 3.0.0
* @since 1.4.2
*/ */
public interface ObjectMapAdapter<T> { public interface ObjectMapAdapter<T> {
@@ -1,18 +1,23 @@
/* /*
* Copyright (C) 2024-2025 OnixByte. * Copyright (c) 2024-2025 OnixByte
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Permission is hereby granted, free of charge, to any person obtaining a copy
* you may not use this file except in compliance with the License. * of this software and associated documentation files (the "Software"), to deal
* You may obtain a copy of the License at * 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:
* *
* http://www.apache.org/licenses/LICENSE-2.0 * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* *
* Unless required by applicable law or agreed to in writing, software * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* distributed under the License is distributed on an "AS IS" BASIS, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* See the License for the specific language governing permissions and * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* limitations under the License. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/ */
package com.onixbyte.common.util; package com.onixbyte.common.util;
@@ -27,6 +32,7 @@ import java.util.stream.IntStream;
* leverage the {@link IntStream} to provide efficient and versatile integer sequences. * leverage the {@link IntStream} to provide efficient and versatile integer sequences.
* *
* @author zihluwang * @author zihluwang
* @version 3.0.0
* @see IntStream * @see IntStream
*/ */
public final class RangeUtil { public final class RangeUtil {
@@ -64,7 +70,7 @@ public final class RangeUtil {
public static IntStream range(int end) { public static IntStream range(int end) {
if (end <= 0) { if (end <= 0) {
throw new IllegalArgumentException("Parameter [end] should not be less than or equal to 0, provided: " + throw new IllegalArgumentException("Parameter [end] should not be less than or equal to 0, provided: " +
end); end);
} }
return IntStream.range(0, end); return IntStream.range(0, end);
} }
@@ -77,8 +83,9 @@ public final class RangeUtil {
* further processing. * further processing.
* <p> * <p>
* If {@code start} is less than {@code end}, an ascending range (exclusive of {@code end}) * If {@code start} is less than {@code end}, an ascending range (exclusive of {@code end})
* is generated. If {@code start} is greater than {@code end}, a descending range (exclusive of {@code end}) * is generated. If {@code start} is greater than {@code end}, a descending range (exclusive
* is generated. If {@code start} equals {@code end}, an empty stream is returned. * of {@code end}) is generated. If {@code start} equals {@code end}, an empty stream
* is returned.
* <p> * <p>
* <b>Example Usage:</b> * <b>Example Usage:</b>
* <pre>{@code * <pre>{@code
@@ -103,7 +110,8 @@ public final class RangeUtil {
* *
* @param start the starting value of the range (inclusive) * @param start the starting value of the range (inclusive)
* @param end upper-bound of the range (exclusive) * @param end upper-bound of the range (exclusive)
* @return an {@code IntStream} of integers in ascending or descending order, exclusive of {@code end} * @return an {@code IntStream} of integers in ascending or descending order, exclusive
* of {@code end}
* @see IntStream * @see IntStream
*/ */
public static IntStream range(int start, int end) { public static IntStream range(int start, int end) {
@@ -150,8 +158,8 @@ public final class RangeUtil {
} }
/** /**
* Generates a stream of integers starting from the specified {@code start} value, incremented by * Generates a stream of integers starting from the specified {@code start} value, incremented
* the specified {@code step}, up to the specified {@code end} value. * by the specified {@code step}, up to the specified {@code end} value.
* <p> * <p>
* It creates a sequential, ordered {@code IntStream} that can be used for iteration or * It creates a sequential, ordered {@code IntStream} that can be used for iteration or
* further processing. * further processing.
@@ -180,9 +188,10 @@ public final class RangeUtil {
* @param start the starting value of the range (inclusive) * @param start the starting value of the range (inclusive)
* @param end upper-bound of the range (exclusive) * @param end upper-bound of the range (exclusive)
* @param step the increment or decrement between each value (non-zero) * @param step the increment or decrement between each value (non-zero)
* @return an {@code IntStream} of integers from {@code start} to {@code end} exclusive stepping by {@code step} * @return an {@code IntStream} of integers from {@code start} to {@code end} exclusive stepping
* @throws IllegalArgumentException if {@code step} is zero or if {@code start} and {@code end} are inconsistent * by {@code step}
* with the direction imposed by {@code step} * @throws IllegalArgumentException if {@code step} is zero or if {@code start} and {@code end}
* are inconsistent with the direction imposed by {@code step}
* @see IntStream * @see IntStream
*/ */
public static IntStream range(int start, int end, int step) { public static IntStream range(int start, int end, int step) {
+18 -13
View File
@@ -1,19 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!-- <!--
~ Copyright (C) 2024-2025 OnixByte. ~ Copyright (c) 2024-2025 OnixByte
~ ~
~ Licensed under the Apache License, Version 2.0 (the "License"); ~ Permission is hereby granted, free of charge, to any person obtaining a copy
~ you may not use this file except in compliance with the License. ~ of this software and associated documentation files (the "Software"), to deal
~ You may obtain a copy of the License at ~ 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:
~ ~
~ http://www.apache.org/licenses/LICENSE-2.0 ~ The above copyright notice and this permission notice shall be included in all
~ copies or substantial portions of the Software.
~ ~
~ Unless required by applicable law or agreed to in writing, software ~ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
~ distributed under the License is distributed on an "AS IS" BASIS, ~ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ~ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
~ ~ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
~ See the License for the specific language governing permissions and ~ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
~ limitations under the License. ~ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
~ SOFTWARE.
--> -->
<configuration> <configuration>
@@ -22,7 +27,7 @@
<property name="STANDARD_OUTPUT" <property name="STANDARD_OUTPUT"
value="%date{'dd MMM, yyyy HH:mm:ss', Asia/Hong_Kong, en-UK} %-5level %black(---) [%10.10t] %-20.20logger{20} : %msg%n"/> value="%date{'dd MMM, yyyy HH:mm:ss', Asia/Hong_Kong, en-UK} %-5level %black(---) [%10.10t] %-20.20logger{20} : %msg%n"/>
<statusListener class="ch.qos.logback.core.status.NopStatusListener" /> <statusListener class="ch.qos.logback.core.status.NopStatusListener"/>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${COLOURFUL_OUTPUT}</pattern> <pattern>${COLOURFUL_OUTPUT}</pattern>
@@ -31,4 +36,4 @@
<root level="INFO"> <root level="INFO">
<appender-ref ref="STDOUT"/> <appender-ref ref="STDOUT"/>
</root> </root>
</configuration> </configuration>
+20 -14
View File
@@ -1,19 +1,25 @@
/* /*
* Copyright (C) 2024-2025 OnixByte. * Copyright (c) 2024-2025 OnixByte
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Permission is hereby granted, free of charge, to any person obtaining a copy
* you may not use this file except in compliance with the License. * of this software and associated documentation files (the "Software"), to deal
* You may obtain a copy of the License at * 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:
* *
* http://www.apache.org/licenses/LICENSE-2.0 * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* *
* Unless required by applicable law or agreed to in writing, software * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* distributed under the License is distributed on an "AS IS" BASIS, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* See the License for the specific language governing permissions and * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* limitations under the License. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/ */
import java.net.URI import java.net.URI
plugins { plugins {
@@ -87,8 +93,8 @@ publishing {
} }
scm { scm {
connection = "scm:git:git://github.com:OnixByte/JDevKit.git" connection = "scm:git:git://github.com:onixbyte/onixbyte-toolbox.git"
developerConnection = "scm:git:git://github.com:OnixByte/JDevKit.git" developerConnection = "scm:git:git://github.com:onixbyte/onixbyte-toolbox.git"
url = projectGithubUrl url = projectGithubUrl
} }
@@ -127,4 +133,4 @@ publishing {
} }
} }
} }
} }
@@ -1,18 +1,23 @@
/* /*
* Copyright (C) 2024-2025 OnixByte. * Copyright (c) 2024-2025 OnixByte
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Permission is hereby granted, free of charge, to any person obtaining a copy
* you may not use this file except in compliance with the License. * of this software and associated documentation files (the "Software"), to deal
* You may obtain a copy of the License at * 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:
* *
* http://www.apache.org/licenses/LICENSE-2.0 * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* *
* Unless required by applicable law or agreed to in writing, software * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* distributed under the License is distributed on an "AS IS" BASIS, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* See the License for the specific language governing permissions and * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* limitations under the License. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/ */
package com.onixbyte.crypto; package com.onixbyte.crypto;
@@ -25,8 +30,7 @@ import java.security.PrivateKey;
* *
* @author zihluwang * @author zihluwang
* @author siujamo * @author siujamo
* @version 2.0.0 * @version 3.0.0
* @since 1.6.0
*/ */
public interface PrivateKeyLoader { public interface PrivateKeyLoader {
@@ -1,18 +1,23 @@
/* /*
* Copyright (C) 2024-2025 OnixByte. * Copyright (c) 2024-2025 OnixByte
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Permission is hereby granted, free of charge, to any person obtaining a copy
* you may not use this file except in compliance with the License. * of this software and associated documentation files (the "Software"), to deal
* You may obtain a copy of the License at * 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:
* *
* http://www.apache.org/licenses/LICENSE-2.0 * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* *
* Unless required by applicable law or agreed to in writing, software * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* distributed under the License is distributed on an "AS IS" BASIS, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* See the License for the specific language governing permissions and * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* limitations under the License. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/ */
package com.onixbyte.crypto; package com.onixbyte.crypto;
@@ -1,18 +1,23 @@
/* /*
* Copyright (C) 2024-2025 OnixByte. * Copyright (c) 2024-2025 OnixByte
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Permission is hereby granted, free of charge, to any person obtaining a copy
* you may not use this file except in compliance with the License. * of this software and associated documentation files (the "Software"), to deal
* You may obtain a copy of the License at * 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:
* *
* http://www.apache.org/licenses/LICENSE-2.0 * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* *
* Unless required by applicable law or agreed to in writing, software * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* distributed under the License is distributed on an "AS IS" BASIS, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* See the License for the specific language governing permissions and * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* limitations under the License. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/ */
package com.onixbyte.crypto.algorithm.ecdsa; package com.onixbyte.crypto.algorithm.ecdsa;
@@ -35,26 +40,18 @@ import java.util.Set;
/** /**
* Key pair loader for loading key pairs for ECDSA-based algorithms. * Key pair loader for loading key pairs for ECDSA-based algorithms.
* <p> * <p>
* * <b>Example usage:</b>
* <b>Example usage for ECDSA:</b>
* <pre>{@code * <pre>{@code
* PrivateKeyLoader keyLoader = new EcKeyLoader(); * PrivateKeyLoader keyLoader = new ECPrivateKeyLoader();
* String pemPrivateKey = """ * String pemPrivateKey = """
* -----BEGIN EC PRIVATE KEY----- * -----BEGIN EC PRIVATE KEY-----
* ... * ...
* -----END EC PRIVATE KEY-----"""; * -----END EC PRIVATE KEY-----""";
* ECPrivateKey privateKey = PrivateKeyLoader.loadEcdsaPrivateKey(pemPrivateKey); * ECPrivateKey privateKey = PrivateKeyLoader.loadEcdsaPrivateKey(pemPrivateKey);
*
* String pemPublicKey = """
* -----BEGIN EC PUBLIC KEY-----
* ...
* -----END EC PUBLIC KEY-----""";
* ECPublicKey publicKey = PrivateKeyLoader.loadPublicKey(pemPublicKey);
* }</pre> * }</pre>
* *
* @author zihluwang * @author zihluwang
* @version 2.0.0 * @version 3.0.0
* @since 2.0.0
*/ */
public class ECPrivateKeyLoader implements PrivateKeyLoader { public class ECPrivateKeyLoader implements PrivateKeyLoader {
@@ -1,18 +1,23 @@
/* /*
* Copyright (C) 2024-2025 OnixByte. * Copyright (c) 2024-2025 OnixByte
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Permission is hereby granted, free of charge, to any person obtaining a copy
* you may not use this file except in compliance with the License. * of this software and associated documentation files (the "Software"), to deal
* You may obtain a copy of the License at * 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:
* *
* http://www.apache.org/licenses/LICENSE-2.0 * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* *
* Unless required by applicable law or agreed to in writing, software * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* distributed under the License is distributed on an "AS IS" BASIS, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* See the License for the specific language governing permissions and * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* limitations under the License. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/ */
package com.onixbyte.crypto.algorithm.ecdsa; package com.onixbyte.crypto.algorithm.ecdsa;
@@ -32,6 +37,9 @@ import java.util.Base64;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
/**
*
*/
public class ECPublicKeyLoader implements PublicKeyLoader { public class ECPublicKeyLoader implements PublicKeyLoader {
/** /**
@@ -1,18 +1,23 @@
/* /*
* Copyright (C) 2024-2025 OnixByte. * Copyright (c) 2024-2025 OnixByte
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Permission is hereby granted, free of charge, to any person obtaining a copy
* you may not use this file except in compliance with the License. * of this software and associated documentation files (the "Software"), to deal
* You may obtain a copy of the License at * 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:
* *
* http://www.apache.org/licenses/LICENSE-2.0 * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* *
* Unless required by applicable law or agreed to in writing, software * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* distributed under the License is distributed on an "AS IS" BASIS, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* See the License for the specific language governing permissions and * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* limitations under the License. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/ */
package com.onixbyte.crypto.algorithm.rsa; package com.onixbyte.crypto.algorithm.rsa;
@@ -32,14 +37,15 @@ import java.util.Base64;
/** /**
* A class responsible for loading RSA keys from PEM formatted text. * A class responsible for loading RSA keys from PEM formatted text.
* <p> * <p>
* This class implements the {@link PrivateKeyLoader} interface and provides methods to load both private * This class implements the {@link PrivateKeyLoader} interface and provides methods to load both
* and public RSA keys. The keys are expected to be in the standard PEM format, which includes * private and public RSA keys. The keys are expected to be in the standard PEM format, which
* Base64-encoded key content surrounded by header and footer lines. The class handles the decoding * includes Base64-encoded key content surrounded by header and footer lines. The class handles
* of Base64 content and the generation of keys using the RSA key factory. * the decoding of Base64 content and the generation of keys using the RSA key factory.
* <p> * <p>
* Any exceptions encountered during the loading process are encapsulated in a * Any exceptions encountered during the loading process are encapsulated in a
* {@link KeyLoadingException}, allowing for flexible error handling. * {@link KeyLoadingException}, allowing for flexible error handling.
* *
* @author zihluwang
* @author siujamo * @author siujamo
* @see PrivateKeyLoader * @see PrivateKeyLoader
* @see KeyLoadingException * @see KeyLoadingException
@@ -1,18 +1,23 @@
/* /*
* Copyright (C) 2024-2025 OnixByte. * Copyright (c) 2024-2025 OnixByte
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Permission is hereby granted, free of charge, to any person obtaining a copy
* you may not use this file except in compliance with the License. * of this software and associated documentation files (the "Software"), to deal
* You may obtain a copy of the License at * 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:
* *
* http://www.apache.org/licenses/LICENSE-2.0 * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* *
* Unless required by applicable law or agreed to in writing, software * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* distributed under the License is distributed on an "AS IS" BASIS, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* See the License for the specific language governing permissions and * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* limitations under the License. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/ */
package com.onixbyte.crypto.algorithm.rsa; package com.onixbyte.crypto.algorithm.rsa;
@@ -31,6 +36,9 @@ import java.security.spec.RSAPublicKeySpec;
import java.security.spec.X509EncodedKeySpec; import java.security.spec.X509EncodedKeySpec;
import java.util.Base64; import java.util.Base64;
/**
*
*/
public class RSAPublicKeyLoader implements PublicKeyLoader { public class RSAPublicKeyLoader implements PublicKeyLoader {
private final Base64.Decoder decoder; private final Base64.Decoder decoder;
@@ -1,18 +1,23 @@
/* /*
* Copyright (C) 2024-2025 OnixByte. * Copyright (c) 2024-2025 OnixByte
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Permission is hereby granted, free of charge, to any person obtaining a copy
* you may not use this file except in compliance with the License. * of this software and associated documentation files (the "Software"), to deal
* You may obtain a copy of the License at * 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:
* *
* http://www.apache.org/licenses/LICENSE-2.0 * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* *
* Unless required by applicable law or agreed to in writing, software * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* distributed under the License is distributed on an "AS IS" BASIS, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* See the License for the specific language governing permissions and * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* limitations under the License. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/ */
package com.onixbyte.crypto.exception; package com.onixbyte.crypto.exception;
@@ -39,7 +44,6 @@ package com.onixbyte.crypto.exception;
* *
* @author zihluwang * @author zihluwang
* @version 3.0.0 * @version 3.0.0
* @since 1.6.0
*/ */
public class KeyLoadingException extends RuntimeException { public class KeyLoadingException extends RuntimeException {
@@ -1,24 +1,35 @@
/* /*
* Copyright (C) 2024-2025 OnixByte. * Copyright (c) 2024-2025 OnixByte
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Permission is hereby granted, free of charge, to any person obtaining a copy
* you may not use this file except in compliance with the License. * of this software and associated documentation files (the "Software"), to deal
* You may obtain a copy of the License at * 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:
* *
* http://www.apache.org/licenses/LICENSE-2.0 * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* *
* Unless required by applicable law or agreed to in writing, software * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* distributed under the License is distributed on an "AS IS" BASIS, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* See the License for the specific language governing permissions and * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* limitations under the License. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/ */
package com.onixbyte.crypto.util; package com.onixbyte.crypto.util;
/**
*
*/
public final class CryptoUtil { public final class CryptoUtil {
/**
* Private constructor to prevent instantiation of this utility class.
*/
private CryptoUtil() { private CryptoUtil() {
} }
+22 -15
View File
@@ -1,26 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!-- <!--
~ Copyright (C) 2024-2024 OnixByte. ~ Copyright (c) 2024-2025 OnixByte
~ ~
~ Licensed under the Apache License, Version 2.0 (the "License"); ~ Permission is hereby granted, free of charge, to any person obtaining a copy
~ you may not use this file except in compliance with the License. ~ of this software and associated documentation files (the "Software"), to deal
~ You may obtain a copy of the License at ~ 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:
~ ~
~ http://www.apache.org/licenses/LICENSE-2.0 ~ The above copyright notice and this permission notice shall be included in all
~ copies or substantial portions of the Software.
~ ~
~ Unless required by applicable law or agreed to in writing, software ~ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
~ distributed under the License is distributed on an "AS IS" BASIS, ~ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ~ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
~ ~ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
~ See the License for the specific language governing permissions and ~ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
~ limitations under the License. ~ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
~ SOFTWARE.
--> -->
<configuration> <configuration>
<property name="COLOURFUL_OUTPUT" value="%black(%date{'dd MMM, yyyy HH:mm:ss', Asia/Hong_Kong, en-UK}) %highlight(%-5level) %black(---) %black([%10.10t]) %cyan(%-20.20logger{20}) %black(:) %msg%n"/> <property name="COLOURFUL_OUTPUT"
<property name="STANDARD_OUTPUT" value="%date{'dd MMM, yyyy HH:mm:ss', Asia/Hong_Kong, en-UK} %-5level %black(---) [%10.10t] %-20.20logger{20} : %msg%n"/> value="%black(%date{'dd MMM, yyyy HH:mm:ss', Asia/Hong_Kong, en-UK}) %highlight(%-5level) %black(---) %black([%10.10t]) %cyan(%-20.20logger{20}) %black(:) %msg%n"/>
<property name="STANDARD_OUTPUT"
value="%date{'dd MMM, yyyy HH:mm:ss', Asia/Hong_Kong, en-UK} %-5level %black(---) [%10.10t] %-20.20logger{20} : %msg%n"/>
<statusListener class="ch.qos.logback.core.status.NopStatusListener" /> <statusListener class="ch.qos.logback.core.status.NopStatusListener"/>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${COLOURFUL_OUTPUT}</pattern> <pattern>${COLOURFUL_OUTPUT}</pattern>
@@ -29,4 +36,4 @@
<root level="INFO"> <root level="INFO">
<appender-ref ref="STDOUT"/> <appender-ref ref="STDOUT"/>
</root> </root>
</configuration> </configuration>
Binary file not shown.
Vendored
+16 -10
View File
@@ -1,19 +1,25 @@
#!/bin/sh #!/bin/sh
# #
# Copyright © 2015-2021 the original authors. # Copyright (c) 2024-2025 OnixByte
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Permission is hereby granted, free of charge, to any person obtaining a copy
# you may not use this file except in compliance with the License. # of this software and associated documentation files (the "Software"), to deal
# You may obtain a copy of the License at # 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:
# #
# https://www.apache.org/licenses/LICENSE-2.0 # The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
# #
# Unless required by applicable law or agreed to in writing, software # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# distributed under the License is distributed on an "AS IS" BASIS, # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# See the License for the specific language governing permissions and # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# limitations under the License. # 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.
# #
############################################################################## ##############################################################################
+17 -11
View File
@@ -1,19 +1,25 @@
/* /*
* Copyright (C) 2024-2025 OnixByte. * Copyright (c) 2024-2025 OnixByte
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Permission is hereby granted, free of charge, to any person obtaining a copy
* you may not use this file except in compliance with the License. * of this software and associated documentation files (the "Software"), to deal
* You may obtain a copy of the License at * 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:
* *
* http://www.apache.org/licenses/LICENSE-2.0 * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* *
* Unless required by applicable law or agreed to in writing, software * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* distributed under the License is distributed on an "AS IS" BASIS, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* See the License for the specific language governing permissions and * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* limitations under the License. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/ */
import java.net.URI import java.net.URI
plugins { plugins {
@@ -1,25 +1,30 @@
/* /*
* Copyright (C) 2024-2025 OnixByte. * Copyright (c) 2024-2025 OnixByte
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Permission is hereby granted, free of charge, to any person obtaining a copy
* you may not use this file except in compliance with the License. * of this software and associated documentation files (the "Software"), to deal
* You may obtain a copy of the License at * 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:
* *
* http://www.apache.org/licenses/LICENSE-2.0 * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* *
* Unless required by applicable law or agreed to in writing, software * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* distributed under the License is distributed on an "AS IS" BASIS, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* See the License for the specific language governing permissions and * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* limitations under the License. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/ */
package com.onixbyte.identitygenerator; package com.onixbyte.identitygenerator;
/** /**
* The {@code IdentityGenerator} is a generic interface for generating globally unique identifiers (GUIDs) * The {@code IdentityGenerator} is a generic interface for generating globally unique identifiers
* of a specific type. * (GUIDs) of a specific type.
* <p> * <p>
* The type of ID is determined by the class implementing this interface. * The type of ID is determined by the class implementing this interface.
* </p> * </p>
@@ -45,9 +50,8 @@ package com.onixbyte.identitygenerator;
* }</pre> * }</pre>
* *
* @param <IdType> this represents the type of the Global Unique Identifier * @param <IdType> this represents the type of the Global Unique Identifier
* @author Zihlu Wang * @author zihluwang
* @version 1.1.0 * @version 3.0.0
* @since 1.0.0
*/ */
public interface IdentityGenerator<IdType> { public interface IdentityGenerator<IdType> {
@@ -1,18 +1,23 @@
/* /*
* Copyright (C) 2024-2025 OnixByte. * Copyright (c) 2024-2025 OnixByte
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Permission is hereby granted, free of charge, to any person obtaining a copy
* you may not use this file except in compliance with the License. * of this software and associated documentation files (the "Software"), to deal
* You may obtain a copy of the License at * 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:
* *
* http://www.apache.org/licenses/LICENSE-2.0 * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* *
* Unless required by applicable law or agreed to in writing, software * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* distributed under the License is distributed on an "AS IS" BASIS, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* See the License for the specific language governing permissions and * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* limitations under the License. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/ */
package com.onixbyte.identitygenerator.exceptions; package com.onixbyte.identitygenerator.exceptions;
@@ -25,8 +30,8 @@ package com.onixbyte.identitygenerator.exceptions;
* provides a description of the exception, while the cause represents the underlying cause of the * provides a description of the exception, while the cause represents the underlying cause of the
* exception and provides additional information about the error. * exception and provides additional information about the error.
* *
* @author Zihlu Wang * @author zihluwang
* @since 1.0.0 * @since 3.0.0
*/ */
public class TimingException extends RuntimeException { public class TimingException extends RuntimeException {
@@ -1,18 +1,23 @@
/* /*
* Copyright (C) 2024-2025 OnixByte. * Copyright (c) 2024-2025 OnixByte
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Permission is hereby granted, free of charge, to any person obtaining a copy
* you may not use this file except in compliance with the License. * of this software and associated documentation files (the "Software"), to deal
* You may obtain a copy of the License at * 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:
* *
* http://www.apache.org/licenses/LICENSE-2.0 * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* *
* Unless required by applicable law or agreed to in writing, software * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* distributed under the License is distributed on an "AS IS" BASIS, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* See the License for the specific language governing permissions and * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* limitations under the License. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/ */
package com.onixbyte.identitygenerator.impl; package com.onixbyte.identitygenerator.impl;
@@ -24,15 +29,20 @@ import java.security.SecureRandom;
import java.util.UUID; import java.util.UUID;
/** /**
* A {@code SequentialUuidGenerator} is responsible for generating UUIDs following the UUID version 7 specification, which * A {@code SequentialUuidGenerator} is responsible for generating UUIDs following the
* combines a timestamp with random bytes to create time-ordered unique identifiers. * UUID version 7 specification, which combines a timestamp with random bytes to create time-ordered
* unique identifiers.
* <p> * <p>
* This implementation utilises a cryptographically strong {@link SecureRandom} instance to produce the random * This implementation utilises a cryptographically strong {@link SecureRandom} instance to produce
* component of the UUID. The first 6 bytes of the UUID encode the current timestamp in milliseconds, ensuring that * the random component of the UUID. The first 6 bytes of the UUID encode the current timestamp in
* generated UUIDs are roughly ordered by creation time. * milliseconds, ensuring that generated UUIDs are roughly ordered by creation time.
* <p> * <p>
* The generated UUID adheres strictly to the layout and variant bits of UUID version 7 as defined in the specification. * The generated UUID adheres strictly to the layout and variant bits of UUID version 7 as defined
* </p> * in the specification.
*
* @author zihluwang
* @author siujamo
* @version 3.0.0
*/ */
public class SequentialUuidGenerator implements IdentityGenerator<UUID> { public class SequentialUuidGenerator implements IdentityGenerator<UUID> {
@@ -1,18 +1,23 @@
/* /*
* Copyright (C) 2024-2025 OnixByte. * Copyright (c) 2024-2025 OnixByte
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Permission is hereby granted, free of charge, to any person obtaining a copy
* you may not use this file except in compliance with the License. * of this software and associated documentation files (the "Software"), to deal
* You may obtain a copy of the License at * 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:
* *
* http://www.apache.org/licenses/LICENSE-2.0 * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* *
* Unless required by applicable law or agreed to in writing, software * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* distributed under the License is distributed on an "AS IS" BASIS, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* See the License for the specific language governing permissions and * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* limitations under the License. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/ */
package com.onixbyte.identitygenerator.impl; package com.onixbyte.identitygenerator.impl;
@@ -35,129 +40,17 @@ import java.time.ZoneId;
* <li>12 bits for sequence number (per millisecond)</li> * <li>12 bits for sequence number (per millisecond)</li>
* </ul> * </ul>
* <p> * <p>
* When initializing a {@link SnowflakeIdentityGenerator}, you must provide the worker ID and data centre * When initializing a {@link SnowflakeIdentityGenerator}, you must provide the worker ID and data
* ID, ensuring they are within the valid range defined by the bit size. The generator maintains an * centre ID, ensuring they are within the valid range defined by the bit size. The generator
* internal sequence number that increments for IDs generated within the same millisecond. If the * maintains an internal sequence number that increments for IDs generated within the
* system clock moves backward, an exception is thrown to prevent generating IDs with * same millisecond. If the system clock moves backward, an exception is thrown to prevent
* repeated timestamps. * generating IDs with repeated timestamps.
* *
* @author Zihlu Wang * @author zihluwang
* @version 1.1.0 * @version 3.0.0
* @since 1.0.0
*/ */
public final class SnowflakeIdentityGenerator implements IdentityGenerator<Long> { public final class SnowflakeIdentityGenerator implements IdentityGenerator<Long> {
/**
* Constructs a SnowflakeGuidGenerator with the default start epoch and custom worker ID, data
* centre ID.
*
* @param dataCentreId the data centre ID (between 0 and 31)
* @param workerId the worker ID (between 0 and 31)
*/
public SnowflakeIdentityGenerator(long dataCentreId, long workerId) {
this(dataCentreId, workerId, DEFAULT_CUSTOM_EPOCH);
}
/**
* Constructs a SnowflakeGuidGenerator with a custom epoch, worker ID, and data centre ID.
*
* @param dataCentreId the data centre ID (between 0 and 31)
* @param workerId the worker ID (between 0 and 31)
* @param startEpoch the custom epoch timestamp (in milliseconds) to start generating IDs from
* @throws IllegalArgumentException if the start epoch is greater than the current timestamp,
* or if the worker ID or data centre ID is out of range
*/
public SnowflakeIdentityGenerator(long dataCentreId, long workerId, long startEpoch) {
if (startEpoch > currentTimestamp()) {
throw new IllegalArgumentException("Start Epoch can not be greater than current timestamp!");
}
var maxWorkerId = ~(-1L << workerIdBits);
if (workerId > maxWorkerId || workerId < 0) {
throw new IllegalArgumentException(String.format("Worker Id can't be greater than %d or less than 0",
maxWorkerId));
}
var maxDataCentreId = ~(-1L << dataCentreIdBits);
if (dataCentreId > maxDataCentreId || dataCentreId < 0) {
throw new IllegalArgumentException(String.format("Data Centre Id can't be greater than %d or less than 0",
maxDataCentreId));
}
this.startEpoch = startEpoch;
this.workerId = workerId;
this.dataCentreId = dataCentreId;
}
/**
* Generates the next unique ID.
*
* @return the generated unique ID
* @throws TimingException if the system clock moves backwards, indicating an invalid sequence
* of timestamps.
*/
@Override
public synchronized Long nextId() {
var timestamp = currentTimestamp();
// if the current time is less than the timestamp of the last ID generation, it means that
// the system clock has been set back and an exception should be thrown
if (timestamp < lastTimestamp) {
throw new TimingException("Clock moved backwards. Refusing to generate id for %d milliseconds"
.formatted(lastTimestamp - timestamp));
}
// if generated at the same time, perform intra-millisecond sequences
long sequenceBits = 12L;
if (lastTimestamp == timestamp) {
long sequenceMask = ~(-1L << sequenceBits);
sequence = (sequence + 1) & sequenceMask;
// sequence overflow in milliseconds
if (sequence == 0) {
// block to the next millisecond, get a new timestamp
timestamp = awaitToNextMillis(lastTimestamp);
}
}
// timestamp change, sequence reset in milliseconds
else {
sequence = 0L;
}
// timestamp of last ID generation
lastTimestamp = timestamp;
// shifted and put together by or operations to form a 64-bit ID
var timestampLeftShift = sequenceBits + workerIdBits + dataCentreIdBits;
var dataCentreIdShift = sequenceBits + workerIdBits;
return ((timestamp - startEpoch) << timestampLeftShift)
| (dataCentreId << dataCentreIdShift)
| (workerId << sequenceBits)
| sequence;
}
/**
* Blocks until the next millisecond to obtain a new timestamp.
*
* @param lastTimestamp the timestamp when the last ID was generated
* @return the current timestamp
*/
private long awaitToNextMillis(long lastTimestamp) {
var timestamp = currentTimestamp();
while (timestamp <= lastTimestamp) {
timestamp = currentTimestamp();
}
return timestamp;
}
/**
* Returns the current timestamp in milliseconds.
*
* @return the current timestamp
*/
private long currentTimestamp() {
return LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
}
/** /**
* Default custom epoch. * Default custom epoch.
* *
@@ -200,5 +93,116 @@ public final class SnowflakeIdentityGenerator implements IdentityGenerator<Long>
*/ */
private long lastTimestamp = -1L; private long lastTimestamp = -1L;
/**
* Constructs a SnowflakeGuidGenerator with the default start epoch and custom worker ID, data
* centre ID.
*
* @param dataCentreId the data centre ID (between 0 and 31)
* @param workerId the worker ID (between 0 and 31)
*/
public SnowflakeIdentityGenerator(long dataCentreId, long workerId) {
this(dataCentreId, workerId, DEFAULT_CUSTOM_EPOCH);
}
/**
* Constructs a SnowflakeGuidGenerator with a custom epoch, worker ID, and data centre ID.
*
* @param dataCentreId the data centre ID (between 0 and 31)
* @param workerId the worker ID (between 0 and 31)
* @param startEpoch the custom epoch timestamp (in milliseconds) to start generating IDs from
* @throws IllegalArgumentException if the start epoch is greater than the current timestamp,
* or if the worker ID or data centre ID is out of range
*/
public SnowflakeIdentityGenerator(long dataCentreId, long workerId, long startEpoch) {
if (startEpoch > currentTimestamp()) {
throw new IllegalArgumentException("Start Epoch can not be greater than current timestamp!");
}
var maxWorkerId = ~(-1L << workerIdBits);
if (workerId > maxWorkerId || workerId < 0) {
throw new IllegalArgumentException(String.format("Worker Id can't be greater than %d or less than 0",
maxWorkerId));
}
var maxDataCentreId = ~(-1L << dataCentreIdBits);
if (dataCentreId > maxDataCentreId || dataCentreId < 0) {
throw new IllegalArgumentException(String.format("Data Centre Id can't be greater than %d or less than 0",
maxDataCentreId));
}
this.startEpoch = startEpoch;
this.workerId = workerId;
this.dataCentreId = dataCentreId;
}
/**
* Generates the next unique ID.
*
* @return the generated unique ID
* @throws TimingException if the system clock moves backwards, indicating an invalid sequence
* of timestamps.
*/
@Override
public synchronized Long nextId() {
var timestamp = currentTimestamp();
// if the current time is less than the timestamp of the last ID generation, it means that
// the system clock has been set back and an exception should be thrown
if (timestamp < lastTimestamp) {
throw new TimingException("Clock moved backwards. Refusing to generate id for %d milliseconds"
.formatted(lastTimestamp - timestamp));
}
// if generated at the same time, perform intra-millisecond sequences
long sequenceBits = 12L;
if (lastTimestamp == timestamp) {
long sequenceMask = ~(-1L << sequenceBits);
sequence = (sequence + 1) & sequenceMask;
// sequence overflow in milliseconds
if (sequence == 0) {
// block to the next millisecond, get a new timestamp
timestamp = awaitToNextMillis(lastTimestamp);
}
}
// timestamp change, sequence reset in milliseconds
else {
sequence = 0L;
}
// timestamp of last ID generation
lastTimestamp = timestamp;
// shifted and put together by or operations to form a 64-bit ID
var timestampLeftShift = sequenceBits + workerIdBits + dataCentreIdBits;
var dataCentreIdShift = sequenceBits + workerIdBits;
return ((timestamp - startEpoch) << timestampLeftShift)
| (dataCentreId << dataCentreIdShift)
| (workerId << sequenceBits)
| sequence;
}
/**
* Blocks until the next millisecond to obtain a new timestamp.
*
* @param lastTimestamp the timestamp when the last ID was generated
* @return the current timestamp
*/
private long awaitToNextMillis(long lastTimestamp) {
var timestamp = currentTimestamp();
while (timestamp <= lastTimestamp) {
timestamp = currentTimestamp();
}
return timestamp;
}
/**
* Returns the current timestamp in milliseconds.
*
* @return the current timestamp
*/
private long currentTimestamp() {
return LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
}
} }
@@ -1,25 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!-- <!--
~ Copyright (C) 2024-2025 OnixByte. ~ Copyright (c) 2024-2025 OnixByte
~ ~
~ Licensed under the Apache License, Version 2.0 (the "License"); ~ Permission is hereby granted, free of charge, to any person obtaining a copy
~ you may not use this file except in compliance with the License. ~ of this software and associated documentation files (the "Software"), to deal
~ You may obtain a copy of the License at ~ 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:
~ ~
~ http://www.apache.org/licenses/LICENSE-2.0 ~ The above copyright notice and this permission notice shall be included in all
~ copies or substantial portions of the Software.
~ ~
~ Unless required by applicable law or agreed to in writing, software ~ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
~ distributed under the License is distributed on an "AS IS" BASIS, ~ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ~ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
~ ~ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
~ See the License for the specific language governing permissions and ~ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
~ limitations under the License. ~ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
~ SOFTWARE.
--> -->
<configuration>
<property name="COLOURFUL_OUTPUT" value="%black(%date{'dd MMM, yyyy HH:mm:ss', Asia/Hong_Kong, en-UK}) %highlight(%-5level) %black(---) %black([%10.10t]) %cyan(%-20.20logger{20}) %black(:) %msg%n"/>
<property name="STANDARD_OUTPUT" value="%date{'dd MMM, yyyy HH:mm:ss', Asia/Hong_Kong, en-UK} %-5level %black(---) [%10.10t] %-20.20logger{20} : %msg%n"/>
<statusListener class="ch.qos.logback.core.status.NopStatusListener" /> <configuration>
<property name="COLOURFUL_OUTPUT"
value="%black(%date{'dd MMM, yyyy HH:mm:ss', Asia/Hong_Kong, en-UK}) %highlight(%-5level) %black(---) %black([%10.10t]) %cyan(%-20.20logger{20}) %black(:) %msg%n"/>
<property name="STANDARD_OUTPUT"
value="%date{'dd MMM, yyyy HH:mm:ss', Asia/Hong_Kong, en-UK} %-5level %black(---) [%10.10t] %-20.20logger{20} : %msg%n"/>
<statusListener class="ch.qos.logback.core.status.NopStatusListener"/>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${COLOURFUL_OUTPUT}</pattern> <pattern>${COLOURFUL_OUTPUT}</pattern>
@@ -28,4 +36,4 @@
<root level="INFO"> <root level="INFO">
<appender-ref ref="STDOUT"/> <appender-ref ref="STDOUT"/>
</root> </root>
</configuration> </configuration>
+30 -33
View File
@@ -1,59 +1,56 @@
# Module `simple-jwt-authzero` # JWT Toolbox :: Auth0
## Introduction ## Introduction
The `simple-jwt-authzero` module is an implementation of module `simple-jwt-facade` which uses the third-party library `com.auth0:java-jwt`. By using this module can help you use JWT to help you in your application. **JWT Toolbox :: Auth0** module is an implementation of module JWT Toolbox, which uses third-party
library `com.auth0:java-jwt`. By using this module can help you use JWT to help you in
## Prerequisites your application.
This whole `JDevKit` is developed by **JDK 17**, which means you have to use JDK 17 for better experience.
## Installation
> This module has already imported `simple-jwt-facade`, there is no need to import it again.
### If you are using `Maven` ### If you are using `Maven`
It is quite simple to install this module by `Maven`. The only thing you need to do is find your `pom.xml` file in the project, then find the `<dependencies>` node in the `<project>` node, and add the following codes to `<dependencies>` node: It is quite simple to install this module by `Maven`. The only thing you need to do is find your
`pom.xml` file in the project, then find the `<dependencies>` node in the `<project>` node, and add
the following codes to `<dependencies>` node:
```xml ```xml
<dependency> <dependency>
<groupId>cn.org.codecrafters</groupId> <groupId>com.onixbyte</groupId>
<artifactId>simple-jwt-authzero</artifactId> <artifactId>jwt-toolbox-auth0</artifactId>
<version>${simple-jwt-authzero.version}</version> <version>${jwt-toolbox-auth0.version}</version>
</dependency> </dependency>
``` ```
And run `mvn dependency:get` in your project root folder(i.e., if your `pom.xml` is located at `/path/to/your/project/pom.xml`, then your current work folder should be `/path/to/your/project`), then `Maven` will automatically download the `jar` archive from `Maven Central Repository`. This could be **MUCH EASIER** if you are using IDE(i.e., IntelliJ IDEA), the only thing you need to do is click the refresh button of `Maven`. And run `mvn dependency:get` in your project root folder(i.e., if your `pom.xml` is located at
`/path/to/your/project/pom.xml`, then your current work folder should be `/path/to/your/project`),
then `Maven` will automatically download the `jar` archive from `Maven Central Repository`.
This could be **MUCH EASIER** if you are using IDE(i.e., IntelliJ IDEA), the only thing you need to
do is click the refresh button of `Maven`.
If you are restricted using the Internet, and have to make `Maven` offline, you could follow the following steps. If you are restricted using the Internet, and have to make `Maven` offline, you could follow the
following steps.
1. Download the `jar` file from any place you can get and transfer the `jar` files to your work computer. 1. Download the `jar` file from any place you can get and transfer the `jar` files to your
2. Move the `jar` files to your local `Maven` Repository as the path of `/path/to/maven_local_repo/cn/org/codecrafters/simple-jwt-facade/`. work computer.
2. Move the `jar` files to your local `Maven` Repository as the path of
`/path/to/maven_local_repo/com/onixbyte/jwt-toolbox-auth0/`.
### If you are using `Gradle` ### If you are using `Gradle`
Add this module to your project with `Gradle` is much easier than doing so with `Maven`. Add this module to your project with `Gradle` is much easier than doing so with `Maven`.
Find `build.gradle` in the needed project, and add the following code to the `dependencies` closure in the build script: Find `build.gradle` in the needed project, and add the following code to the `dependencies` closure
in the build script:
```groovy ```groovy
implementation 'cn.org.codecrafters:simple-jwt-authzero:${simple-jwt-authzero.version}' implementation 'com.onixbyte:jwt-toolbox-auth0:${jwt-toolbox-auth0.version}'
``` ```
### If you are not using `Maven` or `Gradle`
1. Download the `jar` file from the Internet.
2. Create a folder in your project and name it as a name you like(i.e., for me, I prefer `vendor`).
3. Put the `jar` file to the folder you just created in Step 2.
4. Add this folder to your project `classpath`.
## Use the `AuthzeroTokenResolver`
We have implemented `TokenResolver` to make sure you can add JWT to your Java application as soon as possible. All you need to do is to create an instance of `com.onixbyte.jwt.auth0.AuthzeroTokenResolver` and other operations to JWT could follow our instruction in [`simple-jwt-facade`](../simple-jwt-facade/README.md).
## Contact ## Contact
If you have any suggestions, ideas, don't hesitate contacting us via [GitHub Issues](https://github.com/CodeCraftersCN/jdevkit/issues/new) or [Discord Community](https://discord.gg/NQK9tjcBB8). If you have any suggestions, ideas, don't hesitate contacting us via
[GitHub Issues](https://github.com/onixbyte/onixbyte-toolbox/issues/new).
If you face any bugs while using our library and you are able to fix any bugs in our library, we would be happy to accept pull requests from you on [GitHub](https://github.com/CodeCraftersCN/jdevkit/compare). If you face any bugs while using our library and you are able to fix any bugs in our library, we
would be happy to accept pull requests from you on
[GitHub](https://github.com/onixbyte/onixbyte-toolbox/compare).
+18 -13
View File
@@ -1,18 +1,23 @@
/* /*
* Copyright (C) 2024-2025 OnixByte. * Copyright (c) 2024-2025 OnixByte
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Permission is hereby granted, free of charge, to any person obtaining a copy
* you may not use this file except in compliance with the License. * of this software and associated documentation files (the "Software"), to deal
* You may obtain a copy of the License at * 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:
* *
* http://www.apache.org/licenses/LICENSE-2.0 * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* *
* Unless required by applicable law or agreed to in writing, software * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* distributed under the License is distributed on an "AS IS" BASIS, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* See the License for the specific language governing permissions and * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* limitations under the License. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/ */
import java.net.URI import java.net.URI
@@ -90,8 +95,8 @@ publishing {
} }
scm { scm {
connection = "scm:git:git://github.com:OnixByte/JDevKit.git" connection = "scm:git:git://github.com:onixbyte/onixbyte-toolbox.git"
developerConnection = "scm:git:git://github.com:OnixByte/JDevKit.git" developerConnection = "scm:git:git://github.com:onixbyte/onixbyte-toolbox.git"
url = projectGithubUrl url = projectGithubUrl
} }
@@ -0,0 +1,28 @@
/*
* Copyright (c) 2024-2025 OnixByte
*
* 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.onixbyte.jwt.auth0;
import com.onixbyte.jwt.TokenGenerator;
public class Auth0TokenGenerator implements TokenGenerator {
}
@@ -0,0 +1,46 @@
/*
* Copyright (c) 2024-2025 OnixByte
*
* 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.onixbyte.jwt.auth0;
import com.onixbyte.identitygenerator.IdentityGenerator;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.JWTVerifier;
import com.onixbyte.jwt.TokenParser;
/**
*
*
* @author zihluwang
* @version 3.0.0
* @see IdentityGenerator
* @see Algorithm
* @see JWTVerifier
* @see JWTCreator
* @see JWTCreator.Builder
* @since 1.0.0
*/
public class Auth0TokenParser implements TokenParser {
}
@@ -1,658 +0,0 @@
/*
* Copyright (C) 2024-2025 OnixByte.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.onixbyte.jwt.auth0;
import com.onixbyte.common.util.Base64Util;
import com.onixbyte.crypto.algorithm.ecdsa.ECPrivateKeyLoader;
import com.onixbyte.identitygenerator.IdentityGenerator;
import com.onixbyte.jwt.TokenPayload;
import com.onixbyte.jwt.TokenResolver;
import com.onixbyte.jwt.annotations.ExcludeFromPayload;
import com.onixbyte.jwt.annotations.TokenEnum;
import com.onixbyte.jwt.constants.PredefinedKeys;
import com.onixbyte.jwt.constants.TokenAlgorithm;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.auth0.jwt.interfaces.JWTVerifier;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.onixbyte.jwt.exceptions.IllegalKeyPairException;
import com.onixbyte.jwt.exceptions.IllegalSecretException;
import com.onixbyte.jwt.exceptions.UnsupportedAlgorithmException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.reflect.InvocationTargetException;
import java.security.interfaces.ECPrivateKey;
import java.security.interfaces.ECPublicKey;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
import java.util.function.BiFunction;
import java.util.function.Function;
/**
* The {@code AuthzeroTokenResolver} class is an implementation of the {@link TokenResolver}
* interface. It uses the {@code com.auth0:java-jwt} library to handle JSON Web Token (JWT)
* resolution. This resolver provides functionality to create, extract, verify, and renew JWT
* tokens using various algorithms and custom payload data.
* <p>
* <b>Usage:</b>
* To use the {@code AuthzeroTokenResolver}, first, create an instance of this class:
* <pre>{@code
* TokenResolver<DecodedJWT> tokenResolver =
* new AuthzeroTokenResolver(TokenAlgorithm.HS256,
* "Token Subject",
* "Token Issuer",
* "Token Secret");
* }</pre>
* <p>
* Then, you can utilize the various methods provided by this resolver to handle JWT tokens:
* <pre>{@code
* // Creating a new JWT token
* String token =
* tokenResolver.createToken(Duration.ofHours(1),
* "your_subject",
* "your_audience",
* customPayloads);
*
* // Extracting payload data from a JWT token
* DecodedJWT decodedJWT = tokenResolver.resolve(token);
* T payloadData = decodedJWT.extract(token, T.class);
*
* // Renewing an existing JWT token
* String renewedToken =
* tokenResolver.renew(token, Duration.ofMinutes(30), customPayloads);
* }</pre>
* <p>
* <b>Note:</b>
* It is essential to configure the appropriate algorithms, secret, and issuer according to your
* specific use case when using this resolver. Additionally, ensure that the
* {@code com.auth0:java-jwt} library is correctly configured in your project's dependencies.
*
* @author Zihlu Wang
* @version 1.1.1
* @see IdentityGenerator
* @see Algorithm
* @see JWTVerifier
* @see JWTCreator
* @see JWTCreator.Builder
* @since 1.0.0
*/
public class AuthzeroTokenResolver implements TokenResolver<DecodedJWT> {
private final static Logger log = LoggerFactory.getLogger(AuthzeroTokenResolver.class);
/**
* Create a builder of {@link AuthzeroTokenResolver}.
*
* @return a builder instance
*/
public static Builder builder() {
return new Builder();
}
/**
* Builder for {@link AuthzeroTokenResolver}
*/
public static class Builder {
/**
* IdentityGenerator used for generating unique identifiers for "jti" claim in JWT tokens.
*/
private IdentityGenerator<?> jtiCreator;
/**
* The algorithm used for signing and verifying JWT tokens.
*/
private Algorithm algorithm;
/**
* The issuer claim value to be included in JWT tokens.
*/
private String issuer;
/**
* Jackson JSON handler.
*/
private ObjectMapper objectMapper;
/**
* The secret to sign a JWT with HMAC based algorithm.
*/
private String secret;
/**
* The private key to sign a JWT with ECDSA based algorithm.
*/
private ECPrivateKey privateKey;
/**
* The public key to read a JWT with ECDSA based algorithm.
*/
private ECPublicKey publicKey;
/**
* Private constructor to prevent instantiation of this utility class.
*/
private Builder() {
}
/**
* Set the secret to sign a JWT.
*
* @param secret the secret
* @return the builder instance
*/
public Builder secret(String secret) {
this.secret = secret;
return this;
}
/**
* Set the key pair to sign a JWT.
*
* @param publicKey the pem formatted public key text
* @param privateKey the pem formatted private key text
* @return the builder instance
*/
public Builder keyPair(String publicKey, String privateKey) {
var keyLoader = new ECPrivateKeyLoader();
// this.publicKey = keyLoader.loadPublicKey(publicKey);
this.privateKey = keyLoader.loadPrivateKey(privateKey);
return this;
}
/**
* Set the algorithm to sign a JWT.
* <p>
* A secret required by HMAC-based algorithms, or key pair required by ECDSA-based
* algorithms need to be set before initialise an algorithm.
*
* @param algorithm an {@link TokenAlgorithm} value
* @return the builder instance
*/
public Builder algorithm(TokenAlgorithm algorithm) {
// check the secret or key pair before algorithm initialised
if (HMAC_ALGORITHMS.containsKey(algorithm)) {
if (Objects.isNull(secret) || secret.isBlank()) {
throw new IllegalSecretException("""
Please specify a secret before define an algorithm.""");
}
} else if (ECDSA_ALGORITHMS.containsKey(algorithm)) {
if (Objects.isNull(publicKey) || Objects.isNull(privateKey)) {
throw new IllegalKeyPairException("""
Please specify a ECDSA key pair before define an algorithm.""");
}
}
// initialise algorithm
this.algorithm = switch (algorithm) {
case HS256, HS384, HS512 -> HMAC_ALGORITHMS.get(algorithm).apply(secret);
case ES256, ES384, ES512 -> ECDSA_ALGORITHMS.get(algorithm)
.apply(publicKey, privateKey);
default -> throw new UnsupportedAlgorithmException("""
This algorithm is not supported yet.""");
};
return this;
}
/**
* Set the object mapper.
*
* @param objectMapper an object mapper
* @return the builder instance
*/
public Builder objectMapper(ObjectMapper objectMapper) {
this.objectMapper = objectMapper;
return this;
}
/**
* Set the creator of JWT id.
*
* @param jtiCreator a creator to create JWT id
* @return the builder instance
*/
public Builder jtiCreator(IdentityGenerator<?> jtiCreator) {
this.jtiCreator = jtiCreator;
return this;
}
/**
* Set the issuer of created JWT.
*
* @param issuer the person or organisation issued this JWT
* @return the builder instance
*/
public Builder issuer(String issuer) {
this.issuer = issuer;
return this;
}
/**
* Create an {@link AuthzeroTokenResolver} instance
*
* @return created instance
*/
public AuthzeroTokenResolver build() {
return new AuthzeroTokenResolver(jtiCreator, algorithm, issuer, objectMapper);
}
}
/**
* Creates a new token with the specified expiration duration, subject, and
* audience.
*
* @param expireAfter the duration after which the token will expire
* @param subject the subject of the token
* @param audience the audience for which the token is intended
* @return the generated token as a {@code String}
*/
@Override
public String createToken(Duration expireAfter, String audience, String subject) {
final var builder = JWT.create();
buildBasicInfo(builder, expireAfter, subject, audience);
return buildToken(builder);
}
/**
* Creates a new token with the specified expiration time, subject,
* audience, and custom payload data.
*
* @param expireAfter the duration after which the token will expire
* @param subject the subject of the token
* @param audience the audience for which the token is intended
* @param payloads the custom payload data to be included in the token
* @return the generated token as a {@code String}
*/
@Override
public String createToken(Duration expireAfter, String audience, String subject, Map<String, Object> payloads) {
// Create token.
final var builder = JWT.create();
buildBasicInfo(builder, expireAfter, subject, audience);
buildMapClaims(builder, payloads);
return buildToken(builder);
}
/**
* Creates a new token with the specified expiration time, subject,
* audience, and strongly-typed payload data.
*
* @param expireAfter the duration after which the token will expire
* @param subject the subject of the token
* @param audience the audience for which the token is intended
* @param payload the strongly-typed payload data to be included in the
* token
* @return the generated token as a {@code String}
*/
@Override
public <T extends TokenPayload> String createToken(Duration expireAfter, String audience, String subject, T payload) {
final var builder = JWT.create();
buildBasicInfo(builder, expireAfter, subject, audience);
var payloadClass = payload.getClass();
var fields = payloadClass.getDeclaredFields();
for (var field : fields) {
try {
var fieldName = field.getName();
// Skip the fields which are annotated with ExcludeFromPayload
if (field.isAnnotationPresent(ExcludeFromPayload.class))
continue;
Object invokeObj = payload;
var getter = payloadClass.getDeclaredMethod("get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1));
if (field.isAnnotationPresent(TokenEnum.class)) {
var tokenEnum = field.getAnnotation(TokenEnum.class);
invokeObj = getter.invoke(payload);
getter = field.getType().getDeclaredMethod("get" + tokenEnum.propertyName().substring(0, 1).toUpperCase() + tokenEnum.propertyName().substring(1));
}
// Build Claims
addClaim(builder, fieldName, getter.invoke(invokeObj));
} catch (IllegalAccessException e) {
log.error("Cannot access field {}!", field.getName());
} catch (NoSuchMethodException e) {
log.error("Unable to find setter according to given field name.", e);
} catch (InvocationTargetException e) {
log.info("Cannot invoke method.", e);
}
}
return buildToken(builder);
}
/**
* Resolves the given token into a {@link DecodedJWT} object.
*
* @param token the token to be resolved
* @return a {@link DecodedJWT} object
*/
@Override
public DecodedJWT resolve(String token) {
return jwtVerifier.verify(token);
}
/**
* Extracts the payload information from the given token and maps it to the
* specified target type.
*
* @param token the token from which to extract the payload
* @param targetType the target class representing the payload data type
* @return an instance of the specified target type with the extracted
* payload data, or {@code null} when extraction fails
*/
@Override
public <T extends TokenPayload> T extract(String token, Class<T> targetType) {
try {
// Get claims from token.
var payloads = objectMapper.readValue(Base64Util.decodeUrlComponents(resolve(token).getPayload()), new MapTypeReference());
// Get the no-argument constructor to create an instance.
var bean = targetType.getConstructor().newInstance();
for (var entry : payloads.entrySet()) {
// Jump all JWT pre-defined properties and the fields that are annotated to be excluded.
if (PredefinedKeys.KEYS.contains(entry.getKey()) || targetType.getDeclaredField(entry.getKey()).isAnnotationPresent(ExcludeFromPayload.class))
continue;
var field = targetType.getDeclaredField(entry.getKey());
var setter = targetType.getDeclaredMethod("set" + entry.getKey().substring(0, 1).toUpperCase() + entry.getKey().substring(1), field.getType());
var fieldValue = entry.getValue();
if (field.isAnnotationPresent(TokenEnum.class)) {
var annotation = field.getAnnotation(TokenEnum.class);
var enumStaticLoader = field.getType().getDeclaredMethod("loadBy" + annotation.propertyName().substring(0, 1).toUpperCase() + annotation.propertyName().substring(1), annotation.dataType().getMappedClass());
fieldValue = enumStaticLoader.invoke(null, fieldValue);
}
if (setter.canAccess(bean)) {
setter.invoke(bean, fieldValue);
} else {
log.error("Setter for field {} can't be accessed.", entry.getKey());
}
}
return bean;
} catch (JsonProcessingException e) {
log.error("Unable to read payload as a Map<String, Object>.", e);
} catch (InvocationTargetException | InstantiationException | IllegalAccessException |
NoSuchMethodException e) {
log.error("Unable to load the constructor or setter.", e);
} catch (NoSuchFieldException e) {
log.error("Unable to load the field.", e);
}
return null;
}
/**
* Re-generate a new token with the payload in the old one.
*
* @param oldToken the old token
* @param expireAfter how long the new token can be valid for
* @return re-generated token with the payload in the old one or
* {@code null} if an {@link JsonProcessingException} occurred.
*/
@Override
public String renew(String oldToken, Duration expireAfter) {
var resolved = resolve(oldToken);
try {
var payload = objectMapper.readValue(Base64Util.decodeUrlComponents(resolved.getPayload()), ObjectNode.class);
payload.remove(PredefinedKeys.KEYS);
var payloadMap = objectMapper.convertValue(payload, new MapTypeReference());
return createToken(expireAfter, resolved.getAudience().get(0), resolved.getSubject(), payloadMap);
} catch (JsonProcessingException e) {
log.error("Cannot read payload content, error details:", e);
}
return null;
}
/**
* Renews the given expired token with the specified custom payload data.
*
* @param oldToken the expired token to be renewed
* @param payload the custom payload data to be included in the renewed
* token
* @return the renewed token as a {@code String}
*/
@Override
public String renew(String oldToken, Duration expireAfter, Map<String, Object> payload) {
final var resolvedToken = this.resolve(oldToken);
var audience = resolvedToken.getAudience().get(0);
return createToken(expireAfter, audience, resolvedToken.getSubject(), payload);
}
/**
* Renews the given expired token with the specified custom payload data.
*
* @param oldToken the expiring token to be renewed
* @param payload the custom payload data to be included in the renewed
* token
* @return the renewed token as a {@code String}
*/
@Override
public String renew(String oldToken, Map<String, Object> payload) {
return renew(oldToken, Duration.ofMinutes(30), payload);
}
/**
* Renews the given expired token with the new specified strongly-typed
* payload data.
*
* @param oldToken the expiring token to be renewed
* @param payload the strongly-typed payload data to be included in the
* renewed token
* @return the renewed token as a {@code String}
*/
@Override
public <T extends TokenPayload> String renew(String oldToken, Duration expireAfter, T payload) {
final var resolvedToken = this.resolve(oldToken);
var audience = resolvedToken.getAudience().get(0);
return createToken(expireAfter, audience, resolvedToken.getSubject(), payload);
}
/**
* Renews the given expired token with the new specified strongly-typed
* payload data.
*
* @param <T> the type of the payload data, must implement
* {@link TokenPayload}
* @param oldToken the expired token to be renewed
* @param payload the strongly-typed payload data to be included in the
* renewed token
* @return the renewed token as a {@link String}
*/
@Override
public <T extends TokenPayload> String renew(String oldToken, T payload) {
return renew(oldToken, Duration.ofMinutes(30), payload);
}
/**
* Builds the basic information of the JSON Web Token (JWT) using the
* provided parameters and adds it to the JWTCreator.Builder.
*
* @param subject the subject claim value to be included in the JWT
* @param audience an array of audience claim values to be included in
* the JWT
* @param expireAfter the duration after which the JWT will expire
* @param builder the JWTCreator.Builder instance to which the basic
* information will be added
*/
private void buildBasicInfo(JWTCreator.Builder builder, Duration expireAfter, String subject, String... audience) {
var now = LocalDateTime.now();
// bind issuer (iss)
builder.withIssuer(issuer);
// bind issued at (iat)
builder.withIssuedAt(now.atZone(ZoneId.systemDefault()).toInstant());
// bind not before (nbf)
builder.withNotBefore(now.atZone(ZoneId.systemDefault()).toInstant());
// bind audience (aud)
builder.withAudience(audience);
// bind subject (sub)
builder.withSubject(subject);
// bind expire at (exp)
builder.withExpiresAt(now.plus(expireAfter).atZone(ZoneId.systemDefault()).toInstant());
// bind JWT Id (jti)
builder.withJWTId(jtiCreator.nextId().toString());
}
/**
* Add a claim to a builder.
*
* @param builder the builder to build this JSON Web Token
* @param name the property name
* @param value the property value
*/
private void addClaim(JWTCreator.Builder builder, String name, Object value) {
if (Objects.nonNull(value)) {
if (value instanceof Boolean v) {
builder.withClaim(name, v);
} else if (value instanceof Double v) {
builder.withClaim(name, v);
} else if (value instanceof Float v) {
builder.withClaim(name, v.doubleValue());
} else if (value instanceof Integer v) {
builder.withClaim(name, v);
} else if (value instanceof Long v) {
builder.withClaim(name, v);
} else if (value instanceof String v) {
builder.withClaim(name, v);
} else if (value instanceof Date v) {
builder.withClaim(name, v);
} else if (value instanceof List<?> v) {
builder.withClaim(name, v);
} else {
log.warn("""
Unable to determine the type of field {}, we will handle it as a String.""", name);
builder.withClaim(name, value.toString());
}
} else {
builder.withNullClaim(name);
}
}
/**
* Builds the custom claims of the JSON Web Token (JWT) using the provided
* Map of claims and adds them to the JWTCreator.Builder.
* <p>
* This method is used to add custom claims to the JWT. It takes a Map of
* claims, where each entry represents a custom claim name (key) and its
* corresponding value (value). The custom claims will be added to the JWT
* using the JWTCreator.Builder.
*
* @param claims a Map containing the custom claims to be added to the JWT
* @param builder the JWTCreator.Builder instance to which the custom
* claims will be added
*/
private void buildMapClaims(JWTCreator.Builder builder, Map<String, Object> claims) {
if (Objects.nonNull(claims)) {
for (var e : claims.entrySet()) {
addClaim(builder, e.getKey(), e.getValue());
}
}
}
/**
* Finish creating a token.
* <p>
* This is the final step of create a token, to sign this token.
*
* @param builder the builder to build this JWT
* @return the generated token as a {@code String}
*/
private String buildToken(JWTCreator.Builder builder) {
return builder.sign(algorithm);
}
/**
* Default type reference for Map.
*/
public static class MapTypeReference extends TypeReference<Map<String, Object>> {
MapTypeReference() {
}
}
/**
* IdentityGenerator used for generating unique identifiers for "jti" claim in JWT tokens.
*/
private final IdentityGenerator<?> jtiCreator;
/**
* The algorithm used for signing and verifying JWT tokens.
*/
private final Algorithm algorithm;
/**
* The issuer claim value to be included in JWT tokens.
*/
private final String issuer;
/**
* The JSON Web Token resolver.
*/
private final JWTVerifier jwtVerifier;
/**
* Jackson JSON handler.
*/
private final ObjectMapper objectMapper;
/**
* A map contains all HMAC-SHA based algorithms.
*/
public static final Map<TokenAlgorithm, Function<String, Algorithm>> HMAC_ALGORITHMS = Map.of(
TokenAlgorithm.HS256, Algorithm::HMAC256,
TokenAlgorithm.HS384, Algorithm::HMAC384,
TokenAlgorithm.HS512, Algorithm::HMAC512
);
/**
* A map contains all ECDSA based algorithms.
*/
public static final Map<TokenAlgorithm, BiFunction<ECPublicKey, ECPrivateKey, Algorithm>> ECDSA_ALGORITHMS = Map.of(
TokenAlgorithm.ES256, Algorithm::ECDSA256,
TokenAlgorithm.ES384, Algorithm::ECDSA384,
TokenAlgorithm.ES512, Algorithm::ECDSA512
);
/**
* Private constructor to prevent instantiation of this utility class.
*
* @param jtiCreator a creator that can create JWT id
* @param algorithm an algorithm to sign this JWT
* @param issuer the person or organisation who issued this JWT
* @param objectMapper a mapper for handling JSON serialisation and deserialization
*/
private AuthzeroTokenResolver(IdentityGenerator<?> jtiCreator, Algorithm algorithm, String issuer, ObjectMapper objectMapper) {
this.jtiCreator = jtiCreator;
this.algorithm = algorithm;
this.issuer = issuer;
this.objectMapper = objectMapper;
this.jwtVerifier = JWT.require(algorithm).build();
}
}
@@ -1,26 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!-- <!--
~ Copyright (C) 2023-2024 OnixByte. ~ Copyright (c) 2024-2025 OnixByte
~ ~
~ Licensed under the Apache License, Version 2.0 (the "License"); ~ Permission is hereby granted, free of charge, to any person obtaining a copy
~ you may not use this file except in compliance with the License. ~ of this software and associated documentation files (the "Software"), to deal
~ You may obtain a copy of the License at ~ 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:
~ ~
~ http://www.apache.org/licenses/LICENSE-2.0 ~ The above copyright notice and this permission notice shall be included in all
~ copies or substantial portions of the Software.
~ ~
~ Unless required by applicable law or agreed to in writing, software ~ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
~ distributed under the License is distributed on an "AS IS" BASIS, ~ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ~ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
~ ~ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
~ See the License for the specific language governing permissions and ~ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
~ limitations under the License. ~ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
~ SOFTWARE.
--> -->
<configuration> <configuration>
<property name="COLOURFUL_OUTPUT" value="%black(%date{'dd MMM, yyyy HH:mm:ss', Asia/Hong_Kong, en-UK}) %highlight(%-5level) %black(---) %black([%10.10t]) %cyan(%-20.20logger{20}) %black(:) %msg%n"/> <property name="COLOURFUL_OUTPUT"
<property name="STANDARD_OUTPUT" value="%date{'dd MMM, yyyy HH:mm:ss', Asia/Hong_Kong, en-UK} %-5level %black(---) [%10.10t] %-20.20logger{20} : %msg%n"/> value="%black(%date{'dd MMM, yyyy HH:mm:ss', Asia/Hong_Kong, en-UK}) %highlight(%-5level) %black(---) %black([%10.10t]) %cyan(%-20.20logger{20}) %black(:) %msg%n"/>
<property name="STANDARD_OUTPUT"
value="%date{'dd MMM, yyyy HH:mm:ss', Asia/Hong_Kong, en-UK} %-5level %black(---) [%10.10t] %-20.20logger{20} : %msg%n"/>
<statusListener class="ch.qos.logback.core.status.NopStatusListener" /> <statusListener class="ch.qos.logback.core.status.NopStatusListener"/>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${COLOURFUL_OUTPUT}</pattern> <pattern>${COLOURFUL_OUTPUT}</pattern>
@@ -29,4 +36,4 @@
<root level="INFO"> <root level="INFO">
<appender-ref ref="STDOUT"/> <appender-ref ref="STDOUT"/>
</root> </root>
</configuration> </configuration>
@@ -1,27 +0,0 @@
/*
* Copyright (C) 2023 CodeCraftersCN.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.onixbyte.jwt.auth0.test;
/**
* TestAuthzeroTokenResolver
*
* @author Zihlu Wang
*/
public class TestAuthzeroTokenResolver {
}
+25 -17
View File
@@ -1,12 +1,11 @@
# Module `simple-jwt-facade` # JWT Toolbox :: Facade
## Introduction ## Introduction
The `simple-jwt-facade` module is a lightweight and easy-to-use façade for working with JSON Web Tokens (JWT) in Java applications. It provides a simplified interface and utilities to handle the creation, validation, renewal, and processing of JWTs without the need for complex configurations or third-party dependencies. The JWT Toolbox Facade module is a lightweight and easy-to-use façade for working with JSON Web
Tokens (JWT) in Java applications. It provides a simplified interface and utilities to handle the
## Prerequisites creation, validation, renewal, and processing of JWTs without the need for complex configurations or
third-party dependencies.
This whole `JDevKit` is developed by **JDK 17**, which means you have to use JDK 17 for better experience.
## Installation ## Installation
@@ -16,27 +15,36 @@ It is quite simple to install this module by `Maven`. The only thing you need to
```xml ```xml
<dependency> <dependency>
<groupId>cn.org.codecrafters</groupId> <groupId>com.onixbyte</groupId>
<artifactId>simple-jwt-facade</artifactId> <artifactId>jwt-toolkit-facade</artifactId>
<version>${simple-jwt-facade.version}</version> <version>${jwt-toolkit-facade.version}</version>
</dependency> </dependency>
``` ```
And run `mvn dependency:get` in your project root folder(i.e., if your `pom.xml` is located at `/path/to/your/project/pom.xml`, then your current work folder should be `/path/to/your/project`), then `Maven` will automatically download the `jar` archive from `Maven Central Repository`. This could be **MUCH EASIER** if you are using IDE(i.e., IntelliJ IDEA), the only thing you need to do is click the refresh button of `Maven`. And run `mvn dependency:get` in your project root folder(i.e., if your `pom.xml` is located at
`/path/to/your/project/pom.xml`, then your current work folder should be `/path/to/your/project`),
then `Maven` will automatically download the `jar` archive from `Maven Central Repository`.
If you are restricted using the Internet, and have to make `Maven` offline, you could follow the following steps. This could be **MUCH EASIER** if you are using IDE(i.e., IntelliJ IDEA), the only thing you need to
do is click the refresh button of `Maven`.
1. Download the `jar` file from any place you can get and transfer the `jar` files to your work computer. If you are restricted using the Internet, and have to make `Maven` offline, you could follow the
2. Move the `jar` files to your local `Maven` Repository as the path of `/path/to/maven_local_repo/cn/org/codecrafters/simple-jwt-facade/`. following steps.
1. Download the `jar` file from any place you can get and transfer the `jar` files to your
work computer.
2. Move the `jar` files to your local `Maven` Repository as the path of
`/path/to/maven_local_repo/com/onixbyte/jwt-toolbox-facade/`.
### If you are using `Gradle` ### If you are using `Gradle`
Add this module to your project with `Gradle` is much easier than doing so with `Maven`. Add this module to your project with `Gradle` is much easier than doing so with `Maven`.
Find `build.gradle` in the needed project, and add the following code to the `dependencies` closure in the build script: Find `build.gradle` in the needed project, and add the following code to the `dependencies` closure
in the build script:
```groovy ```groovy
implementation 'cn.org.codecrafters:simple-jwt-facade:${simple-jwt-facade.version}' implementation 'com.onixbyte:jwt-toolbox-facade:${jwt-toolbox-facade.version}'
``` ```
### If you are not using `Maven` or `Gradle` ### If you are not using `Maven` or `Gradle`
@@ -67,7 +75,7 @@ After doing all these, an implemented `TokenResolver` is ready to process JWTs.
You will need an instance of the implementation to process JWTs. You will need an instance of the implementation to process JWTs.
```java ```java
var tokenResolver = new ImplementedTokenResolver(/* arguments you declared */) var tokenResolver = new ImplementedTokenResolver(/* arguments you declared */);
``` ```
## Create a JSON Web Token with `TokenResolver` ## Create a JSON Web Token with `TokenResolver`
@@ -124,4 +132,4 @@ This method allows you to pass new custom payload into the updated token. The ne
If you have any suggestions, ideas, don't hesitate contacting us via [GitHub Issues](https://github.com/CodeCraftersCN/jdevkit/issues/new) or [Discord Community](https://discord.gg/NQK9tjcBB8). If you have any suggestions, ideas, don't hesitate contacting us via [GitHub Issues](https://github.com/CodeCraftersCN/jdevkit/issues/new) or [Discord Community](https://discord.gg/NQK9tjcBB8).
If you face any bugs while using our library and you are able to fix any bugs in our library, we would be happy to accept pull requests from you on [GitHub](https://github.com/CodeCraftersCN/jdevkit/compare). If you face any bugs while using our library and you are able to fix any bugs in our library, we would be happy to accept pull requests from you on [GitHub](https://github.com/CodeCraftersCN/jdevkit/compare).
+19 -13
View File
@@ -1,19 +1,25 @@
/* /*
* Copyright (C) 2024-2025 OnixByte. * Copyright (c) 2024-2025 OnixByte
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Permission is hereby granted, free of charge, to any person obtaining a copy
* you may not use this file except in compliance with the License. * of this software and associated documentation files (the "Software"), to deal
* You may obtain a copy of the License at * 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:
* *
* http://www.apache.org/licenses/LICENSE-2.0 * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* *
* Unless required by applicable law or agreed to in writing, software * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* distributed under the License is distributed on an "AS IS" BASIS, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* See the License for the specific language governing permissions and * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* limitations under the License. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/ */
import java.net.URI import java.net.URI
plugins { plugins {
@@ -86,8 +92,8 @@ publishing {
} }
scm { scm {
connection = "scm:git:git://github.com:OnixByte/JDevKit.git" connection = "scm:git:git://github.com:onixbyte/onixbyte-toolbox.git"
developerConnection = "scm:git:git://github.com:OnixByte/JDevKit.git" developerConnection = "scm:git:git://github.com:onixbyte/onixbyte-toolbox.git"
url = projectGithubUrl url = projectGithubUrl
} }
@@ -1,18 +1,23 @@
/* /*
* Copyright (C) 2024-2025 OnixByte. * Copyright (c) 2024-2025 OnixByte
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Permission is hereby granted, free of charge, to any person obtaining a copy
* you may not use this file except in compliance with the License. * of this software and associated documentation files (the "Software"), to deal
* You may obtain a copy of the License at * 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:
* *
* http://www.apache.org/licenses/LICENSE-2.0 * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* *
* Unless required by applicable law or agreed to in writing, software * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* distributed under the License is distributed on an "AS IS" BASIS, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* See the License for the specific language governing permissions and * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* limitations under the License. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/ */
package com.onixbyte.jwt; package com.onixbyte.jwt;
@@ -24,18 +29,16 @@ import org.slf4j.LoggerFactory;
import java.util.Random; import java.util.Random;
/** /**
* {@code SecretCreator} is a utility class that provides methods to generate * {@code SecretCreator} is a utility class that provides methods to generate secure secret strings.
* secure secret strings. The generated secrets can be used as cryptographic * The generated secrets can be used as cryptographic keys or passwords for various
* keys or passwords for various security-sensitive purposes. * security-sensitive purposes.
* *
* @author Zihlu Wang * @author zihluwang
* @version 1.1.0 * @version 3.0.0
* @since 1.0.0 * @since 1.0.0
*/ */
public final class SecretCreator { public final class SecretCreator {
private final static Logger log = LoggerFactory.getLogger(SecretCreator.class);
/** /**
* Generates a secure secret with the specified length and character sets. * Generates a secure secret with the specified length and character sets.
* *
@@ -0,0 +1,26 @@
/*
* Copyright (c) 2024-2025 OnixByte
*
* 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.onixbyte.jwt;
public interface TokenGenerator {
}
@@ -0,0 +1,26 @@
/*
* Copyright (c) 2024-2025 OnixByte
*
* 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.onixbyte.jwt;
public interface TokenParser {
}
@@ -1,45 +0,0 @@
/*
* Copyright (C) 2024-2025 OnixByte.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.onixbyte.jwt;
/**
* {@code TokenPayload} interface is used to mark a data class as suitable
* for being used as the payload in a JSON Web Token (JWT). Any class
* implementing this interface can be used to represent the payload data that
* will be included in a JWT.
* <p>
* Implementing this interface indicates that the data class contains
* information that needs to be securely transmitted and verified as part of a
* JWT. The payload typically contains claims or attributes that provide
* additional information about the JWT subject or context.
* <p>
* <b>Usage:</b>
* To use a class as a JWT payload, simply implement the {@code TokenPayload}
* interface in the data class:
* <pre>
* public class UserData implements TokenPayload {
* // Class implementation with payload data...
* }
* </pre>
*
* @author Zihlu Wang
* @version 1.1.0
* @since 1.0.0
*/
public interface TokenPayload {
}
@@ -1,184 +0,0 @@
/*
* Copyright (C) 2024-2025 OnixByte.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.onixbyte.jwt;
import java.time.Duration;
import java.util.Map;
/**
* {@code TokenResolver} defines methods for creating, extracting, and
* renewing tokens, particularly JSON Web Tokens (JWTs). It provides a set of
* methods to generate tokens with various payload configurations, extract
* payload from tokens, and renew expired tokens.
* <p>
* <b>Token Creation:</b>
* The interface provides overloaded methods for creating tokens with different
* payload configurations, including expiration time, audience, subject, and
* custom payload data. Clients can choose the appropriate method based on
* their specific token requirements.
* <p>
* <b>Token Extraction:</b>
* The interface includes methods to extract payload information from a given
* token. Clients can use these methods to obtain the payload data encoded in
* the token.
* <p>
* <b>Token Renewal:</b>
* The interface also offers methods for token renewal. Clients can renew an
* expired token by providing a new expiration time, audience, subject, and
* optional custom payload data.
*
* @param <ResolvedTokenType> the type of the result obtained by the
* third-party library when parsing JWTs
* @author Zihlu Wang
* @version 1.1.0
* @since 1.0.0
*/
public interface TokenResolver<ResolvedTokenType> {
/**
* Creates a new token with the specified expiration time, subject, and
* audience.
*
* @param expireAfter the duration after which the token will expire
* @param subject the subject of the token
* @param audience the audience for which the token is intended
* @return the generated token as a {@code String}
*/
String createToken(Duration expireAfter, String audience, String subject);
/**
* Creates a new token with the specified expiration time, subject,
* audience, and custom payload data.
*
* @param expireAfter the duration after which the token will expire
* @param subject the subject of the token
* @param audience the audience for which the token is intended
* @param payload the custom payload data to be included in the token
* @return the generated token as a {@code String}
*/
String createToken(Duration expireAfter, String audience, String subject, Map<String, Object> payload);
/**
* Creates a new token with the specified expiration time, subject,
* audience, and strongly-typed payload data.
*
* @param <T> the type of the payload data, must implement
* {@link TokenPayload}
* @param expireAfter the duration after which the token will expire
* @param subject the subject of the token
* @param audience the audience for which the token is intended
* @param payload the strongly-typed payload data to be included in the
* token
* @return the generated token as a {@code String}
*/
<T extends TokenPayload> String createToken(Duration expireAfter, String audience, String subject, T payload);
/**
* Resolves the given token into a ResolvedTokenType object.
*
* @param token the token to be resolved
* @return a ResolvedTokenType object
*/
ResolvedTokenType resolve(String token);
/**
* Extracts the payload information from the given token and maps it to the
* specified target type.
*
* @param <T> the target type to which the payload data will be
* mapped
* @param token the token from which to extract the payload
* @param targetType the target class representing the payload data type
* @return an instance of the specified target type with the extracted
* payload data
*/
<T extends TokenPayload> T extract(String token, Class<T> targetType);
/**
* Re-generate a new token with the payload in the old one.
*
* @param oldToken the old token
* @param expireAfter how long the new token can be valid for
* @return re-generated token with the payload in the old one
*/
String renew(String oldToken, Duration expireAfter);
/**
* Re-generate a new token with the payload in the old one.
*
* @param oldToken the old token
* @return re-generated token with the payload in the old one
* @see #renew(String, Duration)
*/
default String renew(String oldToken) {
return renew(oldToken, Duration.ofMinutes(30));
}
/**
* Renews the given expired token with the specified custom payload data.
*
* @param oldToken the expired token to be renewed
* @param expireAfter specify when does the new token invalid
* @param payload the custom payload data to be included in the renewed
* token
* @return the renewed token as a {@code String}
*/
String renew(String oldToken, Duration expireAfter, Map<String, Object> payload);
/**
* Renews the given expired token with the specified custom payload data.
*
* @param oldToken the expired token to be renewed
* @param payload the custom payload data to be included in the renewed
* token
* @return the renewed token as a {@code String}
*/
default String renew(String oldToken, Map<String, Object> payload) {
return renew(oldToken, Duration.ofMinutes(30), payload);
}
/**
* Renews the given expired token with the specified strongly-typed
* payload data.
*
* @param <T> the type of the payload data, must implement
* {@link TokenPayload}
* @param oldToken the expired token to be renewed
* @param expireAfter specify when does the new token invalid
* @param payload the strongly-typed payload data to be included in the
* renewed token
* @return the renewed token as a {@code String}
*/
<T extends TokenPayload> String renew(String oldToken, Duration expireAfter, T payload);
/**
* Renews the given expired token with the specified strongly-typed
* payload data.
*
* @param <T> the type of the payload data, must implement
* {@link TokenPayload}
* @param oldToken the expired token to be renewed
* @param payload the strongly-typed payload data to be included in the
* renewed token
* @return the renewed token as a {@code String}
*/
default <T extends TokenPayload> String renew(String oldToken, T payload) {
return renew(oldToken, Duration.ofMinutes(30), payload);
}
}
@@ -1,60 +0,0 @@
/*
* Copyright (C) 2024-2025 OnixByte.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.onixbyte.jwt.annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Annotation {@code ExcludeFromPayload} is used to mark a property of a data
* class that should be excluded from being automatically injected into the
* JSON Web Token (JWT) payload during token generation. When a property is
* annotated by this annotation, it will not be included in the JWT payloads.
* <p>
* <b>Usage:</b>
* To exclude a property from the JWT payload, annotate the property with
* {@code @ExcludeFromPayload}:
*
* <pre>{@code
* public class UserData implements TokenPayload {
* private String username;
*
* // This property will not be included in the JWT payload
* @ExcludeFromPayload
* private String sensitiveData;
*
* // Getters and setters...
* }
* }</pre>
* <p>
* <b>Note:</b>
* This annotation should be used on properties that are not intended to
* be included in the JWT payload due to their sensitive nature or for other
* reasons only. It is important to carefully choose which properties are
* excluded from the payload to ensure the JWT remains secure and efficient.
*
* @author Zihlu Wang
* @version 1.1.0
* @since 1.0.0
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
public @interface ExcludeFromPayload {
}
@@ -1,51 +0,0 @@
/*
* Copyright (C) 2024-2025 OnixByte.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.onixbyte.jwt.annotations;
import com.onixbyte.jwt.constants.TokenDataType;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* This annotation marks the enum field declared in payload class will be handled as basic data
* types in {@link TokenDataType}.
*
* @author Zihlu Wang
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
public @interface TokenEnum {
/**
* The name of the field of the base data corresponding to the enumeration data.
*
* @return the name of the property
*/
String propertyName();
/**
* The attribute {@code dataType} specifies what base data type to treat this enum as.
*
* @return the data type of the token
*/
TokenDataType dataType();
}
@@ -1,18 +1,23 @@
/* /*
* Copyright (C) 2024-2025 OnixByte. * Copyright (c) 2024-2025 OnixByte
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Permission is hereby granted, free of charge, to any person obtaining a copy
* you may not use this file except in compliance with the License. * of this software and associated documentation files (the "Software"), to deal
* You may obtain a copy of the License at * 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:
* *
* http://www.apache.org/licenses/LICENSE-2.0 * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* *
* Unless required by applicable law or agreed to in writing, software * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* distributed under the License is distributed on an "AS IS" BASIS, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* See the License for the specific language governing permissions and * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* limitations under the License. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/ */
package com.onixbyte.jwt.constants; package com.onixbyte.jwt.constants;
@@ -26,13 +31,13 @@ import java.util.List;
* <p> * <p>
* The class provides the following standard JWT claim constants: * The class provides the following standard JWT claim constants:
* <ul> * <ul>
* <li>{@link #ISSUER}: Represents the "iss" (Issuer) claim.</li> * <li>{@link #ISSUER}: Represents the "iss" (Issuer) claim.</li>
* <li>{@link #SUBJECT}: Represents the "sub" (Subject) claim.</li> * <li>{@link #SUBJECT}: Represents the "sub" (Subject) claim.</li>
* <li>{@link #AUDIENCE}: Represents the "aud" (Audience) claim.</li> * <li>{@link #AUDIENCE}: Represents the "aud" (Audience) claim.</li>
* <li>{@link #EXPIRATION_TIME}: Represents the "exp" (Expiration Time) claim.</li> * <li>{@link #EXPIRATION_TIME}: Represents the "exp" (Expiration Time) claim.</li>
* <li>{@link #NOT_BEFORE}: Represents the "nbf" (Not Before) claim.</li> * <li>{@link #NOT_BEFORE}: Represents the "nbf" (Not Before) claim.</li>
* <li>{@link #ISSUED_AT}: Represents the "iat" (Issued At) claim.</li> * <li>{@link #ISSUED_AT}: Represents the "iat" (Issued At) claim.</li>
* <li>{@link #JWT_ID}: Represents the "jti" (JWT ID) claim.</li> * <li>{@link #JWT_ID}: Represents the "jti" (JWT ID) claim.</li>
* </ul> * </ul>
* <p> * <p>
* The class also contains a list of all the standard claim constants, accessible via the {@link * The class also contains a list of all the standard claim constants, accessible via the {@link
@@ -43,7 +48,7 @@ import java.util.List;
* the standard JWT claim constants. * the standard JWT claim constants.
* *
* @author zihluwang * @author zihluwang
* @version 1.1.0 * @version 3.0.0
* @since 1.0.0 * @since 1.0.0
*/ */
public final class PredefinedKeys { public final class PredefinedKeys {
@@ -86,8 +91,15 @@ public final class PredefinedKeys {
/** /**
* List containing all the standard JWT claim constants. * List containing all the standard JWT claim constants.
*/ */
public static final List<String> KEYS = public static final List<String> KEYS = List.of(
List.of(ISSUER, SUBJECT, AUDIENCE, EXPIRATION_TIME, NOT_BEFORE, ISSUED_AT, JWT_ID); ISSUER,
SUBJECT,
AUDIENCE,
EXPIRATION_TIME,
NOT_BEFORE,
ISSUED_AT,
JWT_ID
);
/** /**
* Private constructor to prevent instantiation of this utility class. * Private constructor to prevent instantiation of this utility class.
@@ -1,24 +1,27 @@
/* /*
* Copyright (C) 2024-2025 OnixByte. * Copyright (c) 2024-2025 OnixByte
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Permission is hereby granted, free of charge, to any person obtaining a copy
* you may not use this file except in compliance with the License. * of this software and associated documentation files (the "Software"), to deal
* You may obtain a copy of the License at * 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:
* *
* http://www.apache.org/licenses/LICENSE-2.0 * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* *
* Unless required by applicable law or agreed to in writing, software * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* distributed under the License is distributed on an "AS IS" BASIS, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* See the License for the specific language governing permissions and * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* limitations under the License. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/ */
package com.onixbyte.jwt.constants; package com.onixbyte.jwt.constants;
import java.util.List;
/** /**
* The {@code TokenAlgorithm} enum class defines the algorithms that can be * The {@code TokenAlgorithm} enum class defines the algorithms that can be
* used for signing and verifying JSON Web Tokens (JWT). JWT allows various * used for signing and verifying JSON Web Tokens (JWT). JWT allows various
@@ -28,19 +31,19 @@ import java.util.List;
* <p> * <p>
* <b>Supported Algorithms:</b> * <b>Supported Algorithms:</b>
* <ul> * <ul>
* <li>{@link TokenAlgorithm#HS256}: HMAC SHA-256</li> * <li>{@link TokenAlgorithm#HS256}: HMAC SHA-256</li>
* <li>{@link TokenAlgorithm#HS384}: HMAC SHA-384</li> * <li>{@link TokenAlgorithm#HS384}: HMAC SHA-384</li>
* <li>{@link TokenAlgorithm#HS512}: HMAC SHA-512</li> * <li>{@link TokenAlgorithm#HS512}: HMAC SHA-512</li>
* <li>{@link TokenAlgorithm#RS256}: RSA PKCS#1 v1.5 with SHA-256</li> * <li>{@link TokenAlgorithm#RS256}: RSA PKCS#1 v1.5 with SHA-256</li>
* <li>{@link TokenAlgorithm#RS384}: RSA PKCS#1 v1.5 with SHA-384</li> * <li>{@link TokenAlgorithm#RS384}: RSA PKCS#1 v1.5 with SHA-384</li>
* <li>{@link TokenAlgorithm#RS512}: RSA PKCS#1 v1.5 with SHA-512</li> * <li>{@link TokenAlgorithm#RS512}: RSA PKCS#1 v1.5 with SHA-512</li>
* <li>{@link TokenAlgorithm#ES256}: ECDSA with SHA-256</li> * <li>{@link TokenAlgorithm#ES256}: ECDSA with SHA-256</li>
* <li>{@link TokenAlgorithm#ES384}: ECDSA with SHA-384</li> * <li>{@link TokenAlgorithm#ES384}: ECDSA with SHA-384</li>
* <li>{@link TokenAlgorithm#ES512}: ECDSA with SHA-512</li> * <li>{@link TokenAlgorithm#ES512}: ECDSA with SHA-512</li>
* </ul> * </ul>
* *
* @author Zihlu Wang * @author zihluwang
* @version 1.1.0 * @version 3.0.0
* @since 1.0.0 * @since 1.0.0
*/ */
public enum TokenAlgorithm { public enum TokenAlgorithm {
@@ -91,18 +94,4 @@ public enum TokenAlgorithm {
ES512, ES512,
; ;
/**
* HMAC-based algorithms.
*/
public static final List<TokenAlgorithm> HMAC_ALGORITHMS = List.of(
TokenAlgorithm.HS256, TokenAlgorithm.HS384, TokenAlgorithm.HS512
);
/**
* ECDSA-based algorithms.
*/
public static final List<TokenAlgorithm> ECDSA_ALGORITHMS = List.of(
TokenAlgorithm.ES256, TokenAlgorithm.ES384, TokenAlgorithm.ES512
);
} }
@@ -1,78 +0,0 @@
/*
* Copyright (C) 2024-2025 OnixByte.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.onixbyte.jwt.constants;
/**
* The base data types used to process enum data.
*
* @author Zihlu Wang
*/
public enum TokenDataType {
/**
* Marks enumeration being processed as Boolean.
*/
BOOLEAN(Boolean.class),
/**
* Marks enumeration being processed as Double.
*/
DOUBLE(Long.class),
/**
* Marks enumeration being processed as Float.
*/
FLOAT(Float.class),
/**
* Marks enumeration being processed as Integer.
*/
INTEGER(Integer.class),
/**
* Marks enumeration being processed as Long.
*/
LONG(Long.class),
/**
* Marks enumeration being processed as String.
*/
STRING(String.class),
;
/**
* The mapped class to this mark.
*/
private final Class<?> mappedClass;
/**
* Create a TokenDataType with a mapped class.
*/
TokenDataType(Class<?> mappedClass) {
this.mappedClass = mappedClass;
}
/**
* Return the target mapped class.
*
* @return mapped class
*/
public Class<?> getMappedClass() {
return mappedClass;
}
}
@@ -1,18 +1,23 @@
/* /*
* Copyright (C) 2024-2025 OnixByte. * Copyright (c) 2024-2025 OnixByte
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Permission is hereby granted, free of charge, to any person obtaining a copy
* you may not use this file except in compliance with the License. * of this software and associated documentation files (the "Software"), to deal
* You may obtain a copy of the License at * 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:
* *
* http://www.apache.org/licenses/LICENSE-2.0 * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* *
* Unless required by applicable law or agreed to in writing, software * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* distributed under the License is distributed on an "AS IS" BASIS, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* See the License for the specific language governing permissions and * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* limitations under the License. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/ */
package com.onixbyte.jwt.exceptions; package com.onixbyte.jwt.exceptions;
@@ -21,7 +26,7 @@ package com.onixbyte.jwt.exceptions;
* {@link IllegalKeyPairException} indicates an exception that the key pair is invalid. * {@link IllegalKeyPairException} indicates an exception that the key pair is invalid.
* *
* @author zihluwang * @author zihluwang
* @version 1.6.0 * @version 3.0.0
*/ */
public class IllegalKeyPairException extends RuntimeException { public class IllegalKeyPairException extends RuntimeException {
@@ -1,24 +1,29 @@
/* /*
* Copyright (C) 2024-2025 OnixByte. * Copyright (c) 2024-2025 OnixByte
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Permission is hereby granted, free of charge, to any person obtaining a copy
* you may not use this file except in compliance with the License. * of this software and associated documentation files (the "Software"), to deal
* You may obtain a copy of the License at * 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:
* *
* http://www.apache.org/licenses/LICENSE-2.0 * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* *
* Unless required by applicable law or agreed to in writing, software * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* distributed under the License is distributed on an "AS IS" BASIS, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* See the License for the specific language governing permissions and * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* limitations under the License. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/ */
package com.onixbyte.jwt.exceptions; package com.onixbyte.jwt.exceptions;
/** /**
* {@link IllegalKeyPairException} indicates the secret to sign a JWT is illegal. * {@code IllegalKeyPairException} indicates the secret to sign a JWT is illegal.
* *
* @author zihluwang * @author zihluwang
* @version 1.6.0 * @version 1.6.0
@@ -1,28 +1,28 @@
/* /*
* Copyright (C) 2024-2025 OnixByte. * Copyright (c) 2024-2025 OnixByte
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Permission is hereby granted, free of charge, to any person obtaining a copy
* you may not use this file except in compliance with the License. * of this software and associated documentation files (the "Software"), to deal
* You may obtain a copy of the License at * 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:
* *
* http://www.apache.org/licenses/LICENSE-2.0 * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* *
* Unless required by applicable law or agreed to in writing, software * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* distributed under the License is distributed on an "AS IS" BASIS, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* See the License for the specific language governing permissions and * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* limitations under the License. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/ */
package com.onixbyte.jwt.exceptions; package com.onixbyte.jwt.exceptions;
import com.onixbyte.jwt.TokenResolver;
/** /**
* This {@code UnsupportedAlgorithmException} represents the given
* algorithm is not supported by {@link
* TokenResolver} yet.
* <p> * <p>
* If you want the supports to an unsupported algorithm, you could * If you want the supports to an unsupported algorithm, you could
* <ul> * <ul>
@@ -30,42 +30,39 @@ import com.onixbyte.jwt.TokenResolver;
* <li>Communicate with us on Discord Community.</li> * <li>Communicate with us on Discord Community.</li>
* </ul> * </ul>
* *
* @author Zihlu Wang * @author zihluwang
* @version 1.1.0 * @version 3.0.0
* @since 1.0.0
*/ */
public class UnsupportedAlgorithmException extends RuntimeException { public class UnsupportedAlgorithmException extends RuntimeException {
/** /**
* Constructs a new {@code UnsupportedAlgorithmException} with {@code null} * Constructs a new {@code UnsupportedAlgorithmException} with {@code null} as its
* as its detail message. The cause is not initialized, and may * detail message. The cause is not initialized, and may subsequently be initialized by a call
* subsequently be initialized by a call to {@link #initCause}. * to {@link #initCause}.
*/ */
public UnsupportedAlgorithmException() { public UnsupportedAlgorithmException() {
} }
/** /**
* Constructs a new {@code UnsupportedAlgorithmException} with the * Constructs a new {@code UnsupportedAlgorithmException} with the specified detail message.
* specified detail message. The cause is not initialized, and may * The cause is not initialized, and may subsequently be initialized by a call
* subsequently be initialized by a call to {@link #initCause}. * to {@link #initCause}.
* *
* @param message the detail message. The detail message is saved for * @param message the detail message. The detail message is saved for later retrieval by the {@link #getMessage()} method.
* later retrieval by the {@link #getMessage()} method.
*/ */
public UnsupportedAlgorithmException(String message) { public UnsupportedAlgorithmException(String message) {
super(message); super(message);
} }
/** /**
* Constructs a new {@code UnsupportedAlgorithmException} with the * Constructs a new {@code UnsupportedAlgorithmException} with the specified detail message
* specified detail message and cause. * and cause.
* *
* @param message the detail message (which is saved for later retrieval * @param message the detail message (which is saved for later retrieval by the
* by the {@link #getMessage()} method). * {@link #getMessage()} method)
* @param cause the cause (which is saved for later retrieval by the * @param cause the cause (which is saved for later retrieval by the
* {@link #getCause()} method). (A {@code null} value is * {@link #getCause()} method). (A {@code null} value is permitted, and
* permitted, and indicates that the cause is nonexistent or * indicates that the cause is nonexistent or unknown.)
* unknown.)
* @since 1.4 * @since 1.4
*/ */
public UnsupportedAlgorithmException(String message, Throwable cause) { public UnsupportedAlgorithmException(String message, Throwable cause) {
@@ -73,17 +70,14 @@ public class UnsupportedAlgorithmException extends RuntimeException {
} }
/** /**
* Constructs a new {@code UnsupportedAlgorithmException} with the * Constructs a new {@code UnsupportedAlgorithmException} with the specified cause and a detail
* specified cause and a detail message of * message of {@code (cause==null ? null : cause.toString())} (which typically contains the
* {@code (cause==null ? null : cause.toString())} (which typically * class and detail message of {@code cause}). This constructor is useful for runtime
* contains the class and detail message of {@code cause}). This * exceptions that are little more than wrappers for other throwable.
* constructor is useful for runtime exceptions that are little more
* than wrappers for other throwable.
* *
* @param cause the cause (which is saved for later retrieval by the * @param cause the cause (which is saved for later retrieval by the
* {@link #getCause()} method). (A {@code null} value is * {@link #getCause()} method). (A {@code null} value is permitted, and indicates
* permitted, and indicates that the cause is nonexistent or * that the cause is nonexistent or unknown.)
* unknown.)
* @since 1.4 * @since 1.4
*/ */
public UnsupportedAlgorithmException(Throwable cause) { public UnsupportedAlgorithmException(Throwable cause) {
@@ -91,19 +85,22 @@ public class UnsupportedAlgorithmException extends RuntimeException {
} }
/** /**
* Constructs a new {@code UnsupportedAlgorithmException} with the * Constructs a new {@code UnsupportedAlgorithmException} with the specified detail message,
* specified detail message, cause, suppression enabled or disabled, and * cause, suppression enabled or disabled, and writable stack trace enabled or disabled.
* writable stack trace enabled or disabled.
* *
* @param message the detail message. * @param message the detail message.
* @param cause the cause (A {@code null} value is permitted, * @param cause the cause (A {@code null} value is permitted, and indicates that
* and indicates that the cause is nonexistent or * the cause is nonexistent or unknown.)
* unknown.)
* @param enableSuppression whether suppression is enabled or disabled * @param enableSuppression whether suppression is enabled or disabled
* @param writableStackTrace whether the stack trace should be writable * @param writableStackTrace whether the stack trace should be writable
* @since 1.0.0 * @since 1.0.0
*/ */
public UnsupportedAlgorithmException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { public UnsupportedAlgorithmException(
String message,
Throwable cause,
boolean enableSuppression,
boolean writableStackTrace
) {
super(message, cause, enableSuppression, writableStackTrace); super(message, cause, enableSuppression, writableStackTrace);
} }
} }
@@ -1,69 +1,69 @@
/* /*
* Copyright (C) 2024-2025 OnixByte. * Copyright (c) 2024-2025 OnixByte
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Permission is hereby granted, free of charge, to any person obtaining a copy
* you may not use this file except in compliance with the License. * of this software and associated documentation files (the "Software"), to deal
* You may obtain a copy of the License at * 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:
* *
* http://www.apache.org/licenses/LICENSE-2.0 * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* *
* Unless required by applicable law or agreed to in writing, software * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* distributed under the License is distributed on an "AS IS" BASIS, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* See the License for the specific language governing permissions and * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* limitations under the License. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/ */
package com.onixbyte.jwt.exceptions; package com.onixbyte.jwt.exceptions;
/** /**
* {@code WeakSecretException} represents that your secret is too weak to be * {@code WeakSecretException} represents that your secret is too weak to be used in signing JWTs.
* used in signing JWTs.
* <p> * <p>
* {@code WeakSecretException} will only appears that if you are using the * {@code WeakSecretException} will only appears that if you are using the implementation module
* implementation module {@code cn.org.codecrafters:simple-jwt-jjwt} due to * {@code com.onixbyte:jwt-toolbox-auth0} due to it is implemented by {@code com.auth0:java-jwt}.
* it is implemented by {@code io.jsonwebtoken:jjwt}.
* *
* @author Zihlu Wang * @author zihluwang
* @version 1.1.0 * @version 3.0.0
* @since 1.0.0 * @since 1.0.0
*/ */
public class WeakSecretException extends RuntimeException { public class WeakSecretException extends RuntimeException {
/** /**
* Constructs a new {@code WeakSecretException} with {@code null} as its * Constructs a new {@code WeakSecretException} with {@code null} as its detail message.
* detail message. The cause is not initialized, and may subsequently be * The cause is not initialized, and may subsequently be initialized by a call
* initialized by a call to {@link #initCause}. * to {@link #initCause}.
*/ */
public WeakSecretException() { public WeakSecretException() {
} }
/** /**
* Constructs a new {@code WeakSecretException} with the specified detail * Constructs a new {@code WeakSecretException} with the specified detail message. The cause is
* message. The cause is not initialized, and may subsequently be * not initialised, and may subsequently be initialized by a call to {@link #initCause}.
* initialized by a call to {@link #initCause}.
* *
* @param message the detail message. The detail message is saved for * @param message the detail message. The detail message is saved for later retrieval by the
* later retrieval by the {@link #getMessage()} method. * {@link #getMessage()} method.
*/ */
public WeakSecretException(String message) { public WeakSecretException(String message) {
super(message); super(message);
} }
/** /**
* Constructs a new {@code WeakSecretException} with the specified detail * Constructs a new {@code WeakSecretException} with the specified detail message and cause.
* message and cause.
* <p> * <p>
* Note that the detail message associated with {@code cause} is <i>not</i> * Note that the detail message associated with {@code cause} is <i>not</i> automatically
* automatically incorporated in this runtime exception's detail message. * incorporated in this runtime exception's detail message.
* *
* @param message the detail message (which is saved for later retrieval * @param message the detail message (which is saved for later retrieval by the
* by the {@link #getMessage()} method). * {@link #getMessage()} method).
* @param cause the cause (which is saved for later retrieval by the * @param cause the cause (which is saved for later retrieval by the
* {@link #getCause()} method). (A {@code null} value is * {@link #getCause()} method). (A {@code null} value is permitted, and
* permitted, and indicates that the cause is nonexistent or * indicates that the cause is nonexistent or unknown.)
* unknown.)
* @since 1.0.0 * @since 1.0.0
*/ */
public WeakSecretException(String message, Throwable cause) { public WeakSecretException(String message, Throwable cause) {
@@ -71,16 +71,14 @@ public class WeakSecretException extends RuntimeException {
} }
/** /**
* Constructs a new {@code WeakSecretException} with the specified cause * Constructs a new {@code WeakSecretException} with the specified cause and a detail message
* and a detail message of {@code (cause==null ? null : cause.toString())} * of {@code (cause==null ? null : cause.toString())} (which typically contains the class and
* (which typically contains the class and detail message of * detail message of {@code cause}). This constructor is useful for runtime exceptions that are
* {@code cause}). This constructor is useful for runtime exceptions that * little more than wrappers for other throwable.
* are little more than wrappers for other throwable.
* *
* @param cause the cause (which is saved for later retrieval by the * @param cause the cause (which is saved for later retrieval by the
* {@link #getCause()} method). (A {@code null} value is * {@link #getCause()} method). (A {@code null} value is permitted, and indicates
* permitted, and indicates that the cause is nonexistent or * that the cause is nonexistent or unknown.)
* unknown.)
* @since 1.0.0 * @since 1.0.0
*/ */
public WeakSecretException(Throwable cause) { public WeakSecretException(Throwable cause) {
@@ -88,19 +86,22 @@ public class WeakSecretException extends RuntimeException {
} }
/** /**
* Constructs a new {@code WeakSecretException} with the specified detail * Constructs a new {@code WeakSecretException} with the specified detail message, cause,
* message, cause, suppression enabled or disabled, and writable * suppression enabled or disabled, and writable stack trace enabled or disabled.
* stack trace enabled or disabled.
* *
* @param message the detail message. * @param message the detail message.
* @param cause the cause. (A {@code null} value is permitted, * @param cause the cause. (A {@code null} value is permitted, and indicates that
* and indicates that the cause is nonexistent or * the cause is nonexistent or unknown.)
* unknown.)
* @param enableSuppression whether suppression is enabled or disabled * @param enableSuppression whether suppression is enabled or disabled
* @param writableStackTrace whether the stack trace should be writable * @param writableStackTrace whether the stack trace should be writable
* @since 1.0.0 * @since 1.0.0
*/ */
public WeakSecretException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { public WeakSecretException(
String message,
Throwable cause,
boolean enableSuppression,
boolean writableStackTrace
) {
super(message, cause, enableSuppression, writableStackTrace); super(message, cause, enableSuppression, writableStackTrace);
} }
} }
@@ -1,26 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!-- <!--
~ Copyright (C) 2023-2024 OnixByte. ~ Copyright (c) 2024-2025 OnixByte
~ ~
~ Licensed under the Apache License, Version 2.0 (the "License"); ~ Permission is hereby granted, free of charge, to any person obtaining a copy
~ you may not use this file except in compliance with the License. ~ of this software and associated documentation files (the "Software"), to deal
~ You may obtain a copy of the License at ~ 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:
~ ~
~ http://www.apache.org/licenses/LICENSE-2.0 ~ The above copyright notice and this permission notice shall be included in all
~ copies or substantial portions of the Software.
~ ~
~ Unless required by applicable law or agreed to in writing, software ~ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
~ distributed under the License is distributed on an "AS IS" BASIS, ~ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ~ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
~ ~ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
~ See the License for the specific language governing permissions and ~ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
~ limitations under the License. ~ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
~ SOFTWARE.
--> -->
<configuration> <configuration>
<property name="COLOURFUL_OUTPUT" value="%black(%date{'dd MMM, yyyy HH:mm:ss', Asia/Hong_Kong, en-UK}) %highlight(%-5level) %black(---) %black([%10.10t]) %cyan(%-20.20logger{20}) %black(:) %msg%n"/> <property name="COLOURFUL_OUTPUT"
<property name="STANDARD_OUTPUT" value="%date{'dd MMM, yyyy HH:mm:ss', Asia/Hong_Kong, en-UK} %-5level %black(---) [%10.10t] %-20.20logger{20} : %msg%n"/> value="%black(%date{'dd MMM, yyyy HH:mm:ss', Asia/Hong_Kong, en-UK}) %highlight(%-5level) %black(---) %black([%10.10t]) %cyan(%-20.20logger{20}) %black(:) %msg%n"/>
<property name="STANDARD_OUTPUT"
value="%date{'dd MMM, yyyy HH:mm:ss', Asia/Hong_Kong, en-UK} %-5level %black(---) [%10.10t] %-20.20logger{20} : %msg%n"/>
<statusListener class="ch.qos.logback.core.status.NopStatusListener" /> <statusListener class="ch.qos.logback.core.status.NopStatusListener"/>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${COLOURFUL_OUTPUT}</pattern> <pattern>${COLOURFUL_OUTPUT}</pattern>
@@ -29,4 +36,4 @@
<root level="INFO"> <root level="INFO">
<appender-ref ref="STDOUT"/> <appender-ref ref="STDOUT"/>
</root> </root>
</configuration> </configuration>
+9 -2
View File
@@ -1,8 +1,15 @@
# Module `simple-jwt-spring-boot-starter` # JWT Toolbox :: Spring Boot Starter
## Introduction ## Introduction
Module `simple-jwt-spring-boot-starter` is a lightweight and easy-to-use Spring Boot starter module that provides seamless integration with JSON Web Token (JWT) authentication in Spring Boot applications. With this starter, developers can easily configure and enable JWT-based authentication for their APIs and web applications without the need for complex manual setup. It simplifies the process of generating and validating JWTs, making it effortless to secure endpoints and implement token-based authentication in Spring Boot projects. The module is designed to be flexible, allowing developers to customize various aspects of JWT authentication to suit their specific requirements. Overall, `simple-jwt-spring-boot-starter` is a convenient solution for adding secure and efficient JWT authentication to Spring Boot applications. Module **JWT Toolbox :: Spring Boot Starter** is a lightweight and easy-to-use Spring Boot starter
module that provides seamless integration with JSON Web Token (JWT) authentication in Spring Boot
applications. With this starter, developers can easily configure and enable JWT-based authentication
for their APIs and web applications without the need for complex manual setup. It simplifies the
process of generating and validating JWTs, making it effortless to secure endpoints and implement
token-based authentication in Spring Boot projects. The module is designed to be flexible, allowing
developers to customize various aspects of JWT authentication to suit their specific requirements.
Overall, `jwt-toolbox-spring-boot-starter` is a convenient solution for adding secure and efficient JWT authentication to Spring Boot applications.
## Prerequisites ## Prerequisites
@@ -1,19 +1,25 @@
/* /*
* Copyright (C) 2024-2025 OnixByte. * Copyright (c) 2024-2025 OnixByte
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Permission is hereby granted, free of charge, to any person obtaining a copy
* you may not use this file except in compliance with the License. * of this software and associated documentation files (the "Software"), to deal
* You may obtain a copy of the License at * 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:
* *
* http://www.apache.org/licenses/LICENSE-2.0 * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* *
* Unless required by applicable law or agreed to in writing, software * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* distributed under the License is distributed on an "AS IS" BASIS, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* See the License for the specific language governing permissions and * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* limitations under the License. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/ */
import java.net.URI import java.net.URI
plugins { plugins {
@@ -99,8 +105,8 @@ publishing {
} }
scm { scm {
connection = "scm:git:git://github.com:OnixByte/JDevKit.git" connection = "scm:git:git://github.com:onixbyte/onixbyte-toolbox.git"
developerConnection = "scm:git:git://github.com:OnixByte/JDevKit.git" developerConnection = "scm:git:git://github.com:onixbyte/onixbyte-toolbox.git"
url = projectGithubUrl url = projectGithubUrl
} }
@@ -1,119 +0,0 @@
/*
* Copyright (C) 2024-2025 OnixByte.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.onixbyte.jwt.autoconfiguration;
import com.onixbyte.identitygenerator.IdentityGenerator;
import com.onixbyte.jwt.TokenResolver;
import com.onixbyte.jwt.auth0.AuthzeroTokenResolver;
import com.onixbyte.jwt.autoconfiguration.properties.SimpleJwtProperties;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.onixbyte.jwt.constants.TokenAlgorithm;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
/**
* {@code AuthzeroTokenResolverAutoConfiguration} is responsible for automatically configuring the
* Simple JWT library with
* {@code com.auth0:java-jwt} when used in a Spring Boot application. It provides default settings
* and configurations to ensure that the library works smoothly without requiring
* manual configuration.
* <p>
* This autoconfiguration class sets up the necessary beans and components required for JWT
* generation and validation. It automatically creates and configures the
* {@link AuthzeroTokenResolver} bean based on the available options and properties.
* <p>
* Developers using the Simple JWT library with Spring Boot do not need to explicitly configure the
* library, as the autoconfiguration takes care of setting up the necessary components and
* configurations automatically. However, developers still have the flexibility to customise the
* behavior of the library by providing their own configurations and properties.
*
* @author zihluwang
* @version 1.6.0
* @since 1.0.0
*/
@AutoConfiguration
@EnableConfigurationProperties(value = {SimpleJwtProperties.class})
@ConditionalOnClass({DecodedJWT.class, AuthzeroTokenResolver.class})
@ConditionalOnMissingBean({TokenResolver.class})
@ConditionalOnBean(value = {IdentityGenerator.class}, name = "jtiCreator")
@AutoConfigureAfter(value = GuidAutoConfiguration.class)
public class AuthzeroTokenResolverAutoConfiguration {
private final static Logger log = LoggerFactory.getLogger(AuthzeroTokenResolverAutoConfiguration.class);
/**
* Constructs a new {@code SimpleJwtAutoConfiguration} instance with the
* provided SimpleJwtProperties.
*
* @param simpleJwtProperties a {@link SimpleJwtProperties} instance
* @param jtiCreator a creator to create ids for JSON Web Token
* @param objectMapper jackson JSON Handler
*/
@Autowired
public AuthzeroTokenResolverAutoConfiguration(SimpleJwtProperties simpleJwtProperties,
@Qualifier("jtiCreator") IdentityGenerator<?> jtiCreator,
ObjectMapper objectMapper) {
this.jtiCreator = jtiCreator;
this.simpleJwtProperties = simpleJwtProperties;
this.objectMapper = objectMapper;
}
/**
* Creates a new {@link TokenResolver} bean using {@link AuthzeroTokenResolver} if no existing
* {@link TokenResolver} bean is found. The {@link AuthzeroTokenResolver} is configured with the
* provided {@link IdentityGenerator}, {@code algorithm}, {@code issuer}, and {@code secret}
* properties from {@link SimpleJwtProperties}.
*
* @return the {@link TokenResolver} instance
*/
@Bean
public TokenResolver<DecodedJWT> tokenResolver() {
var builder = AuthzeroTokenResolver.builder();
if (TokenAlgorithm.ECDSA_ALGORITHMS.contains(simpleJwtProperties.getAlgorithm())) {
builder.keyPair(simpleJwtProperties.getPublicKey(), simpleJwtProperties.getPrivateKey())
.algorithm(simpleJwtProperties.getAlgorithm());
} else if (TokenAlgorithm.HMAC_ALGORITHMS.contains(simpleJwtProperties.getAlgorithm())) {
builder.secret(simpleJwtProperties.getSecret())
.algorithm(simpleJwtProperties.getAlgorithm());
}
builder.issuer(simpleJwtProperties.getIssuer());
builder.jtiCreator(jtiCreator);
builder.objectMapper(objectMapper);
return builder.build();
}
private final IdentityGenerator<?> jtiCreator;
private final SimpleJwtProperties simpleJwtProperties;
private final ObjectMapper objectMapper;
}
@@ -1,18 +1,23 @@
/* /*
* Copyright (C) 2024-2025 OnixByte. * Copyright (c) 2024-2025 OnixByte
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Permission is hereby granted, free of charge, to any person obtaining a copy
* you may not use this file except in compliance with the License. * of this software and associated documentation files (the "Software"), to deal
* You may obtain a copy of the License at * 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:
* *
* http://www.apache.org/licenses/LICENSE-2.0 * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* *
* Unless required by applicable law or agreed to in writing, software * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* distributed under the License is distributed on an "AS IS" BASIS, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* See the License for the specific language governing permissions and * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* limitations under the License. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/ */
package com.onixbyte.jwt.autoconfiguration; package com.onixbyte.jwt.autoconfiguration;
@@ -1,18 +1,23 @@
/* /*
* Copyright (C) 2024-2025 OnixByte. * Copyright (c) 2024-2025 OnixByte
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Permission is hereby granted, free of charge, to any person obtaining a copy
* you may not use this file except in compliance with the License. * of this software and associated documentation files (the "Software"), to deal
* You may obtain a copy of the License at * 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:
* *
* http://www.apache.org/licenses/LICENSE-2.0 * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* *
* Unless required by applicable law or agreed to in writing, software * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* distributed under the License is distributed on an "AS IS" BASIS, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* See the License for the specific language governing permissions and * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* limitations under the License. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/ */
package com.onixbyte.jwt.autoconfiguration.conditions; package com.onixbyte.jwt.autoconfiguration.conditions;
@@ -29,14 +34,12 @@ import java.util.Objects;
/** /**
* The conditions to create bean {@code jtiCreator}. * The conditions to create bean {@code jtiCreator}.
* *
* @author Zihlu Wang * @author zihluwang
* @version 1.1.0 * @version 3.0.0
* @since 1.0.0 * @since 1.0.0
*/ */
public class GuidCreatorCondition implements Condition { public class GuidCreatorCondition implements Condition {
private final static Logger log = LoggerFactory.getLogger(GuidCreatorCondition.class);
/** /**
* Default constructor. * Default constructor.
*/ */
@@ -1,39 +1,43 @@
/* /*
* Copyright (C) 2024-2025 OnixByte. * Copyright (c) 2024-2025 OnixByte
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Permission is hereby granted, free of charge, to any person obtaining a copy
* you may not use this file except in compliance with the License. * of this software and associated documentation files (the "Software"), to deal
* You may obtain a copy of the License at * 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:
* *
* http://www.apache.org/licenses/LICENSE-2.0 * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* *
* Unless required by applicable law or agreed to in writing, software * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* distributed under the License is distributed on an "AS IS" BASIS, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* See the License for the specific language governing permissions and * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* limitations under the License. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/ */
package com.onixbyte.jwt.autoconfiguration.properties; package com.onixbyte.jwt.autoconfiguration.properties;
import com.onixbyte.jwt.SecretCreator; import com.onixbyte.jwt.SecretCreator;
import com.onixbyte.jwt.autoconfiguration.AuthzeroTokenResolverAutoConfiguration;
import com.onixbyte.jwt.constants.TokenAlgorithm; import com.onixbyte.jwt.constants.TokenAlgorithm;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
/** /**
* {@code SimpleJwtProperties} is a configuration properties class used to store the properties * {@code JwtProperties} is a configuration properties class used to store the properties
* related to Simple JWT library configurations. These properties can be configured in the * related to Simple JWT library configurations. These properties can be configured in the
* application's properties file (e.g., application.properties) with the prefix * application's properties file (e.g., application.properties) with the prefix
* "onixbyte.simple-jwt". * "onixbyte.simple-jwt".
* <p> * <p>
* {@code SimpleJwtProperties} provides configuration options for the JWT algorithm, issuer, * {@code JwtProperties} provides configuration options for the JWT algorithm, issuer,
* and secret. The properties are used by the {@link AuthzeroTokenResolverAutoConfiguration} to * and secret. The properties are used by the {@code Auth0AutoConfiguration} to
* set up the necessary configurations for JWT generation and validation. * set up the necessary configurations for JWT generation and validation.
* <p> * <p>
* Developers can customise the JWT algorithm, issuer, and secret by setting the corresponding * Developers can customise the JWT algorithm, issuer, and secret by setting the corresponding
* properties in the application's properties file. The {@code SimpleJwtAutoConfiguration} class * properties in the application's properties file. The {@code Auth0AutoConfiguration} class
* reads these properties and uses them to create the TokenResolver bean with the * reads these properties and uses them to create the TokenResolver bean with the
* desired configuration. * desired configuration.
* *
@@ -41,13 +45,13 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
* @version 1.1.0 * @version 1.1.0
* @since 1.0.0 * @since 1.0.0
*/ */
@ConfigurationProperties(prefix = "onixbyte.simple-jwt") // @ConfigurationProperties(prefix = "onixbyte.jwt")
public class SimpleJwtProperties { public class JwtProperties {
/** /**
* Default constructor. * Default constructor.
*/ */
public SimpleJwtProperties() { public JwtProperties() {
} }
/** /**
@@ -1,2 +1 @@
com.onixbyte.jwt.autoconfiguration.GuidAutoConfiguration com.onixbyte.jwt.autoconfiguration.GuidAutoConfiguration
com.onixbyte.jwt.autoconfiguration.AuthzeroTokenResolverAutoConfiguration
@@ -1,26 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!-- <!--
~ Copyright (C) 2024-2025 OnixByte. ~ Copyright (c) 2024-2025 OnixByte
~ ~
~ Licensed under the Apache License, Version 2.0 (the "License"); ~ Permission is hereby granted, free of charge, to any person obtaining a copy
~ you may not use this file except in compliance with the License. ~ of this software and associated documentation files (the "Software"), to deal
~ You may obtain a copy of the License at ~ 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:
~ ~
~ http://www.apache.org/licenses/LICENSE-2.0 ~ The above copyright notice and this permission notice shall be included in all
~ copies or substantial portions of the Software.
~ ~
~ Unless required by applicable law or agreed to in writing, software ~ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
~ distributed under the License is distributed on an "AS IS" BASIS, ~ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ~ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
~ ~ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
~ See the License for the specific language governing permissions and ~ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
~ limitations under the License. ~ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
~ SOFTWARE.
--> -->
<configuration> <configuration>
<property name="COLOURFUL_OUTPUT" value="%black(%date{'dd MMM, yyyy HH:mm:ss', Asia/Hong_Kong, en-UK}) %highlight(%-5level) %black(---) %black([%10.10t]) %cyan(%-20.20logger{20}) %black(:) %msg%n"/> <property name="COLOURFUL_OUTPUT"
<property name="STANDARD_OUTPUT" value="%date{'dd MMM, yyyy HH:mm:ss', Asia/Hong_Kong, en-UK} %-5level %black(---) [%10.10t] %-20.20logger{20} : %msg%n"/> value="%black(%date{'dd MMM, yyyy HH:mm:ss', Asia/Hong_Kong, en-UK}) %highlight(%-5level) %black(---) %black([%10.10t]) %cyan(%-20.20logger{20}) %black(:) %msg%n"/>
<property name="STANDARD_OUTPUT"
value="%date{'dd MMM, yyyy HH:mm:ss', Asia/Hong_Kong, en-UK} %-5level %black(---) [%10.10t] %-20.20logger{20} : %msg%n"/>
<statusListener class="ch.qos.logback.core.status.NopStatusListener" /> <statusListener class="ch.qos.logback.core.status.NopStatusListener"/>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${COLOURFUL_OUTPUT}</pattern> <pattern>${COLOURFUL_OUTPUT}</pattern>
@@ -29,4 +36,4 @@
<root level="INFO"> <root level="INFO">
<appender-ref ref="STDOUT"/> <appender-ref ref="STDOUT"/>
</root> </root>
</configuration> </configuration>
+3 -2
View File
@@ -1,3 +1,4 @@
# Num4j # Math Toolkit
`num4j` provides some mathematical algorithms and utilities such as chained high-precision mathematical calculator and percentile statistic algorithm. **Math Toolkit** provides some mathematical algorithms and utilities such as chained high-precision
mathematical calculator and percentile statistic algorithm.
+19 -13
View File
@@ -1,19 +1,25 @@
/* /*
* Copyright (C) 2024-2025 OnixByte. * Copyright (c) 2024-2025 OnixByte
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Permission is hereby granted, free of charge, to any person obtaining a copy
* you may not use this file except in compliance with the License. * of this software and associated documentation files (the "Software"), to deal
* You may obtain a copy of the License at * 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:
* *
* http://www.apache.org/licenses/LICENSE-2.0 * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* *
* Unless required by applicable law or agreed to in writing, software * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* distributed under the License is distributed on an "AS IS" BASIS, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* See the License for the specific language governing permissions and * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* limitations under the License. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/ */
import java.net.URI import java.net.URI
plugins { plugins {
@@ -83,8 +89,8 @@ publishing {
} }
scm { scm {
connection = "scm:git:git://github.com:OnixByte/JDevKit.git" connection = "scm:git:git://github.com:onixbyte/onixbyte-toolbox.git"
developerConnection = "scm:git:git://github.com:OnixByte/JDevKit.git" developerConnection = "scm:git:git://github.com:onixbyte/onixbyte-toolbox.git"
url = projectGithubUrl url = projectGithubUrl
} }
@@ -1,25 +1,27 @@
/* /*
* Copyright (C) 2024-2025 OnixByte. * Copyright (c) 2024-2025 OnixByte
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Permission is hereby granted, free of charge, to any person obtaining a copy
* you may not use this file except in compliance with the License. * of this software and associated documentation files (the "Software"), to deal
* You may obtain a copy of the License at * 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:
* *
* http://www.apache.org/licenses/LICENSE-2.0 * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* *
* Unless required by applicable law or agreed to in writing, software * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* distributed under the License is distributed on an "AS IS" BASIS, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* See the License for the specific language governing permissions and * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* limitations under the License. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/ */
package com.onixbyte.math; package com.onixbyte.math;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.RoundingMode; import java.math.RoundingMode;
import java.util.Objects; import java.util.Objects;
@@ -87,14 +89,12 @@ import java.util.function.Function;
* and may have performance implications for extremely large numbers or complex calculations. * and may have performance implications for extremely large numbers or complex calculations.
* *
* @author sunzsh * @author sunzsh
* @version 1.1.0 * @version 3.0.0
* @see BigDecimal * @see BigDecimal
* @since 1.0.0 * @since 1.0.0
*/ */
public final class ChainedCalcUtil { public final class ChainedCalcUtil {
private final static Logger log = LoggerFactory.getLogger(ChainedCalcUtil.class);
/** /**
* Creates a {@code ChainedCalcUtil} instance with the specified initial value. * Creates a {@code ChainedCalcUtil} instance with the specified initial value.
* *
@@ -1,25 +1,28 @@
/* /*
* Copyright (C) 2024-2025 OnixByte. * Copyright (c) 2024-2025 OnixByte
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Permission is hereby granted, free of charge, to any person obtaining a copy
* you may not use this file except in compliance with the License. * of this software and associated documentation files (the "Software"), to deal
* You may obtain a copy of the License at * 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:
* *
* http://www.apache.org/licenses/LICENSE-2.0 * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* *
* Unless required by applicable law or agreed to in writing, software * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* distributed under the License is distributed on an "AS IS" BASIS, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* See the License for the specific language governing permissions and * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* limitations under the License. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/ */
package com.onixbyte.math; package com.onixbyte.math;
import com.onixbyte.math.model.QuartileBounds; import com.onixbyte.math.model.QuartileBounds;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List; import java.util.List;
@@ -29,30 +32,30 @@ import java.util.List;
* <p> * <p>
* This class contains static methods to: * This class contains static methods to:
* <ul> * <ul>
* <li>Calculate a specified percentile from a list of double values using linear interpolation.</li> * <li>
* <li>Calculate interquartile bounds (Q1, Q3) and the corresponding lower and upper bounds, * Calculate a specified percentile from a list of double values using linear interpolation.
* which can be used to identify outliers in the dataset.</li> * </li>
* <li>
* Calculate interquartile bounds (Q1, Q3) and the corresponding lower and upper bounds,
* which can be used to identify outliers in the dataset.
* </li>
* </ul> * </ul>
* <p> * <p>
* This class is final, meaning it cannot be subclassed, and it only contains static methods, * This class is final, meaning it cannot be subclassed, and it only contains static methods,
* so instances of the class cannot be created. * so instances of the class cannot be created.
* <h2>Example usage:</h2> * <h2>Example usage:</h2>
* <pre> * <pre>{@code
* {@code
* List<Double> data = Arrays.asList(1.0, 2.0, 3.0, 4.0, 5.0); * List<Double> data = Arrays.asList(1.0, 2.0, 3.0, 4.0, 5.0);
* Double percentileValue = PercentileCalculator.calculatePercentile(data, 50.0); // Calculates median * Double percentileValue = PercentileCalculator.calculatePercentile(data, 50.0); // Calculates median
* QuartileBounds bounds = PercentileCalculator.calculatePercentileBounds(data); // Calculates IQR bounds * QuartileBounds bounds = PercentileCalculator.calculatePercentileBounds(data); // Calculates IQR bounds
* } * }</pre>
* </pre>
* *
* @author zihluwang * @author zihluwang
* @version 1.6.5 * @version 3.0.0
* @since 1.6.5 * @since 1.6.5
*/ */
public final class PercentileCalculator { public final class PercentileCalculator {
private final static Logger log = LoggerFactory.getLogger(PercentileCalculator.class);
/** /**
* Private constructor to prevent instantiation of this utility class. * Private constructor to prevent instantiation of this utility class.
*/ */
@@ -100,18 +103,18 @@ public final class PercentileCalculator {
*/ */
public static QuartileBounds calculatePercentileBounds(List<Double> data) { public static QuartileBounds calculatePercentileBounds(List<Double> data) {
var sorted = data.stream().sorted().toList(); var sorted = data.stream().sorted().toList();
var Q1 = calculatePercentile(sorted, 25.); var q1 = calculatePercentile(sorted, 25.);
var Q3 = calculatePercentile(sorted, 75.); var q3 = calculatePercentile(sorted, 75.);
var IQR = Q3 - Q1; var iqr = q3 - q1;
var lowerBound = Q1 - 1.5 * IQR; var lowerBound = q1 - 1.5 * iqr;
var upperBound = Q3 + 1.5 * IQR; var upperBound = q3 + 1.5 * iqr;
return QuartileBounds.builder() return QuartileBounds.builder()
.upperBound(upperBound) .upperBound(upperBound)
.lowerBound(lowerBound) .lowerBound(lowerBound)
.build(); .build();
} }
} }
@@ -1,18 +1,23 @@
/* /*
* Copyright (C) 2024-2025 OnixByte. * Copyright (c) 2024-2025 OnixByte
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Permission is hereby granted, free of charge, to any person obtaining a copy
* you may not use this file except in compliance with the License. * of this software and associated documentation files (the "Software"), to deal
* You may obtain a copy of the License at * 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:
* *
* http://www.apache.org/licenses/LICENSE-2.0 * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* *
* Unless required by applicable law or agreed to in writing, software * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* distributed under the License is distributed on an "AS IS" BASIS, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* See the License for the specific language governing permissions and * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* limitations under the License. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/ */
package com.onixbyte.math.model; package com.onixbyte.math.model;
@@ -26,27 +31,31 @@ package com.onixbyte.math.model;
* <p> * <p>
* Quartile bounds consist of: * Quartile bounds consist of:
* <ul> * <ul>
* <li>{@code lowerBound} - The lower bound of the dataset, typically {@code Q1 - 1.5 * IQR}.</li> * <li>
* <li>{@code upperBound} - The upper bound of the dataset, typically {@code Q3 + 1.5 * IQR}.</li> * {@code lowerBound} - The lower bound of the dataset, typically {@code Q1 - 1.5 * IQR}.
* </li>
* <li>
* {@code upperBound} - The upper bound of the dataset, typically {@code Q3 + 1.5 * IQR}.
* </li>
* </ul> * </ul>
* <p> * <p>
* Example usage: * Example usage:
* <pre> * <pre>{@code
* QuartileBounds bounds = QuartileBounds.builder() * QuartileBounds bounds = QuartileBounds.builder()
* .lowerBound(1.5) * .lowerBound(1.5)
* .upperBound(7.5) * .upperBound(7.5)
* .build(); * .build();
* </pre> * }</pre>
* *
* @param upperBound the upper bound of the dataset * @param upperBound the upper bound of the dataset
* @param lowerBound the lower bound of the dataset * @param lowerBound the lower bound of the dataset
* @author zihluwang * @author zihluwang
* @version 1.6.5 * @version 3.0.0
* @since 1.6.5 * @since 1.6.5
*/ */
public record QuartileBounds( public record QuartileBounds(
Double upperBound, Double upperBound,
Double lowerBound Double lowerBound
) { ) {
/** /**
+22 -15
View File
@@ -1,26 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!-- <!--
~ Copyright (C) 2024-2024 OnixByte. ~ Copyright (c) 2024-2025 OnixByte
~ ~
~ Licensed under the Apache License, Version 2.0 (the "License"); ~ Permission is hereby granted, free of charge, to any person obtaining a copy
~ you may not use this file except in compliance with the License. ~ of this software and associated documentation files (the "Software"), to deal
~ You may obtain a copy of the License at ~ 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:
~ ~
~ http://www.apache.org/licenses/LICENSE-2.0 ~ The above copyright notice and this permission notice shall be included in all
~ copies or substantial portions of the Software.
~ ~
~ Unless required by applicable law or agreed to in writing, software ~ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
~ distributed under the License is distributed on an "AS IS" BASIS, ~ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ~ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
~ ~ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
~ See the License for the specific language governing permissions and ~ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
~ limitations under the License. ~ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
~ SOFTWARE.
--> -->
<configuration> <configuration>
<property name="COLOURFUL_OUTPUT" value="%black(%date{'dd MMM, yyyy HH:mm:ss', Asia/Hong_Kong, en-UK}) %highlight(%-5level) %black(---) %black([%10.10t]) %cyan(%-20.20logger{20}) %black(:) %msg%n"/> <property name="COLOURFUL_OUTPUT"
<property name="STANDARD_OUTPUT" value="%date{'dd MMM, yyyy HH:mm:ss', Asia/Hong_Kong, en-UK} %-5level %black(---) [%10.10t] %-20.20logger{20} : %msg%n"/> value="%black(%date{'dd MMM, yyyy HH:mm:ss', Asia/Hong_Kong, en-UK}) %highlight(%-5level) %black(---) %black([%10.10t]) %cyan(%-20.20logger{20}) %black(:) %msg%n"/>
<property name="STANDARD_OUTPUT"
value="%date{'dd MMM, yyyy HH:mm:ss', Asia/Hong_Kong, en-UK} %-5level %black(---) [%10.10t] %-20.20logger{20} : %msg%n"/>
<statusListener class="ch.qos.logback.core.status.NopStatusListener" /> <statusListener class="ch.qos.logback.core.status.NopStatusListener"/>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${COLOURFUL_OUTPUT}</pattern> <pattern>${COLOURFUL_OUTPUT}</pattern>
@@ -29,4 +36,4 @@
<root level="INFO"> <root level="INFO">
<appender-ref ref="STDOUT"/> <appender-ref ref="STDOUT"/>
</root> </root>
</configuration> </configuration>
+14 -11
View File
@@ -1,17 +1,22 @@
# DevKit BOM # Version Catalogue
The devkit-bom (Bill of Materials) is a Maven POM file provided by OnixByte to manage dependency versions for the DevKit suite of libraries. By incorporating this BOM into your build configuration, you can ensure consistent versioning across all included dependencies without needing to specify versions explicitly in your project files. Published with Gradle metadata, this BOM supports both Maven and Gradle projects, and this document outlines how to integrate and use it effectively in both ecosystems. The **Version Catalogue** (Bill of Materials) is a Maven POM file provided by OnixByte to manage
dependency versions for the **OnixByte Toolbox**. By incorporating this BOM into your build
configuration, you can ensure consistent versioning across all included dependencies without
needing to specify versions explicitly in your project files. Published with Gradle metadata,
this BOM supports both Maven and Gradle projects, and this document outlines how to integrate
and use it effectively in both ecosystems.
## Using in Maven ## Using in Maven
Add the `devkit-bom` to your `pom.xml` under `<dependencyManagement>`: Add the `version-catalogue` to your `pom.xml` under `<dependencyManagement>`:
```xml ```xml
<dependencyManagement> <dependencyManagement>
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>com.onixbyte</groupId> <groupId>com.onixbyte</groupId>
<artifactId>devkit-bom</artifactId> <artifactId>version-catalogue</artifactId>
<version>${devkit-version}</version> <version>${devkit-version}</version>
<type>pom</type> <type>pom</type>
<scope>import</scope> <scope>import</scope>
@@ -20,7 +25,7 @@ Add the `devkit-bom` to your `pom.xml` under `<dependencyManagement>`:
</dependencyManagement> </dependencyManagement>
``` ```
Then reference dependencies like `devkit-core` without a version. Then reference any dependency built by OnixByte without a version.
## Using in Gradle ## Using in Gradle
@@ -28,9 +33,8 @@ In your `build.gradle[.kts]`, apply the BOM using the `platform` dependency:
```groovy ```groovy
dependencies { dependencies {
implementation platform('com.onixbyte:devkit-bom:2.0.0') implementation platform('com.onixbyte:version-catalogue:2.0.0')
implementation 'com.onixbyte:devkit-core' implementation 'com.onixbyte:common-toolbox'
implementation 'com.onixbyte:devkit-utils'
} }
``` ```
@@ -38,9 +42,8 @@ If you are using Kotlin DSL:
```kotlin ```kotlin
dependencies { dependencies {
implementation(platform("com.onixbyte:devkit-bom:2.0.0")) implementation(platform("com.onixbyte:version-catalogue:2.0.0"))
implementation("com.onixbyte:devkit-core") implementation("com.onixbyte:common-toolbox")
implementation("com.onixbyte:devkit-utils")
} }
``` ```
+17 -11
View File
@@ -1,19 +1,25 @@
/* /*
* Copyright (C) 2024-2025 OnixByte. * Copyright (c) 2024-2025 OnixByte
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Permission is hereby granted, free of charge, to any person obtaining a copy
* you may not use this file except in compliance with the License. * of this software and associated documentation files (the "Software"), to deal
* You may obtain a copy of the License at * 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:
* *
* http://www.apache.org/licenses/LICENSE-2.0 * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* *
* Unless required by applicable law or agreed to in writing, software * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* distributed under the License is distributed on an "AS IS" BASIS, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* See the License for the specific language governing permissions and * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* limitations under the License. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/ */
import java.net.URI import java.net.URI
plugins { plugins {