Skip to content

Commit ec6cba8

Browse files
authored
Merge pull request #198 from microsphere-projects/dev
Release 0.1.6
2 parents 339f77d + 6c42c68 commit ec6cba8

File tree

11 files changed

+193
-34
lines changed

11 files changed

+193
-34
lines changed

.github/workflows/maven-build.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ jobs:
1919
runs-on: ubuntu-latest
2020
strategy:
2121
matrix:
22-
java: [ '8', '11' , '17' , '21' ]
22+
java: [ '8', '11' , '17' , '21' , '25' ]
2323
steps:
2424
- name: Checkout Source
2525
uses: actions/checkout@v4

CODE_OF_CONDUCT.md

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# Contributor Code of Conduct
2+
3+
As contributors and maintainers of this project, and in the interest of
4+
fostering an open and welcoming community, we pledge to respect all people who
5+
contribute through reporting issues, posting feature requests, updating
6+
documentation, submitting pull requests or patches, and other activities.
7+
8+
We are committed to making participation in this project a harassment-free
9+
experience for everyone, regardless of level of experience, gender, gender
10+
identity and expression, sexual orientation, disability, personal appearance,
11+
body size, race, ethnicity, age, religion, or nationality.
12+
13+
Examples of unacceptable behavior by participants include:
14+
15+
* The use of sexualized language or imagery
16+
* Personal attacks
17+
* Trolling or insulting/derogatory comments
18+
* Public or private harassment
19+
* Publishing other's private information, such as physical or electronic
20+
addresses, without explicit permission
21+
* Other unethical or unprofessional conduct
22+
23+
Project maintainers have the right and responsibility to remove, edit, or
24+
reject comments, commits, code, wiki edits, issues, and other contributions
25+
that are not aligned to this Code of Conduct, or to ban temporarily or
26+
permanently any contributor for other behaviors that they deem inappropriate,
27+
threatening, offensive, or harmful.
28+
29+
By adopting this Code of Conduct, project maintainers commit themselves to
30+
fairly and consistently applying these principles to every aspect of managing
31+
this project. Project maintainers who do not follow or enforce the Code of
32+
Conduct may be permanently removed from the project team.
33+
34+
This Code of Conduct applies both within project spaces and in public spaces
35+
when an individual is representing the project or its community.
36+
37+
Instances of abusive, harassing, or otherwise unacceptable behavior may be
38+
reported by contacting a project maintainer at [[email protected]](mailto:[email protected]). All
39+
complaints will be reviewed and investigated and will result in a response that
40+
is deemed necessary and appropriate to the circumstances. Maintainers are
41+
obligated to maintain confidentiality with regard to the reporter of an
42+
incident.
43+
44+
45+
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
46+
version 1.3.0, available at https://www.contributor-covenant.org/version/1/3/0/code-of-conduct.html
47+
48+
[homepage]: https://www.contributor-covenant.org

microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/TestAnnotation.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,12 @@
2222

2323
import java.lang.annotation.Annotation;
2424
import java.lang.annotation.Documented;
25-
import java.lang.annotation.ElementType;
2625
import java.lang.annotation.Retention;
27-
import java.lang.annotation.RetentionPolicy;
2826
import java.lang.annotation.Target;
2927
import java.util.concurrent.TimeUnit;
3028

29+
import static java.lang.annotation.ElementType.TYPE;
30+
import static java.lang.annotation.RetentionPolicy.RUNTIME;
3131
import static java.util.concurrent.TimeUnit.DAYS;
3232

3333
/**
@@ -37,8 +37,8 @@
3737
* @see Annotation
3838
* @since 1.0.0
3939
*/
40-
@Retention(RetentionPolicy.RUNTIME)
41-
@Target(ElementType.TYPE)
40+
@Retention(RUNTIME)
41+
@Target(TYPE)
4242
@Documented
4343
public @interface TestAnnotation {
4444

microsphere-java-core/src/main/java/io/microsphere/net/URLUtils.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1315,7 +1315,7 @@ private static String findSubProtocolsString(String url) {
13151315
if (startIndex > -1) {
13161316
int endIndex = url.indexOf("://", startIndex);
13171317
if (endIndex > startIndex) {
1318-
return url.substring(startIndex, endIndex);
1318+
return url.substring(startIndex + 1, endIndex);
13191319
}
13201320
}
13211321
return null;

microsphere-java-core/src/main/java/io/microsphere/util/ClassPathUtils.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
* <li>Locating the runtime URL of a class by name or type</li>
3636
* </ul>
3737
*
38-
* <h3>Example Usage:</h3>
38+
* <h3>Example Usage</h3>
3939
* <pre>{@code
4040
* // Get all application class paths
4141
* Set<String> classPaths = ClassPathUtils.getClassPaths();

microsphere-java-core/src/main/java/io/microsphere/util/StringUtils.java

Lines changed: 63 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,15 @@
1717
package io.microsphere.util;
1818

1919
import io.microsphere.annotation.Immutable;
20+
import io.microsphere.annotation.Nonnull;
2021
import io.microsphere.annotation.Nullable;
2122

22-
import java.util.StringTokenizer;
23+
import java.util.ArrayList;
24+
import java.util.Collection;
25+
import java.util.List;
2326

24-
import static io.microsphere.util.ArrayUtils.asArray;
27+
import static io.microsphere.collection.CollectionUtils.isEmpty;
28+
import static io.microsphere.util.ArrayUtils.ofArray;
2529
import static io.microsphere.util.CharSequenceUtils.isEmpty;
2630
import static io.microsphere.util.CharSequenceUtils.length;
2731
import static java.lang.Character.isDigit;
@@ -127,7 +131,8 @@ public static boolean isNotBlank(String value) {
127131
* @param delimiter the char used as a delimiter to split the String
128132
* @return an array of Strings, split by the delimiter; never null
129133
*/
130-
public static String[] split(String value, char delimiter) {
134+
@Nonnull
135+
public static String[] split(@Nullable String value, char delimiter) {
131136
return split(value, valueOf(delimiter));
132137
}
133138

@@ -140,7 +145,9 @@ public static String[] split(String value, char delimiter) {
140145
* <h3>Example Usage</h3>
141146
* <pre>{@code
142147
* StringUtils.split(null, ",") = []
148+
* StringUtils.split("", null) = []
143149
* StringUtils.split("", ";") = []
150+
* StringUtils.split("abc", "") = ["a", "b", "c"]
144151
* StringUtils.split("a,b,c", ",") = ["a", "b", "c"]
145152
* StringUtils.split("a;b;c", ",") = ["a;b;c"]
146153
* StringUtils.split("a,,b,c", ",") = ["a", "", "b", "c"]
@@ -150,12 +157,41 @@ public static String[] split(String value, char delimiter) {
150157
* @param delimiter the String used as a delimiter to split the String, may be null or empty
151158
* @return an array of Strings, split by the delimiter; never null
152159
*/
153-
public static String[] split(String value, String delimiter) {
154-
if (isEmpty(value) || isEmpty(delimiter)) {
160+
@Nonnull
161+
public static String[] split(@Nullable String value, @Nullable String delimiter) {
162+
int length = length(value);
163+
if (length < 1) {
155164
return EMPTY_STRING_ARRAY;
156165
}
157-
StringTokenizer stringTokenizer = new StringTokenizer(value, delimiter);
158-
return (String[]) asArray(stringTokenizer, String.class);
166+
167+
if (delimiter == null) {
168+
return ofArray(value);
169+
}
170+
171+
int delimiterLength = delimiter.length();
172+
173+
List<String> result = new ArrayList<>();
174+
175+
if (delimiterLength == 0) {
176+
for (int i = 0; i < value.length(); i++) {
177+
result.add(value.substring(i, i + 1));
178+
}
179+
} else {
180+
int startIndex = 0;
181+
int endIndex;
182+
183+
while ((endIndex = value.indexOf(delimiter, startIndex)) > -1) {
184+
String part = value.substring(startIndex, endIndex);
185+
result.add(part);
186+
startIndex = endIndex + delimiterLength;
187+
}
188+
if (startIndex <= length) {
189+
// Add rest of String, but not in case of empty input.
190+
result.add(value.substring(startIndex));
191+
}
192+
}
193+
194+
return toStringArray(result);
159195
}
160196

161197
/**
@@ -780,6 +816,26 @@ public static String uncapitalize(String str) {
780816
return changeFirstCharacter(str, false);
781817
}
782818

819+
/**
820+
* Convert the given {@link Collection} into a {@code String} array.
821+
* <p>The {@code Collection} must contain {@code String} elements only.
822+
*
823+
* <h3>Example Usage</h3>
824+
* <pre>{@code
825+
* StringUtils.toStringArray(null) = []
826+
* StringUtils.toStringArray(new ArrayList<>()) = []
827+
* StringUtils.toStringArray(Arrays.asList("a", "b", "c")) = ["a", "b", "c"]
828+
* }</pre>
829+
*
830+
* @param collection the {@code Collection} to convert
831+
* (potentially {@code null} or empty)
832+
* @return the resulting {@code String} array
833+
*/
834+
@Nonnull
835+
public static String[] toStringArray(@Nullable Collection<String> collection) {
836+
return isEmpty(collection) ? EMPTY_STRING_ARRAY : collection.toArray(EMPTY_STRING_ARRAY);
837+
}
838+
783839
static String changeFirstCharacter(String str, boolean capitalize) {
784840
int len = length(str);
785841
if (len < 1) {

microsphere-java-core/src/test/java/io/microsphere/io/FileUtilsTest.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import static java.util.concurrent.Executors.newFixedThreadPool;
3535
import static java.util.concurrent.Executors.newSingleThreadExecutor;
3636
import static java.util.concurrent.TimeUnit.MILLISECONDS;
37+
import static java.util.concurrent.TimeUnit.SECONDS;
3738
import static org.junit.jupiter.api.Assertions.assertEquals;
3839
import static org.junit.jupiter.api.Assertions.assertFalse;
3940
import static org.junit.jupiter.api.Assertions.assertNotNull;
@@ -113,6 +114,13 @@ void testDeleteDirectoryOnNotExists() throws IOException {
113114

114115
@Test
115116
void testDeleteDirectoryOnIOException() throws Exception {
117+
ExecutorService executor = newSingleThreadExecutor();
118+
executor.submit(this::testDeleteDirectoryOnIOException0);
119+
shutdown(executor);
120+
executor.awaitTermination(5, SECONDS);
121+
}
122+
123+
File testDeleteDirectoryOnIOException0() throws Exception {
116124
File testDir = createRandomTempDirectory();
117125

118126
ExecutorService fileCreationExecutor = newSingleThreadExecutor();
@@ -161,6 +169,8 @@ void testDeleteDirectoryOnIOException() throws Exception {
161169
assertNotNull(ioExceptionReference.get());
162170
assertFalse(creatingFile.get());
163171
assertFalse(deletingDirectory.get());
172+
173+
return testDir;
164174
}
165175

166176
@Test

microsphere-java-core/src/test/java/io/microsphere/lang/ClassDataRepositoryTest.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@ void testGetClassNamesInClassPath() {
5050
for (String classPath : classPaths) {
5151
Set<String> classNames = repository.getClassNamesInClassPath(classPath, true);
5252
assertNotNull(classNames);
53-
assertThrows(UnsupportedOperationException.class, classNames::clear);
5453
}
5554
}
5655

microsphere-java-core/src/test/java/io/microsphere/util/StringUtilsTest.java

Lines changed: 50 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,15 @@
22

33
import org.junit.jupiter.api.Test;
44

5+
import static io.microsphere.collection.ListUtils.newLinkedList;
6+
import static io.microsphere.collection.Lists.ofList;
57
import static io.microsphere.constants.SymbolConstants.COMMA;
6-
import static io.microsphere.constants.SymbolConstants.COMMA_CHAR;
78
import static io.microsphere.constants.SymbolConstants.DOT;
9+
import static io.microsphere.constants.SymbolConstants.SHARP;
810
import static io.microsphere.constants.SymbolConstants.SPACE;
9-
import static io.microsphere.constants.SymbolConstants.SPACE_CHAR;
1011
import static io.microsphere.constants.SymbolConstants.VERTICAL_BAR;
1112
import static io.microsphere.util.ArrayUtils.ofArray;
13+
import static io.microsphere.util.CharSequenceUtils.length;
1214
import static io.microsphere.util.CharSequenceUtilsTest.TEST_BLANK_STRING;
1315
import static io.microsphere.util.CharSequenceUtilsTest.TEST_CSV_STRING;
1416
import static io.microsphere.util.CharSequenceUtilsTest.TEST_EMPTY_STRING;
@@ -31,17 +33,20 @@
3133
import static io.microsphere.util.StringUtils.substringBefore;
3234
import static io.microsphere.util.StringUtils.substringBeforeLast;
3335
import static io.microsphere.util.StringUtils.substringBetween;
36+
import static io.microsphere.util.StringUtils.toStringArray;
3437
import static io.microsphere.util.StringUtils.trimAllWhitespace;
3538
import static io.microsphere.util.StringUtils.trimLeadingWhitespace;
3639
import static io.microsphere.util.StringUtils.trimTrailingWhitespace;
3740
import static io.microsphere.util.StringUtils.trimWhitespace;
3841
import static io.microsphere.util.StringUtils.uncapitalize;
42+
import static java.util.Collections.emptyList;
3943
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
4044
import static org.junit.jupiter.api.Assertions.assertEquals;
4145
import static org.junit.jupiter.api.Assertions.assertFalse;
4246
import static org.junit.jupiter.api.Assertions.assertNull;
4347
import static org.junit.jupiter.api.Assertions.assertSame;
4448
import static org.junit.jupiter.api.Assertions.assertTrue;
49+
import static org.springframework.util.StringUtils.delimitedListToStringArray;
4550

4651
/**
4752
* {@link StringUtils} Test
@@ -81,26 +86,39 @@ void testIsNotBlank() {
8186

8287
@Test
8388
void testSplit() {
84-
String[] values = split(null, SPACE_CHAR);
85-
assertSame(EMPTY_STRING_ARRAY, values);
89+
assertSame(EMPTY_STRING_ARRAY, assertSplit(null, SPACE));
8690

87-
values = split(TEST_EMPTY_STRING, SPACE);
88-
assertSame(EMPTY_STRING_ARRAY, values);
91+
assertSame(EMPTY_STRING_ARRAY, assertSplit(TEST_EMPTY_STRING, SPACE));
8992

90-
values = split(TEST_BLANK_STRING, null);
91-
assertSame(EMPTY_STRING_ARRAY, values);
93+
assertSame(EMPTY_STRING_ARRAY, assertSplit(TEST_EMPTY_STRING, EMPTY_STRING));
9294

93-
values = split(TEST_BLANK_STRING, SPACE);
94-
assertArrayEquals(EMPTY_STRING_ARRAY, values);
95+
assertArrayEquals(ofArray(TEST_BLANK_STRING), assertSplit(TEST_BLANK_STRING, null));
9596

96-
values = split(SPACE + SPACE, SPACE);
97-
assertArrayEquals(EMPTY_STRING_ARRAY, values);
97+
assertArrayEquals(ofArray(TEST_BLANK_STRING), assertSplit(TEST_BLANK_STRING, EMPTY_STRING));
9898

99-
values = split(SPACE + SPACE + SPACE, SPACE);
100-
assertArrayEquals(EMPTY_STRING_ARRAY, values);
99+
assertArrayEquals(ofArray(EMPTY_STRING, EMPTY_STRING), assertSplit(TEST_BLANK_STRING, SPACE));
101100

102-
values = split(TEST_CSV_STRING, COMMA_CHAR);
103-
assertArrayEquals(ofArray("a", "b", "c"), values);
101+
assertArrayEquals(ofArray(EMPTY_STRING, EMPTY_STRING, EMPTY_STRING), assertSplit(SPACE + SPACE, SPACE));
102+
103+
assertArrayEquals(ofArray(EMPTY_STRING, EMPTY_STRING, EMPTY_STRING, EMPTY_STRING), assertSplit(SPACE + SPACE + SPACE, SPACE));
104+
105+
assertArrayEquals(ofArray("a", "b", "c"), assertSplit(TEST_CSV_STRING, COMMA));
106+
107+
assertArrayEquals(ofArray(TEST_CSV_STRING), assertSplit(TEST_CSV_STRING, SPACE));
108+
109+
assertArrayEquals(ofArray("a", "", "b", "c"), assertSplit("a, , b, c", ", "));
110+
}
111+
112+
String[] assertSplit(String str, String delimiter) {
113+
String[] values = split(str, delimiter);
114+
int length = length(delimiter);
115+
if (length == 1) {
116+
assertArrayEquals(split(str, delimiter.charAt(0)), values);
117+
} else if (length > 1) {
118+
String[] valuesFromString = delimitedListToStringArray(str, delimiter);
119+
assertArrayEquals(valuesFromString, values);
120+
}
121+
return values;
104122
}
105123

106124
@Test
@@ -161,7 +179,10 @@ void testEndsWith() {
161179
@Test
162180
void testReplace() {
163181
assertNull(replace(null, null, null));
182+
164183
assertEquals(TEST_EMPTY_STRING, replace(TEST_EMPTY_STRING, null, null));
184+
assertEquals(TEST_EMPTY_STRING, replace(TEST_EMPTY_STRING, "null", null));
185+
assertEquals(TEST_CSV_STRING, replace(TEST_CSV_STRING, "null", "null"));
165186
assertEquals(TEST_EMPTY_STRING, replace(TEST_EMPTY_STRING, TEST_EMPTY_STRING, null));
166187
assertEquals(TEST_EMPTY_STRING, replace(TEST_EMPTY_STRING, TEST_EMPTY_STRING, TEST_EMPTY_STRING, 0));
167188

@@ -173,6 +194,9 @@ void testReplace() {
173194
assertEquals("a|b|c", replace(TEST_CSV_STRING, COMMA, VERTICAL_BAR));
174195
assertEquals("a|b|c", replace(TEST_CSV_STRING, COMMA, VERTICAL_BAR, 100));
175196
assertEquals("a|b,c", replace(TEST_CSV_STRING, COMMA, VERTICAL_BAR, 1));
197+
198+
assertEquals("abc", replace(TEST_CSV_STRING, COMMA, EMPTY_STRING));
199+
176200
}
177201

178202
@Test
@@ -227,6 +251,7 @@ void testSubstringBeforeLast() {
227251
assertSame(TEST_EMPTY_STRING, substringBeforeLast(TEST_EMPTY_STRING, null));
228252
assertSame(TEST_CSV_STRING, substringBeforeLast(TEST_CSV_STRING, null));
229253
assertSame(TEST_CSV_STRING, substringBeforeLast(TEST_CSV_STRING, TEST_EMPTY_STRING));
254+
assertSame(TEST_CSV_STRING, substringBeforeLast(TEST_CSV_STRING, SHARP));
230255

231256
assertEquals("a,b", substringBeforeLast(TEST_CSV_STRING, COMMA));
232257
assertEquals("a,", substringBeforeLast(TEST_CSV_STRING, "b"));
@@ -246,6 +271,7 @@ void testSubstringAfterLast() {
246271
assertEquals(",c", substringAfterLast(TEST_CSV_STRING, "b"));
247272
assertEquals("c", substringAfterLast(TEST_CSV_STRING, COMMA));
248273
assertEquals(TEST_EMPTY_STRING, substringAfterLast(TEST_CSV_STRING, "c"));
274+
assertEquals(TEST_EMPTY_STRING, substringAfterLast(TEST_CSV_STRING, SHARP));
249275
}
250276

251277
@Test
@@ -326,4 +352,12 @@ void testUncapitalize() {
326352
assertSame("hello world", uncapitalize("hello world"));
327353
}
328354

355+
@Test
356+
void testToStringArray() {
357+
assertSame(EMPTY_STRING_ARRAY, toStringArray(null));
358+
assertSame(EMPTY_STRING_ARRAY, toStringArray(emptyList()));
359+
assertSame(EMPTY_STRING_ARRAY, toStringArray(newLinkedList()));
360+
assertArrayEquals(ofArray("a", "b", "c"), toStringArray(ofList("a", "b", "c")));
361+
}
362+
329363
}

0 commit comments

Comments
 (0)