diff --git a/.github/workflows/maven-build.yml b/.github/workflows/maven-build.yml index e6edb1a1f..0bbaba8d5 100644 --- a/.github/workflows/maven-build.yml +++ b/.github/workflows/maven-build.yml @@ -22,21 +22,21 @@ jobs: java: [ '8', '11' , '17' , '21' , '25' ] steps: - name: Checkout Source - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Setup JDK ${{ matrix.Java }} - uses: actions/setup-java@v4 + uses: actions/setup-java@v5 with: distribution: 'temurin' java-version: ${{ matrix.java }} - cache: maven - name: Build with Maven - run: mvn + run: ./mvnw --batch-mode --update-snapshots --file pom.xml -Drevision=0.0.1-SNAPSHOT + -Dsurefire.useSystemClassLoader=false test --activate-profiles test,coverage diff --git a/.github/workflows/maven-publish.yml b/.github/workflows/maven-publish.yml index 6d40bcd43..61db0dc6d 100644 --- a/.github/workflows/maven-publish.yml +++ b/.github/workflows/maven-publish.yml @@ -24,10 +24,10 @@ jobs: if: ${{ inputs.revision }} steps: - name: Checkout Source - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Setup Maven Central Repository - uses: actions/setup-java@v4 + uses: actions/setup-java@v5 with: java-version: '11' distribution: 'temurin' diff --git a/.mvn/wrapper/maven-wrapper.jar b/.mvn/wrapper/maven-wrapper.jar deleted file mode 100755 index bf82ff01c..000000000 Binary files a/.mvn/wrapper/maven-wrapper.jar and /dev/null differ diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties index d83cf1363..423c23e5e 100644 --- a/.mvn/wrapper/maven-wrapper.properties +++ b/.mvn/wrapper/maven-wrapper.properties @@ -1,16 +1,3 @@ -# Copyright 2013-2023 the original author or authors. -# -# 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 -# -# https://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. - -distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.0/apache-maven-3.9.0-bin.zip -wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar \ No newline at end of file +wrapperVersion=3.3.4 +distributionType=only-script +distributionUrl=https://maven.aliyun.com/repository/public/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip diff --git a/microsphere-annotation-processor/pom.xml b/microsphere-annotation-processor/pom.xml index 0af57d196..26473f3d3 100644 --- a/microsphere-annotation-processor/pom.xml +++ b/microsphere-annotation-processor/pom.xml @@ -18,11 +18,6 @@ Microsphere :: Java :: Annotation Processor Microsphere Annotation Processor - - 2.1 - 2.3.1 - - @@ -32,6 +27,13 @@ ${revision} + + + io.github.microsphere-projects + microsphere-lang-model + ${revision} + + org.junit.jupiter @@ -45,6 +47,22 @@ test + + + io.github.microsphere-projects + microsphere-jdk-tools + ${revision} + test + + + + + io.github.microsphere-projects + microsphere-java-test + ${revision} + test + + ch.qos.logback @@ -56,7 +74,6 @@ javax.ws.rs javax.ws.rs-api - ${javax.ws.rs.version} test @@ -64,7 +81,6 @@ javax.xml.ws jaxws-api - ${jaxws-api.version} test diff --git a/microsphere-annotation-processor/src/main/java/io/microsphere/annotation/processor/ConfigurationPropertyAnnotationProcessor.java b/microsphere-annotation-processor/src/main/java/io/microsphere/annotation/processor/ConfigurationPropertyAnnotationProcessor.java index 547c702a2..4523a1e42 100644 --- a/microsphere-annotation-processor/src/main/java/io/microsphere/annotation/processor/ConfigurationPropertyAnnotationProcessor.java +++ b/microsphere-annotation-processor/src/main/java/io/microsphere/annotation/processor/ConfigurationPropertyAnnotationProcessor.java @@ -18,7 +18,7 @@ package io.microsphere.annotation.processor; import io.microsphere.annotation.ConfigurationProperty; -import io.microsphere.annotation.processor.model.util.ConfigurationPropertyJSONElementVisitor; +import io.microsphere.constants.ResourceConstants; import io.microsphere.json.JSONArray; import io.microsphere.metadata.ConfigurationPropertyGenerator; @@ -35,12 +35,12 @@ import java.util.List; import java.util.Set; -import static io.microsphere.annotation.processor.model.util.ConfigurationPropertyJSONElementVisitor.CONFIGURATION_PROPERTY_ANNOTATION_CLASS_NAME; -import static io.microsphere.annotation.processor.util.MessagerUtils.printNote; +import static io.microsphere.annotation.processor.ConfigurationPropertyJSONElementVisitor.CONFIGURATION_PROPERTY_ANNOTATION_CLASS_NAME; import static io.microsphere.constants.ResourceConstants.CONFIGURATION_PROPERTY_METADATA_RESOURCE; import static io.microsphere.constants.SymbolConstants.COMMA_CHAR; import static io.microsphere.constants.SymbolConstants.LEFT_SQUARE_BRACKET_CHAR; import static io.microsphere.constants.SymbolConstants.RIGHT_SQUARE_BRACKET_CHAR; +import static io.microsphere.lang.model.util.MessagerUtils.printNote; import static io.microsphere.metadata.ConfigurationPropertyLoader.loadAll; import static javax.lang.model.SourceVersion.latestSupported; import static javax.tools.StandardLocation.CLASS_OUTPUT; @@ -62,7 +62,7 @@ * *
  • {@link #resolveMetadata(RoundEnvironment)} traverses all root elements to extract configuration property metadata.
  • *
  • {@link #writeMetadata()} writes the generated metadata into a JSON file under - * {@value #CONFIGURATION_PROPERTY_METADATA_RESOURCE_NAME} using a writer.
  • + * {@value ResourceConstants#CONFIGURATION_PROPERTY_METADATA_RESOURCE} using a writer. * * * @author Mercy @@ -106,24 +106,28 @@ public boolean process(Set annotations, RoundEnvironment private void resolveMetadata(RoundEnvironment roundEnv) { Set elements = roundEnv.getRootElements(); - if (!elements.isEmpty()) { + resolveMetadata(elements); + } + + void resolveMetadata(Set elements) { + jsonBuilder.append(LEFT_SQUARE_BRACKET_CHAR); + // Resolve the content + if (!elements.isEmpty()) { Iterator iterator = elements.iterator(); - jsonBuilder.append(LEFT_SQUARE_BRACKET_CHAR); while (iterator.hasNext()) { Element element = iterator.next(); element.accept(jsonElementVisitor, jsonBuilder); } - // append the JSON content generated by ConfigurationPropertyGenerator SPI appendGeneratedConfigurationPropertyJSON(jsonBuilder); + } - int lastIndex = jsonBuilder.length() - 1; - if (COMMA_CHAR == jsonBuilder.charAt(lastIndex)) { - jsonBuilder.setCharAt(lastIndex, RIGHT_SQUARE_BRACKET_CHAR); - } else { - jsonBuilder.append(RIGHT_SQUARE_BRACKET_CHAR); - } + int lastIndex = jsonBuilder.length() - 1; + if (COMMA_CHAR == jsonBuilder.charAt(lastIndex)) { + jsonBuilder.setCharAt(lastIndex, RIGHT_SQUARE_BRACKET_CHAR); + } else { + jsonBuilder.append(RIGHT_SQUARE_BRACKET_CHAR); } } @@ -151,9 +155,12 @@ private void writeMetadata() { }); } + String toJSON() { + return jsonBuilder.toString(); + } + @Override public SourceVersion getSupportedSourceVersion() { return latestSupported(); } } - \ No newline at end of file diff --git a/microsphere-annotation-processor/src/main/java/io/microsphere/annotation/processor/model/util/ConfigurationPropertyJSONElementVisitor.java b/microsphere-annotation-processor/src/main/java/io/microsphere/annotation/processor/ConfigurationPropertyJSONElementVisitor.java similarity index 79% rename from microsphere-annotation-processor/src/main/java/io/microsphere/annotation/processor/model/util/ConfigurationPropertyJSONElementVisitor.java rename to microsphere-annotation-processor/src/main/java/io/microsphere/annotation/processor/ConfigurationPropertyJSONElementVisitor.java index 963392408..e30972026 100644 --- a/microsphere-annotation-processor/src/main/java/io/microsphere/annotation/processor/model/util/ConfigurationPropertyJSONElementVisitor.java +++ b/microsphere-annotation-processor/src/main/java/io/microsphere/annotation/processor/ConfigurationPropertyJSONElementVisitor.java @@ -15,10 +15,11 @@ * limitations under the License. */ -package io.microsphere.annotation.processor.model.util; +package io.microsphere.annotation.processor; import io.microsphere.annotation.ConfigurationProperty; import io.microsphere.beans.ConfigurationProperty.Metadata; +import io.microsphere.lang.model.util.AnnotatedElementJSONElementVisitor; import io.microsphere.metadata.ConfigurationPropertyGenerator; import javax.annotation.processing.ProcessingEnvironment; @@ -26,18 +27,19 @@ import javax.lang.model.element.AnnotationValue; import javax.lang.model.element.Element; import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.TypeElement; import javax.lang.model.element.VariableElement; import javax.lang.model.type.TypeMirror; import java.util.List; import java.util.Map; -import static io.microsphere.annotation.processor.util.AnnotationUtils.getAnnotation; -import static io.microsphere.annotation.processor.util.AnnotationUtils.getAttributeName; -import static io.microsphere.annotation.processor.util.AnnotationUtils.getElementValues; -import static io.microsphere.annotation.processor.util.AnnotationUtils.matchesDefaultAttributeValue; -import static io.microsphere.annotation.processor.util.ClassUtils.getClassName; -import static io.microsphere.annotation.processor.util.TypeUtils.getTypeName; import static io.microsphere.constants.SymbolConstants.COMMA_CHAR; +import static io.microsphere.lang.model.util.AnnotationUtils.getAnnotation; +import static io.microsphere.lang.model.util.AnnotationUtils.getAttributeName; +import static io.microsphere.lang.model.util.AnnotationUtils.getElementValues; +import static io.microsphere.lang.model.util.AnnotationUtils.matchesDefaultAttributeValue; +import static io.microsphere.lang.model.util.ClassUtils.getClassName; +import static io.microsphere.lang.model.util.TypeUtils.getTypeName; import static io.microsphere.util.ServiceLoaderUtils.loadFirstService; import static io.microsphere.util.StringUtils.isBlank; @@ -51,13 +53,13 @@ * @see io.microsphere.beans.ConfigurationProperty * @since 1.0.0 */ -public class ConfigurationPropertyJSONElementVisitor extends AnnotatedElementJSONElementVisitor { +class ConfigurationPropertyJSONElementVisitor extends AnnotatedElementJSONElementVisitor { - public static final String CONFIGURATION_PROPERTY_ANNOTATION_CLASS_NAME = "io.microsphere.annotation.ConfigurationProperty"; + static final String CONFIGURATION_PROPERTY_ANNOTATION_CLASS_NAME = "io.microsphere.annotation.ConfigurationProperty"; private final ConfigurationPropertyGenerator generator; - public ConfigurationPropertyJSONElementVisitor(ProcessingEnvironment processingEnv) { + ConfigurationPropertyJSONElementVisitor(ProcessingEnvironment processingEnv) { super(processingEnv, CONFIGURATION_PROPERTY_ANNOTATION_CLASS_NAME); this.generator = loadFirstService(ConfigurationPropertyGenerator.class); } @@ -87,8 +89,8 @@ public Boolean visitVariableAsField(VariableElement field, StringBuilder jsonBui } else if ("description".equals(attributeName)) { String description = resolveDescription(field, attributeMethod, annotationValue); configurationProperty.setDescription(description); - } else if ("source".equals(attributeName)) { - setSources(configurationProperty, annotationValue); + } else { + setSources(configurationProperty, attributeName, annotationValue); } } setDeclaredClass(configurationProperty, field); @@ -102,6 +104,11 @@ public Boolean visitVariableAsField(VariableElement field, StringBuilder jsonBui return false; } + @Override + protected boolean supportsType(TypeElement e) { + return true; + } + public ConfigurationPropertyGenerator getGenerator() { return generator; } @@ -130,12 +137,14 @@ private String resolveStringValue(ExecutableElement attributeMethod, AnnotationV return (String) value; } - private void setSources(io.microsphere.beans.ConfigurationProperty configurationProperty, AnnotationValue annotationValue) { - List sources = (List) annotationValue.getValue(); - Metadata metadata = configurationProperty.getMetadata(); - for (AnnotationValue source : sources) { - String sourceValue = (String) source.getValue(); - metadata.getSources().add(sourceValue); + void setSources(io.microsphere.beans.ConfigurationProperty configurationProperty, String attributeName, AnnotationValue annotationValue) { + if ("source".equals(attributeName)) { + List sources = (List) annotationValue.getValue(); + Metadata metadata = configurationProperty.getMetadata(); + for (AnnotationValue source : sources) { + String sourceValue = (String) source.getValue(); + metadata.getSources().add(sourceValue); + } } } @@ -149,5 +158,4 @@ private void setDeclaredField(io.microsphere.beans.ConfigurationProperty configu String declaredFieldName = field.getSimpleName().toString(); configurationProperty.getMetadata().setDeclaredField(declaredFieldName); } - -} +} \ No newline at end of file diff --git a/microsphere-annotation-processor/src/main/java/io/microsphere/annotation/processor/FilerProcessor.java b/microsphere-annotation-processor/src/main/java/io/microsphere/annotation/processor/FilerProcessor.java index 36d1416b4..5a34c0fa5 100644 --- a/microsphere-annotation-processor/src/main/java/io/microsphere/annotation/processor/FilerProcessor.java +++ b/microsphere-annotation-processor/src/main/java/io/microsphere/annotation/processor/FilerProcessor.java @@ -24,7 +24,7 @@ import javax.tools.JavaFileManager; import java.util.function.BiFunction; -import static io.microsphere.annotation.processor.util.MessagerUtils.printMandatoryWarning; +import static io.microsphere.lang.model.util.MessagerUtils.printMandatoryWarning; import static io.microsphere.reflect.FieldUtils.getFieldValue; /** diff --git a/microsphere-annotation-processor/src/main/java/io/microsphere/annotation/processor/ResourceProcessor.java b/microsphere-annotation-processor/src/main/java/io/microsphere/annotation/processor/ResourceProcessor.java index ab7b0c883..71852e810 100644 --- a/microsphere-annotation-processor/src/main/java/io/microsphere/annotation/processor/ResourceProcessor.java +++ b/microsphere-annotation-processor/src/main/java/io/microsphere/annotation/processor/ResourceProcessor.java @@ -34,8 +34,8 @@ import java.util.function.BiFunction; import java.util.function.Function; -import static io.microsphere.annotation.processor.util.MessagerUtils.printNote; -import static io.microsphere.annotation.processor.util.MessagerUtils.printWarning; +import static io.microsphere.lang.model.util.MessagerUtils.printNote; +import static io.microsphere.lang.model.util.MessagerUtils.printWarning; import static io.microsphere.util.ExceptionUtils.wrap; import static java.util.Optional.empty; import static java.util.Optional.of; diff --git a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/ConfigurationPropertyAnnotationProcessorTest.java b/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/ConfigurationPropertyAnnotationProcessorTest.java index 82693aa0f..2e2806fa0 100644 --- a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/ConfigurationPropertyAnnotationProcessorTest.java +++ b/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/ConfigurationPropertyAnnotationProcessorTest.java @@ -17,19 +17,11 @@ package io.microsphere.annotation.processor; -import io.microsphere.annotation.ConfigurationProperty; -import io.microsphere.classloading.ManifestArtifactResourceResolver; -import io.microsphere.io.IOUtils; -import io.microsphere.io.StandardFileWatchService; -import io.microsphere.reflect.MethodUtils; -import io.microsphere.reflect.TypeUtils; -import io.microsphere.util.ServiceLoaderUtils; +import io.microsphere.test.annotation.processing.AbstractAnnotationProcessingTest; import org.junit.jupiter.api.Test; -import java.util.Set; - -import static io.microsphere.annotation.processor.model.util.ConfigurationPropertyJSONElementVisitor.CONFIGURATION_PROPERTY_ANNOTATION_CLASS_NAME; -import static org.junit.jupiter.api.Assertions.assertEquals; +import static io.microsphere.util.Assert.assertNotNull; +import static java.util.Collections.emptySet; /** * {@link ConfigurationPropertyAnnotationProcessor} Test @@ -40,24 +32,12 @@ */ class ConfigurationPropertyAnnotationProcessorTest extends AbstractAnnotationProcessingTest { - @Override - protected void beforeTest() { - super.beforeTest(); - } - - @Override - protected void addCompiledClasses(Set> compiledClasses) { - compiledClasses.add(ManifestArtifactResourceResolver.class); - compiledClasses.add(IOUtils.class); - compiledClasses.add(StandardFileWatchService.class); - compiledClasses.add(TypeUtils.class); - compiledClasses.add(ServiceLoaderUtils.class); - compiledClasses.add(MethodUtils.class); - compiledClasses.add(ConfigurationProperty.class); - } - @Test - void testConstants() { - assertEquals("io.microsphere.annotation.ConfigurationProperty", CONFIGURATION_PROPERTY_ANNOTATION_CLASS_NAME); + void testResolveMetadataOnEmptySet() { + ConfigurationPropertyAnnotationProcessor processor = new ConfigurationPropertyAnnotationProcessor(); + processor.init(super.processingEnv); + processor.resolveMetadata(emptySet()); + String json = processor.toJSON(); + assertNotNull("[]", json); } -} +} \ No newline at end of file diff --git a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/ConfigurationPropertyJSONElementVisitorTest.java b/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/ConfigurationPropertyJSONElementVisitorTest.java new file mode 100644 index 000000000..89e4e5deb --- /dev/null +++ b/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/ConfigurationPropertyJSONElementVisitorTest.java @@ -0,0 +1,76 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 io.microsphere.annotation.processor; + + +import io.microsphere.annotation.ConfigurationProperty; +import io.microsphere.classloading.ManifestArtifactResourceResolver; +import io.microsphere.io.IOUtils; +import io.microsphere.io.StandardFileWatchService; +import io.microsphere.reflect.MethodUtils; +import io.microsphere.reflect.TypeUtils; +import io.microsphere.test.annotation.processing.AbstractAnnotationProcessingTest; +import io.microsphere.util.ServiceLoaderUtils; +import org.junit.jupiter.api.Test; + +import java.util.Set; + +import static io.microsphere.annotation.processor.ConfigurationPropertyJSONElementVisitor.CONFIGURATION_PROPERTY_ANNOTATION_CLASS_NAME; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * {@link ConfigurationPropertyJSONElementVisitor} Test + * + * @author Mercy + * @see ConfigurationPropertyJSONElementVisitor + * @since 1.0.0 + */ +class ConfigurationPropertyJSONElementVisitorTest extends AbstractAnnotationProcessingTest { + + @Override + protected void addCompiledClasses(Set> compiledClasses) { + compiledClasses.add(ManifestArtifactResourceResolver.class); + compiledClasses.add(IOUtils.class); + compiledClasses.add(StandardFileWatchService.class); + compiledClasses.add(TypeUtils.class); + compiledClasses.add(ServiceLoaderUtils.class); + compiledClasses.add(MethodUtils.class); + compiledClasses.add(ConfigurationProperty.class); + } + + @Test + void testConstants() { + assertEquals("io.microsphere.annotation.ConfigurationProperty", CONFIGURATION_PROPERTY_ANNOTATION_CLASS_NAME); + } + + @Test + void testSupportsType() { + ConfigurationPropertyJSONElementVisitor visitor = new ConfigurationPropertyJSONElementVisitor(super.processingEnv); + assertTrue(visitor.supportsType(super.testTypeElement)); + assertTrue(visitor.supportsType(NULL_TYPE_ELEMENT)); + } + + @Test + void testSetSourcesOnNoSource() { + ConfigurationPropertyJSONElementVisitor visitor = new ConfigurationPropertyJSONElementVisitor(super.processingEnv); + visitor.setSources(null, "noSource", null); + assertNotNull(visitor); + } +} \ No newline at end of file diff --git a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/FilerProcessorTest.java b/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/FilerProcessorTest.java index 47588edde..8f715df0f 100644 --- a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/FilerProcessorTest.java +++ b/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/FilerProcessorTest.java @@ -18,10 +18,14 @@ package io.microsphere.annotation.processor; +import io.microsphere.test.annotation.processing.AbstractAnnotationProcessingTest; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.api.extension.ReflectiveInvocationContext; import javax.tools.JavaFileManager; import javax.tools.JavaFileObject; +import java.lang.reflect.Method; import static io.microsphere.annotation.processor.ResourceProcessor.exists; import static org.junit.jupiter.api.Assertions.assertFalse; @@ -40,7 +44,7 @@ class FilerProcessorTest extends AbstractAnnotationProcessingTest { private FilerProcessor processor; @Override - protected void beforeTest() { + protected void beforeTest(ReflectiveInvocationContext invocationContext, ExtensionContext extensionContext) { this.processor = new FilerProcessor(super.processingEnv); } diff --git a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/ResourceProcessorTest.java b/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/ResourceProcessorTest.java index 35ad93340..1ed22a16d 100644 --- a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/ResourceProcessorTest.java +++ b/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/ResourceProcessorTest.java @@ -18,9 +18,13 @@ package io.microsphere.annotation.processor; +import io.microsphere.test.annotation.processing.AbstractAnnotationProcessingTest; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.api.extension.ReflectiveInvocationContext; import javax.tools.FileObject; +import java.lang.reflect.Method; import java.util.Optional; import static io.microsphere.annotation.processor.ResourceProcessor.FOR_READING; @@ -30,11 +34,14 @@ import static io.microsphere.nio.charset.CharsetUtils.DEFAULT_CHARSET; import static java.lang.Boolean.FALSE; import static java.lang.System.currentTimeMillis; +import static java.util.Optional.empty; import static javax.tools.StandardLocation.CLASS_OUTPUT; import static javax.tools.StandardLocation.SOURCE_PATH; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertSame; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -56,14 +63,14 @@ class ResourceProcessorTest extends AbstractAnnotationProcessingTest { private String randomResourceName; @Override - protected void beforeTest() { + protected void beforeTest(ReflectiveInvocationContext invocationContext, ExtensionContext extensionContext) { this.classOutputProcessor = new ResourceProcessor(super.processingEnv, CLASS_OUTPUT); this.sourcePathProcessor = new ResourceProcessor(super.processingEnv, SOURCE_PATH); this.randomResourceName = "test/" + currentTimeMillis() + ".txt"; } @Override - protected void afterTest() { + protected void afterTest(ReflectiveInvocationContext invocationContext, ExtensionContext extensionContext, Object result, Throwable failure) { this.classOutputProcessor.getResource(this.randomResourceName, FOR_WRITING).ifPresent(FileObject::delete); } @@ -77,6 +84,10 @@ void testProcessInResourceOnFailed() { assertThrows(RuntimeException.class, () -> this.classOutputProcessor.processInResource(this.randomResourceName, FOR_READING, fileObject -> { throw new RuntimeException(); })); + + assertNull(this.classOutputProcessor.processInResource(this.randomResourceName, FOR_READING, fileObject -> { + throw new RuntimeException(); + }, e -> null)); } @Test @@ -97,6 +108,10 @@ void testProcessInResourceInputStreamOnFailed() { assertThrows(RuntimeException.class, () -> this.sourcePathProcessor.processInResourceInputStream(JAVA_SOURCE_RESOURCE_NAME, inputStream -> { throw new RuntimeException(); })); + + assertSame(empty(), this.sourcePathProcessor.processInResourceInputStream(JAVA_SOURCE_RESOURCE_NAME, inputStream -> { + throw new RuntimeException(); + }, (f, e) -> null)); } @Test @@ -111,6 +126,10 @@ void testProcessInResourceReaderOnFailed() { assertThrows(RuntimeException.class, () -> this.sourcePathProcessor.processInResourceReader(JAVA_SOURCE_RESOURCE_NAME, reader -> { throw new RuntimeException(); })); + + assertSame(empty(), this.sourcePathProcessor.processInResourceReader(JAVA_SOURCE_RESOURCE_NAME, reader -> { + throw new RuntimeException(); + }, (f, e) -> null)); } @Test @@ -124,6 +143,10 @@ void testProcessInResourceContentOnFailed() { assertThrows(RuntimeException.class, () -> this.sourcePathProcessor.processInResourceContent(JAVA_SOURCE_RESOURCE_NAME, content -> { throw new RuntimeException(); })); + + assertSame(empty(), this.sourcePathProcessor.processInResourceContent(JAVA_SOURCE_RESOURCE_NAME, content -> { + throw new RuntimeException(); + }, (f, e) -> null)); } @Test @@ -138,6 +161,12 @@ void testProcessInResourceOutputStreamOnFailed() { assertThrows(RuntimeException.class, () -> this.classOutputProcessor.processInResourceOutputStream(this.randomResourceName, outputStream -> { throw new RuntimeException(); })); + + this.classOutputProcessor.processInResourceOutputStream(this.randomResourceName, outputStream -> { + throw new RuntimeException(); + }, (f, e) -> { + assertNotNull(e); + }); } @Test @@ -152,6 +181,12 @@ void testProcessInResourceOnWriterOnFailed() { assertThrows(RuntimeException.class, () -> this.classOutputProcessor.processInResourceWriter(randomResourceName, writer -> { throw new RuntimeException(); })); + + this.classOutputProcessor.processInResourceWriter(this.randomResourceName, writer -> { + throw new RuntimeException(); + }, (f, e) -> { + assertNotNull(e); + }); } @Test diff --git a/microsphere-java-annotations/pom.xml b/microsphere-java-annotations/pom.xml new file mode 100644 index 000000000..e80e54ea5 --- /dev/null +++ b/microsphere-java-annotations/pom.xml @@ -0,0 +1,44 @@ + + + + io.github.microsphere-projects + microsphere-java-parent + ${revision} + ../microsphere-java-parent/pom.xml + + 4.0.0 + + io.github.microsphere-projects + microsphere-java-annotations + ${revision} + jar + + Microsphere :: Java :: Annotations + Microsphere Java Annotations + + + + + + com.google.code.findbugs + jsr305 + true + + + + + org.junit.jupiter + junit-jupiter + test + + + + org.junit.jupiter + junit-jupiter-engine + test + + + + \ No newline at end of file diff --git a/microsphere-java-core/src/main/java/io/microsphere/annotation/ConfigurationProperty.java b/microsphere-java-annotations/src/main/java/io/microsphere/annotation/ConfigurationProperty.java similarity index 99% rename from microsphere-java-core/src/main/java/io/microsphere/annotation/ConfigurationProperty.java rename to microsphere-java-annotations/src/main/java/io/microsphere/annotation/ConfigurationProperty.java index dd6272f95..10203087e 100644 --- a/microsphere-java-core/src/main/java/io/microsphere/annotation/ConfigurationProperty.java +++ b/microsphere-java-annotations/src/main/java/io/microsphere/annotation/ConfigurationProperty.java @@ -94,4 +94,4 @@ */ String[] source() default {}; -} +} \ No newline at end of file diff --git a/microsphere-java-core/src/main/java/io/microsphere/annotation/Experimental.java b/microsphere-java-annotations/src/main/java/io/microsphere/annotation/Experimental.java similarity index 99% rename from microsphere-java-core/src/main/java/io/microsphere/annotation/Experimental.java rename to microsphere-java-annotations/src/main/java/io/microsphere/annotation/Experimental.java index 498df0028..e3780f909 100644 --- a/microsphere-java-core/src/main/java/io/microsphere/annotation/Experimental.java +++ b/microsphere-java-annotations/src/main/java/io/microsphere/annotation/Experimental.java @@ -49,4 +49,4 @@ */ String description() default ""; -} +} \ No newline at end of file diff --git a/microsphere-java-core/src/main/java/io/microsphere/annotation/Immutable.java b/microsphere-java-annotations/src/main/java/io/microsphere/annotation/Immutable.java similarity index 99% rename from microsphere-java-core/src/main/java/io/microsphere/annotation/Immutable.java rename to microsphere-java-annotations/src/main/java/io/microsphere/annotation/Immutable.java index 593118b5e..0ae81044f 100644 --- a/microsphere-java-core/src/main/java/io/microsphere/annotation/Immutable.java +++ b/microsphere-java-annotations/src/main/java/io/microsphere/annotation/Immutable.java @@ -31,4 +31,4 @@ @Documented @Retention(RUNTIME) public @interface Immutable { -} +} \ No newline at end of file diff --git a/microsphere-java-core/src/main/java/io/microsphere/annotation/Nonnull.java b/microsphere-java-annotations/src/main/java/io/microsphere/annotation/Nonnull.java similarity index 99% rename from microsphere-java-core/src/main/java/io/microsphere/annotation/Nonnull.java rename to microsphere-java-annotations/src/main/java/io/microsphere/annotation/Nonnull.java index 859ec90a4..0a36bb87a 100644 --- a/microsphere-java-core/src/main/java/io/microsphere/annotation/Nonnull.java +++ b/microsphere-java-annotations/src/main/java/io/microsphere/annotation/Nonnull.java @@ -35,4 +35,4 @@ @javax.annotation.Nonnull @TypeQualifierNickname public @interface Nonnull { -} +} \ No newline at end of file diff --git a/microsphere-java-core/src/main/java/io/microsphere/annotation/Nullable.java b/microsphere-java-annotations/src/main/java/io/microsphere/annotation/Nullable.java similarity index 99% rename from microsphere-java-core/src/main/java/io/microsphere/annotation/Nullable.java rename to microsphere-java-annotations/src/main/java/io/microsphere/annotation/Nullable.java index c3a3a49e0..9b708f889 100644 --- a/microsphere-java-core/src/main/java/io/microsphere/annotation/Nullable.java +++ b/microsphere-java-annotations/src/main/java/io/microsphere/annotation/Nullable.java @@ -36,4 +36,4 @@ @javax.annotation.Nonnull(when = MAYBE) @TypeQualifierNickname public @interface Nullable { -} +} \ No newline at end of file diff --git a/microsphere-java-core/src/main/java/io/microsphere/annotation/Since.java b/microsphere-java-annotations/src/main/java/io/microsphere/annotation/Since.java similarity index 96% rename from microsphere-java-core/src/main/java/io/microsphere/annotation/Since.java rename to microsphere-java-annotations/src/main/java/io/microsphere/annotation/Since.java index bb840ccbc..c2ec0c22d 100644 --- a/microsphere-java-core/src/main/java/io/microsphere/annotation/Since.java +++ b/microsphere-java-annotations/src/main/java/io/microsphere/annotation/Since.java @@ -16,8 +16,6 @@ */ package io.microsphere.annotation; -import io.microsphere.util.Version; - import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; @@ -38,7 +36,6 @@ * The annotation that indicates the API is introduced in the first time. * * @author Mercy - * @see Version * @see Experimental * @since 1.0.0 */ @@ -65,7 +62,7 @@ /** * @return The version value of the API, e.g. 1.0.0 - * @see Version */ String value(); -} + +} \ No newline at end of file diff --git a/microsphere-java-core/src/test/java/io/microsphere/annotation/ConfigurationPropertyTest.java b/microsphere-java-annotations/src/test/java/io/microsphere/annotation/ConfigurationPropertyTest.java similarity index 96% rename from microsphere-java-core/src/test/java/io/microsphere/annotation/ConfigurationPropertyTest.java rename to microsphere-java-annotations/src/test/java/io/microsphere/annotation/ConfigurationPropertyTest.java index 54c7d50c6..c31732d3a 100644 --- a/microsphere-java-core/src/test/java/io/microsphere/annotation/ConfigurationPropertyTest.java +++ b/microsphere-java-annotations/src/test/java/io/microsphere/annotation/ConfigurationPropertyTest.java @@ -25,7 +25,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; /** - * {@link ConfigurationProperty} Test + * {@link ConfigurationProperty @ConfigurationProperty} Test * * @author Mercy * @see ConfigurationProperty diff --git a/microsphere-java-core/src/test/java/io/microsphere/annotation/ExperimentalTest.java b/microsphere-java-annotations/src/test/java/io/microsphere/annotation/ExperimentalTest.java similarity index 96% rename from microsphere-java-core/src/test/java/io/microsphere/annotation/ExperimentalTest.java rename to microsphere-java-annotations/src/test/java/io/microsphere/annotation/ExperimentalTest.java index 9014ea8a9..d4db9a409 100644 --- a/microsphere-java-core/src/test/java/io/microsphere/annotation/ExperimentalTest.java +++ b/microsphere-java-annotations/src/test/java/io/microsphere/annotation/ExperimentalTest.java @@ -21,7 +21,7 @@ import static org.junit.jupiter.api.Assertions.assertNull; /** - * {@link Experimental} Test + * {@link Experimental @Experimental} Test * * @author Mercy * @see Experimental diff --git a/microsphere-java-core/src/test/java/io/microsphere/annotation/ImmutableTest.java b/microsphere-java-annotations/src/test/java/io/microsphere/annotation/ImmutableTest.java similarity index 96% rename from microsphere-java-core/src/test/java/io/microsphere/annotation/ImmutableTest.java rename to microsphere-java-annotations/src/test/java/io/microsphere/annotation/ImmutableTest.java index 5d871cf1d..6ae1ffb79 100644 --- a/microsphere-java-core/src/test/java/io/microsphere/annotation/ImmutableTest.java +++ b/microsphere-java-annotations/src/test/java/io/microsphere/annotation/ImmutableTest.java @@ -22,7 +22,7 @@ import static org.junit.jupiter.api.Assertions.assertNotNull; /** - * {@link Immutable} Test + * {@link Immutable @Immutable} Test * * @author Mercy * @see Immutable diff --git a/microsphere-java-annotations/src/test/java/io/microsphere/annotation/NonnullTest.java b/microsphere-java-annotations/src/test/java/io/microsphere/annotation/NonnullTest.java new file mode 100644 index 000000000..cea51bd42 --- /dev/null +++ b/microsphere-java-annotations/src/test/java/io/microsphere/annotation/NonnullTest.java @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 io.microsphere.annotation; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertNotNull; + +/** + * {@link Nonnull @Nonnull} Test + * + * @author Mercy + * @see Nonnull + * @since 1.0.0 + */ +@Nonnull +class NonnullTest { + + @Test + void test() { + assertNotNull(NonnullTest.class.getAnnotation(Nonnull.class)); + } +} \ No newline at end of file diff --git a/microsphere-java-annotations/src/test/java/io/microsphere/annotation/NullableTest.java b/microsphere-java-annotations/src/test/java/io/microsphere/annotation/NullableTest.java new file mode 100644 index 000000000..25a6625fe --- /dev/null +++ b/microsphere-java-annotations/src/test/java/io/microsphere/annotation/NullableTest.java @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 io.microsphere.annotation; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertNotNull; + +/** + * {@link Nullable @Nullable} Test + * + * @author Mercy + * @see Nullable + * @since 1.0.0 + */ +@Nullable +class NullableTest { + + @Test + void test() { + assertNotNull(NullableTest.class.getAnnotation(Nullable.class)); + } +} \ No newline at end of file diff --git a/microsphere-java-core/src/test/java/io/microsphere/annotation/SinceTest.java b/microsphere-java-annotations/src/test/java/io/microsphere/annotation/SinceTest.java similarity index 99% rename from microsphere-java-core/src/test/java/io/microsphere/annotation/SinceTest.java rename to microsphere-java-annotations/src/test/java/io/microsphere/annotation/SinceTest.java index 1ecca38c8..1e6314b95 100644 --- a/microsphere-java-core/src/test/java/io/microsphere/annotation/SinceTest.java +++ b/microsphere-java-annotations/src/test/java/io/microsphere/annotation/SinceTest.java @@ -36,4 +36,4 @@ void test() { assertEquals("microsphere-java-core", since.module()); assertEquals("1.0.0", since.value()); } -} +} \ No newline at end of file diff --git a/microsphere-java-core/pom.xml b/microsphere-java-core/pom.xml index c6063daa5..c31c60b8c 100644 --- a/microsphere-java-core/pom.xml +++ b/microsphere-java-core/pom.xml @@ -20,11 +20,11 @@ - + - com.google.code.findbugs - jsr305 - true + io.github.microsphere-projects + microsphere-java-annotations + ${revision} @@ -62,6 +62,13 @@ test
    + + + com.google.code.findbugs + jsr305 + test + + ch.qos.logback diff --git a/microsphere-java-core/src/main/java/io/microsphere/classloading/BannedArtifactClassLoadingExecutor.java b/microsphere-java-core/src/main/java/io/microsphere/classloading/BannedArtifactClassLoadingExecutor.java index 98749c614..4d5f8325a 100644 --- a/microsphere-java-core/src/main/java/io/microsphere/classloading/BannedArtifactClassLoadingExecutor.java +++ b/microsphere-java-core/src/main/java/io/microsphere/classloading/BannedArtifactClassLoadingExecutor.java @@ -81,21 +81,19 @@ public BannedArtifactClassLoadingExecutor(@Nullable ClassLoader classLoader) { } public void execute() { - List bannedArtifactConfigs = loadBannedArtifactConfigs(); + List bannedArtifactConfigs = loadBannedArtifactConfigs(this.classLoader); List artifacts = artifactDetector.detect(false); - for (Artifact artifact : artifacts) { + artifacts.forEach(artifact -> { URL classPathURL = artifact.getLocation(); - if (classPathURL != null) { - for (MavenArtifact bannedArtifactConfig : bannedArtifactConfigs) { - if (bannedArtifactConfig.matches(artifact)) { - removeClassPathURL(classLoader, classPathURL); - } + for (MavenArtifact bannedArtifactConfig : bannedArtifactConfigs) { + if (bannedArtifactConfig.matches(artifact)) { + removeClassPathURL(classLoader, classPathURL); } } - } + }); } - private List loadBannedArtifactConfigs() { + static List loadBannedArtifactConfigs(ClassLoader classLoader) { List bannedArtifactConfigs = new LinkedList<>(); try { Enumeration configResources = classLoader.getResources(CONFIG_LOCATION); @@ -110,7 +108,7 @@ private List loadBannedArtifactConfigs() { return bannedArtifactConfigs; } - private List loadBannedArtifactConfigs(URL configResource) throws IOException { + static List loadBannedArtifactConfigs(URL configResource) throws IOException { List bannedArtifactConfigs = new LinkedList<>(); try (InputStream inputStream = configResource.openStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, ENCODING)) @@ -127,14 +125,10 @@ private List loadBannedArtifactConfigs(URL configResource) throws return bannedArtifactConfigs; } - /** - * @param definition - * @return - */ - private MavenArtifact loadBannedArtifactConfig(String definition) { + static MavenArtifact loadBannedArtifactConfig(String definition) throws IllegalArgumentException { String[] gav = split(definition.trim(), COLON); if (gav.length != 3) { - throw new RuntimeException("The definition of the banned artifact must contain groupId, artifactId and version : " + definition); + throw new IllegalArgumentException("The definition of the banned artifact must contain groupId, artifactId and version : " + definition); } String groupId = gav[0]; String artifactId = gav[1]; diff --git a/microsphere-java-core/src/main/java/io/microsphere/collection/DelegatingIterator.java b/microsphere-java-core/src/main/java/io/microsphere/collection/DelegatingIterator.java new file mode 100644 index 000000000..3975f19ab --- /dev/null +++ b/microsphere-java-core/src/main/java/io/microsphere/collection/DelegatingIterator.java @@ -0,0 +1,88 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 io.microsphere.collection; + +import io.microsphere.lang.DelegatingWrapper; + +import java.util.Iterator; +import java.util.function.Consumer; + +/** + * A delegating implementation of the {@link Iterator} interface that forwards all method calls to a delegate iterator. + * This class is useful when you want to wrap an existing iterator and potentially override some of its behavior. + * + *

    Example Usage

    + *
    {@code
    + * List list = Arrays.asList("a", "b", "c");
    + * Iterator iterator = new DelegatingIterator<>(list.iterator());
    + * while (iterator.hasNext()) {
    + *     System.out.println(iterator.next());
    + * }
    + * }
    + * + * @param the type of elements returned by this iterator + * @author Mercy + * @see Iterator + */ +public class DelegatingIterator implements Iterator, DelegatingWrapper { + + private final Iterator delegate; + + public DelegatingIterator(Iterator delegate) { + this.delegate = delegate; + } + + @Override + public final boolean hasNext() { + return delegate.hasNext(); + } + + @Override + public final E next() { + return delegate.next(); + } + + @Override + public final void remove() { + delegate.remove(); + } + + @Override + public final void forEachRemaining(Consumer action) { + this.delegate.forEachRemaining(action); + } + + @Override + public final Object getDelegate() { + return this.delegate; + } + + @Override + public final int hashCode() { + return this.delegate.hashCode(); + } + + @Override + public final boolean equals(Object obj) { + return this.delegate.equals(obj); + } + + @Override + public final String toString() { + return this.delegate.toString(); + } +} \ No newline at end of file diff --git a/microsphere-java-core/src/main/java/io/microsphere/collection/EmptyIterator.java b/microsphere-java-core/src/main/java/io/microsphere/collection/EmptyIterator.java index 83f95542d..08514248e 100644 --- a/microsphere-java-core/src/main/java/io/microsphere/collection/EmptyIterator.java +++ b/microsphere-java-core/src/main/java/io/microsphere/collection/EmptyIterator.java @@ -55,31 +55,15 @@ * @see Collections#emptyIterator() */ @Immutable -public class EmptyIterator implements Iterator { +public class EmptyIterator extends DelegatingIterator { /** * The singleton of {@link EmptyIterator} */ public static final EmptyIterator INSTANCE = new EmptyIterator(); - private final Iterator delegate; public EmptyIterator() { - this.delegate = emptyIterator(); - } - - @Override - public boolean hasNext() { - return delegate.hasNext(); - } - - @Override - public E next() { - return delegate.next(); - } - - @Override - public void remove() { - delegate.remove(); + super(emptyIterator()); } } diff --git a/microsphere-java-core/src/main/java/io/microsphere/concurrent/ExecutorUtils.java b/microsphere-java-core/src/main/java/io/microsphere/concurrent/ExecutorUtils.java index a4cfc45e8..930ce67d8 100644 --- a/microsphere-java-core/src/main/java/io/microsphere/concurrent/ExecutorUtils.java +++ b/microsphere-java-core/src/main/java/io/microsphere/concurrent/ExecutorUtils.java @@ -16,6 +16,7 @@ */ package io.microsphere.concurrent; +import io.microsphere.logging.Logger; import io.microsphere.util.ShutdownHookUtils; import io.microsphere.util.Utils; @@ -23,6 +24,7 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import static io.microsphere.logging.LoggerFactory.getLogger; import static io.microsphere.util.ArrayUtils.forEach; import static io.microsphere.util.ShutdownHookUtils.addShutdownHookCallback; @@ -37,6 +39,8 @@ */ public abstract class ExecutorUtils implements Utils { + private static final Logger logger = getLogger(ExecutorUtils.class); + /** * Registers a shutdown hook to gracefully shut down the given {@link Executor} instances when the JVM exits. * @@ -131,9 +135,10 @@ public static boolean shutdown(ExecutorService executorService) { if (!executorService.isShutdown()) { executorService.shutdown(); } + logger.trace("The ExecutorService({}) has been shutdown", executorService); return true; } private ExecutorUtils() { } -} +} \ No newline at end of file diff --git a/microsphere-java-core/src/main/java/io/microsphere/json/JSONStringer.java b/microsphere-java-core/src/main/java/io/microsphere/json/JSONStringer.java index 832787050..37c6dbd51 100644 --- a/microsphere-java-core/src/main/java/io/microsphere/json/JSONStringer.java +++ b/microsphere-java-core/src/main/java/io/microsphere/json/JSONStringer.java @@ -21,6 +21,11 @@ import static io.microsphere.json.JSONObject.NULL; import static io.microsphere.json.JSONObject.numberToString; +import static io.microsphere.json.JSONStringer.Scope.DANGLING_KEY; +import static io.microsphere.json.JSONStringer.Scope.EMPTY_ARRAY; +import static io.microsphere.json.JSONStringer.Scope.EMPTY_OBJECT; +import static io.microsphere.json.JSONStringer.Scope.NONEMPTY_ARRAY; +import static io.microsphere.json.JSONStringer.Scope.NONEMPTY_OBJECT; import static io.microsphere.util.ClassUtils.getTypeName; import static java.util.Arrays.fill; @@ -145,7 +150,7 @@ public JSONStringer(int indentSpaces) { * @throws JSONException if processing of json failed */ public JSONStringer array() throws JSONException { - return open(Scope.EMPTY_ARRAY, "["); + return open(EMPTY_ARRAY, "["); } /** @@ -155,7 +160,7 @@ public JSONStringer array() throws JSONException { * @throws JSONException if processing of json failed */ public JSONStringer endArray() throws JSONException { - return close(Scope.EMPTY_ARRAY, Scope.NONEMPTY_ARRAY, "]"); + return close(EMPTY_ARRAY, NONEMPTY_ARRAY, "]"); } /** @@ -166,7 +171,7 @@ public JSONStringer endArray() throws JSONException { * @throws JSONException if processing of json failed */ public JSONStringer object() throws JSONException { - return open(Scope.EMPTY_OBJECT, "{"); + return open(EMPTY_OBJECT, "{"); } /** @@ -176,7 +181,7 @@ public JSONStringer object() throws JSONException { * @throws JSONException if processing of json failed */ public JSONStringer endObject() throws JSONException { - return close(Scope.EMPTY_OBJECT, Scope.NONEMPTY_OBJECT, "}"); + return close(EMPTY_OBJECT, NONEMPTY_OBJECT, "}"); } /** @@ -188,7 +193,7 @@ public JSONStringer endObject() throws JSONException { * @throws JSONException if processing of json failed */ JSONStringer open(Scope empty, String openBracket) throws JSONException { - if (this.stack.isEmpty() && this.out.length() > 0) { + if (isEmpty() && this.out.length() > 0) { throw new JSONException("Nesting problem: multiple top-level roots"); } beforeValue(); @@ -228,7 +233,7 @@ JSONStringer close(Scope empty, Scope nonempty, String closeBracket) throws JSON * @throws JSONException if processing of json failed */ private Scope peek() throws JSONException { - if (this.stack.isEmpty()) { + if (isEmpty()) { throw new JSONException("Nesting problem"); } return this.stack.get(this.stack.size() - 1); @@ -253,7 +258,7 @@ private void replaceTop(Scope topOfStack) { * @throws JSONException if processing of json failed */ public JSONStringer value(Object value) throws JSONException { - if (this.stack.isEmpty()) { + if (isEmpty()) { throw new JSONException("Nesting problem"); } @@ -288,7 +293,7 @@ public JSONStringer value(Object value) throws JSONException { * @throws JSONException if processing of json failed */ public JSONStringer value(boolean value) throws JSONException { - if (this.stack.isEmpty()) { + if (isEmpty()) { throw new JSONException("Nesting problem"); } beforeValue(); @@ -305,7 +310,7 @@ public JSONStringer value(boolean value) throws JSONException { * @throws JSONException if processing of json failed */ public JSONStringer value(double value) throws JSONException { - if (this.stack.isEmpty()) { + if (isEmpty()) { throw new JSONException("Nesting problem"); } beforeValue(); @@ -321,7 +326,7 @@ public JSONStringer value(double value) throws JSONException { * @throws JSONException if processing of json failed */ public JSONStringer value(long value) throws JSONException { - if (this.stack.isEmpty()) { + if (isEmpty()) { throw new JSONException("Nesting problem"); } beforeValue(); @@ -414,13 +419,13 @@ public JSONStringer key(String name) throws JSONException { */ void beforeKey() throws JSONException { Scope context = peek(); - if (context == Scope.NONEMPTY_OBJECT) { // first in object + if (context == NONEMPTY_OBJECT) { // first in object this.out.append(','); - } else if (context != Scope.EMPTY_OBJECT) { // not in an object! + } else if (context != EMPTY_OBJECT) { // not in an object! throw new JSONException("Nesting problem"); } newline(); - replaceTop(Scope.DANGLING_KEY); + replaceTop(DANGLING_KEY); } /** @@ -431,20 +436,20 @@ void beforeKey() throws JSONException { * @throws JSONException if processing of json failed */ void beforeValue() throws JSONException { - if (this.stack.isEmpty()) { + if (isEmpty()) { return; } Scope context = peek(); - if (context == Scope.EMPTY_ARRAY) { // first in array - replaceTop(Scope.NONEMPTY_ARRAY); + if (context == EMPTY_ARRAY) { // first in array + replaceTop(NONEMPTY_ARRAY); newline(); - } else if (context == Scope.NONEMPTY_ARRAY) { // another in array + } else if (context == NONEMPTY_ARRAY) { // another in array this.out.append(','); newline(); - } else if (context == Scope.DANGLING_KEY) { // value for key + } else if (context == DANGLING_KEY) { // value for key this.out.append(this.indent == null ? ":" : ": "); - replaceTop(Scope.NONEMPTY_OBJECT); + replaceTop(NONEMPTY_OBJECT); } else if (context != Scope.NULL) { throw new JSONException("Nesting problem"); } @@ -466,4 +471,7 @@ public String toString() { return this.out.length() == 0 ? null : this.out.toString(); } + boolean isEmpty() { + return this.stack.isEmpty(); + } } diff --git a/microsphere-java-core/src/main/java/io/microsphere/json/JSONTokener.java b/microsphere-java-core/src/main/java/io/microsphere/json/JSONTokener.java index ac6e4318a..f17066c58 100644 --- a/microsphere-java-core/src/main/java/io/microsphere/json/JSONTokener.java +++ b/microsphere-java-core/src/main/java/io/microsphere/json/JSONTokener.java @@ -19,6 +19,10 @@ import static io.microsphere.json.JSONObject.NULL; import static java.lang.Boolean.FALSE; import static java.lang.Boolean.TRUE; +import static java.lang.Double.valueOf; +import static java.lang.Integer.MAX_VALUE; +import static java.lang.Integer.MIN_VALUE; +import static java.lang.Long.parseLong; /** * Parses a JSON (RFC 4627) encoded @@ -117,8 +121,8 @@ public Object nextValue() throws JSONException { } int nextCleanInternal() throws JSONException { - while (this.pos < this.in.length()) { - int c = this.in.charAt(this.pos++); + while (hasNext()) { + int c = nextChar(); switch (c) { case '\t': case ' ': @@ -131,7 +135,7 @@ int nextCleanInternal() throws JSONException { return c; } - char peek = this.in.charAt(this.pos); + char peek = currentChar(); switch (peek) { case '*': // skip a /* c-style comment */ @@ -175,8 +179,8 @@ int nextCleanInternal() throws JSONException { * terminated by "\r\n", the '\n' must be consumed as whitespace by the caller. */ void skipToEndOfLine() { - for (; this.pos < this.in.length(); this.pos++) { - char c = this.in.charAt(this.pos); + for (; hasNext(); this.pos++) { + char c = currentChar(); if (c == '\r' || c == '\n') { this.pos++; break; @@ -206,8 +210,8 @@ public String nextString(char quote) throws JSONException { /* the index of the first character not yet appended to the builder. */ int start = this.pos; - while (this.pos < this.in.length()) { - int c = this.in.charAt(this.pos++); + while (hasNext()) { + int c = nextChar(); if (c == quote) { if (builder == null) { // a new string avoids leaking memory @@ -244,7 +248,7 @@ public String nextString(char quote) throws JSONException { * @throws JSONException if processing of json failed */ char readEscapeCharacter() throws JSONException { - char escaped = this.in.charAt(this.pos++); + char escaped = nextChar(); switch (escaped) { case 'u': if (this.pos + 4 > this.in.length()) { @@ -309,8 +313,8 @@ public Object readLiteral() throws JSONException { base = 8; } try { - long longValue = Long.parseLong(number, base); - if (longValue <= Integer.MAX_VALUE && longValue >= Integer.MIN_VALUE) { + long longValue = parseLong(number, base); + if (longValue <= MAX_VALUE && longValue >= MIN_VALUE) { return (int) longValue; } else { return longValue; @@ -326,7 +330,7 @@ public Object readLiteral() throws JSONException { /* ...next try to parse as a floating point... */ try { - return Double.valueOf(literal); + return valueOf(literal); } catch (NumberFormatException ignored) { } @@ -343,8 +347,8 @@ public Object readLiteral() throws JSONException { */ String nextToInternal(String excluded) { int start = this.pos; - for (; this.pos < this.in.length(); this.pos++) { - char c = this.in.charAt(this.pos); + for (; hasNext(); this.pos++) { + char c = currentChar(); if (c == '\r' || c == '\n' || excluded.indexOf(c) != -1) { return this.in.substring(start, this.pos); } @@ -389,7 +393,7 @@ public JSONObject readObject() throws JSONException { if (separator != ':' && separator != '=') { throw syntaxError("Expected ':' after " + name); } - if (this.pos < this.in.length() && this.in.charAt(this.pos) == '>') { + if (hasNext() && currentChar() == '>') { this.pos++; } @@ -486,11 +490,15 @@ public String toString() { */ public boolean more() { - return this.pos < this.in.length(); + return hasNext(); } public char next() { - return this.pos < this.in.length() ? this.in.charAt(this.pos++) : '\0'; + return hasNext() ? nextChar() : '\0'; + } + + public boolean hasNext() { + return this.pos < this.in.length(); } public char next(char c) throws JSONException { @@ -547,6 +555,18 @@ public void back() { } } + char currentChar() { + return charAt(this.pos); + } + + char nextChar() { + return charAt(this.pos++); + } + + char charAt(int pos) { + return this.in.charAt(pos); + } + public static int dehexchar(char hex) { if (hex >= '0' && hex <= '9') { return hex - '0'; @@ -559,4 +579,4 @@ public static int dehexchar(char hex) { } } -} +} \ No newline at end of file diff --git a/microsphere-java-core/src/main/java/io/microsphere/management/ManagementUtils.java b/microsphere-java-core/src/main/java/io/microsphere/management/ManagementUtils.java index b14fa3f49..e96d8e662 100644 --- a/microsphere-java-core/src/main/java/io/microsphere/management/ManagementUtils.java +++ b/microsphere-java-core/src/main/java/io/microsphere/management/ManagementUtils.java @@ -1,14 +1,12 @@ package io.microsphere.management; -import io.microsphere.logging.Logger; import io.microsphere.process.ProcessIdResolver; import io.microsphere.util.ServiceLoaderUtils; import io.microsphere.util.Utils; -import java.util.List; +import java.util.Objects; -import static io.microsphere.logging.LoggerFactory.getLogger; import static io.microsphere.process.ProcessIdResolver.UNKNOWN_PROCESS_ID; import static io.microsphere.util.ServiceLoaderUtils.loadServicesList; @@ -22,29 +20,16 @@ */ public abstract class ManagementUtils implements Utils { - private static final Logger logger = getLogger(ManagementUtils.class); - static final long currentProcessId = resolveCurrentProcessId(); private static long resolveCurrentProcessId() { - List resolvers = loadServicesList(ProcessIdResolver.class); - Long processId = null; - for (ProcessIdResolver resolver : resolvers) { - if (resolver.supports()) { - if ((processId = resolver.current()) != null) { - log(resolver, processId); - break; - } - } - } - return processId == null ? UNKNOWN_PROCESS_ID : processId; - } - - static void log(ProcessIdResolver resolver, Long processId) { - if (logger.isTraceEnabled()) { - logger.trace("The process id was resolved by ProcessIdResolver[class : '{}' , priority : {}] successfully : {}", - resolver.getClass().getName(), resolver.getPriority(), processId); - } + return loadServicesList(ProcessIdResolver.class) + .stream() + .filter(ProcessIdResolver::supports) + .map(ProcessIdResolver::current) + .filter(Objects::nonNull) + .findFirst() + .orElse(UNKNOWN_PROCESS_ID); } /** @@ -75,4 +60,4 @@ public static long getCurrentProcessId() { private ManagementUtils() { } -} +} \ No newline at end of file diff --git a/microsphere-java-core/src/main/java/io/microsphere/process/ClassicProcessIdResolver.java b/microsphere-java-core/src/main/java/io/microsphere/process/ClassicProcessIdResolver.java index 7a1ce136c..10ff9f6ac 100644 --- a/microsphere-java-core/src/main/java/io/microsphere/process/ClassicProcessIdResolver.java +++ b/microsphere-java-core/src/main/java/io/microsphere/process/ClassicProcessIdResolver.java @@ -82,9 +82,7 @@ public boolean supports() { @Override public Long current() { Long processId = valueOf(processIdValue); - if (logger.isTraceEnabled()) { - logger.trace("The PID was resolved from the method 'java.lang.management.RuntimeMXBean#getName()' = {} : {}", runtimeName, processId); - } + logger.trace("The PID was resolved from the method 'java.lang.management.RuntimeMXBean#getName()' = {} : {}", runtimeName, processId); return processId; } @@ -92,4 +90,4 @@ public Long current() { public int getPriority() { return NORMAL_PRIORITY + 9; } -} +} \ No newline at end of file diff --git a/microsphere-java-core/src/main/java/io/microsphere/process/ModernProcessIdResolver.java b/microsphere-java-core/src/main/java/io/microsphere/process/ModernProcessIdResolver.java index 6a138378d..c1c606418 100644 --- a/microsphere-java-core/src/main/java/io/microsphere/process/ModernProcessIdResolver.java +++ b/microsphere-java-core/src/main/java/io/microsphere/process/ModernProcessIdResolver.java @@ -22,6 +22,7 @@ import static io.microsphere.reflect.MethodUtils.invokeMethod; import static io.microsphere.reflect.MethodUtils.invokeStaticMethod; import static io.microsphere.util.ClassLoaderUtils.resolveClass; +import static java.util.Objects.nonNull; /** * A {@link ProcessIdResolver} implementation for modern JDKs (Java 9+). @@ -56,16 +57,14 @@ public class ModernProcessIdResolver implements ProcessIdResolver { @Override public boolean supports() { - return PROCESS_HANDLE_CLASS != null; + return nonNull(PROCESS_HANDLE_CLASS); } @Override public Long current() { Object processHandle = invokeStaticMethod(PROCESS_HANDLE_CLASS, "current"); Long pid = invokeMethod(processHandle, PROCESS_HANDLE_CLASS, "pid"); - if (logger.isTraceEnabled()) { - logger.trace("The PID was resolved from the method 'java.lang.ProcessHandle#pid()' : {}", pid); - } + logger.trace("The PID was resolved from the method 'java.lang.ProcessHandle#pid()' : {}", pid); return pid; } diff --git a/microsphere-java-core/src/main/java/io/microsphere/process/VirtualMachineProcessIdResolver.java b/microsphere-java-core/src/main/java/io/microsphere/process/VirtualMachineProcessIdResolver.java index ddfa97746..a2e48bbba 100644 --- a/microsphere-java-core/src/main/java/io/microsphere/process/VirtualMachineProcessIdResolver.java +++ b/microsphere-java-core/src/main/java/io/microsphere/process/VirtualMachineProcessIdResolver.java @@ -27,6 +27,7 @@ import static io.microsphere.reflect.FieldUtils.getFieldValue; import static io.microsphere.reflect.MethodUtils.invokeMethod; import static java.lang.Long.valueOf; +import static java.util.Objects.nonNull; /** * A {@link ProcessIdResolver} implementation for retrieving the process ID using the SUN JVM internal APIs. @@ -81,7 +82,7 @@ public class VirtualMachineProcessIdResolver implements ProcessIdResolver { @Override public boolean supports() { - return JVM_FIELD != null; + return nonNull(JVM_FIELD); } @Override @@ -89,9 +90,7 @@ public Long current() { RuntimeMXBean runtimeMXBean = getRuntimeMXBean(); Object jvm = getFieldValue(runtimeMXBean, JVM_FIELD); Integer processId = invokeMethod(jvm, GET_PROCESS_ID_METHOD_NAME); - if (logger.isTraceEnabled()) { - logger.trace("The PID was resolved from the native method 'sun.management.VMManagementImpl#getProcessId()' : {}", processId); - } + logger.trace("The PID was resolved from the native method 'sun.management.VMManagementImpl#getProcessId()' : {}", processId); return valueOf(processId.longValue()); } diff --git a/microsphere-java-core/src/main/java/io/microsphere/reflect/ReflectionUtils.java b/microsphere-java-core/src/main/java/io/microsphere/reflect/ReflectionUtils.java index f92cd2481..c675db165 100644 --- a/microsphere-java-core/src/main/java/io/microsphere/reflect/ReflectionUtils.java +++ b/microsphere-java-core/src/main/java/io/microsphere/reflect/ReflectionUtils.java @@ -12,18 +12,21 @@ import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.ArrayList; -import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import java.util.Objects; +import static io.microsphere.collection.MapUtils.newLinkedHashMap; import static io.microsphere.logging.LoggerFactory.getLogger; -import static io.microsphere.reflect.AccessibleObjectUtils.trySetAccessible; +import static io.microsphere.reflect.FieldUtils.getFieldValue; +import static io.microsphere.reflect.MemberUtils.isStatic; +import static io.microsphere.reflect.TypeUtils.getTypeName; import static io.microsphere.util.ClassLoaderUtils.resolveClass; +import static io.microsphere.util.ClassUtils.getType; import static io.microsphere.util.ClassUtils.isPrimitive; import static io.microsphere.util.ClassUtils.isSimpleType; import static java.lang.Class.forName; -import static java.lang.reflect.Modifier.isStatic; +import static java.lang.Thread.currentThread; +import static java.util.Collections.emptyMap; import static java.util.Collections.unmodifiableMap; /** @@ -128,7 +131,7 @@ public abstract class ReflectionUtils implements Utils { static { int invocationFrame = 0; // Use java.lang.StackTraceElement to calculate frame - StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace(); + StackTraceElement[] stackTraceElements = currentThread().getStackTrace(); for (StackTraceElement stackTraceElement : stackTraceElements) { String className = stackTraceElement.getClassName(); if (TYPE.getName().equals(className)) { @@ -217,7 +220,7 @@ static String getCallerClassNameInGeneralJVM() { * @return specified invocation frame class */ static String getCallerClassNameInGeneralJVM(int invocationFrame) throws IndexOutOfBoundsException { - StackTraceElement[] elements = Thread.currentThread().getStackTrace(); + StackTraceElement[] elements = currentThread().getStackTrace(); if (invocationFrame < elements.length) { StackTraceElement targetStackTraceElement = elements[invocationFrame]; return targetStackTraceElement.getClassName(); @@ -387,16 +390,14 @@ public static List toList(Object array) throws IllegalArgumentException { return list; } - private static Object toObject(Object object) { - if (object == null) { - return object; - } - Class type = object.getClass(); - if (type.isArray()) { - return toList(object); - } else { - return object; + static Object toObject(Object object) { + if (object != null) { + Class type = object.getClass(); + if (type.isArray()) { + return toList(object); + } } + return object; } @@ -445,31 +446,27 @@ private static Object toObject(Object object) { @Nonnull @Immutable public static Map readFieldsAsMap(Object object) { - Map fieldsAsMap = new LinkedHashMap(); + if (object == null) { + return emptyMap(); + } Class type = object.getClass(); Field[] fields = type.getDeclaredFields(); + Map fieldsAsMap = newLinkedHashMap(fields.length); for (Field field : fields) { - if (isStatic(field.getModifiers())) { // To filter static fields + if (isStatic(field)) { // To filter static fields continue; } - trySetAccessible(field); - - try { - String fieldName = field.getName(); - Object fieldValue = field.get(object); - if (fieldValue != null && fieldValue != object) { - Class fieldValueType = fieldValue.getClass(); - if (!isPrimitive(fieldValueType) - && !isSimpleType(fieldValueType) - && !Objects.equals(object.getClass(), fieldValueType)) { - fieldValue = readFieldsAsMap(fieldValue); - } - fieldsAsMap.put(fieldName, fieldValue); + String fieldName = field.getName(); + Object fieldValue = getFieldValue(object, field); + Class fieldValueType = field.getType(); + if (fieldValue != object) { + if (!isPrimitive(fieldValueType) && !isSimpleType(fieldValueType) + && !object.getClass().equals(fieldValueType)) { + fieldValue = readFieldsAsMap(fieldValue); } - } catch (IllegalAccessException e) { - throw new IllegalStateException(e); + fieldsAsMap.put(fieldName, fieldValue); } } return unmodifiableMap(fieldsAsMap); @@ -502,10 +499,39 @@ public static Map readFieldsAsMap(Object object) { * {@link java.lang.reflect.InaccessibleObjectException}, false otherwise. */ public static boolean isInaccessibleObjectException(Throwable failure) { - return failure != null && INACCESSIBLE_OBJECT_EXCEPTION_CLASS_NAME.equals(failure.getClass().getName()); + return isInaccessibleObjectException(getType(failure)); } - private ReflectionUtils() { + /** + * Checks whether the specified {@link Class} represents + * {@link java.lang.reflect.InaccessibleObjectException}. + * + *

    This method is useful when dealing with reflection operations that may fail due to module system + * restrictions introduced in JDK 9+. It avoids direct dependency on the presence of the class, which + * may not be available in earlier JDK versions.

    + * + *

    Example Usage

    + *
    {@code
    +     * Class exceptionClass = SomeException.class;
    +     * if (ReflectionUtils.isInaccessibleObjectException(exceptionClass)) {
    +     *     System.err.println("The class represents InaccessibleObjectException");
    +     * } else {
    +     *     System.out.println("The class does not represent InaccessibleObjectException");
    +     * }
    +     * }
    + * + * @param throwableClass The {@link Class} to check. + * @return true if the specified {@link Class} represents + * {@link java.lang.reflect.InaccessibleObjectException}, false otherwise. + */ + public static boolean isInaccessibleObjectException(Class throwableClass) { + return isInaccessibleObjectException(getTypeName(throwableClass)); } + static boolean isInaccessibleObjectException(String className) { + return INACCESSIBLE_OBJECT_EXCEPTION_CLASS_NAME.equals(className); + } + + private ReflectionUtils() { + } } \ No newline at end of file diff --git a/microsphere-java-core/src/main/java/io/microsphere/reflect/TypeUtils.java b/microsphere-java-core/src/main/java/io/microsphere/reflect/TypeUtils.java index e0b2a6e60..d105b4059 100644 --- a/microsphere-java-core/src/main/java/io/microsphere/reflect/TypeUtils.java +++ b/microsphere-java-core/src/main/java/io/microsphere/reflect/TypeUtils.java @@ -646,7 +646,9 @@ static List doResolveActualTypeArgumentsInFastPath(Type type) { } @Nonnull - private static Map resolveTypeArgumentsMap(Type type, List hierarchicalTypes, int hierarchicalTypesSize, Class baseClass, TypeVariable[] baseTypeParameters) { + private static Map resolveTypeArgumentsMap(Type type, List hierarchicalTypes, + int hierarchicalTypesSize, Class baseClass, + TypeVariable[] baseTypeParameters) { int size = hierarchicalTypesSize + 1; @@ -663,14 +665,18 @@ private static Map resolveTypeArgumentsMap(Type type, Lis return typeArgumentsMap; } - private static void resolveTypeArgumentsMap(Type type, List hierarchicalTypes, int index, int hierarchicalTypesSize, Map typeArgumentsMap, Class baseClass, TypeVariable[] baseTypeParameters) { + private static void resolveTypeArgumentsMap(Type type, List hierarchicalTypes, int index, + int hierarchicalTypesSize, Map typeArgumentsMap, + Class baseClass, TypeVariable[] baseTypeParameters) { ParameterizedType pType = asParameterizedType(type); if (pType != null) { resolveTypeArgumentsMap(pType, hierarchicalTypes, index, hierarchicalTypesSize, typeArgumentsMap, baseClass, baseTypeParameters); } } - private static void resolveTypeArgumentsMap(ParameterizedType type, List hierarchicalTypes, int index, int hierarchicalTypesSize, Map typeArgumentsMap, Class baseClass, TypeVariable[] baseTypeParameters) { + private static void resolveTypeArgumentsMap(ParameterizedType type, List hierarchicalTypes, int index, + int hierarchicalTypesSize, Map typeArgumentsMap, + Class baseClass, TypeVariable[] baseTypeParameters) { Class klass = asClass(type); int baseTypeArgumentsLength = baseTypeParameters.length; @@ -1192,7 +1198,7 @@ public static List resolveTypeArguments(Class targetClass) { return emptyList(); } List typeArguments = newLinkedList(); - while (targetClass != null && targetClass != Object.class) { + while (targetClass != Object.class) { typeArguments.addAll(resolveTypeArguments(targetClass.getGenericSuperclass())); typeArguments.addAll(resolveTypeArguments(targetClass.getGenericInterfaces())); targetClass = targetClass.getSuperclass(); diff --git a/microsphere-java-core/src/main/java/io/microsphere/util/Assert.java b/microsphere-java-core/src/main/java/io/microsphere/util/Assert.java index 362d81bad..262f56136 100644 --- a/microsphere-java-core/src/main/java/io/microsphere/util/Assert.java +++ b/microsphere-java-core/src/main/java/io/microsphere/util/Assert.java @@ -502,4 +502,7 @@ public static void assertFieldMatchType(Object object, String fieldName, Class messageSupplier) { return messageSupplier == null ? null : messageSupplier.get(); } -} + + private Assert() { + } +} \ No newline at end of file diff --git a/microsphere-java-core/src/main/java/io/microsphere/util/StringUtils.java b/microsphere-java-core/src/main/java/io/microsphere/util/StringUtils.java index b8e92bf57..f5e8da389 100644 --- a/microsphere-java-core/src/main/java/io/microsphere/util/StringUtils.java +++ b/microsphere-java-core/src/main/java/io/microsphere/util/StringUtils.java @@ -173,7 +173,7 @@ public static String[] split(@Nullable String value, @Nullable String delimiter) List result = new ArrayList<>(); if (delimiterLength == 0) { - for (int i = 0; i < value.length(); i++) { + for (int i = 0; i < length; i++) { result.add(value.substring(i, i + 1)); } } else { @@ -882,6 +882,5 @@ static String trimWhitespace(String str, boolean includeLeading, boolean include } private StringUtils() { - super(); } -} +} \ No newline at end of file diff --git a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/model/ArrayTypeModel.java b/microsphere-java-core/src/main/java/io/microsphere/util/ThrowableUtils.java similarity index 62% rename from microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/model/ArrayTypeModel.java rename to microsphere-java-core/src/main/java/io/microsphere/util/ThrowableUtils.java index fc6c057f3..8f6d32c23 100644 --- a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/model/ArrayTypeModel.java +++ b/microsphere-java-core/src/main/java/io/microsphere/util/ThrowableUtils.java @@ -14,23 +14,27 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.microsphere.annotation.processor.model; + +package io.microsphere.util; /** - * Array Type Model + * The uitlities class for {@link Throwable} * + * @author Mercy + * @see Throwable * @since 1.0.0 */ -public class ArrayTypeModel { - - private int[] integers; // Primitive type array - - private String[] strings; // Simple type array - - private PrimitiveTypeModel[] primitiveTypeModels; // Complex type array +public abstract class ThrowableUtils implements Utils { - private Model[] models; // Hierarchical Complex type array + public static Throwable getRootCause(Throwable throwable) { + Throwable rootCause = throwable; + while (rootCause.getCause() != null) { + rootCause = rootCause.getCause(); + } + return rootCause; + } - private Color[] colors; // Enum type array + private ThrowableUtils() { + } } diff --git a/microsphere-java-core/src/test/java/io/microsphere/classloading/BannedArtifactClassLoadingExecutorTest.java b/microsphere-java-core/src/test/java/io/microsphere/classloading/BannedArtifactClassLoadingExecutorTest.java index f5e15dff7..f94a96960 100644 --- a/microsphere-java-core/src/test/java/io/microsphere/classloading/BannedArtifactClassLoadingExecutorTest.java +++ b/microsphere-java-core/src/test/java/io/microsphere/classloading/BannedArtifactClassLoadingExecutorTest.java @@ -18,6 +18,15 @@ import org.junit.jupiter.api.Test; +import java.io.IOException; +import java.net.URL; +import java.util.Enumeration; + +import static io.microsphere.classloading.BannedArtifactClassLoadingExecutor.loadBannedArtifactConfig; +import static io.microsphere.classloading.BannedArtifactClassLoadingExecutor.loadBannedArtifactConfigs; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + /** * {@link BannedArtifactClassLoadingExecutor} Test * @@ -26,10 +35,25 @@ */ class BannedArtifactClassLoadingExecutorTest { - private BannedArtifactClassLoadingExecutor detector = new BannedArtifactClassLoadingExecutor(); - @Test void testDetect() { + BannedArtifactClassLoadingExecutor detector = new BannedArtifactClassLoadingExecutor(); detector.execute(); } -} + + @Test + void testLoadBannedArtifactConfigsOnFailed() { + ClassLoader classLoader = new ClassLoader() { + @Override + public Enumeration getResources(String name) throws IOException { + throw new IOException("For testing"); + } + }; + assertTrue(loadBannedArtifactConfigs(classLoader).isEmpty()); + } + + @Test + void testLoadBannedArtifactConfigOnFailed() { + assertThrows(IllegalArgumentException.class, () -> loadBannedArtifactConfig("invalid-definition")); + } +} \ No newline at end of file diff --git a/microsphere-java-core/src/test/java/io/microsphere/collection/AbstractDequeTest.java b/microsphere-java-core/src/test/java/io/microsphere/collection/AbstractDequeTest.java index eb6aa11fe..df8696b1b 100644 --- a/microsphere-java-core/src/test/java/io/microsphere/collection/AbstractDequeTest.java +++ b/microsphere-java-core/src/test/java/io/microsphere/collection/AbstractDequeTest.java @@ -3,9 +3,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import java.util.Iterator; import java.util.NoSuchElementException; -import java.util.Objects; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNull; @@ -28,107 +26,7 @@ class AbstractDequeTest { @BeforeEach void setUp() { - - deque = new AbstractDeque() { - - private String value; - - @Override - public Iterator iterator() { - return new Iterator() { - - private int cursor = 0; - - @Override - public boolean hasNext() { - return cursor == 0; - } - - @Override - public String next() { - if (cursor++ == 0) { - return value; - } else { - throw new NoSuchElementException(); - } - } - - @Override - public void remove() { - if (cursor <= 1) { - value = null; - } else { - throw new NoSuchElementException(); - } - } - }; - } - - @Override - public Iterator descendingIterator() { - return iterator(); - } - - @Override - public boolean offerFirst(String s) { - if (value == null) { - value = s; - return true; - } - return false; - } - - @Override - public boolean offerLast(String s) { - return offerFirst(s); - } - - @Override - public String pollFirst() { - String s = value; - value = null; - return s; - } - - @Override - public String pollLast() { - return pollFirst(); - } - - @Override - public String getFirst() { - return value; - } - - @Override - public String getLast() { - return getFirst(); - } - - @Override - public String peekFirst() { - return value; - } - - @Override - public String peekLast() { - return value; - } - - @Override - public boolean removeLastOccurrence(Object o) { - if (Objects.equals(o, value)) { - value = null; - return true; - } - return false; - } - - @Override - public int size() { - return 1; - } - }; + deque = new TestDeque<>(1); } @Test @@ -189,7 +87,7 @@ void testPeekLast() { @Test void testRemoveFirstOccurrence() { - assertTrue(deque.removeFirstOccurrence(null)); + assertFalse(deque.removeFirstOccurrence(null)); deque.add(TEST_VALUE); assertFalse(deque.removeFirstOccurrence("")); assertTrue(deque.removeFirstOccurrence(TEST_VALUE)); diff --git a/microsphere-java-core/src/test/java/io/microsphere/collection/DelegatingIteratorTest.java b/microsphere-java-core/src/test/java/io/microsphere/collection/DelegatingIteratorTest.java new file mode 100644 index 000000000..f29382d37 --- /dev/null +++ b/microsphere-java-core/src/test/java/io/microsphere/collection/DelegatingIteratorTest.java @@ -0,0 +1,100 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 io.microsphere.collection; + + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.util.Iterator; +import java.util.List; +import java.util.NoSuchElementException; + +import static io.microsphere.collection.ListUtils.ofArrayList; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * {@link DelegatingIterator} Test + * + * @author Mercy + * @see DelegatingIterator + * @since 1.0.0 + */ +class DelegatingIteratorTest { + + private Iterator iterator; + + private DelegatingIterator delegatingIterator; + + @BeforeEach + void setUp() { + List list = ofArrayList("1", "2", "3"); + this.iterator = list.iterator(); + this.delegatingIterator = new DelegatingIterator<>(this.iterator); + } + + @Test + void testHasNext() { + assertTrue(delegatingIterator.hasNext()); + } + + @Test + void testNext() { + assertEquals("1", this.delegatingIterator.next()); + assertEquals("2", this.delegatingIterator.next()); + assertEquals("3", this.delegatingIterator.next()); + assertThrows(NoSuchElementException.class, this.delegatingIterator::next); + } + + @Test + void testRemove() { + while (this.delegatingIterator.hasNext()) { + this.delegatingIterator.next(); + this.delegatingIterator.remove(); + } + } + + @Test + void testForEachRemaining() { + this.delegatingIterator.forEachRemaining(Assertions::assertNotNull); + } + + @Test + void testGetDelegate() { + assertSame(this.delegatingIterator.getDelegate(), this.iterator); + } + + @Test + void testHashCode() { + assertEquals(this.delegatingIterator.hashCode(), this.iterator.hashCode()); + } + + @Test + void testEquals() { + assertEquals(this.delegatingIterator, this.iterator); + } + + @Test + void testToString() { + assertEquals(this.delegatingIterator.toString(), this.iterator.toString()); + } +} \ No newline at end of file diff --git a/microsphere-java-core/src/test/java/io/microsphere/collection/TestDeque.java b/microsphere-java-core/src/test/java/io/microsphere/collection/TestDeque.java new file mode 100644 index 000000000..f14674a7b --- /dev/null +++ b/microsphere-java-core/src/test/java/io/microsphere/collection/TestDeque.java @@ -0,0 +1,194 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 io.microsphere.collection; + +import java.util.Iterator; +import java.util.LinkedList; +import java.util.Spliterator; +import java.util.function.Consumer; +import java.util.function.Predicate; +import java.util.stream.Stream; + +import static java.lang.Integer.MAX_VALUE; + +/** + * {@link AbstractDeque} class for testing + * + * @author Mercy + * @see AbstractDeque + * @since 1.0.0 + */ +public class TestDeque extends AbstractDeque { + + private final int maxCapacity; + + private final LinkedList delegate = new LinkedList<>(); + + public TestDeque() { + this(MAX_VALUE); + } + + public TestDeque(int maxCapacity) { + this.maxCapacity = maxCapacity; + } + + @Override + public void addFirst(E e) { + super.addFirst(e); + } + + @Override + public void addLast(E e) { + super.addLast(e); + } + + @Override + public E removeFirst() { + return super.removeFirst(); + } + + @Override + public E removeLast() { + return super.removeLast(); + } + + @Override + public boolean removeFirstOccurrence(Object o) { + return super.removeFirstOccurrence(o); + } + + @Override + public void push(E e) { + super.push(e); + } + + @Override + public E pop() { + return super.pop(); + } + + @Override + public boolean offer(E e) { + return super.offer(e); + } + + @Override + public E poll() { + return super.poll(); + } + + @Override + public E peek() { + return super.peek(); + } + + @Override + public Iterator iterator() { + return delegate.iterator(); + } + + @Override + public void forEach(Consumer action) { + delegate.forEach(action); + } + + @Override + public boolean removeIf(Predicate filter) { + return delegate.removeIf(filter); + } + + @Override + public Spliterator spliterator() { + return delegate.spliterator(); + } + + @Override + public Stream stream() { + return delegate.stream(); + } + + @Override + public Stream parallelStream() { + return delegate.parallelStream(); + } + + @Override + public Iterator descendingIterator() { + return delegate.descendingIterator(); + } + + @Override + public boolean offerFirst(E e) { + if (isFull()) { + return false; + } + return delegate.offerFirst(e); + } + + @Override + public boolean offerLast(E e) { + if (isFull()) { + return false; + } + return delegate.offerLast(e); + } + + @Override + public E pollFirst() { + return delegate.pollFirst(); + } + + @Override + public E pollLast() { + return delegate.pollLast(); + } + + @Override + public E getFirst() { + return delegate.getFirst(); + } + + @Override + public E getLast() { + return delegate.getLast(); + } + + @Override + public E peekFirst() { + return delegate.peekFirst(); + } + + @Override + public E peekLast() { + return delegate.peekLast(); + } + + @Override + public boolean removeLastOccurrence(Object o) { + return delegate.removeLastOccurrence(o); + } + + @Override + public int size() { + return delegate.size(); + } + + public boolean isFull() { + return this.size() >= this.maxCapacity; + } +} \ No newline at end of file diff --git a/microsphere-java-core/src/test/java/io/microsphere/concurrent/ExecutorUtilsTest.java b/microsphere-java-core/src/test/java/io/microsphere/concurrent/ExecutorUtilsTest.java index ec6866136..26d821203 100644 --- a/microsphere-java-core/src/test/java/io/microsphere/concurrent/ExecutorUtilsTest.java +++ b/microsphere-java-core/src/test/java/io/microsphere/concurrent/ExecutorUtilsTest.java @@ -1,17 +1,24 @@ package io.microsphere.concurrent; import io.microsphere.AbstractTestCase; +import io.microsphere.util.ShutdownHookUtils; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import java.util.Iterator; import java.util.concurrent.Executor; import java.util.concurrent.ExecutorService; +import java.util.concurrent.PriorityBlockingQueue; import static io.microsphere.concurrent.CustomizedThreadFactory.newThreadFactory; import static io.microsphere.concurrent.ExecutorUtils.shutdown; import static io.microsphere.concurrent.ExecutorUtils.shutdownOnExit; +import static io.microsphere.reflect.FieldUtils.getStaticFieldValue; import static java.util.concurrent.Executors.newSingleThreadExecutor; +import static java.util.concurrent.TimeUnit.MILLISECONDS; import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; /** @@ -27,19 +34,41 @@ class ExecutorUtilsTest extends AbstractTestCase { @BeforeEach void setUp() { - executorService = newSingleThreadExecutor(newThreadFactory("ExecutorUtilsTest-", true)); - executorService.execute(() -> log("Running...")); + this.executorService = newSingleThreadExecutor(newThreadFactory("ExecutorUtilsTest-", true)); + this.executorService.execute(() -> log("Running...")); + } + + @AfterEach + void tearDown() { + this.executorService.shutdown(); } @Test - void testShutdownOnExit() { - shutdownOnExit(executorService, executorService, executorService); + void testShutdownOnExit() throws InterruptedException { + shutdownOnExit(this.executorService, this.executorService, this.executorService); + PriorityBlockingQueue shutdownHookCallbacks = getStaticFieldValue(ShutdownHookUtils.class, "shutdownHookCallbacks"); + assertNotNull(shutdownHookCallbacks); + + Iterator iterator = shutdownHookCallbacks.iterator(); + String classNamePrefix = ExecutorUtils.class.getName() + "$$Lambda/"; + while (iterator.hasNext()) { + Runnable callback = iterator.next(); + Class callbackClass = callback.getClass(); + String callbackClassName = callbackClass.getName(); + if (callbackClassName.startsWith(classNamePrefix)) { + callback.run(); + iterator.remove(); + } + } + if (this.executorService.awaitTermination(50, MILLISECONDS)) { + assertTrue(this.executorService.isShutdown()); + } } @Test void testShutdownForExecutor() { - assertTrue(shutdown((Executor) executorService)); - assertTrue(shutdown((Executor) executorService)); + assertTrue(shutdown((Executor) this.executorService)); + assertTrue(shutdown((Executor) this.executorService)); } @Test @@ -49,8 +78,8 @@ void testShutdownForExecutorOnNull() { @Test void testShutdownForExecutorService() { - assertTrue(shutdown(executorService)); - assertTrue(shutdown(executorService)); + assertTrue(shutdown(this.executorService)); + assertTrue(shutdown(this.executorService)); } @Test diff --git a/microsphere-java-core/src/test/java/io/microsphere/convert/AbstractConverterTest.java b/microsphere-java-core/src/test/java/io/microsphere/convert/AbstractConverterTest.java index b8a2273d3..5148e64ad 100644 --- a/microsphere-java-core/src/test/java/io/microsphere/convert/AbstractConverterTest.java +++ b/microsphere-java-core/src/test/java/io/microsphere/convert/AbstractConverterTest.java @@ -44,8 +44,14 @@ protected Object doConvert(Object source) throws Throwable { @Override protected Integer resolvePriority() { + super.resolvePriority(); return null; } + + @Override + public int getPriority() { + return super.getPriority(); + } }; } @@ -76,4 +82,8 @@ void testGetConverter() { assertNotEquals(this.converter, new Object()); } + @Test + void testEquals() { + assertEquals(this.converter, this.converter); + } } diff --git a/microsphere-java-core/src/test/java/io/microsphere/json/JSONUtilsTest.java b/microsphere-java-core/src/test/java/io/microsphere/json/JSONUtilsTest.java index 76420059c..d50fa6507 100644 --- a/microsphere-java-core/src/test/java/io/microsphere/json/JSONUtilsTest.java +++ b/microsphere-java-core/src/test/java/io/microsphere/json/JSONUtilsTest.java @@ -46,6 +46,7 @@ import static io.microsphere.collection.Sets.ofSet; import static io.microsphere.json.JSONObject.NULL; import static io.microsphere.json.JSONUtils.append; +import static io.microsphere.json.JSONUtils.appendName; import static io.microsphere.json.JSONUtils.convertValue; import static io.microsphere.json.JSONUtils.determineElementClass; import static io.microsphere.json.JSONUtils.escape; @@ -99,219 +100,219 @@ void setUp() { @Test void testAppendOnBoolean() { - append(jsonBuilder, "name", true); - assertEquals("\"name\":true", jsonBuilder.toString()); + append(this.jsonBuilder, "name", true); + assertEquals("\"name\":true", this.jsonBuilder.toString()); } @Test void testAppendOnByte() { - append(jsonBuilder, "name", (byte) 1); - assertEquals("\"name\":1", jsonBuilder.toString()); + append(this.jsonBuilder, "name", (byte) 1); + assertEquals("\"name\":1", this.jsonBuilder.toString()); } @Test void testAppendOnShort() { - append(jsonBuilder, "name", (short) 1); - assertEquals("\"name\":1", jsonBuilder.toString()); + append(this.jsonBuilder, "name", (short) 1); + assertEquals("\"name\":1", this.jsonBuilder.toString()); } @Test void testAppendOnInt() { - append(jsonBuilder, "name", 1); - assertEquals("\"name\":1", jsonBuilder.toString()); + append(this.jsonBuilder, "name", 1); + assertEquals("\"name\":1", this.jsonBuilder.toString()); } @Test void testAppendOnLong() { - append(jsonBuilder, "name", 1L); - assertEquals("\"name\":1", jsonBuilder.toString()); + append(this.jsonBuilder, "name", 1L); + assertEquals("\"name\":1", this.jsonBuilder.toString()); } @Test void testAppendOnFloat() { - append(jsonBuilder, "name", 1.0f); - assertEquals("\"name\":1.0", jsonBuilder.toString()); + append(this.jsonBuilder, "name", 1.0f); + assertEquals("\"name\":1.0", this.jsonBuilder.toString()); } @Test void testAppendOnDouble() { - append(jsonBuilder, "name", 1.0); - assertEquals("\"name\":1.0", jsonBuilder.toString()); + append(this.jsonBuilder, "name", 1.0); + assertEquals("\"name\":1.0", this.jsonBuilder.toString()); } @Test void testAppendOnChar() { - append(jsonBuilder, "name", 'a'); - assertEquals("\"name\":\"a\"", jsonBuilder.toString()); + append(this.jsonBuilder, "name", 'a'); + assertEquals("\"name\":\"a\"", this.jsonBuilder.toString()); } @Test void testAppendOnBooleanObject() { - append(jsonBuilder, "name", TRUE); - assertEquals("\"name\":true", jsonBuilder.toString()); + append(this.jsonBuilder, "name", TRUE); + assertEquals("\"name\":true", this.jsonBuilder.toString()); } @Test void testAppendOnByteObject() { - append(jsonBuilder, "name", valueOf((byte) 1)); - assertEquals("\"name\":1", jsonBuilder.toString()); + append(this.jsonBuilder, "name", valueOf((byte) 1)); + assertEquals("\"name\":1", this.jsonBuilder.toString()); } @Test void testAppendOnShortObject() { - append(jsonBuilder, "name", Short.valueOf((short) 1)); - assertEquals("\"name\":1", jsonBuilder.toString()); + append(this.jsonBuilder, "name", Short.valueOf((short) 1)); + assertEquals("\"name\":1", this.jsonBuilder.toString()); } @Test void testAppendOnIntegerObject() { - append(jsonBuilder, "name", Integer.valueOf(1)); - assertEquals("\"name\":1", jsonBuilder.toString()); + append(this.jsonBuilder, "name", Integer.valueOf(1)); + assertEquals("\"name\":1", this.jsonBuilder.toString()); } @Test void testAppendOnLongObject() { - append(jsonBuilder, "name", Long.valueOf(1L)); - assertEquals("\"name\":1", jsonBuilder.toString()); + append(this.jsonBuilder, "name", Long.valueOf(1L)); + assertEquals("\"name\":1", this.jsonBuilder.toString()); } @Test void testAppendOnFloatObject() { - append(jsonBuilder, "name", Float.valueOf(1.0f)); - assertEquals("\"name\":1.0", jsonBuilder.toString()); + append(this.jsonBuilder, "name", Float.valueOf(1.0f)); + assertEquals("\"name\":1.0", this.jsonBuilder.toString()); } @Test void testAppendOnDoubleObject() { - append(jsonBuilder, "name", Double.valueOf(1.0)); - assertEquals("\"name\":1.0", jsonBuilder.toString()); + append(this.jsonBuilder, "name", Double.valueOf(1.0)); + assertEquals("\"name\":1.0", this.jsonBuilder.toString()); } @Test void testAppendOnCharacterObject() { - append(jsonBuilder, "name", valueOf('a')); - assertEquals("\"name\":\"a\"", jsonBuilder.toString()); + append(this.jsonBuilder, "name", valueOf('a')); + assertEquals("\"name\":\"a\"", this.jsonBuilder.toString()); } @Test void testAppendOnString() { - append(jsonBuilder, "name", "a"); - assertEquals("\"name\":\"a\"", jsonBuilder.toString()); + append(this.jsonBuilder, "name", "a"); + assertEquals("\"name\":\"a\"", this.jsonBuilder.toString()); } @Test void testAppendOnType() { - append(jsonBuilder, "name", String.class); - assertEquals("\"name\":\"java.lang.String\"", jsonBuilder.toString()); + append(this.jsonBuilder, "name", String.class); + assertEquals("\"name\":\"java.lang.String\"", this.jsonBuilder.toString()); } @Test void testAppendOnBooleanObjectArray() { - append(jsonBuilder, "name", new Boolean[]{TRUE, FALSE}); - assertEquals("\"name\":[true,false]", jsonBuilder.toString()); + append(this.jsonBuilder, "name", new Boolean[]{TRUE, FALSE}); + assertEquals("\"name\":[true,false]", this.jsonBuilder.toString()); } @Test void testAppendOnByteObjectArray() { - append(jsonBuilder, "name", new Byte[]{(byte) 1, (byte) 2}); - assertEquals("\"name\":[1,2]", jsonBuilder.toString()); + append(this.jsonBuilder, "name", new Byte[]{(byte) 1, (byte) 2}); + assertEquals("\"name\":[1,2]", this.jsonBuilder.toString()); } @Test void testAppendOnShortObjectArray() { - append(jsonBuilder, "name", new Short[]{(short) 1, (short) 2}); - assertEquals("\"name\":[1,2]", jsonBuilder.toString()); + append(this.jsonBuilder, "name", new Short[]{(short) 1, (short) 2}); + assertEquals("\"name\":[1,2]", this.jsonBuilder.toString()); } @Test void testAppendOnIntegerObjectArray() { - append(jsonBuilder, "name", new Integer[]{1, 2}); - assertEquals("\"name\":[1,2]", jsonBuilder.toString()); + append(this.jsonBuilder, "name", new Integer[]{1, 2}); + assertEquals("\"name\":[1,2]", this.jsonBuilder.toString()); } @Test void testAppendOnLongObjectArray() { - append(jsonBuilder, "name", new Long[]{1L, 2L}); - assertEquals("\"name\":[1,2]", jsonBuilder.toString()); + append(this.jsonBuilder, "name", new Long[]{1L, 2L}); + assertEquals("\"name\":[1,2]", this.jsonBuilder.toString()); } @Test void testAppendOnFloatObjectArray() { - append(jsonBuilder, "name", new Float[]{1.0f, 2.0f}); - assertEquals("\"name\":[1.0,2.0]", jsonBuilder.toString()); + append(this.jsonBuilder, "name", new Float[]{1.0f, 2.0f}); + assertEquals("\"name\":[1.0,2.0]", this.jsonBuilder.toString()); } @Test void testAppendOnDoubleObjectArray() { - append(jsonBuilder, "name", new Double[]{1.0, 2.0}); - assertEquals("\"name\":[1.0,2.0]", jsonBuilder.toString()); + append(this.jsonBuilder, "name", new Double[]{1.0, 2.0}); + assertEquals("\"name\":[1.0,2.0]", this.jsonBuilder.toString()); } @Test void testAppendOnCharacterObjectArray() { - append(jsonBuilder, "name", new Character[]{'a', 'b'}); - assertEquals("\"name\":[\"a\",\"b\"]", jsonBuilder.toString()); + append(this.jsonBuilder, "name", new Character[]{'a', 'b'}); + assertEquals("\"name\":[\"a\",\"b\"]", this.jsonBuilder.toString()); } @Test void testAppendOnBooleanArray() { - append(jsonBuilder, "name", new boolean[]{true, false}); - assertEquals("\"name\":[true,false]", jsonBuilder.toString()); + append(this.jsonBuilder, "name", new boolean[]{true, false}); + assertEquals("\"name\":[true,false]", this.jsonBuilder.toString()); } @Test void testAppendOnByteArray() { - append(jsonBuilder, "name", new byte[]{1, 2}); - assertEquals("\"name\":[1,2]", jsonBuilder.toString()); + append(this.jsonBuilder, "name", new byte[]{1, 2}); + assertEquals("\"name\":[1,2]", this.jsonBuilder.toString()); } @Test void testAppendOnShortArray() { - append(jsonBuilder, "name", new short[]{1, 2}); - assertEquals("\"name\":[1,2]", jsonBuilder.toString()); + append(this.jsonBuilder, "name", new short[]{1, 2}); + assertEquals("\"name\":[1,2]", this.jsonBuilder.toString()); } @Test void testAppendOnIntegerArray() { - append(jsonBuilder, "name", new int[]{1, 2}); - assertEquals("\"name\":[1,2]", jsonBuilder.toString()); + append(this.jsonBuilder, "name", new int[]{1, 2}); + assertEquals("\"name\":[1,2]", this.jsonBuilder.toString()); } @Test void testAppendOnLongArray() { - append(jsonBuilder, "name", new long[]{1, 2}); - assertEquals("\"name\":[1,2]", jsonBuilder.toString()); + append(this.jsonBuilder, "name", new long[]{1, 2}); + assertEquals("\"name\":[1,2]", this.jsonBuilder.toString()); } @Test void testAppendOnFloatArray() { - append(jsonBuilder, "name", new float[]{1.0f, 2.0f}); - assertEquals("\"name\":[1.0,2.0]", jsonBuilder.toString()); + append(this.jsonBuilder, "name", new float[]{1.0f, 2.0f}); + assertEquals("\"name\":[1.0,2.0]", this.jsonBuilder.toString()); } @Test void testAppendOnDoubleArray() { - append(jsonBuilder, "name", new double[]{1.0, 2.0}); - assertEquals("\"name\":[1.0,2.0]", jsonBuilder.toString()); + append(this.jsonBuilder, "name", new double[]{1.0, 2.0}); + assertEquals("\"name\":[1.0,2.0]", this.jsonBuilder.toString()); } @Test void testAppendOnCharArray() { - append(jsonBuilder, "name", new char[]{'a', 'b'}); - assertEquals("\"name\":[\"a\",\"b\"]", jsonBuilder.toString()); + append(this.jsonBuilder, "name", new char[]{'a', 'b'}); + assertEquals("\"name\":[\"a\",\"b\"]", this.jsonBuilder.toString()); } @Test void testAppendOnStringArray() { - append(jsonBuilder, "name", new String[]{"a", "b"}); - assertEquals("\"name\":[\"a\",\"b\"]", jsonBuilder.toString()); + append(this.jsonBuilder, "name", new String[]{"a", "b"}); + assertEquals("\"name\":[\"a\",\"b\"]", this.jsonBuilder.toString()); } @Test void testAppendOnObjectAsArray() { Object value = new boolean[]{TRUE, FALSE}; - append(jsonBuilder, "name", value); - assertEquals("\"name\":[true,false]", jsonBuilder.toString()); + append(this.jsonBuilder, "name", value); + assertEquals("\"name\":[true,false]", this.jsonBuilder.toString()); } @Test @@ -328,44 +329,58 @@ void testAppendOnObjectAsMap() { "string", "8", "strings", new String[]{"9", "10"} ); - append(jsonBuilder, "name", value); + append(this.jsonBuilder, "name", value); } @Test void testAppendOnObjectAsIterable() { Object value = ofList(true, (byte) 1, '2', 3.0, 4.0f, 5L, 6, (short) 7, "8", ofArray("9", "10")); - append(jsonBuilder, "name", value); - assertEquals("\"name\":[true,1,\"2\",3.0,4.0,5,6,7,\"8\",[\"9\",\"10\"]]", jsonBuilder.toString()); + append(this.jsonBuilder, "name", value); + assertEquals("\"name\":[true,1,\"2\",3.0,4.0,5,6,7,\"8\",[\"9\",\"10\"]]", this.jsonBuilder.toString()); } @Test void testAppendOnObjectAsString() { Object value = "s"; - append(jsonBuilder, "name", value); - assertEquals("\"name\":\"s\"", jsonBuilder.toString()); + append(this.jsonBuilder, "name", value); + assertEquals("\"name\":\"s\"", this.jsonBuilder.toString()); } @Test void testAppendOnObjectAsInteger() { Object value = 1; - append(jsonBuilder, "name", value); - assertEquals("\"name\":1", jsonBuilder.toString()); + append(this.jsonBuilder, "name", value); + assertEquals("\"name\":1", this.jsonBuilder.toString()); } @Test void testAppendOnGenericArray() { TimeUnit[] values = ofArray(DAYS, HOURS, MINUTES); - append(jsonBuilder, "name", values); - assertEquals("\"name\":[\"DAYS\",\"HOURS\",\"MINUTES\"]", jsonBuilder.toString()); + append(this.jsonBuilder, "name", values); + assertEquals("\"name\":[\"DAYS\",\"HOURS\",\"MINUTES\"]", this.jsonBuilder.toString()); } @Test void testAppendOnTypeArray() { Class[] classes = ofArray(String.class, Integer.class); - append(jsonBuilder, "name", classes); - assertEquals("\"name\":[\"java.lang.String\",\"java.lang.Integer\"]", jsonBuilder.toString()); + append(this.jsonBuilder, "name", classes); + assertEquals("\"name\":[\"java.lang.String\",\"java.lang.Integer\"]", this.jsonBuilder.toString()); } + @Test + void testAppendName() { + appendName(this.jsonBuilder, null); + assertEquals(EMPTY_STRING, this.jsonBuilder.toString()); + + appendName(this.jsonBuilder, ""); + assertEquals(EMPTY_STRING, this.jsonBuilder.toString()); + + appendName(this.jsonBuilder, " "); + assertEquals(EMPTY_STRING, this.jsonBuilder.toString()); + + appendName(this.jsonBuilder, "name"); + assertEquals("\"name\":", this.jsonBuilder.toString()); + } @Test void testIsUnknownClass() { diff --git a/microsphere-java-core/src/test/java/io/microsphere/management/ManagementUtilsTest.java b/microsphere-java-core/src/test/java/io/microsphere/management/ManagementUtilsTest.java index 7f682bc44..bb40748ba 100644 --- a/microsphere-java-core/src/test/java/io/microsphere/management/ManagementUtilsTest.java +++ b/microsphere-java-core/src/test/java/io/microsphere/management/ManagementUtilsTest.java @@ -1,14 +1,11 @@ package io.microsphere.management; import io.microsphere.AbstractTestCase; -import io.microsphere.process.ProcessIdResolver; import org.junit.jupiter.api.Test; -import java.util.List; - +import static io.microsphere.management.ManagementUtils.currentProcessId; import static io.microsphere.management.ManagementUtils.getCurrentProcessId; -import static io.microsphere.process.ProcessIdResolver.UNKNOWN_PROCESS_ID; -import static io.microsphere.util.ServiceLoaderUtils.loadServicesList; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; /** @@ -22,16 +19,9 @@ class ManagementUtilsTest extends AbstractTestCase { @Test void testGetCurrentProcessId() { - long currentProcessId = getCurrentProcessId(); - assertTrue(currentProcessId > 0); - } - - @Test - void testLog() { - List resolvers = loadServicesList(ProcessIdResolver.class); - for (ProcessIdResolver resolver : resolvers) { - ManagementUtils.log(resolver, UNKNOWN_PROCESS_ID); - } + long processId = getCurrentProcessId(); + assertTrue(processId > 0); + assertEquals(currentProcessId, getCurrentProcessId()); } -} +} \ No newline at end of file diff --git a/microsphere-java-core/src/test/java/io/microsphere/net/DelegatingURLConnectionTest.java b/microsphere-java-core/src/test/java/io/microsphere/net/DelegatingURLConnectionTest.java index 7cfa84144..b2554b3ed 100644 --- a/microsphere-java-core/src/test/java/io/microsphere/net/DelegatingURLConnectionTest.java +++ b/microsphere-java-core/src/test/java/io/microsphere/net/DelegatingURLConnectionTest.java @@ -16,7 +16,6 @@ */ package io.microsphere.net; -import io.microsphere.io.IOUtils; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -27,11 +26,16 @@ import java.util.List; import java.util.Map; +import static io.microsphere.io.IOUtils.copyToString; +import static io.microsphere.net.ServiceLoaderURLStreamHandlerFactory.attach; +import static io.microsphere.net.console.HandlerTest.TEST_CONSOLE_URL; import static java.lang.System.currentTimeMillis; +import static java.lang.System.out; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertSame; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -96,207 +100,213 @@ void testGetReadTimeout() { @Test void testGetURL() { - assertEquals(url, urlConnection.getURL()); + assertEquals(url, this.urlConnection.getURL()); } @Test void testGetContentLength() { - assertEquals(19, urlConnection.getContentLength()); + assertEquals(19, this.urlConnection.getContentLength()); } @Test void testGetContentLengthLong() { - assertEquals(19, urlConnection.getContentLengthLong()); + assertEquals(19, this.urlConnection.getContentLengthLong()); } @Test void testGetContentType() { - assertEquals("content/unknown", urlConnection.getContentType()); + assertEquals("content/unknown", this.urlConnection.getContentType()); } @Test void testGetContentEncoding() { - assertNull(urlConnection.getContentEncoding()); + assertNull(this.urlConnection.getContentEncoding()); } @Test void testGetExpiration() { - assertEquals(0, urlConnection.getExpiration()); + assertEquals(0, this.urlConnection.getExpiration()); } @Test void testGetDate() { - assertEquals(0, urlConnection.getDate()); + assertEquals(0, this.urlConnection.getDate()); } @Test void testGetLastModified() { - assertFalse(urlConnection.getLastModified() > currentTimeMillis()); + assertFalse(this.urlConnection.getLastModified() > currentTimeMillis()); } @Test void testGetHeaderField() { - assertNull(urlConnection.getHeaderField(NOT_EXISTS_HEADER_NAME)); - assertEquals("19", urlConnection.getHeaderField(CONTENT_LENGTH_HEADER_NAME)); - assertNotNull(urlConnection.getHeaderField(LAST_MODIFIED_HEADER_NAME)); + assertNull(this.urlConnection.getHeaderField(NOT_EXISTS_HEADER_NAME)); + assertEquals("19", this.urlConnection.getHeaderField(CONTENT_LENGTH_HEADER_NAME)); + assertNotNull(this.urlConnection.getHeaderField(LAST_MODIFIED_HEADER_NAME)); } @Test void testGetHeaderFields() { - assertNotNull(urlConnection.getHeaderFields()); + assertNotNull(this.urlConnection.getHeaderFields()); } @Test void testGetHeaderFieldInt() { - assertEquals(19, urlConnection.getHeaderFieldInt(CONTENT_LENGTH_HEADER_NAME, 10)); - assertEquals(1, urlConnection.getHeaderFieldInt(NOT_EXISTS_HEADER_NAME, 1)); + assertEquals(19, this.urlConnection.getHeaderFieldInt(CONTENT_LENGTH_HEADER_NAME, 10)); + assertEquals(1, this.urlConnection.getHeaderFieldInt(NOT_EXISTS_HEADER_NAME, 1)); } @Test void testGetHeaderFieldLong() { - assertEquals(19, urlConnection.getHeaderFieldLong(CONTENT_LENGTH_HEADER_NAME, 10)); - assertEquals(1, urlConnection.getHeaderFieldLong(NOT_EXISTS_HEADER_NAME, 1)); + assertEquals(19, this.urlConnection.getHeaderFieldLong(CONTENT_LENGTH_HEADER_NAME, 10)); + assertEquals(1, this.urlConnection.getHeaderFieldLong(NOT_EXISTS_HEADER_NAME, 1)); } @Test void testGetHeaderFieldDate() { long now = currentTimeMillis(); - assertTrue(now > urlConnection.getHeaderFieldDate(LAST_MODIFIED_HEADER_NAME, now)); - assertEquals(now, urlConnection.getHeaderFieldDate(NOT_EXISTS_HEADER_NAME, now)); + assertTrue(now > this.urlConnection.getHeaderFieldDate(LAST_MODIFIED_HEADER_NAME, now)); + assertEquals(now, this.urlConnection.getHeaderFieldDate(NOT_EXISTS_HEADER_NAME, now)); } @Test void testGetHeaderFieldKey() { - assertEquals(CONTENT_LENGTH_HEADER_NAME, urlConnection.getHeaderFieldKey(0)); - assertEquals(LAST_MODIFIED_HEADER_NAME, urlConnection.getHeaderFieldKey(1)); - assertNull(urlConnection.getHeaderFieldKey(2)); + assertEquals(CONTENT_LENGTH_HEADER_NAME, this.urlConnection.getHeaderFieldKey(0)); + assertEquals(LAST_MODIFIED_HEADER_NAME, this.urlConnection.getHeaderFieldKey(1)); + assertNull(this.urlConnection.getHeaderFieldKey(2)); } @Test void testGetHeaderFieldWithInt() { - assertEquals("19", urlConnection.getHeaderField(0)); - assertNotNull(urlConnection.getHeaderField(1)); - assertNull(urlConnection.getHeaderFieldKey(2)); + assertEquals("19", this.urlConnection.getHeaderField(0)); + assertNotNull(this.urlConnection.getHeaderField(1)); + assertNull(this.urlConnection.getHeaderFieldKey(2)); } @Test void testGetContent() throws IOException { - urlConnection.getContent(); + this.urlConnection.getContent(); } @Test void testGetContentWithClassArray() throws IOException { - urlConnection.getContent(new Class[0]); + this.urlConnection.getContent(new Class[0]); } @Test void testGetPermission() throws IOException { - assertNotNull(urlConnection.getPermission()); + assertNotNull(this.urlConnection.getPermission()); } @Test void testGetInputStream() throws Exception { String encoding = "UTF-8"; String data = "name = 测试名称"; - assertEquals(data, IOUtils.toString(urlConnection.getInputStream(), encoding)); + assertEquals(data, copyToString(this.urlConnection.getInputStream(), encoding)); } @Test - void testGetOutputStream() throws Exception { - assertThrows(Exception.class, urlConnection::getOutputStream); + void testGetOutputStream() throws IOException { + assertThrows(Exception.class, this.urlConnection::getOutputStream); + + attach(); + URL url = new URL(TEST_CONSOLE_URL); + URLConnection delegate = url.openConnection(); + this.urlConnection = new DelegatingURLConnection(delegate); + assertSame(out, this.urlConnection.getOutputStream()); } @Test void testToString() { - assertNotNull(urlConnection.toString()); + assertNotNull(this.urlConnection.toString()); } @Test void testSetDoInput() { - urlConnection.setDoInput(true); + this.urlConnection.setDoInput(true); } @Test void testGetDoInput() { testSetDoInput(); - assertTrue(urlConnection.getDoInput()); + assertTrue(this.urlConnection.getDoInput()); } @Test void testSetDoOutput() { - urlConnection.setDoOutput(true); + this.urlConnection.setDoOutput(true); } @Test void testGetDoOutput() { testSetDoOutput(); - assertTrue(urlConnection.getDoOutput()); + assertTrue(this.urlConnection.getDoOutput()); } @Test void testSetAllowUserInteraction() { - urlConnection.setAllowUserInteraction(true); + this.urlConnection.setAllowUserInteraction(true); } @Test void testGetAllowUserInteraction() { testSetAllowUserInteraction(); - assertTrue(urlConnection.getAllowUserInteraction()); + assertTrue(this.urlConnection.getAllowUserInteraction()); } @Test void testSetUseCaches() { - urlConnection.setUseCaches(true); + this.urlConnection.setUseCaches(true); } @Test void testGetUseCaches() { testSetUseCaches(); - assertTrue(urlConnection.getUseCaches()); + assertTrue(this.urlConnection.getUseCaches()); } @Test void testSetIfModifiedSince() { long now = currentTimeMillis(); - urlConnection.setIfModifiedSince(now); + this.urlConnection.setIfModifiedSince(now); } @Test void testGetIfModifiedSince() { testSetIfModifiedSince(); - assertTrue(currentTimeMillis() >= urlConnection.getIfModifiedSince()); + assertTrue(currentTimeMillis() >= this.urlConnection.getIfModifiedSince()); } @Test void testSetDefaultUseCaches() { - urlConnection.setDefaultUseCaches(true); + this.urlConnection.setDefaultUseCaches(true); } @Test void testGetDefaultUseCaches() { - urlConnection.setDefaultUseCaches(true); - assertTrue(urlConnection.getDefaultUseCaches()); + this.urlConnection.setDefaultUseCaches(true); + assertTrue(this.urlConnection.getDefaultUseCaches()); } @Test void testSetRequestProperty() { - urlConnection.setRequestProperty("key-1", "value-1"); + this.urlConnection.setRequestProperty("key-1", "value-1"); } @Test void testAddRequestProperty() { - urlConnection.addRequestProperty("key-1", "value-1-1"); - urlConnection.addRequestProperty("key-2", "value-2"); + this.urlConnection.addRequestProperty("key-1", "value-1-1"); + this.urlConnection.addRequestProperty("key-2", "value-2"); } @Test void testGetRequestProperty() { - assertNull(urlConnection.getRequestProperty("key-1")); + assertNull(this.urlConnection.getRequestProperty("key-1")); } @Test void testGetRequestProperties() { - Map> requestProperties = urlConnection.getRequestProperties(); + Map> requestProperties = this.urlConnection.getRequestProperties(); assertNotNull(requestProperties); } } diff --git a/microsphere-java-core/src/test/java/io/microsphere/reflect/ReflectionUtilsTest.java b/microsphere-java-core/src/test/java/io/microsphere/reflect/ReflectionUtilsTest.java index 9087a231b..6d8c42b7b 100644 --- a/microsphere-java-core/src/test/java/io/microsphere/reflect/ReflectionUtilsTest.java +++ b/microsphere-java-core/src/test/java/io/microsphere/reflect/ReflectionUtilsTest.java @@ -1,24 +1,33 @@ package io.microsphere.reflect; import io.microsphere.AbstractTestCase; +import io.microsphere.test.Data; import org.junit.jupiter.api.Test; import java.util.HashMap; import java.util.List; import java.util.Map; +import static io.microsphere.collection.Lists.ofList; +import static io.microsphere.reflect.ReflectionUtils.INACCESSIBLE_OBJECT_EXCEPTION_CLASS; +import static io.microsphere.reflect.ReflectionUtils.INACCESSIBLE_OBJECT_EXCEPTION_CLASS_NAME; import static io.microsphere.reflect.ReflectionUtils.getCallerClass; import static io.microsphere.reflect.ReflectionUtils.getCallerClassInGeneralJVM; import static io.microsphere.reflect.ReflectionUtils.getCallerClassInSunJVM; import static io.microsphere.reflect.ReflectionUtils.getCallerClassName; import static io.microsphere.reflect.ReflectionUtils.getCallerClassNameInGeneralJVM; import static io.microsphere.reflect.ReflectionUtils.getCallerClassNameInSunJVM; +import static io.microsphere.reflect.ReflectionUtils.isInaccessibleObjectException; import static io.microsphere.reflect.ReflectionUtils.isSupportedSunReflectReflection; import static io.microsphere.reflect.ReflectionUtils.readFieldsAsMap; import static io.microsphere.reflect.ReflectionUtils.toList; +import static io.microsphere.reflect.ReflectionUtils.toObject; +import static io.microsphere.util.ArrayUtils.ofArray; import static java.util.Arrays.asList; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; /** * {@link ReflectionUtils} Test @@ -30,7 +39,7 @@ class ReflectionUtilsTest extends AbstractTestCase { @Test - void testGetCallerClassX() throws Exception { + void testGetCallerClassX() { Class expectedClass = ReflectionUtilsTest.class; Class callerClass = getCallerClass(); @@ -90,5 +99,36 @@ void testReadFieldsAsMap() { value.put("c", "c"); map = readFieldsAsMap(value); assertFalse(map.isEmpty()); + + T t = new T(); + t.self = t; + t.other = new T(); + + map = readFieldsAsMap(t); + assertFalse(map.isEmpty()); + } + + @Test + void testToObject() { + assertNull(toObject(null)); + assertEquals("test", toObject("test")); + assertEquals(ofList("a", "b", "c"), toObject(ofArray("a", "b", "c"))); + } + + @Test + void testIsInaccessibleObjectException() { + assertFalse(isInaccessibleObjectException(new RuntimeException())); + assertFalse(isInaccessibleObjectException((Throwable) null)); + assertFalse(isInaccessibleObjectException((Class) null)); + assertFalse(isInaccessibleObjectException(Class.class)); + assertEquals(INACCESSIBLE_OBJECT_EXCEPTION_CLASS != null, isInaccessibleObjectException(INACCESSIBLE_OBJECT_EXCEPTION_CLASS)); + assertTrue(isInaccessibleObjectException(INACCESSIBLE_OBJECT_EXCEPTION_CLASS_NAME)); + } + + static class T extends Data { + + private T self; + + private T other; } } diff --git a/microsphere-java-core/src/test/java/io/microsphere/util/ThrowableUtilsTest.java b/microsphere-java-core/src/test/java/io/microsphere/util/ThrowableUtilsTest.java new file mode 100644 index 000000000..883f8e5e1 --- /dev/null +++ b/microsphere-java-core/src/test/java/io/microsphere/util/ThrowableUtilsTest.java @@ -0,0 +1,64 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 io.microsphere.util; + + +import io.microsphere.lang.function.ThrowableAction; +import org.junit.jupiter.api.Test; + +import static io.microsphere.lang.function.ThrowableAction.execute; +import static io.microsphere.util.ThrowableUtils.getRootCause; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertThrows; + +/** + * {@link ThrowableUtils} Test + * + * @author Mercy + * @see ThrowableUtils + * @since 1.0.0 + */ +class ThrowableUtilsTest { + + @Test + void testGetRootCause() { + Throwable rootCause = new Throwable("Root Cause"); + Throwable throwable = new Throwable("Throwable", rootCause); + assertSame(rootCause, getRootCause(throwable)); + + ThrowableAction action = () -> { + throw throwable; + }; + + execute(action, e -> { + assertSame(rootCause, getRootCause(e)); + }); + + assertThrows(NullPointerException.class, () -> { + try { + ThrowableAction a = () -> { + String s = null; + s.toString(); + }; + a.execute(); + } catch (Throwable e) { + throw getRootCause(e); + } + }); + } +} \ No newline at end of file diff --git a/microsphere-java-core/src/test/resources/junit-platform.properties b/microsphere-java-core/src/test/resources/junit-platform.properties index 1cebb76d5..993f2b029 100644 --- a/microsphere-java-core/src/test/resources/junit-platform.properties +++ b/microsphere-java-core/src/test/resources/junit-platform.properties @@ -1 +1,3 @@ -junit.jupiter.extensions.autodetection.enabled = true \ No newline at end of file +junit.jupiter.extensions.autodetection.enabled = true + +junit.jupiter.execution.parallel.enabled = true \ No newline at end of file diff --git a/microsphere-java-dependencies/pom.xml b/microsphere-java-dependencies/pom.xml index 1f36e1c37..aba268cdb 100644 --- a/microsphere-java-dependencies/pom.xml +++ b/microsphere-java-dependencies/pom.xml @@ -23,7 +23,7 @@ io.github.microsphere-projects - microsphere-annotation-processor + microsphere-java-annotations ${revision} @@ -33,6 +33,30 @@ ${revision}
    + + io.github.microsphere-projects + microsphere-jdk-tools + ${revision} + + + + io.github.microsphere-projects + microsphere-java-test + ${revision} + + + + io.github.microsphere-projects + microsphere-lang-model + ${revision} + + + + io.github.microsphere-projects + microsphere-annotation-processor + ${revision} + +
    diff --git a/microsphere-java-parent/pom.xml b/microsphere-java-parent/pom.xml index 5e554cb8b..8080f4b93 100644 --- a/microsphere-java-parent/pom.xml +++ b/microsphere-java-parent/pom.xml @@ -20,6 +20,8 @@ 1.3.2 + 2.1 + 2.3.1 3.0.2 1.3.2 7.0.3 @@ -27,10 +29,10 @@ 1.5.26 6.0.2 + 5.14.2 1.37 - @@ -42,6 +44,22 @@ ${javax.annotation-api.version} + + + javax.ws.rs + javax.ws.rs-api + ${javax.ws.rs.version} + true + + + + + javax.xml.ws + jaxws-api + ${jaxws-api.version} + true + + com.google.code.findbugs @@ -82,6 +100,14 @@ ${junit.version} + + + org.mockito + mockito-core + ${mockito.version} + + + org.openjdk.jmh jmh-core @@ -126,7 +152,8 @@ 5.3.39 - 5.13.4 + 5.14.2 + 4.11.0 diff --git a/microsphere-java-test/pom.xml b/microsphere-java-test/pom.xml new file mode 100644 index 000000000..40504c98e --- /dev/null +++ b/microsphere-java-test/pom.xml @@ -0,0 +1,94 @@ + + + + io.github.microsphere-projects + microsphere-java-parent + ${revision} + ../microsphere-java-parent/pom.xml + + 4.0.0 + + io.github.microsphere-projects + microsphere-java-test + ${revision} + jar + + Microsphere :: Java :: Test + Microsphere Java Test + + + + + + io.github.microsphere-projects + microsphere-java-core + ${revision} + + + + + io.github.microsphere-projects + microsphere-jdk-tools + ${revision} + true + + + + + org.junit.jupiter + junit-jupiter + true + + + + + org.mockito + mockito-core + true + + + + org.junit.jupiter + junit-jupiter-engine + true + + + + + ch.qos.logback + logback-classic + true + + + + + javax.ws.rs + javax.ws.rs-api + true + + + + + javax.xml.ws + jaxws-api + true + + + + + org.springframework + spring-context + true + + + + org.springframework + spring-web + true + + + + + \ No newline at end of file diff --git a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/TestAnnotation.java b/microsphere-java-test/src/main/java/io/microsphere/test/annotation/TestAnnotation.java similarity index 97% rename from microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/TestAnnotation.java rename to microsphere-java-test/src/main/java/io/microsphere/test/annotation/TestAnnotation.java index 4d35d6f82..5669e4936 100644 --- a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/TestAnnotation.java +++ b/microsphere-java-test/src/main/java/io/microsphere/test/annotation/TestAnnotation.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package io.microsphere.annotation.processor; +package io.microsphere.test.annotation; import io.microsphere.annotation.ConfigurationProperty; import io.microsphere.annotation.Since; @@ -70,4 +70,4 @@ ConfigurationProperty[] properties() default {}; -} +} \ No newline at end of file diff --git a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/AbstractAnnotationProcessingTest.java b/microsphere-java-test/src/main/java/io/microsphere/test/annotation/processing/AbstractAnnotationProcessingTest.java similarity index 61% rename from microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/AbstractAnnotationProcessingTest.java rename to microsphere-java-test/src/main/java/io/microsphere/test/annotation/processing/AbstractAnnotationProcessingTest.java index ce674e512..57f4a8daf 100644 --- a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/AbstractAnnotationProcessingTest.java +++ b/microsphere-java-test/src/main/java/io/microsphere/test/annotation/processing/AbstractAnnotationProcessingTest.java @@ -14,12 +14,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.microsphere.annotation.processor; +package io.microsphere.test.annotation.processing; -import io.microsphere.annotation.processor.util.TypeUtils; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; +import io.microsphere.annotation.Nullable; import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.api.extension.ReflectiveInvocationContext; import javax.annotation.processing.ProcessingEnvironment; import javax.annotation.processing.RoundEnvironment; @@ -36,19 +36,13 @@ import javax.lang.model.util.Elements; import javax.lang.model.util.Types; import java.lang.annotation.Annotation; +import java.lang.reflect.Method; import java.lang.reflect.Type; import java.util.Collection; import java.util.List; import java.util.Set; import java.util.function.Predicate; -import static io.microsphere.annotation.processor.util.ConstructorUtils.findConstructor; -import static io.microsphere.annotation.processor.util.FieldUtils.findField; -import static io.microsphere.annotation.processor.util.MethodUtils.findMethod; -import static io.microsphere.annotation.processor.util.TypeUtils.ofDeclaredType; -import static java.util.Collections.emptyList; -import static org.junit.jupiter.api.Assertions.assertSame; - /** * Abstract {@link Annotation} Processing Test case * @@ -112,8 +106,6 @@ public abstract class AbstractAnnotationProcessingTest { protected static final AnnotationMirror NULL_ANNOTATION_MIRROR = null; - static ThreadLocal testInstanceHolder = new ThreadLocal<>(); - protected RoundEnvironment roundEnv; protected ProcessingEnvironment processingEnv; @@ -132,71 +124,40 @@ public abstract class AbstractAnnotationProcessingTest { protected DeclaredType testDeclaredType; - @BeforeEach - final void setUp() { - testInstanceHolder.set(this); - } - - @AfterEach - final void tearDown() { - testInstanceHolder.remove(); - } - + /** + * The classes to be compiled. + * + * @param compiledClasses the mutable {@link Set} for classes to be compiled + */ protected void addCompiledClasses(Set> compiledClasses) { } - protected void beforeTest() { - this.testClass = TestServiceImpl.class; - this.testClassName = TestServiceImpl.class.getName(); - this.testTypeElement = getTypeElement(testClass); + protected void initTestClass(Class testClass) { + this.testClass = testClass; + this.testClassName = testClass.getName(); + this.testTypeElement = this.elements.getTypeElement(this.testClassName); this.testTypeMirror = this.testTypeElement.asType(); - this.testDeclaredType = ofDeclaredType(this.testTypeElement); + this.testDeclaredType = (DeclaredType) this.testTypeMirror; } - protected void afterTest() { + /** + * Before Test + * + * @param invocationContext {@link ReflectiveInvocationContext} + * @param extensionContext {@link ExtensionContext} + */ + protected void beforeTest(ReflectiveInvocationContext invocationContext, ExtensionContext extensionContext) { } - protected List getTypeMirrors(Type... types) { - return TypeUtils.getTypeMirrors(processingEnv, types); + /** + * After Test + * + * @param invocationContext {@link ReflectiveInvocationContext} + * @param extensionContext {@link ExtensionContext} + * @param result the result after test method returning + * @param failure the failure after the test methods' execution + */ + protected void afterTest(ReflectiveInvocationContext invocationContext, ExtensionContext extensionContext, + @Nullable Object result, @Nullable Throwable failure) { } - - protected TypeMirror getTypeMirror(Type type) { - return TypeUtils.getTypeMirror(processingEnv, type); - } - - protected List getTypeElements(Type... types) { - return TypeUtils.getTypeElements(processingEnv, types); - } - - protected TypeElement getTypeElement(Type type) { - return TypeUtils.getTypeElement(processingEnv, type); - } - - protected VariableElement getField(Type type, String fieldName) { - TypeElement typeElement = getTypeElement(type); - return findField(typeElement, fieldName); - } - - protected ExecutableElement getMethod(Type type, String methodName, Type... parameterTypes) { - TypeElement typeElement = getTypeElement(type); - return findMethod(typeElement, methodName, parameterTypes); - } - - protected ExecutableElement getConstructor(Type type, Type... parameterTypes) { - TypeElement typeElement = getTypeElement(type); - return findConstructor(typeElement, parameterTypes); - } - - protected Element[] getElements(Type... types) { - return getTypeMirrors(types).stream().map(TypeUtils::ofTypeElement).toArray(Element[]::new); - } - - protected DeclaredType getDeclaredType(Type type) { - return TypeUtils.getDeclaredType(processingEnv, type); - } - - protected void assertEmptyList(List list) { - assertSame(emptyList(), list); - } - -} +} \ No newline at end of file diff --git a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/AnnotationProcessingTestProcessor.java b/microsphere-java-test/src/main/java/io/microsphere/test/annotation/processing/AnnotationProcessingTestProcessor.java similarity index 55% rename from microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/AnnotationProcessingTestProcessor.java rename to microsphere-java-test/src/main/java/io/microsphere/test/annotation/processing/AnnotationProcessingTestProcessor.java index 68e28ccd0..3192d0140 100644 --- a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/AnnotationProcessingTestProcessor.java +++ b/microsphere-java-test/src/main/java/io/microsphere/test/annotation/processing/AnnotationProcessingTestProcessor.java @@ -14,21 +14,26 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.microsphere.annotation.processor; +package io.microsphere.test.annotation.processing; import org.junit.jupiter.api.extension.ExtensionContext; -import org.junit.jupiter.api.extension.InvocationInterceptor; +import org.junit.jupiter.api.extension.InvocationInterceptor.Invocation; import org.junit.jupiter.api.extension.ReflectiveInvocationContext; import javax.annotation.processing.AbstractProcessor; +import javax.annotation.processing.ProcessingEnvironment; import javax.annotation.processing.RoundEnvironment; import javax.annotation.processing.SupportedAnnotationTypes; import javax.lang.model.SourceVersion; import javax.lang.model.element.TypeElement; +import javax.lang.model.util.Elements; +import javax.lang.model.util.Types; import java.lang.reflect.Method; import java.util.Set; import static io.microsphere.constants.SymbolConstants.WILDCARD; +import static io.microsphere.util.ExceptionUtils.wrap; +import static io.microsphere.util.ThrowableUtils.getRootCause; import static javax.lang.model.SourceVersion.latestSupported; /** @@ -38,18 +43,19 @@ * @since 1.0.0 */ @SupportedAnnotationTypes(WILDCARD) -public class AnnotationProcessingTestProcessor extends AbstractProcessor { +class AnnotationProcessingTestProcessor extends AbstractProcessor { private final AbstractAnnotationProcessingTest abstractAnnotationProcessingTest; - private final InvocationInterceptor.Invocation invocation; + + private final Invocation invocation; private final ReflectiveInvocationContext invocationContext; private final ExtensionContext extensionContext; - public AnnotationProcessingTestProcessor(AbstractAnnotationProcessingTest abstractAnnotationProcessingTest, InvocationInterceptor.Invocation invocation, - ReflectiveInvocationContext invocationContext, - ExtensionContext extensionContext) { + AnnotationProcessingTestProcessor(AbstractAnnotationProcessingTest abstractAnnotationProcessingTest, Invocation invocation, + ReflectiveInvocationContext invocationContext, + ExtensionContext extensionContext) { this.abstractAnnotationProcessingTest = abstractAnnotationProcessingTest; this.invocation = invocation; this.invocationContext = invocationContext; @@ -58,25 +64,39 @@ public AnnotationProcessingTestProcessor(AbstractAnnotationProcessingTest abstra @Override public boolean process(Set annotations, RoundEnvironment roundEnv) { + ReflectiveInvocationContext invocationContext = this.invocationContext; + ExtensionContext extensionContext = this.extensionContext; if (!roundEnv.processingOver()) { prepare(roundEnv); - abstractAnnotationProcessingTest.beforeTest(); + Object result = null; + Throwable failure = null; + abstractAnnotationProcessingTest.beforeTest(invocationContext, extensionContext); try { - invocation.proceed(); + result = invocation.proceed(); } catch (Throwable throwable) { - throw new RuntimeException(throwable); + failure = throwable; } finally { - abstractAnnotationProcessingTest.afterTest(); + abstractAnnotationProcessingTest.afterTest(invocationContext, extensionContext, result, failure); + } + if (failure != null) { + Throwable cause = getRootCause(failure); + throw wrap(cause, Error.class); } } return false; } - protected void prepare(RoundEnvironment roundEnv) { + void prepare(RoundEnvironment roundEnv) { + ProcessingEnvironment processingEnv = super.processingEnv; + Elements elements = processingEnv.getElementUtils(); + Types types = processingEnv.getTypeUtils(); + Class testClass = this.invocationContext.getTargetClass(); + abstractAnnotationProcessingTest.roundEnv = roundEnv; - abstractAnnotationProcessingTest.processingEnv = super.processingEnv; - abstractAnnotationProcessingTest.elements = super.processingEnv.getElementUtils(); - abstractAnnotationProcessingTest.types = super.processingEnv.getTypeUtils(); + abstractAnnotationProcessingTest.processingEnv = processingEnv; + abstractAnnotationProcessingTest.elements = elements; + abstractAnnotationProcessingTest.types = types; + abstractAnnotationProcessingTest.initTestClass(testClass); } @Override diff --git a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/CompilerInvocationInterceptor.java b/microsphere-java-test/src/main/java/io/microsphere/test/annotation/processing/CompilerInvocationInterceptor.java similarity index 56% rename from microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/CompilerInvocationInterceptor.java rename to microsphere-java-test/src/main/java/io/microsphere/test/annotation/processing/CompilerInvocationInterceptor.java index 966e6defa..c45776142 100644 --- a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/CompilerInvocationInterceptor.java +++ b/microsphere-java-test/src/main/java/io/microsphere/test/annotation/processing/CompilerInvocationInterceptor.java @@ -14,8 +14,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.microsphere.annotation.processor; +package io.microsphere.test.annotation.processing; +import io.microsphere.jdk.tools.compiler.Compiler; import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.api.extension.InvocationInterceptor; import org.junit.jupiter.api.extension.ReflectiveInvocationContext; @@ -25,10 +26,11 @@ import java.util.LinkedHashSet; import java.util.LinkedList; import java.util.List; +import java.util.ServiceLoader; import java.util.Set; -import static io.microsphere.annotation.processor.AbstractAnnotationProcessingTest.testInstanceHolder; -import static io.microsphere.util.ServiceLoaderUtils.loadServicesList; +import static io.microsphere.util.ArrayUtils.EMPTY_CLASS_ARRAY; +import static java.util.ServiceLoader.load; /** @@ -37,21 +39,29 @@ * @author Mercy * @since 1.0.0 */ -public class CompilerInvocationInterceptor implements InvocationInterceptor { +class CompilerInvocationInterceptor implements InvocationInterceptor { @Override - public void interceptTestMethod(Invocation invocation, - ReflectiveInvocationContext invocationContext, + public void interceptTestMethod(Invocation invocation, ReflectiveInvocationContext invocationContext, ExtensionContext extensionContext) throws Throwable { - Set> compiledClasses = new LinkedHashSet<>(); - AbstractAnnotationProcessingTest abstractAnnotationProcessingTest = testInstanceHolder.get(); - compiledClasses.add(getClass()); - abstractAnnotationProcessingTest.addCompiledClasses(compiledClasses); + Set> compiledClassesSet = new LinkedHashSet<>(); + AbstractAnnotationProcessingTest test = (AbstractAnnotationProcessingTest) invocationContext.getTarget().get(); + Class testClass = extensionContext.getTestClass().get(); + ClassLoader classLoader = testClass.getClassLoader(); + compiledClassesSet.add(testClass); + test.addCompiledClasses(compiledClassesSet); + + Class[] compiledClasses = compiledClassesSet.toArray(EMPTY_CLASS_ARRAY); + Compiler compiler = new Compiler(); compiler.sourcePaths(compiledClasses); - List processors = new LinkedList<>(loadServicesList(Processor.class, this.getClass().getClassLoader())); - processors.add(new AnnotationProcessingTestProcessor(abstractAnnotationProcessingTest, invocation, invocationContext, extensionContext)); + + List processors = new LinkedList<>(); + processors.add(new AnnotationProcessingTestProcessor(test, invocation, invocationContext, extensionContext)); + // Loads the SPI instances of Processor + ServiceLoader loadedProcessors = load(Processor.class, classLoader); + loadedProcessors.forEach(processors::add); compiler.processors(processors.toArray(new Processor[0])); - compiler.compile(compiledClasses.toArray(new Class[0])); + compiler.compile(compiledClasses); } -} +} \ No newline at end of file diff --git a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/model/Ancestor.java b/microsphere-java-test/src/main/java/io/microsphere/test/model/Ancestor.java similarity index 90% rename from microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/model/Ancestor.java rename to microsphere-java-test/src/main/java/io/microsphere/test/model/Ancestor.java index 9a749d056..cf0e07f70 100644 --- a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/model/Ancestor.java +++ b/microsphere-java-test/src/main/java/io/microsphere/test/model/Ancestor.java @@ -14,12 +14,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.microsphere.annotation.processor.model; +package io.microsphere.test.model; import java.io.Serializable; /** * Ancestor + * + * @author Mercy + * @since 1.0.0 */ public class Ancestor implements Serializable { @@ -32,4 +35,4 @@ public boolean isZ() { public void setZ(boolean z) { this.z = z; } -} +} \ No newline at end of file diff --git a/microsphere-java-test/src/main/java/io/microsphere/test/model/ArrayTypeModel.java b/microsphere-java-test/src/main/java/io/microsphere/test/model/ArrayTypeModel.java new file mode 100644 index 000000000..d9588781e --- /dev/null +++ b/microsphere-java-test/src/main/java/io/microsphere/test/model/ArrayTypeModel.java @@ -0,0 +1,76 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 io.microsphere.test.model; + +/** + * Array Type Model + * + * @author Mercy + * @since 1.0.0 + */ +public class ArrayTypeModel { + + private int[] integers; // Primitive type array + + private String[] strings; // Simple type array + + private PrimitiveTypeModel[] primitiveTypeModels; // Complex type array + + private Model[] models; // Hierarchical Complex type array + + private Color[] colors; // Enum type array + + public int[] getIntegers() { + return integers; + } + + public void setIntegers(int[] integers) { + this.integers = integers; + } + + public String[] getStrings() { + return strings; + } + + public void setStrings(String[] strings) { + this.strings = strings; + } + + public PrimitiveTypeModel[] getPrimitiveTypeModels() { + return primitiveTypeModels; + } + + public void setPrimitiveTypeModels(PrimitiveTypeModel[] primitiveTypeModels) { + this.primitiveTypeModels = primitiveTypeModels; + } + + public Model[] getModels() { + return models; + } + + public void setModels(Model[] models) { + this.models = models; + } + + public Color[] getColors() { + return colors; + } + + public void setColors(Color[] colors) { + this.colors = colors; + } +} \ No newline at end of file diff --git a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/model/CollectionTypeModel.java b/microsphere-java-test/src/main/java/io/microsphere/test/model/CollectionTypeModel.java similarity index 58% rename from microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/model/CollectionTypeModel.java rename to microsphere-java-test/src/main/java/io/microsphere/test/model/CollectionTypeModel.java index 3f5426361..414d65451 100644 --- a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/model/CollectionTypeModel.java +++ b/microsphere-java-test/src/main/java/io/microsphere/test/model/CollectionTypeModel.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.microsphere.annotation.processor.model; +package io.microsphere.test.model; import java.util.Collection; import java.util.Deque; @@ -25,6 +25,7 @@ /** * {@link Collection} Type Model * + * @author Mercy * @since 1.0.0 */ public class CollectionTypeModel { @@ -39,4 +40,43 @@ public class CollectionTypeModel { private Set modelArrays; // The composite element is hierarchical POJO type -} + public Collection getStrings() { + return strings; + } + + public void setStrings(Collection strings) { + this.strings = strings; + } + + public List getColors() { + return colors; + } + + public void setColors(List colors) { + this.colors = colors; + } + + public Queue getPrimitiveTypeModels() { + return primitiveTypeModels; + } + + public void setPrimitiveTypeModels(Queue primitiveTypeModels) { + this.primitiveTypeModels = primitiveTypeModels; + } + + public Deque getModels() { + return models; + } + + public void setModels(Deque models) { + this.models = models; + } + + public Set getModelArrays() { + return modelArrays; + } + + public void setModelArrays(Set modelArrays) { + this.modelArrays = modelArrays; + } +} \ No newline at end of file diff --git a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/model/Color.java b/microsphere-java-test/src/main/java/io/microsphere/test/model/Color.java similarity index 92% rename from microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/model/Color.java rename to microsphere-java-test/src/main/java/io/microsphere/test/model/Color.java index 177dfaffc..f362a8376 100644 --- a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/model/Color.java +++ b/microsphere-java-test/src/main/java/io/microsphere/test/model/Color.java @@ -14,11 +14,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.microsphere.annotation.processor.model; +package io.microsphere.test.model; /** * Color enumeration * + * @author Mercy * @since 1.0.0 */ public enum Color { @@ -43,4 +44,4 @@ public String toString() { public int getValue() { return value; } -} +} \ No newline at end of file diff --git a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/model/ConfigurationPropertyModel.java b/microsphere-java-test/src/main/java/io/microsphere/test/model/ConfigurationPropertyModel.java similarity index 67% rename from microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/model/ConfigurationPropertyModel.java rename to microsphere-java-test/src/main/java/io/microsphere/test/model/ConfigurationPropertyModel.java index 9a6505460..a8e206bd0 100644 --- a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/model/ConfigurationPropertyModel.java +++ b/microsphere-java-test/src/main/java/io/microsphere/test/model/ConfigurationPropertyModel.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package io.microsphere.annotation.processor.model; +package io.microsphere.test.model; import io.microsphere.annotation.ConfigurationProperty; @@ -43,5 +43,43 @@ public class ConfigurationPropertyModel { @ConfigurationProperty(name = "microsphere.annotation.processor.model.description") private String description; + public String getName() { + return name; + } -} + public void setName(String name) { + this.name = name; + } + + public Class getType() { + return type; + } + + public void setType(Class type) { + this.type = type; + } + + public String getDefaultValue() { + return defaultValue; + } + + public void setDefaultValue(String defaultValue) { + this.defaultValue = defaultValue; + } + + public boolean isRequired() { + return required; + } + + public void setRequired(boolean required) { + this.required = required; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } +} \ No newline at end of file diff --git a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/model/MapTypeModel.java b/microsphere-java-test/src/main/java/io/microsphere/test/model/MapTypeModel.java similarity index 57% rename from microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/model/MapTypeModel.java rename to microsphere-java-test/src/main/java/io/microsphere/test/model/MapTypeModel.java index 3c9fc58c4..bf051c5b9 100644 --- a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/model/MapTypeModel.java +++ b/microsphere-java-test/src/main/java/io/microsphere/test/model/MapTypeModel.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.microsphere.annotation.processor.model; +package io.microsphere.test.model; import java.util.HashMap; import java.util.Map; @@ -25,6 +25,7 @@ /** * {@link Map} Type model * + * @author Mercy * @since 1.0.0 */ public class MapTypeModel { @@ -38,4 +39,44 @@ public class MapTypeModel { private HashMap models; // The composite element is hierarchical POJO type private TreeMap modelArrays; // The composite element is hierarchical POJO type -} + + public Map getStrings() { + return strings; + } + + public void setStrings(Map strings) { + this.strings = strings; + } + + public SortedMap getColors() { + return colors; + } + + public void setColors(SortedMap colors) { + this.colors = colors; + } + + public NavigableMap getPrimitiveTypeModels() { + return primitiveTypeModels; + } + + public void setPrimitiveTypeModels(NavigableMap primitiveTypeModels) { + this.primitiveTypeModels = primitiveTypeModels; + } + + public HashMap getModels() { + return models; + } + + public void setModels(HashMap models) { + this.models = models; + } + + public TreeMap getModelArrays() { + return modelArrays; + } + + public void setModelArrays(TreeMap modelArrays) { + this.modelArrays = modelArrays; + } +} \ No newline at end of file diff --git a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/model/Model.java b/microsphere-java-test/src/main/java/io/microsphere/test/model/Model.java similarity index 94% rename from microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/model/Model.java rename to microsphere-java-test/src/main/java/io/microsphere/test/model/Model.java index 08348e513..5d972f3c9 100644 --- a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/model/Model.java +++ b/microsphere-java-test/src/main/java/io/microsphere/test/model/Model.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.microsphere.annotation.processor.model; +package io.microsphere.test.model; import java.math.BigDecimal; import java.math.BigInteger; @@ -22,6 +22,9 @@ /** * Model Object + * + * @author Mercy + * @since 1.0.0 */ public class Model extends Parent { @@ -84,4 +87,4 @@ public BigDecimal getBd() { public void setBd(BigDecimal bd) { this.bd = bd; } -} +} \ No newline at end of file diff --git a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/model/Parent.java b/microsphere-java-test/src/main/java/io/microsphere/test/model/Parent.java similarity index 92% rename from microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/model/Parent.java rename to microsphere-java-test/src/main/java/io/microsphere/test/model/Parent.java index b124fb814..f5e85fe1e 100644 --- a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/model/Parent.java +++ b/microsphere-java-test/src/main/java/io/microsphere/test/model/Parent.java @@ -14,10 +14,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.microsphere.annotation.processor.model; +package io.microsphere.test.model; /** * Parent + * + * @author Mercy + * @since 1.0.0 */ public class Parent extends Ancestor { @@ -60,4 +63,4 @@ public long getL() { public void setL(long l) { this.l = l; } -} +} \ No newline at end of file diff --git a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/model/PrimitiveTypeModel.java b/microsphere-java-test/src/main/java/io/microsphere/test/model/PrimitiveTypeModel.java similarity index 93% rename from microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/model/PrimitiveTypeModel.java rename to microsphere-java-test/src/main/java/io/microsphere/test/model/PrimitiveTypeModel.java index 2bbe5372b..5a1065fc7 100644 --- a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/model/PrimitiveTypeModel.java +++ b/microsphere-java-test/src/main/java/io/microsphere/test/model/PrimitiveTypeModel.java @@ -14,11 +14,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.microsphere.annotation.processor.model; +package io.microsphere.test.model; /** * Primitive Type model * + * @author Mercy * @since 1.0.0 */ public class PrimitiveTypeModel { @@ -70,4 +71,4 @@ public float getF() { public double getD() { return d; } -} +} \ No newline at end of file diff --git a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/model/SimpleTypeModel.java b/microsphere-java-test/src/main/java/io/microsphere/test/model/SimpleTypeModel.java similarity index 96% rename from microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/model/SimpleTypeModel.java rename to microsphere-java-test/src/main/java/io/microsphere/test/model/SimpleTypeModel.java index 4522d5554..86a8b6b8b 100644 --- a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/model/SimpleTypeModel.java +++ b/microsphere-java-test/src/main/java/io/microsphere/test/model/SimpleTypeModel.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.microsphere.annotation.processor.model; +package io.microsphere.test.model; import java.math.BigDecimal; import java.math.BigInteger; @@ -23,6 +23,7 @@ /** * Simple Type model * + * @author Mercy * @since 1.0.0 */ public class SimpleTypeModel { @@ -158,4 +159,4 @@ public Date getDt() { public void setDt(Date dt) { this.dt = dt; } -} +} \ No newline at end of file diff --git a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/model/StringArrayList.java b/microsphere-java-test/src/main/java/io/microsphere/test/model/StringArrayList.java similarity index 95% rename from microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/model/StringArrayList.java rename to microsphere-java-test/src/main/java/io/microsphere/test/model/StringArrayList.java index f59710d58..e7c115a09 100644 --- a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/model/StringArrayList.java +++ b/microsphere-java-test/src/main/java/io/microsphere/test/model/StringArrayList.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package io.microsphere.annotation.processor.model; +package io.microsphere.test.model; import java.util.ArrayList; @@ -27,4 +27,4 @@ * @since 1.0.0 */ public class StringArrayList extends ArrayList { -} +} \ No newline at end of file diff --git a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/DefaultTestService.java b/microsphere-java-test/src/main/java/io/microsphere/test/service/DefaultTestService.java similarity index 93% rename from microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/DefaultTestService.java rename to microsphere-java-test/src/main/java/io/microsphere/test/service/DefaultTestService.java index 7e643daab..4ca1d694b 100644 --- a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/DefaultTestService.java +++ b/microsphere-java-test/src/main/java/io/microsphere/test/service/DefaultTestService.java @@ -14,10 +14,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.microsphere.annotation.processor; +package io.microsphere.test.service; -import io.microsphere.annotation.processor.model.Model; +import io.microsphere.test.model.Model; import java.util.concurrent.TimeUnit; diff --git a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/GenericTestService.java b/microsphere-java-test/src/main/java/io/microsphere/test/service/GenericTestService.java similarity index 96% rename from microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/GenericTestService.java rename to microsphere-java-test/src/main/java/io/microsphere/test/service/GenericTestService.java index 449b73611..d4a81a787 100644 --- a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/GenericTestService.java +++ b/microsphere-java-test/src/main/java/io/microsphere/test/service/GenericTestService.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.microsphere.annotation.processor; +package io.microsphere.test.service; import java.util.EventListener; @@ -30,4 +30,4 @@ public class GenericTestService extends DefaultTestService implements TestServic public String echo(String message) { return "[ECHO] " + message; } -} +} \ No newline at end of file diff --git a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/TestService.java b/microsphere-java-test/src/main/java/io/microsphere/test/service/TestService.java similarity index 93% rename from microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/TestService.java rename to microsphere-java-test/src/main/java/io/microsphere/test/service/TestService.java index 860748c13..22839bc80 100644 --- a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/TestService.java +++ b/microsphere-java-test/src/main/java/io/microsphere/test/service/TestService.java @@ -14,9 +14,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.microsphere.annotation.processor; +package io.microsphere.test.service; -import io.microsphere.annotation.processor.model.Model; + +import io.microsphere.test.model.Model; import javax.ws.rs.DefaultValue; import javax.ws.rs.GET; diff --git a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/TestServiceImpl.java b/microsphere-java-test/src/main/java/io/microsphere/test/service/TestServiceImpl.java similarity index 95% rename from microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/TestServiceImpl.java rename to microsphere-java-test/src/main/java/io/microsphere/test/service/TestServiceImpl.java index e587e888e..27a53b2d3 100644 --- a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/TestServiceImpl.java +++ b/microsphere-java-test/src/main/java/io/microsphere/test/service/TestServiceImpl.java @@ -14,10 +14,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.microsphere.annotation.processor; +package io.microsphere.test.service; import io.microsphere.annotation.ConfigurationProperty; import io.microsphere.annotation.Since; +import io.microsphere.test.annotation.TestAnnotation; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.Cacheable; import org.springframework.context.ApplicationContext; @@ -76,9 +77,9 @@ public class TestServiceImpl extends GenericTestService implements TestService, AutoCloseable, Serializable { @Autowired - private ApplicationContext context; + protected ApplicationContext context; - private Environment environment; + protected Environment environment; public TestServiceImpl() { this(null); diff --git a/microsphere-java-test/src/main/resources/junit-platform.properties b/microsphere-java-test/src/main/resources/junit-platform.properties new file mode 100644 index 000000000..1e4594242 --- /dev/null +++ b/microsphere-java-test/src/main/resources/junit-platform.properties @@ -0,0 +1,5 @@ +junit.jupiter.extensions.autodetection.enabled = true + +junit.jupiter.execution.parallel.enabled = true +junit.jupiter.execution.parallel.mode.default = concurrent +junit.jupiter.execution.parallel.mode.classes.default = concurrent \ No newline at end of file diff --git a/microsphere-java-test/src/main/resources/logback-test.xml b/microsphere-java-test/src/main/resources/logback-test.xml new file mode 100644 index 000000000..e3375b74c --- /dev/null +++ b/microsphere-java-test/src/main/resources/logback-test.xml @@ -0,0 +1,15 @@ + + + + + + + ${ENCODER_PATTERN} + + + + + + + + \ No newline at end of file diff --git a/microsphere-java-test/src/test/java/io/microsphere/test/annotation/processing/AnnotationProcessingTest.java b/microsphere-java-test/src/test/java/io/microsphere/test/annotation/processing/AnnotationProcessingTest.java new file mode 100644 index 000000000..9b40f9b77 --- /dev/null +++ b/microsphere-java-test/src/test/java/io/microsphere/test/annotation/processing/AnnotationProcessingTest.java @@ -0,0 +1,99 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 io.microsphere.test.annotation.processing; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.api.extension.ReflectiveInvocationContext; +import org.junit.jupiter.api.extension.TestExecutionExceptionHandler; + +import javax.lang.model.element.Element; +import javax.lang.model.type.TypeMirror; +import java.lang.reflect.Method; +import java.lang.reflect.Type; +import java.util.Collection; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; + +/** + * {@link AbstractAnnotationProcessingTest} Test + * + * @author Mercy + * @see AbstractAnnotationProcessingTest + * @since 1.0.0 + */ +public class AnnotationProcessingTest extends AbstractAnnotationProcessingTest implements TestExecutionExceptionHandler { + + @Test + void test() { + assertNull(NULL_TYPE_MIRROR); + assertArrayEquals(new TypeMirror[0], EMPTY_TYPE_MIRROR_ARRAY); + assertNull(NULL_TYPE_MIRROR_ARRAY); + assertArrayEquals(new Collection[0], EMPTY_COLLECTION_ARRAY); + assertNull(NULL_COLLECTION); + assertNull(NULL_LIST); + assertNull(NULL_ELEMENT); + assertNull(NULL_ELEMENT_KIND); + assertArrayEquals(new Element[0], EMPTY_ELEMENT_ARRAY); + assertNull(NULL_ELEMENT_ARRAY); + assertNull(NULL_TYPE_ELEMENT); + assertNull(NULL_TYPE_ARRAY); + assertArrayEquals(new Type[0], EMPTY_TYPE_ARRAY); + assertNull(NULL_TYPE); + assertNull(NULL_PROCESSING_ENVIRONMENT); + assertNull(NULL_STRING); + assertNull(NULL_STRING_ARRAY); + assertNull(NULL_CLASS); + assertNull(NULL_CLASS_ARRAY); + assertNull(NULL_ANNOTATED_CONSTRUCT); + assertNull(NULL_PREDICATE_ARRAY); + assertNull(NULL_FIELD); + assertNull(NULL_MODIFIER); + assertNull(NULL_MODIFIER_ARRAY); + assertNull(NULL_METHOD); + assertNull(NULL_METHOD_ARRAY); + assertNull(NULL_ANNOTATION_MIRROR); + } + + @Test + @ExtendWith(AnnotationProcessingTest.class) + void testOnFailure() { + throw new RuntimeException("For testing"); + } + + @Override + protected void afterTest(ReflectiveInvocationContext invocationContext, ExtensionContext extensionContext, Object result, Throwable failure) { + super.afterTest(invocationContext, extensionContext, result, failure); + if (failure != null) { + assertEquals("For testing", failure.getMessage()); + } + } + + @Override + public void handleTestExecutionException(ExtensionContext context, Throwable throwable) throws Throwable { + if (throwable != null) { + Method method = context.getTestMethod().get(); + if ("testOnFailure".equals(method.getName())) { + // ingnore + } + } + } +} \ No newline at end of file diff --git a/microsphere-java-test/src/test/java/io/microsphere/test/model/AncestorTest.java b/microsphere-java-test/src/test/java/io/microsphere/test/model/AncestorTest.java new file mode 100644 index 000000000..b96c57b36 --- /dev/null +++ b/microsphere-java-test/src/test/java/io/microsphere/test/model/AncestorTest.java @@ -0,0 +1,81 @@ +package io.microsphere.test.model; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * Unit tests for the Ancestor class + */ +class AncestorTest { + + private Ancestor ancestor; + + @BeforeEach + void setUp() { + ancestor = new Ancestor(); + } + + @Test + void testDefaultConstructor() { + // Verify that the default value of z is false + assertFalse(ancestor.isZ(), "Default value of z should be false"); + } + + @Test + void testSetZTrue() { + // Set z to true and verify + ancestor.setZ(true); + assertTrue(ancestor.isZ(), "Value of z should be true after setting it to true"); + } + + @Test + void testSetZFalse() { + // Explicitly set z to false and verify + ancestor.setZ(false); + assertFalse(ancestor.isZ(), "Value of z should be false after setting it to false"); + } + + @Test + void testSetZToggle() { + // Test toggling the value from default false to true and back to false + assertFalse(ancestor.isZ(), "Initial value should be false"); + + ancestor.setZ(true); + assertTrue(ancestor.isZ(), "Value should be true after first toggle"); + + ancestor.setZ(false); + assertFalse(ancestor.isZ(), "Value should be false after second toggle"); + } + + @Test + void testMultipleInstanceIndependence() { + // Create two instances and verify they maintain independent state + Ancestor ancestor1 = new Ancestor(); + Ancestor ancestor2 = new Ancestor(); + + // Initially both should have false + assertFalse(ancestor1.isZ(), "First instance should initially be false"); + assertFalse(ancestor2.isZ(), "Second instance should initially be false"); + + // Modify only the first instance + ancestor1.setZ(true); + + // Verify that only the first instance changed + assertTrue(ancestor1.isZ(), "First instance should be true after modification"); + assertFalse(ancestor2.isZ(), "Second instance should remain false"); + } + + @Test + void testSerializableImplementation() { + // Test that the class can be instantiated and used as a Serializable object + // This test verifies basic functionality without actual serialization + ancestor.setZ(true); + assertTrue(ancestor.isZ(), "Should properly handle boolean value when used as Serializable"); + + ancestor.setZ(false); + assertFalse(ancestor.isZ(), "Should properly handle boolean value when used as Serializable"); + } +} diff --git a/microsphere-java-test/src/test/java/io/microsphere/test/model/ArrayTypeModelTest.java b/microsphere-java-test/src/test/java/io/microsphere/test/model/ArrayTypeModelTest.java new file mode 100644 index 000000000..ebf9644af --- /dev/null +++ b/microsphere-java-test/src/test/java/io/microsphere/test/model/ArrayTypeModelTest.java @@ -0,0 +1,122 @@ +package io.microsphere.test.model; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static io.microsphere.test.model.Color.BLUE; +import static io.microsphere.test.model.Color.RED; +import static io.microsphere.test.model.Color.YELLOW; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertSame; + +/** + * Unit tests for the ArrayTypeModel class + */ +class ArrayTypeModelTest { + + private ArrayTypeModel model; + + @BeforeEach + void setUp() { + model = new ArrayTypeModel(); + } + + @Test + void testDefaultValues() { + // Verify all array fields are null by default + assertNull(model.getIntegers(), "integers array should be null by default"); + assertNull(model.getStrings(), "strings array should be null by default"); + assertNull(model.getPrimitiveTypeModels(), "primitiveTypeModels array should be null by default"); + assertNull(model.getModels(), "models array should be null by default"); + assertNull(model.getColors(), "colors array should be null by default"); + } + + @Test + void testSetGetIntegers() { + int[] testArray = {1, 2, 3, 4, 5}; + + model.setIntegers(testArray); + assertSame(testArray, model.getIntegers(), "Should return the same array reference that was set"); + + // Verify the contents match + assertArrayEquals(testArray, model.getIntegers(), "Array contents should match the set value"); + } + + @Test + void testSetGetStrings() { + String[] testArray = {"hello", "world", "test"}; + + model.setStrings(testArray); + assertSame(testArray, model.getStrings(), "Should return the same array reference that was set"); + + // Verify the contents match + assertArrayEquals(testArray, model.getStrings(), "Array contents should match the set value"); + } + + @Test + void testSetGetPrimitiveTypeModels() { + PrimitiveTypeModel[] testArray = {new PrimitiveTypeModel(), new PrimitiveTypeModel()}; + + model.setPrimitiveTypeModels(testArray); + assertSame(testArray, model.getPrimitiveTypeModels(), "Should return the same array reference that was set"); + + // Verify the contents match + assertArrayEquals(testArray, model.getPrimitiveTypeModels(), "Array contents should match the set value"); + } + + @Test + void testSetGetModels() { + Model[] testArray = {new Model(), new Model()}; + + model.setModels(testArray); + assertSame(testArray, model.getModels(), "Should return the same array reference that was set"); + + // Verify the contents match + assertArrayEquals(testArray, model.getModels(), "Array contents should match the set value"); + } + + @Test + void testSetGetColors() { + Color[] testArray = {RED, BLUE, YELLOW}; + + model.setColors(testArray); + assertSame(testArray, model.getColors(), "Should return the same array reference that was set"); + + // Verify the contents match + assertArrayEquals(testArray, model.getColors(), "Array contents should match the set value"); + } + + @Test + void testSetNullValues() { + // Test setting each field to null + model.setIntegers(null); + assertNull(model.getIntegers(), "integers should be null after setting to null"); + + model.setStrings(null); + assertNull(model.getStrings(), "strings should be null after setting to null"); + + model.setPrimitiveTypeModels(null); + assertNull(model.getPrimitiveTypeModels(), "primitiveTypeModels should be null after setting to null"); + + model.setModels(null); + assertNull(model.getModels(), "models should be null after setting to null"); + + model.setColors(null); + assertNull(model.getColors(), "colors should be null after setting to null"); + } + + @Test + void testArrayMutability() { + int[] originalArray = {1, 2, 3}; + model.setIntegers(originalArray); + + // Modify the original array + originalArray[0] = 999; + + // Check if the change is reflected in the getter result + assertEquals(999, model.getIntegers()[0], + "Changes to the original array should be reflected since arrays are passed by reference"); + } +} \ No newline at end of file diff --git a/microsphere-java-test/src/test/java/io/microsphere/test/model/CollectionTypeModelTest.java b/microsphere-java-test/src/test/java/io/microsphere/test/model/CollectionTypeModelTest.java new file mode 100644 index 000000000..af3ae9098 --- /dev/null +++ b/microsphere-java-test/src/test/java/io/microsphere/test/model/CollectionTypeModelTest.java @@ -0,0 +1,138 @@ +package io.microsphere.test.model; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Deque; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; +import java.util.Set; + +import static io.microsphere.test.model.Color.BLUE; +import static io.microsphere.test.model.Color.RED; +import static io.microsphere.test.model.Color.YELLOW; +import static java.util.Arrays.asList; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * Unit tests for the CollectionTypeModel class + */ +class CollectionTypeModelTest { + + private CollectionTypeModel model; + + @BeforeEach + void setUp() { + model = new CollectionTypeModel(); + } + + @Test + void testDefaultValues() { + // Verify all collection fields are null by default + assertNull(model.getStrings(), "strings collection should be null by default"); + assertNull(model.getColors(), "colors list should be null by default"); + assertNull(model.getPrimitiveTypeModels(), "primitiveTypeModels queue should be null by default"); + assertNull(model.getModels(), "models deque should be null by default"); + assertNull(model.getModelArrays(), "modelArrays set should be null by default"); + } + + @Test + void testSetGetStrings() { + Collection testCollection = asList("hello", "world", "test"); + + model.setStrings(testCollection); + assertSame(testCollection, model.getStrings(), "Should return the same collection reference that was set"); + + // Verify the contents match + assertEquals(testCollection, model.getStrings(), "Collection contents should match the set value"); + } + + @Test + void testSetGetColors() { + List testList = asList(RED, BLUE, YELLOW); + + model.setColors(testList); + assertSame(testList, model.getColors(), "Should return the same list reference that was set"); + + // Verify the contents match + assertEquals(testList, model.getColors(), "List contents should match the set value"); + } + + @Test + void testSetGetPrimitiveTypeModels() { + Queue testQueue = new LinkedList<>(); + testQueue.add(new PrimitiveTypeModel()); + testQueue.add(new PrimitiveTypeModel()); + + model.setPrimitiveTypeModels(testQueue); + assertSame(testQueue, model.getPrimitiveTypeModels(), "Should return the same queue reference that was set"); + + // Verify the contents match + assertEquals(testQueue, model.getPrimitiveTypeModels(), "Queue contents should match the set value"); + } + + @Test + void testSetGetModels() { + Deque testDeque = new LinkedList<>(); + testDeque.add(new Model()); + testDeque.add(new Model()); + + model.setModels(testDeque); + assertSame(testDeque, model.getModels(), "Should return the same deque reference that was set"); + + // Verify the contents match + assertEquals(testDeque, model.getModels(), "Deque contents should match the set value"); + } + + @Test + void testSetGetModelArrays() { + Set testSet = new HashSet<>(); + testSet.add(new Model[]{new Model(), new Model()}); + testSet.add(new Model[]{new Model()}); + + model.setModelArrays(testSet); + assertSame(testSet, model.getModelArrays(), "Should return the same set reference that was set"); + + // Verify the contents match + assertEquals(testSet, model.getModelArrays(), "Set contents should match the set value"); + } + + @Test + void testSetNullValues() { + // Test setting each field to null + model.setStrings(null); + assertNull(model.getStrings(), "strings should be null after setting to null"); + + model.setColors(null); + assertNull(model.getColors(), "colors should be null after setting to null"); + + model.setPrimitiveTypeModels(null); + assertNull(model.getPrimitiveTypeModels(), "primitiveTypeModels should be null after setting to null"); + + model.setModels(null); + assertNull(model.getModels(), "models should be null after setting to null"); + + model.setModelArrays(null); + assertNull(model.getModelArrays(), "modelArrays should be null after setting to null"); + } + + @Test + void testCollectionMutability() { + List originalList = new ArrayList<>(asList(RED, BLUE)); + model.setColors(originalList); + + // Modify the original collection + originalList.add(RED); + + // Check if the change is reflected in the getter result + assertTrue(model.getColors().contains(RED), + "Changes to the original collection should be reflected since collections are passed by reference"); + } +} diff --git a/microsphere-java-test/src/test/java/io/microsphere/test/model/ColorTest.java b/microsphere-java-test/src/test/java/io/microsphere/test/model/ColorTest.java new file mode 100644 index 000000000..9f8f0cfde --- /dev/null +++ b/microsphere-java-test/src/test/java/io/microsphere/test/model/ColorTest.java @@ -0,0 +1,103 @@ +package io.microsphere.test.model; + +import org.junit.jupiter.api.Test; + +import static io.microsphere.test.model.Color.BLUE; +import static io.microsphere.test.model.Color.RED; +import static io.microsphere.test.model.Color.YELLOW; +import static java.util.Arrays.asList; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * Unit tests for the Color enum + */ +class ColorTest { + + @Test + void testEnumValues() { + // Verify that all enum constants exist and are accessible + assertNotNull(RED, "RED color should exist"); + assertNotNull(YELLOW, "YELLOW color should exist"); + assertNotNull(BLUE, "BLUE color should exist"); + } + + @Test + void testGetValueMethod() { + // Verify the value associated with each color + assertEquals(1, RED.getValue(), "RED should have value 1"); + assertEquals(2, YELLOW.getValue(), "YELLOW should have value 2"); + assertEquals(3, BLUE.getValue(), "BLUE should have value 3"); + } + + @Test + void testToStringMethod() { + // Verify the string representation of each color + String redString = RED.toString(); + assertTrue(redString.contains("Color{value=1}"), "RED toString should contain value=1"); + assertTrue(redString.endsWith("RED"), "RED toString should end with RED"); + + String yellowString = YELLOW.toString(); + assertTrue(yellowString.contains("Color{value=2}"), "YELLOW toString should contain value=2"); + assertTrue(yellowString.endsWith("YELLOW"), "YELLOW toString should end with YELLOW"); + + String blueString = BLUE.toString(); + assertTrue(blueString.contains("Color{value=3}"), "BLUE toString should contain value=3"); + assertTrue(blueString.endsWith("BLUE"), "BLUE toString should end with BLUE"); + } + + @Test + void testEnumOrdinality() { + // Verify that enum constants have expected ordinal positions + assertEquals(0, RED.ordinal(), "RED should be at ordinal position 0"); + assertEquals(1, YELLOW.ordinal(), "YELLOW should be at ordinal position 1"); + assertEquals(2, BLUE.ordinal(), "BLUE should be at ordinal position 2"); + } + + @Test + void testEnumName() { + // Verify that enum constants have correct names + assertEquals("RED", RED.name(), "RED name should be 'RED'"); + assertEquals("YELLOW", YELLOW.name(), "YELLOW name should be 'YELLOW'"); + assertEquals("BLUE", BLUE.name(), "BLUE name should be 'BLUE'"); + } + + @Test + void testEnumEquality() { + // Verify that enum equality works correctly + assertEquals(RED, RED, "RED should equal itself"); + assertEquals(YELLOW, YELLOW, "YELLOW should equal itself"); + assertEquals(BLUE, BLUE, "BLUE should equal itself"); + + assertNotEquals(RED, BLUE, "RED should not equal BLUE"); + assertNotEquals(RED, YELLOW, "RED should not equal YELLOW"); + assertNotEquals(BLUE, YELLOW, "BLUE should not equal YELLOW"); + } + + @Test + void testValueImmutability() { + // Verify that the value cannot be changed (as it's final) + int redValue = RED.getValue(); + int yellowValue = YELLOW.getValue(); + int blueValue = BLUE.getValue(); + + // Values should remain constant across multiple calls + assertEquals(redValue, RED.getValue(), "RED value should be immutable"); + assertEquals(yellowValue, YELLOW.getValue(), "YELLOW value should be immutable"); + assertEquals(blueValue, BLUE.getValue(), "BLUE value should be immutable"); + } + + @Test + void testAllEnumConstantsExist() { + // Verify that we can retrieve all enum constants + Color[] allColors = Color.values(); + assertEquals(3, allColors.length, "There should be exactly 3 color constants"); + + // Verify that all expected colors are present + assertTrue(asList(allColors).contains(RED), "All colors should include RED"); + assertTrue(asList(allColors).contains(YELLOW), "All colors should include YELLOW"); + assertTrue(asList(allColors).contains(BLUE), "All colors should include BLUE"); + } +} diff --git a/microsphere-java-test/src/test/java/io/microsphere/test/model/ConfigurationPropertyModelTest.java b/microsphere-java-test/src/test/java/io/microsphere/test/model/ConfigurationPropertyModelTest.java new file mode 100644 index 000000000..4218d3d43 --- /dev/null +++ b/microsphere-java-test/src/test/java/io/microsphere/test/model/ConfigurationPropertyModelTest.java @@ -0,0 +1,152 @@ +package io.microsphere.test.model; + +import io.microsphere.annotation.ConfigurationProperty; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * Unit tests for the ConfigurationPropertyModel class + */ +class ConfigurationPropertyModelTest { + + private ConfigurationPropertyModel model; + + @BeforeEach + void setUp() { + model = new ConfigurationPropertyModel(); + } + + @Test + void testDefaultValues() { + // Verify all fields have their default values + assertNull(model.getName(), "name should be null by default"); + assertNull(model.getType(), "type should be null by default"); + assertNull(model.getDefaultValue(), "defaultValue should be null by default"); + assertFalse(model.isRequired(), "required should be false by default"); + assertNull(model.getDescription(), "description should be null by default"); + } + + @Test + void testSetNameAndGet() { + String testName = "test.config.property"; + model.setName(testName); + assertEquals(testName, model.getName(), "getName should return the set value"); + } + + @Test + void testSetTypeAndGet() { + Class testType = String.class; + model.setType(testType); + assertEquals(testType, model.getType(), "getType should return the set value"); + } + + @Test + void testSetDefaultValueAndGet() { + String testDefaultValue = "default_value"; + model.setDefaultValue(testDefaultValue); + assertEquals(testDefaultValue, model.getDefaultValue(), "getDefaultValue should return the set value"); + } + + @Test + void testSetRequiredAndGet() { + model.setRequired(true); + assertTrue(model.isRequired(), "isRequired should return true after setting to true"); + + model.setRequired(false); + assertFalse(model.isRequired(), "isRequired should return false after setting to false"); + } + + @Test + void testSetDescriptionAndGet() { + String testDescription = "This is a test configuration property"; + model.setDescription(testDescription); + assertEquals(testDescription, model.getDescription(), "getDescription should return the set value"); + } + + @Test + void testConfigurationPropertyAnnotations() { + // Test that the ConfigurationProperty annotations are present on the fields + java.lang.reflect.Field[] fields = ConfigurationPropertyModel.class.getDeclaredFields(); + + boolean hasNameAnnotation = false; + boolean hasTypeAnnotation = false; + boolean hasDefaultValueAnnotation = false; + boolean hasRequiredAnnotation = false; + boolean hasDescriptionAnnotation = false; + + for (java.lang.reflect.Field field : fields) { + if (field.isAnnotationPresent(ConfigurationProperty.class)) { + ConfigurationProperty annotation = field.getAnnotation(ConfigurationProperty.class); + + switch (field.getName()) { + case "name": + if ("microsphere.annotation.processor.model.name".equals(annotation.name())) { + hasNameAnnotation = true; + } + break; + case "type": + if ("microsphere.annotation.processor.model.type".equals(annotation.name())) { + hasTypeAnnotation = true; + } + break; + case "defaultValue": + if ("microsphere.annotation.processor.model.default-value".equals(annotation.name())) { + hasDefaultValueAnnotation = true; + } + break; + case "required": + if ("microsphere.annotation.processor.model.required".equals(annotation.name())) { + hasRequiredAnnotation = true; + } + break; + case "description": + if ("microsphere.annotation.processor.model.description".equals(annotation.name())) { + hasDescriptionAnnotation = true; + } + break; + } + } + } + + assertTrue(hasNameAnnotation, "name field should have ConfigurationProperty annotation with correct name"); + assertTrue(hasTypeAnnotation, "type field should have ConfigurationProperty annotation with correct name"); + assertTrue(hasDefaultValueAnnotation, "defaultValue field should have ConfigurationProperty annotation with correct name"); + assertTrue(hasRequiredAnnotation, "required field should have ConfigurationProperty annotation with correct name"); + assertTrue(hasDescriptionAnnotation, "description field should have ConfigurationProperty annotation with correct name"); + } + + @Test + void testSetAllProperties() { + // Test setting all properties and verifying they are returned correctly + model.setName("full.test.name"); + model.setType(Integer.class); + model.setDefaultValue("42"); + model.setRequired(true); + model.setDescription("Complete test configuration"); + + assertEquals("full.test.name", model.getName(), "Name should match set value"); + assertEquals(Integer.class, model.getType(), "Type should match set value"); + assertEquals("42", model.getDefaultValue(), "DefaultValue should match set value"); + assertTrue(model.isRequired(), "Required should match set value"); + assertEquals("Complete test configuration", model.getDescription(), "Description should match set value"); + } + + @Test + void testNullValueHandling() { + // Test setting fields to null + model.setName(null); + model.setType(null); + model.setDefaultValue(null); + model.setDescription(null); + + assertNull(model.getName(), "Name should be null"); + assertNull(model.getType(), "Type should be null"); + assertNull(model.getDefaultValue(), "DefaultValue should be null"); + assertNull(model.getDescription(), "Description should be null"); + } +} diff --git a/microsphere-java-test/src/test/java/io/microsphere/test/model/MapTypeModelTest.java b/microsphere-java-test/src/test/java/io/microsphere/test/model/MapTypeModelTest.java new file mode 100644 index 000000000..9640d802c --- /dev/null +++ b/microsphere-java-test/src/test/java/io/microsphere/test/model/MapTypeModelTest.java @@ -0,0 +1,138 @@ +package io.microsphere.test.model; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.util.HashMap; +import java.util.Map; +import java.util.NavigableMap; +import java.util.SortedMap; +import java.util.TreeMap; + +import static io.microsphere.test.model.Color.BLUE; +import static io.microsphere.test.model.Color.RED; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * Unit tests for the MapTypeModel class + */ +class MapTypeModelTest { + + private MapTypeModel model; + + @BeforeEach + void setUp() { + model = new MapTypeModel(); + } + + @Test + void testDefaultValues() { + // Verify all map fields are null by default + assertNull(model.getStrings(), "strings map should be null by default"); + assertNull(model.getColors(), "colors sorted map should be null by default"); + assertNull(model.getPrimitiveTypeModels(), "primitiveTypeModels navigable map should be null by default"); + assertNull(model.getModels(), "models hash map should be null by default"); + assertNull(model.getModelArrays(), "modelArrays tree map should be null by default"); + } + + @Test + void testSetGetStrings() { + Map testMap = new HashMap<>(); + testMap.put("key1", "value1"); + testMap.put("key2", "value2"); + + model.setStrings(testMap); + assertSame(testMap, model.getStrings(), "Should return the same map reference that was set"); + + // Verify the contents match + assertEquals(testMap, model.getStrings(), "Map contents should match the set value"); + } + + @Test + void testSetGetColors() { + SortedMap testMap = new TreeMap<>(); + testMap.put("red_key", RED); + testMap.put("blue_key", BLUE); + + model.setColors(testMap); + assertSame(testMap, model.getColors(), "Should return the same map reference that was set"); + + // Verify the contents match + assertEquals(testMap, model.getColors(), "SortedMap contents should match the set value"); + } + + @Test + void testSetGetPrimitiveTypeModels() { + NavigableMap testMap = new TreeMap<>(); + testMap.put(RED, new PrimitiveTypeModel()); + testMap.put(BLUE, new PrimitiveTypeModel()); + + model.setPrimitiveTypeModels(testMap); + assertSame(testMap, model.getPrimitiveTypeModels(), "Should return the same map reference that was set"); + + // Verify the contents match + assertEquals(testMap, model.getPrimitiveTypeModels(), "NavigableMap contents should match the set value"); + } + + @Test + void testSetGetModels() { + HashMap testMap = new HashMap<>(); + testMap.put("model1", new Model()); + testMap.put("model2", new Model()); + + model.setModels(testMap); + assertSame(testMap, model.getModels(), "Should return the same map reference that was set"); + + // Verify the contents match + assertEquals(testMap, model.getModels(), "HashMap contents should match the set value"); + } + + @Test + void testSetGetModelArrays() { + TreeMap testMap = new TreeMap<>((a, b) -> 1); // Using custom comparator to avoid issues with PrimitiveTypeModel not implementing Comparable + testMap.put(new PrimitiveTypeModel(), new Model[]{new Model()}); + testMap.put(new PrimitiveTypeModel(), new Model[]{new Model(), new Model()}); + + model.setModelArrays(testMap); + assertSame(testMap, model.getModelArrays(), "Should return the same map reference that was set"); + + // Verify the contents match + assertEquals(testMap, model.getModelArrays(), "TreeMap contents should match the set value"); + } + + @Test + void testSetNullValues() { + // Test setting each field to null + model.setStrings(null); + assertNull(model.getStrings(), "strings should be null after setting to null"); + + model.setColors(null); + assertNull(model.getColors(), "colors should be null after setting to null"); + + model.setPrimitiveTypeModels(null); + assertNull(model.getPrimitiveTypeModels(), "primitiveTypeModels should be null after setting to null"); + + model.setModels(null); + assertNull(model.getModels(), "models should be null after setting to null"); + + model.setModelArrays(null); + assertNull(model.getModelArrays(), "modelArrays should be null after setting to null"); + } + + @Test + void testMapMutability() { + Map originalMap = new HashMap<>(); + originalMap.put("initial", "value"); + model.setStrings(originalMap); + + // Modify the original map + originalMap.put("added", "new_value"); + + // Check if the change is reflected in the getter result + assertTrue(model.getStrings().containsKey("added"), + "Changes to the original map should be reflected since maps are passed by reference"); + } +} diff --git a/microsphere-java-test/src/test/java/io/microsphere/test/model/ModelTest.java b/microsphere-java-test/src/test/java/io/microsphere/test/model/ModelTest.java new file mode 100644 index 000000000..5a9b63b28 --- /dev/null +++ b/microsphere-java-test/src/test/java/io/microsphere/test/model/ModelTest.java @@ -0,0 +1,116 @@ +package io.microsphere.test.model; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.concurrent.TimeUnit; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * Unit tests for the Model class + */ +class ModelTest { + + private Model model; + + @BeforeEach + void setUp() { + model = new Model(); + } + + @Test + void testDefaultValues() { + // Verify all primitive fields have their default values + assertEquals(0.0f, model.getF(), "float field f should be 0.0f by default"); + assertEquals(0.0d, model.getD(), "double field d should be 0.0d by default"); + + // Verify all object fields are null by default + assertNull(model.getTu(), "TimeUnit field tu should be null by default"); + assertNull(model.getStr(), "String field str should be null by default"); + assertNull(model.getBi(), "BigInteger field bi should be null by default"); + assertNull(model.getBd(), "BigDecimal field bd should be null by default"); + } + + @Test + void testSetGetFloat() { + float testValue = 3.14f; + model.setF(testValue); + assertEquals(testValue, model.getF(), "getF should return the set value"); + } + + @Test + void testSetGetDouble() { + double testValue = 2.71828d; + model.setD(testValue); + assertEquals(testValue, model.getD(), "getD should return the set value"); + } + + @Test + void testSetGetTimeUnit() { + TimeUnit testValue = TimeUnit.SECONDS; + model.setTu(testValue); + assertEquals(testValue, model.getTu(), "getTu should return the set value"); + } + + @Test + void testSetGetString() { + String testValue = "Hello World"; + model.setStr(testValue); + assertEquals(testValue, model.getStr(), "getStr should return the set value"); + } + + @Test + void testSetGetBigInteger() { + BigInteger testValue = new BigInteger("123456789012345678901234567890"); + model.setBi(testValue); + assertEquals(testValue, model.getBi(), "getBi should return the set value"); + } + + @Test + void testSetGetBigDecimal() { + BigDecimal testValue = new BigDecimal("1234567890.12345678901234567890"); + model.setBd(testValue); + assertEquals(testValue, model.getBd(), "getBd should return the set value"); + } + + @Test + void testInheritanceFromParent() { + // Verify that the model inherits from Parent class + assertTrue(model instanceof Parent, "Model should extend Parent class"); + } + + @Test + void testMultipleValueChanges() { + // Test changing values multiple times + model.setF(1.0f); + assertEquals(1.0f, model.getF(), "f should be 1.0f"); + + model.setF(2.0f); + assertEquals(2.0f, model.getF(), "f should be 2.0f after second assignment"); + + model.setD(10.0d); + assertEquals(10.0d, model.getD(), "d should be 10.0d"); + + model.setD(20.0d); + assertEquals(20.0d, model.getD(), "d should be 20.0d after second assignment"); + } + + @Test + void testNullHandling() { + // Test setting object fields to null + model.setTu(null); + model.setStr(null); + model.setBi(null); + model.setBd(null); + + assertNull(model.getTu(), "tu should be null after setting to null"); + assertNull(model.getStr(), "str should be null after setting to null"); + assertNull(model.getBi(), "bi should be null after setting to null"); + assertNull(model.getBd(), "bd should be null after setting to null"); + } +} diff --git a/microsphere-java-test/src/test/java/io/microsphere/test/model/ParentTest.java b/microsphere-java-test/src/test/java/io/microsphere/test/model/ParentTest.java new file mode 100644 index 000000000..30d489e6e --- /dev/null +++ b/microsphere-java-test/src/test/java/io/microsphere/test/model/ParentTest.java @@ -0,0 +1,86 @@ +package io.microsphere.test.model; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * Unit tests for the Parent class + */ +class ParentTest { + + private Parent parent; + + @BeforeEach + void setUp() { + parent = new Parent(); + } + + @Test + void testDefaultValues() { + // Verify all primitive fields have their default values + assertEquals((byte) 0, parent.getB(), "byte field b should be 0 by default"); + assertEquals((short) 0, parent.getS(), "short field s should be 0 by default"); + assertEquals(0, parent.getI(), "int field i should be 0 by default"); + assertEquals(0L, parent.getL(), "long field l should be 0L by default"); + } + + @Test + void testSetGetByte() { + byte testValue = (byte) 42; + parent.setB(testValue); + assertEquals(testValue, parent.getB(), "getB should return the set value"); + } + + @Test + void testSetGetShort() { + short testValue = (short) 1000; + parent.setS(testValue); + assertEquals(testValue, parent.getS(), "getS should return the set value"); + } + + @Test + void testSetGetInt() { + int testValue = 123456; + parent.setI(testValue); + assertEquals(testValue, parent.getI(), "getI should return the set value"); + } + + @Test + void testSetGetLong() { + long testValue = 9876543210L; + parent.setL(testValue); + assertEquals(testValue, parent.getL(), "getL should return the set value"); + } + + @Test + void testInheritanceFromAncestor() { + // Verify that the parent inherits from Ancestor class + assertTrue(parent instanceof Ancestor, "Parent should extend Ancestor class"); + + // Test inherited functionality + assertFalse(parent.isZ(), "Should inherit default z value of false from Ancestor"); + + parent.setZ(true); + assertTrue(parent.isZ(), "Should be able to modify inherited z field"); + } + + @Test + void testMultipleValueChanges() { + // Test changing values multiple times + parent.setB((byte) 1); + assertEquals((byte) 1, parent.getB(), "b should be 1"); + + parent.setB((byte) 2); + assertEquals((byte) 2, parent.getB(), "b should be 2 after second assignment"); + + parent.setI(100); + assertEquals(100, parent.getI(), "i should be 100"); + + parent.setI(200); + assertEquals(200, parent.getI(), "i should be 200 after second assignment"); + } +} diff --git a/microsphere-java-test/src/test/java/io/microsphere/test/model/PrimitiveTypeModelTest.java b/microsphere-java-test/src/test/java/io/microsphere/test/model/PrimitiveTypeModelTest.java new file mode 100644 index 000000000..1f28bcb4d --- /dev/null +++ b/microsphere-java-test/src/test/java/io/microsphere/test/model/PrimitiveTypeModelTest.java @@ -0,0 +1,81 @@ +package io.microsphere.test.model; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; + +/** + * Unit tests for the PrimitiveTypeModel class + */ +class PrimitiveTypeModelTest { + + private PrimitiveTypeModel model; + + @BeforeEach + void setUp() { + model = new PrimitiveTypeModel(); + } + + @Test + void testDefaultValues() { + // Verify all primitive fields have their default values + assertFalse(model.isZ(), "boolean field z should be false by default"); + assertEquals((byte) 0, model.getB(), "byte field b should be 0 by default"); + assertEquals('\u0000', model.getC(), "char field c should be null character by default"); + assertEquals((short) 0, model.getS(), "short field s should be 0 by default"); + assertEquals(0, model.getI(), "int field i should be 0 by default"); + assertEquals(0L, model.getL(), "long field l should be 0L by default"); + assertEquals(0.0f, model.getF(), "float field f should be 0.0f by default"); + assertEquals(0.0d, model.getD(), "double field d should be 0.0d by default"); + } + + @Test + void testBooleanField() { + // Test boolean field specifically since it uses 'is' prefix instead of 'get' + assertFalse(model.isZ(), "Initial value should be false"); + } + + @Test + void testPrimitiveTypesRange() { + // Test various ranges for different primitive types + PrimitiveTypeModel testModel = new PrimitiveTypeModel(); + + // Boolean + // Cannot set values directly as there are no setters, but we can verify the default + + // Byte range (-128 to 127) + byte minByte = Byte.MIN_VALUE; + byte maxByte = Byte.MAX_VALUE; + + // Char range (0 to 65535) + char minChar = Character.MIN_VALUE; + char maxChar = Character.MAX_VALUE; + + // Short range (-32768 to 32767) + short minShort = Short.MIN_VALUE; + short maxShort = Short.MAX_VALUE; + + // Int range + int minInt = Integer.MIN_VALUE; + int maxInt = Integer.MAX_VALUE; + + // Long range + long minLong = Long.MIN_VALUE; + long maxLong = Long.MAX_VALUE; + + // Float range + float minFloat = Float.MIN_VALUE; + float maxFloat = Float.MAX_VALUE; + + // Double range + double minDouble = Double.MIN_VALUE; + double maxDouble = Double.MAX_VALUE; + + // These are just to ensure the getters work with different possible values + // Since there are no setters, we're just validating the getters return values + assertEquals(0, testModel.getI(), "Integer field should have default value"); + assertEquals(0.0f, testModel.getF(), "Float field should have default value"); + } +} diff --git a/microsphere-java-test/src/test/java/io/microsphere/test/model/SimpleTypeModelTest.java b/microsphere-java-test/src/test/java/io/microsphere/test/model/SimpleTypeModelTest.java new file mode 100644 index 000000000..6a0d24251 --- /dev/null +++ b/microsphere-java-test/src/test/java/io/microsphere/test/model/SimpleTypeModelTest.java @@ -0,0 +1,182 @@ +package io.microsphere.test.model; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.Date; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; + +/** + * Unit tests for the SimpleTypeModel class + */ +class SimpleTypeModelTest { + + private SimpleTypeModel model; + + @BeforeEach + void setUp() { + model = new SimpleTypeModel(); + } + + @Test + void testDefaultValues() { + // Verify all object fields are null by default + assertNull(model.getV(), "Void field v should be null by default"); + assertNull(model.getZ(), "Boolean field z should be null by default"); + assertNull(model.getC(), "Character field c should be null by default"); + assertNull(model.getB(), "Byte field b should be null by default"); + assertNull(model.getS(), "Short field s should be null by default"); + assertNull(model.getI(), "Integer field i should be null by default"); + assertNull(model.getL(), "Long field l should be null by default"); + assertNull(model.getF(), "Float field f should be null by default"); + assertNull(model.getD(), "Double field d should be null by default"); + assertNull(model.getStr(), "String field str should be null by default"); + assertNull(model.getBd(), "BigDecimal field bd should be null by default"); + assertNull(model.getBi(), "BigInteger field bi should be null by default"); + assertNull(model.getDt(), "Date field dt should be null by default"); + } + + @Test + void testSetGetVoid() { + // Void is always null, so setting it to null should work + model.setV(null); + assertNull(model.getV(), "Void should always be null"); + } + + @Test + void testSetGetBoolean() { + Boolean testValue = Boolean.TRUE; + model.setZ(testValue); + assertEquals(testValue, model.getZ(), "getZ should return the set value"); + + model.setZ(Boolean.FALSE); + assertEquals(Boolean.FALSE, model.getZ(), "getZ should return the set value"); + } + + @Test + void testSetGetCharacter() { + Character testValue = 'A'; + model.setC(testValue); + assertEquals(testValue, model.getC(), "getC should return the set value"); + } + + @Test + void testSetGetByte() { + Byte testValue = (byte) 42; + model.setB(testValue); + assertEquals(testValue, model.getB(), "getB should return the set value"); + } + + @Test + void testSetGetShort() { + Short testValue = (short) 1000; + model.setS(testValue); + assertEquals(testValue, model.getS(), "getS should return the set value"); + } + + @Test + void testSetGetInteger() { + Integer testValue = 123456; + model.setI(testValue); + assertEquals(testValue, model.getI(), "getI should return the set value"); + } + + @Test + void testSetGetLong() { + Long testValue = 9876543210L; + model.setL(testValue); + assertEquals(testValue, model.getL(), "getL should return the set value"); + } + + @Test + void testSetGetFloat() { + Float testValue = 3.14f; + model.setF(testValue); + assertEquals(testValue, model.getF(), "getF should return the set value"); + } + + @Test + void testSetGetDouble() { + Double testValue = 2.71828d; + model.setD(testValue); + assertEquals(testValue, model.getD(), "getD should return the set value"); + } + + @Test + void testSetGetString() { + String testValue = "Hello World"; + model.setStr(testValue); + assertEquals(testValue, model.getStr(), "getStr should return the set value"); + } + + @Test + void testSetGetBigDecimal() { + BigDecimal testValue = new BigDecimal("1234567890.12345678901234567890"); + model.setBd(testValue); + assertEquals(testValue, model.getBd(), "getBd should return the set value"); + } + + @Test + void testSetGetBigInteger() { + BigInteger testValue = new BigInteger("123456789012345678901234567890"); + model.setBi(testValue); + assertEquals(testValue, model.getBi(), "getBi should return the set value"); + } + + @Test + void testSetGetDate() { + Date testValue = new Date(); + model.setDt(testValue); + assertEquals(testValue, model.getDt(), "getDt should return the set value"); + } + + @Test + void testNullHandling() { + // Test setting all fields to null + model.setZ(null); + model.setC(null); + model.setB(null); + model.setS(null); + model.setI(null); + model.setL(null); + model.setF(null); + model.setD(null); + model.setStr(null); + model.setBd(null); + model.setBi(null); + model.setDt(null); + + assertNull(model.getZ(), "z should be null after setting to null"); + assertNull(model.getC(), "c should be null after setting to null"); + assertNull(model.getB(), "b should be null after setting to null"); + assertNull(model.getS(), "s should be null after setting to null"); + assertNull(model.getI(), "i should be null after setting to null"); + assertNull(model.getL(), "l should be null after setting to null"); + assertNull(model.getF(), "f should be null after setting to null"); + assertNull(model.getD(), "d should be null after setting to null"); + assertNull(model.getStr(), "str should be null after setting to null"); + assertNull(model.getBd(), "bd should be null after setting to null"); + assertNull(model.getBi(), "bi should be null after setting to null"); + assertNull(model.getDt(), "dt should be null after setting to null"); + } + + @Test + void testMultipleValueChanges() { + // Test changing values multiple times + model.setI(100); + assertEquals(Integer.valueOf(100), model.getI(), "i should be 100"); + + model.setI(200); + assertEquals(Integer.valueOf(200), model.getI(), "i should be 200 after second assignment"); + + model.setStr("first"); + assertEquals("first", model.getStr(), "str should be 'first'"); + + model.setStr("second"); + assertEquals("second", model.getStr(), "str should be 'second' after second assignment"); + } +} diff --git a/microsphere-java-test/src/test/java/io/microsphere/test/model/StringArrayListTest.java b/microsphere-java-test/src/test/java/io/microsphere/test/model/StringArrayListTest.java new file mode 100644 index 000000000..cc417fa20 --- /dev/null +++ b/microsphere-java-test/src/test/java/io/microsphere/test/model/StringArrayListTest.java @@ -0,0 +1,137 @@ +package io.microsphere.test.model; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * Unit tests for the StringArrayList class + */ +class StringArrayListTest { + + private StringArrayList stringArrayList; + + @BeforeEach + void setUp() { + stringArrayList = new StringArrayList(); + } + + @Test + void testDefaultConstructor() { + // Verify that the StringArrayList can be instantiated and is empty initially + assertNotNull(stringArrayList, "StringArrayList should be instantiated successfully"); + assertTrue(stringArrayList.isEmpty(), "StringArrayList should be empty by default"); + assertEquals(0, stringArrayList.size(), "StringArrayList size should be 0 by default"); + } + + @Test + void testAddAndGetSize() { + // Test adding elements and checking size + stringArrayList.add("element1"); + assertEquals(1, stringArrayList.size(), "Size should be 1 after adding one element"); + + stringArrayList.add("element2"); + assertEquals(2, stringArrayList.size(), "Size should be 2 after adding two elements"); + } + + @Test + void testAddAndGetElements() { + // Test adding elements and retrieving them + String element1 = "Hello"; + String element2 = "World"; + String element3 = "Test"; + + stringArrayList.add(element1); + stringArrayList.add(element2); + stringArrayList.add(element3); + + assertEquals(element1, stringArrayList.get(0), "Element at index 0 should match added value"); + assertEquals(element2, stringArrayList.get(1), "Element at index 1 should match added value"); + assertEquals(element3, stringArrayList.get(2), "Element at index 2 should match added value"); + } + + @Test + void testAddAll() { + // Test adding multiple elements at once + String[] elements = {"item1", "item2", "item3"}; + + boolean result = stringArrayList.addAll(Arrays.asList(elements)); + assertTrue(result, "addAll should return true when elements are added"); + + assertEquals(3, stringArrayList.size(), "Size should match number of added elements"); + assertEquals("item1", stringArrayList.get(0), "First element should match"); + assertEquals("item2", stringArrayList.get(1), "Second element should match"); + assertEquals("item3", stringArrayList.get(2), "Third element should match"); + } + + @Test + void testRemoveElement() { + // Test removing elements + stringArrayList.add("element1"); + stringArrayList.add("element2"); + + boolean removed = stringArrayList.remove("element1"); + assertTrue(removed, "Should return true when element is successfully removed"); + assertEquals(1, stringArrayList.size(), "Size should decrease after removal"); + assertEquals("element2", stringArrayList.get(0), "Remaining element should still be accessible"); + } + + @Test + void testClear() { + // Test clearing all elements + stringArrayList.add("element1"); + stringArrayList.add("element2"); + stringArrayList.add("element3"); + + assertEquals(3, stringArrayList.size(), "Size should be 3 before clear"); + + stringArrayList.clear(); + + assertTrue(stringArrayList.isEmpty(), "List should be empty after clear"); + assertEquals(0, stringArrayList.size(), "Size should be 0 after clear"); + } + + @Test + void testContains() { + // Test contains functionality + String element = "test_element"; + stringArrayList.add(element); + + assertTrue(stringArrayList.contains(element), "List should contain the added element"); + assertFalse(stringArrayList.contains("non_existent"), "List should not contain non-existent element"); + } + + @Test + void testIterator() { + // Test iterator functionality + String[] elements = {"a", "b", "c"}; + stringArrayList.addAll(Arrays.asList(elements)); + + Iterator iterator = stringArrayList.iterator(); + int index = 0; + + while (iterator.hasNext() && index < elements.length) { + String nextElement = iterator.next(); + assertEquals(elements[index], nextElement, "Iterator should return elements in order"); + index++; + } + + assertFalse(iterator.hasNext(), "Iterator should be exhausted after processing all elements"); + } + + @Test + void testInheritanceFromArrayList() { + // Verify that StringArrayList properly extends ArrayList + assertTrue(stringArrayList instanceof ArrayList, "StringArrayList should extend ArrayList"); + assertTrue(stringArrayList instanceof java.util.List, "StringArrayList should implement List interface"); + assertTrue(stringArrayList instanceof java.util.Collection, "StringArrayList should implement Collection interface"); + } +} diff --git a/microsphere-java-test/src/test/java/io/microsphere/test/service/DefaultTestServiceTest.java b/microsphere-java-test/src/test/java/io/microsphere/test/service/DefaultTestServiceTest.java new file mode 100644 index 000000000..a7713e79a --- /dev/null +++ b/microsphere-java-test/src/test/java/io/microsphere/test/service/DefaultTestServiceTest.java @@ -0,0 +1,83 @@ +package io.microsphere.test.service; + +import io.microsphere.test.model.Model; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.util.concurrent.TimeUnit; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertSame; + +/** + * Unit tests for the DefaultTestService class. + */ +class DefaultTestServiceTest { + + private DefaultTestService defaultTestService; + + @BeforeEach + void setUp() { + defaultTestService = new DefaultTestService(); + } + + /** + * Test the echo method. + * Verifies that the method correctly prefixes the input message with "[ECHO] ". + */ + @Test + void testEcho() { + String input = "Hello, World!"; + String expectedOutput = "[ECHO] Hello, World!"; + String actualOutput = defaultTestService.echo(input); + assertEquals(expectedOutput, actualOutput, "The echo method should prefix the message with '[ECHO] '."); + } + + /** + * Test the model method. + * Verifies that the method returns the same Model object that was passed in. + */ + @Test + void testModel() { + Model inputModel = new Model(); + Model outputModel = defaultTestService.model(inputModel); + assertSame(inputModel, outputModel, "The model method should return the same Model object."); + } + + /** + * Test the testPrimitive method. + * Currently, this method returns null, so the test verifies that null is returned. + */ + @Test + void testTestPrimitive() { + boolean z = true; + int i = 42; + String result = defaultTestService.testPrimitive(z, i); + assertNull(result, "The testPrimitive method should return null."); + } + + /** + * Test the testEnum method. + * Currently, this method returns null, so the test verifies that null is returned. + */ + @Test + void testTestEnum() { + TimeUnit timeUnit = TimeUnit.SECONDS; + Model result = defaultTestService.testEnum(timeUnit); + assertNull(result, "The testEnum method should return null."); + } + + /** + * Test the testArray method. + * Currently, this method returns null, so the test verifies that null is returned. + */ + @Test + void testTestArray() { + String[] strArray = {"a", "b", "c"}; + int[] intArray = {1, 2, 3}; + Model[] modelArray = {new Model(), new Model()}; + String result = defaultTestService.testArray(strArray, intArray, modelArray); + assertNull(result, "The testArray method should return null."); + } +} diff --git a/microsphere-java-test/src/test/java/io/microsphere/test/service/GenericTestServiceTest.java b/microsphere-java-test/src/test/java/io/microsphere/test/service/GenericTestServiceTest.java new file mode 100644 index 000000000..d97ca6011 --- /dev/null +++ b/microsphere-java-test/src/test/java/io/microsphere/test/service/GenericTestServiceTest.java @@ -0,0 +1,58 @@ +package io.microsphere.test.service; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * Unit tests for the GenericTestService class. + */ +class GenericTestServiceTest { + + private GenericTestService genericTestService; + + @BeforeEach + void setUp() { + genericTestService = new GenericTestService(); + } + + /** + * Test the echo method. + * Verifies that the method correctly prefixes the input message with "[ECHO] ". + */ + @Test + void testEcho() { + String input = "Hello, World!"; + String expectedOutput = "[ECHO] Hello, World!"; + String actualOutput = genericTestService.echo(input); + assertEquals(expectedOutput, actualOutput, "The echo method should prefix the message with '[ECHO] '."); + } + + /** + * Test inheritance from DefaultTestService. + * Verifies that methods from the parent class are accessible and functional. + */ + @Test + void testInheritedMethods() { + // Example: Testing a method inherited from DefaultTestService + // Assuming DefaultTestService has a method like model(Model model) + // Uncomment and adapt the following lines if such a method exists: + /* + Model inputModel = new Model(); + Model outputModel = genericTestService.model(inputModel); + assertSame(inputModel, outputModel, "The inherited model method should return the same Model object."); + */ + } + + /** + * Test implementation of EventListener interface. + * Verifies that the class correctly implements the EventListener marker interface. + */ + @Test + void testEventListenerImplementation() { + assertTrue(genericTestService instanceof java.util.EventListener, + "GenericTestService should implement the EventListener interface."); + } +} diff --git a/microsphere-java-test/src/test/java/io/microsphere/test/service/TestServiceImplTest.java b/microsphere-java-test/src/test/java/io/microsphere/test/service/TestServiceImplTest.java new file mode 100644 index 000000000..b7fc3ecf8 --- /dev/null +++ b/microsphere-java-test/src/test/java/io/microsphere/test/service/TestServiceImplTest.java @@ -0,0 +1,75 @@ +package io.microsphere.test.service; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.context.ApplicationContext; +import org.springframework.core.env.Environment; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.mockito.Mockito.mock; + +/** + * Unit tests for the TestServiceImpl class. + */ +class TestServiceImplTest { + + private TestServiceImpl testService; + private ApplicationContext mockContext; + private Environment mockEnvironment; + + @BeforeEach + void setUp() { + // Mock dependencies + mockContext = mock(ApplicationContext.class); + mockEnvironment = mock(Environment.class); + + // Initialize the service with mocked dependencies + testService = new TestServiceImpl(mockEnvironment); + testService.context = mockContext; // Inject mocked ApplicationContext + } + + /** + * Test the echo method. + * Verifies that the method correctly prefixes the input message with "[ECHO] ". + */ + @Test + void testEcho() { + String input = "Hello, World!"; + String expectedOutput = "[ECHO] Hello, World!"; + String actualOutput = testService.echo(input); + assertEquals(expectedOutput, actualOutput, "The echo method should prefix the message with '[ECHO] '."); + } + + /** + * Test the close method. + * Verifies that the method does not throw any exceptions. + */ + @Test + void testClose() { + assertDoesNotThrow(() -> testService.close(), "The close method should not throw any exceptions."); + } + + /** + * Test constructor with Environment parameter. + * Verifies that the environment is properly injected. + */ + @Test + void testConstructorWithEnvironment() { + assertNotNull(testService.environment, "The environment should be injected via constructor."); + assertSame(mockEnvironment, testService.environment, "The injected environment should match the mocked instance."); + } + + /** + * Test default constructor. + * Verifies that the service can be instantiated without an Environment. + */ + @Test + void testDefaultConstructor() { + TestServiceImpl service = new TestServiceImpl(); + assertNull(service.environment, "The environment should be null when using the default constructor."); + } +} diff --git a/microsphere-jdk-tools/pom.xml b/microsphere-jdk-tools/pom.xml new file mode 100644 index 000000000..b0822a8de --- /dev/null +++ b/microsphere-jdk-tools/pom.xml @@ -0,0 +1,58 @@ + + + + io.github.microsphere-projects + microsphere-java-parent + ${revision} + ../microsphere-java-parent/pom.xml + + 4.0.0 + + io.github.microsphere-projects + microsphere-jdk-tools + ${revision} + jar + + Microsphere :: JDK :: Tools + Microsphere JDK Tools + + + + + + io.github.microsphere-projects + microsphere-java-core + ${revision} + + + + + org.junit.jupiter + junit-jupiter + test + + + + org.junit.jupiter + junit-jupiter-engine + test + + + + + org.mockito + mockito-core + test + + + + + ch.qos.logback + logback-classic + test + + + + \ No newline at end of file diff --git a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/Compiler.java b/microsphere-jdk-tools/src/main/java/io/microsphere/jdk/tools/compiler/Compiler.java similarity index 50% rename from microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/Compiler.java rename to microsphere-jdk-tools/src/main/java/io/microsphere/jdk/tools/compiler/Compiler.java index b8545abbc..09ab04336 100644 --- a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/Compiler.java +++ b/microsphere-jdk-tools/src/main/java/io/microsphere/jdk/tools/compiler/Compiler.java @@ -14,11 +14,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.microsphere.annotation.processor; +package io.microsphere.jdk.tools.compiler; import io.microsphere.logging.Logger; import javax.annotation.processing.Processor; +import javax.tools.DiagnosticListener; import javax.tools.JavaCompiler; import javax.tools.JavaCompiler.CompilationTask; import javax.tools.JavaFileObject; @@ -26,24 +27,35 @@ import java.io.File; import java.io.IOException; import java.net.URL; -import java.util.LinkedHashSet; +import java.nio.charset.Charset; +import java.security.CodeSource; +import java.security.ProtectionDomain; import java.util.List; +import java.util.Locale; +import java.util.Objects; import java.util.Set; import static io.microsphere.collection.CollectionUtils.addAll; import static io.microsphere.collection.CollectionUtils.first; -import static io.microsphere.collection.ListUtils.newArrayList; +import static io.microsphere.collection.CollectionUtils.isEmpty; import static io.microsphere.collection.Lists.ofList; import static io.microsphere.collection.SetUtils.newLinkedHashSet; +import static io.microsphere.collection.Sets.ofSet; import static io.microsphere.constants.FileConstants.JAVA_EXTENSION; -import static io.microsphere.constants.ProtocolConstants.FILE_PROTOCOL; import static io.microsphere.constants.SymbolConstants.DOT_CHAR; import static io.microsphere.io.scanner.SimpleFileScanner.INSTANCE; import static io.microsphere.logging.LoggerFactory.getLogger; +import static io.microsphere.text.FormatUtils.format; +import static io.microsphere.util.ArrayUtils.ofArray; import static io.microsphere.util.ClassUtils.getTypeName; import static io.microsphere.util.StringUtils.substringBefore; import static java.io.File.separatorChar; +import static java.util.Collections.emptyList; +import static java.util.Collections.emptySet; import static java.util.Collections.singleton; +import static java.util.Collections.unmodifiableList; +import static java.util.Collections.unmodifiableSet; +import static java.util.stream.Stream.of; import static javax.tools.StandardLocation.CLASS_OUTPUT; import static javax.tools.StandardLocation.SOURCE_OUTPUT; import static javax.tools.StandardLocation.SOURCE_PATH; @@ -59,136 +71,144 @@ public class Compiler { private static final Logger logger = getLogger(Compiler.class); + public static final String[] DEFAULT_OPTIONS = ofArray("-parameters", "-Xlint:unchecked", "-nowarn", "-Xlint:deprecation"); + private final Set sourcePaths; + private final File targetDirectory; + private final JavaCompiler javaCompiler; - private final StandardJavaFileManager javaFileManager; + private Set processors; + + private List options; + + private DiagnosticListener diagnosticListener; - private final Set processors = new LinkedHashSet<>(); + private Locale locale; - public Compiler() throws IOException { + private Charset charset; + + public Compiler() { this(defaultTargetDirectory()); } - public Compiler(File targetDirectory) throws IOException { + public Compiler(File targetDirectory) { this(defaultSourceDirectory(), targetDirectory); } - public Compiler(File defaultSourceDirectory, File targetDirectory) throws IOException { + public Compiler(File defaultSourceDirectory, File targetDirectory) { + options(DEFAULT_OPTIONS); this.sourcePaths = newLinkedHashSet(defaultSourceDirectory); + this.targetDirectory = targetDirectory; this.javaCompiler = getSystemJavaCompiler(); - this.javaFileManager = javaCompiler.getStandardFileManager(null, null, null); - this.javaFileManager.setLocation(SOURCE_PATH, sourcePaths); - this.javaFileManager.setLocation(CLASS_OUTPUT, singleton(targetDirectory)); - this.javaFileManager.setLocation(SOURCE_OUTPUT, singleton(targetDirectory)); } - static File defaultSourceDirectory() { - return detectSourcePath(Compiler.class); + public Compiler options(String... options) { + this.options = ofList(options); + return this; } - static File defaultRootDirectory() { - return detectRootDirectory(Compiler.class); + public Compiler sourcePaths(File... sourcePaths) { + addAll(this.sourcePaths, sourcePaths); + return this; } - static File defaultTargetDirectory() { - File dir = new File(defaultRootDirectory(), "target/generated-classes"); - dir.mkdirs(); - return dir; + public Compiler sourcePaths(Class... sourceClasses) { + for (Class sourceClass : sourceClasses) { + sourcePath(sourceClass); + } + return this; } - static File detectSourcePath(Class sourceClass) { - File rootDirectory = detectRootDirectory(sourceClass); - String javaSourceFileRelativePath = resolveJavaSourceFileRelativePath(sourceClass); - - Set sourceFiles = INSTANCE.scan(rootDirectory, true, - file -> file.getAbsolutePath().endsWith(javaSourceFileRelativePath)); - if (sourceFiles.isEmpty()) { - if (logger.isTraceEnabled()) { - logger.trace("The source files of class[name : '{}'] can't be found in the root directory[path :'{}']", - getTypeName(sourceClass), rootDirectory.getAbsolutePath()); - } - return null; + public Compiler sourcePath(Class sourceClass) { + File sourcePath = detectSourcePath(sourceClass); + if (sourcePath != null) { + return sourcePaths(sourcePath); } + return this; + } - File sourceFile = first(sourceFiles); - String javaSourceFilePath = sourceFile.getAbsolutePath(); - String javaSourcePath = substringBefore(javaSourceFilePath, javaSourceFileRelativePath); - File sourcePath = new File(javaSourcePath); + public Compiler processors(Processor... processors) { + this.processors = ofSet(processors); + return this; + } - if (logger.isTraceEnabled()) { - logger.trace("The source file[path : '{}] of class[name : '{}'] was found in the source directory[path :'{}']", - sourceFile.getAbsolutePath(), getTypeName(sourceClass), sourcePath.getAbsolutePath()); - } + public Compiler diagnosticListener(DiagnosticListener diagnosticListener) { + this.diagnosticListener = diagnosticListener; + return this; + } - return sourcePath.exists() ? sourcePath : null; + public Compiler locale(Locale locale) { + this.locale = locale; + return this; } - static File detectRootDirectory(Class sourceClass) { - File classPath = detectClassPath(sourceClass); - // classPath : "${rootDirectory}/target/classes" - File rootDirectory = classPath.getParentFile().getParentFile(); - if (logger.isTraceEnabled()) { - logger.trace("The root directory[path : '{}'] was found by the source class[name : '{}']", - rootDirectory.getAbsolutePath(), getTypeName(sourceClass)); - } - return rootDirectory; + public Compiler charset(Charset charset) { + this.charset = charset; + return this; } - static File detectClassPath(Class sourceClass) { - URL classFileURL = sourceClass.getProtectionDomain().getCodeSource().getLocation(); - if (FILE_PROTOCOL.equals(classFileURL.getProtocol())) { - return new File(classFileURL.getPath()); - } else { - throw new RuntimeException("No support"); - } + public boolean compile(Class... sourceClasses) throws IOException { + JavaCompiler javaCompiler = getJavaCompiler(); + StandardJavaFileManager javaFileManager = getJavaFileManager(); + CompilationTask task = javaCompiler.getTask(null, javaFileManager, + getDiagnosticListener(), getOptions(), null, getJavaFileObjects(javaFileManager, sourceClasses)); + task.setProcessors(this.getProcessors()); + return task.call(); } - static String resolveJavaSourceFileRelativePath(Class sourceClass) { - return sourceClass.getName().replace(DOT_CHAR, separatorChar).concat(JAVA_EXTENSION); + public JavaCompiler getJavaCompiler() { + return this.javaCompiler; } - public Compiler sourcePaths(File... sourcePaths) { - addAll(this.sourcePaths, sourcePaths); - return this; + public StandardJavaFileManager getJavaFileManager() throws IOException { + StandardJavaFileManager javaFileManager = getJavaCompiler().getStandardFileManager(getDiagnosticListener(), getLocale(), getCharset()); + javaFileManager.setLocation(SOURCE_PATH, this.sourcePaths); + javaFileManager.setLocation(CLASS_OUTPUT, singleton(this.targetDirectory)); + javaFileManager.setLocation(SOURCE_OUTPUT, singleton(this.targetDirectory)); + return javaFileManager; } - public Compiler sourcePaths(Iterable> sourceClasses) { - for (Class sourceClass : sourceClasses) { - sourcePath(sourceClass); - } - return this; + public DiagnosticListener getDiagnosticListener() { + return this.diagnosticListener; } - public Compiler sourcePath(Class sourceClass) { - File sourcePath = detectSourcePath(sourceClass); - if (sourcePath != null) { - return sourcePaths(sourcePath); - } - return this; + public Locale getLocale() { + return this.locale; } - public Compiler processors(Processor... processors) { - addAll(this.processors, processors); - return this; + public Charset getCharset() { + return this.charset; } - private Iterable getJavaFileObjects(Class... sourceClasses) { - int size = sourceClasses == null ? 0 : sourceClasses.length; - List javaSourceFiles = newArrayList(size); - for (int i = 0; i < size; i++) { - File javaSourceFile = searchJavaSourceFile(sourceClasses[i]); - if (javaSourceFile != null) { - javaSourceFiles.add(javaSourceFile); - } + public List getOptions() { + List options = this.options; + if (isEmpty(options)) { + return emptyList(); } - return javaFileManager.getJavaFileObjects(javaSourceFiles.toArray(new File[0])); + return unmodifiableList(options); + } + + public Set getProcessors() { + Set processors = this.processors; + if (processors == null) { + return emptySet(); + } + return unmodifiableSet(processors); + } + + private Iterable getJavaFileObjects(StandardJavaFileManager javaFileManager, Class... sourceClasses) { + File[] javaFiles = of(sourceClasses) + .map(this::searchJavaSourceFile) + .filter(Objects::nonNull) + .toArray(File[]::new); + return javaFileManager.getJavaFileObjects(javaFiles); } private File searchJavaSourceFile(Class sourceClass) { String javaSourceFilePath = resolveJavaSourceFileRelativePath(sourceClass); - for (File sourceDirectory : sourcePaths) { + for (File sourceDirectory : this.sourcePaths) { File javaSourceFile = new File(sourceDirectory, javaSourceFilePath); if (javaSourceFile.exists()) { return javaSourceFile; @@ -197,18 +217,63 @@ private File searchJavaSourceFile(Class sourceClass) { return null; } - public boolean compile(Class... sourceClasses) { - CompilationTask task = javaCompiler.getTask(null, this.javaFileManager, null, - ofList("-parameters", "-Xlint:unchecked", "-nowarn", "-Xlint:deprecation"), -// null, - null, getJavaFileObjects(sourceClasses)); - if (!processors.isEmpty()) { - task.setProcessors(processors); + static File defaultSourceDirectory() { + return detectSourcePath(Compiler.class); + } + + static File defaultRootDirectory() { + return detectRootDirectory(Compiler.class); + } + + static File defaultTargetDirectory() { + File dir = new File(defaultRootDirectory(), "target/generated-classes"); + dir.mkdirs(); + return dir; + } + + public static File detectSourcePath(Class sourceClass) { + File rootDirectory = detectRootDirectory(sourceClass); + String javaSourceFileRelativePath = resolveJavaSourceFileRelativePath(sourceClass); + + Set sourceFiles = INSTANCE.scan(rootDirectory, true, + file -> file.getAbsolutePath().endsWith(javaSourceFileRelativePath)); + + File sourceFile = first(sourceFiles); + if (sourceFile == null) { + logger.trace("The source files of {} can't be found in the root directory[path :'{}']", sourceClass, rootDirectory); + return null; } - return task.call(); + + String javaSourceFilePath = sourceFile.getAbsolutePath(); + String javaSourcePath = substringBefore(javaSourceFilePath, javaSourceFileRelativePath); + File sourcePath = new File(javaSourcePath); + + logger.trace("The source file[path : '{}] of {} was found in the source directory[path :'{}']", sourceFile, sourceClass, sourcePath); + + return sourcePath; } - public JavaCompiler getJavaCompiler() { - return javaCompiler; + public static File detectRootDirectory(Class sourceClass) { + File classPath = detectClassPath(sourceClass); + // classPath : "${rootDirectory}/target/classes" + File rootDirectory = classPath.getParentFile().getParentFile(); + logger.trace("The root directory[path : '{}'] was found by the source class[name : '{}']", + rootDirectory.getAbsolutePath(), getTypeName(sourceClass)); + return rootDirectory; + } + + public static File detectClassPath(Class sourceClass) { + ProtectionDomain protectionDomain = sourceClass.getProtectionDomain(); + CodeSource codeSource = protectionDomain.getCodeSource(); + if (codeSource != null) { + URL location = codeSource.getLocation(); + return new File(location.getPath()); + } + String message = format("The source {} is based on the file system, the class path can't be detected.", sourceClass); + throw new UnsupportedOperationException(message); + } + + public static String resolveJavaSourceFileRelativePath(Class sourceClass) { + return sourceClass.getName().replace(DOT_CHAR, separatorChar).concat(JAVA_EXTENSION); } -} +} \ No newline at end of file diff --git a/microsphere-jdk-tools/src/test/java/io/microsphere/jdk/tools/compiler/CompilerTest.java b/microsphere-jdk-tools/src/test/java/io/microsphere/jdk/tools/compiler/CompilerTest.java new file mode 100644 index 000000000..78023fafc --- /dev/null +++ b/microsphere-jdk-tools/src/test/java/io/microsphere/jdk/tools/compiler/CompilerTest.java @@ -0,0 +1,188 @@ +package io.microsphere.jdk.tools.compiler; + +import org.junit.jupiter.api.Test; + +import javax.annotation.processing.AbstractProcessor; +import javax.annotation.processing.Processor; +import javax.annotation.processing.RoundEnvironment; +import javax.lang.model.element.TypeElement; +import java.io.File; +import java.io.IOException; +import java.util.Set; + +import static io.microsphere.jdk.tools.compiler.Compiler.defaultRootDirectory; +import static io.microsphere.jdk.tools.compiler.Compiler.defaultSourceDirectory; +import static io.microsphere.jdk.tools.compiler.Compiler.defaultTargetDirectory; +import static io.microsphere.jdk.tools.compiler.Compiler.detectClassPath; +import static io.microsphere.jdk.tools.compiler.Compiler.detectRootDirectory; +import static io.microsphere.jdk.tools.compiler.Compiler.detectSourcePath; +import static io.microsphere.jdk.tools.compiler.Compiler.resolveJavaSourceFileRelativePath; +import static java.io.File.separatorChar; +import static java.nio.charset.StandardCharsets.UTF_8; +import static java.util.Locale.getDefault; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * Unit tests for the Compiler class + * + * @see Compiler + */ +class CompilerTest { + + @Test + void testDefaultConstructor() { + // Test default constructor which uses default target directory + Compiler compiler = new Compiler(); + + assertNotNull(compiler, "Compiler should be instantiated successfully"); + assertNotNull(compiler.getJavaCompiler(), "JavaCompiler should be initialized"); + } + + @Test + void testTargetDirectoryConstructor() { + File targetDir = new File("target/test-classes"); + targetDir.mkdirs(); // Ensure directory exists + + Compiler compiler = new Compiler(targetDir); + + assertNotNull(compiler, "Compiler should be instantiated successfully with target directory"); + assertNotNull(compiler.getJavaCompiler(), "JavaCompiler should be initialized"); + } + + @Test + void testSourceAndTargetDirectoryConstructor() { + File sourceDir = new File("src/test/java"); + File targetDir = new File("target/test-classes"); + targetDir.mkdirs(); // Ensure target directory exists + + Compiler compiler = new Compiler(sourceDir, targetDir); + + assertNotNull(compiler, "Compiler should be instantiated successfully with source and target directories"); + assertNotNull(compiler.getJavaCompiler(), "JavaCompiler should be initialized"); + } + + @Test + void testDefaultDirectories() { + // Test the static methods that determine default directories + File defaultSourceDir = defaultSourceDirectory(); + File defaultTargetDir = defaultTargetDirectory(); + File defaultRootDir = defaultRootDirectory(); + + // Root directory should exist (it's derived from the Compiler class location) + assertNotNull(defaultSourceDir, "Default source directory should not be null"); + assertNotNull(defaultRootDir, "Default root directory should not be null"); + assertTrue(defaultRootDir.exists(), "Default root directory should exist"); + + // Target directory should be created + assertNotNull(defaultTargetDir, "Default target directory should not be null"); + } + + @Test + void testDetectClassPath() { + File classPath = detectClassPath(Compiler.class); + + assertNotNull(classPath, "Detected class path should not be null"); + assertTrue(classPath.exists(), "Detected class path should exist"); + + assertThrows(UnsupportedOperationException.class, () -> detectClassPath(String.class)); + } + + @Test + void testResolveJavaSourceFileRelativePath() { + String expectedPath = Compiler.class.getName() + .replace('.', separatorChar) + .concat(".java"); + String actualPath = resolveJavaSourceFileRelativePath(Compiler.class); + + assertEquals(expectedPath, actualPath, + "Resolved Java source file relative path should match expected format"); + } + + @Test + void testSourcePathsMethod() { + File targetDir = new File("target/test-classes"); + targetDir.mkdirs(); + + Compiler compiler = new Compiler(targetDir); + + File testSourcePath = new File("src/main/java"); + Compiler result = compiler.sourcePaths(testSourcePath); + + // Verify method chaining returns the same instance + assertSame(compiler, result, "sourcePaths method should return the same instance for chaining"); + + result = compiler.sourcePaths(Compiler.class, Test.class); + assertSame(compiler, result, "sourcePaths method should return the same instance for chaining"); + } + + @Test + void testProcessorsMethod() { + File targetDir = new File("target/test-classes"); + targetDir.mkdirs(); + + Compiler compiler = new Compiler(targetDir); + Processor processor = new AbstractProcessor() { + @Override + public boolean process(Set annotations, RoundEnvironment roundEnv) { + return false; + } + }; + + Compiler result = compiler.processors(processor); + + // Verify method chaining returns the same instance + assertSame(compiler, result, "processors method should return the same instance for chaining"); + } + + @Test + void testCompile() throws IOException { + Compiler compiler = new Compiler(); + + // This would normally attempt compilation, but with mocked compiler it's safe to call + boolean result = compiler.compile(Compiler.class, Test.class); + + // For this test, we're primarily verifying the setup doesn't fail + // Actual compilation success depends on the mock setup + assertTrue(result, "Test setup completed without exceptions"); + + compiler.options() + .processors(new AbstractProcessor() { + + @Override + public boolean process(Set annotations, RoundEnvironment roundEnv) { + return false; + } + }) + .diagnosticListener(diagnostic -> { + }) + .locale(getDefault()) + .charset(UTF_8) + ; + + result = compiler.compile(Compiler.class); + + assertTrue(result, "Test setup completed without exceptions"); + } + + @Test + void testDetectRootDirectory() { + File rootDir = detectRootDirectory(Compiler.class); + + assertNotNull(rootDir, "Root directory should not be null"); + assertTrue(rootDir.exists(), "Root directory should exist"); + } + + @Test + void testDetectSourcePath() { + // This might be null if source path cannot be detected in test environment + // but the method should not throw exceptions + assertNotNull(detectSourcePath(Compiler.class), "Should be able to call detectSourcePath without errors"); + assertNotNull(detectSourcePath(CompilerTest.class), "Should be able to call detectSourcePath without errors"); + assertNull(detectSourcePath(Test.class), "Should be able to call detectSourcePath without errors"); + } +} diff --git a/microsphere-jdk-tools/src/test/resources/logback-test.xml b/microsphere-jdk-tools/src/test/resources/logback-test.xml new file mode 100644 index 000000000..e3375b74c --- /dev/null +++ b/microsphere-jdk-tools/src/test/resources/logback-test.xml @@ -0,0 +1,15 @@ + + + + + + + ${ENCODER_PATTERN} + + + + + + + + \ No newline at end of file diff --git a/microsphere-lang-model/pom.xml b/microsphere-lang-model/pom.xml new file mode 100644 index 000000000..101084931 --- /dev/null +++ b/microsphere-lang-model/pom.xml @@ -0,0 +1,95 @@ + + + + io.github.microsphere-projects + microsphere-java-parent + ${revision} + ../microsphere-java-parent/pom.xml + + 4.0.0 + + io.github.microsphere-projects + microsphere-lang-model + ${revision} + jar + + Microsphere :: Java :: Language Model + Microsphere Language Model + + + + + + io.github.microsphere-projects + microsphere-java-core + ${revision} + + + + + org.junit.jupiter + junit-jupiter + test + + + + org.junit.jupiter + junit-jupiter-engine + test + + + + + io.github.microsphere-projects + microsphere-jdk-tools + ${revision} + test + + + + + io.github.microsphere-projects + microsphere-java-test + ${revision} + test + + + + + ch.qos.logback + logback-classic + test + + + + + javax.ws.rs + javax.ws.rs-api + test + + + + + javax.xml.ws + jaxws-api + test + + + + + org.springframework + spring-context + test + + + + org.springframework + spring-web + test + + + + + \ No newline at end of file diff --git a/microsphere-annotation-processor/src/main/java/io/microsphere/annotation/processor/model/element/StringAnnotationValue.java b/microsphere-lang-model/src/main/java/io/microsphere/lang/model/element/StringAnnotationValue.java similarity index 96% rename from microsphere-annotation-processor/src/main/java/io/microsphere/annotation/processor/model/element/StringAnnotationValue.java rename to microsphere-lang-model/src/main/java/io/microsphere/lang/model/element/StringAnnotationValue.java index 42a583f75..ba92765e6 100644 --- a/microsphere-annotation-processor/src/main/java/io/microsphere/annotation/processor/model/element/StringAnnotationValue.java +++ b/microsphere-lang-model/src/main/java/io/microsphere/lang/model/element/StringAnnotationValue.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package io.microsphere.annotation.processor.model.element; +package io.microsphere.lang.model.element; import io.microsphere.annotation.Immutable; diff --git a/microsphere-annotation-processor/src/main/java/io/microsphere/annotation/processor/model/util/AnnotatedElementJSONElementVisitor.java b/microsphere-lang-model/src/main/java/io/microsphere/lang/model/util/AnnotatedElementJSONElementVisitor.java similarity index 90% rename from microsphere-annotation-processor/src/main/java/io/microsphere/annotation/processor/model/util/AnnotatedElementJSONElementVisitor.java rename to microsphere-lang-model/src/main/java/io/microsphere/lang/model/util/AnnotatedElementJSONElementVisitor.java index b5c76b0b1..e6df266ec 100644 --- a/microsphere-annotation-processor/src/main/java/io/microsphere/annotation/processor/model/util/AnnotatedElementJSONElementVisitor.java +++ b/microsphere-lang-model/src/main/java/io/microsphere/lang/model/util/AnnotatedElementJSONElementVisitor.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package io.microsphere.annotation.processor.model.util; +package io.microsphere.lang.model.util; import io.microsphere.annotation.Nonnull; @@ -29,16 +29,16 @@ import java.lang.annotation.ElementType; import java.lang.reflect.AnnotatedElement; -import static io.microsphere.annotation.processor.util.AnnotationUtils.getElementTypes; -import static io.microsphere.annotation.processor.util.ElementUtils.matchesElementType; -import static io.microsphere.annotation.processor.util.TypeUtils.getDeclaredType; +import static io.microsphere.lang.model.util.AnnotationUtils.getElementTypes; +import static io.microsphere.lang.model.util.ElementUtils.matchesElementType; +import static io.microsphere.lang.model.util.TypeUtils.getDeclaredType; import static io.microsphere.util.Assert.assertNotNull; /** * An abstract implementation of {@link ElementVisitor} that generates JSON content for elements * annotated with a specific annotation. * - *

    This class extends {@link JSONElementVisitor}, providing functionality to filter and process + *

    This class extends {@link io.microsphere.lang.model.util.JSONElementVisitor}, providing functionality to filter and process * only those elements that are annotated with the specified annotation. It leverages the annotation * processing environment to gather information about the annotated elements and constructs JSON * representations accordingly.

    @@ -79,7 +79,7 @@ * type elements annotated with a custom annotation and generates JSON output for them.

    * * @author Mercy - * @see JSONElementVisitor + * @see io.microsphere.lang.model.util.JSONElementVisitor * @see AnnotatedElement * @see Annotation * @see ElementType @@ -124,5 +124,4 @@ public final String getAnnotationClassName() { protected boolean supports(Element e) { return matchesElementType(e, this.elementTypes); } - } diff --git a/microsphere-annotation-processor/src/main/java/io/microsphere/annotation/processor/util/AnnotationUtils.java b/microsphere-lang-model/src/main/java/io/microsphere/lang/model/util/AnnotationUtils.java similarity index 98% rename from microsphere-annotation-processor/src/main/java/io/microsphere/annotation/processor/util/AnnotationUtils.java rename to microsphere-lang-model/src/main/java/io/microsphere/lang/model/util/AnnotationUtils.java index 4df0bdfc6..ea4859b76 100644 --- a/microsphere-annotation-processor/src/main/java/io/microsphere/annotation/processor/util/AnnotationUtils.java +++ b/microsphere-lang-model/src/main/java/io/microsphere/lang/model/util/AnnotationUtils.java @@ -14,12 +14,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.microsphere.annotation.processor.util; +package io.microsphere.lang.model.util; import io.microsphere.annotation.Immutable; import io.microsphere.annotation.Nonnull; import io.microsphere.annotation.Nullable; -import io.microsphere.annotation.processor.model.util.ResolvableAnnotationValueVisitor; import io.microsphere.util.Utils; import javax.annotation.processing.ProcessingEnvironment; @@ -43,20 +42,21 @@ import java.util.Objects; import java.util.function.Predicate; -import static io.microsphere.annotation.processor.util.MethodUtils.findDeclaredMethods; -import static io.microsphere.annotation.processor.util.MethodUtils.getDeclaredMethods; -import static io.microsphere.annotation.processor.util.MethodUtils.getMethodName; -import static io.microsphere.annotation.processor.util.TypeUtils.getAllTypeElements; -import static io.microsphere.annotation.processor.util.TypeUtils.getTypeElement; -import static io.microsphere.annotation.processor.util.TypeUtils.isSameType; -import static io.microsphere.annotation.processor.util.TypeUtils.ofTypeElement; import static io.microsphere.collection.CollectionUtils.isEmpty; import static io.microsphere.collection.CollectionUtils.size; +import static io.microsphere.collection.ListUtils.first; import static io.microsphere.collection.MapUtils.immutableEntry; import static io.microsphere.collection.MapUtils.isEmpty; import static io.microsphere.collection.MapUtils.newFixedLinkedHashMap; import static io.microsphere.lang.function.Predicates.EMPTY_PREDICATE_ARRAY; import static io.microsphere.lang.function.Streams.filterAll; +import static io.microsphere.lang.model.util.MethodUtils.findDeclaredMethods; +import static io.microsphere.lang.model.util.MethodUtils.getDeclaredMethods; +import static io.microsphere.lang.model.util.MethodUtils.getMethodName; +import static io.microsphere.lang.model.util.TypeUtils.getAllTypeElements; +import static io.microsphere.lang.model.util.TypeUtils.getTypeElement; +import static io.microsphere.lang.model.util.TypeUtils.isSameType; +import static io.microsphere.lang.model.util.TypeUtils.ofTypeElement; import static io.microsphere.util.ArrayUtils.isNotEmpty; import static io.microsphere.util.StringUtils.isBlank; import static java.util.Collections.emptyList; @@ -170,7 +170,7 @@ static AnnotationMirror getAnnotation(AnnotatedConstruct annotatedConstruct, Cha return null; } List annotations = getAnnotations(annotatedConstruct, annotationClassName); - return annotations.isEmpty() ? null : annotations.get(0); + return first(annotations); } /** @@ -607,7 +607,7 @@ static AnnotationMirror findAnnotation(Element element, CharSequence annotationC return null; } List annotations = findAllAnnotations(element, annotation -> matchesAnnotationTypeName(annotation, annotationClassName)); - return isEmpty(annotations) ? null : annotations.get(0); + return first(annotations); } /** @@ -1142,7 +1142,10 @@ static boolean matchesAttributeValue(AnnotationValue annotationValue, Object att * {@code false} otherwise */ static boolean matchesDefaultAttributeValue(ExecutableElement attributeMethod, AnnotationValue annotationValue) { - return attributeMethod != null && matchesAttributeValue(attributeMethod.getDefaultValue(), annotationValue); + if (attributeMethod == null) { + return false; + } + return matchesAttributeValue(attributeMethod.getDefaultValue(), annotationValue); } /** @@ -1582,17 +1585,18 @@ static Entry getElementValue(AnnotationMirro if (withDefault && annotationValue == null) { // not found if the default value is required DeclaredType annotationType = annotation.getAnnotationType(); - List attributeMethods = findDeclaredMethods(annotationType, method -> !elementValues.containsKey(method)); - int size = attributeMethods.size(); - for (int i = 0; i < size; i++) { - attributeMethod = attributeMethods.get(i); - if (matchesAttributeMethod(attributeMethod, attributeName)) { - annotationValue = attributeMethod.getDefaultValue(); - break; - } + List attributeMethods = findDeclaredMethods(annotationType, method -> + !elementValues.containsKey(method) && matchesAttributeMethod(method, attributeName)); + attributeMethod = first(attributeMethods); + if (attributeMethod != null) { + annotationValue = attributeMethod.getDefaultValue(); } } + if (annotationValue == null) { + return null; + } + return immutableEntry(attributeMethod, annotationValue); } diff --git a/microsphere-annotation-processor/src/main/java/io/microsphere/annotation/processor/util/ClassUtils.java b/microsphere-lang-model/src/main/java/io/microsphere/lang/model/util/ClassUtils.java similarity index 97% rename from microsphere-annotation-processor/src/main/java/io/microsphere/annotation/processor/util/ClassUtils.java rename to microsphere-lang-model/src/main/java/io/microsphere/lang/model/util/ClassUtils.java index 77988604c..7b83b0c99 100644 --- a/microsphere-annotation-processor/src/main/java/io/microsphere/annotation/processor/util/ClassUtils.java +++ b/microsphere-lang-model/src/main/java/io/microsphere/lang/model/util/ClassUtils.java @@ -15,15 +15,15 @@ * limitations under the License. */ -package io.microsphere.annotation.processor.util; +package io.microsphere.lang.model.util; import io.microsphere.util.Utils; import javax.lang.model.type.TypeMirror; -import static io.microsphere.annotation.processor.util.TypeUtils.ofTypeElement; import static io.microsphere.constants.SymbolConstants.DOLLAR_CHAR; import static io.microsphere.constants.SymbolConstants.DOT_CHAR; +import static io.microsphere.lang.model.util.TypeUtils.ofTypeElement; import static io.microsphere.util.ClassLoaderUtils.getClassLoader; import static io.microsphere.util.ClassLoaderUtils.resolveClass; diff --git a/microsphere-annotation-processor/src/main/java/io/microsphere/annotation/processor/util/ConstructorUtils.java b/microsphere-lang-model/src/main/java/io/microsphere/lang/model/util/ConstructorUtils.java similarity index 97% rename from microsphere-annotation-processor/src/main/java/io/microsphere/annotation/processor/util/ConstructorUtils.java rename to microsphere-lang-model/src/main/java/io/microsphere/lang/model/util/ConstructorUtils.java index e19f43845..c864c1c7d 100644 --- a/microsphere-annotation-processor/src/main/java/io/microsphere/annotation/processor/util/ConstructorUtils.java +++ b/microsphere-lang-model/src/main/java/io/microsphere/lang/model/util/ConstructorUtils.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package io.microsphere.annotation.processor.util; +package io.microsphere.lang.model.util; import io.microsphere.annotation.Immutable; import io.microsphere.annotation.Nonnull; @@ -32,12 +32,12 @@ import java.util.List; import java.util.function.Predicate; -import static io.microsphere.annotation.processor.util.ElementUtils.filterElements; -import static io.microsphere.annotation.processor.util.ElementUtils.matchParameterTypes; -import static io.microsphere.annotation.processor.util.MemberUtils.getDeclaredMembers; import static io.microsphere.collection.CollectionUtils.isEmpty; import static io.microsphere.collection.ListUtils.first; import static io.microsphere.lang.function.Predicates.EMPTY_PREDICATE_ARRAY; +import static io.microsphere.lang.model.util.ElementUtils.filterElements; +import static io.microsphere.lang.model.util.ElementUtils.matchParameterTypes; +import static io.microsphere.lang.model.util.MemberUtils.getDeclaredMembers; import static java.util.Collections.emptyList; import static javax.lang.model.util.ElementFilter.constructorsIn; diff --git a/microsphere-annotation-processor/src/main/java/io/microsphere/annotation/processor/util/ElementUtils.java b/microsphere-lang-model/src/main/java/io/microsphere/lang/model/util/ElementUtils.java similarity index 99% rename from microsphere-annotation-processor/src/main/java/io/microsphere/annotation/processor/util/ElementUtils.java rename to microsphere-lang-model/src/main/java/io/microsphere/lang/model/util/ElementUtils.java index a6d7db851..f24373a19 100644 --- a/microsphere-annotation-processor/src/main/java/io/microsphere/annotation/processor/util/ElementUtils.java +++ b/microsphere-lang-model/src/main/java/io/microsphere/lang/model/util/ElementUtils.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package io.microsphere.annotation.processor.util; +package io.microsphere.lang.model.util; import io.microsphere.annotation.Immutable; import io.microsphere.annotation.Nonnull; @@ -32,9 +32,9 @@ import java.util.Set; import java.util.function.Predicate; -import static io.microsphere.annotation.processor.util.TypeUtils.isSameType; import static io.microsphere.collection.CollectionUtils.isEmpty; import static io.microsphere.lang.function.Predicates.and; +import static io.microsphere.lang.model.util.TypeUtils.isSameType; import static io.microsphere.reflect.TypeUtils.getTypeNames; import static io.microsphere.util.ArrayUtils.isNotEmpty; import static io.microsphere.util.ArrayUtils.length; diff --git a/microsphere-annotation-processor/src/main/java/io/microsphere/annotation/processor/util/ExecutableElementComparator.java b/microsphere-lang-model/src/main/java/io/microsphere/lang/model/util/ExecutableElementComparator.java similarity index 98% rename from microsphere-annotation-processor/src/main/java/io/microsphere/annotation/processor/util/ExecutableElementComparator.java rename to microsphere-lang-model/src/main/java/io/microsphere/lang/model/util/ExecutableElementComparator.java index c7e561224..ead937db0 100644 --- a/microsphere-annotation-processor/src/main/java/io/microsphere/annotation/processor/util/ExecutableElementComparator.java +++ b/microsphere-lang-model/src/main/java/io/microsphere/lang/model/util/ExecutableElementComparator.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.microsphere.annotation.processor.util; +package io.microsphere.lang.model.util; import io.microsphere.util.CharSequenceComparator; diff --git a/microsphere-annotation-processor/src/main/java/io/microsphere/annotation/processor/util/FieldUtils.java b/microsphere-lang-model/src/main/java/io/microsphere/lang/model/util/FieldUtils.java similarity index 98% rename from microsphere-annotation-processor/src/main/java/io/microsphere/annotation/processor/util/FieldUtils.java rename to microsphere-lang-model/src/main/java/io/microsphere/lang/model/util/FieldUtils.java index f1c195fd9..b14dd47a1 100644 --- a/microsphere-annotation-processor/src/main/java/io/microsphere/annotation/processor/util/FieldUtils.java +++ b/microsphere-lang-model/src/main/java/io/microsphere/lang/model/util/FieldUtils.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.microsphere.annotation.processor.util; +package io.microsphere.lang.model.util; import io.microsphere.annotation.Immutable; import io.microsphere.annotation.Nonnull; @@ -29,14 +29,14 @@ import java.util.List; import java.util.function.Predicate; -import static io.microsphere.annotation.processor.util.ElementUtils.filterElements; -import static io.microsphere.annotation.processor.util.ElementUtils.hasModifiers; -import static io.microsphere.annotation.processor.util.ElementUtils.matchesElementKind; -import static io.microsphere.annotation.processor.util.MemberUtils.getDeclaredMembers; -import static io.microsphere.annotation.processor.util.TypeUtils.isEnumType; import static io.microsphere.collection.CollectionUtils.isEmpty; import static io.microsphere.lang.function.Predicates.EMPTY_PREDICATE_ARRAY; import static io.microsphere.lang.function.Streams.filterFirst; +import static io.microsphere.lang.model.util.ElementUtils.filterElements; +import static io.microsphere.lang.model.util.ElementUtils.hasModifiers; +import static io.microsphere.lang.model.util.ElementUtils.matchesElementKind; +import static io.microsphere.lang.model.util.MemberUtils.getDeclaredMembers; +import static io.microsphere.lang.model.util.TypeUtils.isEnumType; import static java.util.Collections.emptyList; import static javax.lang.model.element.ElementKind.ENUM_CONSTANT; import static javax.lang.model.element.ElementKind.FIELD; diff --git a/microsphere-annotation-processor/src/main/java/io/microsphere/annotation/processor/model/util/JSONAnnotationValueVisitor.java b/microsphere-lang-model/src/main/java/io/microsphere/lang/model/util/JSONAnnotationValueVisitor.java similarity index 96% rename from microsphere-annotation-processor/src/main/java/io/microsphere/annotation/processor/model/util/JSONAnnotationValueVisitor.java rename to microsphere-lang-model/src/main/java/io/microsphere/lang/model/util/JSONAnnotationValueVisitor.java index 327c954b0..01b074447 100644 --- a/microsphere-annotation-processor/src/main/java/io/microsphere/annotation/processor/model/util/JSONAnnotationValueVisitor.java +++ b/microsphere-lang-model/src/main/java/io/microsphere/lang/model/util/JSONAnnotationValueVisitor.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package io.microsphere.annotation.processor.model.util; +package io.microsphere.lang.model.util; import javax.lang.model.element.AnnotationMirror; import javax.lang.model.element.AnnotationValue; @@ -28,9 +28,6 @@ import java.util.Map; import java.util.Map.Entry; -import static io.microsphere.annotation.processor.util.AnnotationUtils.getAttributeName; -import static io.microsphere.annotation.processor.util.AnnotationUtils.getElementValues; -import static io.microsphere.annotation.processor.util.TypeUtils.getTypeName; import static io.microsphere.constants.SymbolConstants.COMMA_CHAR; import static io.microsphere.constants.SymbolConstants.LEFT_CURLY_BRACE_CHAR; import static io.microsphere.constants.SymbolConstants.LEFT_SQUARE_BRACKET_CHAR; @@ -38,6 +35,9 @@ import static io.microsphere.constants.SymbolConstants.RIGHT_SQUARE_BRACKET_CHAR; import static io.microsphere.json.JSONUtils.append; import static io.microsphere.json.JSONUtils.appendName; +import static io.microsphere.lang.model.util.AnnotationUtils.getAttributeName; +import static io.microsphere.lang.model.util.AnnotationUtils.getElementValues; +import static io.microsphere.lang.model.util.TypeUtils.getTypeName; /** * A visitor implementation for converting {@link AnnotationValue} objects into JSON-formatted strings. @@ -78,7 +78,6 @@ public JSONAnnotationValueVisitor(StringBuilder jsonBuilder) { this.jsonBuilder = jsonBuilder; } - @Override public StringBuilder visitBoolean(boolean value, ExecutableElement attributeMethod) { append(jsonBuilder, getAttributeName(attributeMethod), value); diff --git a/microsphere-annotation-processor/src/main/java/io/microsphere/annotation/processor/model/util/JSONElementVisitor.java b/microsphere-lang-model/src/main/java/io/microsphere/lang/model/util/JSONElementVisitor.java similarity index 90% rename from microsphere-annotation-processor/src/main/java/io/microsphere/annotation/processor/model/util/JSONElementVisitor.java rename to microsphere-lang-model/src/main/java/io/microsphere/lang/model/util/JSONElementVisitor.java index 99856edb3..416eafce3 100644 --- a/microsphere-annotation-processor/src/main/java/io/microsphere/annotation/processor/model/util/JSONElementVisitor.java +++ b/microsphere-lang-model/src/main/java/io/microsphere/lang/model/util/JSONElementVisitor.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package io.microsphere.annotation.processor.model.util; +package io.microsphere.lang.model.util; import javax.lang.model.element.Element; import javax.lang.model.element.ElementVisitor; @@ -62,26 +62,36 @@ public JSONElementVisitor() { @Override public final Boolean visitPackage(PackageElement e, StringBuilder jsonBuilder) { - return supportsPackage(e) && doVisitPackage(e, jsonBuilder); + if (!supportsPackage(e)) { + return false; + } + return doVisitPackage(e, jsonBuilder); } @Override public final Boolean visitVariable(VariableElement e, StringBuilder stringBuilder) { - return supportsVariable(e) && super.visitVariable(e, stringBuilder); + if (!supportsVariable(e)) { + return false; + } + return super.visitVariable(e, stringBuilder); } @Override public final Boolean visitExecutable(ExecutableElement e, StringBuilder jsonBuilder) { - return supportsExecutable(e) && super.visitExecutable(e, jsonBuilder); + if (!supportsExecutable(e)) { + return false; + } + return super.visitExecutable(e, jsonBuilder); } @Override public final Boolean visitType(TypeElement e, StringBuilder jsonBuilder) { - boolean appended = false; - if (supportsType(e) && super.visitType(e, jsonBuilder)) { - appended = true; + if (!supportsType(e)) { + return false; } + boolean appended = super.visitType(e, jsonBuilder); + // The declared members of the type element if (visitMembers(e.getEnclosedElements(), jsonBuilder)) { appended = true; @@ -92,21 +102,10 @@ public final Boolean visitType(TypeElement e, StringBuilder jsonBuilder) { @Override public final Boolean visitTypeParameter(TypeParameterElement e, StringBuilder jsonBuilder) { - if (!supports(e)) { - return FALSE; + if (!supportsTypeParameter(e)) { + return false; } - - boolean appended = false; - if (supportsTypeParameter(e) && doVisitTypeParameter(e, jsonBuilder)) { - appended = true; - } - - // The declared members of the type element - if (visitMembers(e.getEnclosedElements(), jsonBuilder)) { - appended = true; - } - - return appended; + return doVisitTypeParameter(e, jsonBuilder); } protected boolean visitMembers(List members, StringBuilder jsonBuilder) { @@ -218,4 +217,4 @@ protected boolean doVisitPackage(PackageElement e, StringBuilder jsonBuilder) { protected boolean doVisitTypeParameter(TypeParameterElement e, StringBuilder jsonBuilder) { return super.visitTypeParameter(e, jsonBuilder); } -} +} \ No newline at end of file diff --git a/microsphere-annotation-processor/src/main/java/io/microsphere/annotation/processor/util/LoggerUtils.java b/microsphere-lang-model/src/main/java/io/microsphere/lang/model/util/LoggerUtils.java similarity index 93% rename from microsphere-annotation-processor/src/main/java/io/microsphere/annotation/processor/util/LoggerUtils.java rename to microsphere-lang-model/src/main/java/io/microsphere/lang/model/util/LoggerUtils.java index 17b69dbeb..4fed09a7f 100644 --- a/microsphere-annotation-processor/src/main/java/io/microsphere/annotation/processor/util/LoggerUtils.java +++ b/microsphere-lang-model/src/main/java/io/microsphere/lang/model/util/LoggerUtils.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.microsphere.annotation.processor.util; +package io.microsphere.lang.model.util; import io.microsphere.logging.Logger; @@ -30,7 +30,7 @@ */ public interface LoggerUtils extends Utils { - Logger LOGGER = getLogger("microsphere-annotation-processor"); + Logger LOGGER = getLogger("microsphere-lang-model"); static void trace(String format, Object... args) { LOGGER.trace(format, args); diff --git a/microsphere-annotation-processor/src/main/java/io/microsphere/annotation/processor/util/MemberUtils.java b/microsphere-lang-model/src/main/java/io/microsphere/lang/model/util/MemberUtils.java similarity index 98% rename from microsphere-annotation-processor/src/main/java/io/microsphere/annotation/processor/util/MemberUtils.java rename to microsphere-lang-model/src/main/java/io/microsphere/lang/model/util/MemberUtils.java index 46c1d9270..77f027a4f 100644 --- a/microsphere-annotation-processor/src/main/java/io/microsphere/annotation/processor/util/MemberUtils.java +++ b/microsphere-lang-model/src/main/java/io/microsphere/lang/model/util/MemberUtils.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.microsphere.annotation.processor.util; +package io.microsphere.lang.model.util; import io.microsphere.annotation.Immutable; import io.microsphere.annotation.Nonnull; @@ -27,10 +27,10 @@ import java.util.List; import java.util.function.Predicate; -import static io.microsphere.annotation.processor.util.ElementUtils.filterElements; -import static io.microsphere.annotation.processor.util.TypeUtils.getAllDeclaredTypes; -import static io.microsphere.annotation.processor.util.TypeUtils.ofTypeElement; import static io.microsphere.lang.function.Predicates.EMPTY_PREDICATE_ARRAY; +import static io.microsphere.lang.model.util.ElementUtils.filterElements; +import static io.microsphere.lang.model.util.TypeUtils.getAllDeclaredTypes; +import static io.microsphere.lang.model.util.TypeUtils.ofTypeElement; import static java.util.Collections.emptyList; import static java.util.stream.Collectors.toList; diff --git a/microsphere-annotation-processor/src/main/java/io/microsphere/annotation/processor/util/MessagerUtils.java b/microsphere-lang-model/src/main/java/io/microsphere/lang/model/util/MessagerUtils.java similarity index 97% rename from microsphere-annotation-processor/src/main/java/io/microsphere/annotation/processor/util/MessagerUtils.java rename to microsphere-lang-model/src/main/java/io/microsphere/lang/model/util/MessagerUtils.java index 7668c478d..63ad95180 100644 --- a/microsphere-annotation-processor/src/main/java/io/microsphere/annotation/processor/util/MessagerUtils.java +++ b/microsphere-lang-model/src/main/java/io/microsphere/lang/model/util/MessagerUtils.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package io.microsphere.annotation.processor.util; +package io.microsphere.lang.model.util; import io.microsphere.util.Utils; @@ -23,10 +23,10 @@ import javax.annotation.processing.ProcessingEnvironment; import javax.tools.Diagnostic.Kind; -import static io.microsphere.annotation.processor.util.LoggerUtils.debug; -import static io.microsphere.annotation.processor.util.LoggerUtils.error; -import static io.microsphere.annotation.processor.util.LoggerUtils.info; -import static io.microsphere.annotation.processor.util.LoggerUtils.warn; +import static io.microsphere.lang.model.util.LoggerUtils.debug; +import static io.microsphere.lang.model.util.LoggerUtils.error; +import static io.microsphere.lang.model.util.LoggerUtils.info; +import static io.microsphere.lang.model.util.LoggerUtils.warn; import static io.microsphere.text.FormatUtils.format; import static javax.tools.Diagnostic.Kind.ERROR; import static javax.tools.Diagnostic.Kind.MANDATORY_WARNING; diff --git a/microsphere-annotation-processor/src/main/java/io/microsphere/annotation/processor/util/MethodUtils.java b/microsphere-lang-model/src/main/java/io/microsphere/lang/model/util/MethodUtils.java similarity index 98% rename from microsphere-annotation-processor/src/main/java/io/microsphere/annotation/processor/util/MethodUtils.java rename to microsphere-lang-model/src/main/java/io/microsphere/lang/model/util/MethodUtils.java index 510f73f59..de250a897 100644 --- a/microsphere-annotation-processor/src/main/java/io/microsphere/annotation/processor/util/MethodUtils.java +++ b/microsphere-lang-model/src/main/java/io/microsphere/lang/model/util/MethodUtils.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.microsphere.annotation.processor.util; +package io.microsphere.lang.model.util; import io.microsphere.annotation.Immutable; @@ -34,17 +34,18 @@ import java.util.Objects; import java.util.function.Predicate; -import static io.microsphere.annotation.processor.util.ElementUtils.filterElements; -import static io.microsphere.annotation.processor.util.ElementUtils.isPublicNonStatic; -import static io.microsphere.annotation.processor.util.ElementUtils.matchParameterTypeNames; -import static io.microsphere.annotation.processor.util.ElementUtils.matchParameterTypes; -import static io.microsphere.annotation.processor.util.MemberUtils.getDeclaredMembers; -import static io.microsphere.annotation.processor.util.TypeUtils.isSameType; -import static io.microsphere.annotation.processor.util.TypeUtils.ofDeclaredType; import static io.microsphere.collection.CollectionUtils.isEmpty; +import static io.microsphere.collection.ListUtils.first; import static io.microsphere.lang.function.Predicates.EMPTY_PREDICATE_ARRAY; import static io.microsphere.lang.function.Predicates.and; import static io.microsphere.lang.function.Streams.filterFirst; +import static io.microsphere.lang.model.util.ElementUtils.filterElements; +import static io.microsphere.lang.model.util.ElementUtils.isPublicNonStatic; +import static io.microsphere.lang.model.util.ElementUtils.matchParameterTypeNames; +import static io.microsphere.lang.model.util.ElementUtils.matchParameterTypes; +import static io.microsphere.lang.model.util.MemberUtils.getDeclaredMembers; +import static io.microsphere.lang.model.util.TypeUtils.isSameType; +import static io.microsphere.lang.model.util.TypeUtils.ofDeclaredType; import static io.microsphere.util.ArrayUtils.EMPTY_STRING_ARRAY; import static io.microsphere.util.ArrayUtils.EMPTY_TYPE_ARRAY; import static io.microsphere.util.ArrayUtils.isNotEmpty; @@ -666,7 +667,7 @@ static ExecutableElement findMethod(TypeMirror type, String methodName, Type... return null; } List allDeclaredMethods = findAllDeclaredMethods(type, method -> matches(method, methodName, parameterTypes)); - return allDeclaredMethods.isEmpty() ? null : allDeclaredMethods.get(0); + return first(allDeclaredMethods); } /** @@ -730,7 +731,7 @@ static ExecutableElement findMethod(TypeMirror type, String methodName, CharSequ return null; } List allDeclaredMethods = findAllDeclaredMethods(type, method -> matches(method, methodName, parameterTypeNames)); - return allDeclaredMethods.isEmpty() ? null : allDeclaredMethods.get(0); + return first(allDeclaredMethods); } /** diff --git a/microsphere-annotation-processor/src/main/java/io/microsphere/annotation/processor/model/util/ResolvableAnnotationValueVisitor.java b/microsphere-lang-model/src/main/java/io/microsphere/lang/model/util/ResolvableAnnotationValueVisitor.java similarity index 95% rename from microsphere-annotation-processor/src/main/java/io/microsphere/annotation/processor/model/util/ResolvableAnnotationValueVisitor.java rename to microsphere-lang-model/src/main/java/io/microsphere/lang/model/util/ResolvableAnnotationValueVisitor.java index 888c2f7aa..86bce41b5 100644 --- a/microsphere-annotation-processor/src/main/java/io/microsphere/annotation/processor/model/util/ResolvableAnnotationValueVisitor.java +++ b/microsphere-lang-model/src/main/java/io/microsphere/lang/model/util/ResolvableAnnotationValueVisitor.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package io.microsphere.annotation.processor.model.util; +package io.microsphere.lang.model.util; import javax.lang.model.element.AnnotationMirror; import javax.lang.model.element.AnnotationValue; @@ -30,10 +30,10 @@ import java.util.Map; import java.util.Map.Entry; -import static io.microsphere.annotation.processor.util.AnnotationUtils.getAttributeName; -import static io.microsphere.annotation.processor.util.AnnotationUtils.getElementValues; -import static io.microsphere.annotation.processor.util.ClassUtils.loadClass; import static io.microsphere.collection.MapUtils.newFixedLinkedHashMap; +import static io.microsphere.lang.model.util.AnnotationUtils.getAttributeName; +import static io.microsphere.lang.model.util.AnnotationUtils.getElementValues; +import static io.microsphere.lang.model.util.ClassUtils.loadClass; import static io.microsphere.reflect.MethodUtils.findMethod; import static io.microsphere.reflect.MethodUtils.invokeStaticMethod; import static io.microsphere.util.ArrayUtils.newArray; diff --git a/microsphere-annotation-processor/src/main/java/io/microsphere/annotation/processor/util/TypeUtils.java b/microsphere-lang-model/src/main/java/io/microsphere/lang/model/util/TypeUtils.java similarity index 99% rename from microsphere-annotation-processor/src/main/java/io/microsphere/annotation/processor/util/TypeUtils.java rename to microsphere-lang-model/src/main/java/io/microsphere/lang/model/util/TypeUtils.java index 829ed464c..1da76f704 100644 --- a/microsphere-annotation-processor/src/main/java/io/microsphere/annotation/processor/util/TypeUtils.java +++ b/microsphere-lang-model/src/main/java/io/microsphere/lang/model/util/TypeUtils.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.microsphere.annotation.processor.util; +package io.microsphere.lang.model.util; import io.microsphere.annotation.Immutable; import io.microsphere.annotation.Nonnull; @@ -579,7 +579,10 @@ static boolean isTypeElement(Element element) { */ static boolean isTypeElement(TypeMirror type) { DeclaredType declaredType = ofDeclaredType(type); - return declaredType != null && isTypeElement(declaredType.asElement()); + if (declaredType == null) { + return false; + } + return isTypeElement(declaredType.asElement()); } /** diff --git a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/model/element/StringAnnotationValueTest.java b/microsphere-lang-model/src/test/java/io/microsphere/lang/model/element/StringAnnotationValueTest.java similarity index 91% rename from microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/model/element/StringAnnotationValueTest.java rename to microsphere-lang-model/src/test/java/io/microsphere/lang/model/element/StringAnnotationValueTest.java index 6e96fb50a..df77ef12c 100644 --- a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/model/element/StringAnnotationValueTest.java +++ b/microsphere-lang-model/src/test/java/io/microsphere/lang/model/element/StringAnnotationValueTest.java @@ -15,10 +15,10 @@ * limitations under the License. */ -package io.microsphere.annotation.processor.model.element; +package io.microsphere.lang.model.element; -import io.microsphere.annotation.processor.model.util.ResolvableAnnotationValueVisitor; +import io.microsphere.lang.model.util.ResolvableAnnotationValueVisitor; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/microsphere-lang-model/src/test/java/io/microsphere/lang/model/util/AnnotatedElementJSONElementVisitorTest.java b/microsphere-lang-model/src/test/java/io/microsphere/lang/model/util/AnnotatedElementJSONElementVisitorTest.java new file mode 100644 index 000000000..3dd0cc74c --- /dev/null +++ b/microsphere-lang-model/src/test/java/io/microsphere/lang/model/util/AnnotatedElementJSONElementVisitorTest.java @@ -0,0 +1,52 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 io.microsphere.lang.model.util; + + +import org.junit.jupiter.api.Test; + +import javax.lang.model.element.ExecutableElement; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * {@link AnnotatedElementJSONElementVisitor} Test + * + * @author Mercy + * @see AnnotatedElementJSONElementVisitor + * @since 1.0.0 + */ +class AnnotatedElementJSONElementVisitorTest extends UtilTest { + + @Test + void test() { + String annotationClassName = Test.class.getName(); + AnnotatedElementJSONElementVisitor visitor = new AnnotatedElementJSONElementVisitor(super.processingEnv, annotationClassName) { + }; + + assertEquals(annotationClassName, visitor.getAnnotationClassName()); + + ExecutableElement testMethod = getMethod(AnnotatedElementJSONElementVisitorTest.class, "test"); + assertTrue(visitor.supports(testMethod)); + assertFalse(visitor.supports(super.testTypeElement)); + assertFalse(visitor.supports(NULL_ELEMENT)); + } + +} \ No newline at end of file diff --git a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/util/AnnotationUtilsTest.java b/microsphere-lang-model/src/test/java/io/microsphere/lang/model/util/AnnotationUtilsTest.java similarity index 68% rename from microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/util/AnnotationUtilsTest.java rename to microsphere-lang-model/src/test/java/io/microsphere/lang/model/util/AnnotationUtilsTest.java index 7aae66dc0..5b01b35da 100644 --- a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/util/AnnotationUtilsTest.java +++ b/microsphere-lang-model/src/test/java/io/microsphere/lang/model/util/AnnotationUtilsTest.java @@ -14,14 +14,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.microsphere.annotation.processor.util; - -import io.microsphere.annotation.processor.AbstractAnnotationProcessingTest; -import io.microsphere.annotation.processor.TestAnnotation; -import io.microsphere.annotation.processor.TestService; -import io.microsphere.annotation.processor.TestServiceImpl; -import io.microsphere.annotation.processor.model.Model; -import io.microsphere.annotation.processor.model.element.StringAnnotationValue; +package io.microsphere.lang.model.util; + +import io.microsphere.lang.model.element.StringAnnotationValue; +import io.microsphere.test.annotation.TestAnnotation; +import io.microsphere.test.model.Model; +import io.microsphere.test.service.TestService; +import io.microsphere.test.service.TestServiceImpl; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.Cacheable; @@ -52,40 +51,42 @@ import java.util.Map; import java.util.Map.Entry; -import static io.microsphere.annotation.processor.util.AnnotationUtils.EMPTY_ELEMENT_TYPE_ARRAY; -import static io.microsphere.annotation.processor.util.AnnotationUtils.findAllAnnotations; -import static io.microsphere.annotation.processor.util.AnnotationUtils.findAnnotation; -import static io.microsphere.annotation.processor.util.AnnotationUtils.findAnnotations; -import static io.microsphere.annotation.processor.util.AnnotationUtils.findMetaAnnotation; -import static io.microsphere.annotation.processor.util.AnnotationUtils.getAllAnnotations; -import static io.microsphere.annotation.processor.util.AnnotationUtils.getAnnotation; -import static io.microsphere.annotation.processor.util.AnnotationUtils.getAnnotations; -import static io.microsphere.annotation.processor.util.AnnotationUtils.getAttribute; -import static io.microsphere.annotation.processor.util.AnnotationUtils.getAttributeName; -import static io.microsphere.annotation.processor.util.AnnotationUtils.getAttributesMap; -import static io.microsphere.annotation.processor.util.AnnotationUtils.getElementTypes; -import static io.microsphere.annotation.processor.util.AnnotationUtils.getElementValue; -import static io.microsphere.annotation.processor.util.AnnotationUtils.getElementValues; -import static io.microsphere.annotation.processor.util.AnnotationUtils.getValue; -import static io.microsphere.annotation.processor.util.AnnotationUtils.isAnnotationPresent; -import static io.microsphere.annotation.processor.util.AnnotationUtils.matchesAnnotationTypeName; -import static io.microsphere.annotation.processor.util.AnnotationUtils.matchesAttributeMethod; -import static io.microsphere.annotation.processor.util.AnnotationUtils.matchesAttributeValue; -import static io.microsphere.annotation.processor.util.AnnotationUtils.matchesDefaultAttributeValue; -import static io.microsphere.annotation.processor.util.FieldUtils.findField; -import static io.microsphere.annotation.processor.util.MethodUtils.findMethod; -import static io.microsphere.annotation.processor.util.MethodUtils.getAllDeclaredMethods; import static io.microsphere.lang.function.Predicates.alwaysFalse; import static io.microsphere.lang.function.Predicates.alwaysTrue; +import static io.microsphere.lang.model.util.AnnotationUtils.EMPTY_ELEMENT_TYPE_ARRAY; +import static io.microsphere.lang.model.util.AnnotationUtils.findAllAnnotations; +import static io.microsphere.lang.model.util.AnnotationUtils.findAnnotation; +import static io.microsphere.lang.model.util.AnnotationUtils.findAnnotations; +import static io.microsphere.lang.model.util.AnnotationUtils.findMetaAnnotation; +import static io.microsphere.lang.model.util.AnnotationUtils.getAllAnnotations; +import static io.microsphere.lang.model.util.AnnotationUtils.getAnnotation; +import static io.microsphere.lang.model.util.AnnotationUtils.getAnnotations; +import static io.microsphere.lang.model.util.AnnotationUtils.getAttribute; +import static io.microsphere.lang.model.util.AnnotationUtils.getAttributeName; +import static io.microsphere.lang.model.util.AnnotationUtils.getAttributesMap; +import static io.microsphere.lang.model.util.AnnotationUtils.getElementTypes; +import static io.microsphere.lang.model.util.AnnotationUtils.getElementValue; +import static io.microsphere.lang.model.util.AnnotationUtils.getElementValues; +import static io.microsphere.lang.model.util.AnnotationUtils.getValue; +import static io.microsphere.lang.model.util.AnnotationUtils.isAnnotationPresent; +import static io.microsphere.lang.model.util.AnnotationUtils.matchesAnnotationTypeName; +import static io.microsphere.lang.model.util.AnnotationUtils.matchesAttributeMethod; +import static io.microsphere.lang.model.util.AnnotationUtils.matchesAttributeValue; +import static io.microsphere.lang.model.util.AnnotationUtils.matchesDefaultAttributeValue; +import static io.microsphere.lang.model.util.FieldUtils.findField; +import static io.microsphere.lang.model.util.MethodUtils.findMethod; +import static io.microsphere.lang.model.util.MethodUtils.getAllDeclaredMethods; import static io.microsphere.util.ArrayUtils.EMPTY_STRING_ARRAY; import static io.microsphere.util.ArrayUtils.ofArray; import static io.microsphere.util.StringUtils.EMPTY_STRING; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.TYPE; import static java.util.Collections.emptyMap; +import static javax.xml.ws.Service.Mode.PAYLOAD; import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertSame; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -96,7 +97,7 @@ * @author Mercy * @since 1.0.0 */ -class AnnotationUtilsTest extends AbstractAnnotationProcessingTest { +class AnnotationUtilsTest extends UtilTest { @Test void testGetAnnotation() { @@ -110,21 +111,21 @@ void testGetAnnotationWithClassName() { @Test void testGetAnnotationOnNull() { - assertNull(getAnnotation(testTypeElement, NULL_CLASS)); - assertNull(getAnnotation(testTypeElement.asType(), NULL_CLASS)); + assertNull(getAnnotation(super.testTypeElement, NULL_CLASS)); + assertNull(getAnnotation(super.testTypeElement.asType(), NULL_CLASS)); assertNull(getAnnotation(NULL_ANNOTATED_CONSTRUCT, NULL_CLASS)); } @Test void testGetAnnotationWithClassNameOnNull() { - assertNull(getAnnotation(testTypeElement, NULL_STRING)); - assertNull(getAnnotation(testTypeElement.asType(), NULL_STRING)); + assertNull(getAnnotation(super.testTypeElement, NULL_STRING)); + assertNull(getAnnotation(super.testTypeElement.asType(), NULL_STRING)); assertNull(getAnnotation(NULL_ANNOTATED_CONSTRUCT, NULL_STRING)); } @Test void testGetAnnotations() { - List annotations = getAnnotations(testTypeElement); + List annotations = getAnnotations(super.testTypeElement); assertEquals(4, annotations.size()); assertAnnotation(annotations.get(0), Service.class); assertAnnotation(annotations.get(1), ServiceMode.class); @@ -147,13 +148,13 @@ void testGetAnnotationsWithAnnotationClass() { @Test void testGetAnnotationsWithAnnotationClassOnNull() { assertTrue(getAnnotations(NULL_ANNOTATED_CONSTRUCT, NULL_CLASS).isEmpty()); - assertTrue(getAnnotations(testTypeElement, NULL_CLASS).isEmpty()); + assertTrue(getAnnotations(super.testTypeElement, NULL_CLASS).isEmpty()); assertTrue(getAnnotations(NULL_ANNOTATED_CONSTRUCT, Service.class).isEmpty()); } @Test void testGetAnnotationsWithAnnotationClassOnNotFound() { - List annotations = getAnnotations(testTypeElement, Override.class); + List annotations = getAnnotations(super.testTypeElement, Override.class); assertEquals(0, annotations.size()); } @@ -166,16 +167,16 @@ void testGetAnnotationsWithAnnotationClassName() { @Test void testGetAnnotationsWithAnnotationClassNameOnNull() { assertTrue(getAnnotations(NULL_ANNOTATED_CONSTRUCT, NULL_STRING).isEmpty()); - assertTrue(getAnnotations(testTypeElement, NULL_STRING).isEmpty()); + assertTrue(getAnnotations(super.testTypeElement, NULL_STRING).isEmpty()); assertTrue(getAnnotations(NULL_ANNOTATED_CONSTRUCT, "org.springframework.stereotype.Service").isEmpty()); } @Test void testGetAllAnnotations() { - List annotations = getAllAnnotations(testTypeElement); + List annotations = getAllAnnotations(super.testTypeElement); assertEquals(5, annotations.size()); - annotations = getAllAnnotations(testTypeMirror); + annotations = getAllAnnotations(super.testTypeMirror); assertEquals(5, annotations.size()); } @@ -187,16 +188,16 @@ void testGetAllAnnotationsOnNull() { @Test void testGetAllAnnotationsWithAnnotationClass() { - List annotations = getAllAnnotations(testTypeElement, Override.class); + List annotations = getAllAnnotations(super.testTypeElement, Override.class); assertEquals(0, annotations.size()); - annotations = getAllAnnotations(testTypeMirror, Override.class); + annotations = getAllAnnotations(super.testTypeMirror, Override.class); assertEquals(0, annotations.size()); - annotations = getAllAnnotations(testTypeElement, Service.class); + annotations = getAllAnnotations(super.testTypeElement, Service.class); assertEquals(1, annotations.size()); - annotations = getAllAnnotations(testTypeMirror, Service.class); + annotations = getAllAnnotations(super.testTypeMirror, Service.class); assertEquals(1, annotations.size()); annotations = getAllAnnotations(processingEnv, TestServiceImpl.class); @@ -213,17 +214,17 @@ void testGetAllAnnotationsWithAnnotationClassOnNull() { assertEmptyList(getAllAnnotations(NULL_TYPE_MIRROR, Service.class)); assertEmptyList(getAllAnnotations(NULL_PROCESSING_ENVIRONMENT, Service.class)); - assertEmptyList(getAllAnnotations(testTypeElement, NULL_CLASS)); - assertEmptyList(getAllAnnotations(testTypeMirror, NULL_CLASS)); + assertEmptyList(getAllAnnotations(super.testTypeElement, NULL_CLASS)); + assertEmptyList(getAllAnnotations(super.testTypeMirror, NULL_CLASS)); assertEmptyList(getAllAnnotations(processingEnv, NULL_CLASS)); } @Test void testGetAllAnnotationsWithAnnotationClassName() { - List annotations = getAllAnnotations(testTypeElement, "java.lang.Override"); + List annotations = getAllAnnotations(super.testTypeElement, "java.lang.Override"); assertEquals(0, annotations.size()); - annotations = getAllAnnotations(testTypeMirror, "org.springframework.stereotype.Service"); + annotations = getAllAnnotations(super.testTypeMirror, "org.springframework.stereotype.Service"); assertEquals(1, annotations.size()); } @@ -235,8 +236,8 @@ void testGetAllAnnotationsWithAnnotationClassNameOnNull() { assertTrue(getAllAnnotations(NULL_ELEMENT, "org.springframework.stereotype.Service").isEmpty()); assertTrue(getAllAnnotations(NULL_TYPE_MIRROR, "org.springframework.stereotype.Service").isEmpty()); - assertEmptyList(getAllAnnotations(testTypeElement, NULL_STRING)); - assertEmptyList(getAllAnnotations(testTypeMirror, NULL_STRING)); + assertEmptyList(getAllAnnotations(super.testTypeElement, NULL_STRING)); + assertEmptyList(getAllAnnotations(super.testTypeMirror, NULL_STRING)); } @Test @@ -247,23 +248,23 @@ void testFindAnnotation() { @Test void testFindAnnotationOnNotFound() { - assertNull(findAnnotation(testTypeMirror, Target.class)); - assertNull(findAnnotation(testTypeElement, Target.class)); - assertNull(findAnnotation(testTypeMirror, Override.class)); - assertNull(findAnnotation(testTypeElement, Override.class)); + assertNull(findAnnotation(super.testTypeMirror, Target.class)); + assertNull(findAnnotation(super.testTypeElement, Target.class)); + assertNull(findAnnotation(super.testTypeMirror, Override.class)); + assertNull(findAnnotation(super.testTypeElement, Override.class)); } @Test void testFindAnnotationOnNull() { assertNull(findAnnotation(NULL_ELEMENT, NULL_CLASS)); assertNull(findAnnotation(NULL_TYPE_MIRROR, NULL_CLASS)); - assertNull(findAnnotation(testTypeMirror, NULL_CLASS)); - assertNull(findAnnotation(testTypeElement, NULL_CLASS)); + assertNull(findAnnotation(super.testTypeMirror, NULL_CLASS)); + assertNull(findAnnotation(super.testTypeElement, NULL_CLASS)); assertNull(findAnnotation(NULL_ELEMENT, NULL_STRING)); assertNull(findAnnotation(NULL_TYPE_MIRROR, NULL_STRING)); - assertNull(findAnnotation(testTypeMirror, NULL_STRING)); - assertNull(findAnnotation(testTypeElement, NULL_STRING)); + assertNull(findAnnotation(super.testTypeMirror, NULL_STRING)); + assertNull(findAnnotation(super.testTypeElement, NULL_STRING)); } @Test @@ -275,19 +276,19 @@ void testFindMetaAnnotationWithAnnotationClass() { @Test void testFindMetaAnnotationWithAnnotationClassOnNotFound() { - assertNull(findMetaAnnotation(testTypeElement, Service.class)); + assertNull(findMetaAnnotation(super.testTypeElement, Service.class)); } @Test void testFindMetaAnnotationWithAnnotationClassNameOnNotFound() { - assertNull(findMetaAnnotation(testTypeElement, "org.springframework.stereotype.Service")); + assertNull(findMetaAnnotation(super.testTypeElement, "org.springframework.stereotype.Service")); } @Test void testFindMetaAnnotationWithAnnotationClassOnNull() { assertNull(findMetaAnnotation(NULL_ELEMENT, NULL_CLASS)); assertNull(findMetaAnnotation(NULL_ELEMENT, Service.class)); - assertNull(findMetaAnnotation(testTypeElement, NULL_CLASS)); + assertNull(findMetaAnnotation(super.testTypeElement, NULL_CLASS)); } @Test @@ -301,30 +302,30 @@ void testFindMetaAnnotationWithAnnotationClassName() { void testFindMetaAnnotationWithAnnotationClassNameOnNull() { assertNull(findMetaAnnotation(NULL_ELEMENT, NULL_STRING)); assertNull(findMetaAnnotation(NULL_ELEMENT, "test")); - assertNull(findMetaAnnotation(testTypeElement, NULL_STRING)); + assertNull(findMetaAnnotation(super.testTypeElement, NULL_STRING)); } @Test void testFindAllAnnotationsWithTypeMirror() { - List annotations = findAllAnnotations(testTypeMirror, alwaysTrue()); + List annotations = findAllAnnotations(super.testTypeMirror, alwaysTrue()); assertEquals(5, annotations.size()); - annotations = findAllAnnotations(testTypeMirror, alwaysFalse()); + annotations = findAllAnnotations(super.testTypeMirror, alwaysFalse()); assertEmptyList(annotations); } @Test void testFindAllAnnotationsWithTypeElement() { - List annotations = findAllAnnotations(testTypeElement, alwaysTrue()); + List annotations = findAllAnnotations(super.testTypeElement, alwaysTrue()); assertEquals(5, annotations.size()); - annotations = findAllAnnotations(testTypeElement, alwaysFalse()); + annotations = findAllAnnotations(super.testTypeElement, alwaysFalse()); assertEmptyList(annotations); } @Test void testFindAllAnnotationsWithMethod() { - ExecutableElement method = findMethod(testTypeElement, "echo", String.class); + ExecutableElement method = findMethod(super.testTypeElement, "echo", String.class); List annotations = findAllAnnotations(method, alwaysTrue()); assertEquals(1, annotations.size()); @@ -359,13 +360,13 @@ void testFindAllAnnotationsWithMethodParameters() { @Test void testFindAllAnnotationsWithField() { - VariableElement field = findField(testTypeElement, "context"); + VariableElement field = findField(super.testTypeElement, "context"); List annotations = findAllAnnotations(field, alwaysTrue()); assertEquals(1, annotations.size()); assertAnnotation(annotations.get(0), Autowired.class); - field = findField(testTypeElement, "environment"); + field = findField(super.testTypeElement, "environment"); annotations = findAllAnnotations(field, alwaysTrue()); assertEmptyList(annotations); } @@ -402,38 +403,38 @@ void testFindAllAnnotationsOnNull() { @Test void testMatchesAnnotationClass() { - AnnotationMirror annotation = findAnnotation(testTypeElement, Service.class); + AnnotationMirror annotation = findAnnotation(super.testTypeElement, Service.class); assertTrue(AnnotationUtils.matchesAnnotationType(annotation, Service.class)); } @Test void testMatchesAnnotationClassOnNull() { assertFalse(AnnotationUtils.matchesAnnotationType(NULL_ANNOTATION_MIRROR, Service.class)); - assertFalse(AnnotationUtils.matchesAnnotationType(findAnnotation(testTypeElement, Service.class), NULL_CLASS)); + assertFalse(AnnotationUtils.matchesAnnotationType(findAnnotation(super.testTypeElement, Service.class), NULL_CLASS)); } @Test void testMatchesAnnotationTypeName() { - AnnotationMirror annotation = findAnnotation(testTypeElement, "org.springframework.stereotype.Service"); + AnnotationMirror annotation = findAnnotation(super.testTypeElement, "org.springframework.stereotype.Service"); assertTrue(matchesAnnotationTypeName(annotation, "org.springframework.stereotype.Service")); } @Test void testMatchesAnnotationTypeNameOnNull() { assertFalse(matchesAnnotationTypeName(NULL_ANNOTATION_MIRROR, "org.springframework.stereotype.Service")); - assertFalse(matchesAnnotationTypeName(findAnnotation(testTypeElement, "org.springframework.stereotype.Service"), NULL_STRING)); + assertFalse(matchesAnnotationTypeName(findAnnotation(super.testTypeElement, "org.springframework.stereotype.Service"), NULL_STRING)); } @Test void testGetAttribute() { - assertEquals("testService", getAttribute(findAnnotation(testTypeElement, Service.class), "value")); - assertEquals("testService", getAttribute(findAnnotation(testTypeElement, Service.class), "value", false)); - assertEquals("/echo", getAttribute(findAnnotation(testTypeElement, Path.class), "value")); + assertEquals("testService", getAttribute(findAnnotation(super.testTypeElement, Service.class), "value")); + assertEquals("testService", getAttribute(findAnnotation(super.testTypeElement, Service.class), "value", false)); + assertEquals("/echo", getAttribute(findAnnotation(super.testTypeElement, Path.class), "value")); - assertNull(getAttribute(findAnnotation(testTypeElement, Path.class), NULL_STRING)); - assertNull(getAttribute(findAnnotation(testTypeElement, NULL_CLASS), NULL_STRING)); + assertNull(getAttribute(findAnnotation(super.testTypeElement, Path.class), NULL_STRING)); + assertNull(getAttribute(findAnnotation(super.testTypeElement, NULL_CLASS), NULL_STRING)); - ExecutableElement echoMethod = findMethod(testTypeElement, "echo", String.class); + ExecutableElement echoMethod = findMethod(super.testTypeElement, "echo", String.class); AnnotationMirror cacheableAnnotation = findAnnotation(echoMethod, Cacheable.class); String[] cacheNames = getAttribute(cacheableAnnotation, "cacheNames"); assertArrayEquals(ofArray("cache-1", "cache-2"), cacheNames); @@ -456,54 +457,54 @@ void testGetValue() { @Test void testIsAnnotationPresentOnAnnotationClass() { - assertTrue(isAnnotationPresent(testTypeElement, Service.class)); - assertTrue(isAnnotationPresent(testTypeElement, Component.class)); - assertTrue(isAnnotationPresent(testTypeElement, ServiceMode.class)); - assertTrue(isAnnotationPresent(testTypeElement, Inherited.class)); - assertTrue(isAnnotationPresent(testTypeElement, Documented.class)); + assertTrue(isAnnotationPresent(super.testTypeElement, Service.class)); + assertTrue(isAnnotationPresent(super.testTypeElement, Component.class)); + assertTrue(isAnnotationPresent(super.testTypeElement, ServiceMode.class)); + assertTrue(isAnnotationPresent(super.testTypeElement, Inherited.class)); + assertTrue(isAnnotationPresent(super.testTypeElement, Documented.class)); } @Test void testIsAnnotationPresentOnAnnotationClassOnNull() { assertFalse(isAnnotationPresent(NULL_ELEMENT, Service.class)); - assertFalse(isAnnotationPresent(testTypeElement, NULL_CLASS)); - assertFalse(isAnnotationPresent(testTypeElement, Override.class)); + assertFalse(isAnnotationPresent(super.testTypeElement, NULL_CLASS)); + assertFalse(isAnnotationPresent(super.testTypeElement, Override.class)); } @Test void testIsAnnotationPresentOnAnnotationClassName() { - assertTrue(isAnnotationPresent(testTypeElement, "org.springframework.stereotype.Service")); - assertTrue(isAnnotationPresent(testTypeElement, "org.springframework.stereotype.Component")); - assertTrue(isAnnotationPresent(testTypeElement, "javax.xml.ws.ServiceMode")); - assertTrue(isAnnotationPresent(testTypeElement, "java.lang.annotation.Inherited")); - assertTrue(isAnnotationPresent(testTypeElement, "java.lang.annotation.Documented")); + assertTrue(isAnnotationPresent(super.testTypeElement, "org.springframework.stereotype.Service")); + assertTrue(isAnnotationPresent(super.testTypeElement, "org.springframework.stereotype.Component")); + assertTrue(isAnnotationPresent(super.testTypeElement, "javax.xml.ws.ServiceMode")); + assertTrue(isAnnotationPresent(super.testTypeElement, "java.lang.annotation.Inherited")); + assertTrue(isAnnotationPresent(super.testTypeElement, "java.lang.annotation.Documented")); } @Test void testIsAnnotationPresentOnAnnotationClassNameOnNull() { assertFalse(isAnnotationPresent(NULL_ELEMENT, "org.springframework.stereotype.Service")); - assertFalse(isAnnotationPresent(testTypeElement, NULL_STRING)); - assertFalse(isAnnotationPresent(testTypeElement, "java.lang.Override")); + assertFalse(isAnnotationPresent(super.testTypeElement, NULL_STRING)); + assertFalse(isAnnotationPresent(super.testTypeElement, "java.lang.Override")); } @Test void testFindAnnotations() { - List annotations = findAnnotations(testTypeElement); + List annotations = findAnnotations(super.testTypeElement); assertEquals(4, annotations.size()); assertAnnotation(annotations.get(0), Service.class); assertAnnotation(annotations.get(1), ServiceMode.class); assertAnnotation(annotations.get(2), ComponentScans.class); assertAnnotation(annotations.get(3), TestAnnotation.class); - annotations = findAnnotations(testTypeElement, alwaysTrue()); + annotations = findAnnotations(super.testTypeElement, alwaysTrue()); assertEquals(4, annotations.size()); assertAnnotation(annotations.get(0), Service.class); assertAnnotation(annotations.get(1), ServiceMode.class); assertAnnotation(annotations.get(2), ComponentScans.class); assertAnnotation(annotations.get(3), TestAnnotation.class); - annotations = findAnnotations(testTypeElement, alwaysFalse()); + annotations = findAnnotations(super.testTypeElement, alwaysFalse()); assertEmptyList(annotations); } @@ -519,7 +520,7 @@ void testFindAnnotationsOnNull() { @Test void testGetAttributeName() { - Map elementValues = getElementValues(testTypeElement, TestAnnotation.class); + Map elementValues = getElementValues(super.testTypeElement, TestAnnotation.class); for (Entry entry : elementValues.entrySet()) { ExecutableElement attributeMethod = entry.getKey(); assertEquals(attributeMethod.getSimpleName().toString(), getAttributeName(attributeMethod)); @@ -528,7 +529,7 @@ void testGetAttributeName() { @Test void testMatchesAttributeMethod() { - Map elementValues = getElementValues(testTypeElement, TestAnnotation.class); + Map elementValues = getElementValues(super.testTypeElement, TestAnnotation.class); for (Entry entry : elementValues.entrySet()) { ExecutableElement attributeMethod = entry.getKey(); assertTrue(matchesAttributeMethod(attributeMethod, getAttributeName(attributeMethod))); @@ -539,7 +540,7 @@ void testMatchesAttributeMethod() { void testMatchesAttributeMethodOnNull() { assertFalse(matchesAttributeMethod(null, null)); - Map elementValues = getElementValues(testTypeElement, TestAnnotation.class); + Map elementValues = getElementValues(super.testTypeElement, TestAnnotation.class); for (Entry entry : elementValues.entrySet()) { ExecutableElement attributeMethod = entry.getKey(); assertFalse(matchesAttributeMethod(attributeMethod, null)); @@ -548,7 +549,7 @@ void testMatchesAttributeMethodOnNull() { @Test void testMatchesAttributeValue() { - Map elementValues = getElementValues(testTypeElement, TestAnnotation.class); + Map elementValues = getElementValues(super.testTypeElement, TestAnnotation.class); for (Entry entry : elementValues.entrySet()) { AnnotationValue annotationValue = entry.getValue(); assertTrue(matchesAttributeValue(annotationValue, annotationValue)); @@ -563,26 +564,36 @@ void testMatchesAttributeValueOnNull() { assertTrue(matchesAttributeValue(null, null)); assertFalse(matchesAttributeValue(null, (Object) null)); - Map elementValues = getElementValues(testTypeElement, TestAnnotation.class); + Map elementValues = getElementValues(super.testTypeElement, TestAnnotation.class); for (Entry entry : elementValues.entrySet()) { AnnotationValue annotationValue = entry.getValue(); assertFalse(matchesAttributeValue(annotationValue, null)); assertFalse(matchesAttributeValue(annotationValue, (Object) null)); + assertFalse(matchesAttributeValue(null, annotationValue)); } } @Test void testMatchesDefaultAttributeValue() { - Map elementValues = getElementValues(testTypeElement, ServiceMode.class); + Map elementValues = getElementValues(super.testTypeElement, ServiceMode.class); for (Entry entry : elementValues.entrySet()) { ExecutableElement attributeMethod = entry.getKey(); assertTrue(matchesDefaultAttributeValue(attributeMethod, attributeMethod.getDefaultValue())); } } + @Test + void testMatchesDefaultAttributeValueOnNull() { + Map elementValues = getElementValues(super.testTypeElement, ServiceMode.class); + for (Entry entry : elementValues.entrySet()) { + ExecutableElement attributeMethod = entry.getKey(); + assertFalse(matchesDefaultAttributeValue(NULL_METHOD, attributeMethod.getDefaultValue())); + } + } + @Test void testGetElementValue() { - Map elementValues = getElementValues(testTypeElement, TestAnnotation.class); + Map elementValues = getElementValues(super.testTypeElement, TestAnnotation.class); for (Entry entry : elementValues.entrySet()) { ExecutableElement attributeMethod = entry.getKey(); String attributeName = getAttributeName(attributeMethod); @@ -590,11 +601,29 @@ void testGetElementValue() { } assertNull(getElementValue(elementValues, "unknown")); + + AnnotationMirror annotation = findAnnotation(super.testTypeElement, ServiceMode.class); + Entry elementValue = getElementValue(annotation, "value", true); + + assertAttributeEntry(elementValue, "value", PAYLOAD); + + elementValue = getElementValue(annotation, "value", false); + assertNull(elementValue); + } + + @Test + void testGetElementValueOnNotFound() { + AnnotationMirror annotation = findAnnotation(super.testTypeElement, ServiceMode.class); + Entry elementValue = getElementValue(annotation, "z", true); + assertNull(elementValue); + + elementValue = getElementValue(annotation, "z", false); + assertNull(elementValue); } @Test void testGetElementValueOnEmptyElementValues() { - AnnotationMirror annotation = findAnnotation(testTypeElement, ServiceMode.class); + AnnotationMirror annotation = findAnnotation(super.testTypeElement, ServiceMode.class); Map elementValues = annotation.getElementValues(); assertNull(getElementValue(elementValues, "value")); } @@ -606,14 +635,14 @@ void testGetElementValueOnNull() { @Test void testGetElementValuesMapOnAnnotatedClass() { - Map attributesMap = getAttributesMap(testTypeElement, Service.class); + Map attributesMap = getAttributesMap(super.testTypeElement, Service.class); assertEquals(1, attributesMap.size()); assertEquals("testService", attributesMap.get("value")); } @Test void testGetElementValuesMapOnAnnotatedMethod() { - ExecutableElement method = findMethod(testTypeElement, "echo", String.class); + ExecutableElement method = findMethod(super.testTypeElement, "echo", String.class); Map attributesMap = getAttributesMap(method, Cacheable.class); assertEquals(9, attributesMap.size()); assertArrayEquals(ofArray("cache-1", "cache-2"), (String[]) attributesMap.get("cacheNames")); @@ -621,7 +650,7 @@ void testGetElementValuesMapOnAnnotatedMethod() { @Test void testGetElementValuesMapOnRepeatableAnnotation() { - Map attributesMap = getAttributesMap(testTypeElement, ComponentScans.class); + Map attributesMap = getAttributesMap(super.testTypeElement, ComponentScans.class); assertEquals(1, attributesMap.size()); ComponentScans componentScans = testClass.getAnnotation(ComponentScans.class); @@ -635,7 +664,7 @@ void testGetElementValuesMapOnNull() { Map attributesMap = getAttributesMap(null, null); assertSame(emptyMap(), attributesMap); - attributesMap = getAttributesMap(testTypeElement, null); + attributesMap = getAttributesMap(super.testTypeElement, null); assertSame(emptyMap(), attributesMap); attributesMap = getAttributesMap(null); @@ -644,16 +673,16 @@ void testGetElementValuesMapOnNull() { @Test void testGetElementValuesOnAnnotatedClass() { - Map elementValues = getElementValues(testTypeElement, Service.class); + Map elementValues = getElementValues(super.testTypeElement, Service.class); assertServiceAttributes(elementValues); - elementValues = getElementValues(testTypeElement, Service.class, false); + elementValues = getElementValues(super.testTypeElement, Service.class, false); assertServiceAttributes(elementValues); } @Test void testGetElementValuesOnAnnotatedMethod() { - ExecutableElement method = findMethod(testTypeElement, "echo", String.class); + ExecutableElement method = findMethod(super.testTypeElement, "echo", String.class); Map elementValues = getElementValues(method, Cacheable.class, false); assertEquals(1, elementValues.size()); assertAttributeEntry(elementValues, "cacheNames", ofArray("cache-1", "cache-2")); @@ -687,7 +716,7 @@ void testGetElementTypes() { } void assertElementTypes(Class annotationClass, ElementType... expectedElementTypes) { - AnnotationMirror annotationMirror = findAnnotation(this.testTypeElement, annotationClass); + AnnotationMirror annotationMirror = findAnnotation(super.testTypeElement, annotationClass); assertArrayEquals(expectedElementTypes, getElementTypes(annotationMirror)); } @@ -712,19 +741,26 @@ void assertAttributeEntry(Map attributes, St } } - void assertAttributeEntry(Entry attributeEntry, String attributeName, Object attributeValue) { + void assertAttributeEntry(Entry attributeEntry, String attributeName, Object expectedAttributeValue) { + assertNotNull(attributeEntry); + ExecutableElement attributeMethod = attributeEntry.getKey(); - AnnotationValue annotationValue = attributeEntry.getValue(); + AnnotationValue attributeValue = attributeEntry.getValue(); + assertNotNull(attributeMethod); + assertNotNull(attributeValue); + assertEquals(attributeName, getAttributeName(attributeMethod)); + assertTrue(matchesAttributeMethod(attributeMethod, getAttributeName(attributeMethod))); + Object value = getAttribute(attributeEntry); Class attributeValueClass = value.getClass(); if (attributeValueClass.isArray()) { Class componentType = attributeValueClass.getComponentType(); if (String.class.equals(componentType)) { - assertArrayEquals((String[]) attributeValue, (String[]) value); + assertArrayEquals((String[]) expectedAttributeValue, (String[]) value); } } else { - assertEquals(attributeValue, value); + assertEquals(expectedAttributeValue, value); } } @@ -737,30 +773,30 @@ private void assertFindMetaAnnotation(Element element, String annotationClassNam } private void assertFindAnnotation(Class annotationClass) { - assertAnnotation(findAnnotation(testTypeMirror, annotationClass), annotationClass); - assertAnnotation(findAnnotation(testTypeElement, annotationClass), annotationClass); - assertAnnotation(findAnnotation(testTypeMirror, annotationClass.getName()), annotationClass); - assertAnnotation(findAnnotation(testTypeElement, annotationClass.getName()), annotationClass); + assertAnnotation(findAnnotation(super.testTypeMirror, annotationClass), annotationClass); + assertAnnotation(findAnnotation(super.testTypeElement, annotationClass), annotationClass); + assertAnnotation(findAnnotation(super.testTypeMirror, annotationClass.getName()), annotationClass); + assertAnnotation(findAnnotation(super.testTypeElement, annotationClass.getName()), annotationClass); } private void asserGetAnnotation(Class annotationClass) { - AnnotationMirror annotation = getAnnotation(testTypeElement, annotationClass); + AnnotationMirror annotation = getAnnotation(super.testTypeElement, annotationClass); assertAnnotation(annotation, annotationClass); } private void asserGetAnnotation(String annotationClassName) { - AnnotationMirror annotation = getAnnotation(testTypeElement, annotationClassName); + AnnotationMirror annotation = getAnnotation(super.testTypeElement, annotationClassName); assertAnnotation(annotation, annotationClassName); } private void assertGetAnnotations(Class annotationClass) { - List annotations = getAnnotations(testTypeElement, annotationClass); + List annotations = getAnnotations(super.testTypeElement, annotationClass); assertEquals(1, annotations.size()); assertAnnotation(annotations.get(0), annotationClass); } private void assertGetAnnotations(String annotationClassName) { - List annotations = getAnnotations(testTypeElement, annotationClassName); + List annotations = getAnnotations(super.testTypeElement, annotationClassName); assertEquals(1, annotations.size()); assertAnnotation(annotations.get(0), annotationClassName); } diff --git a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/util/ClassUtilsTest.java b/microsphere-lang-model/src/test/java/io/microsphere/lang/model/util/ClassUtilsTest.java similarity index 81% rename from microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/util/ClassUtilsTest.java rename to microsphere-lang-model/src/test/java/io/microsphere/lang/model/util/ClassUtilsTest.java index 3785041ad..c6857d5ed 100644 --- a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/util/ClassUtilsTest.java +++ b/microsphere-lang-model/src/test/java/io/microsphere/lang/model/util/ClassUtilsTest.java @@ -15,15 +15,15 @@ * limitations under the License. */ -package io.microsphere.annotation.processor.util; +package io.microsphere.lang.model.util; -import io.microsphere.annotation.processor.AbstractAnnotationProcessingTest; import org.junit.jupiter.api.Test; import org.springframework.context.annotation.ComponentScan; -import static io.microsphere.annotation.processor.util.ClassUtils.getClassName; -import static io.microsphere.annotation.processor.util.ClassUtils.loadClass; +import static io.microsphere.lang.model.util.ClassUtils.getClassName; +import static io.microsphere.lang.model.util.ClassUtils.loadClass; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertSame; /** @@ -33,7 +33,7 @@ * @see ClassUtils * @since 1.0.0 */ -class ClassUtilsTest extends AbstractAnnotationProcessingTest { +class ClassUtilsTest extends UtilTest { @Test void testGetClassName() { @@ -48,5 +48,6 @@ void testLoadClassOnTypeMirror() { @Test void testLoadClass() { assertSame(ComponentScan.Filter.class, loadClass("org.springframework.context.annotation.ComponentScan.Filter")); + assertNull(loadClass("not-found-class")); } } diff --git a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/util/ConstructorUtilsTest.java b/microsphere-lang-model/src/test/java/io/microsphere/lang/model/util/ConstructorUtilsTest.java similarity index 91% rename from microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/util/ConstructorUtilsTest.java rename to microsphere-lang-model/src/test/java/io/microsphere/lang/model/util/ConstructorUtilsTest.java index 09aac37d9..a4b513650 100644 --- a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/util/ConstructorUtilsTest.java +++ b/microsphere-lang-model/src/test/java/io/microsphere/lang/model/util/ConstructorUtilsTest.java @@ -15,10 +15,9 @@ * limitations under the License. */ -package io.microsphere.annotation.processor.util; +package io.microsphere.lang.model.util; -import io.microsphere.annotation.processor.AbstractAnnotationProcessingTest; import org.junit.jupiter.api.Test; import org.springframework.core.env.Environment; @@ -26,12 +25,12 @@ import java.io.Serializable; import java.util.List; -import static io.microsphere.annotation.processor.util.ConstructorUtils.findConstructor; -import static io.microsphere.annotation.processor.util.ConstructorUtils.findDeclaredConstructors; -import static io.microsphere.annotation.processor.util.ConstructorUtils.getDeclaredConstructors; -import static io.microsphere.annotation.processor.util.ElementUtils.matchParameterTypes; import static io.microsphere.lang.function.Predicates.alwaysFalse; import static io.microsphere.lang.function.Predicates.alwaysTrue; +import static io.microsphere.lang.model.util.ConstructorUtils.findConstructor; +import static io.microsphere.lang.model.util.ConstructorUtils.findDeclaredConstructors; +import static io.microsphere.lang.model.util.ConstructorUtils.getDeclaredConstructors; +import static io.microsphere.lang.model.util.ElementUtils.matchParameterTypes; import static java.util.Collections.emptyList; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; @@ -45,7 +44,7 @@ * @see ConstructorUtils * @since 1.0.0 */ -class ConstructorUtilsTest extends AbstractAnnotationProcessingTest { +class ConstructorUtilsTest extends UtilTest { @Test void testGetDeclaredConstructors() { diff --git a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/util/ElementUtilsTest.java b/microsphere-lang-model/src/test/java/io/microsphere/lang/model/util/ElementUtilsTest.java similarity index 77% rename from microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/util/ElementUtilsTest.java rename to microsphere-lang-model/src/test/java/io/microsphere/lang/model/util/ElementUtilsTest.java index 91cb83a6f..b65ea7b2c 100644 --- a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/util/ElementUtilsTest.java +++ b/microsphere-lang-model/src/test/java/io/microsphere/lang/model/util/ElementUtilsTest.java @@ -15,41 +15,43 @@ * limitations under the License. */ -package io.microsphere.annotation.processor.util; +package io.microsphere.lang.model.util; -import io.microsphere.annotation.processor.AbstractAnnotationProcessingTest; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.api.extension.ReflectiveInvocationContext; import javax.lang.model.element.Element; import javax.lang.model.element.ElementKind; import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.VariableElement; import java.lang.annotation.ElementType; +import java.lang.reflect.Method; import java.util.List; -import static io.microsphere.annotation.processor.util.ElementUtils.filterElements; -import static io.microsphere.annotation.processor.util.ElementUtils.hasModifiers; -import static io.microsphere.annotation.processor.util.ElementUtils.isClass; -import static io.microsphere.annotation.processor.util.ElementUtils.isDeclaredType; -import static io.microsphere.annotation.processor.util.ElementUtils.isExecutable; -import static io.microsphere.annotation.processor.util.ElementUtils.isField; -import static io.microsphere.annotation.processor.util.ElementUtils.isInitializer; -import static io.microsphere.annotation.processor.util.ElementUtils.isInterface; -import static io.microsphere.annotation.processor.util.ElementUtils.isMember; -import static io.microsphere.annotation.processor.util.ElementUtils.isPublicNonStatic; -import static io.microsphere.annotation.processor.util.ElementUtils.isVariable; -import static io.microsphere.annotation.processor.util.ElementUtils.matchParameterTypeNames; -import static io.microsphere.annotation.processor.util.ElementUtils.matchParameterTypes; -import static io.microsphere.annotation.processor.util.ElementUtils.matchesElementKind; -import static io.microsphere.annotation.processor.util.ElementUtils.matchesElementType; -import static io.microsphere.annotation.processor.util.ElementUtils.toElementKind; -import static io.microsphere.annotation.processor.util.MemberUtils.getAllDeclaredMembers; -import static io.microsphere.annotation.processor.util.MemberUtils.getDeclaredMembers; -import static io.microsphere.annotation.processor.util.MethodUtils.findMethod; import static io.microsphere.collection.ListUtils.ofList; import static io.microsphere.lang.function.Predicates.alwaysFalse; import static io.microsphere.lang.function.Predicates.alwaysTrue; +import static io.microsphere.lang.model.util.ElementUtils.filterElements; +import static io.microsphere.lang.model.util.ElementUtils.hasModifiers; +import static io.microsphere.lang.model.util.ElementUtils.isClass; +import static io.microsphere.lang.model.util.ElementUtils.isDeclaredType; +import static io.microsphere.lang.model.util.ElementUtils.isExecutable; +import static io.microsphere.lang.model.util.ElementUtils.isField; +import static io.microsphere.lang.model.util.ElementUtils.isInitializer; +import static io.microsphere.lang.model.util.ElementUtils.isInterface; +import static io.microsphere.lang.model.util.ElementUtils.isMember; +import static io.microsphere.lang.model.util.ElementUtils.isPublicNonStatic; +import static io.microsphere.lang.model.util.ElementUtils.isVariable; +import static io.microsphere.lang.model.util.ElementUtils.matchParameterTypeNames; +import static io.microsphere.lang.model.util.ElementUtils.matchParameterTypes; +import static io.microsphere.lang.model.util.ElementUtils.matchesElementKind; +import static io.microsphere.lang.model.util.ElementUtils.matchesElementType; +import static io.microsphere.lang.model.util.ElementUtils.toElementKind; +import static io.microsphere.lang.model.util.MemberUtils.getAllDeclaredMembers; +import static io.microsphere.lang.model.util.MemberUtils.getDeclaredMembers; +import static io.microsphere.lang.model.util.MethodUtils.findMethod; import static java.lang.annotation.ElementType.PACKAGE; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.ElementType.TYPE_USE; @@ -70,7 +72,7 @@ import static javax.lang.model.element.ElementKind.PARAMETER; import static javax.lang.model.element.ElementKind.RESOURCE_VARIABLE; import static javax.lang.model.element.ElementKind.STATIC_INIT; -import static javax.lang.model.element.Modifier.PRIVATE; +import static javax.lang.model.element.Modifier.PROTECTED; import static javax.lang.model.util.ElementFilter.fieldsIn; import static javax.lang.model.util.ElementFilter.methodsIn; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -86,26 +88,26 @@ * @see ElementUtils * @since 1.0.0 */ -class ElementUtilsTest extends AbstractAnnotationProcessingTest { +class ElementUtilsTest extends UtilTest { private ExecutableElement echoMethod; @Override - protected void beforeTest() { - super.beforeTest(); + protected void beforeTest(ReflectiveInvocationContext invocationContext, ExtensionContext extensionContext) { + super.beforeTest(invocationContext, extensionContext); this.echoMethod = findMethod(testTypeElement, "echo", "java.lang.String"); } @Test void testMatchesElementTypeElementKind() { assertTrue(matchesElementKind(echoMethod, METHOD)); - assertFalse(matchesElementKind(echoMethod, FIELD)); + assertFalse(matchesElementKind(this.echoMethod, FIELD)); } @Test void testMatchesElementTypeElementKindOnNull() { assertFalse(matchesElementKind(NULL_ELEMENT, FIELD)); - assertFalse(matchesElementKind(echoMethod, NULL_ELEMENT_KIND)); + assertFalse(matchesElementKind(this.echoMethod, NULL_ELEMENT_KIND)); } @Test @@ -125,7 +127,7 @@ void testIsPublicNonStaticOnNull() { void testHasModifiers() { List members = getAllDeclaredMembers(testTypeElement.asType()); List fields = fieldsIn(members); - assertTrue(hasModifiers(fields.get(0), PRIVATE)); + assertTrue(hasModifiers(fields.get(0), PROTECTED)); } @Test @@ -279,7 +281,8 @@ void testMatchesElementTypeWithArray() { @Test void testMatchesElementTypeWithElement() { - matchesElementType(this.testTypeElement, TYPE); + assertTrue(matchesElementType(this.testTypeElement, TYPE)); + assertFalse(matchesElementType(this.testTypeElement, PACKAGE)); } @Test @@ -304,33 +307,35 @@ void testFilterElements() { @Test void testFilterElementsOnNull() { assertEmptyList(filterElements(NULL_LIST, alwaysTrue())); - List methods = ofList(echoMethod); + List methods = ofList(this.echoMethod); assertSame(emptyList(), filterElements(methods, NULL_PREDICATE_ARRAY)); } @Test void testFilterElementsOnEmpty() { assertEmptyList(filterElements(emptyList(), alwaysTrue())); - List methods = ofList(echoMethod); + List methods = ofList(this.echoMethod); assertEquals(methods, filterElements(methods)); } @Test void testMatchParameterTypes() { - assertTrue(matchParameterTypes(echoMethod.getParameters(), String.class)); - assertFalse(matchParameterTypes(echoMethod.getParameters(), Object.class)); + assertTrue(matchParameterTypes(this.echoMethod.getParameters(), String.class)); + assertFalse(matchParameterTypes(this.echoMethod.getParameters(), Object.class)); } @Test void testMatchParameterTypesOnNull() { assertFalse(matchParameterTypes(NULL_LIST, String.class)); assertFalse(matchParameterTypes(emptyList(), NULL_CLASS_ARRAY)); + assertFalse(matchParameterTypes(NULL_METHOD, String.class)); + assertFalse(matchParameterTypes(this.echoMethod, NULL_CLASS_ARRAY)); } @Test void testMatchParameterTypeNames() { - assertTrue(matchParameterTypeNames(echoMethod.getParameters(), "java.lang.String")); - assertFalse(matchParameterTypeNames(echoMethod.getParameters(), "java.lang.Object")); + assertTrue(matchParameterTypeNames(this.echoMethod.getParameters(), "java.lang.String")); + assertFalse(matchParameterTypeNames(this.echoMethod.getParameters(), "java.lang.Object")); } @Test diff --git a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/util/ExecutableElementComparatorTest.java b/microsphere-lang-model/src/test/java/io/microsphere/lang/model/util/ExecutableElementComparatorTest.java similarity index 85% rename from microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/util/ExecutableElementComparatorTest.java rename to microsphere-lang-model/src/test/java/io/microsphere/lang/model/util/ExecutableElementComparatorTest.java index dfd4eaa25..9043220bb 100644 --- a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/util/ExecutableElementComparatorTest.java +++ b/microsphere-lang-model/src/test/java/io/microsphere/lang/model/util/ExecutableElementComparatorTest.java @@ -1,15 +1,14 @@ -package io.microsphere.annotation.processor.util; +package io.microsphere.lang.model.util; -import io.microsphere.annotation.processor.AbstractAnnotationProcessingTest; -import io.microsphere.annotation.processor.TestService; +import io.microsphere.test.service.TestService; import org.junit.jupiter.api.Test; import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.TypeElement; import java.lang.reflect.Type; -import static io.microsphere.annotation.processor.util.ExecutableElementComparator.INSTANCE; -import static io.microsphere.annotation.processor.util.MethodUtils.findMethod; +import static io.microsphere.lang.model.util.ExecutableElementComparator.INSTANCE; +import static io.microsphere.lang.model.util.MethodUtils.findMethod; import static org.junit.jupiter.api.Assertions.assertEquals; /** @@ -19,7 +18,7 @@ * @see ExecutableElementComparator * @since 1.0.0 */ -class ExecutableElementComparatorTest extends AbstractAnnotationProcessingTest { +class ExecutableElementComparatorTest extends UtilTest { private final ExecutableElementComparator comparator = INSTANCE; diff --git a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/util/FieldUtilsTest.java b/microsphere-lang-model/src/test/java/io/microsphere/lang/model/util/FieldUtilsTest.java similarity index 90% rename from microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/util/FieldUtilsTest.java rename to microsphere-lang-model/src/test/java/io/microsphere/lang/model/util/FieldUtilsTest.java index 7477f52ee..afa535fb0 100644 --- a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/util/FieldUtilsTest.java +++ b/microsphere-lang-model/src/test/java/io/microsphere/lang/model/util/FieldUtilsTest.java @@ -14,11 +14,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.microsphere.annotation.processor.util; +package io.microsphere.lang.model.util; -import io.microsphere.annotation.processor.AbstractAnnotationProcessingTest; -import io.microsphere.annotation.processor.model.Color; -import io.microsphere.annotation.processor.model.Model; +import io.microsphere.test.model.Color; +import io.microsphere.test.model.Model; import org.junit.jupiter.api.Test; import javax.lang.model.element.ExecutableElement; @@ -33,22 +32,22 @@ import java.util.List; import java.util.concurrent.TimeUnit; -import static io.microsphere.annotation.processor.util.FieldUtils.equalsFieldName; -import static io.microsphere.annotation.processor.util.FieldUtils.filterDeclaredFields; -import static io.microsphere.annotation.processor.util.FieldUtils.findAllDeclaredFields; -import static io.microsphere.annotation.processor.util.FieldUtils.findDeclaredFields; -import static io.microsphere.annotation.processor.util.FieldUtils.findField; -import static io.microsphere.annotation.processor.util.FieldUtils.getAllDeclaredFields; -import static io.microsphere.annotation.processor.util.FieldUtils.getAllNonStaticFields; -import static io.microsphere.annotation.processor.util.FieldUtils.getDeclaredField; -import static io.microsphere.annotation.processor.util.FieldUtils.getDeclaredFields; -import static io.microsphere.annotation.processor.util.FieldUtils.getNonStaticFields; -import static io.microsphere.annotation.processor.util.FieldUtils.isEnumMemberField; -import static io.microsphere.annotation.processor.util.FieldUtils.isField; -import static io.microsphere.annotation.processor.util.FieldUtils.isNonStaticField; -import static io.microsphere.annotation.processor.util.MethodUtils.findMethod; import static io.microsphere.lang.function.Predicates.alwaysFalse; import static io.microsphere.lang.function.Predicates.alwaysTrue; +import static io.microsphere.lang.model.util.FieldUtils.equalsFieldName; +import static io.microsphere.lang.model.util.FieldUtils.filterDeclaredFields; +import static io.microsphere.lang.model.util.FieldUtils.findAllDeclaredFields; +import static io.microsphere.lang.model.util.FieldUtils.findDeclaredFields; +import static io.microsphere.lang.model.util.FieldUtils.findField; +import static io.microsphere.lang.model.util.FieldUtils.getAllDeclaredFields; +import static io.microsphere.lang.model.util.FieldUtils.getAllNonStaticFields; +import static io.microsphere.lang.model.util.FieldUtils.getDeclaredField; +import static io.microsphere.lang.model.util.FieldUtils.getDeclaredFields; +import static io.microsphere.lang.model.util.FieldUtils.getNonStaticFields; +import static io.microsphere.lang.model.util.FieldUtils.isEnumMemberField; +import static io.microsphere.lang.model.util.FieldUtils.isField; +import static io.microsphere.lang.model.util.FieldUtils.isNonStaticField; +import static io.microsphere.lang.model.util.MethodUtils.findMethod; import static io.microsphere.util.StringUtils.EMPTY_STRING; import static javax.lang.model.element.Modifier.FINAL; import static javax.lang.model.element.Modifier.PRIVATE; @@ -65,7 +64,7 @@ * @author Mercy * @since 1.0.0 */ -class FieldUtilsTest extends AbstractAnnotationProcessingTest { +class FieldUtilsTest extends UtilTest { @Test void testGetDeclaredField() { diff --git a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/model/util/JSONAnnotationValueVisitorTest.java b/microsphere-lang-model/src/test/java/io/microsphere/lang/model/util/JSONAnnotationValueVisitorTest.java similarity index 83% rename from microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/model/util/JSONAnnotationValueVisitorTest.java rename to microsphere-lang-model/src/test/java/io/microsphere/lang/model/util/JSONAnnotationValueVisitorTest.java index 094b1460c..d89d3c732 100644 --- a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/model/util/JSONAnnotationValueVisitorTest.java +++ b/microsphere-lang-model/src/test/java/io/microsphere/lang/model/util/JSONAnnotationValueVisitorTest.java @@ -15,19 +15,21 @@ * limitations under the License. */ -package io.microsphere.annotation.processor.model.util; +package io.microsphere.lang.model.util; -import io.microsphere.annotation.processor.AbstractAnnotationProcessingTest; -import io.microsphere.annotation.processor.TestAnnotation; +import io.microsphere.test.annotation.TestAnnotation; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.api.extension.ReflectiveInvocationContext; import javax.lang.model.element.AnnotationValue; import javax.lang.model.element.ExecutableElement; +import java.lang.reflect.Method; import java.util.Map; -import static io.microsphere.annotation.processor.util.AnnotationUtils.getElementValue; -import static io.microsphere.annotation.processor.util.AnnotationUtils.getElementValues; +import static io.microsphere.lang.model.util.AnnotationUtils.getElementValue; +import static io.microsphere.lang.model.util.AnnotationUtils.getElementValues; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertSame; @@ -38,7 +40,7 @@ * @see JSONAnnotationValueVisitor * @since 1.0.0 */ -class JSONAnnotationValueVisitorTest extends AbstractAnnotationProcessingTest { +class JSONAnnotationValueVisitorTest extends UtilTest { private StringBuilder jsonBuilder; @@ -46,8 +48,9 @@ class JSONAnnotationValueVisitorTest extends AbstractAnnotationProcessingTest { private Map testAnnotationAttributes; - protected void beforeTest() { - super.beforeTest(); + @Override + protected void beforeTest(ReflectiveInvocationContext invocationContext, ExtensionContext extensionContext) { + super.beforeTest(invocationContext,extensionContext); this.jsonBuilder = new StringBuilder(); this.visitor = new JSONAnnotationValueVisitor(jsonBuilder); this.testAnnotationAttributes = getElementValues(testTypeElement, TestAnnotation.class); @@ -100,7 +103,7 @@ void testVisitString() { @Test void testVisitType() { - testVisit("type", "\"type\":\"io.microsphere.annotation.processor.GenericTestService\""); + testVisit("type", "\"type\":\"io.microsphere.test.service.GenericTestService\""); } @Test diff --git a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/model/util/JSONElementVisitorTest.java b/microsphere-lang-model/src/test/java/io/microsphere/lang/model/util/JSONElementVisitorTest.java similarity index 93% rename from microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/model/util/JSONElementVisitorTest.java rename to microsphere-lang-model/src/test/java/io/microsphere/lang/model/util/JSONElementVisitorTest.java index 81a9a5adf..f9c20e905 100644 --- a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/model/util/JSONElementVisitorTest.java +++ b/microsphere-lang-model/src/test/java/io/microsphere/lang/model/util/JSONElementVisitorTest.java @@ -15,13 +15,12 @@ * limitations under the License. */ -package io.microsphere.annotation.processor.model.util; +package io.microsphere.lang.model.util; -import io.microsphere.annotation.processor.AbstractAnnotationProcessingTest; -import io.microsphere.annotation.processor.TestAnnotation; -import io.microsphere.annotation.processor.model.Color; -import io.microsphere.annotation.processor.model.StringArrayList; +import io.microsphere.test.annotation.TestAnnotation; +import io.microsphere.test.model.Color; +import io.microsphere.test.model.StringArrayList; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -35,7 +34,7 @@ import java.io.Serializable; import java.util.List; -import static io.microsphere.annotation.processor.util.TypeUtils.ofTypeElement; +import static io.microsphere.lang.model.util.TypeUtils.ofTypeElement; import static java.lang.Boolean.TRUE; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; @@ -48,7 +47,7 @@ * @see JSONElementVisitor * @since 1.0.0 */ -class JSONElementVisitorTest extends AbstractAnnotationProcessingTest { +class JSONElementVisitorTest extends UtilTest { private boolean supported; @@ -141,14 +140,14 @@ public Boolean visitTypeAsAnnotationType(TypeElement e, StringBuilder stringBuil @Test void testVisitPackage() { - assertTrue(visitor.visitPackage(this.elements.getPackageElement("io.microsphere.annotation.processor.model.util"), jsonBuilder)); + assertTrue(visitor.visitPackage(this.elements.getPackageElement("io.microsphere.lang.model.util"), jsonBuilder)); assertJson("visitPackage"); } @Test - void testVisitVariableOnUnsupported() { + void testVisitPackageOnUnsupported() { supported = false; - assertFalse(visitor.visitVariable(null, jsonBuilder)); + assertFalse(visitor.visitPackage(this.elements.getPackageElement("io.microsphere.lang.model.util"), jsonBuilder)); } @Test @@ -156,7 +155,6 @@ void testVisitVariableAsEnumConstant() { VariableElement element = getField(Color.class, "RED"); assertTrue(visitor.visitVariable(element, jsonBuilder)); assertJson("visitVariableAsEnumConstant"); - } @Test @@ -176,9 +174,9 @@ void testVisitVariableAsParameter() { } @Test - void testVisitExecutableOnUnsupported() { + void testVisitVariableOnUnsupported() { supported = false; - assertFalse(visitor.visitExecutable(null, jsonBuilder)); + assertFalse(visitor.visitVariable(null, jsonBuilder)); } @Test @@ -196,10 +194,9 @@ void testVisitExecutableAsMethod() { } @Test - void testVisitTypeOnUnsupported() { + void testVisitExecutableOnUnsupported() { supported = false; - TypeElement typeElement = getTypeElement(Serializable.class); - assertFalse(visitor.visitType(typeElement, jsonBuilder)); + assertFalse(visitor.visitExecutable(null, jsonBuilder)); } @Test @@ -231,9 +228,10 @@ void testVisitTypeAsAnnotationType() { } @Test - void testVisitTypeParameterOnUnsupported() { + void testVisitTypeOnUnsupported() { supported = false; - assertFalse(visitor.visitTypeParameter(null, jsonBuilder)); + TypeElement typeElement = getTypeElement(Serializable.class); + assertFalse(visitor.visitType(typeElement, jsonBuilder)); } @Test @@ -248,6 +246,12 @@ void testVisitTypeParameter() { } } + @Test + void testVisitTypeParameterOnUnsupported() { + supported = false; + assertFalse(visitor.visitTypeParameter(null, jsonBuilder)); + } + void assertJson(String expected) { assertEquals(expected, jsonBuilder.toString()); } diff --git a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/util/LoggerUtilsTest.java b/microsphere-lang-model/src/test/java/io/microsphere/lang/model/util/LoggerUtilsTest.java similarity index 78% rename from microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/util/LoggerUtilsTest.java rename to microsphere-lang-model/src/test/java/io/microsphere/lang/model/util/LoggerUtilsTest.java index dd436fae9..7f916931b 100644 --- a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/util/LoggerUtilsTest.java +++ b/microsphere-lang-model/src/test/java/io/microsphere/lang/model/util/LoggerUtilsTest.java @@ -14,16 +14,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.microsphere.annotation.processor.util; +package io.microsphere.lang.model.util; import org.junit.jupiter.api.Test; -import static io.microsphere.annotation.processor.util.LoggerUtils.LOGGER; -import static io.microsphere.annotation.processor.util.LoggerUtils.debug; -import static io.microsphere.annotation.processor.util.LoggerUtils.error; -import static io.microsphere.annotation.processor.util.LoggerUtils.info; -import static io.microsphere.annotation.processor.util.LoggerUtils.trace; -import static io.microsphere.annotation.processor.util.LoggerUtils.warn; +import static io.microsphere.lang.model.util.LoggerUtils.LOGGER; +import static io.microsphere.lang.model.util.LoggerUtils.debug; +import static io.microsphere.lang.model.util.LoggerUtils.error; +import static io.microsphere.lang.model.util.LoggerUtils.info; +import static io.microsphere.lang.model.util.LoggerUtils.trace; +import static io.microsphere.lang.model.util.LoggerUtils.warn; import static org.junit.jupiter.api.Assertions.assertNotNull; /** diff --git a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/util/MemberUtilsTest.java b/microsphere-lang-model/src/test/java/io/microsphere/lang/model/util/MemberUtilsTest.java similarity index 92% rename from microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/util/MemberUtilsTest.java rename to microsphere-lang-model/src/test/java/io/microsphere/lang/model/util/MemberUtilsTest.java index aa455d3a5..bae09a873 100644 --- a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/util/MemberUtilsTest.java +++ b/microsphere-lang-model/src/test/java/io/microsphere/lang/model/util/MemberUtilsTest.java @@ -14,10 +14,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.microsphere.annotation.processor.util; +package io.microsphere.lang.model.util; -import io.microsphere.annotation.processor.AbstractAnnotationProcessingTest; -import io.microsphere.annotation.processor.model.Model; +import io.microsphere.test.model.Model; import org.junit.jupiter.api.Test; import javax.lang.model.element.Element; @@ -25,12 +24,12 @@ import javax.lang.model.element.VariableElement; import java.util.List; -import static io.microsphere.annotation.processor.util.MemberUtils.findAllDeclaredMembers; -import static io.microsphere.annotation.processor.util.MemberUtils.findDeclaredMembers; -import static io.microsphere.annotation.processor.util.MemberUtils.getAllDeclaredMembers; -import static io.microsphere.annotation.processor.util.MemberUtils.getDeclaredMembers; import static io.microsphere.lang.function.Predicates.alwaysFalse; import static io.microsphere.lang.function.Predicates.alwaysTrue; +import static io.microsphere.lang.model.util.MemberUtils.findAllDeclaredMembers; +import static io.microsphere.lang.model.util.MemberUtils.findDeclaredMembers; +import static io.microsphere.lang.model.util.MemberUtils.getAllDeclaredMembers; +import static io.microsphere.lang.model.util.MemberUtils.getDeclaredMembers; import static javax.lang.model.util.ElementFilter.fieldsIn; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -40,7 +39,7 @@ * @author Mercy * @since 1.0.0 */ -class MemberUtilsTest extends AbstractAnnotationProcessingTest { +class MemberUtilsTest extends UtilTest { @Test void testGetDeclaredMembers() { diff --git a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/util/MessagerUtilsTest.java b/microsphere-lang-model/src/test/java/io/microsphere/lang/model/util/MessagerUtilsTest.java similarity index 73% rename from microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/util/MessagerUtilsTest.java rename to microsphere-lang-model/src/test/java/io/microsphere/lang/model/util/MessagerUtilsTest.java index 9e7d629ae..554d4b4d2 100644 --- a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/util/MessagerUtilsTest.java +++ b/microsphere-lang-model/src/test/java/io/microsphere/lang/model/util/MessagerUtilsTest.java @@ -15,19 +15,21 @@ * limitations under the License. */ -package io.microsphere.annotation.processor.util; +package io.microsphere.lang.model.util; -import io.microsphere.annotation.processor.AbstractAnnotationProcessingTest; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.api.extension.ReflectiveInvocationContext; import javax.annotation.processing.Messager; +import java.lang.reflect.Method; -import static io.microsphere.annotation.processor.util.MessagerUtils.printError; -import static io.microsphere.annotation.processor.util.MessagerUtils.printMandatoryWarning; -import static io.microsphere.annotation.processor.util.MessagerUtils.printMessage; -import static io.microsphere.annotation.processor.util.MessagerUtils.printNote; -import static io.microsphere.annotation.processor.util.MessagerUtils.printWarning; +import static io.microsphere.lang.model.util.MessagerUtils.printError; +import static io.microsphere.lang.model.util.MessagerUtils.printMandatoryWarning; +import static io.microsphere.lang.model.util.MessagerUtils.printMessage; +import static io.microsphere.lang.model.util.MessagerUtils.printNote; +import static io.microsphere.lang.model.util.MessagerUtils.printWarning; import static javax.tools.Diagnostic.Kind.OTHER; /** @@ -38,12 +40,13 @@ * @see Messager * @since 1.0.0 */ -class MessagerUtilsTest extends AbstractAnnotationProcessingTest { +class MessagerUtilsTest extends UtilTest { private Messager messager; @Override - protected void beforeTest() { + protected void beforeTest(ReflectiveInvocationContext invocationContext, ExtensionContext extensionContext) { + super.beforeTest(invocationContext,extensionContext); this.messager = this.processingEnv.getMessager(); } diff --git a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/util/MethodUtilsTest.java b/microsphere-lang-model/src/test/java/io/microsphere/lang/model/util/MethodUtilsTest.java similarity index 90% rename from microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/util/MethodUtilsTest.java rename to microsphere-lang-model/src/test/java/io/microsphere/lang/model/util/MethodUtilsTest.java index f5e728b85..67a87679d 100644 --- a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/util/MethodUtilsTest.java +++ b/microsphere-lang-model/src/test/java/io/microsphere/lang/model/util/MethodUtilsTest.java @@ -14,45 +14,47 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.microsphere.annotation.processor.util; +package io.microsphere.lang.model.util; -import io.microsphere.annotation.processor.AbstractAnnotationProcessingTest; -import io.microsphere.annotation.processor.TestService; -import io.microsphere.annotation.processor.model.Model; import io.microsphere.constants.Constants; import io.microsphere.constants.PropertyConstants; +import io.microsphere.test.model.Model; +import io.microsphere.test.service.TestService; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.api.extension.ReflectiveInvocationContext; import javax.lang.model.element.Element; import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.TypeElement; import javax.lang.model.type.TypeMirror; import java.io.Serializable; +import java.lang.reflect.Method; import java.lang.reflect.Type; import java.util.List; import java.util.Set; -import static io.microsphere.annotation.processor.util.ElementUtils.isPublicNonStatic; -import static io.microsphere.annotation.processor.util.MemberUtils.getDeclaredMembers; -import static io.microsphere.annotation.processor.util.MethodUtils.filterMethods; -import static io.microsphere.annotation.processor.util.MethodUtils.findAllDeclaredMethods; -import static io.microsphere.annotation.processor.util.MethodUtils.findDeclaredMethods; -import static io.microsphere.annotation.processor.util.MethodUtils.findMethod; -import static io.microsphere.annotation.processor.util.MethodUtils.findPublicNonStaticMethods; -import static io.microsphere.annotation.processor.util.MethodUtils.getAllDeclaredMethods; -import static io.microsphere.annotation.processor.util.MethodUtils.getDeclaredMethods; -import static io.microsphere.annotation.processor.util.MethodUtils.getEnclosingElement; -import static io.microsphere.annotation.processor.util.MethodUtils.getMethodName; -import static io.microsphere.annotation.processor.util.MethodUtils.getMethodParameterTypeMirrors; -import static io.microsphere.annotation.processor.util.MethodUtils.getMethodParameterTypeNames; -import static io.microsphere.annotation.processor.util.MethodUtils.getOverrideMethod; -import static io.microsphere.annotation.processor.util.MethodUtils.getReturnTypeName; -import static io.microsphere.annotation.processor.util.MethodUtils.isMethod; -import static io.microsphere.annotation.processor.util.MethodUtils.isPublicNonStaticMethod; -import static io.microsphere.annotation.processor.util.MethodUtils.matches; import static io.microsphere.collection.Lists.ofList; import static io.microsphere.lang.function.Predicates.alwaysFalse; import static io.microsphere.lang.function.Predicates.alwaysTrue; +import static io.microsphere.lang.model.util.ElementUtils.isPublicNonStatic; +import static io.microsphere.lang.model.util.MemberUtils.getDeclaredMembers; +import static io.microsphere.lang.model.util.MethodUtils.filterMethods; +import static io.microsphere.lang.model.util.MethodUtils.findAllDeclaredMethods; +import static io.microsphere.lang.model.util.MethodUtils.findDeclaredMethods; +import static io.microsphere.lang.model.util.MethodUtils.findMethod; +import static io.microsphere.lang.model.util.MethodUtils.findPublicNonStaticMethods; +import static io.microsphere.lang.model.util.MethodUtils.getAllDeclaredMethods; +import static io.microsphere.lang.model.util.MethodUtils.getDeclaredMethods; +import static io.microsphere.lang.model.util.MethodUtils.getEnclosingElement; +import static io.microsphere.lang.model.util.MethodUtils.getMethodName; +import static io.microsphere.lang.model.util.MethodUtils.getMethodParameterTypeMirrors; +import static io.microsphere.lang.model.util.MethodUtils.getMethodParameterTypeNames; +import static io.microsphere.lang.model.util.MethodUtils.getOverrideMethod; +import static io.microsphere.lang.model.util.MethodUtils.getReturnTypeName; +import static io.microsphere.lang.model.util.MethodUtils.isMethod; +import static io.microsphere.lang.model.util.MethodUtils.isPublicNonStaticMethod; +import static io.microsphere.lang.model.util.MethodUtils.matches; import static io.microsphere.reflect.TypeUtils.getTypeNames; import static io.microsphere.util.ArrayUtils.EMPTY_STRING_ARRAY; import static io.microsphere.util.ArrayUtils.ofArray; @@ -71,7 +73,7 @@ * @author Mercy * @since 1.0.0 */ -class MethodUtilsTest extends AbstractAnnotationProcessingTest { +class MethodUtilsTest extends UtilTest { private List objectMethods; @@ -83,8 +85,8 @@ protected void addCompiledClasses(Set> compiledClasses) { } @Override - protected void beforeTest() { - super.beforeTest(); + protected void beforeTest(ReflectiveInvocationContext invocationContext, ExtensionContext extensionContext) { + super.beforeTest(invocationContext,extensionContext); TypeElement type = getTypeElement(Object.class); List methods = getDeclaredMethods(type); this.objectMethods = methods; diff --git a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/model/util/ResolvableAnnotationValueVisitorTest.java b/microsphere-lang-model/src/test/java/io/microsphere/lang/model/util/ResolvableAnnotationValueVisitorTest.java similarity index 78% rename from microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/model/util/ResolvableAnnotationValueVisitorTest.java rename to microsphere-lang-model/src/test/java/io/microsphere/lang/model/util/ResolvableAnnotationValueVisitorTest.java index 0f0ef36d7..3189ce3f9 100644 --- a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/model/util/ResolvableAnnotationValueVisitorTest.java +++ b/microsphere-lang-model/src/test/java/io/microsphere/lang/model/util/ResolvableAnnotationValueVisitorTest.java @@ -15,24 +15,26 @@ * limitations under the License. */ -package io.microsphere.annotation.processor.model.util; +package io.microsphere.lang.model.util; -import io.microsphere.annotation.processor.AbstractAnnotationProcessingTest; -import io.microsphere.annotation.processor.GenericTestService; -import io.microsphere.annotation.processor.TestAnnotation; -import io.microsphere.annotation.processor.TestService; +import io.microsphere.test.annotation.TestAnnotation; +import io.microsphere.test.service.GenericTestService; +import io.microsphere.test.service.TestService; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.api.extension.ReflectiveInvocationContext; import javax.lang.model.element.AnnotationValue; import javax.lang.model.element.AnnotationValueVisitor; import javax.lang.model.element.ExecutableElement; import java.io.Serializable; +import java.lang.reflect.Method; import java.util.LinkedHashMap; import java.util.Map; import java.util.Map.Entry; -import static io.microsphere.annotation.processor.util.AnnotationUtils.getElementValue; -import static io.microsphere.annotation.processor.util.AnnotationUtils.getElementValues; +import static io.microsphere.lang.model.util.AnnotationUtils.getElementValue; +import static io.microsphere.lang.model.util.AnnotationUtils.getElementValues; import static java.util.Objects.deepEquals; import static java.util.concurrent.TimeUnit.HOURS; import static java.util.stream.Stream.of; @@ -47,7 +49,7 @@ * @see ResolvableAnnotationValueVisitor * @since 1.0.0 */ -class ResolvableAnnotationValueVisitorTest extends AbstractAnnotationProcessingTest { +class ResolvableAnnotationValueVisitorTest extends UtilTest { private ResolvableAnnotationValueVisitor visitor; @@ -79,17 +81,18 @@ class ResolvableAnnotationValueVisitorTest extends AbstractAnnotationProcessingT private Map testAnnotationAttributes; - protected void beforeTest() { - super.beforeTest(); + @Override + protected void beforeTest(ReflectiveInvocationContext invocationContext, ExtensionContext extensionContext) { + super.beforeTest(invocationContext, extensionContext); this.visitor = new ResolvableAnnotationValueVisitor(); this.visitor1 = new ResolvableAnnotationValueVisitor(true); this.visitor2 = new ResolvableAnnotationValueVisitor(true, true); - this.testAnnotationAttributes = getElementValues(testTypeElement, TestAnnotation.class); + this.testAnnotationAttributes = getElementValues(this.testTypeElement, TestAnnotation.class); } @Test void testVisitBoolean() { - assertEquals(BOOLEAN_VALUE, visitor.visitBoolean(BOOLEAN_VALUE, null)); + assertEquals(BOOLEAN_VALUE, this.visitor.visitBoolean(BOOLEAN_VALUE, null)); assertVisit(this.visitor, "z", BOOLEAN_VALUE); assertVisit(this.visitor1, "z", BOOLEAN_VALUE); assertVisit(this.visitor2, "z", BOOLEAN_VALUE); @@ -97,7 +100,7 @@ void testVisitBoolean() { @Test void testVisitByte() { - assertEquals(BYTE_VALUE, visitor.visitByte(BYTE_VALUE, null)); + assertEquals(BYTE_VALUE, this.visitor.visitByte(BYTE_VALUE, null)); assertVisit(this.visitor, "b", BYTE_VALUE); assertVisit(this.visitor1, "b", BYTE_VALUE); assertVisit(this.visitor2, "b", BYTE_VALUE); @@ -105,7 +108,7 @@ void testVisitByte() { @Test void testVisitChar() { - assertEquals(CHAR_VALUE, visitor.visitChar(CHAR_VALUE, null)); + assertEquals(CHAR_VALUE, this.visitor.visitChar(CHAR_VALUE, null)); assertVisit(this.visitor, "c", CHAR_VALUE); assertVisit(this.visitor1, "c", CHAR_VALUE); assertVisit(this.visitor2, "c", CHAR_VALUE); @@ -113,7 +116,7 @@ void testVisitChar() { @Test void testVisitDouble() { - assertEquals(DOUBLE_VALUE, visitor.visitDouble(DOUBLE_VALUE, null)); + assertEquals(DOUBLE_VALUE, this.visitor.visitDouble(DOUBLE_VALUE, null)); assertVisit(this.visitor, "d", DOUBLE_VALUE); assertVisit(this.visitor1, "d", DOUBLE_VALUE); assertVisit(this.visitor2, "d", DOUBLE_VALUE); @@ -121,7 +124,7 @@ void testVisitDouble() { @Test void testVisitFloat() { - assertEquals(FLOAT_VALUE, visitor.visitFloat(FLOAT_VALUE, null)); + assertEquals(FLOAT_VALUE, this.visitor.visitFloat(FLOAT_VALUE, null)); assertVisit(this.visitor, "f", FLOAT_VALUE); assertVisit(this.visitor1, "f", FLOAT_VALUE); assertVisit(this.visitor2, "f", FLOAT_VALUE); @@ -129,7 +132,7 @@ void testVisitFloat() { @Test void testVisitInt() { - assertEquals(INT_VALUE, visitor.visitInt(INT_VALUE, null)); + assertEquals(INT_VALUE, this.visitor.visitInt(INT_VALUE, null)); assertVisit(this.visitor, "i", INT_VALUE); assertVisit(this.visitor1, "i", INT_VALUE); assertVisit(this.visitor2, "i", INT_VALUE); @@ -137,7 +140,7 @@ void testVisitInt() { @Test void testVisitLong() { - assertEquals(LONG_VALUE, visitor.visitLong(LONG_VALUE, null)); + assertEquals(LONG_VALUE, this.visitor.visitLong(LONG_VALUE, null)); assertVisit(this.visitor, "l", LONG_VALUE); assertVisit(this.visitor1, "l", LONG_VALUE); assertVisit(this.visitor2, "l", LONG_VALUE); @@ -145,7 +148,7 @@ void testVisitLong() { @Test void testVisitShort() { - assertEquals(SHORT_VALUE, visitor.visitShort(SHORT_VALUE, null)); + assertEquals(SHORT_VALUE, this.visitor.visitShort(SHORT_VALUE, null)); assertVisit(this.visitor, "s", SHORT_VALUE); assertVisit(this.visitor1, "s", SHORT_VALUE); assertVisit(this.visitor2, "s", SHORT_VALUE); @@ -153,15 +156,15 @@ void testVisitShort() { @Test void testVisitString() { - assertEquals(STRING_VALUE, visitor.visitString(STRING_VALUE, null)); + assertEquals(STRING_VALUE, this.visitor.visitString(STRING_VALUE, null)); assertVisit(this.visitor, "string", STRING_VALUE); assertVisit(this.visitor1, "string", STRING_VALUE); - assertVisit(this.visitor1, "string", STRING_VALUE); + assertVisit(this.visitor2, "string", STRING_VALUE); } @Test void testVisitType() { - assertEquals(TYPE_VALUE, visitor.visitType(getTypeMirror(TYPE_VALUE), null)); + assertEquals(TYPE_VALUE, this.visitor.visitType(getTypeMirror(TYPE_VALUE), null)); assertVisit(this.visitor, "type", TYPE_VALUE); assertVisit(this.visitor1, "type", TYPE_VALUE.getName()); assertVisit(this.visitor2, "type", TYPE_VALUE.getName()); @@ -201,7 +204,7 @@ void testVisitUnknown() { for (Entry elementValue : this.testAnnotationAttributes.entrySet()) { ExecutableElement attributeMethod = elementValue.getKey(); AnnotationValue annotationValue = elementValue.getValue(); - assertSame(annotationValue, visitor.visitUnknown(annotationValue, attributeMethod)); + assertSame(annotationValue, this.visitor.visitUnknown(annotationValue, attributeMethod)); } } diff --git a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/util/TypeUtilsTest.java b/microsphere-lang-model/src/test/java/io/microsphere/lang/model/util/TypeUtilsTest.java similarity index 94% rename from microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/util/TypeUtilsTest.java rename to microsphere-lang-model/src/test/java/io/microsphere/lang/model/util/TypeUtilsTest.java index 3908724fc..9e73f8b5c 100644 --- a/microsphere-annotation-processor/src/test/java/io/microsphere/annotation/processor/util/TypeUtilsTest.java +++ b/microsphere-lang-model/src/test/java/io/microsphere/lang/model/util/TypeUtilsTest.java @@ -14,19 +14,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.microsphere.annotation.processor.util; - -import io.microsphere.annotation.processor.AbstractAnnotationProcessingTest; -import io.microsphere.annotation.processor.DefaultTestService; -import io.microsphere.annotation.processor.GenericTestService; -import io.microsphere.annotation.processor.TestService; -import io.microsphere.annotation.processor.TestServiceImpl; -import io.microsphere.annotation.processor.model.ArrayTypeModel; -import io.microsphere.annotation.processor.model.CollectionTypeModel; -import io.microsphere.annotation.processor.model.Color; -import io.microsphere.annotation.processor.model.MapTypeModel; -import io.microsphere.annotation.processor.model.Model; -import io.microsphere.annotation.processor.model.PrimitiveTypeModel; +package io.microsphere.lang.model.util; + +import io.microsphere.test.model.ArrayTypeModel; +import io.microsphere.test.model.CollectionTypeModel; +import io.microsphere.test.model.Color; +import io.microsphere.test.model.MapTypeModel; +import io.microsphere.test.model.Model; +import io.microsphere.test.model.PrimitiveTypeModel; +import io.microsphere.test.service.DefaultTestService; +import io.microsphere.test.service.GenericTestService; +import io.microsphere.test.service.TestService; +import io.microsphere.test.service.TestServiceImpl; import org.junit.jupiter.api.Test; import javax.lang.model.element.Element; @@ -45,56 +44,56 @@ import java.util.concurrent.TimeUnit; import java.util.function.Predicate; -import static io.microsphere.annotation.processor.util.FieldUtils.findField; -import static io.microsphere.annotation.processor.util.FieldUtils.getDeclaredFields; -import static io.microsphere.annotation.processor.util.MethodUtils.findMethod; -import static io.microsphere.annotation.processor.util.TypeUtils.findAllDeclaredTypes; -import static io.microsphere.annotation.processor.util.TypeUtils.findAllDeclaredTypesOfInterfaces; -import static io.microsphere.annotation.processor.util.TypeUtils.findAllDeclaredTypesOfSuperTypes; -import static io.microsphere.annotation.processor.util.TypeUtils.findAllDeclaredTypesOfSuperclasses; -import static io.microsphere.annotation.processor.util.TypeUtils.findAllTypeElementsOfInterfaces; -import static io.microsphere.annotation.processor.util.TypeUtils.findAllTypeElementsOfSuperclasses; -import static io.microsphere.annotation.processor.util.TypeUtils.findAllTypeMirrorsOfInterfaces; -import static io.microsphere.annotation.processor.util.TypeUtils.findDeclaredTypes; -import static io.microsphere.annotation.processor.util.TypeUtils.findDeclaredTypesOfInterfaces; -import static io.microsphere.annotation.processor.util.TypeUtils.findInterfaceTypeMirror; -import static io.microsphere.annotation.processor.util.TypeUtils.findTypeElements; -import static io.microsphere.annotation.processor.util.TypeUtils.findTypeElementsOfInterfaces; -import static io.microsphere.annotation.processor.util.TypeUtils.findTypeMirrorsOfInterfaces; -import static io.microsphere.annotation.processor.util.TypeUtils.getAllDeclaredTypes; -import static io.microsphere.annotation.processor.util.TypeUtils.getAllDeclaredTypesOfInterfaces; -import static io.microsphere.annotation.processor.util.TypeUtils.getAllDeclaredTypesOfSuperTypes; -import static io.microsphere.annotation.processor.util.TypeUtils.getAllDeclaredTypesOfSuperclasses; -import static io.microsphere.annotation.processor.util.TypeUtils.getAllTypeElements; -import static io.microsphere.annotation.processor.util.TypeUtils.getAllTypeElementsOfInterfaces; -import static io.microsphere.annotation.processor.util.TypeUtils.getAllTypeElementsOfSuperTypes; -import static io.microsphere.annotation.processor.util.TypeUtils.getAllTypeElementsOfSuperclasses; -import static io.microsphere.annotation.processor.util.TypeUtils.getAllTypeMirrorsOfInterfaces; -import static io.microsphere.annotation.processor.util.TypeUtils.getDeclaredTypeOfSuperclass; -import static io.microsphere.annotation.processor.util.TypeUtils.getDeclaredTypes; -import static io.microsphere.annotation.processor.util.TypeUtils.getDeclaredTypesOfInterfaces; -import static io.microsphere.annotation.processor.util.TypeUtils.getTypeElementOfSuperclass; -import static io.microsphere.annotation.processor.util.TypeUtils.getTypeElementsOfInterfaces; -import static io.microsphere.annotation.processor.util.TypeUtils.getTypeMirrorsOfInterfaces; -import static io.microsphere.annotation.processor.util.TypeUtils.isAnnotationType; -import static io.microsphere.annotation.processor.util.TypeUtils.isArrayType; -import static io.microsphere.annotation.processor.util.TypeUtils.isClassType; -import static io.microsphere.annotation.processor.util.TypeUtils.isDeclaredType; -import static io.microsphere.annotation.processor.util.TypeUtils.isEnumType; -import static io.microsphere.annotation.processor.util.TypeUtils.isInterfaceType; -import static io.microsphere.annotation.processor.util.TypeUtils.isPrimitiveType; -import static io.microsphere.annotation.processor.util.TypeUtils.isSameType; -import static io.microsphere.annotation.processor.util.TypeUtils.isSimpleType; -import static io.microsphere.annotation.processor.util.TypeUtils.isTypeElement; -import static io.microsphere.annotation.processor.util.TypeUtils.ofDeclaredType; -import static io.microsphere.annotation.processor.util.TypeUtils.ofDeclaredTypes; -import static io.microsphere.annotation.processor.util.TypeUtils.ofTypeElement; -import static io.microsphere.annotation.processor.util.TypeUtils.ofTypeElements; -import static io.microsphere.annotation.processor.util.TypeUtils.ofTypeMirrors; -import static io.microsphere.annotation.processor.util.TypeUtils.typeElementFinder; import static io.microsphere.collection.ListUtils.ofList; import static io.microsphere.lang.function.Predicates.alwaysFalse; import static io.microsphere.lang.function.Predicates.alwaysTrue; +import static io.microsphere.lang.model.util.FieldUtils.findField; +import static io.microsphere.lang.model.util.FieldUtils.getDeclaredFields; +import static io.microsphere.lang.model.util.MethodUtils.findMethod; +import static io.microsphere.lang.model.util.TypeUtils.findAllDeclaredTypes; +import static io.microsphere.lang.model.util.TypeUtils.findAllDeclaredTypesOfInterfaces; +import static io.microsphere.lang.model.util.TypeUtils.findAllDeclaredTypesOfSuperTypes; +import static io.microsphere.lang.model.util.TypeUtils.findAllDeclaredTypesOfSuperclasses; +import static io.microsphere.lang.model.util.TypeUtils.findAllTypeElementsOfInterfaces; +import static io.microsphere.lang.model.util.TypeUtils.findAllTypeElementsOfSuperclasses; +import static io.microsphere.lang.model.util.TypeUtils.findAllTypeMirrorsOfInterfaces; +import static io.microsphere.lang.model.util.TypeUtils.findDeclaredTypes; +import static io.microsphere.lang.model.util.TypeUtils.findDeclaredTypesOfInterfaces; +import static io.microsphere.lang.model.util.TypeUtils.findInterfaceTypeMirror; +import static io.microsphere.lang.model.util.TypeUtils.findTypeElements; +import static io.microsphere.lang.model.util.TypeUtils.findTypeElementsOfInterfaces; +import static io.microsphere.lang.model.util.TypeUtils.findTypeMirrorsOfInterfaces; +import static io.microsphere.lang.model.util.TypeUtils.getAllDeclaredTypes; +import static io.microsphere.lang.model.util.TypeUtils.getAllDeclaredTypesOfInterfaces; +import static io.microsphere.lang.model.util.TypeUtils.getAllDeclaredTypesOfSuperTypes; +import static io.microsphere.lang.model.util.TypeUtils.getAllDeclaredTypesOfSuperclasses; +import static io.microsphere.lang.model.util.TypeUtils.getAllTypeElements; +import static io.microsphere.lang.model.util.TypeUtils.getAllTypeElementsOfInterfaces; +import static io.microsphere.lang.model.util.TypeUtils.getAllTypeElementsOfSuperTypes; +import static io.microsphere.lang.model.util.TypeUtils.getAllTypeElementsOfSuperclasses; +import static io.microsphere.lang.model.util.TypeUtils.getAllTypeMirrorsOfInterfaces; +import static io.microsphere.lang.model.util.TypeUtils.getDeclaredTypeOfSuperclass; +import static io.microsphere.lang.model.util.TypeUtils.getDeclaredTypes; +import static io.microsphere.lang.model.util.TypeUtils.getDeclaredTypesOfInterfaces; +import static io.microsphere.lang.model.util.TypeUtils.getTypeElementOfSuperclass; +import static io.microsphere.lang.model.util.TypeUtils.getTypeElementsOfInterfaces; +import static io.microsphere.lang.model.util.TypeUtils.getTypeMirrorsOfInterfaces; +import static io.microsphere.lang.model.util.TypeUtils.isAnnotationType; +import static io.microsphere.lang.model.util.TypeUtils.isArrayType; +import static io.microsphere.lang.model.util.TypeUtils.isClassType; +import static io.microsphere.lang.model.util.TypeUtils.isDeclaredType; +import static io.microsphere.lang.model.util.TypeUtils.isEnumType; +import static io.microsphere.lang.model.util.TypeUtils.isInterfaceType; +import static io.microsphere.lang.model.util.TypeUtils.isPrimitiveType; +import static io.microsphere.lang.model.util.TypeUtils.isSameType; +import static io.microsphere.lang.model.util.TypeUtils.isSimpleType; +import static io.microsphere.lang.model.util.TypeUtils.isTypeElement; +import static io.microsphere.lang.model.util.TypeUtils.ofDeclaredType; +import static io.microsphere.lang.model.util.TypeUtils.ofDeclaredTypes; +import static io.microsphere.lang.model.util.TypeUtils.ofTypeElement; +import static io.microsphere.lang.model.util.TypeUtils.ofTypeElements; +import static io.microsphere.lang.model.util.TypeUtils.ofTypeMirrors; +import static io.microsphere.lang.model.util.TypeUtils.typeElementFinder; import static io.microsphere.reflect.TypeUtils.getTypeNames; import static io.microsphere.util.ArrayUtils.EMPTY_STRING_ARRAY; import static io.microsphere.util.ArrayUtils.combine; @@ -114,7 +113,7 @@ * @author Mercy * @since 1.0.0 */ -class TypeUtilsTest extends AbstractAnnotationProcessingTest { +class TypeUtilsTest extends UtilTest { /** * self type diff --git a/microsphere-lang-model/src/test/java/io/microsphere/lang/model/util/UtilTest.java b/microsphere-lang-model/src/test/java/io/microsphere/lang/model/util/UtilTest.java new file mode 100644 index 000000000..2730dab41 --- /dev/null +++ b/microsphere-lang-model/src/test/java/io/microsphere/lang/model/util/UtilTest.java @@ -0,0 +1,97 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 io.microsphere.lang.model.util; + +import io.microsphere.test.annotation.processing.AbstractAnnotationProcessingTest; +import io.microsphere.test.service.TestServiceImpl; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.api.extension.ReflectiveInvocationContext; + +import javax.lang.model.element.Element; +import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.TypeElement; +import javax.lang.model.element.VariableElement; +import javax.lang.model.type.DeclaredType; +import javax.lang.model.type.TypeMirror; +import java.lang.reflect.Method; +import java.lang.reflect.Type; +import java.util.List; + +import static io.microsphere.lang.model.util.ConstructorUtils.findConstructor; +import static io.microsphere.lang.model.util.FieldUtils.findField; +import static io.microsphere.lang.model.util.MethodUtils.findMethod; +import static java.util.Collections.emptyList; +import static org.junit.jupiter.api.Assertions.assertSame; + +/** + * The utilies class for testing + * + * @author Mercy + * @see AbstractAnnotationProcessingTest + * @since 1.0.0 + */ +public abstract class UtilTest extends AbstractAnnotationProcessingTest { + + @Override + protected void beforeTest(ReflectiveInvocationContext invocationContext, ExtensionContext extensionContext) { + initTestClass(TestServiceImpl.class); + } + + protected List getTypeMirrors(Type... types) { + return TypeUtils.getTypeMirrors(processingEnv, types); + } + + protected TypeMirror getTypeMirror(Type type) { + return TypeUtils.getTypeMirror(processingEnv, type); + } + + protected List getTypeElements(Type... types) { + return TypeUtils.getTypeElements(processingEnv, types); + } + + protected TypeElement getTypeElement(Type type) { + return TypeUtils.getTypeElement(processingEnv, type); + } + + protected VariableElement getField(Type type, String fieldName) { + TypeElement typeElement = getTypeElement(type); + return findField(typeElement, fieldName); + } + + protected ExecutableElement getMethod(Type type, String methodName, Type... parameterTypes) { + TypeElement typeElement = getTypeElement(type); + return findMethod(typeElement, methodName, parameterTypes); + } + + protected ExecutableElement getConstructor(Type type, Type... parameterTypes) { + TypeElement typeElement = getTypeElement(type); + return findConstructor(typeElement, parameterTypes); + } + + protected Element[] getElements(Type... types) { + return getTypeMirrors(types).stream().map(TypeUtils::ofTypeElement).toArray(Element[]::new); + } + + protected DeclaredType getDeclaredType(Type type) { + return TypeUtils.getDeclaredType(processingEnv, type); + } + + protected void assertEmptyList(List list) { + assertSame(emptyList(), list); + } +} diff --git a/mvnw b/mvnw index 8a8fb2282..bd8896bf2 100755 --- a/mvnw +++ b/mvnw @@ -8,7 +8,7 @@ # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # -# https://www.apache.org/licenses/LICENSE-2.0 +# 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 @@ -19,298 +19,277 @@ # ---------------------------------------------------------------------------- # ---------------------------------------------------------------------------- -# Maven Start Up Batch script -# -# Required ENV vars: -# ------------------ -# JAVA_HOME - location of a JDK home dir +# Apache Maven Wrapper startup batch script, version 3.3.4 # # Optional ENV vars # ----------------- -# M2_HOME - location of maven2's installed home dir -# MAVEN_OPTS - parameters passed to the Java VM when running Maven -# e.g. to debug Maven itself, use -# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 -# MAVEN_SKIP_RC - flag to disable loading of mavenrc files +# JAVA_HOME - location of a JDK home dir, required when download maven via java source +# MVNW_REPOURL - repo url base for downloading maven distribution +# MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven +# MVNW_VERBOSE - true: enable verbose log; debug: trace the mvnw script; others: silence the output # ---------------------------------------------------------------------------- -if [ -z "$MAVEN_SKIP_RC" ] ; then - - if [ -f /usr/local/etc/mavenrc ] ; then - . /usr/local/etc/mavenrc - fi - - if [ -f /etc/mavenrc ] ; then - . /etc/mavenrc - fi +set -euf +[ "${MVNW_VERBOSE-}" != debug ] || set -x - if [ -f "$HOME/.mavenrc" ] ; then - . "$HOME/.mavenrc" - fi +# OS specific support. +native_path() { printf %s\\n "$1"; } +case "$(uname)" in +CYGWIN* | MINGW*) + [ -z "${JAVA_HOME-}" ] || JAVA_HOME="$(cygpath --unix "$JAVA_HOME")" + native_path() { cygpath --path --windows "$1"; } + ;; +esac -fi +# set JAVACMD and JAVACCMD +set_java_home() { + # For Cygwin and MinGW, ensure paths are in Unix format before anything is touched + if [ -n "${JAVA_HOME-}" ]; then + if [ -x "$JAVA_HOME/jre/sh/java" ]; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + JAVACCMD="$JAVA_HOME/jre/sh/javac" + else + JAVACMD="$JAVA_HOME/bin/java" + JAVACCMD="$JAVA_HOME/bin/javac" -# OS specific support. $var _must_ be set to either true or false. -cygwin=false; -darwin=false; -mingw=false -case "`uname`" in - CYGWIN*) cygwin=true ;; - MINGW*) mingw=true;; - Darwin*) darwin=true - # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home - # See https://developer.apple.com/library/mac/qa/qa1170/_index.html - if [ -z "$JAVA_HOME" ]; then - if [ -x "/usr/libexec/java_home" ]; then - export JAVA_HOME="`/usr/libexec/java_home`" - else - export JAVA_HOME="/Library/Java/Home" + if [ ! -x "$JAVACMD" ] || [ ! -x "$JAVACCMD" ]; then + echo "The JAVA_HOME environment variable is not defined correctly, so mvnw cannot run." >&2 + echo "JAVA_HOME is set to \"$JAVA_HOME\", but \"\$JAVA_HOME/bin/java\" or \"\$JAVA_HOME/bin/javac\" does not exist." >&2 + return 1 fi fi - ;; -esac - -if [ -z "$JAVA_HOME" ] ; then - if [ -r /etc/gentoo-release ] ; then - JAVA_HOME=`java-config --jre-home` + else + JAVACMD="$( + 'set' +e + 'unset' -f command 2>/dev/null + 'command' -v java + )" || : + JAVACCMD="$( + 'set' +e + 'unset' -f command 2>/dev/null + 'command' -v javac + )" || : + + if [ ! -x "${JAVACMD-}" ] || [ ! -x "${JAVACCMD-}" ]; then + echo "The java/javac command does not exist in PATH nor is JAVA_HOME set, so mvnw cannot run." >&2 + return 1 + fi fi -fi - -if [ -z "$M2_HOME" ] ; then - ## resolve links - $0 may be a link to maven's home - PRG="$0" +} - # need this for relative symlinks - while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG="`dirname "$PRG"`/$link" - fi +# hash string like Java String::hashCode +hash_string() { + str="${1:-}" h=0 + while [ -n "$str" ]; do + char="${str%"${str#?}"}" + h=$(((h * 31 + $(LC_CTYPE=C printf %d "'$char")) % 4294967296)) + str="${str#?}" done + printf %x\\n $h +} - saveddir=`pwd` +verbose() { :; } +[ "${MVNW_VERBOSE-}" != true ] || verbose() { printf %s\\n "${1-}"; } - M2_HOME=`dirname "$PRG"`/.. +die() { + printf %s\\n "$1" >&2 + exit 1 +} - # make it fully qualified - M2_HOME=`cd "$M2_HOME" && pwd` +trim() { + # MWRAPPER-139: + # Trims trailing and leading whitespace, carriage returns, tabs, and linefeeds. + # Needed for removing poorly interpreted newline sequences when running in more + # exotic environments such as mingw bash on Windows. + printf "%s" "${1}" | tr -d '[:space:]' +} - cd "$saveddir" - # echo Using m2 at $M2_HOME -fi +scriptDir="$(dirname "$0")" +scriptName="$(basename "$0")" + +# parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties +while IFS="=" read -r key value; do + case "${key-}" in + distributionUrl) distributionUrl=$(trim "${value-}") ;; + distributionSha256Sum) distributionSha256Sum=$(trim "${value-}") ;; + esac +done <"$scriptDir/.mvn/wrapper/maven-wrapper.properties" +[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" + +case "${distributionUrl##*/}" in +maven-mvnd-*bin.*) + MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ + case "${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)" in + *AMD64:CYGWIN* | *AMD64:MINGW*) distributionPlatform=windows-amd64 ;; + :Darwin*x86_64) distributionPlatform=darwin-amd64 ;; + :Darwin*arm64) distributionPlatform=darwin-aarch64 ;; + :Linux*x86_64*) distributionPlatform=linux-amd64 ;; + *) + echo "Cannot detect native platform for mvnd on $(uname)-$(uname -m), use pure java version" >&2 + distributionPlatform=linux-amd64 + ;; + esac + distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip" + ;; +maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;; +*) MVN_CMD="mvn${scriptName#mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;; +esac -# For Cygwin, ensure paths are in UNIX format before anything is touched -if $cygwin ; then - [ -n "$M2_HOME" ] && - M2_HOME=`cygpath --unix "$M2_HOME"` - [ -n "$JAVA_HOME" ] && - JAVA_HOME=`cygpath --unix "$JAVA_HOME"` - [ -n "$CLASSPATH" ] && - CLASSPATH=`cygpath --path --unix "$CLASSPATH"` -fi +# apply MVNW_REPOURL and calculate MAVEN_HOME +# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ +[ -z "${MVNW_REPOURL-}" ] || distributionUrl="$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*"$_MVNW_REPO_PATTERN"}" +distributionUrlName="${distributionUrl##*/}" +distributionUrlNameMain="${distributionUrlName%.*}" +distributionUrlNameMain="${distributionUrlNameMain%-bin}" +MAVEN_USER_HOME="${MAVEN_USER_HOME:-${HOME}/.m2}" +MAVEN_HOME="${MAVEN_USER_HOME}/wrapper/dists/${distributionUrlNameMain-}/$(hash_string "$distributionUrl")" + +exec_maven() { + unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || : + exec "$MAVEN_HOME/bin/$MVN_CMD" "$@" || die "cannot exec $MAVEN_HOME/bin/$MVN_CMD" +} -# For Mingw, ensure paths are in UNIX format before anything is touched -if $mingw ; then - [ -n "$M2_HOME" ] && - M2_HOME="`(cd "$M2_HOME"; pwd)`" - [ -n "$JAVA_HOME" ] && - JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" +if [ -d "$MAVEN_HOME" ]; then + verbose "found existing MAVEN_HOME at $MAVEN_HOME" + exec_maven "$@" fi -if [ -z "$JAVA_HOME" ]; then - javaExecutable="`which javac`" - if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then - # readlink(1) is not available as standard on Solaris 10. - readLink=`which readlink` - if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then - if $darwin ; then - javaHome="`dirname \"$javaExecutable\"`" - javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" - else - javaExecutable="`readlink -f \"$javaExecutable\"`" - fi - javaHome="`dirname \"$javaExecutable\"`" - javaHome=`expr "$javaHome" : '\(.*\)/bin'` - JAVA_HOME="$javaHome" - export JAVA_HOME - fi - fi -fi +case "${distributionUrl-}" in +*?-bin.zip | *?maven-mvnd-?*-?*.zip) ;; +*) die "distributionUrl is not valid, must match *-bin.zip or maven-mvnd-*.zip, but found '${distributionUrl-}'" ;; +esac -if [ -z "$JAVACMD" ] ; then - if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - else - JAVACMD="`\\unset -f command; \\command -v java`" - fi +# prepare tmp dir +if TMP_DOWNLOAD_DIR="$(mktemp -d)" && [ -d "$TMP_DOWNLOAD_DIR" ]; then + clean() { rm -rf -- "$TMP_DOWNLOAD_DIR"; } + trap clean HUP INT TERM EXIT +else + die "cannot create temp dir" fi -if [ ! -x "$JAVACMD" ] ; then - echo "Error: JAVA_HOME is not defined correctly." >&2 - echo " We cannot execute $JAVACMD" >&2 - exit 1 -fi +mkdir -p -- "${MAVEN_HOME%/*}" + +# Download and Install Apache Maven +verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." +verbose "Downloading from: $distributionUrl" +verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" -if [ -z "$JAVA_HOME" ] ; then - echo "Warning: JAVA_HOME environment variable is not set." +# select .zip or .tar.gz +if ! command -v unzip >/dev/null; then + distributionUrl="${distributionUrl%.zip}.tar.gz" + distributionUrlName="${distributionUrl##*/}" fi -CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher +# verbose opt +__MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q __MVNW_QUIET_TAR='' +[ "${MVNW_VERBOSE-}" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' __MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v -# traverses directory structure from process work directory to filesystem root -# first directory with .mvn subdirectory is considered project base directory -find_maven_basedir() { +# normalize http auth +case "${MVNW_PASSWORD:+has-password}" in +'') MVNW_USERNAME='' MVNW_PASSWORD='' ;; +has-password) [ -n "${MVNW_USERNAME-}" ] || MVNW_USERNAME='' MVNW_PASSWORD='' ;; +esac - if [ -z "$1" ] - then - echo "Path not specified to find_maven_basedir" - return 1 - fi +if [ -z "${MVNW_USERNAME-}" ] && command -v wget >/dev/null; then + verbose "Found wget ... using wget" + wget ${__MVNW_QUIET_WGET:+"$__MVNW_QUIET_WGET"} "$distributionUrl" -O "$TMP_DOWNLOAD_DIR/$distributionUrlName" || die "wget: Failed to fetch $distributionUrl" +elif [ -z "${MVNW_USERNAME-}" ] && command -v curl >/dev/null; then + verbose "Found curl ... using curl" + curl ${__MVNW_QUIET_CURL:+"$__MVNW_QUIET_CURL"} -f -L -o "$TMP_DOWNLOAD_DIR/$distributionUrlName" "$distributionUrl" || die "curl: Failed to fetch $distributionUrl" +elif set_java_home; then + verbose "Falling back to use Java to download" + javaSource="$TMP_DOWNLOAD_DIR/Downloader.java" + targetZip="$TMP_DOWNLOAD_DIR/$distributionUrlName" + cat >"$javaSource" <<-END + public class Downloader extends java.net.Authenticator + { + protected java.net.PasswordAuthentication getPasswordAuthentication() + { + return new java.net.PasswordAuthentication( System.getenv( "MVNW_USERNAME" ), System.getenv( "MVNW_PASSWORD" ).toCharArray() ); + } + public static void main( String[] args ) throws Exception + { + setDefault( new Downloader() ); + java.nio.file.Files.copy( java.net.URI.create( args[0] ).toURL().openStream(), java.nio.file.Paths.get( args[1] ).toAbsolutePath().normalize() ); + } + } + END + # For Cygwin/MinGW, switch paths to Windows format before running javac and java + verbose " - Compiling Downloader.java ..." + "$(native_path "$JAVACCMD")" "$(native_path "$javaSource")" || die "Failed to compile Downloader.java" + verbose " - Running Downloader.java ..." + "$(native_path "$JAVACMD")" -cp "$(native_path "$TMP_DOWNLOAD_DIR")" Downloader "$distributionUrl" "$(native_path "$targetZip")" +fi - basedir="$1" - wdir="$1" - while [ "$wdir" != '/' ] ; do - if [ -d "$wdir"/.mvn ] ; then - basedir=$wdir - break +# If specified, validate the SHA-256 sum of the Maven distribution zip file +if [ -n "${distributionSha256Sum-}" ]; then + distributionSha256Result=false + if [ "$MVN_CMD" = mvnd.sh ]; then + echo "Checksum validation is not supported for maven-mvnd." >&2 + echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 + exit 1 + elif command -v sha256sum >/dev/null; then + if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c - >/dev/null 2>&1; then + distributionSha256Result=true fi - # workaround for JBEAP-8937 (on Solaris 10/Sparc) - if [ -d "${wdir}" ]; then - wdir=`cd "$wdir/.."; pwd` + elif command -v shasum >/dev/null; then + if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | shasum -a 256 -c >/dev/null 2>&1; then + distributionSha256Result=true fi - # end of workaround - done - echo "${basedir}" -} - -# concatenates all lines of a file -concat_lines() { - if [ -f "$1" ]; then - echo "$(tr -s '\n' ' ' < "$1")" + else + echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2 + echo "Please install either command, or disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 + exit 1 + fi + if [ $distributionSha256Result = false ]; then + echo "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised." >&2 + echo "If you updated your Maven version, you need to update the specified distributionSha256Sum property." >&2 + exit 1 fi -} - -BASE_DIR=`find_maven_basedir "$(pwd)"` -if [ -z "$BASE_DIR" ]; then - exit 1; fi -########################################################################################## -# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central -# This allows using the maven wrapper in projects that prohibit checking in binary data. -########################################################################################## -if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then - if [ "$MVNW_VERBOSE" = true ]; then - echo "Found .mvn/wrapper/maven-wrapper.jar" - fi +# unzip and move +if command -v unzip >/dev/null; then + unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" || die "failed to unzip" else - if [ "$MVNW_VERBOSE" = true ]; then - echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." - fi - if [ -n "$MVNW_REPOURL" ]; then - jarUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" - else - jarUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" - fi - while IFS="=" read key value; do - case "$key" in (wrapperUrl) jarUrl="$value"; break ;; - esac - done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" - if [ "$MVNW_VERBOSE" = true ]; then - echo "Downloading from: $jarUrl" - fi - wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" - if $cygwin; then - wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` - fi + tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed to untar" +fi - if command -v wget > /dev/null; then - if [ "$MVNW_VERBOSE" = true ]; then - echo "Found wget ... using wget" - fi - if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then - wget "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" - else - wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" - fi - elif command -v curl > /dev/null; then - if [ "$MVNW_VERBOSE" = true ]; then - echo "Found curl ... using curl" - fi - if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then - curl -o "$wrapperJarPath" "$jarUrl" -f - else - curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f - fi +# Find the actual extracted directory name (handles snapshots where filename != directory name) +actualDistributionDir="" - else - if [ "$MVNW_VERBOSE" = true ]; then - echo "Falling back to using Java to download" - fi - javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" - # For Cygwin, switch paths to Windows format before running javac - if $cygwin; then - javaClass=`cygpath --path --windows "$javaClass"` - fi - if [ -e "$javaClass" ]; then - if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then - if [ "$MVNW_VERBOSE" = true ]; then - echo " - Compiling MavenWrapperDownloader.java ..." - fi - # Compiling the Java class - ("$JAVA_HOME/bin/javac" "$javaClass") - fi - if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then - # Running the downloader - if [ "$MVNW_VERBOSE" = true ]; then - echo " - Running MavenWrapperDownloader.java ..." - fi - ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") - fi - fi - fi +# First try the expected directory name (for regular distributions) +if [ -d "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" ]; then + if [ -f "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/bin/$MVN_CMD" ]; then + actualDistributionDir="$distributionUrlNameMain" + fi fi -########################################################################################## -# End of extension -########################################################################################## -export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} -if [ "$MVNW_VERBOSE" = true ]; then - echo $MAVEN_PROJECTBASEDIR -fi -MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" - -# For Cygwin, switch paths to Windows format before running java -if $cygwin; then - [ -n "$M2_HOME" ] && - M2_HOME=`cygpath --path --windows "$M2_HOME"` - [ -n "$JAVA_HOME" ] && - JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` - [ -n "$CLASSPATH" ] && - CLASSPATH=`cygpath --path --windows "$CLASSPATH"` - [ -n "$MAVEN_PROJECTBASEDIR" ] && - MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` +# If not found, search for any directory with the Maven executable (for snapshots) +if [ -z "$actualDistributionDir" ]; then + # enable globbing to iterate over items + set +f + for dir in "$TMP_DOWNLOAD_DIR"/*; do + if [ -d "$dir" ]; then + if [ -f "$dir/bin/$MVN_CMD" ]; then + actualDistributionDir="$(basename "$dir")" + break + fi + fi + done + set -f fi -# Provide a "standardized" way to retrieve the CLI args that will -# work with both Windows and non-Windows executions. -MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" -export MAVEN_CMD_LINE_ARGS +if [ -z "$actualDistributionDir" ]; then + verbose "Contents of $TMP_DOWNLOAD_DIR:" + verbose "$(ls -la "$TMP_DOWNLOAD_DIR")" + die "Could not find Maven distribution directory in extracted archive" +fi -WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain +verbose "Found extracted Maven distribution directory: $actualDistributionDir" +printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$actualDistributionDir/mvnw.url" +mv -- "$TMP_DOWNLOAD_DIR/$actualDistributionDir" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME" -exec "$JAVACMD" \ - $MAVEN_OPTS \ - $MAVEN_DEBUG_OPTS \ - -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ - "-Dmaven.home=${M2_HOME}" \ - "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ - ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" +clean || : +exec_maven "$@" diff --git a/mvnw.cmd b/mvnw.cmd index 1d8ab018e..5761d9489 100644 --- a/mvnw.cmd +++ b/mvnw.cmd @@ -1,188 +1,189 @@ -@REM ---------------------------------------------------------------------------- -@REM Licensed to the Apache Software Foundation (ASF) under one -@REM or more contributor license agreements. See the NOTICE file -@REM distributed with this work for additional information -@REM regarding copyright ownership. The ASF licenses this file -@REM to you under the Apache License, Version 2.0 (the -@REM "License"); you may not use this file except in compliance -@REM with the License. You may obtain a copy of the License at -@REM -@REM https://www.apache.org/licenses/LICENSE-2.0 -@REM -@REM Unless required by applicable law or agreed to in writing, -@REM software distributed under the License is distributed on an -@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -@REM KIND, either express or implied. See the License for the -@REM specific language governing permissions and limitations -@REM under the License. -@REM ---------------------------------------------------------------------------- - -@REM ---------------------------------------------------------------------------- -@REM Maven Start Up Batch script -@REM -@REM Required ENV vars: -@REM JAVA_HOME - location of a JDK home dir -@REM -@REM Optional ENV vars -@REM M2_HOME - location of maven2's installed home dir -@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands -@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending -@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven -@REM e.g. to debug Maven itself, use -@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 -@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files -@REM ---------------------------------------------------------------------------- - -@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' -@echo off -@REM set title of command window -title %0 -@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' -@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% - -@REM set %HOME% to equivalent of $HOME -if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") - -@REM Execute a user defined script before this one -if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre -@REM check for pre script, once with legacy .bat ending and once with .cmd ending -if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %* -if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %* -:skipRcPre - -@setlocal - -set ERROR_CODE=0 - -@REM To isolate internal variables from possible post scripts, we use another setlocal -@setlocal - -@REM ==== START VALIDATION ==== -if not "%JAVA_HOME%" == "" goto OkJHome - -echo. -echo Error: JAVA_HOME not found in your environment. >&2 -echo Please set the JAVA_HOME variable in your environment to match the >&2 -echo location of your Java installation. >&2 -echo. -goto error - -:OkJHome -if exist "%JAVA_HOME%\bin\java.exe" goto init - -echo. -echo Error: JAVA_HOME is set to an invalid directory. >&2 -echo JAVA_HOME = "%JAVA_HOME%" >&2 -echo Please set the JAVA_HOME variable in your environment to match the >&2 -echo location of your Java installation. >&2 -echo. -goto error - -@REM ==== END VALIDATION ==== - -:init - -@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". -@REM Fallback to current working directory if not found. - -set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% -IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir - -set EXEC_DIR=%CD% -set WDIR=%EXEC_DIR% -:findBaseDir -IF EXIST "%WDIR%"\.mvn goto baseDirFound -cd .. -IF "%WDIR%"=="%CD%" goto baseDirNotFound -set WDIR=%CD% -goto findBaseDir - -:baseDirFound -set MAVEN_PROJECTBASEDIR=%WDIR% -cd "%EXEC_DIR%" -goto endDetectBaseDir - -:baseDirNotFound -set MAVEN_PROJECTBASEDIR=%EXEC_DIR% -cd "%EXEC_DIR%" - -:endDetectBaseDir - -IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig - -@setlocal EnableExtensions EnableDelayedExpansion -for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a -@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% - -:endReadAdditionalConfig - -SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" -set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" -set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain - -set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" - -FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( - IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B -) - -@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central -@REM This allows using the maven wrapper in projects that prohibit checking in binary data. -if exist %WRAPPER_JAR% ( - if "%MVNW_VERBOSE%" == "true" ( - echo Found %WRAPPER_JAR% - ) -) else ( - if not "%MVNW_REPOURL%" == "" ( - SET DOWNLOAD_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" - ) - if "%MVNW_VERBOSE%" == "true" ( - echo Couldn't find %WRAPPER_JAR%, downloading it ... - echo Downloading from: %DOWNLOAD_URL% - ) - - powershell -Command "&{"^ - "$webclient = new-object System.Net.WebClient;"^ - "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ - "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ - "}"^ - "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ - "}" - if "%MVNW_VERBOSE%" == "true" ( - echo Finished downloading %WRAPPER_JAR% - ) -) -@REM End of extension - -@REM Provide a "standardized" way to retrieve the CLI args that will -@REM work with both Windows and non-Windows executions. -set MAVEN_CMD_LINE_ARGS=%* - -%MAVEN_JAVA_EXE% ^ - %JVM_CONFIG_MAVEN_PROPS% ^ - %MAVEN_OPTS% ^ - %MAVEN_DEBUG_OPTS% ^ - -classpath %WRAPPER_JAR% ^ - "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^ - %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* -if ERRORLEVEL 1 goto error -goto end - -:error -set ERROR_CODE=1 - -:end -@endlocal & set ERROR_CODE=%ERROR_CODE% - -if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost -@REM check for post script, once with legacy .bat ending and once with .cmd ending -if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat" -if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd" -:skipRcPost - -@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' -if "%MAVEN_BATCH_PAUSE%"=="on" pause - -if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE% - -cmd /C exit /B %ERROR_CODE% +<# : batch portion +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Apache Maven Wrapper startup batch script, version 3.3.4 +@REM +@REM Optional ENV vars +@REM MVNW_REPOURL - repo url base for downloading maven distribution +@REM MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven +@REM MVNW_VERBOSE - true: enable verbose log; others: silence the output +@REM ---------------------------------------------------------------------------- + +@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0) +@SET __MVNW_CMD__= +@SET __MVNW_ERROR__= +@SET __MVNW_PSMODULEP_SAVE=%PSModulePath% +@SET PSModulePath= +@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @( + IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B) +) +@SET PSModulePath=%__MVNW_PSMODULEP_SAVE% +@SET __MVNW_PSMODULEP_SAVE= +@SET __MVNW_ARG0_NAME__= +@SET MVNW_USERNAME= +@SET MVNW_PASSWORD= +@IF NOT "%__MVNW_CMD__%"=="" ("%__MVNW_CMD__%" %*) +@echo Cannot start maven from wrapper >&2 && exit /b 1 +@GOTO :EOF +: end batch / begin powershell #> + +$ErrorActionPreference = "Stop" +if ($env:MVNW_VERBOSE -eq "true") { + $VerbosePreference = "Continue" +} + +# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties +$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl +if (!$distributionUrl) { + Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" +} + +switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) { + "maven-mvnd-*" { + $USE_MVND = $true + $distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip" + $MVN_CMD = "mvnd.cmd" + break + } + default { + $USE_MVND = $false + $MVN_CMD = $script -replace '^mvnw','mvn' + break + } +} + +# apply MVNW_REPOURL and calculate MAVEN_HOME +# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ +if ($env:MVNW_REPOURL) { + $MVNW_REPO_PATTERN = if ($USE_MVND -eq $False) { "/org/apache/maven/" } else { "/maven/mvnd/" } + $distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace "^.*$MVNW_REPO_PATTERN",'')" +} +$distributionUrlName = $distributionUrl -replace '^.*/','' +$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$','' + +$MAVEN_M2_PATH = "$HOME/.m2" +if ($env:MAVEN_USER_HOME) { + $MAVEN_M2_PATH = "$env:MAVEN_USER_HOME" +} + +if (-not (Test-Path -Path $MAVEN_M2_PATH)) { + New-Item -Path $MAVEN_M2_PATH -ItemType Directory | Out-Null +} + +$MAVEN_WRAPPER_DISTS = $null +if ((Get-Item $MAVEN_M2_PATH).Target[0] -eq $null) { + $MAVEN_WRAPPER_DISTS = "$MAVEN_M2_PATH/wrapper/dists" +} else { + $MAVEN_WRAPPER_DISTS = (Get-Item $MAVEN_M2_PATH).Target[0] + "/wrapper/dists" +} + +$MAVEN_HOME_PARENT = "$MAVEN_WRAPPER_DISTS/$distributionUrlNameMain" +$MAVEN_HOME_NAME = ([System.Security.Cryptography.SHA256]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join '' +$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME" + +if (Test-Path -Path "$MAVEN_HOME" -PathType Container) { + Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME" + Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" + exit $? +} + +if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) { + Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl" +} + +# prepare tmp dir +$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile +$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir" +$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null +trap { + if ($TMP_DOWNLOAD_DIR.Exists) { + try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } + catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } + } +} + +New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null + +# Download and Install Apache Maven +Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." +Write-Verbose "Downloading from: $distributionUrl" +Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" + +$webclient = New-Object System.Net.WebClient +if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) { + $webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD) +} +[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 +$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null + +# If specified, validate the SHA-256 sum of the Maven distribution zip file +$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum +if ($distributionSha256Sum) { + if ($USE_MVND) { + Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." + } + Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash + if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) { + Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property." + } +} + +# unzip and move +Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null + +# Find the actual extracted directory name (handles snapshots where filename != directory name) +$actualDistributionDir = "" + +# First try the expected directory name (for regular distributions) +$expectedPath = Join-Path "$TMP_DOWNLOAD_DIR" "$distributionUrlNameMain" +$expectedMvnPath = Join-Path "$expectedPath" "bin/$MVN_CMD" +if ((Test-Path -Path $expectedPath -PathType Container) -and (Test-Path -Path $expectedMvnPath -PathType Leaf)) { + $actualDistributionDir = $distributionUrlNameMain +} + +# If not found, search for any directory with the Maven executable (for snapshots) +if (!$actualDistributionDir) { + Get-ChildItem -Path "$TMP_DOWNLOAD_DIR" -Directory | ForEach-Object { + $testPath = Join-Path $_.FullName "bin/$MVN_CMD" + if (Test-Path -Path $testPath -PathType Leaf) { + $actualDistributionDir = $_.Name + } + } +} + +if (!$actualDistributionDir) { + Write-Error "Could not find Maven distribution directory in extracted archive" +} + +Write-Verbose "Found extracted Maven distribution directory: $actualDistributionDir" +Rename-Item -Path "$TMP_DOWNLOAD_DIR/$actualDistributionDir" -NewName $MAVEN_HOME_NAME | Out-Null +try { + Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null +} catch { + if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) { + Write-Error "fail to move MAVEN_HOME" + } +} finally { + try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } + catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } +} + +Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" diff --git a/pom.xml b/pom.xml index 2d4bac37e..dc5c6a270 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.github.microsphere-projects microsphere-build - 0.2.2 + 0.2.3 io.github.microsphere-projects @@ -51,14 +51,18 @@ - 0.1.7-SNAPSHOT + 0.1.8-SNAPSHOT microsphere-java-parent microsphere-java-dependencies - microsphere-annotation-processor + microsphere-java-annotations microsphere-java-core + microsphere-jdk-tools + microsphere-java-test + microsphere-lang-model + microsphere-annotation-processor \ No newline at end of file